[Zope3-Users] Re: Attn Jim Fulton: Buildout builder
Jim Fulton wrote: I replied to this privately. This has gotten so much discussion, I think I'd better clarify my position. On Mar 14, 2008, at 8:27 AM, Derek Richardson wrote: I am the Plone champion for the buildout builder. The buildout builder will be a web application, likely written in Grok, that will allow textually-challenged users to configure a buildout via a GUI and receive a .cfg in return. Jim, you mentioned at PSPS-2008 that you would gladly help whoever championed this. There was a misunderstanding or miscommunication. Sorry about that. I volunteered to help with a buildout-based installer. This is *much* narrower than a buildout-building GUI. My thought was that, for a simple installer, there could be GUI that asked the user some high-level configuration questions and then ran a buildout included with the software to set up instances. This is similar to what we're doing for deployments at ZC where we have high-level non-buildout configuration files that collect options that control instance installs. The instance installs are actually done by running buildouts. I have about as much interest in a GUI to help me write buildout configurations as I have in a GUI to help me write Python scripts. :) No, I don't think you're the target audience. ;) I do see potential benefits of having GUIs or other automation tools to help people get started assuming that the scope of these tools is very narrow. They are only either to help people get started or for people who's needs will never be anything but simple. The audience is the question. Plone seems to be moving to a buildout-centric model. We have developers who gladly use buildout (I am one of them); they will continue to do just what they do now. We have some users who use installers. Some of them will always simply use installers and will be unaffected by the buildout builder. Some of them will decide, after they use the installer, that they'd like to tweak their install. Some of them will be text-comfortable and will move straight to modifying their buildout.cfg. Some of them will not be and the buildout builder will be a good incremental step for them - it will give them the ability to make simple, supported changes to their buildout without having to face a blank spot in their buildout.cfg and decide, ex nihilo, how to fill it. In this case, you can consider the buildout builder a web version of the buildout-based installer with GUI that you mention above. A third category of user (in addition to buildout-mavens and installer-people), perhaps specific to Plone, are systems integrators. These folks may have considerable knowledge of Plone and technical skills in some areas, but may not be buildout-mavens or even know (or want to know) Python. They may be text-averse, not wanting to manipulate a buildout.cfg. They may not want to root through the Python code of less-documented recipes to figure out configuration options. They may simply want a less-steep learning curve. They may have complex needs that they understand from a system-administration viewpoint, but may not want to learn Plone behind-the-scenes, which includes buildout. I am not defending these people's choices to not learn buildout (or Python). The simple fact is that these people exist in sizable numbers in the Plone community and their needs are important. We heard from them loudly after the 3.0 release and at the PSPS. We need to address their concerns. This audience may not exist in the Zope community-at-large. I don't presume that anyone here wants to help me address their needs. I was simply following up on what I thought was an offer of help, which turned out to be a simple hallucination. That is the value in general. I, personally, have a more specific itch to scratch. I'm interested in what I call Plone-on-Demand, the ability to host Plone sites as a service. I want people who don't know Python or Zope or Plone, who simply want a website, to be able to go to a web page, fill in some options about what they would like in their website (skin, functionality, etc), and, 20 minutes later, get an email saying 'Here's the url of your new website - enjoy!'. This competes with similar services built on PHP at providers like godaddy. I want this for my university, which has a need for a web hosting solution and I think Python/Zope/Plone is appropriate. The buildout builder is a step in this direction. If I write the infrastructure for Plone-on-Demand, I intend to open-source it. It could be used by other service providers who currently shy away from Zope and Plone. It can also be used to provide demo sites for evaluation, perhaps deployed on a public grid. If you still think this is the wrong route to follow, I'm interested in hearing your reasons. But, in my view, this is good for the Plone community in several ways. Coupled wi
[Zope3-Users] Attn Jim Fulton: Buildout builder
I am the Plone champion for the buildout builder. The buildout builder will be a web application, likely written in Grok, that will allow textually-challenged users to configure a buildout via a GUI and receive a .cfg in return. Jim, you mentioned at PSPS-2008 that you would gladly help whoever championed this. I am now asking for assistance. Please contact me at the gmane email address on this post. Anyone else who has interest and would like to contribute questions, ideas, or code is welcome to contact me, as well, or continue discussion here (please cc me, since I don't regularly read this list). The buildout builder may very well be a Plone Summmer of Code project. At the current time, it is unclear whether someone else or I will be the student. In either case, I'd like to get some of the high-level coneptual design out of the way so that, whoever the student is, she/he can get down to business immediately. Thanks! Derek ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
[Zope3-Users] zope.formlib doesn't check invariants on subschemas - need workaround
I have a schema, let's call it B. It contains an @invariant function. I observed that it is not being called during form validation. After help from Philipp and some investigation, I determined that the problem is that schema B isn't itself the main form, but is nested within schema A as the value_type of a Tuple field. When schema A is validated, schema B's invariant is not checked. I think this may be a bug. If someone more knowledgeable will confirm, then I will open a bug report. In the mean time, I need a workaround that verifies that the invariants on all instances of schema B in the Tuple on schema A hold during form validation. My nascent idea is to put an invariant on schema A that checks all the invariants on all schema B instances. However, I am not familiar enough with formlib internals to code this up without significant research. Can someone help me out with an implementation for this workaround or an idea for a different, better workaround? Thanks, Derek ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
[Zope3-Users] Buildout fails with zope.recipe.egg 1.0.0 vs 1.0.0b6 conflict
zc.recipe.egg was released 2 days ago. Now, when trying to re-run a buildout that was done before the z.r.e release, I get a VersionConflict: # [EMAIL PROTECTED] share-it]$ bin/buildout Develop: '/srv/share-it/quills.remoteblogging' Develop: '/srv/share-it/quills.core' Develop: '/srv/share-it/quills.app' Develop: '/srv/share-it/plone.marquis' Uninstalling zopepy. While: Installing. Uninstalling zopepy. Loading recipe 'zc.recipe.egg==1.0.0b6'. An internal error occured due to a bug in either zc.buildout or in a recipe being used: VersionConflict: (zc.recipe.egg 1.0.0 (/srv/share-it/eggs/zc.recipe.egg-1.0.0-py2.4.egg), Requirement.parse('zc.recipe.egg==1.0.0b6')) # I tried to remove the zopepy from the buildout, but it still tried to uninstall it and I get the error above. I also tried 'bin/buildout -n' to not get the new egg, but no luck. I can post my buildout.cfg if it is necessary to debug the problem - i.e., other people in a similar situation aren't having the same problem. I've pinned all my recipes, so I guess the problem might be there - but I thought this is exactly the kind of problem that pinning is supposed to solve. :( Thanks! Derek ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
[Zope3-Users] Re: Getting current user and current user's group in a buildout script
Benji York wrote: Derek Richardson wrote: So, is there an easy way to do it? I know I can write a recipe, but a recipe seems heavyweight for this. It seems to me that access to these two values should be built into buildout as implicit variables. Is this contrary to the lightweight, pluggable design philosophy? The way we've handled similar needs is to require the user to enter that kind of information in their default.cfg. That way you don't have to sniff the environment, and the user has explicit control over what values buildout sees. Yeah, that explicit control is nice. But I want the easy case to be easy - just svn co the buildout and run, no edits. So I modified the recipe to take a user. If the user is supplied, it returns the same user. If the user is not supplied, it returns the current user. And, in any case, it returns the group for that user, which I don't want to specify separately. Oh, I just realized, you said *default*.cfg, not *buildout*.cfg. Hadn't thought of that - that's even nicer. I will change my buildout to reflect that. However, it is only an in-house standard. Which is not to say it's a bad idea, it's only to say 'if this is the best solution, then should we standardize it across all buildouts, not just individual organizations?' Then, when I check out a buildout, I can be guaranteed that it will have access to the account I want it to have, if it needs an account for anything. Derek ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
[Zope3-Users] Re: Getting current user and current user's group in a buildout script
Martin Aspeli wrote: Derek Richardson wrote: So, is there an easy way to do it? I know I can write a recipe, but a recipe seems heavyweight for this. It seems to me that access to these two values should be built into buildout as implicit variables. Is this contrary to the lightweight, pluggable design philosophy? What's the use case here? I can't think of many good uses for something that's going to vary depending on who's running the buildout. The use case is that the pound (http://www.apsis.ch/pound) install is evil. Configure takes -o (owner) and -g (group) parameters to set ownership of the pound binary. This would be fine if leaving them blank defaulted to the current user and group. However, it defaults to system-specific settings, which, on my mac, is the 'www' user and 'www' group. Unless I run my buildout as root, the build fails. Not cool. Really, I'm only assuming that running as root would work, since I refuse to run buildout as root. So, to test on my mac, I want to pick up the current user and group. I've written a recipe that, given no parameters, returns the name of the current user and current user's group. Given a user name, it returns the name of the specified user's group. Secondly, buildout and at least the recipes we like to promote are cross-platform. This may not be as easy to achieve on Windows. Yep. So, unfortunately, I may not release this recipe. Thirdly, users can be in multiple groups, so at least you'd need a list, which may not lend itself so well to the standard way of using variables in buildout. The UNIX gid from the password database is good enough. ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
[Zope3-Users] Getting current user and current user's group in a buildout script
So, is there an easy way to do it? I know I can write a recipe, but a recipe seems heavyweight for this. It seems to me that access to these two values should be built into buildout as implicit variables. Is this contrary to the lightweight, pluggable design philosophy? Derek ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
[Zope3-Users] Installing a run script in bin/ after using cmmi
After I install pound using cmmi, I want to create a run script in bin/. This should be easy - the script should be boilerplate and not require mods for individual installs. I can use the os command recipe to put it in bin/. My question: where is best to store the script? Does it belong rightfully in src/, since it is source code that will be used by the buildout? Or should it go somewhere else, since it's merely a production artifact and not a develop egg? Just checking to make sure I stay in line with best practices Thanks, Derek ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
[Zope3-Users] Buildout recipe to create config file from contents in buildout.cfg?
I am using hexagonit.recipe.cmmi to install pound (www.apsis.ch/pound) in front of zope. After I cmmi, I need to install a config file. I'd like to include the pound config file in buildout.cfg, like the zcml section in zc.zope3recipes:application. Is there a simple recipe for making a file out of a section in the buildout.cfg and putting it in a particular place? Or is there a 'best' recipe to use to get close? Or is this a reason to write a new recipe from scratch and contribute it? I see this simple functionality as having many use cases. Thanks, Derek ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
[Zope3-Users] Re: Moving from z3 tarball to z3 buildout/eggs
Philipp von Weitershausen wrote: * If vice depends on the configuration of another package, but always assumed that this package's configuration was being loaded by Zope 3.3's site.zcml, make this dependency *explicit* now in vice's configure.zcml. For example, let's say that vice needs the intid utility and event subscriber registrations to be active, then it should do: at the top of vice/configure.zcml. This will probably add more explicit depenencies to vice than you currently have (they should also go into setup.py). Note that you won't have to worry about ZCML being loaded several times. It won't be, zope.configuration makes sure of that. OK, agreed, this is the *right* way. And thank you for the detailed instructions on how to achieve this - they are very clear and I plan to follow them closely. One problem confronts me, though, before I do the boring work of sorting out the dependencies. My package is designed to run in both z2 and z3. So, I could add a bunch of z3-specific dependencies to a z3-configure.zcml that is loaded only if Five is not installed. Not too hard. But, the hard part is: I don't want to add all the z3 eggs to my setup.py, because that's ugly if I'm actually running in z2. My idea is to have a z3-only package that depends on my z3/z2 hybrid package and that simply has a setup.py that includes all the z3 dependencies and a configure.zcml and an ftesting.zcml that does all the z3-specific zcml work. And then I can have a z3-specific buildout that uses the z3-specific package and another buildout for z2 that uses the base package and a third buildout for z2+plone, which includes some additional plone-specific packages. A big pain, but I want my code usuable in all three environments, to the extent that is possible. Opinions? Thanks, Derek ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
[Zope3-Users] Moving from z3 tarball to z3 buildout/eggs
I developed my Vice outbound syndication library on z3.3 (originally) using the full tarball of z3.3. I now want to move to a buildout-based, eggified method of developing and testing Vice. I use functional tests (using zope.testbrowser.testing.Browser) in Vice. These functional tests log into the zmi, create some folders and files, syndicate them, read the resulting feed, and verify that it is correct. The problem is that I don't know how much of zope.app these tests depend on. Very few eggs are actually required by imports in Vice. But the library is not much use (and there's not much to test) without a pretty thorough install, I suspect. Should I be attempting to grab all the zope eggs and making a replica of the full install? Or should I be trying to judiciously minimize the eggs that I use for testing? And what is the best way to go about whichever of these paths I should follow? I *really* like the buildout approach. It would just be even nicer if I knew of some way to have buildout replicate the entire Zope app server ecosystem for testing without having to specify the eggs one ... by ... one. Thanks, Derek ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
[Zope3-Users] Re: Varying Default Value for Subschema (Object in Tuple)
Derek Richardson wrote: I have a schema (the Tuple of Objects is the important part): class ISyndications(Interface): """Annotation that indicates the object can provide IFeed and that stores the current syndication configuration. """ enabled = Bool(title=_(u'Enable syndication'), description=_(u'...'), default=False, ) syndications = Tuple(title=_(u'Feeds'), description=_(u'...'), required=False, default=(), value_type=Object(title=_(u'Feed'), description=_(u'...'), schema=ISyndication, ), ) def findSyndicationByLocalURL(url): """Find an ISyndication in syndications by the local URL it contains. """ The subschema is (the UUID field is the important part): class ISyndication(Interface): """Configuration for an individual feed. """ name = TextLine(title=_(u'Name'), description=_(u'...'), ) format = Choice(title=_(u'Format'), description=_(u'Data format for this feed'), values=[u'atom', u'rss 1.0', u'rss 2.0'], ) recurse = Bool(title=_(u'Recurse'), description=_(u'...'), default=False, ) enabled = Bool(title=_(u'Enabled'), description=_(u'...'), default=True, ) referring_URL = URI(title=_(u'URL'), description=_(u'...'), ) local_URL = URI(title=_(u'Local URL'), description=_(u'...'), ) UUID = TextLine(title=_(u'UUID'), description=_(u'UUID for this feed.'), required=False, readonly=True, ) I want to populate the UUID upon creation from a function. So I tried this (the __init__ is the important part): class Syndication(persistent.Persistent): """See ISyndication """ implements(ISyndication, IItemUUIDable) self.name = u'' self.format = u'' self.recurse = False self.enabled = False self.referring_URL = None self.local_URL = None def __init__(self): self.UUID = uuid1() However, the UUID field does not show up in the interface as initialized when I do: class SyndicationsEditForm(EditForm): """Edit form for syndications. """ form_fields = Fields(ISyndications) ow = CustomWidgetFactory(ObjectWidget, Syndication) sw = CustomWidgetFactory(SequenceWidget, subwidget=ow) form_fields['syndications'].custom_widget = sw label = u'Configure syndications' This seems like it should be an easy thing to do. Who can tell me what I'm doing wrong? Thanks, Derek The problem *may* stem from sequencewidget.py (lines 235-239 in Zope 3.3.1): # add an entry to the list if the add button has been pressed if self.name + ".add" in self.request.form: # Should this be using self.context.value_type.missing_value # instead of None? sequence.append(None) When I hack it just to prove a point, like so: # add an entry to the list if the add button has been pressed if self.name + ".add" in self.request.form: # Should this be using self.context.value_type.missing_value # instead of None? from plone.syndication.syndication import Syndication sequence.append(Syndication()) #sequence.append(None) The UUID field gets populated. But I'm not sure where to go with this. I don't see any bugs for SequenceWidget on launchpad, so I'm still figuring I'm doing something wrong... Derek ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
[Zope3-Users] Varying Default Value for Subschema (Object in Tuple)
I have a schema (the Tuple of Objects is the important part): class ISyndications(Interface): """Annotation that indicates the object can provide IFeed and that stores the current syndication configuration. """ enabled = Bool(title=_(u'Enable syndication'), description=_(u'...'), default=False, ) syndications = Tuple(title=_(u'Feeds'), description=_(u'...'), required=False, default=(), value_type=Object(title=_(u'Feed'), description=_(u'...'), schema=ISyndication, ), ) def findSyndicationByLocalURL(url): """Find an ISyndication in syndications by the local URL it contains. """ The subschema is (the UUID field is the important part): class ISyndication(Interface): """Configuration for an individual feed. """ name = TextLine(title=_(u'Name'), description=_(u'...'), ) format = Choice(title=_(u'Format'), description=_(u'Data format for this feed'), values=[u'atom', u'rss 1.0', u'rss 2.0'], ) recurse = Bool(title=_(u'Recurse'), description=_(u'...'), default=False, ) enabled = Bool(title=_(u'Enabled'), description=_(u'...'), default=True, ) referring_URL = URI(title=_(u'URL'), description=_(u'...'), ) local_URL = URI(title=_(u'Local URL'), description=_(u'...'), ) UUID = TextLine(title=_(u'UUID'), description=_(u'UUID for this feed.'), required=False, readonly=True, ) I want to populate the UUID upon creation from a function. So I tried this (the __init__ is the important part): class Syndication(persistent.Persistent): """See ISyndication """ implements(ISyndication, IItemUUIDable) self.name = u'' self.format = u'' self.recurse = False self.enabled = False self.referring_URL = None self.local_URL = None def __init__(self): self.UUID = uuid1() However, the UUID field does not show up in the interface as initialized when I do: class SyndicationsEditForm(EditForm): """Edit form for syndications. """ form_fields = Fields(ISyndications) ow = CustomWidgetFactory(ObjectWidget, Syndication) sw = CustomWidgetFactory(SequenceWidget, subwidget=ow) form_fields['syndications'].custom_widget = sw label = u'Configure syndications' This seems like it should be an easy thing to do. Who can tell me what I'm doing wrong? Thanks, Derek ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
[Zope3-Users] Re: Utility Local to an Annotation?
Derek Richardson wrote: Derek Richardson wrote: Benji York wrote: Derek Richardson wrote: The specific case is uuids for atom feed entries. We have annotations representing feeds and I would like my uuid utility to be local to the feed annotation, thus recording and making available uuids only for entries in that feed. How about a multi-adapter from content and feed to UUID? Hmmm, to do that I have to be able to annotate an annotation, right? As the feed is an annotation and that is where I want to store the UUIDs. I tried this tonight and was unable to make it work - I got the following: blah, blah, blah File "/Users/dkr/Zope-3.3.1/build/lib.darwin-8.8.1-i386-2.4/zope/security/adapter.py", line 84, in __call__ adapter = self.factory(*args) File "/Users/dkr/Zope-3.3.1/build/lib.darwin-8.8.1-i386-2.4/zope/annotation/factory.py", line 38, in getAnnotation annotations = IAnnotations(context) TypeError: ('Could not adapt', , ) I've made it further and am now getting a TraversalError. It seems the cause is that the annotation lacks __parent__, so I can't adapt it to IAnnotations using: zope.app.keyreference.persistent.connectionOfPersistent Any ideas about how I can give a __parent__ to an annotation? Debugging error. Please disregard. Sorry, Derek ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
[Zope3-Users] Re: Utility Local to an Annotation?
Derek Richardson wrote: Benji York wrote: Derek Richardson wrote: The specific case is uuids for atom feed entries. We have annotations representing feeds and I would like my uuid utility to be local to the feed annotation, thus recording and making available uuids only for entries in that feed. How about a multi-adapter from content and feed to UUID? Hmmm, to do that I have to be able to annotate an annotation, right? As the feed is an annotation and that is where I want to store the UUIDs. I tried this tonight and was unable to make it work - I got the following: blah, blah, blah File "/Users/dkr/Zope-3.3.1/build/lib.darwin-8.8.1-i386-2.4/zope/security/adapter.py", line 84, in __call__ adapter = self.factory(*args) File "/Users/dkr/Zope-3.3.1/build/lib.darwin-8.8.1-i386-2.4/zope/annotation/factory.py", line 38, in getAnnotation annotations = IAnnotations(context) TypeError: ('Could not adapt', , ) I've made it further and am now getting a TraversalError. It seems the cause is that the annotation lacks __parent__, so I can't adapt it to IAnnotations using: zope.app.keyreference.persistent.connectionOfPersistent Any ideas about how I can give a __parent__ to an annotation? Thanks, Derek ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
[Zope3-Users] Re: Utility Local to an Annotation?
Martin Aspeli wrote: Derek Richardson-2 wrote: Yes, it does feel like I'm going about this the wrong way. a - The "feed" is actually just configuration metadata - whether the feed is enabled, whether it is recursive, what its display name is, etc. The actual feed document is not stored - it is simply rendered dynamically when requested, based on the metadata and the existent content items. The "feed" is an annotation on a container; at the current time, only folders are feeds and only contained files are feed items. Okay, so the feed is really a view, which consults some annotations on a container and then recursively looks for objects in that container and constructs XML? Yes. b - In the Atom syndication format, UUIDs are necessary for two things. One, the overall feed has a UUID. This is easy - I'm storing them in a site-local named utility, indexed by the feed annotation object. What do yuo mean "indexed by"? Hand the utility a feed annotation, get back a uuid for the feed. Also, is this UUID not just another aspect of feed "metadata" and thus a candidate for the container annotation? This was the original plan, but I was convinced to go with the more generalized solution of a uuid utility. I guess I can cache it in the container annotation, but that's an optimization and tangential to this discussion. Two, each entry in a feed has a UUID. A content item that is an entry (a file, in the current case) can, however, be in multiple feeds and needs a different UUID in each. Thus, I need to be able to look up UUIDs by the content object that will be rendered as a feed entry and look them up relative to the feed, rather than globally. That sounds to me like you want a composite UUID - a UUID utility gives each content item a UUID (which is not feed-specific, and stays in line with the general concept of a content object UUID). The one you put in the feed is the feed's UUID and the object's UUID are combined. You could possibly use some kind of hash if you needed to. I considered this. I have a certain understanding of what I'm doing that precludes the combinatorial UUID approach, but no one I talk to seems to grasp it, so I think I will air it here so we can discuss it. I am using RFC 4122 type 1 UUIDs. These are (practically) guaranteed universally unique, as they are based on spatial (MAC address) and temporal (CPU clock time) location. They have safeguards built in for things like multiple CPUs and resetting the CPU clock. However, they are only (practically) guaranteed universally unique if *everyone* follows the same algorithm. If you use a different algorithm for computing your UUIDs, then they may collide with my RFC 4122 ones, since your algorithm doesn't compute them the same way and thus may use different, supposedly unique information included in a different way that results in the same UUID that I generate. Highly unlikely, but vastly more likely than if we all follow the RFC. Thus, to me, part of being a good citizen of the UUID world is to follow the exact RFC 4122 algorithm, so we can all get along without collisions. There is no provision in RFC 4122 for combining two UUIDs to generate a third, still unique, UUID. So, in my mind, combining two UUIDs, by whatever method, results in a relative UID, not a UUID. Granted, I live in a fantasy world where everyone plays by the same RFC 4122 rules. Still, it's a nice world and I want to do what I can to encourage others to join me in it. So, I want to generate strictly-compliant RFC 4122 UUIDs for use in my product (and my utility makes it easy for others to use them elsewhere in Zope). Thus I take the hard road, here. Is there a flaw in my reasoning? c - I use the UUIDs only when rendering the feed, looking them up by object and sending them to the client embedded in the feed document. They are used for no other purpose. Still, the concept of a UUID of a content object ought to be separate from and more general than your particular need for a feed item UUID. Right, you can still assign one (or more) UUIDs to any content object, if you have a use case. My UUID is for the (dynamically generated) feed item. The uuid utility is perfectly general and will let you assign a UUID to any object that can be adapted to KeyReference (or perhaps, in Zope2, any object that is usable by the intid utility). So, my situation is that I've written my nifty uuid utility based on intid and I want to reuse it for feed entry UUID lookup. I can't use unnamed utilities because I may be accessing different uuid utilities for entries from the same place in the tree. It occurs to me that I could make them named utilities local to the object underlying the entry and look them up by the feed UUID they correspond to, but, in my understanding, that would require littering sites all over the place, which seems like bad citizenshi
[Zope3-Users] Re: Utility Local to an Annotation?
Martin Aspeli wrote: Derek Richardson-2 wrote: Benji York wrote: Derek Richardson wrote: The specific case is uuids for atom feed entries. We have annotations representing feeds and I would like my uuid utility to be local to the feed annotation, thus recording and making available uuids only for entries in that feed. How about a multi-adapter from content and feed to UUID? Hmmm, to do that I have to be able to annotate an annotation, right? As the feed is an annotation and that is where I want to store the UUIDs. I tried this tonight and was unable to make it work - I got the following: There's no reason why you can't mark an object that you fish out of an annotation with IAttributeAnnotatable and then annotate that. However, this feels suspiciously like you're asking the wrong kind question. :) Can you explain (a) what you are trying to store (what is a "feed" in this case? is it just feed-specific metadata? or an actual list of items rendered to RDF?) and (b) what you need UUIDs for and (c) when you need to use the UUIDS? Yes, it does feel like I'm going about this the wrong way. a - The "feed" is actually just configuration metadata - whether the feed is enabled, whether it is recursive, what its display name is, etc. The actual feed document is not stored - it is simply rendered dynamically when requested, based on the metadata and the existent content items. The "feed" is an annotation on a container; at the current time, only folders are feeds and only contained files are feed items. b - In the Atom syndication format, UUIDs are necessary for two things. One, the overall feed has a UUID. This is easy - I'm storing them in a site-local named utility, indexed by the feed annotation object. Two, each entry in a feed has a UUID. A content item that is an entry (a file, in the current case) can, however, be in multiple feeds and needs a different UUID in each. Thus, I need to be able to look up UUIDs by the content object that will be rendered as a feed entry and look them up relative to the feed, rather than globally. c - I use the UUIDs only when rendering the feed, looking them up by object and sending them to the client embedded in the feed document. They are used for no other purpose. So, my situation is that I've written my nifty uuid utility based on intid and I want to reuse it for feed entry UUID lookup. I can't use unnamed utilities because I may be accessing different uuid utilities for entries from the same place in the tree. It occurs to me that I could make them named utilities local to the object underlying the entry and look them up by the feed UUID they correspond to, but, in my understanding, that would require littering sites all over the place, which seems like bad citizenship. So, I thought I'd just attach the utility to the "feed" (remember, metadata), so that I can access it through an adapter. Benji's short post gave me this idea. An alternative is perhaps that I can just directly use the uuid utility class from the "feed" class and avoid the annotations but have the same effect. In fact, since the UUID lookup is an integral part of the feed and not just an after-thought, this might indeed be more appropriate (and simpler) than the annotation. Both these approaches that I favor (annotations and direct usage) tightly couple the "feed" to the utility implementation, which is unfortunate if I want to swap in another uuid utility implementation (and, from what I've heard, this will be likely when I backport to Five). I hope this additional background makes things clearer. Thanks, Derek ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
[Zope3-Users] Re: Utility Local to an Annotation?
Benji York wrote: Derek Richardson wrote: The specific case is uuids for atom feed entries. We have annotations representing feeds and I would like my uuid utility to be local to the feed annotation, thus recording and making available uuids only for entries in that feed. How about a multi-adapter from content and feed to UUID? Hmmm, to do that I have to be able to annotate an annotation, right? As the feed is an annotation and that is where I want to store the UUIDs. I tried this tonight and was unable to make it work - I got the following: blah, blah, blah File "/Users/dkr/Zope-3.3.1/build/lib.darwin-8.8.1-i386-2.4/zope/security/adapter.py", line 84, in __call__ adapter = self.factory(*args) File "/Users/dkr/Zope-3.3.1/build/lib.darwin-8.8.1-i386-2.4/zope/annotation/factory.py", line 38, in getAnnotation annotations = IAnnotations(context) TypeError: ('Could not adapt', , ) Did you have something else in mind? Or is annotating an annotation possible and something is wrong in my implementation? Thanks, Derek ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
[Zope3-Users] Utility Local to an Annotation?
I would like to create utility instances that are local to annotation instances. Each utility would be valid only within the scope of the related annotation. The specific case is uuids for atom feed entries. We have annotations representing feeds and I would like my uuid utility to be local to the feed annotation, thus recording and making available uuids only for entries in that feed. See http://www.openplans.org/projects/vice/uuids-in-atom for more details and an architectural diagram. FYI, an object can be syndicated in more than one feed. Thus, for feed X, I want to look up the uuid associated with object a for feed x; for feed y, I would want the *different* uuid associated with object x (same object) for feed y. However, I am not sure I can turn an annotation into a site and, even if I can, am not sure that's what I want to do. Comments? Suggestions? Thanks, Derek ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
[Zope3-Users] Re: zope.intid and UUIDs
Philipp von Weitershausen wrote: Martin and Gary pointed out other good reasons why not to go with subclassing: the standard intid utility doesn't work in all environments. Apparently in Zope 2 you'll need a slightly differnet implementation. If you just defer to it via utility lookup, your UUID utility might actually work on both platforms, as long as there's an intid utility. It makes things more flexible. Hmmm. I've looked in Zope 2.10.3 final (the earliest release I may target) and zope.app.intid is the same between Zope 2.10.3 and Zope 3.3.1, except for the presence in 2.10.3 of zope.app.intid-configure.zcml, which is just a slug. Am I looking in the wrong place? Your subclassing idea has a lot of appeal to it. To answer your question what's suboptimal about it: you'll have to wait till the next Zope 3 release cycle to actually make use those modifications. Also, like I said above, the composition approach allows you to be more flexible. OK, yes, this is a problem. I'm targeting on Plone 3.5 (for the final product, not the uuid utility alone), but I'd like to be backwards-compatible with Zope 2.10.x. So, yes, I'll have to provide a complete backwards-compatible package. I've thought about it and decided that these two proposals (subclassing and composition) are partially orthogonal. Half of subclassing is simply genericizing the interfaces; composition is a matter of implementation. For proof, consider that we could have a UUIDs that implements IIDs and defers to an IntIds for implementation, which also implements IIDs. This might reduce the benefits of code reuse, but would still gain the benefit of one set of interfaces (aside from the IntIds and UUIDs markers). So, my plan. I am going to copy IntIds, genericize the interfaces, and split the superclass from the subclass as mentioned. I'm going to do this in my package. I will provide a UUID implementation but not an IntId implementation. That way if, in the future, y'all decide to move towards this in the core, there will be a pre-existing implementation and I'll be ready. You could include just the interfaces, the interfaces and the utility superclass with a new IntIds subclass without the UUID implementation, or you could include everything - it's up to you. And, if you don't, then I haven't lost anything but 15 minutes of time. As for implementation, I'm going to have to think through whether composition is appropriate for my use. Another advantage of genericizing the interfaces is that this is an implementation detail - I may provide two uuid implementations, one that is composed by intid and one that is not. I may also rethink the implementation of the base utility class to see if I can maximize reuse between these two cases. And, having this flexibility will help me later if I run into trouble backporting to Zope 2.10.x. A fun project! The code will be in the Vice project in the Plone collective, for now, in the packages collective.id and collective.uuid. Thanks, Derek ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
[Zope3-Users] Zope as an XML-RPC *Client*
A colleague is interested in using Zope 3 (and, if possible, Grok) to write a web app whose objects live, not in the ZODB or in an SQL DB, but on the other end of XML-RPC calls. I am unclear how to implement this one. Would an application of this type even have content objects? If not, how would it be architected? Thanks, Derek ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
[Zope3-Users] Re: zope.intid and UUIDs
Philipp von Weitershausen wrote: Derek Richardson wrote: I sense that I'm missing the point here. Perhaps you can elaborate on what you mean when you say "use" and "collaboration." I usually know what those terms mean, but I'm not sure I am getting it in this context. The paragraph definitely seems to miss the point, so let me speak code:: class UUIDUtility(Contained, Persistent): def __init__(self): self.uuids = IOBTree.IOBTree() self.intids = OIBTree.OIBTree() def getObject(self, uuid): intid = self.intids[uuid] return getUtility(IIntIds).getObject(intid) def getUUID(self, object): intid = getUtility(IIntIds).getId(object) return self.uuids[intid] I'm omitting several seatbelts and various functions to add/remove objects from the UUID utility, but I hope you'll get the idea. With the composition approach, the actual utility class may be a little shorter than simply copying the whole thing, but I'll still have to copy and just change the names on a bunch of stuff in interfaces.py (IIntIds -> IUUIDs, IIntIdsQuery -> UUIDSQuery, etc). And I'll have to copy most of the tests. It still seems to me that the best approach is: class BaseIdUtility(Contained, Persistent): implements(IIds) def getObject(self, id): return self.refs[id]() def getId(self, object): ... # 9 lines of code ... # registration functions and the like and class IntIdUtility(BaseIdUtility): implements(IIntIds) # marker def __init__(self): self.ids = OIBTree.OIBTree() self.refs = IOBTree.IOBTree() self.added_event = IntIdAddedEvent self.removed_event = IntIdRemovedEvent def _generateId(self): """Generates a unique integer id. """ ... # this is 8 lines of code and class UUIDUtility(BaseIdUtility): implements(IUUIDs) # marker def __init__(self): self.ids = OOBTree.OOBTree() self.refs = OOBTree.OOBTree() self.added_event = UUIDAddedEvent self.removed_event = UUIDRemovedEvent def _generateId(self): """Generates a RFC 4122 uuid. """ return uuid1() The subclasses are pretty much complete as written here and the BaseIdUtility is just a minor abridgment of IntIds. This allows all the interfaces (other than the two empty markers and the events) to be reused between intids and UUIDs and most of the tests can be performed for both, as well. We've talked a lot about the composition alternative to my idea, but we haven't talked about my idea much. What is suboptimal with the way I'm proposing, other than that it requires changing zope core? Or is that a good enough reason to not do it? Derek ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
[Zope3-Users] Re: zope.intid and UUIDs
Benji York wrote: Derek Richardson wrote: I wrote most of it today and there is more code shared between the two than is different. The main differences are: * OOBTrees, instead of an IOBTree and an OIBTree * Different events are fired when an object is registered and unregistered (they could be merged, but this is easy backwards-compatibility) * _generateId() is, of course, different The rest is pretty much copied and pasted, even most of the tests. This suggests to me that you instead want to /use/ an int ID utility, not /be/ (a mutated) one. Unless there's a very compelling reason to copy all that functionality composition would be much cleaner. I definitely don't want to be an *int* id utility. I may want to be, however, a uuid variety of an *id* utility, of which another variety would be int, and perhaps others, as well. I see no compelling reason to copy all that functionality, which is why I'm exploring alternatives. *Using* an int id utility, though, doesn't seem to cleanly solve the problem, which makes me wonder if I'm understanding you. If you mean use the intid utility to map keyrefs to int ids and then map int ids to uuids, this has a few problems. What I want to vary is the implementation - I want to keep the same interface. This would be keeping, and adding another layer to, the implementation and I'll still have to re-implement the interface on top of it. That's more work than just copying and doesn't reduce the copying at all, as I see it. Plus, it'll be (perhaps marginally) slower. If you mean use the intid utility by instantiating one and then changing the data structures and _generateId() and the events at runtime, this would indeed solve the need to copy and paste. However, this seems like an obfuscating solution - who would guess that what is masquerading as an intid utility is really a uuid utility? Perhaps that's my static-typing background speaking, but it seems cleaner to have an "abstract" id utility and then write 10 lines of code to subclass and turn it into an int id utility and then another 10 lines for uuids. I sense that I'm missing the point here. Perhaps you can elaborate on what you mean when you say "use" and "collaboration." I usually know what those terms mean, but I'm not sure I am getting it in this context. Derek ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
[Zope3-Users] Re: zope.intid and UUIDs
I have no principled objection to a ZPL license. And I would like the code to make it into the core, if appropriate. So, the answer is, a ZPL license is likely. David Pratt wrote: I like this idea of abstracting the code for ids myself. It will be interesting to hear what others have to say. Can you advise whether the UUID utility will be ZPL licensed since this is important if you are talking about something with generic functionality for z3. Many thanks. Regards, David Derek Richardson wrote: All, I've decided to go ahead and write an RFC 4122 UUID utility based on zope.intid (this is for a Plone SoC project, but this bit is pure Zope 3). I wrote most of it today and there is more code shared between the two than is different. The main differences are: * OOBTrees, instead of an IOBTree and an OIBTree * Different events are fired when an object is registered and unregistered (they could be merged, but this is easy backwards-compatibility) * _generateId() is, of course, different The rest is pretty much copied and pasted, even most of the tests. My question is: should the common parts be abstracted out into a framework for id utilities, of which intid and uuid will be two instantiations? I know this is a small amount of code but: * I hate copy and paste * I hate the idea of bugs in two places (implicit coupling, from a bug fixer's perspective) * Larger codebases mean more to read to understand what is going on for newbies, like me Of course, the duplication rule is "If you do it three times, you're doing it wrong" and I've only done it the second time. So, part of this question is whether anyone can see a future need for any id utilities other than intid and uuid. If so, I think this would definitely be a good move. Otherwise, I'm up in the air. Of course, this would be a change to zope core, which is the main reason I'm leery. I will be sending in my contributor agreement tomorrow. So, I'm really wondering whether this is worth changing in the core or whether we shouldn't bother. Thanks, Derek ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
[Zope3-Users] zope.intid and UUIDs
All, I've decided to go ahead and write an RFC 4122 UUID utility based on zope.intid (this is for a Plone SoC project, but this bit is pure Zope 3). I wrote most of it today and there is more code shared between the two than is different. The main differences are: * OOBTrees, instead of an IOBTree and an OIBTree * Different events are fired when an object is registered and unregistered (they could be merged, but this is easy backwards-compatibility) * _generateId() is, of course, different The rest is pretty much copied and pasted, even most of the tests. My question is: should the common parts be abstracted out into a framework for id utilities, of which intid and uuid will be two instantiations? I know this is a small amount of code but: * I hate copy and paste * I hate the idea of bugs in two places (implicit coupling, from a bug fixer's perspective) * Larger codebases mean more to read to understand what is going on for newbies, like me Of course, the duplication rule is "If you do it three times, you're doing it wrong" and I've only done it the second time. So, part of this question is whether anyone can see a future need for any id utilities other than intid and uuid. If so, I think this would definitely be a good move. Otherwise, I'm up in the air. Of course, this would be a change to zope core, which is the main reason I'm leery. I will be sending in my contributor agreement tomorrow. So, I'm really wondering whether this is worth changing in the core or whether we shouldn't bother. Thanks, Derek ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
[Zope3-Users] Re: RFC 4122 UUIDs
Stephan Richter wrote: On Thursday 05 April 2007 15:28, Jürgen Kartnaller wrote: Please do not use an annotation! This is a performance issue. Your data is very small so do not create a new object in the database store it directly as a property on the instance. Every object lookup is expensive, especially if you use ZEO! Hey Juergen, come on! I know you guys are on an optimization trip at Lovely, but this is great information to store on an annotation. The UUID does not usually need to be looked up and is mainly for external world reference, such as feeds like Derek metioned he wanted. The package is also an add-on. You don't need it, then do not use it. As further optimization, Derek mainly needs this id for a very specific set of content types, so I would narrow the subscriber to only give those special types a UUID. Regards, Stephan My use case is very constrained - I need UUIDs for syndicated objects only. So, potentially, I could just generate and assign them when content is syndicated and keep them in an annotation I'm already using for syndication. However, as Martin Aspeli mentioned, this functionality seems ripe for a general-purpose package. If I split it out into its own add-on, it's more work for me but perhaps generally useful. I've seen past buzz about UUIDs in Zope, but it seems nothing has ever come of it. My question is: are there potential use cases, outside of my own, that justify the extra work to make it a separate add-on? And, if so, what are these use cases and what do I need to do to support them? I could see that there might be performance-sensitive applications that would need UUIDs on many objects, but I don't know of one. Does anyone else? The scenario I'm most trying to avoid is several different packages implementing UUIDs and objects getting multiple UUIDs, one from each package, all implemented different ways, because of the lack of a general solution. Derek ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
[Zope3-Users] Re: RFC 4122 UUIDs
Martin Aspeli wrote: Derek Richardson-2 wrote: Martin Aspeli wrote: Stephan Richter-2 wrote: On Wednesday 04 April 2007 13:06, Derek Richardson wrote: I am hoping that Zope 3 assigns an RFC 4122 UUID to each content item. If not, I am hoping there is a third-party product to do this. No there is neither. We have an intid utility that guarantees System-wide unique ids. This utility is used at several places most notably the catalog. I would like RFC 4122 UUIDs to provide standard Atom feeds of Zope content [1]. It will be better if Zope itself assigns UUIDs, so that there is a single source and not a possibility of multiple packages assigning different UUIDs to the same content item. You have to write your own utility to generate the UUID. I checked the RFC quickly and our IntIds are certainly not of the format requested by RFC 4122. Presumably, the intid implementation would be a useful reference for such a utility, and this would a good canidate for a general, re-usable package. Martin Good. I would like to write it as a general, re-usable package. Generating RFC 4122 UUIDs is easy - there's a routine for it in the python 2.5 standard libraries and a python 2.3+ version here: http://zesty.ca/python/uuid.html What seems more difficult is how to plug the routine in so that all content items receive one and only one UUID upon creation. Maybe listen for IObjectCreatedEvent and annotate then? Or is there a potential race condition that means events are not the way to go? (Unsure of the depths of Zope 3's architecture) Look at zope.intid; it should be IObjectCreatedEvent or IObjectAddedEvent. Martin I have started coding a uuid package for Zope. zope.intid uses IObjectAddedEvent; I plan to as well. However, the uuid differs from the intid in that I want to store the uuid on the object, rather than in a utility. This will ensure that uuids travel with their objects without having to modify import/export or other code. My initial idea is to use an annotation, but I'm not sure this is right. I'll have to annotate all the content classes in the system, which seems to be a *huge* zcml pain. Any advice for avoiding this? Thanks, Derek ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
[Zope3-Users] Re: RFC 4122 UUIDs
Fred Drake wrote: On 4/5/07, David Pratt <[EMAIL PROTECTED]> wrote: The UUID generator that I have been looking at is with the Chandler project (currently under Apache license) that could be easily wrapped: Python 2.5 comes with a "uuid" module that works just fine with Python 2.4; that comes in handy as well, and doesn't need wrapping. -Fred Yes, at the cheesehop (uuid, not pyuuid). That's what I am starting to use for my uuid package for zope. Derek ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
[Zope3-Users] Re: RFC 4122 UUIDs
I believe that that will not guarantee a *universally* unique id, but only an id unique within that ZODB. Am I wrong? The RFC prescribes a specific algorithm for generating universally unique IDs. Derek Benji York wrote: Derek Richardson wrote: I am hoping that Zope 3 assigns an RFC 4122 UUID to each content item. If not, I am hoping there is a third-party product to do this. I would use the standard intid utility and simply encode the generated integer as a UUID. ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
[Zope3-Users] Re: RFC 4122 UUIDs
Martin Aspeli wrote: Stephan Richter-2 wrote: On Wednesday 04 April 2007 13:06, Derek Richardson wrote: I am hoping that Zope 3 assigns an RFC 4122 UUID to each content item. If not, I am hoping there is a third-party product to do this. No there is neither. We have an intid utility that guarantees System-wide unique ids. This utility is used at several places most notably the catalog. I would like RFC 4122 UUIDs to provide standard Atom feeds of Zope content [1]. It will be better if Zope itself assigns UUIDs, so that there is a single source and not a possibility of multiple packages assigning different UUIDs to the same content item. You have to write your own utility to generate the UUID. I checked the RFC quickly and our IntIds are certainly not of the format requested by RFC 4122. Presumably, the intid implementation would be a useful reference for such a utility, and this would a good canidate for a general, re-usable package. Martin Good. I would like to write it as a general, re-usable package. Generating RFC 4122 UUIDs is easy - there's a routine for it in the python 2.5 standard libraries and a python 2.3+ version here: http://zesty.ca/python/uuid.html What seems more difficult is how to plug the routine in so that all content items receive one and only one UUID upon creation. Maybe listen for IObjectCreatedEvent and annotate then? Or is there a potential race condition that means events are not the way to go? (Unsure of the depths of Zope 3's architecture) Derek ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
[Zope3-Users] RFC 4122 UUIDs
I am hoping that Zope 3 assigns an RFC 4122 UUID to each content item. If not, I am hoping there is a third-party product to do this. I would like RFC 4122 UUIDs to provide standard Atom feeds of Zope content [1]. It will be better if Zope itself assigns UUIDs, so that there is a single source and not a possibility of multiple packages assigning different UUIDs to the same content item. I googled (of course) but was unable to draw any definite conclusions from my results. Thanks, Derek [1] http://www.atomenabled.org/developers/syndication/atom-format-spec.php#element.id The "atom:id" element conveys a permanent, universally unique identifier for an entry or feed. atomId = element atom:id { atomCommonAttributes, (atomUri) } Its content MUST be an IRI, as defined by [RFC3987]. Note that the definition of "IRI" excludes relative references. Though the IRI might use a dereferencable scheme, Atom Processors MUST NOT assume it can be dereferenced. When an Atom Document is relocated, migrated, syndicated, republished, exported, or imported, the content of its atom:id element MUST NOT change. Put another way, an atom:id element pertains to all instantiations of a particular Atom entry or feed; revisions retain the same content in their atom:id elements. It is suggested that the atom:id element be stored along with the associated resource. The content of an atom:id element MUST be created in a way that assures uniqueness. ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users