Re: [sugar] Fwd: Roadmap update
There was just a discussion on IRC about this, and I wanted to put some of the clarifications from there up here on the mailing list: [07:59] dsd_ my 2 immediate concerns were: are contracts ending, and is olpc ditching sugar [07:59] dsd_ sounds like no for both, which is reassuring [07:59] tomeu well, I would say yes (in short) and no (for now) [07:59] tomeu but I'm guessing just as you are [07:59] dsd_ kk [08:00] tomeu anyway, I'm personally quite positive about it [08:00] homunq how so? [08:00] homunq (reassure us) [08:01] tomeu I personally find that sugar has a very clear need to satisfy and is well positioned to do so [08:01] tomeu lots of people have shown interest in sugar [08:06] homunq Whether or not OLPC clarifies, I think it would be healthy for sugarlabs to do so [08:07] homunq not try to speak for OLPC, of course, but just to say: we have this many people paid to work on sugar through these mechanisms, and these prospects of getting more. [08:08] tomeu homunq: that may not be too upbeat ;) [08:08] dsd_ Ridderman: lets not jump to conclusions until we have actual details.. right now nobody knows really what this means [08:09] homunq tomeu: I understand that. But, personally, I'd rather know than keep guessing, and I suspect others agree. [08:09] tomeu well, we don't know lots of things, but we know what has been said [08:10] tomeu one of the few things I know is that I will self fund my work on sugar until my savings end, probably one year [08:10] tomeu I really think sugar has a bright future and I'm willing to invest on it [08:11] tomeu homunq: a pity you couldn't attend sugarcamp, you would have noticed how much people cared about sugar [08:11] tomeu see, I'm not just doing this because I can, I know other people are going to invest on sugar [08:12] tomeu and I see a great potential there [08:12] icarito i think a clear statement from OLPC is in order [08:12] tomeu olpc is going to keep shipping sugar AFAIK, and that's very good, we need to aknowledge that and make sure it's a success, within our capabilities [08:13] icarito headlines here stated OLPC will come with windows [08:13] icarito when its only a 50 machine test [08:13] tomeu icarito: that means ms has a good marketing department ;) [08:18] * cjb wakes up, and is annoyed [08:18] cjb marcopg: in what conceivable way is it true that OLPC is not funding Sugar development anymore? [08:20] cjb It didn't say effective today, tomeu/simon/sayamindu/morgan are fired [08:25] cjb Ed said he wants to concentrate on deployability for the next release [08:25] cjb that does not mean some sugar bugs won't be fixed (it means it isn't the main focus) [08:25] cjb that does not mean sugar work won't be funded in the future [08:25] cjb and it does not mean, finally, that OLPC is no longer funding work on sugar development [08:26] Ridderman to me, this just underscores the need for self sufficiency in the Sugar community OLPC has very limited resources and is choosing to focus on other things than core Sugar development for now [08:46] marcopg dsd_: I'm not sure how you can compare sugar running on more platforms with a list that doesn't include journal, collaboration, performance or any of the big goals we had set for 0.84 (based on OLPC product manager input) [08:47] marcopg let's keep it concrete: [08:47] marcopg I don't feel like I can work on journal, collaboration, performance in OLPC time for 9.1 [08:48] marcopg *if* OLPC management tells me that's not the case [08:48] marcopg then I'll happily change my statement about funding [08:49] cjb marcopg: Sorry for getting angry. I feel that what you said is really unfair, but it'll get worked out. [08:51] cjb it is unfair to announce that OLPC is not funding Sugar development anymore as a proxy for OLPC said we have to concentrate on deployability, which means I'm not sure what to work on anymore, therefore OLPC is not funding Sugar development. [08:58] tomeu cjb: it cannot be told that we haven't given time or notice for olpc to be clear about their intentions [08:58] cjb A rewording I think I would agree with is -- For the next release cycle, OLPC isn't going to have time/resources to work on fundamental isssues like a Journal or Collaboration rewrite. [08:58] marcopg cjb: the community needs to know and asap, because we need to move on. If OLPC wants to announce it in a positive way, it should explicitly spin-off Sugar and announce it publically, as we requested for months [08:59] tomeu cjb: ok, I like that rewording better as well, but I don't care so much about how it is said [09:00] cjb and when SL announces that OLPC just pulled out of working on Sugar publically, when OLPC thinks it's doing nothing of the sort, that makes my job very hard. [09:01] dsd_ marco's mail made me seriously wonder if OLPC is going to stop shipping sugar [09:01] dsd_ which is not a message that anyone here wants to put across [09:01] marcopg you can put it in nice words, sure [09:01] marcopg but that
Re: [sugar] list of complaints from sugarcamp community building talk
+1 embedding mibbit or cgiirc in our wiki? Tomeu ___ Sugar mailing list Sugar@lists.laptop.org http://lists.laptop.org/listinfo/sugar
[sugar] [RELEASE] Develop 35
These are edits on the XO to work with Rainbow. New activity now works, and open activity is improved. There are some other minor bugs fixed (no duplicate log tab). However, the log tab still does not work with Rainbow enabled; this is a basic feature of rainbow, and will not work until there is a P_VIEW_LOGS bitfrost privilege implemented. ___ Sugar mailing list Sugar@lists.laptop.org http://lists.laptop.org/listinfo/sugar
[sugar] P_READ_LOGS
For when we actually have bitfrost permissions in the interface, I propose another simple bitfrost permission: P_READ_LOGS. This is easily doable with groups and permissions. I think it would be safe and useful if it were: not given by default; not compatible with P_NETWORK except through user intervention; but given to any non-P_NETWORK activity which requested it. It is true that some private data could leak into the logs, but in general the amount would be negligible; in the exceptional cases (which would be bugs in some activity), the lack of P_NETWORK would keep the data from spreading anyway. This would be useful for Develop, and also to remove Log and Analyze from the list of activities which need the far-more-dangerous (and also not-fully-consensed) P_ROOT. ___ Sugar mailing list Sugar@lists.laptop.org http://lists.laptop.org/listinfo/sugar
[sugar] [PATCH] 5657: don't install activities in Rainbow's loophole (and draft 2 of bigger patch for 9.1)
attachments, in order: (1) 0...the proposed patch to sugar (2) suga..9.1 sugar part of a draft patch for 9.1, only read it if you're interested, scarcely tested. (3) 0...s-l proposed patch for sugar-toolkit (4) tool...9.1 the sugar-toolkit part of the draft 9.1 patch (5) 0...fixes some minor pylint cleanup to sugar, to be applied after patch 1 above. So, the important parts here are (1) and (3). Patch (1) makes sugar registry service not add bundles unless they're in ~/Activities. (The registry can add such bundles, but the service will refuse to). Patch (3) makes activitybundle.py refuse to install loopholed activities unless called with securitycheck=False. From 4db7faf72edc7eaa2aa4631a98aa29819f2e5ec8 Mon Sep 17 00:00:00 2001 From: Jameson Quinn [EMAIL PROTECTED] Date: Mon, 4 Aug 2008 19:17:11 -0600 Subject: [PATCH] bug #5657 - don't add bundles to registry unless they're in ~/Activities --- service/bundleregistry.py |7 +-- 1 files changed, 5 insertions(+), 2 deletions(-) diff --git a/service/bundleregistry.py b/service/bundleregistry.py index e7c30a8..5d3fec8 100644 --- a/service/bundleregistry.py +++ b/service/bundleregistry.py @@ -174,12 +174,15 @@ class BundleRegistry(gobject.GObject): bundle_dirs.sort(lambda d1, d2: cmp(bundles[d1], bundles[d2])) for folder in bundle_dirs: try: -self.add_bundle(folder) +self.add_bundle(folder, securitycheck=False) except Exception, e: logging.error('Error while processing installed activity ' \ 'bundle: %s, %s, %s' % (folder, e.__class__, e)) -def add_bundle(self, bundle_path): +def add_bundle(self, bundle_path, securitycheck=True): +if securitycheck and not bundle_path.startswith( +os.path.expanduser(~/Activities)): +return False try: bundle = ActivityBundle(bundle_path) except MalformedBundleException: -- 1.5.2.5 diff --git a/service/activityregistryservice.py b/service/activityregistryservice.py index 6ba5598..7b3415a 100644 --- a/service/activityregistryservice.py +++ b/service/activityregistryservice.py @@ -24,6 +24,11 @@ _ACTIVITY_REGISTRY_SERVICE_NAME = 'org.laptop.ActivityRegistry' _ACTIVITY_REGISTRY_IFACE = 'org.laptop.ActivityRegistry' _ACTIVITY_REGISTRY_PATH = '/org/laptop/ActivityRegistry' +def log_it(s): +f = file(/home/chema/.sugar/default/logs/hardcoded,ab) +f.write(s+\n) +f.close() + class ActivityRegistry(dbus.service.Object): def __init__(self): bus = dbus.SessionBus() @@ -64,11 +69,8 @@ class ActivityRegistry(dbus.service.Object): @dbus.service.method(_ACTIVITY_REGISTRY_IFACE, in_signature='', out_signature='aa{sv}') def GetActivities(self): -result = [] registry = bundleregistry.get_registry() -for bundle in registry: -result.append(self._bundle_to_dict(bundle)) -return result +return (bundle for bundle in registry) @dbus.service.method(_ACTIVITY_REGISTRY_IFACE, in_signature='s', out_signature='a{sv}') @@ -78,7 +80,8 @@ class ActivityRegistry(dbus.service.Object): if not bundle: return {} -return self._bundle_to_dict(bundle) +log_it(service about to return +str(bundle)) +return bundle @dbus.service.method(_ACTIVITY_REGISTRY_IFACE, in_signature='s', out_signature='aa{sv}') @@ -90,18 +93,15 @@ class ActivityRegistry(dbus.service.Object): name = bundle.get_name().lower() bundle_id = bundle.get_bundle_id().lower() if name.find(key) != -1 or bundle_id.find(key) != -1: -result.append(self._bundle_to_dict(bundle)) +result.append(bundle) return result @dbus.service.method(_ACTIVITY_REGISTRY_IFACE, in_signature='s', out_signature='aa{sv}') def GetActivitiesForType(self, mime_type): -result = [] registry = bundleregistry.get_registry() -for bundle in registry.get_activities_for_type(mime_type): -result.append(self._bundle_to_dict(bundle)) -return result +return registry.get_activities_for_type(mime_type) @dbus.service.method(_ACTIVITY_REGISTRY_IFACE, in_signature='sib', out_signature='') @@ -127,32 +127,14 @@ class ActivityRegistry(dbus.service.Object): def ActivityChanged(self, activity_info): pass -def _bundle_to_dict(self, bundle): -registry = bundleregistry.get_registry() -favorite = registry.is_bundle_favorite(bundle.get_bundle_id(), - bundle.get_activity_version()) -x, y = registry.get_bundle_position(bundle.get_bundle_id(), -
Re: [sugar] video bleeds through somewhat between sessions
Both persons who have answered me have talked about how things from the video frame can be seen. But I was not looking at video - I was looking at TEXT. If I understand correctly what has been told me here, neither the 'black' of the text characters themselves, nor the 'white' of the background for the text, should have _allowed_ things from the video frame to be seen. I definitely did not see any color. What I did see was that some parts of the 'black' text characters changed briefly to _less_ 'black' (they went black -- gray -- black) depending on where on *its* screen the ongoing video 'session' WOULD HAVE depicted bright or dark areas. I think that the operating theory is that, around the edges of the black text, there are some pixels which are grey (or even, because of the funny xo color magic, colored?). These pixels would then be transparent. Is this consistent with your experience? In other words, is it possible that the video was fully visible in occasional pixels, instead of partially visible in all the black text pixels? ___ Sugar mailing list Sugar@lists.laptop.org http://lists.laptop.org/listinfo/sugar
[sugar] preliminary [PATCH] and discussion for #5657: activity isolation for all activities in ~/Activities
Problem: anything named Journal, Terminal, Log, or Analyze is not isolated. This is the biggest security hole we have right now: it is a trivial way for any activity to get root access. Idea: as a short-term hack (until we have good cryptographic signatures for activities), only turn off isolation if an activity is in .../share/sugar/activities. Installation here is only possible for root (or at build time). Implementation: This makes sense to implement in activitybundle.py, respecting a line in activity.info like: bitfrost_requests = P_ROOT, P_OTHER_UNIMPLEMENTED_THING, ... That means that the data then passes up the chain: to bundleregistry, to activityregistryservice, to sugar.activity.registry, and then to activityfactory. Passing it up the chain meant fixing the call signatures all the way along, and doing some refactoring along the way. Status: Works, not well tested (I will test more before submitting it definitively. Also I'll have to include the patch to Journal's activity.info. Patches to the other activities and packaging concerns will wait for round 3.) Marcopg or others, feel free to start the review on the included patches; there are enough bigger design decisions evident that we can get a jump on review even before I do the solid testing on Monday. Consequences: - Changing the four activities named above to be installed in share/sugar/activities. To remove them, a country would need to use a customization key. - If the activities above are in a country's build, they cannot be uninstalled by user. If they are upgraded by user, they lose their unisolated powers; if the upgrade is removed, they regain them. (Not tested) Related issues: - The use of version numbers to distinguish two versions of a single activity is improved by this patch, but is still inconsistent. Erratic behaviour is expected when two versions of the same activity are present, although in normal use (all installation through the journal) this would never happen as the older versions would be uninstalled automatically. - Of course, the long-term solution is activity signatures. - It will still be possible for a web link to claim to be activity X, but to actually replace Browse (or other) with a trojanned version. (I know, this is only weakly related, but it came up while I was discussing this patch with Eben, so I mention it here.) I tracced this: #7761 http://dev.laptop.org/ticket/7761 From 2c114c26003d10705e3d174d47eae11311bffaaf Mon Sep 17 00:00:00 2001 From: Jameson Quinn [EMAIL PROTECTED] Date: Fri, 1 Aug 2008 13:40:25 -0600 Subject: [PATCH] bug #5657: gets security requests from activitybundle, checks them, and passes them up to registry --- service/activityregistryservice.py | 54 ++ service/bundleregistry.py | 107 2 files changed, 102 insertions(+), 59 deletions(-) diff --git a/service/activityregistryservice.py b/service/activityregistryservice.py index 6ba5598..7b3415a 100644 --- a/service/activityregistryservice.py +++ b/service/activityregistryservice.py @@ -24,6 +24,11 @@ _ACTIVITY_REGISTRY_SERVICE_NAME = 'org.laptop.ActivityRegistry' _ACTIVITY_REGISTRY_IFACE = 'org.laptop.ActivityRegistry' _ACTIVITY_REGISTRY_PATH = '/org/laptop/ActivityRegistry' +def log_it(s): +f = file(/home/chema/.sugar/default/logs/hardcoded,ab) +f.write(s+\n) +f.close() + class ActivityRegistry(dbus.service.Object): def __init__(self): bus = dbus.SessionBus() @@ -64,11 +69,8 @@ class ActivityRegistry(dbus.service.Object): @dbus.service.method(_ACTIVITY_REGISTRY_IFACE, in_signature='', out_signature='aa{sv}') def GetActivities(self): -result = [] registry = bundleregistry.get_registry() -for bundle in registry: -result.append(self._bundle_to_dict(bundle)) -return result +return (bundle for bundle in registry) @dbus.service.method(_ACTIVITY_REGISTRY_IFACE, in_signature='s', out_signature='a{sv}') @@ -78,7 +80,8 @@ class ActivityRegistry(dbus.service.Object): if not bundle: return {} -return self._bundle_to_dict(bundle) +log_it(service about to return +str(bundle)) +return bundle @dbus.service.method(_ACTIVITY_REGISTRY_IFACE, in_signature='s', out_signature='aa{sv}') @@ -90,18 +93,15 @@ class ActivityRegistry(dbus.service.Object): name = bundle.get_name().lower() bundle_id = bundle.get_bundle_id().lower() if name.find(key) != -1 or bundle_id.find(key) != -1: -result.append(self._bundle_to_dict(bundle)) +result.append(bundle) return result @dbus.service.method(_ACTIVITY_REGISTRY_IFACE, in_signature='s', out_signature='aa{sv}') def GetActivitiesForType(self, mime_type): -result = [] registry =
Re: [sugar] [OLPC Security] preliminary [PATCH] and discussion for #5657: activity isolation for all activities in ~/Activities
On Fri, Aug 1, 2008 at 4:01 PM, C. Scott Ananian [EMAIL PROTECTED] wrote: On Fri, Aug 1, 2008 at 5:01 PM, Jameson Chema Quinn [EMAIL PROTECTED] wrote: Problem: anything named Journal, Terminal, Log, or Analyze is not isolated. This is the biggest security hole we have right now: it is a trivial way for any activity to get root access. Another possible short-term hack is to simple disable activitybundle.install() and activitybundle.upgrade() for bundes with bundle_ids matching those of Journal, Terminal, Log, or Analyze. This allows these activities to be installed in /home/olpc/Activites with a customization key, as usual, but prevents malicious attackers from using a web link or the activity updater to replace the originally-installed versions. This has the benefit of (a) not requiring us to revisit the activities in /home war, and (b) allowing us to upgrade the versions of these trusted activities in /home in (say) 9.1, using the proper mechanism. --scott I like this idea. Of course, it means that can install using cp -r, including installing a trojan activity which does not *look* like Terminal. ... My patch has activities requesting P_ROOT in activity.info. Could we simply refuse to do a normal install for such activities? We could even keep a list of them, and not respect what's not on the list, and only update the list on a keyed install. This is not as secure as signatures, because a sneaky attack could still modify the contents of an installed activity, but it is getting pretty close. Jameson ___ Sugar mailing list Sugar@lists.laptop.org http://lists.laptop.org/listinfo/sugar
[sugar] [RELEASE] Develop 34
A new version of Develop is available. See the Develop pagehttp://wiki.laptop.org/go/Developon the wiki. Since this is the first time I announce a release on @sugar, there is little point in enumerating specific bug fixes. Not recommended for Glucose joyride-2171 (You can make it work, but there are several issues, and I'd rather not explain all the needed workarounds). I have cleaned up the bugs in component:Develop on trac. If you submit a bug there, I will see it (though I'll probably see it faster if you email me or ping me on IRC). Please feel free to respond to this email with any questions. I'd be happy to know where I need to explain things better. ___ Sugar mailing list Sugar@lists.laptop.org http://lists.laptop.org/listinfo/sugar
Re: [sugar] Congratulations! but Sugar sucks
| 1. The datastore | 2. OS Updates | 3. File Sharing | 4. Activity Modification | 5. Bitfrost | 6. Power management On Thu, Jul 24, 2008 at 11:02 PM, C. Scott Ananian [EMAIL PROTECTED] wrote: On Thu, Jul 24, 2008 at 8:18 PM, Benjamin M. Schwartz [EMAIL PROTECTED] wrote: really surprisingly short. Each item on the list has been debated to a stationary point over the last two years, so all that is left is to make a final decision for the engineers to execute. Each task could be completed or hugely improved by a single developer in a few months, provided that we do not allow changes to the requirements, and the developers are not asked to split their time and focus. I do not believe that either of these statements is correct. We are not lacking in decisions: we have substantially complete designs; we are lacking implementation. Each of your items is not the work of a single developer in a few months: solving these problems is realistically a year's work at least, if we have a single developer working full time on each. I have experience with numbers 1, 3, and 5, and am the principal person responsible for 4 right now. I would say that 3 and 4 are definitely within the single dev in a few months time frame; depending on the definition, 4 is in the as soon as currently applied patches percolate into production time frame. The further work on 4 - already started - is in the area of activity signatures, which is actually encroaching on 5. In a few full-time months of a single developer, this would put 4 at a place which other platforms could envy, and make concrete strides towards 5, to the point where security would be better, not worse, than other modern platforms (though I agree that there is plenty more work to fulfill the true promise of Bitfrost). I agree that 1 is not so simple; while a rockstar developer might be able to solve all our problems in a two-month all-nighter, 6 months to a year is a more realistic timeframe to get something really solid and stable. What I have accomplished - admittedly too slowly - on Develop, I have done in under half-time commitment. I have made it pretty clear that I was available for full-time work, pretty cheaply, but not for free. I could work to contract, with payment working out to around what the GSoC students are getting, and have Develop and Bitfrost in a significantly better place by the end of September (activity signatures done, bitfrost privileges by-application secure on that basis, the Terminal/Journal bitfrost loophole mendedl; Develop collaboration/source control starting to be usable). ps. and, of course, you've neglected software for kids that does things kids want to do, powerful and pervasive collaboration and mesh networking in your list of items. All of which are slightly less sucky in their current state than the items mentioned, I think, but definitely need work too. To sum up: if this is a matter of resources, just hire people. Me, and others who want it - I have heard marcopg complaining that he should be full-time, I think. In my case, the worst that could happen is that I don't come through, and, since I am asking for contract work, that would mean you don't pay me, so it would be identical to current situation. The best would be that for less than the price of a classroom-full of XOs, you would get large steps on two of these list items in a couple of months. ___ Sugar mailing list Sugar@lists.laptop.org http://lists.laptop.org/listinfo/sugar
Re: [sugar] Congratulations! but Sugar sucks
I think that one useful thing that we could work out in this thread would be how many dollars and months it would take to get each of these areas from suckage to ruleage. Here's some estimates out of my ... head: 1. datastore. Get consensus: 1.5 months from now (really, 1 month from 8.2). Hire/reassignAndClearTheDecksOf someone to work on this full time: 1 month. Actual work to reach The Next Level: 2-3 months. Cleanup: 2-3 months. Realistically, we can't guarantee that this can make it by 9.1, but it should be close. Time: 6+ months, cost: 4-6 months FTE. Someone with these skills could cost up to $80K/yr in US, over half that internationally. 2. OS updates. Design and consensus: 2.5 months from now. Actual coding: 2 months. (This is the kind of problem that needs good clean design, but is not too very hard to implement.) Time: 5 months, cost: using existing resources. 3. File Sharing. Apparently there is already an intern on this. 3 months, existing resources. 4. Activity Modification: 2 months and $5K. 5. Bitfrost Blocked by 4 (activity bundle signatures), above. After that, there are about 2 biggish (1-2 months) features to add, and then the rest is eternal vigilance (much debugging). Say 2-4 months FTE, 6 months ETA 6. Power management ??? 7. Software: if you build it, they will come. 8. Collab: ??? existing resources? 9. Mesh: ??? Add it all up, and I think that with about 3 expensive new-hire FTEs and me (much, much cheaper), 90% of this list could be done in time for 9.1; the other 10% could be done by 9.2 without even using the new FTEs, which would free them up for nextgen development. On the other hand, I think that with just existing resources, only about 30% will be done by 9.1, which will Still Suck. IMO this is a steal - I know nothing about funding here, but if there is a chance of this level of funding I think it is a no-brainer. Say there's $100,000,000 of hardware out there, shipped; I think that this list accounts for easily 10% of the use-value of this hardware; and the costs above are far under $300K, with the most pessimistic accounting. That means that the *immediate* social-value for investment would be around a factor of 20. ___ Sugar mailing list Sugar@lists.laptop.org http://lists.laptop.org/listinfo/sugar
Re: [sugar] Activity versioning schema
On Wed, Jul 16, 2008 at 3:54 PM, Martin Langhoff [EMAIL PROTECTED] wrote: On Thu, Jul 17, 2008 at 4:54 AM, Michael Stone [EMAIL PROTECTED] wrote: What _should_ be happening in this thread is the collection of use cases. For a small selection of the issues involved, please refer to http://wiki.laptop.org/go/User:Mstone/Commentaries/Bundles_1 http://wiki.laptop.org/go/User:Mstone/Commentaries/Bundles_2 +1 on creating use cases for activity versions. -1 on that being necessary to resolve this particular thread (except insofar as it makes opaque version strings less attractive). The security issues are with the service ID, not the version. ...In the meantime, a simply obvious solution that meets our needs is standing in front of us, glowing warmly . grab it +2 ___ Sugar mailing list Sugar@lists.laptop.org http://lists.laptop.org/listinfo/sugar
[sugar] Feature/string freeze exception: 7534: need_upgrade() always True
Currently, when you ask activitybundle.py to install an xo bundle, it first checks need_upgrade. This returns False in only one circumstance: when the installed version has the same version number as the new version. In that circumstance, the install silently fails, as it presumes same version number means same xo bundle. This assumption, and thus this behaviour, is dangerous - the effect would be to silently block out the installation of a specific bundle version. The workaround would be simple, but the diagnosis would be hard in the field; it could arise from malice, individual error, or even countrywide error (country X creates a new version with changed icons, later a crucial security fix collides with the country X version number...). It is also very annoying if you're using Develop, because it forces you to churn the version number (up or down, it doesn't matter) on every debug cycle. My posted patch simply has need_upgrade always return true. It is called in only one place - in datastore.py DSObject.resume(). The downside is only that manually reinstalling the same bundle will actually reinstall it, instead of quickly and silently deciding not to - which seems to me a non-helpful optimization, since the time it saves will be orders of magnitude less than the debugging time it causes. The need_upgrade function remains, for later when we do have a cryptographically solid way of checking bundle identity. ___ Sugar mailing list Sugar@lists.laptop.org http://lists.laptop.org/listinfo/sugar
Re: [sugar] Activity versioning schema
On Mon, Jul 14, 2008 at 8:29 PM, Mikus Grinbergs [EMAIL PROTECTED] wrote: If, as is the current plan, multiple versions of an activity can coexist on an XO, ... Two use cases: 1. I have a journal object. I want to choose which activity to open it with. I am presented with a multilevel menu: the top level has all activities which open the mime type, the next level has all major versions of those activities, the next level minor versions, etc. If click without bothering to move over to the sublevels, I get the default version from the sublevel of my current menu, which is the starred version (if it exists) or the highest version (applied recursively down the sublevels). I'm sorry, but my mind boggles at the thought of a four-year old clicking on a Journal entry and being presented with a palette of seventeen different versions of 'TamTam' -- so that he may choose which of those versions is appropriate for whatever upgrade the adults had made to that XO last week. mikus This is not, of course, the default behavior - if you just click on a journal entry, it opens with whatever version created it, or the starred version (if the creator version is not marked as creating incompatible entries), whichever is more mature. All that logic happens with no need for human interaction (and yes, we need Glucose to understand something about versions for that to work). Nevertheless, the behavior I described is my best understanding of the approximate consensus of severalhttp://wiki.laptop.org/go/User:Mstone/Bundle_commentary discussions http://wiki.laptop.org/go/User:Mstone/Commentaries/Bundles_2(+2 more) I have had on IRC about this matter. I myself would (and did) advocate for more automatic updating, and no decision is set in stone; but no matter how automatic and smart we make things, we are going to have to choose at some point between having a manual fallback, or having some things break because we don't have a manual fallback. I'd rather have the fallback, and I think that if we do, we should be hiding it in heirarchical menus as much as possible (so that even if you DO need the fallback and even if you DO have 6 installed versions of TamTam, Glucose is at every moment hiding as many of them as possible until you deliberately, by hovering, ask it to show you more). If you have a better idea of how Glucose should handle these issues, please share it. Simplifying assumptions are good, even if they're not 100% valid. ___ Sugar mailing list Sugar@lists.laptop.org http://lists.laptop.org/listinfo/sugar
Re: [sugar] Activity versioning schema
On Tue, Jul 15, 2008 at 12:57 PM, C. Scott Ananian [EMAIL PROTECTED] wrote: 2008/7/15 Jameson Chema Quinn [EMAIL PROTECTED]: If you have a better idea of how Glucose should handle these issues, please share it. Simplifying assumptions are good, even if they're not 100% valid. Versions in activity.info files are either plain integers, or RPM-standard version strings, with no pretense that these correspond in any way to sugar major releases or anything at all, except that they are ordered: if the activity updater sees that you have version N, and there is a version M announced[*] as compatible with your build where M N, then it will suggest that you upgrade to M. All other meanings are encoded with other mechanisms. --scott I meant the UI issues, since that is what Mikus objected to. I.e., can multiple versions of the same activity coexist on same xo? What about journal instances from multiple versions of an activity? What can we do concretely to try to avoid/deal with this situation? ___ Sugar mailing list Sugar@lists.laptop.org http://lists.laptop.org/listinfo/sugar
Re: [sugar] Activity versioning schema
On Tue, Jul 15, 2008 at 12:57 PM, C. Scott Ananian [EMAIL PROTECTED] wrote: 2008/7/15 Jameson Chema Quinn [EMAIL PROTECTED]: If you have a better idea of how Glucose should handle these issues, please share it. Simplifying assumptions are good, even if they're not 100% valid. Versions in activity.info files are either plain integers, or RPM-standard version strings, with no pretense that these correspond in any way to sugar major releases or anything at all, except that they are ordered: if the activity updater sees that you have version N, and there is a version M announced[*] as compatible with your build where M N, then it will suggest that you upgrade to M. All other meanings are encoded with other mechanisms. --scott I meant the UI issues, since that is what Mikus objected to. I.e., can multiple versions of the same activity coexist on same xo? What about journal instances from multiple versions of an activity? What can we do concretely to try to avoid/deal with this situation? ___ Sugar mailing list Sugar@lists.laptop.org http://lists.laptop.org/listinfo/sugar
Re: [sugar] Activity versioning schema
I agree with the signature approach. However, I don't really know what happens when I have 37, 38, and 39 where 39 is a bugfix release of 37, and 39 is a brand new version...I'd prefer to see them ordered 37, 39, 38, to coincide with the level of newness. This is something we will lose completely without a minor release number. The logical assumption is that the bigger the number, the better/newer it is, which is blatantly false when point releases are intermixed with brand new versions with ever-increasing version numbers. I might decide I need to clear up space, and so delete versions 37 and 38, thinking I was keeping the latest and greatest version 39 and be quite disappointed. - Eben This idea works well when developers time their new-features releases to coincide with Sucrose updates. It starts to break down when that does not hold - does version 3.x mean runs on same Sucrose as 3.0 or holds essentially the same feature-set as 3.0 or some combination of both? I think that Eben is assuming the former - that nobody would go back and release lower version numbers except in order to maintain system compatibility - but this conflicts with a common assumption that major version changes are synonymous with major new features. Basically, there are two separate problems here, and we should not be solving them together. One is that the latest release may not be the greatest - because of bugfix releases. I agree with Eben's proposal of minor version numbers as a (totally optional) solution; as long as the minor/major separator is not a decimal separator (that is, [.,]), the meaning is pretty self-evident. (I think that : is the best candidate, by analogy with times and bible verses.) But the second problem is harder: how do you tell people which versions run on which Glucose. Any attempt to encode this implicitly in version numbers is, I think, bound to fail, and not too helpful anyway. The update_url solution for #4951 fixes the most useful version of this problem - what is the latest working version on my system. I think we can live without a more general solution to will version X run on system Y - even though that means some ugly trial-and-error when sharing activities across Glucose versions. ... and cscott just wrote an email which says many of the same things. Jameson ___ Sugar mailing list Sugar@lists.laptop.org http://lists.laptop.org/listinfo/sugar
Re: [sugar] Activity versioning schema
On Mon, Jul 14, 2008 at 4:18 PM, C. Scott Ananian [EMAIL PROTECTED] wrote: If we're going to a 'dotted decimal' scheme, we should use '.'. ... Is 1.1 newer or older than 1.11?) This is exactly the reason I think that 1-1 ... 1-11 is clearer (you're right, colon is unworkable because it cannot go in NTFS file names). From an educational standpoint, 1.10 is teaching kids the wrong ideas about the decimal system. I do not think that hyphens are impractical. In most cases people will get it right the first time by following examples. Those who don't will quickly learn from installation warnings. I think anything from 1-3 levels should be allowed, and that 3 == 3-0 == 3-0-0. Leading zeroes should cause warnings - that will mostly keep things from looking like dates (even in 2010, bugfix 10 should be rare). ___ Sugar mailing list Sugar@lists.laptop.org http://lists.laptop.org/listinfo/sugar
Re: [sugar] Activity versioning schema
I'd like to pose an alternative goal, inspired by your comment: Glucose should never attempt to parse version strings. I believe that we can accomplish this without sacrificing any of the user-facing behaviors that we truly desire. The choice of an appropriate versioning scheme may then be left to the author. I disagree. It is desirable for Sugar to be able to compare versions and guess which one is newer. If, as is the current plan, multiple versions of an activity can coexist on an XO, it is reasonable to want sugar to present these in some sane order, and possibly give hints and/or aid if the user wants to update and/or garbage collect. Otherwise, we might as well just be using activity hash, which can be calculated without being explicitly included in activity.info. ___ Sugar mailing list Sugar@lists.laptop.org http://lists.laptop.org/listinfo/sugar
Re: [sugar] Activity versioning schema
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 Jameson Chema Quinn wrote: | It is desirable for Sugar to be able to compare versions and | guess which one is newer. Newer means more recent. If this capability is important to you, then we may simply include a datestamp in each bundle, separate from the version. However, I do not know of any planned Sugar feature that would require the ability to determine which bundle was created most recently. I misspoke. I meant, the latest, in the same sense that Eben is using it: the version with all relevant new feature decisions (including added and dropped features) and bugfixes. This is not always the one created at the latest calendar date. | If, as is the current plan, multiple versions of | an activity can coexist on an XO, it is reasonable to want sugar to present | these in some sane order, and possibly give hints and/or aid if the user | wants to update and/or garbage collect. Otherwise, we might as well just be | using activity hash, which can be calculated without being explicitly | included in activity.info. I favor including a version string with every bundle. I favor displaying this string in places where it is needed to disambiguate multiple versions of an Activity. I'm merely suggesting that the system not attempt to parse it. You mention ordering. The Journal designs have long called for all columns to be sorted, with the user selecting the order of sorting precedence. One intermediate position would be for the Version column to be sorted according to a best-effort ordering that attempts to do something sane when faced with any of the common version string conventions. Two use cases: 1. I have a journal object. I want to choose which activity to open it with. I am presented with a multilevel menu: the top level has all activities which open the mime type, the next level has all major versions of those activities, the next level minor versions, etc. If click without bothering to move over to the sublevels, I get the default version from the sublevel of my current menu, which is the starred version (if it exists) or the highest version (applied recursively down the sublevels). 2. I just quit an activity version which is signed (ie, not just a development build) and is a higher number than the starred version. A dialog pops up asking if I want to update to that version. If I click yes, Sugar moves the star to the new version (freeing the older version for possible later GC). If I choose no, the dialog will not appear again. (Dealing with instances associated with the old version is more complicated. Say I have an instance from Write 50 and Write 60 is starred. I suggest that the ideal behaviour would be to open by default with Write 60, assuming it handles the mime type, but ask after closing if that worked; if not, remember that Write 50 instances may be incompatible with other versions and open them by default with Write 50 always. An instance of Write 70 should open with Write 70. This would not change GC behaviour: you might end up GC-ing an old version and losing access to your instances, but the old version would be available if necessary from the backup server.) I guess you could argue that use case 2 should offer to assist downgrades as well as upgrades (since we would be keeping separate already-showed-dialog metadata for each version, any version would only show the dialog once, and that would be more likely to be when it was newer), but I think that even then it would be useful to include the words higher version or lower version in the dialog. ___ Sugar mailing list Sugar@lists.laptop.org http://lists.laptop.org/listinfo/sugar
Re: [sugar] [PATCH] #7205: fix_manifest command for bundlebuilder
Really this is a convenience function, but since we're now being picky about MANIFEST, I think that not having a way to fix the MANIFEST counts as a regression. Thus I do nominate this for 8.2 . fix_manifest.patch is just these changes, but it collides with the other patch I submitted. combined.patch is both patches together. diff --git a/src/sugar/activity/bundlebuilder.py b/src/sugar/activity/bundlebuilder.py index 2480b03..52cd3e5 100644 --- a/src/sugar/activity/bundlebuilder.py +++ b/src/sugar/activity/bundlebuilder.py @@ -192,6 +192,8 @@ setup.py uninstall [dirname] - uninstall the bundle \n\ setup.py genpot - generate the gettext pot file \n\ setup.py release - do a new release of the bundle \n\ setup.py help- print this message \n\ +setup.py fix_manifest- fix the MANIFEST file to list all files in directory \n\ + except dist/* .git/* .gitignore MANIFEST *.pyc *~ *.bak \n\ ' def cmd_dev(config, options, args): @@ -361,6 +363,10 @@ def cmd_build(config, options, args): builder = Builder(config) builder.build() +def cmd_fix_manifest(config, options, args): +buildpackager = BuildPackager(config) +buildpackager.fix_manifest() + def start(bundle_name=None): if bundle_name: logging.warn(bundle_name deprecated, now comes from activity.info) diff --git a/src/sugar/activity/bundlebuilder.py b/src/sugar/activity/bundlebuilder.py index 2480b03..7744f0b 100644 --- a/src/sugar/activity/bundlebuilder.py +++ b/src/sugar/activity/bundlebuilder.py @@ -81,6 +81,10 @@ class Builder(object): def build_locale(self): po_dir = os.path.join(self.config.source_dir, 'po') +if not self.config.bundle.is_dir(po_dir): +logging.warn(Missing po/ dir, cannot build_locale) +return + for f in os.listdir(po_dir): if not f.endswith('.po'): continue @@ -192,6 +196,8 @@ setup.py uninstall [dirname] - uninstall the bundle \n\ setup.py genpot - generate the gettext pot file \n\ setup.py release - do a new release of the bundle \n\ setup.py help- print this message \n\ +setup.py fix_manifest- fix the MANIFEST file to list all files in directory \n\ + except dist/* .git/* .gitignore MANIFEST *.pyc *~ *.bak \n\ ' def cmd_dev(config, options, args): @@ -214,6 +220,10 @@ def cmd_dist_xo(config, options, args): packager = XOPackager(config) packager.package() +def cmd_dist(config, options, args): +logging.warn(dist deprecated, use dist_xo.) +cmd_dist_xo(config, options, args) + def cmd_dist_source(config, options, args): packager = SourcePackager(config) packager.package() @@ -361,6 +371,10 @@ def cmd_build(config, options, args): builder = Builder(config) builder.build() +def cmd_fix_manifest(config, options, args): +buildpackager = BuildPackager(config) +buildpackager.fix_manifest() + def start(bundle_name=None): if bundle_name: logging.warn(bundle_name deprecated, now comes from activity.info) diff --git a/src/sugar/bundle/bundle.py b/src/sugar/bundle/bundle.py index 9e876c2..eccbe9a 100644 --- a/src/sugar/bundle/bundle.py +++ b/src/sugar/bundle/bundle.py @@ -132,7 +132,18 @@ class Bundle: zip_file.close() return True - + +def is_dir(self, filename): +if self._unpacked: +path = os.path.join(self._path, filename) +return os.path.isdir(path) +else: +zip_file = zipfile.ZipFile(self._path) +path = os.path.join(self._zip_root_dir, filename, ) +for subfile in zip_file.namelist(): +if subfile.startswith(path): +return True +return False def get_path(self): Get the bundle path. ___ Sugar mailing list Sugar@lists.laptop.org http://lists.laptop.org/listinfo/sugar
[sugar] [PATCH] #7205: bundlebuilder to work for Pippy
For review. Marcopg didn't like this patch when is_dir was hackier in the packed case (which never gets exercised), so I've fixed that part. From 8ed4af6b7197625026945c75e0296bba5c5cf961 Mon Sep 17 00:00:00 2001 From: chema [EMAIL PROTECTED](none) Date: Thu, 10 Jul 2008 13:58:12 -0600 Subject: [PATCH] 7205: bundlebuilder accepts old dist cmd, checks for po dir --- src/sugar/activity/bundlebuilder.py |8 src/sugar/bundle/bundle.py | 13 - 2 files changed, 20 insertions(+), 1 deletions(-) diff --git a/src/sugar/activity/bundlebuilder.py b/src/sugar/activity/bundlebuilder.py index 5afd78f..abe91b6 100644 --- a/src/sugar/activity/bundlebuilder.py +++ b/src/sugar/activity/bundlebuilder.py @@ -81,6 +81,10 @@ class Builder(object): def build_locale(self): po_dir = os.path.join(self.config.source_dir, 'po') +if not self.config.bundle.is_dir(po_dir): +logging.warn(Missing po/ dir, cannot build_locale) +return + for f in os.listdir(po_dir): if not f.endswith('.po'): continue @@ -214,6 +218,10 @@ def cmd_dist_xo(config, options, args): packager = XOPackager(config) packager.package() +def cmd_dist(config, options, args): +logging.warn(dist deprecated, use dist_xo.) +cmd_dist_xo(config, options, args) + def cmd_dist_source(config, options, args): packager = SourcePackager(config) packager.package() diff --git a/src/sugar/bundle/bundle.py b/src/sugar/bundle/bundle.py index 9e876c2..eccbe9a 100644 --- a/src/sugar/bundle/bundle.py +++ b/src/sugar/bundle/bundle.py @@ -132,7 +132,18 @@ class Bundle: zip_file.close() return True - + +def is_dir(self, filename): +if self._unpacked: +path = os.path.join(self._path, filename) +return os.path.isdir(path) +else: +zip_file = zipfile.ZipFile(self._path) +path = os.path.join(self._zip_root_dir, filename, ) +for subfile in zip_file.namelist(): +if subfile.startswith(path): +return True +return False def get_path(self): Get the bundle path. -- 1.5.2.5 ___ Sugar mailing list Sugar@lists.laptop.org http://lists.laptop.org/listinfo/sugar
Re: [sugar] [PATCH] Journal able to use open with for activity bundles
Here's the revised patch. May I respectfully suggest that further discussion of ancillary issues move to other threads? (I actually started another thread, and got no responses, while this one continued one more round.) Jameson diff --git a/NEWS b/NEWS index 3910546..06c5a53 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,7 @@ +84 + +* #6639 Journal can't resume activity bundles using another activity (homunq) + 80 * #5017 Correctly expose some strings to gettext. (tomeu) diff --git a/activity/activity.info b/activity/activity.info old mode 100755 new mode 100644 diff --git a/journaltoolbox.py b/journaltoolbox.py index 08b6157..c4d5bee 100644 --- a/journaltoolbox.py +++ b/journaltoolbox.py @@ -415,12 +415,13 @@ class EntryToolbar(gtk.Toolbar): for menu_item in palette.menu.get_children(): palette.menu.remove(menu_item) menu_item.destroy() - -if not self._jobject.is_activity_bundle(): -for activity in self._jobject.get_activities(): -menu_item = MenuItem(activity.name) -menu_item.set_image(Icon(file=activity.icon, icon_size=gtk.ICON_SIZE_MENU)) -menu_item.connect('activate', self._resume_menu_item_activate_cb, - activity.bundle_id) -palette.menu.append(menu_item) -menu_item.show() + +activities = self._jobject.get_activities() +for handler in activities: +menu_item = MenuItem(handler.name) +menu_item.set_image(Icon(file=handler.icon, + icon_size=gtk.ICON_SIZE_MENU)) +menu_item.connect('activate', self._resume_menu_item_activate_cb, + handler.bundle_id) +palette.menu.append(menu_item) +menu_item.show() ___ Sugar mailing list Sugar@lists.laptop.org http://lists.laptop.org/listinfo/sugar
Re: [sugar] [PATCH] Bundlebuilder use manifest, fix_manifest function
here you go. Sorry for the delay. On Tue, Jun 10, 2008 at 2:51 PM, Marco Pesenti Gritti [EMAIL PROTECTED] wrote: On Mon, Jun 9, 2008 at 7:00 PM, Jameson Chema Quinn [EMAIL PROTECTED] wrote: Here is the new version of the patch. Tell me if there are any problems applying it cleanly, and I will fix. [EMAIL PROTECTED] sugar-toolkit]$ patch -p1 /home/marco/Download/bundleMANIFEST.formarco2.patch patching file src/sugar/activity/bundlebuilder.py Hunk #5 FAILED at 113. 1 out of 6 hunks FAILED -- saving rejects to file src/sugar/activity/bundlebuilder.py.rej patching file src/sugar/bundle/activitybundle.py patching file src/sugar/bundle/bundle.py Marco ___ Sugar mailing list Sugar@lists.laptop.org http://lists.laptop.org/listinfo/sugar From 1ce15e72cfa4a5c7aca081cdeb575cad74905520 Mon Sep 17 00:00:00 2001 From: chema [EMAIL PROTECTED](none) Date: Thu, 12 Jun 2008 17:18:13 -0600 Subject: [PATCH] use MANIFEST. Deprecate bundle_name. fix_manifest(). bundlebuilder.config() cleanup. --- src/sugar/activity/bundlebuilder.py | 122 ++- src/sugar/bundle/activitybundle.py | 113 src/sugar/bundle/bundle.py | 32 - 3 files changed, 207 insertions(+), 60 deletions(-) diff --git a/src/sugar/activity/bundlebuilder.py b/src/sugar/activity/bundlebuilder.py index bf21085..d7e4bfd 100644 --- a/src/sugar/activity/bundlebuilder.py +++ b/src/sugar/activity/bundlebuilder.py @@ -23,6 +23,8 @@ import subprocess import re import gettext from optparse import OptionParser +import logging +from fnmatch import fnmatch from sugar import env from sugar.bundle.activitybundle import ActivityBundle @@ -31,10 +33,14 @@ def list_files(base_dir, ignore_dirs=None, ignore_files=None): result = [] for root, dirs, files in os.walk(base_dir): +if ignore_files: +for pattern in ignore_files: +files = [f for f in files if not fnmatch(f, pattern)] + +rel_path = root[len(base_dir) + 1:] for f in files: -if ignore_files and f not in ignore_files: -rel_path = root[len(base_dir) + 1:] -result.append(os.path.join(rel_path, f)) +result.append(os.path.join(rel_path, f)) + if ignore_dirs and root == base_dir: for ignore in ignore_dirs: if ignore in dirs: @@ -43,25 +49,27 @@ def list_files(base_dir, ignore_dirs=None, ignore_files=None): return result class Config(object): -def __init__(self, bundle_name): -self.source_dir = os.getcwd() - -bundle = ActivityBundle(self.source_dir) -version = bundle.get_activity_version() - -self.bundle_name = bundle_name -self.xo_name = '%s-%d.xo' % (self.bundle_name, version) -self.tarball_name = '%s-%d.tar.bz2' % (self.bundle_name, version) +def __init__(self, source_dir=None, dist_dir = None, dist_name = None): +self.source_dir = source_dir or os.getcwd() + +self.bundle = bundle = ActivityBundle(self.source_dir) +self.version = bundle.get_activity_version() +self.activity_name = bundle.get_name() self.bundle_id = bundle.get_bundle_id() -self.bundle_root_dir = self.bundle_name + '.activity' -self.tarball_root_dir = '%s-%d' % (self.bundle_name, version) +self.bundle_name = reduce(lambda x, y:x+y, self.activity_name.split()) -info_path = os.path.join(self.source_dir, 'activity', 'activity.info') -f = open(info_path,'r') -info = f.read() -f.close() -match = re.search('^name\s*=\s*(.*)$', info, flags = re.MULTILINE) -self.activity_name = match.group(1) +if dist_dir: +self.dist_dir = dist_dir +else: +self.dist_dir = os.path.join(self.source_dir, 'dist') + +if dist_name: +self.xo_name = self.tar_name = dist_name +else: +self.xo_name = '%s-%d.xo' % (self.bundle_name, self.version) +self.tar_name = '%s-%d.tar.bz2' % (self.bundle_name, self.version) +self.bundle_root_dir = self.bundle_name + '.activity' +self.tar_root_dir = '%s-%d' % (self.bundle_name, self.version) class Builder(object): def __init__(self, config): @@ -71,6 +79,10 @@ class Builder(object): self.build_locale() def build_locale(self): +if not self.config.bundle.is_dir('po'): +logging.warn(Activity lacks a po directory for translations) +return + po_dir = os.path.join(self.config.source_dir, 'po') for f in os.listdir(po_dir): @@ -101,54 +113,74 @@ class Builder(object): class Packager(object): def __init__(self, config): self.config = config -self.dist_dir = os.path.join(self.config.source_dir, 'dist
Re: [sugar] [PATCH] Journal able to use open with for activity bundles
re open with, etc. In English, I think the best construction is verb preposition this, where verb is usually but not always the activity name, and preposition is activity-specific. Paint on this, rewrite this, read this, browse from this, etc. With the icon as an extra clue to meaning. In general, the phrase will not be able to just use the activity name - to begin with, verbs in other languages need conjugation whereas the activity name will be infinitive. So I think that this should be another line in activity.info, and there should be no %s for munging in the this (in some languages, this could change depending on the surrounding words, like a/an in English). If the activity-specific string is missing from activity.info, Glucose should default to (%s with this % activityname). ___ Sugar mailing list Sugar@lists.laptop.org http://lists.laptop.org/listinfo/sugar
[sugar] bundles and parts (was Re: [PATCH] Journal able to use open with for activity bundles)
The objects and translators model, as described, does not have any easy way to retar a bundle; nor is it easy to figure out how to assign different mime types to different kinds of tar files (this one is a web page, that one is an activity bundle). Note that the rebundle problem is not so trivial - what do you do with the metadata on the subfiles? Let me try to sketch out the problem of bundles, with everything a good solution should enable. 1. In journal, the most default view shows only bundles, is not cluttered with all subfiles. 2. Bundles have their own metadata, and a mime-type that reflects their holistic nature (a set of photos, a web page, an activity) 3. Subfiles inherit (some?) bundle metadata, but can also have their own metadata. 4. Some subfiles, which make no sense on their own, are hidden by default (dotted files) 5. Possible to grab a piece of a bundle and start treating it as a separate top-level object. 6. Possible to edit a piece of a bundle as if it were a top-level object, yet keep it as part of the bundle. This creates a new version of the whole bundle, with the edited file. 7. Possible to take a top-level object and add it to a bundle. 8. Possible to remove (delete) an object from a bundle. 9. Possible to import/ export bundles as single files (zip/tar) to external media/over the net 10. Possible to import/export bundles as directories to external media. 11. For easier porting of legacy apps: ability to open a subfile in context, with the directory structure of the bundle extracted, so that relative paths work. ... I think it is clear from the above list that moving back and forth from bundle to file view should be as transparent as possible. Internal storage could be as separate files or as zipped/tarred groups; either way, there would need to be a storage of stubs/pointers to stand in for the other model. Here's one proposal to kick things off: External format: metadata for a traditional file is represented on external media by an invisible file in the same directory, with a related name, which contains json. bundles are represented on external media by a zip, which politely extracts itself to a subdirectory. metadata for bundles is represented by an invisible file next to the zip. This file is a zip which extracts to the same subdirectory, putting global metadata in an invisible file in the root, and subfile metadata in dotfiles as above. Internal format: Same as external format. Glucose knows how to unpack and repack the bundles. There is no pretense that Glucose maintains any integrity/signatures for the bundles. When editing as in option 6 above, the bundle is extracted (see option 11 above) and then repacked on *each save* of the subfile. Each non-hidden subfile is also represented by a metadata-only datastore pointer into the bundle, for journal searches. Note: this proposal is less than ideal in some ways. For one instance: small changes to large files inside a zip are not good for delta-based storage. For another, zip has no way to include empty directories, which might be important for directory structure in some legacy cases. It assumes relatively large atomic saves in any subfile. Jameson On Wed, Jun 11, 2008 at 9:37 AM, Benjamin M. Schwartz [EMAIL PROTECTED] wrote: -BEGIN PGP SIGNED MESSAGE- Hash: SHA1 I have a proposal for how to manage objects in the datastore, to resolve the various issues we have discussed. I call it the Objects and Translators model. The fundamental idea is this: the datastore is a flat, non-hierarchical listing of objects (versioned, but that does not come into play here). The datastore provides these objects for use by Activities. However, the datastore (or perhaps the Journal) also contains a new element: Translators. A Translator is a non-interactive object processing machine that takes an object as input and returns a set of objects as output. Each Translator has a specified set of input types on which it can act. The user, having selected a particular object, should be provided with a list of all compatible Translators. Clicking on a Translator should show the list of output objects that Translator would generate for this input object, and the user may repeat this process on each of those objects as well. This model allows us to reproduce the usual sorts of directory hierarchies, simply by using a group object (I think of it as a .tar file) and an untar Translator. To the user, this looks very much like a directory hierarchy. However, because each directory is in fact a first-class object, it can also be associated with Activity instances, or passed from one XO to another over the network, etc. The Translator system is appealing to me because it can provide far more than a simple storage hierarchy. For example, I have often had to extract a particular image from a PDF file, in order to include it in a class project. I, and most people, have done this by blowing up the image and
Re: [sugar] Avoid duplicates in the bundle registry
Let me try to sketch out the plan understand and interpret it from http://wiki.laptop.org/go/User:Mstone/Commentaries/Bundles_1. (episode 2 was more about how to handle the files/bundles or objects/actions distinction, which is farther off). 1. in the future, object ID will just be a hash of the non-human-readable signing key for an activity. 1.a) this will not change over minor version changes. It may not change over major version changes, or, if author intends bugfix releases of the old version, it may deliberately change. If there is a discontinuity in authorship (key lost) it must change. 1.a)1)when we have signatures, hash collisions will be assumed to be a deliberate attack, and will just refuse to install. b) for right now, we can just use object ID. 2. Within each object ID, there can be any number of versions simultaneously installed. 2.a) just id/version is not unique, for instance if an activity is under active development on that machine. 2.a)i) An idea of mine, not discussed yet: we actually could try to enforce the idea that any two activities which match on {id,version,bool(has valid signature)} are interchangeable - just silently use the first one seen for bundles with a valid signature (release versions), and the last one seen for b. without v.s. (development versions. 2.b)Even if we can get some combination of data (besides just hashing the whole bundle) that is unique, or if we make a pre-signature approximation that id/version is unique, there will still be a large potential for clutter. 3. Which one to use? 3a) Each journal object will have metadata with all identifying data (id, version, sig?, hash) of the last activity. 3b) For some activity ids, there will be (at most) one starred version. 3c) Journal objects will open by default with {own id, max(starred version, own version)}, or if that is unavailable starred version, or if that is unavailable latest version. 3d) Unstarred id's can still be grouped/collapsed in the activity list. 3d) imported objects will open by default with starred or latest version 4. Garbage collection of old installed versions (this patch) 4a) Any versions older than starred version are eligible for GC. 4b) Suggestion (not discussed): Grace period to notice broken features: When starred version changes, garbage collection on that ID is frozen until the new starred version has been used at least 3 times. 4c) Suggestion: Suggested updates: First time quitting a version newer than starred version, ask user if they want to move the star. 4d) Suggestion: when you see a shared activity in the mesh, some UI hint to show if it is newer/older/same version as your starred/latest version. (also, see imposing changelogs in the discussion) ... As an aside, I think that it is a mistake to impose integer versions. I think that a general n-number versioning system, with a hyphen as a separator (to avoid the 1.10 problem), but Glucose only understands the ordering and makes no distinction between major and minor version. This would support integers, major-minor, major-minor-bugfix, or other similar systems, without imposing one. Jameson ___ Sugar mailing list Sugar@lists.laptop.org http://lists.laptop.org/listinfo/sugar
Re: [sugar] [PATCH] Journal able to use open with for activity bundles
This change fixes a bug: journal is unable to do anything but start a bundle, even if you have an activity (Develop) which can handle the activity bundle mime type. The immediate question is: should start be available only by pressing the button, or should it also be an option in the pulldown? I think that the answer is an obvious yes. The longer term question is: should start always be the default for bundles, or should it be possible to have a bundle whose default action is Develop? However, discussion on this larger question should not block approving the immediate patch. On Tue, Jun 10, 2008 at 10:02 AM, Eben Eliason [EMAIL PROTECTED] wrote: I'm confused, actually. We already have Start as the first option in the palette for raw activities, and as the action listed on the button in the detail view. What is the intent for the change being discussed here? - Eben On Tue, Jun 10, 2008 at 5:57 AM, Tomeu Vizoso [EMAIL PROTECTED] wrote: (sorry about the big delay) On Wed, May 28, 2008 at 9:44 PM, Jameson Chema Quinn [EMAIL PROTECTED] wrote: On Wed, May 28, 2008 at 12:16 PM, Tomeu Vizoso [EMAIL PROTECTED] wrote: Hi, +if self._jobject.is_activity_bundle(): +menu_item = MenuItem(_('Start')) +menu_item.connect('activate', self._resume_menu_item_activate_cb, + None) +palette.menu.append(menu_item) +menu_item.show() Why are we adding a Start menu item? How is it different from clicking on the button? We add a start menu item in case there is a choice to run or open with; if there are choices, they should all be listed, even if one is available in a simpler way (by just clicking). Also note that I plan, in the future, to make the default behavior (clicking on the button) configurable using metadata, so that you can have some bundles which are for editing. Eben, can you comment on this UI change? Thanks, Tomeu ___ Sugar mailing list Sugar@lists.laptop.org http://lists.laptop.org/listinfo/sugar ___ Sugar mailing list Sugar@lists.laptop.org http://lists.laptop.org/listinfo/sugar
Re: [sugar] [PATCH] Journal able to use open with for activity bundles
On Tue, Jun 10, 2008 at 12:21 PM, Eben Eliason [EMAIL PROTECTED] wrote: On Tue, Jun 10, 2008 at 2:16 PM, Jameson Chema Quinn [EMAIL PROTECTED] wrote: This change fixes a bug: journal is unable to do anything but start a bundle, even if you have an activity (Develop) which can handle the activity bundle mime type. Right, this merits the possible addition of a Start as (wording?) type menu. The immediate question is: should start be available only by pressing the button, or should it also be an option in the pulldown? I think that the answer is an obvious yes. I'm stating that Start is /already/ an option in the pulldown, so what's the point of argument? This is the details view pulldow. Look at the patch: - -if not self._jobject.is_activity_bundle(): -for activity in self._jobject.get_activities(): -menu_item = MenuItem(activity.name) -menu_item.set_image(Icon(file=activity.icon, icon_size=gtk.ICON_SIZE_MENU)) -menu_item.connect('activate', self._resume_menu_item_activate_cb, - activity.bundle_id) -palette.menu.append(menu_item) -menu_item.show() + +if self._jobject.is_activity_bundle(): +menu_item = MenuItem(_('Start')) +menu_item.connect('activate', self._resume_menu_item_activate_cb, + None) +palette.menu.append(menu_item) +menu_item.show() +activities = self._jobject.get_activities() +for activity in activities: +menu_item = MenuItem(activity.name) +menu_item.set_image(Icon(file=activity.icon, icon_size=gtk.ICON_SIZE_MENU)) +menu_item.connect('activate', self._resume_menu_item_activate_cb, + activity.bundle_id) +palette.menu.append(menu_item) +menu_item.show() Instead of only constructing a pulldown for non-activity-bundles, it does one for both. It first includes an option to start for activity bundles, then continues with the normal logic which gives options of all activities which handle the relevant MIME. I submit that this should not be controversial, that the controversy here comes from misunderstanding. ___ Sugar mailing list Sugar@lists.laptop.org http://lists.laptop.org/listinfo/sugar
Re: [sugar] [PATCH] Journal able to use open with for activity bundles
On Tue, Jun 10, 2008 at 2:30 PM, Eben Eliason [EMAIL PROTECTED] wrote: Actually, I disagree with adding Start separately to the secondary palette as this will appear redundant beneath the already existing Start label in the primary palette. The better solution (and I think, the expected behavior) is to make the primary palette clickable when the palette is anchored, such that clicking it enacts the action of the button it is attached to. I agree that this is how palettes should work (of course, not the issue here). However, I don't understand your opposition to repeating the start option in the submenu. Any journal item already repeats the default option in this list; doing the same for activity bundles is only consistent. If we are going to change this, it is a separate patch. Regarding the other options, I think it would be clearer (albeit, admittedly, slightly more indirect) to place the list of available activities in a submenu labeled Start with to convey the action that selecting an activity will take. This would be true of the submenu regardless of whether or not the entry represents a bundle, leaving us in a state where the only difference between bundles and instances is the phrasing used within the menu. Otherwise, they are functionally identical. This is not a bad idea. Again, if you are serious about this, we should prioritize it and do it, as a separate patch; and I'd be happy to work through the options with you, in a separate thread. Jameson ___ Sugar mailing list Sugar@lists.laptop.org http://lists.laptop.org/listinfo/sugar
Re: [sugar] [PATCH] Journal able to use open with for activity bundles
Sorry, I am stuck in windows land today, so I cannot confirm anything. I will respond based on how I recall things, and I'm pretty sure, but cannot vouch 100% for what I will say here. On Tue, Jun 10, 2008 at 3:02 PM, Eben Eliason [EMAIL PROTECTED] wrote: On Tue, Jun 10, 2008 at 4:43 PM, Jameson Chema Quinn [EMAIL PROTECTED] wrote: On Tue, Jun 10, 2008 at 2:30 PM, Eben Eliason [EMAIL PROTECTED] wrote: Actually, I disagree with adding Start separately to the secondary palette as this will appear redundant beneath the already existing Start label in the primary palette. The better solution (and I think, the expected behavior) is to make the primary palette clickable when the palette is anchored, such that clicking it enacts the action of the button it is attached to. I agree that this is how palettes should work (of course, not the issue here). However, I don't understand your opposition to repeating the start option in the submenu. Any journal item already repeats the default option in this list; doing the same for activity bundles is only consistent. If we are going to change this, it is a separate patch. Could you please clarify exactly what it is you are trying to do, and exactly what parts of the GUI it's affecting? I've taken two stabs at this, and it seems neither are correct. I read the code, but I don't know what context it sits in. The secondary palettes that appear for activity icons (bundle or instance) all contain a Start or Resume option, respectively. The button in the toolbar of the detail view reads either Start or Resume, also as appropriate. None of the secondary palettes anywhere in the system repeat the default action of the button within the secondary palette, as far as I'm aware, as this would be redundant. (It would be even more redundant (in other words, functionally, instead of only visually) if the primary palette were clickable.) This patch is for the secondary palette on the start/resume button on the details view. Say you have a picture you made in Paint. You'd have an arrow button in details, primary palette resume (= Paint), secondary palette Paint or TuxPaint. This is not verbally redundant, but is obviously redundant in the sense that one of the options in the secondary palette is equivalent to the simple button push. It is this redundancy that I was copying, as my feelings were that inconsistency would be confusing, and that intuitive accessibility is a higher priority than non-redundancy. If you disagree, I am not really attached to this idea. I just didn't realize it was controversial (and clung to that blind-spot even when it meant assuming you misunderstood). I'd vote for redundancy, but it is a weak vote. (BTW: again, I have no way to test this right now, but I think that the journal list view item palettes are also redundant. Don't the secondary palettes have options for run, copy, delete? And run is the same as just clicking the object's icon? BTBTW: This is actually a place where a nested open with menu makes even more sense, and I could write such a patch if this one clears.) ___ Sugar mailing list Sugar@lists.laptop.org http://lists.laptop.org/listinfo/sugar
Re: [sugar] [PATCH] Journal able to use open with for activity bundles
On Tue, Jun 10, 2008 at 4:28 PM, Eben Eliason [EMAIL PROTECTED] wrote: On Tue, Jun 10, 2008 at 6:01 PM, Jameson Chema Quinn [EMAIL PROTECTED] wrote: Sorry, I am stuck in windows land today, so I cannot confirm anything. I will respond based on how I recall things, and I'm pretty sure, but cannot vouch 100% for what I will say here. On Tue, Jun 10, 2008 at 3:02 PM, Eben Eliason [EMAIL PROTECTED] wrote: On Tue, Jun 10, 2008 at 4:43 PM, Jameson Chema Quinn [EMAIL PROTECTED] wrote: On Tue, Jun 10, 2008 at 2:30 PM, Eben Eliason [EMAIL PROTECTED] wrote: Actually, I disagree with adding Start separately to the secondary palette as this will appear redundant beneath the already existing Start label in the primary palette. The better solution (and I think, the expected behavior) is to make the primary palette clickable when the palette is anchored, such that clicking it enacts the action of the button it is attached to. I agree that this is how palettes should work (of course, not the issue here). However, I don't understand your opposition to repeating the start option in the submenu. Any journal item already repeats the default option in this list; doing the same for activity bundles is only consistent. If we are going to change this, it is a separate patch. Could you please clarify exactly what it is you are trying to do, and exactly what parts of the GUI it's affecting? I've taken two stabs at this, and it seems neither are correct. I read the code, but I don't know what context it sits in. The secondary palettes that appear for activity icons (bundle or instance) all contain a Start or Resume option, respectively. The button in the toolbar of the detail view reads either Start or Resume, also as appropriate. None of the secondary palettes anywhere in the system repeat the default action of the button within the secondary palette, as far as I'm aware, as this would be redundant. (It would be even more redundant (in other words, functionally, instead of only visually) if the primary palette were clickable.) This patch is for the secondary palette on the start/resume button on the details view. Say you have a picture you made in Paint. You'd have an arrow button in details, primary palette resume (= Paint), secondary palette Paint or TuxPaint. This is not verbally redundant, but is obviously redundant in the sense that one of the options in the secondary palette is equivalent to the simple button push. It is this redundancy that I was copying, as my feelings were that inconsistency would be confusing, and that intuitive accessibility is a higher priority than non-redundancy. If you disagree, I am not really attached to this idea. I just didn't realize it was controversial (and clung to that blind-spot even when it meant assuming you misunderstood). I'd vote for redundancy, but it is a weak vote. I see. Well I think I vote against it in the current implementation, actually, since the redundancy (side by side, no less) could actually be confusing (which one do I want!? what's the difference!?). My first instinct was to think that it might be OK if we used a submenu, to clarify the action more as I mentioned before. After considering this, however, I find that it's actually much clearer /not/ to do that. The reason that Paint is repeated (as per your example) is that the Paint instance can be resumed by Paint, or other supporting activities. Including Paint itself in the list provides clarification of the action by revealing the name of the default activity, which otherwise wasn't revealed. We could take a hint from Apple and append (default) to the first in the list, with a separator, to make this more evident. On the other hand, an activity bundle (not an instance) can be started, or resumed by another supporting activity. Opening the bundle as an object with another activity is actually a very different action from starting a new instance of it. The former creates a new version of the bundle in the same thread. The latter creates a new instance/entry in the Journal in it's own brand new thread. I think we should do without the redundant Start option in the menu. I think this is still consistent with the other entries: You either create a new instance of the activity, or you open the bundle (as an object) with some other activity. You don't in general open the bundle (as an object) with itself (eg. you start a new painting...you don't open the paint bundle in Paint). The exception to the rule is an activity like Develop, which can indeed open itself. However, that will be handled naturally by the system, since Develop claims to handle the bundle type already. This is still very different from saying Start, which would create an /emtpy/ develop project; it would instead open up to reveal the source code
Re: [sugar] [PATCH] Bundlebuilder use manifest, fix_manifest function
Some quick responses, before I dig into this... On Sun, Jun 8, 2008 at 4:08 AM, Marco Pesenti Gritti [EMAIL PROTECTED] wrote: -import subprocess +from subprocess import Popen, PIPE import re import gettext from optparse import OptionParser +import warnings +import subprocess warnings seem unused, doesn't pylint warn you about it? Brain fart. I read pylint output, said OK, there are warnings about unused imports, but which unused imports? :) Actually, this is fixed in later patches I sent. Will fix. Since you are importing subprocess just use that for Popen and PIPE. +from sugar.bundle.activitybundle import ActivityBundle, MANIFEST, list_files It doesn't make sense for activitybundle to expose something a generic as list_files, especially since you are just using it to walk files inside that module. So I should duplicate the code of list_files? (This is my biggest question with your response) I think the MANIFEST definition is overkill and you are using it inconsistently anyway. Just use the string. As the number of metadata files in the activity format grows, it seems likely that eventually we'll give them their own directory. Making this a global now is the first step to being able to change it later. But if you prefer, I'll use a string for now. +def __init__(self, bundle_name, source_dir=None, dist_dir = None, + dist_name = None): As I explained in my previous mail, I want to keep passing in the config here. Please remove the extra params. disagree a bit, but will do. +def fix_manifest(self): +allfiles = list_files(self.config.source_dir, + ignore_dirs=['dist', '.git'], + ignore_files=['.gitignore', 'MANIFEST', +'*.pyc', '*~', '*.bak']) +for afile in allfiles: +if afile not in self.config.bundle.manifest: +self.config.bundle.manifest.append(afile) +manifestfile = open(os.path.join(self.config.source_dir, + MANIFEST), +wb) +for line in self.config.bundle.manifest: +manifestfile.write(line + \n) This is all really hard to read. Some suggestions: * Split the ignore lists out of the list_files call. * We are never using aX for list iteration in the code. Just use f or filename there. * Do a manifest = self.config.bundle.manifest, you are repeating it 3 times * s/manifestfile/manifest so that it feet in one line and you don't need the crazy split up. * Add a \n after manifestfile = open... will do def get_files(self): -return list_files(self.config.source_dir, - ignore_dirs=['locale', 'dist', '.git'], - ignore_files=['.gitignore']) +git_ls = Popen('git-ls-files', stdout=PIPE, cwd=self.config.source_dir) +if git_ls.wait(): +#non-0 return code - failed +return BuildPackager.get_files(self) +f = git_ls.stdout +files = [] +for line in f.readlines(): +filename = line.strip() +if not filename.startswith('.'): +files.append(filename) +f.close() +return files Please separate groups of code with \n to make it more readable. I don't think this comment is necessary #non-0 return code - failed, it's obvious if you ever used Popen. will do +from sugar import activity +from sugar import env Unless you have a concrete need for this please drop it from the patch. To fix it properly I think we need to really cleanup the dependencies. But that's another patch. will do +def _is_dir(self, filename): +def _is_file(self, filename): As you did in your last patch remove the _ will do +def install(self): I don't think installation should be expose by ActivityBundle, we need to cleanup the dependencies. Let's remove it from this patch and we can discuss how to do it properly install was already exposed, I just refactored unpack out of it (and thus also exposed unpack). This only showed up in the patch because I put unpack first, and the body of unpack matched with that part of the body of install. I'm pretty sure this function is used by Journal, we can't just drop it. +try: +f = self._get_file(MANIFEST) +except IOError: +f = None +if not f: +logging.warning(Activity directory lacks a MANIFEST file.) +return [] All the other code which uses _get_file, assumes it will just return None if there is an IOError. Seems easier to just change the method to really do so (if it doesn't already). Will do. +#strip trailing \n and other whitespace I think this comment is unnecessary, it's implicit in the definition of the strip function. Will do. I
Re: [sugar] [PATCH] Bundlebuilder use manifest, fix_manifest function
Here is the revised patch. It has your suggested changes, plus a couple more: - Check for existence of po directory in Builder - Config.__init__() is cleaned up. Now gets bundle name from activity.info. start() no longer needs a bundle name, and has deprecation warning. Also I put things in a more logical order. On Sun, Jun 8, 2008 at 7:11 AM, Marco Pesenti Gritti [EMAIL PROTECTED] wrote: On Sun, Jun 8, 2008 at 1:59 PM, Jameson Chema Quinn [EMAIL PROTECTED] wrote: It doesn't make sense for activitybundle to expose something a generic as list_files, especially since you are just using it to walk files inside that module. So I should duplicate the code of list_files? (This is my biggest question with your response) Unless I'm missing something you won't really duplicate much of it, since you are not using the ignore_* which are the big part of the code and the actual purpose of that function. You will basically just need the for... I think the MANIFEST definition is overkill and you are using it inconsistently anyway. Just use the string. As the number of metadata files in the activity format grows, it seems likely that eventually we'll give them their own directory. Making this a global now is the first step to being able to change it later. But if you prefer, I'll use a string for now. If you move it to a directory you will better construct to the path with os.path.join, so it would probably be a method of Bundle. Anyway I don't think it's worth to worry about that yet, it's easy enough to refactor if/when necessary. +def __init__(self, bundle_name, source_dir=None, dist_dir = None, + dist_name = None): As I explained in my previous mail, I want to keep passing in the config here. Please remove the extra params. disagree a bit, but will do. Just look at all the ugly None checks you need to do to support it... :) +def install(self): I don't think installation should be expose by ActivityBundle, we need to cleanup the dependencies. Let's remove it from this patch and we can discuss how to do it properly install was already exposed, I just refactored unpack out of it (and thus also exposed unpack). This only showed up in the patch because I put unpack first, and the body of unpack matched with that part of the body of install. I'm pretty sure this function is used by Journal, we can't just drop it. You are right, That's ok then. Thanks, Marco ___ Sugar mailing list Sugar@lists.laptop.org http://lists.laptop.org/listinfo/sugar diff --git a/src/sugar/activity/bundlebuilder.py b/src/sugar/activity/bundlebuilder.py index 1063f72..c16845d 100644 --- a/src/sugar/activity/bundlebuilder.py +++ b/src/sugar/activity/bundlebuilder.py @@ -19,53 +19,52 @@ import os import zipfile import tarfile import shutil -import subprocess import re import gettext from optparse import OptionParser +import subprocess +import logging from sugar import env from sugar.bundle.activitybundle import ActivityBundle +IGNORE_DIRS=['dist', '.git'], +IGNORE_FILES=['.gitignore', 'MANIFEST', '*.pyc', '*~', '*.bak'] + def list_files(base_dir, ignore_dirs=None, ignore_files=None): result = [] - + for root, dirs, files in os.walk(base_dir): for f in files: -if ignore_files and f not in ignore_files: +if not (ignore_files and +[True for pat in ignore_files if fnmatch(f,pat)]): +#not (result matches a pattern in ignore_files, ignore it) rel_path = root[len(base_dir) + 1:] result.append(os.path.join(rel_path, f)) if ignore_dirs and root == base_dir: for ignore in ignore_dirs: if ignore in dirs: dirs.remove(ignore) - return result class Config(object): -def __init__(self, bundle_name, source_dir=None): -if source_dir: -self.source_dir = source_dir -else: -self.source_dir = os.getcwd() +def __init__(self, source_dir=None, dist_path = ): +self.source_dir = source_dir or os.getcwd() - -bundle = ActivityBundle(self.source_dir) -version = bundle.get_activity_version() - -self.bundle_name = bundle_name -self.xo_name = '%s-%d.xo' % (self.bundle_name, version) -self.tarball_name = '%s-%d.tar.bz2' % (self.bundle_name, version) +self.bundle = bundle = ActivityBundle(self.source_dir) +self.version = bundle.get_activity_version() +self.activity_name = bundle.get_name() self.bundle_id = bundle.get_bundle_id() +self.bundle_name = reduce(lambda x, y:x+y, self.activity_name.split()) + +dist_dir, dist_name = os.path.split(dist_path) +self.dist_dir = dist_dir or os.path.join(self.source_dir, 'dist') +self.xo_name = dist_name or '%s-%d.xo
Re: [sugar] [PATCH] Bundlebuilder use manifest, fix_manifest function
I'm away from my machine, but quick response, I'll say more later. On Sat, Jun 7, 2008 at 6:51 AM, Marco Pesenti Gritti [EMAIL PROTECTED] wrote: I'm still getting a few pylint errors, you don't?. I was just getting defined outside of __init__ for ActivityBundle.manifest ... I don't know how I'm supposed to fix that, since it is defined from a subroutine of __init__ that is also useful elsewhere. Also can you please answer the question/notes I posted before I go ahead an do a full review? OK, here: * Please run pylint on the changed files. You can use sugar-jhbuild/scripts/data /pylintrc. That will catch several problems and nitpicks that I'd ask you to fix anyway. Done, I think, I will check again later. * I dont understand all the warnings.warn(MalformedBundleException(...)). What's the purpose of those. Shouldn't they be real exceptions? What's the advantage of using the warnings module over logging.warning? fixed in the patch I reposted * I'm not sure what you are using dest_dir for, but it looks like it should be part of Config. again, fixed. * Why are you moving the activity and env imports inline. I answered that in my previous email: to make it easier to use these files without having the rest of Sugar installed. ___ Sugar mailing list Sugar@lists.laptop.org http://lists.laptop.org/listinfo/sugar
Re: [sugar] [PATCH] Bundlebuilder use manifest, fix_manifest function
bundleManifest.all2.patch /*here*/ = (bundleMANIFEST.patch + bundleManifest.subpatch + bundleMANIFEST.sub2.patch /*here*/) bundleMANIFEST.sub2.patch makes bundle.Bundle.is_file public, makes version an attribute of bundlebuilder.RawActivity (and all children), and fixes a minor versioning bug in cmd_release. On Sat, Jun 7, 2008 at 7:54 PM, Jameson Chema Quinn [EMAIL PROTECTED] wrote: oops, I left out the more complete patch. As I said, bundleManifest.all.patch /*here*/ = (bundleMANIFEST.patch /*15K, included in msg 3 of this thread*/ + bundleManifest.subpatch /*included in previous message*/) diff --git a/src/sugar/activity/bundlebuilder.py b/src/sugar/activity/bundlebuilder.py index 1063f72..1b682a2 100644 --- a/src/sugar/activity/bundlebuilder.py +++ b/src/sugar/activity/bundlebuilder.py @@ -19,64 +19,45 @@ import os import zipfile import tarfile import shutil -import subprocess +from subprocess import Popen, PIPE import re import gettext from optparse import OptionParser +import subprocess +import logging from sugar import env -from sugar.bundle.activitybundle import ActivityBundle - -def list_files(base_dir, ignore_dirs=None, ignore_files=None): -result = [] - -for root, dirs, files in os.walk(base_dir): -for f in files: -if ignore_files and f not in ignore_files: -rel_path = root[len(base_dir) + 1:] -result.append(os.path.join(rel_path, f)) -if ignore_dirs and root == base_dir: -for ignore in ignore_dirs: -if ignore in dirs: -dirs.remove(ignore) - -return result - -class Config(object): -def __init__(self, bundle_name, source_dir=None): -if source_dir: -self.source_dir = source_dir -else: -self.source_dir = os.getcwd() - - -bundle = ActivityBundle(self.source_dir) -version = bundle.get_activity_version() +from sugar.bundle.activitybundle import ActivityBundle, MANIFEST, list_files -self.bundle_name = bundle_name -self.xo_name = '%s-%d.xo' % (self.bundle_name, version) -self.tarball_name = '%s-%d.tar.bz2' % (self.bundle_name, version) +class RawActivity(object): +def __init__(self, source_dir=None, dist_path = ): +self.source_dir = source_dir or os.getcwd() + +self.bundle = bundle = ActivityBundle(self.source_dir) +self.version = bundle.get_activity_version() +self.activity_name = bundle.get_name() self.bundle_id = bundle.get_bundle_id() +self.bundle_name = reduce(lambda x, y:x+y, self.activity_name.split()) + +dist_dir, dist_name = os.path.split(dist_path) +self.dist_dir = dist_dir or os.path.join(self.source_dir, 'dist') +self.xo_name = dist_name or '%s-%d.xo' % (self.bundle_name, + self.version) +self.tarball_name = (dist_name or + '%s-%d.tar.bz2' % (self.bundle_name, +self.version)) self.bundle_root_dir = self.bundle_name + '.activity' -self.tarball_root_dir = '%s-%d' % (self.bundle_name, version) - -info_path = os.path.join(self.source_dir, 'activity', 'activity.info') -f = open(info_path,'r') -info = f.read() -f.close() -match = re.search('^name\s*=\s*(.*)$', info, flags = re.MULTILINE) -self.activity_name = match.group(1) - -class Builder(object): -def __init__(self, config): -self.config = config - +self.tarball_root_dir = '%s-%d' % (self.bundle_name, self.version) + +class Builder(RawActivity): def build(self): self.build_locale() def build_locale(self): -po_dir = os.path.join(self.config.source_dir, 'po') - +if not self.bundle.is_dir('po'): +logging.warn(Activity lacks a po directory for translations) +return +po_dir = os.path.join(self.source_dir, 'po') for f in os.listdir(po_dir): if not f.endswith('.po'): continue @@ -84,78 +65,92 @@ class Builder(object): file_name = os.path.join(po_dir, f) lang = f[:-3] -localedir = os.path.join(self.config.source_dir, 'locale', lang) +localedir = os.path.join(self.source_dir, 'locale', lang) mo_path = os.path.join(localedir, 'LC_MESSAGES') if not os.path.isdir(mo_path): os.makedirs(mo_path) -mo_file = os.path.join(mo_path, %s.mo % self.config.bundle_id) +mo_file = os.path.join(mo_path, %s.mo % self.bundle_id) args = [msgfmt, --output-file=%s % mo_file, file_name] retcode = subprocess.call(args) if retcode: print 'ERROR - msgfmt failed with return code %i.' % retcode cat = gettext.GNUTranslations(open(mo_file, 'r
Re: [sugar] [PATCH] Bundlebuilder use manifest, fix_manifest function
Changes: bundle.py Added zip-agnostic _is_file() method to bundle class; used in activitybundle for checking MANIFEST without unpacking activitybundle.py Moved basic logic for processing MANIFEST, including list_files, to activitybundle.py ; this is necessary for checking when installing a bundle. moved dependencies on activity registry and env to inline imports in relevant methods; some bundle tasks should be doable with just these three files. (This is doing only half of the job, the other half would be falling back to importing the other modules not as submodules). some simple globbing in list_files for ignored files, to allow ignoring *.pyc. reads manifest into a list of lines; then replaces invalid lines in place with blank lines. This allows fix_manifest in bundlebuilder to leave all existing files on same MANIFEST line number, which will help with diffs later. separate unpack from install (= unpack + register). Unpack checks for valid MANIFEST but is set to only complain, not throw exceptions, by default, to give folks time to clean up. bundlebuilder.py: fix_manifest function rewrites MANIFEST file. SourcePackager.get_files calls out to git to get file names, or falls back to MANIFEST otherwise. On Fri, Jun 6, 2008 at 1:24 PM, Marco Pesenti Gritti [EMAIL PROTECTED] wrote: On Fri, Jun 6, 2008 at 6:13 PM, Jameson Chema Quinn [EMAIL PROTECTED] wrote: Note: this patch does not expose the fix_manifest function when running bundlebuilder as a script. That would be a 2 or 3 line patch, seperately. Some initial notes: * Please run pylint on the changed files. You can use sugar-jhbuild/scripts/data/pylintrc. That will catch several problems and nitpicks that I'd ask you to fix anyway. * I dont understand all the warnings.warn(MalformedBundleException(...)). What's the purpose of those. Shouldn't they be real exceptions? What's the advantage of using the warnings module over logging.warning? * I'm not sure what you are using dest_dir for, but it looks like it should be part of Config. * Why are you moving the activity and env imports inline. As we discussed in irc, it would be good to split up patches. But anyway in the case of big patches like this, containing unrelated changes is good to provide a list of the changes you made and the reason you made them (can you provide such list when you resubmit the patch with pylint fixed? Thanks!). Marco ___ Sugar mailing list Sugar@lists.laptop.org http://lists.laptop.org/listinfo/sugar diff --git a/src/sugar/activity/bundlebuilder.py b/src/sugar/activity/bundlebuilder.py index 1063f72..3c8f7dc 100644 --- a/src/sugar/activity/bundlebuilder.py +++ b/src/sugar/activity/bundlebuilder.py @@ -19,46 +19,36 @@ import os import zipfile import tarfile import shutil -import subprocess +from subprocess import Popen, PIPE import re import gettext from optparse import OptionParser +import warnings +import subprocess from sugar import env -from sugar.bundle.activitybundle import ActivityBundle - -def list_files(base_dir, ignore_dirs=None, ignore_files=None): -result = [] +from sugar.bundle.activitybundle import ActivityBundle, MANIFEST, list_files -for root, dirs, files in os.walk(base_dir): -for f in files: -if ignore_files and f not in ignore_files: -rel_path = root[len(base_dir) + 1:] -result.append(os.path.join(rel_path, f)) -if ignore_dirs and root == base_dir: -for ignore in ignore_dirs: -if ignore in dirs: -dirs.remove(ignore) - -return result class Config(object): -def __init__(self, bundle_name, source_dir=None): -if source_dir: -self.source_dir = source_dir -else: -self.source_dir = os.getcwd() +def __init__(self, bundle_name, source_dir=None, dist_dir = None, + dist_name = None): +self.source_dir = source_dir or os.getcwd() +self.dist_dir = dist_dir or os.path.join(self.source_dir, 'dist') bundle = ActivityBundle(self.source_dir) version = bundle.get_activity_version() +self.bundle = bundle self.bundle_name = bundle_name -self.xo_name = '%s-%d.xo' % (self.bundle_name, version) -self.tarball_name = '%s-%d.tar.bz2' % (self.bundle_name, version) +self.xo_name = dist_name or '%s-%d.xo' % (self.bundle_name, version) +self.tarball_name = (dist_name or + '%s-%d.tar.bz2' % (self.bundle_name, version)) self.bundle_id = bundle.get_bundle_id() self.bundle_root_dir = self.bundle_name + '.activity' self.tarball_root_dir = '%s-%d' % (self.bundle_name, version) + info_path = os.path.join(self.source_dir, 'activity', 'activity.info') f = open(info_path,'r') @@ -105,48 +95,65 @@ class Builder(object): class Packager(object
Re: [sugar] Preparing for the feature freeze
It is proving hard for me to get consensus on the new bundle format, but I hope that I can do so soon enough to get some forward-compatibility patches in. Right now, I think that that would be: allow tar as well as zip bundles (though zip bundles would remain the norm for now) allow multiple installed versions of a bundle (activity registry by hash, version, and key/thread/bundle id) metadata to associate journal entries with correct version of bundle. (The signature stuff may or may not be ready to include in this list, but is not as urgent for forward-compatibility purposes.) On Tue, Jun 3, 2008 at 11:29 AM, Marco Pesenti Gritti [EMAIL PROTECTED] wrote: On Tue, Jun 3, 2008 at 7:20 PM, Erik Garrison [EMAIL PROTECTED] wrote: On Tue, Jun 03, 2008 at 11:03:44AM +0200, Marco Pesenti Gritti wrote: The feature (and strings) freeze is approaching very quickly. We have 17 days left. Can we make a quick list of things that we need to get in by the 20 June? ___ Sugar mailing list Sugar@lists.laptop.org http://lists.laptop.org/listinfo/sugar
[sugar] [PATCH] reduce dependence on cwd in bundlebuilder.py
a simple revision to Marco's latest patch. Jameson From f2662f592c3c24ffefbd873a3050e02267d1c2e5 Mon Sep 17 00:00:00 2001 From: chema [EMAIL PROTECTED](none) Date: Thu, 29 May 2008 11:42:37 -0600 Subject: [PATCH] allow to init Config object with source_dir, instead of always using cwd. --- src/sugar/activity/bundlebuilder.py |8 ++-- 1 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/sugar/activity/bundlebuilder.py b/src/sugar/activity/bundlebuilder.py index 7a89ab4..1063f72 100644 --- a/src/sugar/activity/bundlebuilder.py +++ b/src/sugar/activity/bundlebuilder.py @@ -43,8 +43,12 @@ def list_files(base_dir, ignore_dirs=None, ignore_files=None): return result class Config(object): -def __init__(self, bundle_name): -self.source_dir = os.getcwd() +def __init__(self, bundle_name, source_dir=None): +if source_dir: +self.source_dir = source_dir +else: +self.source_dir = os.getcwd() + bundle = ActivityBundle(self.source_dir) version = bundle.get_activity_version() -- 1.5.2.5 ___ Sugar mailing list Sugar@lists.laptop.org http://lists.laptop.org/listinfo/sugar
[sugar] [PATCH] Journal able to use open with for activity bundles
trac 6639. diff --git a/NEWS b/NEWS index 3910546..06c5a53 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,7 @@ +84 + +* #6639 Journal can't resume activity bundles using another activity (homunq) + 80 * #5017 Correctly expose some strings to gettext. (tomeu) diff --git a/activity/activity.info b/activity/activity.info old mode 100755 new mode 100644 diff --git a/journaltoolbox.py b/journaltoolbox.py index 08b6157..b95b3f0 100644 --- a/journaltoolbox.py +++ b/journaltoolbox.py @@ -376,7 +376,10 @@ class EntryToolbar(gtk.Toolbar): def _resume_menu_item_activate_cb(self, menu_item, service_name): if self._jobject: -self._jobject.resume(service_name) +if not service_name: +self._jobject.resume() +else: +self._jobject.resume(service_name) def _copy_menu_item_activate_cb(self, menu_item, volume): if self._jobject: @@ -415,12 +418,18 @@ class EntryToolbar(gtk.Toolbar): for menu_item in palette.menu.get_children(): palette.menu.remove(menu_item) menu_item.destroy() - -if not self._jobject.is_activity_bundle(): -for activity in self._jobject.get_activities(): -menu_item = MenuItem(activity.name) -menu_item.set_image(Icon(file=activity.icon, icon_size=gtk.ICON_SIZE_MENU)) -menu_item.connect('activate', self._resume_menu_item_activate_cb, - activity.bundle_id) -palette.menu.append(menu_item) -menu_item.show() + +if self._jobject.is_activity_bundle(): +menu_item = MenuItem(_('Start')) +menu_item.connect('activate', self._resume_menu_item_activate_cb, + None) +palette.menu.append(menu_item) +menu_item.show() +activities = self._jobject.get_activities() +for activity in activities: +menu_item = MenuItem(activity.name) +menu_item.set_image(Icon(file=activity.icon, icon_size=gtk.ICON_SIZE_MENU)) +menu_item.connect('activate', self._resume_menu_item_activate_cb, + activity.bundle_id) +palette.menu.append(menu_item) +menu_item.show() ___ Sugar mailing list Sugar@lists.laptop.org http://lists.laptop.org/listinfo/sugar
Re: [sugar] Release process
Finding the balance of authority between these two people is IMHO a critical strategic issue. yes. Without an explicit decision, there will be tension. But some tension is good. ___ Sugar mailing list Sugar@lists.laptop.org http://lists.laptop.org/listinfo/sugar
Re: [sugar] Pippy VS Develop
Here is my thinking on view source. Possible use cases: 1. within same activity: get properties in an svg editor, view model in OpenSim, go to definition within develop itself. To be really useful, the UI for these should be as streamlined as possible. 2. Separate activities: view html in Browse--Write (in text-only mode, preferably); view raw svg in svg editor -- Write; edit activity bundle -- Develop or Pippy, depending on activity (should be global default for Python-based activities) Note that, due to bitfrost/security constraints, option 2 means at least one step through a trusted UI (although lack of xorg security makes this a little bit silly). The obvious such step, and the one currently implemented, is to bring up an item in the journals detail view, ready for launching in its appropriate activity. This is a good first approximation, but it is not ideal in a couple of ways: it means that any user choice between use-cases must go in a separate step; it currently lacks an obvious oops, go back option (without using the frame, which requires a more-advanced understanding); and it pollutes the journal with another item which could have been avoided if the user chooses not to view it or even perhaps if the user views it without editing it (Develop, for instance, has the ability to view an installed activity in-place without a bundle in the journal; the first edit causes it to make a backup copy in the journal, and all saves are to the journal of course). Looking at the use cases, one tempting way to streamline the UI is to use modifier keys. Shift-view source would always point to Develop, while unmodified view source would default to Develop but be overrideable by a given activity (for all other use cases). (extra credit if there is some transient UI when you use an overrided view-source to remind you about shift-view-source.) There would be no built-in possibility to choose between more than two use cases for a given activity, though an activity could custom-code something if necessary. In that case, the only important, nontrivial thing missing is a special details view in journal that includes a back button, which would just switch to the most recent nonjournal activity. On Mon, May 19, 2008 at 8:40 AM, Eben Eliason [EMAIL PROTECTED] wrote: On Mon, May 19, 2008 at 9:35 AM, Chris Ball [EMAIL PROTECTED] wrote: to solve. I don't view the two activities as competitive: * Pippy:Introductory Python tutor * Develop: Activity creation IDE Agreed. I think they serve different audiences/purposes. The only reason this could become confused is because Pippy grew the ability to export activity bundles, albeit somewhat limited ones. Regarding view source, I don't think anyone has nailed down the proper implementation yet. However, I certainly feel that the lowest level of the view source key ultimately should be to open the appropriate activity bundle within Develop. I'm hoping for something like a modal alert which the activity can use some API to cater to its needs, and which provides a way for the user to view/edit relevant code in other activities (via some URI handling system which Rainbow could provide for opening content). Opening the bundle in develop would /always/ be an option, but it might be possible to open the HTML/CSS/JS for a webpage in a mini-dreamweaver, or even in Write for that matter. - Eben ___ Sugar mailing list Sugar@lists.laptop.org http://lists.laptop.org/listinfo/sugar ___ Sugar mailing list Sugar@lists.laptop.org http://lists.laptop.org/listinfo/sugar
Re: [sugar] Pippy VS Develop
Looking at the use cases, one tempting way to streamline the UI is to use modifier keys. Shift-view source would always point to Develop, while unmodified view source would default to Develop but be overrideable by a I think this is ultimately the wrong course. If we can come up with a solution that presents options in a meaningful way without prior knowledge of the user, we are much better off in my opinion. I think my above proposal is a potential direction which could make this work. I agree, your proposal above is closer to ideal (though mine is easier in the short term). However, part of my motivation for my modifier key proposal was that some of the within-same-activity use cases could be everyday uses, where an intervening dialog would be an annoyance. Can you think of a way for the power user to short-circuit the dialog? For instance, there could be some fine print in the dialog to the effect that future shift-view-source from this activity will repeat whatever option you select now. ___ Sugar mailing list Sugar@lists.laptop.org http://lists.laptop.org/listinfo/sugar
Re: [sugar] On the Naming of Sugar
Just a note: in Spanish, sweet and candy are the same word. Sweetness is less problematic in Spanish, and I'd guess at worst the same as sweet in most languages, so I suggest trying for that. has sweetness is more explicit than is sweet anyway. (This kind of problem, as well as tougher googling, can arise when your code names are translatable.) ___ Sugar mailing list Sugar@lists.laptop.org http://lists.laptop.org/listinfo/sugar
Re: [sugar] OLPC priorities for Sugar in the August release
One low-hanging fruit for faster activity start is having activity install compile .pyc files, with (tiny) extra points if the .pyc gets hints to not use jffs2 compression. This is on my gameplan with the bundle format update stuff, but I have gotten stuck on the signatures (openssl cannot read ssh public keys) so I am behind on that. I had hoped to finish it in my free time this week but starting next week I cannot be so sure I'll have time. On Wed, May 14, 2008 at 6:57 AM, Marco Pesenti Gritti [EMAIL PROTECTED] wrote: On Wed, May 14, 2008 at 1:46 PM, Mikus Grinbergs [EMAIL PROTECTED] wrote: * More responsive UI - faster launch of activities Is the solution currently in joyride satisfactory for the August release? I use a recent Joyride on my G1G1. My average time to launch Browse (from the time I click in the F3 Activity Ring on the Browse icon, to the time when I can click on the entry field in Browse itself (so that I can start typing in an URL) is 25 seconds. If you could download the latest joyride, time startup and open a ticket that would be useful. 25 seconds are too much obviously. Please take both time on the very first start and after a reboot, xulrunner does component registration on the very first start which could be expensive Thanks. Marco ___ Sugar mailing list Sugar@lists.laptop.org http://lists.laptop.org/listinfo/sugar ___ Sugar mailing list Sugar@lists.laptop.org http://lists.laptop.org/listinfo/sugar
Re: [sugar] Recursive Signal Loop.
I may not be understanding this right, but what if the CollapsedEntry, when it got the signal, checked if it was actually going to have to change the jobject, and if it was already kept, it would just abort? This would quash the signal the second time around - one step more than strictly necessary/ideal, but I don't know how to convince gtk not to send the signal if it was already pressed, which is what would be necessary to quash it exactly the first time. Either that or on this step: and updates the entry as required. This includes setting the keep property you check the keep property before you set it, and do not touch it if you are not going to change it. On 4/24/08, Eben Eliason [EMAIL PROTECTED] wrote: Hello, my name is Eben Eliason, and I have a problem... Symptom: The keep buttons in the Journal (the stars) take 1 second or so between being clicked and visually reflecting that change. This is, admittedly, a rather minor problem, but as you'll see, it spells out a larger underlying ugliness. I expect the feedback to be instant both because it's better that way, and also because the identical (well, nearly so, as shown below) favorite icons used in the list view of the new Home already function perfectly, and quickly. Diagnosis: Upon inspection, the KeepIcon class used in the Journal differs from the FavoriteIcon class used in Home in one crucial way. The former does not connect to a button-release-event at all, and instead depends on the code which uses it to do so for it, take the necessary actions based on the toggle, and then tell the KeepIcon itself that it has been clicked on in order to update its internal state and reflect that with visual changes. This is obviously the incorrect approach to the problem, as the KeepIcon should abide by all the wonderful properties that makes object oriented programming useful, manage its internal state so that, if nothing else, it remains consistent when clicked (it's basically a checkboxa boolean toggle), and notify anything that may happen to care about its value when it changes. Treatment: Take the object oriented approach above, which works nicely in Home, and should also work nicely in the Journal. This cleans up the code, and allows the KeepIcon to update its internal state immediately before emitting the signal, thus redrawing before anything which wishes to be notified of its state has a chance to waste lots of time, slowing feedback. Side-effects: This is where things get ugly. The above changes were trivial, but they create an ugly signal loop which makes the treatment worthless in its purest state as described above. Here's what goes down: When a KeepIcon is clicked, its button-release-event handler updates its internal state, including its keep property, which thus emits a notify::keep signal. The CollapsedEntry object which contains the KeepIcon connects to this signal in order to update the value of the keep key in the metadata of the associated JObject. So far so good. The DS then emits an updated signal, which includes a reference to the JObject which has been updated. Off in Never-Never-Land, query.py is listening for the update signal from the DS, and the handler for this signal replaces the JObject in its internal dict, and then emits its own modified signal. The listview.py connects to the modified signal, and its handler then calls self._do_scroll, which in turn calls self._refresh_view. The latter of these functions takes it upon itself to loop over all of the CollapsedEntry objects visible on screen, updating a match for the changed JObject by setting its corresponding jobject property. The method responsible for handling the setting of this jobject property within the CollapsedEntry then reads all of the info out of the newly passed JObject, and updates the entry as required. This includes setting the keep property of the KeepIcon within the entry, which cannot assume that it has previously been set, since this is also the function that gets called to initialize the CollapsedEntry in the first place. This, of course, triggers the do_set_property of the KeepIcon, which in turn emits a notify::keep signal. Hooray. Treatment of side-effects: Anyone know the best way to handle this issue? I'm fairly convinced that the fundamental changes to the KeepIcon class suggested above are the correct approach logically and semantically. I'm unsure about the correct way to sever the recursive loop, however. Any thoughts are very much appreciated, since I've now spent considerable time messing with an issue that I thought would have a 10 minute fix. - Eben PS. Thanks for listening! ___ Sugar mailing list Sugar@lists.laptop.org http://lists.laptop.org/listinfo/sugar ___ Sugar mailing list Sugar@lists.laptop.org http://lists.laptop.org/listinfo/sugar
Re: [sugar] Usability testing
I'm going to take a flier here... I live in Guatemala and could try to organize a rural test site here. More usability data would be the least of the outcomes. This is obviously not a simple task. Looking at the give many numbers (100 XOs @ $299; 1000 @ $249; 10,000 @ $199) these numbers are over my horizon. I know that if I go to local rotary clubs and other such small-scale funding sources, it will be more than 3 times easier to get arount $10,000 (50 laptops @ $199 each) than $30,000 (100 laptops @ $299). Is there any way those give many numbers could have 3rd world pricing/volumes? (On the other hand, I also plan to try to get XOs adopted by a wealthy private school here; for them, current prices would be fine and the issue is speedy delivery. You'd have to define 3rd world not just by country but by target population.) I understand that devel and sugar may not be the right places to ask this question, but I don't really know where the right place is. Jameson On Sun, Apr 13, 2008 at 2:56 AM, Tomeu Vizoso [EMAIL PROTECTED] wrote: On Sun, Apr 13, 2008 at 2:37 AM, Patrick Dubroy [EMAIL PROTECTED] wrote: If there's one conclusion we can make here, it's that we could do a better job in coordinating our usability efforts. In the next few days, I'll try to set up a central place on the wiki that can use to do this. Anyone else who is interested in this can feel free to do so, of simply get in touch with me to let me know you're interested. Thank you very much, the developers have no means to organize such things, so the only way I see is the community stepping up and organizing themselves. I have heard discussions inside OLPC about the need of using usability testing in order to gather a better understanding of how the UI decisions work when a kid is finally put in front of Sugar. I think we'll see at some point OLPC resources dedicated to this task, but I don't think it's wise to wait for that to happen. In my opinion, things would work better if an OLPC employee/contractor is later integrated into an existing wider community effort for usability improvement, rather than people waiting for things to happen from OLPC. Thanks again, Tomeu ___ Sugar mailing list Sugar@lists.laptop.org http://lists.laptop.org/listinfo/sugar ___ Sugar mailing list Sugar@lists.laptop.org http://lists.laptop.org/listinfo/sugar
Re: [sugar] sugar roadmap
I'm assuming that the data would only go one way. In that case, the permission would be, an app without P_NETWORK would not be able to request opening of apps with P_NETWORK. No new permissions needed, just careful attention to the ones we have. On Fri, Apr 11, 2008 at 7:53 AM, Eben Eliason [EMAIL PROTECTED] wrote: On Fri, Apr 11, 2008 at 9:45 AM, Benjamin M. Schwartz [EMAIL PROTECTED] wrote: -BEGIN PGP SIGNED MESSAGE- Hash: SHA1 Eben Eliason wrote: |3. Need easy way to group links to activities, such as in a lesson |plan. | |Use Case: |Kid reads through geometry tutorial and clicks on first activity which |opens up Dr. Geo. After finishing w/ Dr. Geo he does some more reading |in the tutorial and then clicks on a second link which opens up a |related GCompris activity. | |We need a way to launch different activities from within a graphical |context, e.g. a tutorial. HTML is the most practical way to do this. I |know there are issues w/ Rainbow and activities calling other activities |but this is very important to the learning process. | | Interesting, would like to know what Eben thinks about it. | | This is an interesting idea, and one I don't really have a direct | solution for, at present. One potential option, and perhaps the most | interesting, is also a fair bit of work. It entails adding a bitfrost | permission (does it already have one?) akin to P_EXEC or something | similar, which allows an activity to make a request to the shell to | launch another activity, passing it a URI (could be a file, could be a | URL, etc) and having it ask the user to confirm the action. With such | an approach, any activity that wanted could embed links to other | activities, or to web sites. If we build this into the shell, and | offer it as a permission, I don't believe that it will pose any | security problems*. | | * I could be very wrong, though. IMHO, the best solution is the one already used by Browse in the case of PDF downloads. The files are downloaded, and then the Journal is asked to present the user with information about the item and the option to launch it. This is akin to how most modern browsers handle media files that will launch outside the browser. They present a window saying You are downloading a file of type PDF. Would you like to open it using Document Viewer? They also offer a drop-down list of alternative applications. Letting the Journal handle all open requests improves usability, in my view, by ensuring that the user can always postpone an opening action, or choose an alternative handler. I also think it improves security, by avoiding a number of potential DoS, privilege escalation, and information disclosure (e.g. #6837, #6838) problems. In case I was unclear, that is just the kind of thing I was suggesting. I think that the shell should expose a launcher service, which will do just the kinds of things you mention here. The UI would all be handled by the shell, not the activity making the request. Perhaps if it's always done this way through the shell service, we don't even need a permission. - Eben ___ Sugar mailing list Sugar@lists.laptop.org http://lists.laptop.org/listinfo/sugar ___ Sugar mailing list Sugar@lists.laptop.org http://lists.laptop.org/listinfo/sugar
Re: [sugar] Clicking links (was Re: sugar roadmap)
On Fri, Apr 11, 2008 at 1:37 PM, Eben Eliason [EMAIL PROTECTED] wrote: On Fri, Apr 11, 2008 at 11:15 AM, Bert Freudenberg [EMAIL PROTECTED] wrote: On 11.04.2008, at 07:12, Eben Eliason wrote: On Fri, Apr 11, 2008 at 10:03 AM, Jameson Chema Quinn [EMAIL PROTECTED] wrote: I'm assuming that the data would only go one way. In that case, the permission would be, an app without P_NETWORK would not be able to request opening of apps with P_NETWORK. No new permissions needed, just careful attention to the ones we have. Sorry, I'm not sure I understand this particular requirement. The activity launched will be completely isolated from that which requested it. Why would we need to make this statement hold? If I have, for instance, chosen to trust my web browser to use P_NETWORK, then why should it matter that it was asked to launch by something that didn't? Because a malicious activity could encode a private document as URL and have the browser go to that URL, which would send it to any server on the internet. Well, isn't that interesting. You have a point, there, and I don't see any good way around it. One way would be to launch an instance of Browse without P_NETWORK (and, of course, with a virgin configuration, which was deleted after running). You could view your document locally, and P_NETWORK would not be violated. If, in fact, this use case is considered important enough to be worth the effort. I'd say that watching P_NETWORK as I suggested originally would be a good enough first-pass solution that probably we'd never get a second pass. Well, perhaps a permission is in fact needed then. Of course, I still see that there could be worth in a service which allows activities to launch others. Perhaps the Develop activity eventually wants to launch an SVG editor for its icon. Perhaps Write wants to be able to embed links to other projects (as was initially mentioned as the use case) for writing tutorials. I'm not sure how to accomplish this. - Eben Note that these use-cases can be done with the P_NETWORK scheme - assuming that, instead of writing your tutorials in Write, you do it in Blog (which may indeed by a special case of Browse), which makes more sense anyway. (Yes, I am proposing a url format for activity launching - this is safe, since the originating app would have P_NETWORK.) Jameson ___ Sugar mailing list Sugar@lists.laptop.org http://lists.laptop.org/listinfo/sugar
Re: [sugar] Clicking links (was Re: sugar roadmap)
On Fri, Apr 11, 2008 at 2:16 PM, Benjamin M. Schwartz [EMAIL PROTECTED] wrote: -BEGIN PGP SIGNED MESSAGE- Hash: SHA1 Eben Eliason wrote: | In fact, this exploit could happen even without a launcher service. | Any activity that wants to could write the users private data to the | disk in a URL format, as an object, and give it a fun preview image. | When the later discovers and becomes curious about it, she'll open it | and send out her private data to whatever site the other activity | wanted. Is there something in place to prevent this that I'm unaware | of? I would argue that there is no way around this, and that it should not be seen as an exploit. Users must understand that any object produced by an activity instance can potentially contain any information available to that instance at that time. The best we can do is to show the user which instances have written data in each object, and which objects those instances had access to. That list is the list of all private data that could potentially be enclosed in each object. This is relevant not only to HTTP access but also to Sharing. What you are describing is a clear position, but it does not sound like bitfrost to me. The bitfrost paradigm is that security is maintained without any users must understand requirements. This could be maintained if: 1. There is a private attribute of journal objects. 2. Journal objects which are private are encrypted at some time before being backed up (possibly before being written to fs). 3. Journal objects which are private will not open with any P_NETWORK activity except the same one which created them (or will open with a special P_NETWORK-crippled, zero-configuration instance of that activity). (Yes, the same activity which created them needs better definition, I would accept bundles signed by the same key personally but that is another discussion) 4. All objects created by non-P_NETWORK activities are private by default. 5. There is of course some way in the journal for a user to remove the private flag from an object. At that point, the way to open another activity is to send the user to an instance in the journal to click it open is perfectly compatible with security. Jameson ___ Sugar mailing list Sugar@lists.laptop.org http://lists.laptop.org/listinfo/sugar
[sugar] [PATCH] Allow open with for activity bundles
diff --git a/sugar/datastore/datastore.py b/sugar/datastore/datastore.py index 334c866..c1ce64c 100644 --- a/sugar/datastore/datastore.py +++ b/sugar/datastore/datastore.py @@ -156,9 +156,7 @@ class DSObject(object): def resume(self, bundle_id=None): from sugar.activity import activityfactory -if self.is_activity_bundle(): -if bundle_id is not None: -raise ValueError('Object is a bundle, cannot be resumed as an activity.') +if self.is_activity_bundle() and not bundle_id: logging.debug('Creating activity bundle') bundle = ActivityBundle(self.file_path) diff --git a/sugar/datastore/datastore.py b/sugar/datastore/datastore.py index 334c866..c1ce64c 100644 --- a/sugar/datastore/datastore.py +++ b/sugar/datastore/datastore.py @@ -156,9 +156,7 @@ class DSObject(object): def resume(self, bundle_id=None): from sugar.activity import activityfactory -if self.is_activity_bundle(): -if bundle_id is not None: -raise ValueError('Object is a bundle, cannot be resumed as an activity.') +if self.is_activity_bundle() and not bundle_id: logging.debug('Creating activity bundle') bundle = ActivityBundle(self.file_path) ___ Sugar mailing list Sugar@lists.laptop.org http://lists.laptop.org/listinfo/sugar
[sugar] [PATCH] activity.py: dirty flag and fix create_jobject == False case.
This patch also has one unrelated change, creating INSTANCE_DIR as a global. a86 12 INSTANCE_DIR = 'instance' class WarningDictionary(dict): def __getitem__(self,key): warnings.warn(Trying to get key %s in unallocated activity metadata dictionary %s%(key,self), RuntimeWarning, stacklevel=2) return None def __setetitem__(self,key,value): warnings.warn(Trying to set key %s in unallocated activity metadata dictionary %s%(key,self), RuntimeWarning, stacklevel=2) return dict.__setitem__(self,key,value) a444 4 self.dirty = bool(handle or create_jobject) #do not save if not dirty. #Individual activities responsible for setting and clearing #this flag, but activity.py respects it. d694 1 a694 1 logging.debug('Activity.save: %r' % self._jobject.object_id if self._jobject else 'NOTHING') a699 4 if not self.dirty: logging.info('Activity.save: no need, nothing has happened since last save.') return d710 1 a710 1 file_path = os.path.join(self.get_activity_root(), INSTANCE_DIR, d713 2 a714 4 if os.path.isfile(file_path): self._owns_file = True if self._jobject: self._jobject.file_path = file_path a771 2 logging.debug(u'DIRTY') self.dirty = True #force a save of new data. d908 1 a908 1 return WarningDictionary() ___ Sugar mailing list Sugar@lists.laptop.org http://lists.laptop.org/listinfo/sugar
Re: [sugar] [PATCH] activity.py: dirty flag and fix create_jobject == False case.
Resending patch in unified format On Thu, Apr 10, 2008 at 11:01 AM, Jameson Chema Quinn [EMAIL PROTECTED] wrote: This patch also has one unrelated change, creating INSTANCE_DIR as a global. a86 12 INSTANCE_DIR = 'instance' class WarningDictionary(dict): def __getitem__(self,key): warnings.warn(Trying to get key %s in unallocated activity metadata dictionary %s%(key,self), RuntimeWarning, stacklevel=2) return None def __setetitem__(self,key,value): warnings.warn(Trying to set key %s in unallocated activity metadata dictionary %s%(key,self), RuntimeWarning, stacklevel=2) return dict.__setitem__(self,key,value) a444 4 self.dirty = bool(handle or create_jobject) #do not save if not dirty. #Individual activities responsible for setting and clearing #this flag, but activity.py respects it. d694 1 a694 1 logging.debug('Activity.save: %r' % self._jobject.object_id if self._jobject else 'NOTHING') a699 4 if not self.dirty: logging.info('Activity.save: no need, nothing has happened since last save.') return d710 1 a710 1 file_path = os.path.join(self.get_activity_root(), INSTANCE_DIR, d713 2 a714 4 if os.path.isfile(file_path): self._owns_file = True if self._jobject: self._jobject.file_path = file_path a771 2 logging.debug(u'DIRTY') self.dirty = True #force a save of new data. d908 1 a908 1 return WarningDictionary() ___ Sugar mailing list Sugar@lists.laptop.org http://lists.laptop.org/listinfo/sugar
Re: [sugar] [PATCH] activity.py: dirty flag and fix create_jobject == False case.
third try is the charm. Sorry tomeu (and others). On Thu, Apr 10, 2008 at 11:10 AM, Jameson Chema Quinn [EMAIL PROTECTED] wrote: Resending patch in unified format On Thu, Apr 10, 2008 at 11:01 AM, Jameson Chema Quinn [EMAIL PROTECTED] wrote: This patch also has one unrelated change, creating INSTANCE_DIR as a global. diff --git a/sugar/activity/activity.py b/sugar/activity/activity.py index 2c1eaae..ceefc3c 100644 --- a/sugar/activity/activity.py +++ b/sugar/activity/activity.py @@ -84,6 +84,18 @@ J_DBUS_SERVICE = 'org.laptop.Journal' J_DBUS_PATH = '/org/laptop/Journal' J_DBUS_INTERFACE = 'org.laptop.Journal' +INSTANCE_DIR = 'instance' + +class WarningDictionary(dict): +def __getitem__(self,key): +warnings.warn(Trying to get key %s in unallocated activity metadata dictionary %s%(key,self), +RuntimeWarning, stacklevel=2) +return None +def __setetitem__(self,key,value): +warnings.warn(Trying to set key %s in unallocated activity metadata dictionary %s%(key,self), +RuntimeWarning, stacklevel=2) +return dict.__setitem__(self,key,value) + class ActivityToolbar(gtk.Toolbar): The Activity toolbar with the Journal entry title, sharing, Keep and Stop buttons @@ -442,6 +454,10 @@ class Activity(Window, gtk.Container): share_scope = SCOPE_PRIVATE +self.dirty = bool(handle or create_jobject) #do not save if not dirty. +#Individual activities responsible for setting and clearing +#this flag, but activity.py respects it. + if handle.object_id: self._jobject = datastore.get(handle.object_id) # TODO: Don't create so many objects until we have versioning @@ -691,12 +707,16 @@ class Activity(Window, gtk.Container): own implementation of write_file() to save your Activity specific data. -logging.debug('Activity.save: %r' % self._jobject.object_id) +logging.debug('Activity.save: %r' % self._jobject.object_id if self._jobject else 'NOTHING') if self._updating_jobject: logging.info('Activity.save: still processing a previous request.') return +if not self.dirty: +logging.info('Activity.save: no need, nothing has happened since last save.') +return + buddies_dict = self._get_buddies() if buddies_dict: self.metadata['buddies_id'] = json.write(buddies_dict.keys()) @@ -707,11 +727,13 @@ class Activity(Window, gtk.Container): self.metadata['preview'] = dbus.ByteArray(preview) try: -file_path = os.path.join(self.get_activity_root(), 'instance', +file_path = os.path.join(self.get_activity_root(), INSTANCE_DIR, '%i' % time.time()) self.write_file(file_path) -self._owns_file = True -self._jobject.file_path = file_path +if os.path.isfile(file_path): +self._owns_file = True +if self._jobject: +self._jobject.file_path = file_path except NotImplementedError: pass @@ -769,6 +791,8 @@ class Activity(Window, gtk.Container): logging.debug('Share of activity %s successful, PS activity is %r.', self._activity_id, activity) +logging.debug(u'DIRTY') +self.dirty = True #force a save of new data. activity.props.name = self._jobject.metadata['title'] self._shared_activity = activity @@ -905,7 +929,7 @@ class Activity(Window, gtk.Container): if self._jobject: return self._jobject.metadata else: -return None +return WarningDictionary() metadata = property(get_metadata, None) ___ Sugar mailing list Sugar@lists.laptop.org http://lists.laptop.org/listinfo/sugar
[sugar] [PATCH] Allow open with for activity bundles in journal
Here you go, tomeu. diff --git a/NEWS b/NEWS index 398ed2c..06c5a53 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,9 @@ +84 + +* #6639 Journal can't resume activity bundles using another activity (homunq) + +80 + * #5017 Correctly expose some strings to gettext. (tomeu) * #6190 Don't crash when an activity has its icon missing. (tomeu) * #6029 Don't fail when the mount point is already occupied. (tomeu) diff --git a/activity/activity.info b/activity/activity.info old mode 100755 new mode 100644 index 9d65a95..6f39a2a --- a/activity/activity.info +++ b/activity/activity.info @@ -1,6 +1,6 @@ [Activity] name = Journal -activity_version = 79 +activity_version = 84 service_name = org.laptop.JournalActivity icon = activity-journal class = journalactivity.JournalActivity diff --git a/journaltoolbox.py b/journaltoolbox.py index 630d245..164a0f6 100644 --- a/journaltoolbox.py +++ b/journaltoolbox.py @@ -408,7 +408,10 @@ class EntryToolbar(gtk.Toolbar): def _resume_menu_item_activate_cb(self, menu_item, service_name): if self._jobject: -self._jobject.resume(service_name) +if not service_name: +self._jobject.resume() +else: +self._jobject.resume(service_name) def _copy_menu_item_activate_cb(self, menu_item, volume): if self._jobject: @@ -447,12 +450,18 @@ class EntryToolbar(gtk.Toolbar): for menu_item in palette.menu.get_children(): palette.menu.remove(menu_item) menu_item.destroy() - -if not self._jobject.is_activity_bundle(): -for activity in self._jobject.get_activities(): -menu_item = MenuItem(activity.name) -menu_item.set_image(Icon(file=activity.icon, icon_size=gtk.ICON_SIZE_MENU)) -menu_item.connect('activate', self._resume_menu_item_activate_cb, - activity.bundle_id) -palette.menu.append(menu_item) -menu_item.show() + +if self._jobject.is_activity_bundle(): +menu_item = MenuItem(_('Start')) +menu_item.connect('activate', self._resume_menu_item_activate_cb, + None) +palette.menu.append(menu_item) +menu_item.show() +activities = self._jobject.get_activities() +for activity in activities: +menu_item = MenuItem(activity.name) +menu_item.set_image(Icon(file=activity.icon, icon_size=gtk.ICON_SIZE_MENU)) +menu_item.connect('activate', self._resume_menu_item_activate_cb, + activity.bundle_id) +palette.menu.append(menu_item) +menu_item.show() diff --git a/setup.py b/setup.py old mode 100755 new mode 100644 ___ Sugar mailing list Sugar@lists.laptop.org http://lists.laptop.org/listinfo/sugar
[sugar] Bundles, versions, and updates - oh my!
*The story so far:* The Develop activity uses the bundle format natively. Thus, it relies on bundlebuilder.py to create bundles and activitybundle.py to install them. But many activities have developed their own way of creating bundles, and do not follow the bundle spec (missing or incorrect MANIFEST). This means that their bundles do not rebuild correctly in Develop, which could lead to data loss in the current incarnation. So, I have to fix bundlebuilder to have more error checking, and activitybundle to throw warnings to encourage people to follow the spec. Also, there is a major part of the sugar spec unimplemented - the part where people can install activities by joining a shared instance of them. Implementing this will, almost inevitably, mean changes in the bundle spec. If I am going to start enforcing the spec, *it would seem like the logical time to update the spec to work for updates.* *Some terminology, and **an idea from the mini-conference:* By *a bundle* I mean a specific set of bytes. Any change in those bytes means it's a different bundle. Yet actually there are some changes I generally don't care about. Using a different zip algorithm on the same set of files, for instance. Another *possible* instance is a change in translation strings/ localizable icons that does not touch any executable code. I have a proposal (see below) in which such extras would be exempt from signature. Thus, when precision is important, I will use *executable bundle* to denote everything with the same valid main signature - that is, everything which has identical executable code. At the mini-conference, a shortcut to key management was proposed, where a developer would create a special-purpose key when they started a new activity, and sign all versions of that activity with their key. This is called the *activity's key* and the signature using this key is the *main signature*. This idea assumes that key management is manual - either they send the key itself to collaborating developers, or they accept and apply patches and sign the results locally. If we decide that there are important key management issues missing from this picture, we could do something like SPKI. Thus the original developer would become an authority, and they would grant signing rights to other keys. Even in this case, main signature will refer to whatever set of data constitutes a valid signature under this scheme. Generally speaking, such data should not require network confirmation, although a finite lifetime is acceptable. All bundles signed with the same activity's key are known as an *unbroken activity thread*. It is assumed that key management would work and that there would be no forking within an activity thread (aside from, possibly, temporary experimental branches which never move beyond one machine). I propose that the unbroken activity thread should be the basic unit of analysis in sugar, and that each such thread should have a unique *bundle ID* (like org.laptop.392A7F). If the key is lost or somebody wants to create a new version (and risk forking), there could be different bundle ID's that are ancestor and descendant (and handle the same files). These are part of the same *[broken] activity thread*, which inevitably means that forks are possible. In my proposal, broken activity threads can be identified using the alleged history from the later version, which consists of prior bundle IDs and last-common-versions. Also relevant to this discussion is the new planned journal design at http://wiki.laptop.org/go/Designs/Journal. Note that there are two kinds of things in the journal: *actions*, which, as m_stone puts it, are like UI completions, and *objects*, which are more like normal files (pictures, documents, etc.) with mime types. Actions contain objects, but those objects are also accessible independently. See also http://wiki.laptop.org/go/Designs/Activity_Management. *Favorite* bundles are visible in the *Home screen* (or *donut*), while all activities are available in the *activity list [view]*. * The issues *The point of all of this is the user experience that it enables. Some possible goals (including straw men): 1no such thing as versions: all actions are associated with a given executable bundle, and can only be opened with that bundle. The favorites can be any set of bundles, whether or not these have an ancestry relationship. The XO does not garbage collect (GC) old bundles until there are no more instances which use them. 1aNSTAV ++: there is some way to manually open an action with a different bundle. What is the UI to make this easier? 2latest version, but no such thing as forks: All actions are 100% upward-compatible across unbroken activity threads (when they aren't, you just break the thread). All actions open with latest version in an unbroken thread and favorite is an attribute of an unbroken thread - the latest version available is the one that opens. Broken activity threads are treated as in NSTAV.
Re: [sugar] Bundles, versions, and updates - oh my!
My terminology in the preceding letter was bad. Rather than resend the fixed version, I put it on the wiki: http://wiki.laptop.org/go/Bundles_and_updates. Please read that instead of the letter above: it has all the same content, but with better clarity, and one added paragraph near the end. ___ Sugar mailing list Sugar@lists.laptop.org http://lists.laptop.org/listinfo/sugar
Re: [sugar] Summer of Code update : applications so far, and thanks
Finally, to stimulate discussion, below are a few applications that deserve more feedback and mentor attention. 2 points: 1. A lot of these are not on the wiki, or were not in the [[Category:GSoC proposals]]. I've rectified that for the ones I could find, but I'd really like to read some that I couldn't find. I understand that some people may not have found all the different places for communication - the GSoC website, this list, the wiki, IRC, the other mailing lists, trac it is a lot to keep track of. So it would be great if mentors could use the GSoC website to suggest to students that putting an application on the wiki will get more feedback. 2. My app http://wiki.laptop.org/go/Bityi/GSoC has gotten more feedback than most, so I understand why I'm not on this list, but I still feel left out. My idea is to modify Develop let you program in a Python based on your own language, but keep it as English-based python on disk - it takes maybe a few more words to describe than most applications because nothing like it really exists anywhere else. And yet most of the feedback I've gotten has to do more with technical or logistical points, not the basic question of whether this new idea is worth doing. For those of you whose first language is not English - do you think it would help people learn to program if the keywords and basic modules were readable in your own language? (Don't just think about your own case, think about your average potential programmer - would it help?) If you have an answer, add it to the talk pagehttp://wiki.laptop.org/go/Talk:Bityi/GSoC- of course I'd love any yesses, but if I get a couple of no's there's still (barely) time for me to submit another Develop-related application. = Good applications that need review by a mentor with topic-specific expertise = * An XO Eclipse environment - Phan quoc huy I really want to see this, it sounds very interesting. * Handwriting recognition - Juliana Lipková (Thomas Breuel, call your office) * your voice on XO - Alex Escalona, on community-wide building of new Festival voices for TTS = Projects attracting more than one good application = (e.g., where there are detailed comparisons to be made) * Typing tutor - at least three good proposals * Flashcards - at least two good proposals * [[Elements]] extension - at least two good proposals * Artificial neural network simulations - at least one good proposal * A light email client - a few proposals that need clarification * Blogging platforms - * Finance activities - [[Finance One]], c = Other applications of note = == Core system components == * The publish/share button - Robson Mendonça, Eric Burns * Server interface design - Michał Ściubidło and others * LustreFS for XO (Distributed mesh filesystem) - Evelina Stepanova * Memory/disk tuning (schoolserver) - Waseem Shaukat == Fundamental activities == * [[Listen and Spell]] - Assim Deodia * Homework manager - Jason Tran * [[VideoEdit]] - Roberto Fagá * [[Coding Tutor]] - Rahul Bagaria This is where I'd put my proposal, Bityi - on-screen code i18n in XO Develop activity http://wiki.laptop.org/go/Talk:Bityi/GSoC. In other words, the activity is Develop == Learning games == * Incredible machine - Alex Levenson, with a prototype * [[PlayGo]] extensions - Brandon Wilson * Water Game - Lin Zhou, for learning water sanitation and safety * Garden Game - Javier Trejo, for learning genetics; developing in both en and es. Cheers, SJ ___ Sugar mailing list Sugar@lists.laptop.org http://lists.laptop.org/listinfo/sugar ___ Sugar mailing list Sugar@lists.laptop.org http://lists.laptop.org/listinfo/sugar
Re: [sugar] Mini-Conference Proposal: Automatic transfer/update of activities on the mesh
OK, the mini-conference happened - thanks for trying to let off-siters like me participate. Here's the Gobby doc which resulted, below are my post-meeting comments: Activity sharing: * Should we show people what the size/download time for a package is before d/l? * We might download something more readily if it's coming from a friend. * Michael: Trusting a friend isn't the same as trusting code coming from that friend. Ben: The only security question is whether it's safe to *replace* an activity with a new one. Bitfrost guarantees that running untrusted code is safe. Scott: You can always modify code, but you have to give it a new name. Michael: Making something default is a separate UI action from downloading it. Should distinguish between activities by their hashes; version numbers shouldn't be used for equality. homunq: unsigned versions should obviously not get the same preference directory. proposals for naming: * centralized registry, e.g. microsoft.com * mstone: first person to get there owns the space (and others get another version of %s) * each activity has a random guid for same activity and ... http://wiki.laptop.org/go/Talk:Activity_bundles#A_proposal_for_Activity_Signing How to put related activities together? * group by tag * add prefix in name, sort by name * group by magic sortkey tag decision: A and/or B as author decides. SJ: Attach names to the inherent identity of an activity .. okay, SJ can type what he meant ;-) I make a new activity, *E*. It gets a ¨unique¨ id, E.id and a ¨pretty unique¨ package name, ¨E¨. ¨E¨ is the friendly name you use locally to identify the activity. There is also a pretty name ued in interfaces, which is ¨E!¨ this can be translated, changed from version to versiion. when I join a larger group that has some other activity named E, I should change my public activity-name (andraelly should change the display name). Everyone can see that my ¨E¨ is differnet from the existing one, since they have different unique IDs, but to supprot simple intreface-driven updates and version selection, the friendly package name should change. aside: there is some confusion about the hisotrical and practical use of sortkeys. this is some piece of metadata that an author can acontribuet, which will help to sort a cluster of related activities with one another. similarly, which activities appear nextto which other ones in the circle view is improtnt. note - this is NOT aout ¨favorites¨. Grouping Version Identity P10 X \- P 9 O -- change in ownership N 8 X \- N 7 X Eben: Use tags to support grouping, e.g. tamtam or mamamedia or draw Scott: Localisation of tags is hard. note : having ¨signed¨ versions of activities, and the ecure model, is not necesarily relevant to lots of activities and use caes. we should support identifying versions that claim to e of the same underlying activity, and claimed merges and forks, without worrying about keys and signing. THINGS ABOUT WHICH THERE IS NOT CONSENSUS. how to bulk update a set of activities soeveryone in a room has the same version update on share? is this a good idea? how would it work in ui? push updates - is this a good idea? how would it work? My post-meeting comments: 1. for version threading, what we need for an activity is not a claim like I am a version of activity ID but My prior version was XXX and the one before that was YYY. What is the granularity of XXX and YYY? I'd say, a hash on the activity.info would be fine - that way, version changes are automatically picked up, but not every change in the source code. If, later, activity.info picks up some elements which are too volatile (thus leading to unnecessarily-long geneologies), we could filter those out before hashing. Note that this is totally orthogonal to whether an activity version is signed by the original devteam, and yet allows for forks to become independent without fighting over who is the real pippy org.laptop.XYZ1FFE3. I submit that merges are unnecessary. 2. If we get the version threads right, then the auto-update on sharing becomes safer. I still don't understand who has to sign to avoid a break in the ownership chain - I would presume a given set of maintainer/developers, and I would presume that there would be some way for the group to change over time - but those details can be worked out. 3. For push updates and school versions, I would presume you'd in some manner beyond the scope of this discussion get an xo bundle (or a bundle of bundles), the only problem here is how to install it and mark it as the official school version. Stated like that, it seems to be obviously a problem of tagging. How do you securely tag documents you receive from external sources? I'd say that only signed tags should be allowed to move from one XO to another, and that it should be possible to have a filter which automatically pushes
Re: [sugar] Automatic transfer/update of activities on the mesh (Was: Sharing behavior in the core Read activity)
Develop clearly needs to be aware of whatever solution we come up with for activity updates. This means that Develop has to be able to do the signing. Right now, bitfrost does not give out the private key to activities (correctly) and does not allow activities to request a signature for something (wrongly - there is a P_IDENT bitfrost privilege which should allow activities which have it to sign things). I raised this issue on IRC and got two responses. 1. neuralis/ ivan krstic was the security guy on the team and he has just left. Do not expect this to be fixed soon. 2. Do not try to fix this yourself, as security must be done right or not at all. (apologies for stripping the nuances) I disagree with #2. Security must not be done wrong, but it can be done partially if we think things through. Adding a hook so that activities with P_IDENT can request signatures, without seeing the private key, is IMO safe and simple enough to be worth doing if it helps us with activity updates. (More summary from IRC: the tricky, unresolved issue is key trust - does a given public key mean what we think it means? This is separate from key security. Let me give a scenario. Activities spread virally by sharing. Alicia codes a new activity V1 and signs it, it starts to spread. Bad Bob replaces Alicia's sig with his own and keeps spreading it. Now Bad Bob can add his malicious code to the activity later, and all the people who got the activity downstream from him will automatically update to the malicious version. To me this is not a problem, because Bob could have added his code to the activity in the first place. It just lets him be a little lazier. It is 100% equivalent if Bob had added some general-purpose trojan to the app immediately, so auto-update has not created any new vulnerabilities. Also, if there are two versions of the same activity floating around with different signatures, noticeable things will start to happen - either someone downstream from Bob will get an update from Alicia that will mysteriously fail to autoinstall, or vice versa.) On Wed, Mar 26, 2008 at 7:10 AM, Guillaume Desmottes [EMAIL PROTECTED] wrote: Le mardi 25 mars 2008 à 16:02 -0400, Benjamin M. Schwartz a écrit : This works, and will work for the proposed case. For the future, I see file transfer as precisely the sort of thing that should be handled internally to Telepathy. Perhaps Telepathy should implement XEP-0234 (file transfer)[2] or even XEP-0214 (file sharing)[3]. We have a draft of spec for file transfer (but it will be probably modified) and a Salut branch implementing it. So that's definitely something that could be done at some point. G. ___ Sugar mailing list Sugar@lists.laptop.org http://lists.laptop.org/listinfo/sugar ___ Sugar mailing list Sugar@lists.laptop.org http://lists.laptop.org/listinfo/sugar
Re: [sugar] New multilingual dictionary activity
For the XO, it would be great if dictionaries were *not* constant databases. Many of the countries where the XO is/will be deployed have local languages for which good free electronic dictionaries very much do not exist. Moreover, even in places where the local language is digital-age, creating a schoolwide jargon file would be a great project for involving the kids. I know that, if the University of Southern Denmark and the dead author's daughter ever finish giving me CC-like rights to a multilanguage Mayan dictionary, a good wiktionary-like activity would become *the* major argument for adopting the XO in Guatemala. (the dictionary is large, but antiquated - it would need to be user-extensible to be useful). I am very happy that a dictionary activity exists, and I know that the programming work for a user-modifiable one is several times as much as just a static one. So I am not belittling Chris's accomplishment, just saying that tying it to a static database is not the direction I would advise. Jameson On Mon, Mar 10, 2008 at 3:01 AM, Assim Deodia [EMAIL PROTECTED] wrote: Hi, On 3/10/08, Hemant Goyal [EMAIL PROTECTED] wrote: Hi, Next steps: * I have a Speak button that I'd like to hook up to espeak with the appropriate accent loaded. Josh, any interest in helping to get that working? Should I just wait for the speech server? The speech dispatcher API is what you can use for the speech synthesis. The python API is accessible here : http://cvs.freebsoft.org/repository/speechd/src/python/speechd/client.py?view=markup I am still trying to get the speech dispatcher and its dependencies packaged for Fedora :\. And that is the only reason why the speech server is still not present on the XO :(. I really request an expert to look into this and help speed up the work. In the long run, we plan to explore other Text to Speech engines other than eSpeak (because of voice quality issues). So coupling your app with eSpeak is not so sensible when you can directly use speech-dispatcher for all testing. I have a few unapproved speech-dispatcher packages here: http://www.nsitonline.in/hemant/stuff/speechd-rpm/ You'll need dotconf packages to install speech dispatcher. Perhaps Assim can help you get a *usable* dotconf pacakge. You can get dotconf RPM's from http://nsitonline.in/assim/stuffs/olpc/dotconf/dotconf-devel-1.0.13-6.fc7.i386.rpm http://nsitonline.in/assim/stuffs/olpc/dotconf/dotconf-debuginfo-1.0.13-6.fc7.i386.rpm http://nsitonline.in/assim/stuffs/olpc/dotconf/dotconf-1.0.13-6.fc7.i386.rpm These RPM's are clean to use with only some minor bugs regarding Fedora Guidelines. We would really appreciate some help in process of review request to get both the packages (speech-dispatcher and dotconf) into OLPC build soon. I'd gladly hook your activity to speech dispatcher and make it self voicing _once_ speechd gets accepted in the OLPC build. Thanks! Hemant -- Regards Assim ___ Sugar mailing list Sugar@lists.laptop.org http://lists.laptop.org/listinfo/sugar ___ Sugar mailing list Sugar@lists.laptop.org http://lists.laptop.org/listinfo/sugar
Re: [sugar] Disconnected backups.
I don't know what you mean by erasure-coded. I am only talking about storing something the size of a private key - say, 2K - on three other laptops. Your own private key would be 2K and you would, on average, have 3 other keys - a grand total of 8K average. Not going to break the back of even the most limited modern storage. But considering the complexity of implementing key-part-management (mostly on the restore side of the equation), I think that brute-forceable password encryption of the backed-up private key is the better idea. The automated brute-forcing script should be written for the XO, not for the server (although of course porting it would be easy). When creating your password, it should even give you a pregenerated default random password. If you just broke your XO and forgot (or never wrote down) your password, a few more hours of cracking once you get your new XO is a minor nuisance. And yet this simple step would cut down privacy invasions by orders of magnitude, IMO. On Tue, Feb 19, 2008 at 2:36 PM, Ivan Krstić [EMAIL PROTECTED] wrote: On Feb 19, 2008, at 3:32 PM, Jameson Chema Quinn wrote: That's a separate issue - at the simplest, you just store the encryption key on the first backup and only manually thereafter; a more complicated scheme, for implementing later, would break it into 5 parts of which any 3 would suffice, and store the same 2 parts on all the backups Collaborative erasure-coded backups are not a good idea for devices with very limited storage, except in special cases. -- Ivan Krstić [EMAIL PROTECTED] | http://radian.org ___ Sugar mailing list Sugar@lists.laptop.org http://lists.laptop.org/listinfo/sugar ___ Sugar mailing list Sugar@lists.laptop.org http://lists.laptop.org/listinfo/sugar
Re: [sugar] Disconnected backups.
* We could use the favorite flag, or a new backup flag, to signify which jobjects the user would like to back up, and we can try to accomodate them. We probably still need a per-user quota. ... * Encryption/privacy probably isn't desirable here -- we're dealing with objects that the user has chosen to have backed up. Also, this would provide a good way for kids to turn in homework to their teachers: the teacher passes around a USB key, and as each child inserts the key, their homework gets automatically copied over to a directory named after them if it's marked favorite. I disagree with the latter statement, I think it is not too hard to do encryption intelligently. I understand that if you are backing up against possible loss of hardware, you need to have a backup of the encryption key itself, and that if you keep the encryption key next to the files it defeats the purpose. That's a separate issue - at the simplest, you just store the encryption key on the first backup and only manually thereafter; a more complicated scheme, for implementing later, would break it into 5 parts of which any 3 would suffice, and store the same 2 parts on all the backups, giving the other 3 parts separately to randomly chosen peers over the mesh... In the simple scheme, you could also password-protect the backup of the encryption key, as long as you enforced that the password be of a length that takes a few hours to brute-force on an XO; this would be sufficient nuisance value to discourage routine or widespread snooping, but still allow for data recovery in the inevitable case of the kid who loses their XO and forgets their password. We are not short on room for flags. I propose 3 of them would work here: shared, favorite, and unbacked-up. -shared would be set for all files which were shared globally or with a group. Files shared with other individuals would not be marked. UI for setting this bit is TBD but for now it would just be set if the activity instance was shared. Files with the shared flag would not be encrypted, and would be given priority if backup space were limited. This covers the student half of the turn-it-in use case; the teacher half would be from Terminal or with some TBD backup-browser activity. -favorite flag exists, it just means try to fit me into the backup even if I am big. -unbacked-up is just what it sounds like, it keeps files from landing in every single backup. They could still be backed up repeatedly as space allowed; you could even add a last-backed-up-date metadatum to help with this. The other thing that could be used to figure out file priority would be whether there were newer versions of a file in the datastore. ___ Sugar mailing list Sugar@lists.laptop.org http://lists.laptop.org/listinfo/sugar
Re: [sugar] Update.1 testing
I know that we're supposed to all be developers here, and know how to change the firmware in our sleep; but it would be great to include a link to instructions. I searched the wiki - http://wiki.laptop.org/go/Manual_Firmware_Install is worse than useless, and http://wiki.laptop.org/go/OLPC_Firmware_q2d09#Unsecure_Machines is the wrong place (why include separate instructions on each firmware build page, instead of having a general instructions page?) and also does not tell you how to do it using SD instead of USB or internal. I'll take responsibility for putting the instructions on the wiki and making appropriate links to them, if someone tells me how to do it with SD. ___ Sugar mailing list Sugar@lists.laptop.org http://lists.laptop.org/listinfo/sugar
Re: [sugar] Update.1 testing
Simple. Put the manual install instructions in http://wiki.laptop.org/go/Manual_Firmware_Install and then, in each relnotes page add {{:Manual_Firmware_Install}}, which will include the text of that page in the one it is as a template in. If you want to be even cooler, in Manual_Firmware_Install, put the tags onlyinclude and /onlyinclude on the stuff that you want to be included. I've done this - and, even cooler, I used a template parameter so that you can have the instructions refer to the right version, like this: {{:Manual_Firmware_Install|version=q2d09}} . ___ Sugar mailing list Sugar@lists.laptop.org http://lists.laptop.org/listinfo/sugar
Re: [sugar] Develop activity (Oops...)
I've been thinking about the design issues for coding i18n in develop. The problem is that if you want to translate identifiers at all, you immediately have to work with multiple dictionaries for all the modules you're importing. Initially I just slogged in and tried to start coding something that would keep a whole import tree in its head, and magically decide for you where any changes in the dictionary should end up. I took about a day to realize that thence lay only nasty pointed teeth (I should have realized sooner). So after thinking about what simplifying assumptions I can make, I have a basic design that I'm kinda proud of. I'll try to explain it below, and to keep the just LOOK at how hairy the problems are if you don't do it my way details to a minimum. Trust me, they're hairy. Nonetheless, I know y'all need no map from me, if you see another path, or a minor modification, which still avoids the hair and teeth, by all means, suggest it. Also speak up if you see some hair on my path I've missed, of course. Summary: 1-As discussed already, any identifier or keyword with a translation is presented in user's preferred language on screen, but in English on disk. 2-The identifier-translating dictionary for any given file - say, somemodule.py - stays in a parallel file in the same directory, say .someModule.p4n. 2a- The editor would have to understand import statements and have the ability to fine the relevant .p4n's. from and as modifiers would be ignored, except when combined, because even a single imported item could carry with it all the identifiers. 3-This dictionary ONLY contains translations for the public interface of somemodule.py, that is, those identifiers which are used in importer modules. It also defines a single, unchanging preferred language for that file, which is the assumed language for all non-translated identifiers in that file. 4-There is good UI support for creating a new translation for a word. However, the assumed user model is that words will be translated INTO a users preferred language; FROM the context of an importer module (you'd generally not add translations for a module from that module itself, since generally you wouldn't even have modules open whose preferred language is not your own); and therefore WITH an explicit user decision as to which module this translation belongs in (they want to use their language for identifier X which is in English, well, they must have had a reason to write it in English rather than their language so they presumably know what imported module it comes from.) 5-As a consequence of points 1 and 4, when you add a translation to a module whose preferred language is not English, that results in a change on-disk of the python code for that file. (Unlike the case for adding a translation for a file whose preferred language is English, which only anywhere results in safe on-screen changes). To enable the EDITOR to intelligently propagate these changes to other importers of the changed module, and the INTERPRETER to dumbly continue to work for these other importers before the editor gets to them, the changed file (and its dictionary) is given a new name (for instance importedmodule.i18n.v1.py). The old version is not deleted and keeps the old name. 6. Due to the notable disadvantages of point 5 (polluting the filesystem and, worse, the import/pythonpath namespace with old versions, whereas the best version of a file would always have a name like importedmodule.i18n.v37.py), there would be one change to the python core to facilitate cleanup. If someone deleted all the old copies and renamed the aforementioned best version to just importedmodule.py again, the default __import__ function would know how to find it when it couldn't find importedmodule.i18n.v37.py. This new feature would have no impact on any existing python code, and, to be honest, I think that its presence in the changes in python3001 lists would be (minor but useful) propaganda for the new i18n features. (obviously, a good delinting tool would take care of all the issues created by 5 at once.) 7. Docstrings and comments, as always, are a separate issue, but I think that they're also a soluble one. . Is all this clear? Do y'all understand why it's necessary? Do you have any other ideas, or see problems with the above that I missed? Do you think I've made any intolerable or unnecessary compromises? Or do you just think that it's absolutely brilliant? Cheers, Jameson Quinn ___ Sugar mailing list Sugar@lists.laptop.org http://lists.laptop.org/listinfo/sugar