[Zope3-Users] Buildout and the Data.fs
When developing and/or deploying using Buildout, how do you deal with the Data.fs? I'm particularly concerned with running on different environments (desktop development, server development, staging, deployment) as I don't want the Data.fs to be under source control nor inside the application package at all, really. In some of my playing around, I've often blown away the local Data.fs, either by doing a 'git clean' or just by tinkering with my buildout.cfg. I know that buildout supports extending other buildout.cfg files. Is the best option to have a different buildout.cfg for every environment? As a side question then, is buildout:directory relative to a config file, or relative to where buildout is being run? I'd like to have a base buildout.cfg in the base, but put the others in a sub-dir. ie: myapp/buildout.cfg -- ... ; generates zope.conf [zope.conf] recipe = z3c.recipe.filetemplate files = zope.conf here = ${buildout:directory} site_definition = site.zcml zodb = ${database:zconfig} devmode = on myapp/etc/jeffdesktop.cfg: --- [buildout] extends = ../buildout.cfg [database] recipe = zc.recipe.filestorage path = ${buildout:directory}/var/Data.fs myapp/etc/deployment.cfg --- [buildout] extends = ../buildout.cfg [database] ; can't remember the ZEO configs, but ; let's pretend this one sets up a ZEO client. - I should be able to run:: myapp buildout -c etc/jeffdesktop.cfg And it would run relative to 'myapp', I would imagine. Anyways - is this the best option, bad idea, better ideas? I've been basing my latest buildout experiments on the style generated by zopeproject (using 'paster serve', none of the zope3instance/whatsit recipes, as I still don't really understand those and the zopeproject one seems simpler). I've modified it by playing with some of the 'filetemplate' recipes to try to keep any generated ZCML, zope.conf, whatever, in a format that's easier for me to see and understand; I think I'm finally coming up with a working buildout based setup!! Well, I've got one working, but now I'm trying to understand it better and polish it up. Thanks, Jeff Shell ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
[Zope3-Users] Zope on WSGI for Deployment - best to still use proxy behind apache? Good/bad servers?
While continuing to experiment with buildout options and restructuring one of our applications to be self-contained, I started experimenting with a setup based on what zopeproject generates, which includes being able to run via 'paster serve'. I was pleasantly surprised to see Zope run on different servers, including CherryPy. Our deployments for the past many years have been behind Apache via mod_proxy. I imagine this combination would continue to work just fine with Zope running on a different server. Seeing this post about Trying on different WSGI Servers: http://blog.repoze.org/fitting_room-20071029.html got me to thinking about running on something different if we could get better performance, although my quick tests didn't produce much difference between `egg:Paste#http`, CherryPy, or ZServer. About the only thing that I saw of any interest was warnings about more threads running than there were available ZODB connections (seen on CherryPy, and I think on Paste#http too), but I didn't spend any time configuring the server settings aside from the serving-port. Is there any preferred server to use or not use? why? And ... mod_wsgi. I don't know much about it, but is it better to run through that than to go through mod_proxy? Or nginx? We had one new customer totally surprise us with their traffic/load (mostly solved, for now, due to some aggressive caching) and I'm interested in trying to find new setups. Thanks, Jeff Shell ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
Re: [Zope3-Users] Re: buildout and egg depedencies
the circumstances my little company is operating in right now. Buildout *seems* like it could fix some big problems that have been hitting us hard in recent weeks. But I still can't wrap my head around how. Maybe you should start a new thread and tell of your use cases and ask for examples of how to solve them? Now that I'm getting farther along, I should be able to do that. If I have time. Got a lot of pressure things the next couple of days :(. -- Jeff Shell ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
Re: [Zope3-Users] buildout and egg depedencies
On Dec 6, 2007 8:08 AM, Benji York [EMAIL PROTECTED] wrote: Jim Fulton wrote: None of the above. What is the harm of the dependencies? One of the options included in none of the above is to not use buildout at all. Forget that the project in question uses buildout (or setuptools) and integrate it into your project however you would have before those tools existed (svn:externals, make a checkout, whatever). That's such a disappointing answer. It's one that I've gotten a couple of times when I've said hey, I'm trying to move to a release based system using distutils and setuptools and I'm floundering. And I have made our own system. And it's I don't know. I'd like to spend more time solving customer problems than figuring out how to install our solutions to customer problems. We're in desperate need of reliable, repeatable distributions. DESPERATE. How did it come to be that the Python tools are so bad at this? Setuptools is horrible when it comes to doing local (instance-home-ish) installations, requiring virtualenv or whatever. And I've had little success getting those to work. Maybe they just break my way of thinking about how Python does and should work. Whatever. Buildout looks like it tries to address many of those issues, but again I find myself fighting against my natural instincts. Where's some end user documentation? The doc-test is difficult to read and speaks in generics, not about day-to-day problems. The Recipes are even worse, leaving one to clamor through the web to get back to the cheeseshop page and then face the same difficult to read doc-test kind of 'help'. Which I wouldn't mind reading, if I could easily read that help locally, like a man page or using Python's 'help()' system. ``buildout help zc.recipe.egg``, ``buildout help zc.recipe.cmmi``, whatever. That I'm still frustrated by these tools all this time later is disappointing. And yes, it's easier to write your own. That's the Python way. Don't understand [zope, pylons, cherrypy, quixote, skunkweb]? Write your own web framework! Python does make it easy to do that because it's such a fantastic language. But I think that attitude, in turn, gives us worse tools, because everyone scratches their own itch and moves on, leaving everything incomplete. It seems almost like it's easier to write your own tool than to read whatever cryptic documentation exists for another. I've gotten Buildout to work on some small components. It's great - check out the source, run buildout, wait, wait, wait, and then have a nice little self contained testing and development environment. But I've never been able to get a full Zope 3 Application up and running in that environment. There's just no time and the tools are just too hard to learn under the circumstances my little company is operating in right now. Buildout *seems* like it could fix some big problems that have been hitting us hard in recent weeks. But I still can't wrap my head around how. -- Jeff Shell ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
Re: [Zope3-Users] buildout and egg depedencies
of people have. I expect that there are a number of examples. One example is the zc.z3monitor buildout, svn://svn.zope.org/repos/ main/zc.z3monitor/trunk. This buildouts out a working ZEO server and a minimal Zope 3 application that uses it. Others might be able to suggest better examples, Thanks, Jeff Shell ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
Zope 3 w/ SQLAlchemy 0.4 (was Re: [Zope3-Users] Eggs and classic instance homes, again...)
On Nov 9, 2007 12:04 AM, Hermann Himmelbauer [EMAIL PROTECTED] wrote: Am Freitag, 9. November 2007 01:31 schrieb Jeff Shell: - zope.component 3.4.0 (or anything built into the zope 3.4 tarball) - sqlalchemy 0.4.0 - simplejson Btw., how do you integrate Zope3 with SQLAlchemy 0.4? As far as I know zalchemy is not SQLAlchemy-0.4 ready yet? We have an in-house solution/framework. And it's actually not ready for SQLAlchemy 0.4 yet either :). I do have a branch for it, but I haven't been working on any major RDBMS backed projects lately. The above list was more of an example than a list of requirements from any existing app. For core connection and integration, I take a lot of inspiration from zalchemy and some other toolkits, and the last bit of work I did towards SQLAlchemy 0.4 integration came from there. -- Jeff Shell ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
Re: [Zope3-Users] Eggs and classic instance homes, again... (was Re: Eggs, workingenv.py, and 'classic' instance homes)
Oops. Forgot to send this to the list as well as Stephan. Goddamn Gmail. On Nov 8, 2007 8:28 AM, Stephan Richter [EMAIL PROTECTED] wrote: Hi Jeff, last time I promised I would be more responsive to your mails, so here you go. :-) Thanks! First of all, let me say that I have no system in production yet, which uses eggs. I think only Lovely Systems and Zope Corp. do; and maybe some smaller applications. So I would not worry about not being up-to-date. In fact, the last stable release is still 3.3.1, which tells the story of the big Zope 3 tree. That said, have you seen my Zope 3.4.0b2 announcement _[1]? It was the first public announcement making people aware that eggs are really happening. I purposefully did not say that Zope 3.4 will be the last tarball release, because (a) I think we cannot abandon people that quickly and (b) it is now really easy to create a new tarball release thanks to a couple of scripts I wrote. This is where I start to get confused. I understand, and am glad for, the continuation of tarball releases for this round. My main question is: how does one mix and match? We have a lot of external software requirements and I'd rather get some of those as eggs than keep doing individual subversion checkouts. My big concern, which is something that affects all packaging systems, is how to tell packaged stuff that hand-build stuff meets the requirements. If I want to use an egg in a particular environment that has dependencies on: - zope.component 3.4.0 (or anything built into the zope 3.4 tarball) - sqlalchemy 0.4.0 - simplejson Would it know that zope.component was already offered via the whole Zope 3.4 tarball? It seems like you do things the classic way, or the egg/buildout way, and nothing in between. This makes things like z3c.form intimidating to me because I don't know if/how it will work in my vanilla zope environment (and with such a long time span between 3.3.1 and the eventual 3.4, I doubt it or its dependencies could work in 3.3.1). I may be wrong about all of that, but that's how I currently perceive things. Things just look so different between the two. -- Jeff Shell ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
Re: [Zope3-Users] Eggs and classic instance homes, again... (was Re: Eggs, workingenv.py, and 'classic' instance homes)
On Nov 7, 2007 7:53 PM, Darryl Cousins [EMAIL PROTECTED] wrote: Hi Jeff, I hope that this might at least give you the optimism you appear to be lacking. Thank you. That does give me a much more clear starting point. I was having a hard time seeing all of the recipes come together. As for optimism... We'll see. :) But this was the step I could never make work (getting a buildout-managed instance up and running) before running out of time. Thanks again. -- Jeff Shell ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
[Zope3-Users] Eggs and classic instance homes, again... (was Re: Eggs, workingenv.py, and 'classic' instance homes)
The last time I was active on this list was back in mid-august. I was fighting an uphill battle to try to figure out how to migrate our software to 'Eggs'. I ultimately had to abandon the process as there was just too much real work to be done, and I was getting conflicting answers about how to move forward. Actually, I couldn't get much help from the community at all. I apologize for the crankiness of this email. The last time I tried to get help on this topic was an excercise in sheer frustration. Since then, the gulf I've worried about seems to have gotten even bigger, and I'm feeling very stressed right now. So now I see all that's going on with Zope 3 and I still don't understand a thing about how to move forward. We have about twelve active customers deployed on Zope 3, on top of one or two large frameworks that we've built on top if Z3. We still use the basic 'instance home' layout. We don't use eggs - we just check things out directly into the instance home. Even stuff from the Zope community, because it's easier to do that than to even get workingenv or any of these other things running. I'm still lost about what to do. Grok is of no use to us at the moment. Many of these apps have been up and running for longer than Grok's been alive. Is there any kind of migration documentation out there? Or have these new ways of doing things been in use for so long that most people have just rolled along with them? I just don't have the time. I scarcely have time to keep up with the lists (which is obvious since I haven't read a thing for nearly three months). I'm going to resume my conversation here, responding to myself. August 16, 2007, Jeff Shell wrote: Jeff Shell wrote: But now I'd like to be able to install that into classic zope 3.3 instance homes, trying to be as unobtrusive as possible. How have you installed other packages before? I suspect by just dumping their source in INSTANCE/lib/python. Any reason not to continue to do that? Because I feel like we're falling further and further behind, or at least trapped in our own little world. Yep, this is becoming even more true. We're now even further behind. But yes, this is how we did it. I ended up writing most of rocketbuild/rockout (our Rake-ish tool) because of this. There are a lot of external tools out there that we still don't use because we don't have the time to deal with the headache (made minor by `rockout`, but still present) of dumping sources into lib/python. For internal stuff, it's not so bad. I want to get away from this (using source control as distribution mechanism). Eggs and buildout are supposed to help here, but ultimately it was easier to roll our own tool as we just could not figure out how to apply them to our configurations. We're about to do a massive server upgrade, which would be a good time to sneak in new deployment practices. The longer we avoid whatever is going on with setuptools and buildout, the harder it will be to migrate. It's hard enough already. Yep. Feels even harder now, but probably because they cause me so much stress just by looking at them. That seems backward. If you want to install an package into a classic environment, it doesn't seem that surprising you'll also have to do it the classic way... It doesn't seem entirely backward. I mean, it does. But at the same time... I just don't know how it's all supposed to work. But if we keep doing things in the 'classic' way without trying to step forward, then I fear we'll stay this way forever because it's already scary enough peeking over the hill at how buildout and all of that stuff works and how different it is from how we've done things. I don't want the gulf to get bigger, because I think that with our plans for growth and for a more distributed deployment server setup, 'buildout' will help tremendously. I'm just trying for baby steps right now, because it feels like we've still got a long way to go to get to anything better. I saw mention of 'workingenv' in your book, so I assumed it was or is possible to easily have instance homes with locally managed eggs. Shouldn't it be? Still have a long way to go. Still have no answers for what to do or how to start migrating. Some of our problem is caused by the stupidity of CVS, which will go away when we migrate to Git. Is there going to be a Zope 3.4, for real this time? Will it offer the clues I'm looking for? 'zopeproject' says 'You can start a new Zope-based web application from scratch with just two commands'. But what about those of us who have started many many Zope based web projects? Thanks, Jeff Shell ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
Re: [Zope3-Users] Kupu and Zope3
On Aug 20, 2007, at 3:45 AM, Jeremy Cook [EMAIL PROTECTED] wrote: Is anyone using Kupu (or any other visual editor) with zope3? I saw hints that it might be ported to zope3 or conversely that kupu must die. When I tried installing it under zope3 I didn't get awfully far. I tried and tried to use Kupu, and it was damn near impossible. I wouldn't recommend it to anybody. Which is too bad - the editor itself is great. But integrating it into custom environments was way too difficult. We went with TinyMCE. It gets the job done. I yearn for more though. Kupu's ability to have link and image browsers is great. TinyMCE has them available, but as commercial add-ons. ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
Re: [Zope3-Users] Re: ObjectModifiedEvent but not ContainerModifiedEvent
On Aug 17, 2007, at 5:29 PM, Chris Withers [EMAIL PROTECTED] wrote: Martin Aspeli wrote: def handler(event): if IContainerModifiedEvent.providedBy(event): return ...which is pretty inefficient. All the subscriber lookup, etc, has to happen to get this far. There must be a better way.. Well, a container is an object. It's being modified by the sake of its content changing. So it makes sense that a container modified event is a specialized extension of object modified. Better way? The only better way, really, would be doing a re-dispatch. Or fire off your own event when you modify other properties on a container. Or kick all of the code that sends modified events so that they send along descriptions of what has changed. Sometimes I want to respond only when a Dublin core element has changed - ie, to clear a cache. I ended up writing a replacement for formlib's applyChanges so that it not only returns a true/false value if changes where made, but also a sequence of Modified descriptions for each changed field. Then when these are included with the modified event, I can do further filtering within my code to see what exactly changed. ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
[Zope3-Users] Eggs, workingenv.py, and 'classic' instance homes
My office's migration to eggs and the like is going slowly (too much other work to do). However, I'm trying to do new work in the 'right' way and use eggs and buildouts for making small reusable packages. I did such a package yesterday and it works like a champ on its own: buildout can get everything it needs to run the tests, the tests have 100% coverage (yay!), etc. But now I'd like to be able to install that into classic zope 3.3 instance homes, trying to be as unobtrusive as possible. I tried using 'workingenv.py' and it looked like a decent solution...for a moment. However, when I try to install my component it then starts trying to install the dependencies. Even when I specify '--no-deps' to easy_install. Since the Zope 3.3 installation satisfies most of my component's dependencies, I don't want it fetching everything else. But I do want it to get those pieces for testing, etc. I've worried about this issue for a while -- how to get setuptools to ignore dependencies that are satisfied by some big installation like Zope 3.3. In my setup.py, should I move all of my 'install_requires' bits that are satisfied by a regular Zope installation into an 'extras_require'? Thanks, Jeff Shell ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
Re: [Zope3-Users] Eggs, workingenv.py, and 'classic' instance homes
We don't use subversion. I wish we did... Or something like it. But my fallback plan is something similar - use our rockout scripts to automate checkouts into auto-built namespace packages. Its how we get things like zc.resourcelibrary now. I'd like to move to using proper releases, but it's been an uphill battle just to get this far. On Aug 16, 2007, at 11:29 AM, Benji York [EMAIL PROTECTED] wrote: Jeff Shell wrote: But now I'd like to be able to install that into classic zope 3.3 instance homes, trying to be as unobtrusive as possible. I don't know anything about workingenv, but I would just use Subversion externals. -- Benji York Senior Software Engineer Zope Corporation ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
[Zope3-Users] Re: Eggs, workingenv.py, and 'classic' instance homes
Jeff Shell wrote: But now I'd like to be able to install that into classic zope 3.3 instance homes, trying to be as unobtrusive as possible. How have you installed other packages before? I suspect by just dumping their source in INSTANCE/lib/python. Any reason not to continue to do that? Because I feel like we're falling further and further behind, or at least trapped in our own little world. But yes, this is how we did it. I ended up writing most of rocketbuild/rockout (our Rake-ish tool) because of this. There are a lot of external tools out there that we still don't use because we don't have the time to deal with the headache (made minor by `rockout`, but still present) of dumping sources into lib/python. For internal stuff, it's not so bad. The longer we avoid whatever is going on with setuptools and buildout, the harder it will be to migrate. It's hard enough already. I tried using 'workingenv.py' and it looked like a decent solution...for a moment. However, when I try to install my component it then starts trying to install the dependencies. Even when I specify '--no-deps' to easy_install. Sounds like a bug in easy_install or workingenv then... Since the Zope 3.3 installation satisfies most of my component's dependencies, I don't want it fetching everything else. But I do want it to get those pieces for testing, etc. I've worried about this issue for a while -- how to get setuptools to ignore dependencies that are satisfied by some big installation like Zope 3.3. In my setup.py, should I move all of my 'install_requires' bits that are satisfied by a regular Zope installation into an 'extras_require'? That seems backward. If you want to install an package into a classic environment, it doesn't seem that surprising you'll also have to do it the classic way... It doesn't seem entirely backward. I mean, it does. But at the same time... I just don't know how it's all supposed to work. But if we keep doing things in the 'classic' way without trying to step forward, then I fear we'll stay this way forever because it's already scary enough peeking over the hill at how buildout and all of that stuff works and how different it is from how we've done things. I don't want the gulf to get bigger, because I think that with our plans for growth and for a more distributed deployment server setup, 'buildout' will help tremendously. I'm just trying for baby steps right now, because it feels like we've still got a long way to go to get to anything better. I saw mention of 'workingenv' in your book, so I assumed it was or is possible to easily have instance homes with locally managed eggs. Shouldn't it be? I assume so, so I guess I may have just run into yet another setuptools bug that I get to hack around. Yay. -- Jeff Shell ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
[Zope3-Users] Ahh, counters... Best practice?
We're working on something where we need to allow site visitors to rate items. It's the basic star-rating thing. We want to keep a count of the number of votes along with the current value. Since these are relatively small values - an integer and a float - that may be changing often, what is the best way to handle them efficiently so that the ZODB only keeps historical changes on those two items (ie - changing them does not mean that the item which is being voted on has changed)? I was thinking of something like BTrees.Length.Length, but I'm not sure it's the right solution (I don't understand the implications of '_p_independent', and some quick glancing around the web makes it appear as though you wouldn't want to count on a Length object for business logic). Would an annotation or tiny sub-object with two fields, the int and float, be enough? Thanks, Jeff Shell ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
Re: [Zope3-Users] Cheeseshop very flakey today
Anyone else noticing the Cheeseshop is operating very poorly today. It just sucks. :( I guess I should really be storing more egg content locally since the service just seems to be getting worse as time goes on. Yes! I'm noticing it too. Today was the first day I was going to try out buildout by watching it run on z3c.formdemo. But, alas, it's been very flakey. How common is this problem? -- Jeff Shell ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
Re: [Zope3-Users] Re: Using svn checkout with zc packages
On 7/25/07, Philipp von Weitershausen [EMAIL PROTECTED] wrote: Florian Lindner wrote: Hello, I use a Zope3 svn checkout for developement. What is the best way to make this working with the zc packages? I don't want to easy_install the entire Zope checkout but I also want my code to work with easy_install'ed versions of these packages. (don't want to change import statements and so on...) My favorite way would be to just do a svn checkout of the zc packages too but it seems to me that it won't work this way (or am I missing something?) $ mkdir zc $ touch __init__.py $ cd zc $ svn co /zc.resourcelibrary/trunk/src/zc/resourcelibrary And then additional checkouts. Basically: - Create an empty 'zc' package with an empty ``__init__.py`` - Go into that directory - When making checkouts from the zc packages in the subversion repository, go into the 'src' instead of getting the root which has the 'setup.py'. So if it's zc.resourcelibrary, typically you will want to check out `trunk/src/zc/resourcelibrary`. Of course you can get a checkout of any package you wish from svn.zope.org, including the zc.* packages. However, they'll likely have dependencies which you will have to resolve as well. Some might also define entry points which means they really want to be installed as eggs. Why do you use checkouts? Do you actually change the packages while you're developing with them? FWIW, we use checkouts at Bottlerocket because that's how we use our own packages. And there are many packages which don't have eggs, or don't have good releases as eggs. For example, there's zc.resourcelibrary - release 0.6 had a serious bug, and I haven't checked to see if there's been a fixed release made since then. For packages like that, we don't do blind checkouts, but we stick with a certain revision number so that we don't get surprised if the code starts using Zope 3.4 features while we're still using 3.3. We handle dependencies semi-manually, semi-automatically. I ended up writing our own build-ish system, inspired by Ruby's Rake, primarily to automate all of the SVN and CVS checkouts, their associated tags, and so on. Have you looked at zc.buildout? Checkout the tutorial [1]. Also, pretty much any zope.* or zc.* package's sandbox is set up using buildout these days, providing you with lots of examples. Last time I checked, which I admit has been a while, buildout didn't provide any examples of how to transition into buildout style development. NONE of our internal code - at least, none of our Zope-focused code is in egg style format. I've been checking out or exporting or unzipping/untarring into either $INSTANCE_HOME/Products or $INSTANCE_HOME/lib/python for nearly a decade. I don't know how to write a new product or library in this style. I don't know how to safely and securely deploy it so that it's only accessible by our internal, deployment, and home and office machines (cvs over ssh has worked fine for us, again, for six-plus years). Even more overwhelming - I don't know how to transition our existing code - internal frameworks and customer projects - into an egg-ish format. And I really don't know where we'll find the time. I still don't know how Eggs work. setuptools documentation, while comprehensive, is about as clear as mud in many places. I don't understand development eggs. And it looks like only subversion is supported for those anyways, am I right? ``zc.buildout`` is something that I'd like us (my company) to start using. But at present, it's overwhelming. It was overwhelming enough that it was easier to write our own automation system that fit in with the way we've worked for so many years than to try to figure out buildout, eggs, all of the various half documented recipes, etc. I feel like I need a training course or consultancy to move to buildout, which requires time and money that we just don't have. -- Jeff Shell ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
[Zope3-Users] Unicode for Stupid Americans (like me)?
I continue to feel like an idiot in the face of Unicode. I finally understand what a unicode 'string' really is, and what encode and decode mean (they were previously interchangable in my mind). But I don't know the best practices. My desire is to: - Not have any encode / decode errors. 'ascii codec doesn't recognize character ... at position ...'. I don't want to keep on bullying through whenever this pops up. - Not turn customer input into garbage. It may render to the public site fine, but sometimes in the admin skin's text areas, things turn funky. I don't know if there's something I need to do at form-handling time, or at rendering time, or what... I did a test based on a document by Sam Ruby, and guess that I'm often getting Latin-1 from our customers, which doesn't map to UTF-8 (the diacritic marks go haywire). - HOW do I know what a browser has sent me? There doesn't seem to be a real way of handling this. Do I guess? - Know without a doubt when to encode, and when to decode. I guess the proper thing to do is to store everything as unicode, and to decode to unicode as early as possible when input is coming in. But again, how do I know when to decode from latin-1 and when to decode from UTF-8? When or why should I encode to one or the other at response time? Should I worry at all? If there are any documents, web pages, Zope 3 book chapters, and past messages that I may have missed or need to look at in more detail, please let me know. I've had a hard time sifting through all of the information, and I apoligize if I've missed something written by anyone here. It's most important that the documents are from a Zope 3 perspective, or that the lessons can easily apply to Zope 3. Some of the more general documents I've found say your language / database may or may not natively support unicode, so we can't tell you what to do from here, which makes it difficult to translate to good Zope idioms. I feel like I know enough to squeak by, but that's no longer acceptable. Sometimes I quiver in terror, waiting for everything to fall down because of something so seemingly basic like strings/text. It may be a lot of technical debt, or it may be extremely easy to pay down. In any case, it's time to pay it down. :) Thanks, -- Jeff Shell ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
Re: [Zope3-Users] Re: Unicode for Stupid Americans (like me)?
On 2/28/07, Philipp von Weitershausen [EMAIL PROTECTED] wrote: Jeff Shell wrote: - Not have any encode / decode errors. 'ascii codec doesn't recognize character ... at position ...'. I don't want to keep on bullying through whenever this pops up. You can't just simply do str(some_unicode) or unicode(some_str), unless you really know that you're only dealing with the ASCII subset in both cases. Use explicit encodings to convert. Now, the trick is obviously to know the encoding. A 'str' object is worth squat if you don't know the encoding that goes along with it. In other words, (some_str, encoding) is isomorph to a unicode object. Ahh. I finally get this now. I was casting back and forth with wild abandon in some key places - in one particular place I was doing wild encoding somersaults when I really meant to be doing a small set of decode tries. I think this is why I was seeing customer garbage: I was turning unicode into strs and back again long before the final response was all built up. - HOW do I know what a browser has sent me? There doesn't seem to be a real way of handling this. Do I guess? That's sorta what zope.publisher does. Actually, it figures that if the browser sends an Accept-Charset header, the stuff that its sending to us would be encoded in one of those encodings, so it tries the ones in Accept-Charset until it's lucky. It falls back to UTF-8. This seems to work. But yeah, it's relying on implementation details of the browser and it's weird. Ugh. I don't know how I missed that header. I was always looking for a content-type on the post, hoping that it had the information. I was finally able to confirm that Zope was handing me the data properly; it was some of my HTML generation code that was mangling data on output. But again, how do I know when to decode from latin-1 and when to decode from UTF-8? When or why should I encode to one or the other at response time? Should I worry at all? If you're using Zope, you don't have to encode outgoing text at all, unless you're setting a non-text content-type on the outgoing response. If the context-type is text/*, you can just return unicode from your browser view and zope.publisher will use the best encoding that the browser prefers (from Accept-Charset). Best meaning that if the browser accepts latin-1,utf-8 and your page contains Korean text, it'll use utf-8, not latin-1. utf-8 is always a fallback, anyway, so that there's no chance to not be able to encode. This finally made sense to me as well. I had a form with a widget rendered by my own HTML generation code, and with a zope.app.widgets text field. I pasted Sam Ruby's Internationalization diacritic-heavy string into both fields. When I saw that the zope.app.widget was rendering properly while my own field was not, that sealed it. Unfortunately, all of my prior tests had involved my own widget, since that is where I had seen the junk characters. Now I ensure that my HTML generator is all unicode. Any basic string that it encounters, which typically come from source code, is decoded into unicode immediately. As mentioned above, I was wildly and inappropriately encoding to strings with some forceful settings so that I could join elements together. I'm wondering if I make this clear enough in my book. It's always hard to tell by myself since these things seem obvious to me. If you got any constructive feedback regarding this, I'll be more than happy to hear it and consequently improve the book for you Stupid Americans :). At quick glance, I didn't see where this might have been described. There's no mention of unicode in the back index, and from the table of contents I didn't see much besides the chapter on internationalization (which we're completely avoiding until we absolutely need to do it). But this helps. Between all of the answers I've received thus far, I finally have a grasp of what I'm doing. I'll try to codify it into a useful document. Thanks! -- Jeff Shell ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
Re: [Zope3-Users] Using zope.component outside Zope 3-how to bootstrap the registries
On 2/16/07, Andreas Jung [EMAIL PROTECTED] wrote: I am trying to use zope.component (Zope3 3.0) within a Python module (not running the whole Zope 3 boilerplate). I want to register a utility. What is the correct way to setup the registries (in particular the Utility registry) in order to register utilities? I don't think you need to set up the registries. There should be a base Global Registry in place already. Quite some time ago, I used zope.component, zope.interface, and a couple of other core supporting packages (zope.exceptions, zope.testing) in a command line tool. I didn't need to do any bootstrapping. I was able to use `zope.component.provideUtility` immediately. I used packages extracted manually from Zope 3.1. I'm not sure what `zope.component (Zope3 3.0)` is like. If it's from Zope3 3.0.0, it may be radically different than what I used. I believe Zope 3.1 implemented the Simplify Component Architecture proposal which got rid of extraneous bits like Services, and as such may be a bit easier to work with. -- Jeff Shell ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
Re: Re: [Zope3-Users] z3c.zrtresource or zc.resourcelibrary
On 10/31/06, Gary Poster [EMAIL PROTECTED] wrote: I do a lot inline in my Python code, using our nevow.Stan inspired tag generation system and little bits and pieces I threw together to ease in generating short bits of JS from within Python. In particular, marshalling of basic Python structures to Javascript using a modified `jsonencode` module from the `simplejson` package. What are the modifications? The things you list below all sound like normal simplejson stuff. The main modification is that it pass over 'raw' JS Code - statements that have already been encoded, function calls, raw names, etc. I think I did some tweaks to its string quoting system as well, but I don't recall. :: print js.encode('raw') 'raw' print js.encode(js.raw('raw')) raw This gets to be handy when generating function calls. `js.call` str's the first option, and then encodes the rest to create an arguments list, which it returns as a `js.raw` object so that it won't be quoted as a string:: dumbalert = js.call('window.alert', 'Stupid simple example') print dumbalert window.alert('Stupid simple example') print js.anonymous(js.expr(dumbalert)) function() {window.alert('Stupid simple example');} print js.call('setTimeout', js.anonymous(js.expr(dumbalert)), 5*1000) setTimeout(function() {window.alert('Stupid simple example');}, 5000) It's simple, but helpful, especially as calls and data build up. But even without building up a little system like this, it's probably good to use tools like `simplejson` to keep javascript data pretty, even in generated strings such as in TAL/TALES, just as it's good practice to use SQL Quoting. Other JS-related bits to know about (you'll have to do your own reading sometime :-): http://zif.hill-street.net/headincludes (WSGI variation on resourcelibrary), http://zif.hill-street.net/gzipper/ (WSGI, gzips all output for smaller browser page sizes), http:// zif.hill-street.net/jsmin/ (WSGI, compresses JS for smaller browser page sizes), and http://svn.zope.org/z3c.javascript/ (resourcelibrary- aware collection of mochikit, dojo, et al). Ah, the real reason for my response here: how does one use third party WSGI Middleware with Zope? zope.paste, maybe (http://svn.zope.org/zope.paste/)? I think that's what Jim Washington has used. Ahh, thanks, I'll take a look. -- Jeff Shell ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
Re: Re: [Zope3-Users] z3c.zrtresource or zc.resourcelibrary
On 10/24/06, Gary Poster [EMAIL PROTECTED] wrote: It might be nice to have zc.resourcelibrary be able to somehow serve z3c.zrtresource files too...it doesn't right now. FWIW, right now in lieu of zrtresource I just use script ... tal:content=string: /* ... JS that specifies dynamic variables and calls ... */ /script. Simple, and encourages delineation between library and usage; but a bit hacky, and unfriendly to designers. I do a lot inline in my Python code, using our nevow.Stan inspired tag generation system and little bits and pieces I threw together to ease in generating short bits of JS from within Python. In particular, marshalling of basic Python structures to Javascript using a modified `jsonencode` module from the `simplejson` package. Among other things, it lets me use normal Python dictionaries, strings, lists, numbers, etc, for use in generating code. `jsonencode` ensures that everything is escaped properly. It gets to be handy to build on, especially when wanting to generate a Javascript call and supply it with a big list of generated dictionaries. Other JS-related bits to know about (you'll have to do your own reading sometime :-): http://zif.hill-street.net/headincludes (WSGI variation on resourcelibrary), http://zif.hill-street.net/gzipper/ (WSGI, gzips all output for smaller browser page sizes), http:// zif.hill-street.net/jsmin/ (WSGI, compresses JS for smaller browser page sizes), and http://svn.zope.org/z3c.javascript/ (resourcelibrary- aware collection of mochikit, dojo, et al). Ah, the real reason for my response here: how does one use third party WSGI Middleware with Zope? Alternately, does anyone have any experience running Zope in another WSGI supporting server? There are quite a few things out there in WSGI land that I'm interested in, but I've never quite understood how they work together on their own and/or with big systems like Zope. By the way - I've had some issues with the dependency tracking in zc.resourcelibrary. Is there a tracker where I can post said issues? (if I can remember and reconstruct them, that is) -- Jeff Shell ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
[Zope3-Users] Links / Relationships (again)
Howdy. What is the state of various relationship / link managers for Zope 3? A year ago we banged out a quick idea that used Int IDs to track links (mostly to generate in-site URLs) to target objects. And then we ended up copying and pasting the code across a lot of projects. I'm wanting to clean that up by, perhaps, implementing a widget. But I'm wondering if there's a better way to track references to targets. A source object might be a banner ad or promo button with a link to some other internal object like a page with more details. For one customer I made a Schema field and a Property that used schoolbell.relationship (probably from a quite old version of Schoolbell) but made it basically as easy to use as what I could figure out from zope.agxassociation, which doesn't appear to be finished. Basically I generated the Triple that schoolbell.relationship requires automatically using interface/field names to make the URI. (I don't think in RDF, so I wanted that aspect to be as invisible as possible). I don't know whether I should reuse what I made there, or if there were some other viable options. Basically, I would like there to be a way that I can easily query an object to see if there are any links pointing in its direction so that I could handle a Delete operation. IE - Deleting the Summer Sale page will break the following items: (1. Summer Sale Promo, 2. Summer Sale Newsletter Banner). Do you want to delete those as well? .. or something like that. It's a bit beyond the scope of my current project, but is something I'd like to get back to. I see there's a `zc.extrinsicreference` in the svn.zope.org repository. Is that in a usable state? Thanks, Jeff Shell ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
[Zope3-Users] Using buildout for Zope 3 development instances (not developing Zope 3, but for developing against it)?
I started taking another look at zc.buildout last night and am happy to find that the documentation has improved dramatically from when I first looked at it. And I'd really like to start using it on our new projects. But I don't know where to begin, nor how much we (my company) might have to alter our development or deployment strategies. I don't know if this is the right list to ask these questions on, but my questions are specific to using Buildout to automate building development-focused Zope 3 instances, more than they are about using Buildout itself. I would like to maintain our current development setup, where our local Products are checked out of a repository into `$INSTANCE_HOME/lib/python`, while also ensuring that all third-party dependencies are also installed into that particular instance home. Keeping track of dependencies has been enough of an annoyance up until now that we've kept our use of third party products low. We knew there were good ones out there, but playing the game of oh crap, I forgot to get that! over and over again gets old. :) Anyways, my questions: 1) Where are the Zope specific recipes, particularly ``zc.recipe.zope3instance`` and ``zc.recipe.filestorage``? They don't appear to be in the Cheeseshop. I think that there may be a ``downloads.zope.org`` site, or something like that, but with the DNS issues affecting *.zope.org right now, I haven't been able to find out if that's really where they are or should be. 2) I have very little experience with Eggs. I've never developed one. Heck, I've never really developed a proper 'distutils' style package. I'm used to making my packages / products in CVS as the root package module itself, never as something with a 'src' subdirectory and a 'setup.py'. Traditionally, distutils hasn't made much sense for Zope focused products/packages, so I've never really bothered with it. It's made it easy to do ``cvs co -d cms Products/cms`` into ``$INSTANCE_HOME/lib/python`` and go merrily along my way during development. I gather that this should be possible with a distutils style setup, using ``cvs co -d cms Products/cms/src/cms`` instead? If the targets for most of our products/packages consist of my company and its customers, should I even bother with making them into Eggs? We tend to use CVS checkouts on our deployment servers (a policy that I wish we didn't do, but it does make it easy to fix critical bugs found in that environment and get them back to the repository). 3) Does anyone have experience with using zc.buildout to make simple Zope 3 instances for both development and deployment, where the Eggs are local to the Zope 3 instance (and Zope knows where to look to get the local eggs)? The Zope-specific buildout recipes may address some of this, but as I can't access svn.zope.org at the moment to study the source, I can't really tell. I understand (sortof) how Eggs and Ruby Gems work when installing site-wide packages, but I don't understand how they work as packages local to an application (like a Zope 3 instance). I'm too used to just seeing a package like 'sqlalchemy' on my path as a directory, not as `SQLAlchemy-0.2.8-py24.egg`. Ultimately, I would really like to have is a setup that has the following: - Installs dependent third party products, either as eggs or as cvs/subversion checkouts/exports. Installs **locally into the instance home**, but perhaps in a separate path from `lib/python`. (Zope 2's ZConfig let you specify additional items to add to PYTHONPATH, but I don't think I've ever seen this in Zope 3. Am I missing something?) This could include things like zc.resourcelibrary, PIL, SQLAlchemy, simplejson, etc. - Checks out **source** for all of the neccesary internal packages into `$INSTANCE_HOME/lib/python`. - Could install/copy/move some scripts from internal packages (whether from a repository or egg) into `$INSTANCE_HOME/bin`. We have some code that I always run from `debugzope` that I'd like to run via `zopectl run` (now that `run` is back for Zope 3). My interests right now are aimed primarily at building out development instances so that my coworker and I can up and running quickly without having to keep lists around of Subversion commands to copy and paste for checking out specific revisions/tags of third-party products (SQLAlchemy, zc.catalog, hurry, etc). I know I may need to write Recipes for some of what I want to do and I don't mind that. I just would like to keep our development strategy -- develop in an instance home built on a zope 3 release -- working smoothly while automating all of the dependencies and site.zcml/configure bits. -- Jeff Shell ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
[Zope3-Users] Re: Re: So you've just downloaded Zope 3.3....
On 9/28/06, Philipp von Weitershausen [EMAIL PROTECTED] wrote: Jeff Shell wrote: One blow-up instance was on something that was marked deprecated (a vocabulary that used `zope.app.utility.vocabulary.UtilityVocabulary` as its factory). How? can you provide a traceback? Like Jim said, we tried having 3.3 be backward compatible. It's a reference that was marked as deprecated, and that it would go away in 3.3. Now it's 3.3, and it's gone! It's just something that I wish I had caught sooner, but it was an easy fix. Strangely, I never saw that deprecation warning, or I would have fixed it a long time ago. It looks like deprecated items referenced in ZCML wouldn't trigger the warnings in Zope 3.2, whereas Python based importing/referencing would. Hmmm. Weird. Can you reproduce this? If so, please file a bug. I'll submit one if I can make an easily re-producable case. I'm a bit swamped right now. That said, I still don't really know much about what's new and special. Ugh, that's bad. I'm sorry if we've been unclear. Does http://kpug.zwiki.org/WhatIsNewInZope33 help? Yes. Why isn't that linked off of any sensible page or place in the Zope 3 wiki? Releas page? I was pretty sure someone had been working on such a document. But I couldn't find it at all, which is why I asked here. I see a lot of things in the Wiki in proposals, but the proposals don't always mirror final implementations, so sometimes it's a bit of a guessing game if one even has that to go on. Only a few of the proposed ZCML reductions went into play, correct? I just checked and the Implementation status section is correct regarding Zope 3 (trunk refers to 3.3 though). I admit, though, I coudl've done a better job updating the proposals after having implemented them. Without moving the blame elsewhere, I think we should consider a more formal proposal process again, like I suggested once. Python PEPs and Plone PLIPs seem to work very well. I agree. The Wiki is perhaps a good place to collaborate or brainstorm initially. But there's just not enough data ever available to maintain pages like this: http://plone.org/products/plone/roadmap without a lot of human intervention (manually creating the tables, status information, owner information, etc, in multiple places). It would be nice if there was at least a small document that went through deprecated items and covered how to migrate away from them - separate from the change log or proposals. I've tried to emit helpful deprecation warnigns that dont' just say this is deprecated but also say use XYZ instead. The proposals should also document this. What is it that you're particularly struggling with? I saw those messages! Those made me happy. And that kpug.zwiki.org page looks like it'd be very helpful too. I'm struggling with the migrate by hitting ./runzope over and over again until the thing starts up Having some better information before I even download a Zope release would help - including reminders that certain features that had been marked for removal in 3.3 have actually been removed. I have some old Zope 3.1 era code that I'm trying to update right now. It was made to work comfortably with Zope 3.2, but we had one customer continue along with that installation and we've just forgot about it and never got around to the change this when everything is running on Zope 3.2 comments we had lying around. Now, here's the strange one: What happened to Tools? `zope.app.component.browser.tools`? I'm not even sure what tools were, We weren't either ;) so we got rid of them. I was able to get rid of our references with no change in expected behavior, so I think we're good. Like I said, I think we just used those directives because we saw someone / something else doing it. We certainly weren't getting any special behavior out of them that I know of, I just wanted to be sure I could kill them off completely. -- Jeff Shell ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
Re: Re: [Zope3-Users] So you've just downloaded Zope 3.3....
On 9/28/06, Jim Fulton [EMAIL PROTECTED] wrote: Jeff Shell wrote: ... now what? I just tried moving some work over to Zope 3.3. Already things are blowing up. What do you mean by blowing up? We certainly tried to make 3.3 backward compatible. Jim One blow-up instance was on something that was marked deprecated (a vocabulary that used `zope.app.utility.vocabulary.UtilityVocabulary` as its factory). Strangely, I never saw that deprecation warning, or I would have fixed it a long time ago. It looks like deprecated items referenced in ZCML wouldn't trigger the warnings in Zope 3.2, whereas Python based importing/referencing would. That said, I still don't really know much about what's new and special. I see a lot of things in the Wiki in proposals, but the proposals don't always mirror final implementations, so sometimes it's a bit of a guessing game if one even has that to go on. Only a few of the proposed ZCML reductions went into play, correct? It would be nice if there was at least a small document that went through deprecated items and covered how to migrate away from them - separate from the change log or proposals. Now, here's the strange one: What happened to Tools? `zope.app.component.browser.tools`? I'm not even sure what tools were, but we used them in some places in our code: most of that code being done over a year ago against Zope 3.1 in a time crunch. I'm not sure why we used those directives/interface types, but it was probably from a book or from looking at someone else's code. `zope.app.component.browser.tools` was never marked as deprecated as far as I can tell, so now I'm looking at a co-worker's ZCML that references the `IToolType` interface type in a couple of places, and uses the `browser:tool` directive in a couple of places. They seem to be completely gone now, and probably for good reason. Still, since it never seemed to be marked as deprecated, I had no direction for moving us away from its use. All I could find on the `tool` directive in the Wiki was its proposal page. From looking at that page, I'm not sure it's something we ever needed (at least, not in the form described). I'm pretty sure that at least one of the instances where we use it is something my co-worker wants to completely re-do anyway. But until he gets back, what do I replace those directives with? Are they a localUtility? -- Jeff Shell ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
Re: Re: [Zope3-Users] Re: zalchemy integration
On 8/14/06, Stephan Richter [EMAIL PROTECTED] wrote: Right, so you fixed the problem with the provider TALES expression, which has to do update()/render() at the same time. My question is: How do you know which content providers are used by a view? Do you manually list them? A Page class (or any provider manager) may optionally list names. The names also provide some ordering support (ensuring that provider A is updated before provider B). If no names are listed in the class, then all Content Providers registered for the page are looked up:: self._content_providers = dict(zapi.getAdapters( (self.context, self.request, self), IContentProvider )) I was thinking about implementing a way to inspect TAL code to determine all the providers that should be looked up before rendering. I even talked to Fred about it already; but it is non-trivial, if I understand him correctly. I wouldn't want to be bound to TAL though. As I mentioned, we use a STAN-inspired system for generating HTML in many places where there's no desire to maintain a separate file just to render something simple - or even moderately complex. As we've also started implementing a system inspired by Rails Helpers which eases some generation of common tasks from formatting to link/URL generation, our need to TAL has decreased. It's still useful in design heavy sites, but I'm really starting to wish for some simplified expressions (even TALES expressions would be nice) to do structured inserts with a helluva-lot-less typing. We still use page templates fairly heavily. I just wouldn't want to depend on TAL code so heavily that any other template/html/xml generation system one wants to plug in really becomes a second or third class citizen at that point. Right, I see you use viewlets/providers heavily; at least we are not the only ones. :-) I would be interested in a lot more dialog here to share best practices and code. We haven't gone into super-heavy usage, but that should start changing this week as we push for the front end UI of this project. Then we'll see if my theories worked :). BTW, another part of the UI power tools is zc.table. I will publish a bunch of extensions later this week. I haven't had too much time to look at `zc.table`. It was a little overwhelming last time I looked at it... I think because of the 'resource library' system being kindof scary. While I haven't pushed my full-Page system concept to its extremes yet, I'm hoping that it can - perhaps - deal with the issues of 'A widget in some form on the page wants to add some javascript or css to the head' issue without badgering the response; something similar to Seaside's `updateRoot` method. -- Jeff Shell ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
Re: [Zope3-Users] Security Roles and custom authenticators and scarcely-persistent apps (HELP!)
On 4/26/06, Bernd Dorn [EMAIL PROTECTED] wrote: On 27.04.2006, at 02:44, Jeff Shell wrote: So I spent the day writing an IAuthenticator utility that loads principals out of an RDBMS (via a SQLAlchemy mapper based model). I got that working. All I want right now is to have my site, 'presenters', have view access restricted to the role 'app.Presenters'. The site is persistent and the authenticator is a local utility. I set up the site on load to disallow the 'zope.View' and 'zope.app.dublincore.view' (not really needed, I guess, since I'm not using dublin core anywhere) for the 'zope.Anonymous' role, and allow it for 'app.Presenters' and 'zope.Manager'. It's just a simple / blanket security policy, I know. But something similar has been in place on the Zope 2 based version of this app for a number of years now and has worked fine for this use case. But.. I have no idea how to do this in Zope 3 land. It took me all day to write my authenticator, At the end of the day I saw it working in so far as it obviously retrieved a user record out of the database, validated the password, and returned a dirt simple principal object. I could tell this by the login form giving me a different message this time (you're not allowed to do that operation). I tried looking at the Principal-Role map and... I don't understand it. just plug your own implementation in adapter factory=.your.security.RoleMapImplementation provides=zope.app.securitypolicy.interfaces.IPrincipalRoleMap for=.interfaces.IYourSiteOrSo trusted=true / just for granting local roles on the site it's inough to implement def getRolesForPrincipal(principal_id): Get the roles granted to a principal. Return the list of (role id, setting) assigned or removed from this principal. If no roles have been assigned to this principal, then the empty list is returned. but you have to set your authenticator somewhere, so that you can see if the principal is from your authenticator by comparing ids Thanks for the response. After some snooping around tonight, I was suspecting that'd be the option to use. But then I decided to try using IGroupedPrincipal instead. So now when my site configurator sets up this particular site/app, it: - Denies permission 'zope.View' to role 'zope.Anybody' - Grants permission 'zope.View' to principal 'presenter.group' My authenticator recognizes that and returns an IGroup. All of the presenters returned have a groups attribute with the value ['presenter.group']. Seems to work so far, and I'm breathing a sigh of relief tonight. Sure beats hoping I don't mess up an IPrincipalRoleMap when I've got so much other work to do and am so far behind as it is. Wheee, life! -- Jeff Shell ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
[Zope3-Users] Other SQLAlchemy thoughts, Zope transaction manager, etc...
for some kind of two-phase commit support in SQLAlchemy's unit of work system where the object graph writing and the actual 'commit' command for the storage are more obviously separated and usable for API's like Zope's. Martin -- Jeff Shell ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
Re: [Zope3-Users] editform onSuccess-method
On 3/29/06, Frank Burkhardt [EMAIL PROTECTED] wrote: On Wed, Mar 29, 2006 at 04:12:40PM +0530, baiju m wrote: On 3/29/06, Frank Burkhardt [EMAIL PROTECTED] wrote: Hi, I need to do some changes to an object, after it's either created or modifed. Is there a chance to define methods on the object's class that are called after the addform or the editform are done creating/changing the object? Maybe there's a ZCML-way to do this? May be you are looking for events ? http://www.zope.org/Wikis/DevSite/Projects/ComponentArchitecture/Zope3Book/events.html Maybe that's what I have to use. But I would rather like a solution like this: subclass class XXX overwrite method YYY define statement ZZZ in ZCML If you need to do these changes all the time - regardless of how the object is created or modified - then you do want to go with events. * subclass nothing * write event handler functions (for IObjectAddedEvent and IObjectModifiedEvent) * register handler in ZCML. If you're using formlib (Zope 3.2 feature) based forms (which I recommend using), look at the formlib API and the zope/formlib/forms.txt document. There are some excellent base classes in there for editing, adding, and just doing your own thing. With each 'action', it's very possible to do your own responses. In that case, it's: * subclass zope.formlib.form base classes (Form, EditForm, etc) * override an action / write a new action / overwrite update or render * no ZCML - just register it as a view. class EditItineraryForm(form.EditForm): form_fields = form.Fields(IItinerary) @form.action(uSave Changes, condition=form.haveInputWidgets) def handleEditAction(self, action, data): if form.applyChanges(self.context,self.form_fields,data,self.adapters): notify(ObjectModifiedEvent(self.context)) self.status = uItinerary Details Updated self.onSuccess() else: self.status = uNo Changes Something like that should work. You could even make your own base EditForm class that defined the above action, and a subclass would just need to provide onSuccess and the form_fields. -- Jeff Shell ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
Re: [Zope3-Users] PyWebOff
Argh. Darn that user group meeting being down in Utah Valley. Don't they consider the fact that there may be Utahn's who still try to cling to a car-free urban lifestyle notion (especially when they live and work on the same block)? :) Tell them to come up by my house. Terrific restaurants, delis, italian markets, etc. Some of the best Thai food in the city... Anyways, it's too late to help you for the user group meeting in question, but I'd like to take this on as a personal little challenge, seeing if I can come up with a more interesting and pleasing to the Python developer solution. Maybe you can show it next month as an alternate option? On 3/3/06, Shane Hathaway [EMAIL PROTECTED] wrote: Hello, I've been assigned to present Zope in a local upcoming Python user group meeting. As part of the assignment, I'm supposed to solve the PyWebOff challenge using Zope: http://pyre.third-bit.com/pyweb/challenge.html I'd like to do this using Zope 3. However, I'm really struggling. I feel like I must be using Zope 3 in a really dumb way, because the code so far is highly repetitive, completely dependent on Zope, and more XML than Python. This is not going to go over well in the presentation. Can anyone tell me how to do this better with Zope 3? Maybe my Zope 2 experience is preventing me from seeing something obvious. I've attached the __init__.py and configure.zcml that I created in a package called challenge. Shane configure xmlns=http://namespaces.zope.org/zope; xmlns:browser=http://namespaces.zope.org/browser; content class=.Book require permission=zope.View interface=.IBook / require permission=zope.ManageContent set_schema=.IBook / /content content class=.Loan require permission=zope.ManageContent interface=.ILoan / require permission=zope.ManageContent set_schema=.ILoan / /content content class=.Library require permission=zope.ManageContent interface=.ILibrary / require permission=zope.ManageContent set_schema=.ILibrary / /content browser:addform name=addlibrary schema=.ILibrary content_factory=.Library permission=zope.ManageContent / browser:addMenuItem class=.Library permission=zope.ManageContent view=addlibrary title=Library / browser:containerViews for=.ILibrary index=zope.View contents=zope.View add=zope.ManageContent / browser:addform name=addbook schema=.IBook content_factory=.Book permission=zope.ManageContent / browser:addMenuItem class=.Book permission=zope.ManageContent view=addbook title=Book / browser:editform schema=.IBook permission=zope.ManageContent menu=zmi_views title=Edit name=edit / browser:addform name=addloan schema=.ILoan content_factory=.Loan permission=zope.ManageContent / browser:addMenuItem class=.Loan permission=zope.ManageContent view=addloan title=Loan / browser:editform schema=.ILoan permission=zope.ManageContent menu=zmi_views title=Edit name=edit / /configure ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users -- Jeff Shell ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
[Zope3-Users] Visionaire! (All your problems, solved)
, while sticking with the current timed release plan as well. And it would finally make a useful and usable Zope Without Zope downloadable option available as Zope 3 CA. I can envision the web site now, and may mock a simple and sexy text based one up later this evening. We could even get it up now (zopesuite.org anybody?). - Zope 3 CA: Provides the core elements and concepts for building and sustaining loosely coupled Python programs, as well as the fundamental object publishing toolkit that's been powering Zope based web sites since 1996 (1995?). [download now | more information] - Zope 3 AS: The Zope 3 Application Server. A new approach to Zope web sites built entirely on the Zope 3 Component Architecture and Zope Object Database. A full stack for developing custom web sites and applications using only Python and your imagination. [download Zope 3.2 now | more info ] - Zope Suite: Built on Zope 2 and leveraging elements of the Zope 3 CA and Zope 3 AS, the Zope Suite provides a robust and mature web development environment that is in place already behind many web sites and applications worldwide. [download zope 2.9 now | more info | roadmap ] Thoughts? I think this keeps Zope 3 as we know it alive, keeps the Zope brand intact, and offers a future for Zope 2 and similar caliber desires for a Big App Server while not interfering with the more pure and simple concepts that makes Zope 3 appealing for developers like me. -- Jeff Shell ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
Re: [Zope3-Users] Re: browser:form
On 2/22/06, suresh [EMAIL PROTECTED] wrote: Jeff Shell wrote: On 2/21/06, David Johnson [EMAIL PROTECTED] wrote: With formlib, you'd be able to get/set this in the update() method, or if you're clever, you can do it in publishTraverse so you can have url like '.../mycontacts/contact/1234'. Thanks for the mini-tutorial :) Will publishTraverse work with Five? I'm not sure. I haven't used Five. But if it doesn't, you *should* be able to get by with ``__bobo_traverse__``. I think the signature is the same - accepts a request and a name, and should return a callable or traversable object:: def __bobo_traverse__(self, REQUEST, key): self.contactid = key return self *Should* work if publishTraverse doesn't. But since publishTraverse is a core protocol from zope.publisher, I would expect Five views to support it. -- Jeff Shell ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
Re: [Zope3-Users] browser:form
On 2/20/06, David Johnson [EMAIL PROTECTED] wrote: I've implemented the browser:form ZCML directive. The implementation works well until I add an __init__ method to my view class. The following error is generated. File /home/myuser/Zope-3.2.0/build/lib.linux-i686-2.4/zope/app/form/browser/editview.py, line 76, in widgets return [getattr(self, name+'_widget') AttributeError: 'SimpleViewClass from edit.pt' object has no attribute 'name_widget' Here is the __init__ that leads to the error ---: class Function(object): A transaction function. __used_for__ = ITPM def __init__(self, context, request, base_url=''): self.context = context self.request = request self.base_url = base_url First - if you're running on Zope 3.2, I (and many others) would recommend looking at zope.formlib. Later in this message, I go into a little more detail about how it might help you. But the direct answer is - you need to call ``super(...)``. Use super()? you ask, I'm just subclassing from ``object``, right? Wrong! The browser:form directive, like many view generating directives for ZCML, is making a new class on the fly by mixing in a few base classes and your class together. Those other classes that are used as bases are likely to provide their own __init__, and you need to ensure they get called because they could be doing something important, like one of the zope.app.form.browser form classes is doing in this case. Try this: class Function(object): def __init__(self, context, request, base_url=''): self.base_url = base_url super(Function, self).__init__(context, request) That will set up context and request for you. More importantly, it *should* call __init__ on the class that's created by the browser:form directive, which calls something like self.setUpWidgets. self.setUpWidgets (I'm not sure that's the method name, but it's something like that) creates attributes on the view in the form of ``fieldname_widget``: so ``name_widget``, ``title_widget``, and so on, based on the schema and options provided by ZCML. Since you're not calling super(), that setup step is not being run. But I have a question: how is this form going to be used? Are you instantiating it directly in other Python code? Because it's unlikely that base_url will ever have a value applied to it otherwise. Most views are instantiated in Zope by calling ``getMultiAdapter((context, request)...)``, which calls __init__ on the view object found and passes in context and request as the two arguments. Unless you are explicitly calling ``Function(context, request, 'foo/bar')``, that third argument is unlikely to be set. If you just want to ensure that it's there as an attribute, you can put it in the class definition:: class Function(object): base_url = And then you don't have to override __init__. It's probably not a good idea to provide/expect extra __init__ arguments when writing an adapter (or view), since most of the time it's the adapter lookup machinery that will be calling that __init__ code. It's not bad to write your own __init__ though. But I do recommend trying to find out what classes you're inheriting from and what they do in __init__ so you can either do it yourself or use super(). Formlib === If you're using forms and you're running Zope 3.2, look at zope.formlib. With formlib, it's easier to see what classes you can inherit from and what they're doing and when you might want to override a method and would need to call super, and what you would need to pass along to the superclass when you do. This is an example of what that might look like: from zope.formlib import form class Function(form.FormBase): # form.Fields finds the fields that might have been provided by # browser:form schema=...ITPM. form_fields = form.Fields(ITPM) base_url = '' # if you have a custom template, you can provide it here # instead of ZCML template = ViewPageTemplateFile('functionform.pt') And then register via browser:view. (You'd need to do a little bit more work, of course, to load/bind custom data or respond to a 'Save' action, depending on your requirements). It really is a more flexible, adaptive, controllable, and documented system than the form views available from zope.app.form via the browser:*form directives. You should be able to print out the documentation from apidoc in the 'book' menu, and look up the IFormAPI interface too. All of our custom forms became so much easier to control and understand after moving to formlib, and in many cases the code to support a form actually shrank. There's a lot more plain old Python code and a lot less ZCML magic, which makes it easier to trace how a form and its widgets get built. It might take a little bit of time to read and understand all of the options available, but it's well worth it as I've found zope.formlib to be a wonderfully solid foundation to build on. -- Jeff Shell
Re: [Zope3-Users] browser:form
On 2/21/06, David Johnson [EMAIL PROTECTED] wrote: Thanks. I will look into formlib. My goals is to be able to provide forms that allow editing of SQL based database entries. I am exploring SQL and Zope integration, and I liked the simplicity of the browser:form concept. You'll (most likely) want zope.formlib then. It will give you the control you'll need while still providing a lot of useful base classes and helpful functions to keep form generation and validation simple. I had started writing my thoughts and past experiences with Zope - SQL integration here, but am moving that to a separate topic. Here is what I am generally trying to do. Imagine a database of contacts. My thought is to architect it as follows. 1. Create a view which simply lists all the contacts. Each contact displayed would be an href link to the individual contact. 2. Clicking on a contact which generate a form to edit that contact. The href link for the contact would contain the contact id. http://localhost/mycontacts/contact.html?contactid=1234 The __init__ of the browser:form I was planning to use to get the contactid from the request. With formlib, you'd be able to get/set this in the update() method, or if you're clever, you can do it in publishTraverse so you can have url like '.../mycontacts/contact/1234'. If you're doing really custom data handling - ie, the data's not an object that a field can bind to but a dictionary - you'll probably want to use formlib.FormBase and override setUpWidgets and update() both. I'll show the publishTraverse trick that I've started to use too. This *should* work. Note: ``IContactGateway`` is a complete fabrication of my imagination. In this scenario, it loads and stores contact information from a SQL Database, returning a dictionary (load) and accepting a primary key and dictionary of validated / restricted data (only elements from the IContact interface in this case) to save. from zope.app import zapi from zope.formlib import form from myapp.interfaces import IContact, IContactGateway class ContactEditForm(form.FormBase): form_fields = form.FormFields(IContact) contactid = '' def publishTraverse(self, request, name): Used by zope.publisher to traverse to 'name' # We expect 'name' to be a contactid. Set it as the attribute. Return # self to the publisher, which will call __call__ (which then calls # self.update() and returns self.render()). self.contactid = name return self def setUpWidgets(self, ignore_request=False): Overrides FormBase.setUpWidget to send ``self.contact_data`` to the ``data`` argument of form.setUpWidgets. self.adapters = {} self.widgets = form.setUpWidgets( self.form_fields, self.prefix, request=self.request, form=self, adapters=self.adapters, ignore_request=ignore_request, data=self.contact_data ) def update(self): # How you load the contact record is up to you... contacts = self.contacts = zapi.getUtility(IContactGateway) self.contact_data = contacts.get(self.contactid) # FormBase.update calls self.setUpWidgets and responds to any # submitted action. super(ContactEditForm, self).update() # Here's where you can respond to 'save'. This creates a 'Save Contact' # button and calls the following method if form validation succeeds. @form.action(u'Save Contact') def handleSaveContact(self, action, data): # 'data' is the validated dictionary. How you save it is up to you # :-) self.contacts.save(self.contactid, data) self.status = Changes Saved In *theory*, that should set you up. The generated form's action will be a full URL which should include the contactid, so 'publishTraverse' will get called again with that contact id. (ie - it will render ``form action=.../contacts/1234``, with 'contacts' being the name of this view). Alternately, in 'update', you could do:: self.contactid = self.request.get('contactid') But you would have to ensure that contactid is included in the rendered form. I would use sqlos, but my limited exposure makes me think it is not as flexible as I would like. I haven't used sqlos. A benefit of sqlos is that, in theory, it would load your Contact object and make it appear pretty much like any other Zope object. At that point you could use more regular forms. That would be a good thing. However, I personally feel there are other options that could be explored.. They may not exist yet :), but I've got thoughts brewing. -- Jeff Shell ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
Re: [Zope3-Users] What attributes are made persistent
On 2/14/06, Peter Bengtsson [EMAIL PROTECTED] wrote: D'oh! That's confusing. Isn't there a class that gathers all of these in one. It seems confusing, you derive from Persistent but only some are accepted. Does that mean that there's PersistentFloat and PersistentTuple too? If not, why *only* dicts? As mentioned above, it applies to *mutable* objects. Objects whose value can change are said to be mutable; objects whose value is unchangeable once they are created are called immutable. (The value of an immutable container object that contains a reference to a mutable object can change when the latter's value is changed; however the container is still considered immutable, because the collection of objects it contains cannot be changed. So, immutability is not strictly the same as having an unchangeable value, it is more subtle.) An object's mutability is determined by its type; for instance, numbers, strings and tuples are immutable, while dictionaries and lists are mutable. http://docs.python.org/ref/objects.html Instances of Persistent based classes know when they change. Like if you do:: clive.age = 28 Which is effectively ``setattr(clive, 'age', 28)``. As a persistent object, clive notices that an attribute is being set (even if it's replacing an existing value), and flags that 'clive' has changes that need to be saved. So again - here, it's the 'clive' object that's being updated in this case. The fact that the value is an integer doesn't matter. It's not changing. 28 is 28. But 'clive' is changing by having a new/updated 'age' attribute set. On the other hand, if you do:: clive.favoriteNumbers.append(13) 'clive' does not change. 'favoriteNumbers' changes. If favoriteNumbers is a regular Python list, the persistence machinery has no idea that it's changed. It's not being assigned to 'clive', it's already an attribute there and is not being replaced. So if it's not a PersistentList, it gets forgotten. If favoriteNumbers was a tuple, you couldn't append to it. You could do an addition, but in a form like this:: clive.favoriteNumbers = clive.favoriteNumbers + (13,) # Alternately clive.favoriteNumbers += (13,) This is doing assignment. 'clive' is getting a new attribute set, and as a Persistent object 'clive' can be set as needing its changes saved. It's not only dicts, it's dicts and lists (PersistentDict and PersistentList). I don't know if there's a PersistentSet. Python offers two sets since 2.3 - a mutable (list-like) one and an immutable (tuple-like) one. I imagine that if you use the mutable set (``sets.Set`` in 2.3, ``set`` in 2.4), you'd run into the same problems. But if you used the immutable set (``sets.ImmutableSet``, ``frozenset`` in 2.4) you wouldn't. Note that this issue affects not just ZODB persistence. If you used even the simple 'shelve' module that's in Python, you have the same issue unless you use a 'writeback' option: If the writeback parameter is True, the object will hold a cache of all entries accessed and write them back to the dict at sync and close times. This allows natural operations on mutable entries, but can consume much more memory and make sync and close take a long time. So as a way of making working with default mutable objects feel natural, this option makes shelve read and write its whole database, which would obviously be very expensive for the ZODB. So - just use PersistentList and PersistentDict (or look into BTrees for better storage options). For more details, visit the ZODB documentation on ZODB programming, and visit the section on modifying mutable objects: http://www.zope.org/Wikis/ZODB/FrontPage/guide/node3.html ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
Re: [Zope3-Users] What attributes are made persistent
Oh! And reference to related Persistence modules (persistent mappings, lists, BTrees): http://www.zope.org/Wikis/ZODB/FrontPage/guide/node6.html On 2/14/06, Jeff Shell [EMAIL PROTECTED] wrote: On 2/14/06, Peter Bengtsson [EMAIL PROTECTED] wrote: D'oh! That's confusing. Isn't there a class that gathers all of these in one. It seems confusing, you derive from Persistent but only some are accepted. Does that mean that there's PersistentFloat and PersistentTuple too? If not, why *only* dicts? As mentioned above, it applies to *mutable* objects. Objects whose value can change are said to be mutable; objects whose value is unchangeable once they are created are called immutable. (The value of an immutable container object that contains a reference to a mutable object can change when the latter's value is changed; however the container is still considered immutable, because the collection of objects it contains cannot be changed. So, immutability is not strictly the same as having an unchangeable value, it is more subtle.) An object's mutability is determined by its type; for instance, numbers, strings and tuples are immutable, while dictionaries and lists are mutable. http://docs.python.org/ref/objects.html Instances of Persistent based classes know when they change. Like if you do:: clive.age = 28 Which is effectively ``setattr(clive, 'age', 28)``. As a persistent object, clive notices that an attribute is being set (even if it's replacing an existing value), and flags that 'clive' has changes that need to be saved. So again - here, it's the 'clive' object that's being updated in this case. The fact that the value is an integer doesn't matter. It's not changing. 28 is 28. But 'clive' is changing by having a new/updated 'age' attribute set. On the other hand, if you do:: clive.favoriteNumbers.append(13) 'clive' does not change. 'favoriteNumbers' changes. If favoriteNumbers is a regular Python list, the persistence machinery has no idea that it's changed. It's not being assigned to 'clive', it's already an attribute there and is not being replaced. So if it's not a PersistentList, it gets forgotten. If favoriteNumbers was a tuple, you couldn't append to it. You could do an addition, but in a form like this:: clive.favoriteNumbers = clive.favoriteNumbers + (13,) # Alternately clive.favoriteNumbers += (13,) This is doing assignment. 'clive' is getting a new attribute set, and as a Persistent object 'clive' can be set as needing its changes saved. It's not only dicts, it's dicts and lists (PersistentDict and PersistentList). I don't know if there's a PersistentSet. Python offers two sets since 2.3 - a mutable (list-like) one and an immutable (tuple-like) one. I imagine that if you use the mutable set (``sets.Set`` in 2.3, ``set`` in 2.4), you'd run into the same problems. But if you used the immutable set (``sets.ImmutableSet``, ``frozenset`` in 2.4) you wouldn't. Note that this issue affects not just ZODB persistence. If you used even the simple 'shelve' module that's in Python, you have the same issue unless you use a 'writeback' option: If the writeback parameter is True, the object will hold a cache of all entries accessed and write them back to the dict at sync and close times. This allows natural operations on mutable entries, but can consume much more memory and make sync and close take a long time. So as a way of making working with default mutable objects feel natural, this option makes shelve read and write its whole database, which would obviously be very expensive for the ZODB. So - just use PersistentList and PersistentDict (or look into BTrees for better storage options). For more details, visit the ZODB documentation on ZODB programming, and visit the section on modifying mutable objects: http://www.zope.org/Wikis/ZODB/FrontPage/guide/node3.html -- Jeff Shell ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
Re: [Zope3-Users] Re: Please Guido, pick me, pick me!
doesn't do them justice. I, and a few others, try to cover things like this in our weblogs when we have the time. But... ahhh, time. I think that Zope's tagline could easily be - Makes you so productive and impressive that you're guaranteed customers and work and little free time to market, pontificate, or whine. Because it's true - I think that many of us are all busy professionals, more than we are dreamers looking for the next big distraction. Almost everything that I've done with Zope 3 since last august has opened the door to more uses, more customers, and more interest. A pet knowledge base project meant for internal use only is suddenly being shown to a couple of our biggest clients, and also provided the patterns for a suddenly different (and new!) project put into rapid-develop-and-deliver mode that led to a late night last night, but has given me today off so I have time to actually write this message. And I know that a lot of what I've done this past week I'll get to use/reuse in a big project coming up in the next few days. Finding time to advocate in the middle of all of this is hard. Plus, we kindof view it as a competitive advantage and don't necessarily want to give away our secrets (nor do we want to give our customers details or benefits away easily). It's not really about being selfish, it's about not having time to think about licensing, advocacy, promotional materials. Our own website has been nothing but contact information for years now! And still we stay busy, often busy. And I know that my company isn't the only one like this. So I understand why there's still no good Zope 3 site. I really hope that The Foundation can help with that though. .. [1] I just used schoolbell.relationship (from schoolbell 1.2.x, prior to the big restructuring they appear to have applied) in an application I wrote this past week. Awesome. Thank you for making this available! .. [etc] zope.formlib is so many many many kinds of awesome, and I really hope that more Zope 3 'core' development follows that pattern. The lack of ZCML magic is wonderful. Even more wonderful - i was dreading trying to make an add form that populated a custom written date widget with values based on the end of a date range set on the parent if there were no values set yet. I was dreading that all week. But last night, when it came time to implement that feature, I found the 'get_rendered' option very quickly, and three lines of code later I had a form whose usability had increased tenfold. -- Jeff Shell ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
Re: [Zope3-Users] How To Solve in Zope 3
On 2/3/06, Gary Poster [EMAIL PROTECTED] wrote: On Feb 3, 2006, at 9:32 PM, matt wilbert wrote: I have exactly the same situation, as I am writing a network management tool. I am using one big container and a local catalog. Then you can slice and dice as best suits you. I also think it is more extensible if you ever think you might add new object types. There is also the relationships stuff in Schooltool. I haven't needed it yet, but I was thinking it might be useful. I used those this week, with some success. I found the API a little hard to work with - I think it has RDF influences and I had a bit of a time getting my brain to wrap to that. But borrowing some ideas from zope.agxassociation, I made a Field and a property that uses that Field and got a pleasantly working system that masks some of the things that I had a hard time wrapping my head around (roles, groups, etc). That's GPL, if that makes a difference to you, and designed for intrinsic relationships. There's also One of these days, I'm going to need to learn what GPL really means, and how it should affect my choices of libraries that are open source that seem comparatively similar otherwise but for the license. I guess I need to revisit all the code we're using and check the licenses again, since we might be branching into some new business models. - zc.relationship, which is ZPL, relatively simple in concept, designed for extrinsic relationships between persistent objects, and pretty flexible; Ooo. I'll have to take a look at that one. - zope.agxassociation, which is ZPL, relatively simple in concept, and designed for intrinsic relationships; I was looking at this earlier this week, but it seemed incomplete... Actually, in subversion, the interfaces.py module ends after an opening parenthesis. Was I looking in the wrong place? I liked what I generally saw of agxassociation, but saw no concept of removing associations (only adding them). schoolbell.relationships (from Schoolbell 1.2.x) seemed a bit more complete. I hope it makes it into the Zope core. Now that I have relationships in my application, a whole new world has opened up - especially now that I've rigged up a system that doesn't require me to think in RDF. ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
Re: [Zope3-Users] Tagging content
. One of these days I'm going to make a kick-ass site where I can write documents about how I did this. It's cool when you get it working, but figuring out the traversal options and all of that just to have cool URLs like 'tags/foo/bar/baz' when 'foo', 'bar', and 'baz' are all objects being created on the fly was not easy. Anyways, the summary is: I used Catalog with a SetIndex (zc.catalog, look at http://svn.zope.org/Sandbox/zc/catalog/ ) for ``ITaggable.tags``. I use publishTraverse and views to do tag traversal. I have an AllTags view that when called renders a page showing tags in the 'cloud' style (showing popularity by size and with a number of matching), and when that's traversed through the TagMatcher sequence starts which creates these objects for each point along the URL that collect each tag name and when the end is reached, the default view runs the query and presents the results. You don't delete 'tags', since they're not first class objects. The set index deals with everything and seems quite efficient. You can do your option #2. My previous implementation, done last summer, worked that way.. kindof. Tags were more of a first class object and intids and all of that were used. But this new implementation I'm using seems a lot faster and more efficient. There were some hard things (namely the traversal stuff for nice URLs), but as far as indexing and querying goes, the Catalog/SetIndex combination works great. On 1/8/06, Igor Stroh [EMAIL PROTECTED] wrote: Hi there, I'm trying to figure out the best way to implements a general solution for tags (like tags on flickr or del.icio.us). So far I've two different approaches, maybe someone could comment on them: 1) Store the tags as attributes of the particular content types. Searching for tagged content is handled by a catalog index. New tags are created by simply adding them to the object, a collection of tags is the set of all tags from the catalog. Drawbacks: centralized tag management is inefficient, e.g. deleting a tag implies searching for the particular tag and removing it from all objects it was tagged with. 2) Store tags in a local utility. The utility manages a tag - intids mapping (similar to a catalog index). Searching for tags is easy - just query the mapping for appropriate keys. New tags are created by adding a new key to the mapping, a (weighted) collection of tags is the list if mapping keys. Drawbacks: I can't think of any right now Has anyone done that before? Maybe I'm just reinventing the wheel... Thanks in advance, Igor ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users -- -- Jeff Shell ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
Re: [Zope3-Users] Importing Lots of Objects
On 1/8/06, David Johnson [EMAIL PROTECTED] wrote: What is the best for merchants to manage the product list and content of their site? I can certainly put in into an RDBMS, but what would be the easiest way for them to manage their offering? Should I create a portal site for them or should I allow them into the ZMI in some way? Based upon the varied needs of the merchants, I would like to let them into the ZMI, and see their products as instances under their site. It's very easy to design multiple user interfaces in Zope 3 thanks to the skins system. You don't need to give them access to the ZMI. The ZMI in Zope 3 is just a default skin. It exposes a lot of things that are best used by those who understand Zope 3. You could fit custom product management screens into it, but in my experience it's better to build a custom interface. It's not that difficult to do. As far as managing the data in the RDBMS from Zope 3, you can always use SQL Methods / Scripts or just interact with the database adapters directly and do the SQL interaction that way. For a more object-oriented solution you can try using 'sqlos' (SQLObject Support) which integrates the Python SQLObject system with Zope 3. You can still use Zope 3's schema, widgets, and form system - even if you generate the SQL yourself. If you have a product schema like this: class IProductInfo(Interface): name = zope.schema.TextLine( title=uProduct Name, maxlength=255, required=True) price = zope.schema.Float(title=uProduct Cost, required=True) you can still use the form system to get those fields, validate the input against the schema, and if validation succeeds, you can generate SQL from the validated data instead of assigning it to a Python object. You can make a site for the merchants that is specific to their needs. It doesn't need to be the ZMI (it would be a lot of work to integrate into that), but it can be that kind system. All of the tools are there. For the amount of data that you're talking about, an RDBMS is probably better tuned to your requirements. But you can still take full advantage of Zope 3's features even if you're not using the ZODB as your primary storage. ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
Re: [Zope3-Users] Access attributes of content object from view
Try using ``len(self.context)``. The container will report its size. For a BTreeContainer, methods like ``values`` return OOBTreeItems, not a regular Python list. That's where the error is happening. You can get to the values of the OOBTreeItems object, but not its length. But the container itself you should be able to access just fine. The other option is to turn the result of values into a list or tuple:: values = list(self.context.values()) len(values) But if you're just trying to get the number of items in the container, ``len(self.context)`` is the best pattern to use. On 1/7/06, John Smith [EMAIL PROTECTED] wrote: Dear All, I have a containerish content object, subclassed from BTreeContainer. I have a view class which lists some of the contents. The view class receives a security proxied version of the content object but when I try len(self.context.values()) if get Forbidden Attribute : ('__len__', OOBTreeItems object at ) I have tried altering the zcml content/require permissions but they are all set for zope.View, including the IReadContainer interface. Is it to do with the fact that the object is subclassed from BTreeContainer? Any pointers gratefully received, Thanks, John ___ Yahoo! Messenger - NEW crystal clear PC to PC calling worldwide with voicemail http://uk.messenger.yahoo.com ___ 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
Viewlets (was Re: [Zope3-Users] using tal to insert zwiki content)
On 1/4/06, Benji York [EMAIL PROTECTED] wrote: Jeff Shell wrote: Viewlets are a new feature in Zope 3.2. They are? I don't recall it being so (and would prefer it not). Why not? They're great! I've been using them in a new application I've been developing against the 3.2 betas. I try to use only released software, and hope that these don't languish in something-you-must-know-how-and-where-to-checkout land Speaking of which, it's time to start lobbying for inclusion (or release) of zc.catalog. SetIndex works like a champ for what I've been writing. I mean to write up my experiences working on this new little application soon. Viewlets figure heavily into the story. ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
Re: [Zope3-Users] Permission required for renaming?
One option that you have is to protect the View object that you use to do the renaming, unless you're using views that are provided by someone/something else (the default Zope UI, etc). You can protect your 'rename' view and inside of it use 'zope.security.proxy.removeSecurityProxy' to get access to the renaming. Use removeSecurityProxy carefully, and make sure the code that uses it is itself restricted. On 1/5/06, Alec Munro [EMAIL PROTECTED] wrote: Hi Stephan, Actually, my users don't have that role(permission?), because I got the impression that having it would give them access to a number of things I don't want them to see, such as the metadata and introspector tabs. Is that strictly required for any kind of renaming/copying/pasting? Is there an easy way to change that? Thanks for your response, Alec On 1/4/06, Stephan Richter [EMAIL PROTECTED] wrote: On Wednesday 14 December 2005 12:40, Alec Munro wrote: Any ideas where I can go with this? It seems like there's probably a simple step I'm missing in the creation of my components, but so far I've had no luck figuring it out. Are you sure your user has the zope.ManageContent role? (BTW, please always post responses to the list as well.) Regards, Stephan -- Stephan Richter CBU Physics Chemistry (B.S.) / Tufts Physics (Ph.D. student) Web2k - Web Software Design, Development and Training ___ 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
Re: [Zope3-Users] How come no IView?
Thanks Chris, that actually does make things clearer. As a Z3 beginner, longtime Z2 user (ZPTs, scripts, ZSQL), and corporate developer who is trying to promote Z3 in-house, I am all for the current trend toward simplification, especially of ZCML (http://www.z3lab.org/sections/blogs/philipp-weitershausen/2005_12_14_zcml-needs-to-do-less). It seems like view class is a useful concept that gets talked about a lot. We're not going to have to start saying named multiadapter for content and request, are we? -- Wade No. It's pretty much understood what a View is... Typically it means a 'browser view', but it could in fact be anything. FTP, a graphical toolkit, and so on. The core component architecture doesn't tie anything to the web. But if you're looking for a base interface and class: interface: zope.app.publisher.interfaces.IBrowserView class: zope.app.publisher.BrowserView - has the __init__ with context and request, and is also locatable (mapping __parent__ to the context). This is a good one to subclass from, so if you need to do more work in __init__ you can call BrowserView's to ensure that anything it might do upon initialization in the future you get. But I doubt it will do much more than set self.context and self.request. While ZCML's view and page directives will put BrowserView into your base classes automatically if it's not there, I prefer to still use it as a base class directly. It makes the code more readable (I can see that 'SearchResults' is a browser view immediately), and is just a good concept (I believe) in making your code more Pythonic and less dependent on you or other readers of it understanding the ZCML 'magic' that goes on in the browser declarations. ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
Re: [Zope3-Users] Container Constraints
First - you can use ``from zope.app.container.constraints import contains``. It's a bit easier to write. Anyways, in Python you can't reference the class you're in because that name, 'ILinkContainer' does not exist **until the end of the class statement** (after all of the things indented within the class). A common thing to do in Zope 3 to deal with this is to separate the container / containment constraints into separate interfaces. This gets around the issue stated above. It's also nice to use 'IContained' to say an object is contained (IContained defines the fields __parent__ and __name__), but if you use that as a base interface for something with a schema you're likely to see extra fields when using edit forms. So the container / containment constraints are usually put in a separate interface. It's a bit of a separate policy. For your situation, you may want to separate that into a separate marker interface that is then implemented by both Link and LinkContainer objects. from zope.app.container.interfaces import IContainer, IContained from zope.app.container.constraints import contains class ILinkContainerContainable(IContained): Declare support for this to be stored in an ILinkContainer class ILinkContainer(IContainer): A container that can contain LinkContainerContainable objects, like links and other link containers. # this does the same as the __setitem__.precondition stuff. contains(ILinkContainerContainable) And then in implementation: from zope.app.container.contained import Contained from interfaces import ILinkContainer, ILinkContainerContainable, ILink class Link(Persistent, Contained): implements(ILink, ILinkContainerContainable) class LinkContainer(WhateverYourContainerRootMightBe): implements(ILinkContainer, ILinkContainerContainable) Having this one interface, 'ILinkContainerContainable' (or whatever you choose) then allows you to add other objects in the future that could be contained, or you can have a RootLinkContainer that's a special class that is an ILinkContainer but not containable so you can't add it below the root: class RootLinkContainer(AgainWithTheRootClass): # Picks up the link container constraints, but since it doesn't add # ILinkContainerContainable, it can't be added to other link containers. implements(ILinkContainer) But just remember - without special tricks, you can't refer to a class while you're inside of it. class Foo: any statement at this level can't access Foo but this level can. On 12/31/05, Marcus J. Ertl [EMAIL PROTECTED] wrote: Hi! I want to have container, witch should contain links and others containers of his own type! What I did is this in my interface-definition: class ILinkContainer(IContainer): Basic folder, containing only links and other link folders. def __setitem__(name, object): Add an ITodo object. __setitem__.precondition = ItemTypePrecondition(ILink, ILinkContainer) But zope tells me: NameError: name 'ILinkContainer' is not defined I'm shure, he is right! It's a little bit of recursion at this place. But what to do? Creating a marker interface? Something like: class IMarker(IContainer): ... class ILinkContainer(IMarker): Basic folder, containing only links and other link folders. def __setitem__(name, object): Add an ITodo object. __setitem__.precondition = ItemTypePrecondition(ILink, IMarker) Should work, but why creating a Interface for nothing? Must be a better way! And last but not least: Happy new Year! Bye Marcus Ertl ___ 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
Re: [Zope3-Users] Re: Get classes implementing Interface
On 12/30/05, Florian Lindner [EMAIL PROTECTED] wrote: Am Freitag, 30. Dezember 2005 17:45 schrieb Jim Fulton: Philipp von Weitershausen wrote: So, what you want is not a list of classes but a list of factories that can create IContainers. This is possible by using zapi.getUtilitiesFor(IFactory) and then checking each factory's getInterfaces() method whether IContainer is a part of the returned result. I would probably base an implementation of all on the UtilityVocabulary. I'll also note that the use case is also directly addressed through containment constraints. You can say that a container should only contain objects of some given types and you will get just those types in the add list. But the HomeFolderManager is not a container itself it's just a utility that creates container upon requests. And I want to make choosable which container to create. Or do I misunderstand you? Well first (and I apologize if this has been mentioned before), 'containers' are a more abstract notion while 'folders' are more concrete. A message or document that allows comments might be a container, but it's not something that you'd see in the ZMI or any content management type interface as a folder. You'd see it as an article. Something that's Folderish (to drag up an old term) will probably have a folder icon, will probably (but not necessarily) will have sub-folders, will have a view to manage its contents, and so on. It's important to keep these concepts distinct. In our content management system, we have a lot of containers. Due to a lack of understanding on my part about when I really wanted a generic container versus when I wanted a folder, we had some behavioral issues in our code at times because generic views were being applied to the wrong thing. During a big refactoring sweep I just completed, I separated these concerns completely and made a specific marker interface, 'IFolderishContainer' (ahh, memories again of _isPrincipiaFolderish ;) that classes or interfaces had to _explicitly_ declare support for. I made the common Folder class that we were using taboo for subclassing unless one really meant to take on all of the responsibilities of that Folder (user interface support for reordering, navigation menu building, and so on). And that folder class, itself, does not subclass from zope.app.folder.Folder since I didn't want these folders to be potential site managers. So then a photo gallery or jobs folder would just declare support for that interface, typically in ZCML. Then they could selectively choose what other capabilities they wanted. And that's how we separate Folders from other kinds of Containers. I think that was some of the earlier questions in this thread - how to tell if a container is really folderish versus a more generic container. In the closed world of our custom applications, this is how I solved the problem after some painful lessons along the way. Using marker interfaces like this has been awfully helpful. I use it in another situation where I have a single addMenuItem item that uses a view that lists all factories that declare support for a couple of specific interfaces. Something like this could probably help you too if this is what you mean by providing a choice as to what folders / containers can be created. This provides data to a template via the 'addableContainers' method which just looks for factories for the IHomeFolderableContainer faux interface I made up here. ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
Re: [Zope3-Users] Re: Get classes implementing Interface
Oops. It didn't seem to provide the code. Ahhh, GMail. Not even you can convince me that web based mail is going to replace real clients... And if there are multiple copies of this message, I apologize. from zope.interface import Interface, implements from zope.app import zapi from zope.event import notify from zope.publisher.interfaces.browser import IDefaultBrowserLayer from zope.app.container.interfaces import IAdding from zope.app.event.objectevent import ObjectCreatedEvent from zope.app.publisher.browser import BrowserView from zope.app.publisher.browser.interfaces import IBrowserView class IHomeFolderableFolder(Interface): Marker interface for home folderable folders class HomeFolderableFoldersAddView(BrowserView): Note - this particular implementation is for an IAdding view. But adding without IAdding is not too difficult on its own. implements(IBrowserView) zapi.adapts(IAdding, IDefaultBrowserLayer) def addableContainers(self): Returns a sequence of mappings with the keys ``name``, ``title``, and ``description``. ``name`` refers to the factory name which can be used to create the chosen container when the form is submitted. addable = [ {'name': name, 'title': fact.title,'description': fact.description} for name, fact in zapi.getFactoriesFor(IHomeFolderableFolder) if fact.title ] addable.sort(key=lambda x:x['title']) return addable def action(self): The form submission action. Looks for the factory identifier in the request by the name ``factory``, and calls self.createAndAdd(factory) with that value. factory = self.request.form.get('factory', '') if not factory: # report error here return u # redirect back to form self.createAndAdd(factory) return self.request.response.redirect(self.nextURL()) def createAndAdd(self, factory): container = zapi.createObject(factory) notify(ObjectCreatedEvent(container)) # The parent of this view is IAdding, and it will actually add the # content to the container. If not used in an IAdding situation, # provide your own way of checking constraints, choosing a name, and # adding the object to the place it needs to go. container = self.context.add(container) # Do anything else needed here... return container def nextURL(self): # This just dispatches to the IAdding view's nextURL method... return self.context.nextURL() Well first (and I apologize if this has been mentioned before), 'containers' are a more abstract notion while 'folders' are more concrete. A message or document that allows comments might be a container, but it's not something that you'd see in the ZMI or any content management type interface as a folder. You'd see it as an article. Something that's Folderish (to drag up an old term) will probably have a folder icon, will probably (but not necessarily) will have sub-folders, will have a view to manage its contents, and so on. It's important to keep these concepts distinct. In our content management system, we have a lot of containers. Due to a lack of understanding on my part about when I really wanted a generic container versus when I wanted a folder, we had some behavioral issues in our code at times because generic views were being applied to the wrong thing. During a big refactoring sweep I just completed, I separated these concerns completely and made a specific marker interface, 'IFolderishContainer' (ahh, memories again of _isPrincipiaFolderish ;) that classes or interfaces had to _explicitly_ declare support for. I made the common Folder class that we were using taboo for subclassing unless one really meant to take on all of the responsibilities of that Folder (user interface support for reordering, navigation menu building, and so on). And that folder class, itself, does not subclass from zope.app.folder.Folder since I didn't want these folders to be potential site managers. So then a photo gallery or jobs folder would just declare support for that interface, typically in ZCML. Then they could selectively choose what other capabilities they wanted. And that's how we separate Folders from other kinds of Containers. I think that was some of the earlier questions in this thread - how to tell if a container is really folderish versus a more generic container. In the closed world of our custom applications, this is how I solved the problem after some painful lessons along the way. Using marker interfaces like this has been awfully helpful. I use it in another situation where I have a single addMenuItem item that uses a view that lists all factories that declare support for a couple of specific interfaces. Something like this could probably help you too if this
[Zope3-Users] Specialized URL traversal.. Best way?
This week I've been revisiting some of my early Zope 3 ideas in a small new application we plan to use internally. One of the core concepts of this system is 'tagging', similar to del.icio.us, flickr, snippets, etc. Old versions that I wrote managed tags manually, with a 'taglib' object and tags being their own indexes that manually tracked the documents that mentioned them. I wanted to use the catalog, but the required indexes weren't available or usable by me at the time, and then other projects came along. In the last version I wrote prior to now, I wrote a custom Traversable adapter for this 'taglib', which was BTreeContainer. zope.app.traversing.interfaces.ITraversable - traverse(name, furtherPath) I used 'furtherPath' to go along and turn paths like 'zope/enterprise/cms' into tags to search (again, using a manual system due to lack of catalog). Since this was on a custom container, it somehow worked. So today, I thought I could provide a similar adapter, but on a view object, that could get the rest of the requested path in one swoop that I could then use to query a SetIndex in the catalog. But no matter what I did, I couldn't get it to work. It doesn't seem like my ITraversable gets called at all for my view - even with that view providing the interface I say I adapt and on and on. I could get my traversable adapter from the interpreter, but it wasn't ever touched during the zope.publisher publication process. At best, I figured that 'publishTraverse()' was where I needed to go based on the errors that I kept having. But publishTraverse() deals with one name at a time... But it does pass in the request. And at most, I guessed that the traversal stack was what I needed. Again, this is to have URLs like: myapp/@@tags/zope/viewlet And turn that into a catalog search for anyof {'zope', 'viewlet'} def publishTraverse(self, request, name): namestack = request.getTraversalStack() if name not in namestack: namestack.append(name) namestack.reverse() tags = tuple(namestack) request.setTraversalStack([]) results = TaggedArticleFinder(self.__name__,self.__parent__,tags) results.prepareSearch(request) return results The 'TaggedArticleFinder' then provides an interface that a view can be found for that displays the results. So I've got it all working now... But it seems kindof awkward. There are a few different traversing options, and knowing which one applies when is difficult to figure out. And monkeying with the traversal stack.. Is that really what I should be doing here? It seems like the interface for ITraversable that specified 'furtherPath' is what I'd like to be using when I'm wanting to play with the whole path from this point on. I ultimately want to provide a few more options similar to this one for things like date based filtering (urls like @@bydate/2005/12 or 2005/12/29). None of these are containers or real objects, just URL segments used to construct a query. I was wondering - is this the best way to do this? Is there a better recipe floating around out there? I appreciate Zope's direct-to-object URL publishing (been using it since '97!), but custom URL maps past a certain object like a view seem to be quite tricky, whereas Django and generic toolkits like Routes are specializing in ways of managing custom URL maps. I know there are a few places where one can take over this process, but it's not obvious when and how to use them, or which to use. BeforeTraversal event? publishTraverse? ITraversable? ITraversing? Ultimately I'd like to put a couple of views into the root of my app that can do something akin to Django's url_dispatch: http://www.djangoproject.com/documentation/url_dispatch/ where a set of patterns and a name are used to allow for various dynamic queries. The name would be used to look up a component to respond to the matched items in the path. It wouldn't interfere with any other traversal (ie - wouldn't replace the default way of doing it). Doing it from a browser view seems safest, since this is almost exclusively about keeping nice URLs for web browsing. I just want to know the best place to plug in. ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
Re: [Zope3-Users] Re: ZCML, practicality, purity (was Excellent perspective...)
On 12/23/05, Shane Hathaway [EMAIL PROTECTED] wrote: Jeff Shell wrote: I just believe - heavily - after many of my Zope 2 experiences that configuration as done by ZCML should be as separate from the code itself as possible. If it's going to be in the same programming language, it needs to be made clear what it is, what can be done, and what can NOT be done. Ok, but you broke your own rule. Quoting your blog entry [1]: zope.component.provideUtility(greyhounds, name='greyhound') [1] http://griddlenoise.blogspot.com/2005/12/zope-component-architecture-interfaces.html This code appears at module scope. You've hardcoded the configuration of a utility. You did it again with some provideAdapter() calls. You're doing configuration the same way Zope 2 does it. You created nontrivial side effects that no one can control without changing your code. Even worse, this is a public example which I myself promoted! I apparently made a mistake. Upon reflection, I realize that your example is dangerous and illegal, since it integrates poorly with Zope. You're outright wrong and your blog should be shot! I was not writing a Zope 3 Application Server Application - I had one utility and three adapters crammed into a make believe module :). In the second article, I moved those into 'basicConfigure()' functions anyways. My code used nothing more than zope.component and zope.interface, and that's all that I was trying to show. I do believe that the component architecture is and should be usable without ZCML. But I also believe that large systems such as the full app server and applications built on the larger Zope framework can benefit from it. Ok, not really. ;-) But this illustrates why the line between code and configuration shouldn't be a brick wall. Your example would have been much cleaner if you had written a function at module scope where you perform all registrations for the module. Then users of your module could choose to call your registrations or not. ... which is pretty much what you did in a later example, in basicConfigure()! [2] Users can choose to call basicConfigure(), and if they don't, they start with a squeaky clean configuration. See, this idea is not really mine. *You* configured things in Python code. You did it because it's natural and easier to explain. I'm suggesting a way to let you write configuration code safely, so that those who follow your example don't descend into a Zope 2 mess. [2] http://griddlenoise.blogspot.com/2005/12/zope-component-architecture-one-way-to.html I was also writing an advocacy post (in the first one) at midnight that was bordering days that nearly dropped me dead from the point of exhaustion. I wasn't wanting to show endless black magic - and then I wave my hands and everything is configured!. I was wanting to show how two modules - zope.component and zope.interface - could be used without the rest of Zope (aside from zope.exception, I believe). Not long after ZCML came into existence, I invented a way to configure using Python code, and I think I posted some examples. I realize now that the simple way I did it was wrong. What I'm suggesting now is to retain the semantics of ZCML but switch the syntax. It would be possible to automate the conversion of all existing ZCML files. The XML implementation of Zope configuration is an overreaction to the things that went wrong in Zope 2. Configuration in Zope 2 was bad simply because there was no consistent method of configuring things. Now that we have a fairly complete configuration system and a set of conventions, sloppy configuration will no longer proliferate in the Zope community, unless the system is too rigid. Your example broke convention, with potentially harmful consequences for people who follow your example, suggesting the system is currently too rigid. My example, again, was a single standalone module written on near zero sleep. It was by the second example that it had already grown to be too big to be configured in-line. I think you could achieve this with Python, but you'd need do document the hell out of it and put in a smart and restrictive system that would ensure that sloppy configuration didn't happen, that the 'configure.py' module was unused by anything but the configuration system, and that the package it was in could be loaded as a Python package/module without the 'configure.py' module (which would have the most requirements on the configuration of the outside system) be ignored or otherwise not blow up when trying to register against something not defined. Restrictions aren't necessary. If developers are simply told what the convention is and why they should follow it, they'll follow it. Again, the problem in Zope 2 was that there was no convention for configuration, so everyone made one up. Restrictions help. Or, at the very least, warnings. warning: configuration module imported by non
Re: [Zope3-Users] Re: ZCML, practicality, purity (was Excellent perspective...)
into meaningful objects. The ability to use local dotted names: foo for=.interfaces.IPony far class=..zoo.Butterstick. The ability to see those things _clearly_ defined in APIDOC because of their schema-ness. If I need to know whether I can pass only one interface reference in to a particular ZCML attribute or if I can pass in multiple, I can actually get that information and it's based on the schema, but still pass it in as just a string in XML. How would that work in Python? Would it be the responsibility of the 'configure.py' maintainer to use tools to expand things? Would the configuration machinery used try to be smart about what's passed in to allow for both: from interfaces import IThis, IThat configure.registerView(for=IThis, adapts=(IThat, '..interfaces.IOther')). Would that be allowed? Configuration's not easy when wanting to allow a big system to all be used together via the sort of loose coupling that Zope 3 allows. Staying within the native programming language has benefits, but also may be a dangerous path to shortcuts that then cut down on the sort of re-use and extendible / replaceable connection points that I've been able to benefit from over the past few months of Zope 3.x based development. I'm not saying this is impossible to do in Python. These are just the risks and issues that I've been thinking of, and have thought of for the past couple of years. We've developed a custom framework for dealing with data flow and transformation for a couple of 'enterprise' level customers, and XML is used heavily to wire all of these transforms together. The XML files can get HUGE and not always easy to maintain. But the job that they perform is so wildly different than what the Python application and component code is doing that, well, it made sense to separate them. (Plus we had the special requirement to be able to reload that configuration file and all that it specifies. Clearing out a big registry and then filling it up again based on those configuration settings is a lot easier than refreshing a big system of Python code). Let people have their Rails. Let them grow their applications. Let them see what happens when it gets big and the whole programming by convention thing starts to break down because conventions get forgotten or you put a text file in one of their magic directories that causes the whole system to blow up because it shares the name with some forgotten convention that Rails (or its clones) looks for. We've been through that. I think that the ZCML situation could be improved with: * simpler use - let Python code say what it adapts and implements. Let Python code subclass from BrowserView. Use ZCML to just register and name the object. Promote this in documentation, advocacy articles, and so on. * alternate syntax? Not Python, but maybe something python-ish but geared towards entering the kind of data references that one has to type a lot in configuration. * cut down on the magics like dynamic class creation. this was a frustrating surprise when I first encountered it a couple of months ago. * for many of the core ZCML configuration directives, explain their Python alternative. Not to promote its use when writing large systems, shared toolkits or frameworks, but to show how to test or just to use adapters and utilities in small applications that don't require the full Zope toolkit. I mentioned that I liked the ZCML documentation. It's great for finding out what directives are available and what their options are. But it's still pretty poor at explaining what is really going on behind the scenes. That may be more advanced documentation for some cases - but it could cut down on some users frustration and surprises. OK. This has been long and rambling. I blame the christmas lunch cocktails. :) -- Jeff Shell ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
[Zope3-Users] Re: [Zope3-dev] URGENT RFC: Is anyone using response.write in Zope 3?
I was using it in some custom views for HurryFile based images. I've removed it since I started testing our code against Zope 3.2. Right now I just return the hurryfile binary data with a return statement (one big chunk), but am looking forward to knowing how to return long output. On 12/19/05, Jim Fulton [EMAIL PROTECTED] wrote: When we refactored the Zope 3 pubisher to work more closely with WSGI, we decided to remove the response.write method. We should have written a proposal for this, but we failed to do so. Over the last few weeks there has been much discussion of this in which I asserted many times that I didn't think any applications outside of Zope 3 itself used this method. No one has disagreed with me. I want to double check this. Does anyone have any Zope 3 applications that are using response.write? Assuming that the answer is no (or that no one answers today), I'm going to more clearly document how to return long output and I'm going to add a method that generates a hopefully helpful error. Note that we may add this method (or something like it) back in the future to support chunked streaming output, Jim -- Jim Fulton mailto:[EMAIL PROTECTED] Python Powered! CTO (540) 361-1714http://www.python.org Zope Corporation http://www.zope.com http://www.zope.org ___ Zope3-dev mailing list Zope3-dev@zope.org Unsub: http://mail.zope.org/mailman/options/zope3-dev/eucci.group%40gmail.com ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
Re: [Zope3-Users] Catalog for newbies
On 12/6/05, Frank Burkhardt [EMAIL PROTECTED] wrote: Hi, after adding a Unique Id utility, Catalog and some field + text indices I successfully added documents which seem to be added to the catalog (as shown in the catalog's Advanced-tab). However I've got two question now: 1. How do I search the catalog? Querying the catalog directly is kindof a pain right now, as the indexes have their own 'query' syntax. I'd recommend checking out 'hurry.query' which makes building queries easier: http://faassen.n--tree.net/blog/view/weblog/2005/09/09/0 But to query directly, you can basically do this in a view: catalog = zapi.getUtility(ICatalog, 'catalog', self.context) results = self._results = catalog.searchResults(textindexname='text to search for', fieldindexname=('low value', 'high value')) and so on, with 'textindexname' and 'fieldindexname' being the names of the indexes you're searching for. For field indexes, you have to specify a 'low' and 'high' value in the tuple. This surprised me when I was doing catalog work a few months ago before we started using hurry.query - I thought I could do a search like ``section='winter'`` to get all documents in the 'winter' section of the site. That worked fine. But when we added 'summer' to the site and I did ``section='summer'``, winter documents showed up too! What happened is that when only one value is passed into the field index for querying, it's thought that the high value is open. Since 'winter' 'summer', the winter documents were being returned in my summer query, but not the other way around. So a field index query is a range. If you want items that match a single value like I did, you have to do something like ``section=('summer', 'summer')``. With 'hurry.query' you can build complex queries more easily. 2. Documents are added to the index only when they are added to the ZODB. Is there a Way to scan the entire ZODB to index all objects matching the indices interface constraints? On the 'Advanced' tab for the catalog in the default skin(s) there is a 'Reindex' button which will rebuild all of the indices based on their configuration. ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
[Zope3-Users] Re: Denying permissions for 'everybody' - which principals to use?
Nobody knows? I'm bouncing this up to see if anyone has any input yet. I had some other projects come up that put this on hold for a bit, but just now looking at the code I realized I still need help. And before I go through the joys of experimentation this weekend or early next week with all of the combinations I ask here, I thought I'd float this by again. The summary of what I say below is: I don't know how to programatically deny zope.View to everybody. The implementation I currently have challenges the visitor but then still allows access to the object in question even if the HTTP auth challenge box is canceled out of. On 11/16/05, Jeff Shell [EMAIL PROTECTED] wrote: For a simple content management system we're building, I've started working on a simple security interface which is supposed to enable / disable 'view' (and dublin core view). The setup that I have - or want to have - is a UI that says: Who can see this item? - Everybody - Nobody (grants view to zope.Manager and our.cms.ContentEditor roles only, for now) - Specific Users If 'specific users' is selected, users from the local principal folder are listed for selection. I seem to have my implementation working somewhat - I can go to the normal Grant screen and see specific users have 'Allow' checked for the view permissions managed by my sharing view. And 'zope.anybody' is denied: pprint(settingsForObject(jobs)) [(u'jobs', {'principalPermissions': [{'permission': 'zope.View', 'principal': u'brcmscms.user2', 'setting': PermissionSetting: Allow}, {'permission': 'zope.View', 'principal': 'zope.anybody', 'setting': PermissionSetting: Deny}, {'permission': 'zope.app.dublincore.view', 'principal': u'brcmscms.user2', 'setting': PermissionSetting: Allow}, {'permission': 'zope.app.dublincore.view', 'principal': 'zope.anybody', 'setting': PermissionSetting: Deny}], 'principalRoles': [], 'rolePermissions': []}), ... When I traverse to the object in question in another browser, I get prompted for login. But if I supply different credentials (ie, one of the users not Allowed explicit view privileges), I'll still see the page. Am I denying the right person here? Globally, the permission is set up as follows: {'permission': 'zope.View', 'role': 'zope.Anonymous', 'setting': PermissionSetting: Allow}, Should I Deny access to the zope.Anonymous role? To the Everybody group? To the Unauthenticated Group? Right now, I only deny the principal: def denyUnauthenticated(self): Explicitly deny the view permissions for unauthenticated users. anybody = zapi.getUtility(IUnauthenticatedPrincipal).id pmanager = IPrincipalPermissionManager(self.context) for permission in self._view_permissions: pmanager.denyPermissionToPrincipal(permission, anybody) This is in Zope 3.1.0 on Python 2.3.5 The point of this simple 'sharing' interface is to let our customer have a press folder that they can restrict access to by allowing only limited people in to it. We're trying to keep the user interface as simple as possible. ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
[Zope3-Users] Generations - a missed use case? (Evolving an application for the first time)
I have an application where I'm trying to use 'zope.app.generations' for the first time. And after much pulling of hair and looking at the core code, I found what may be a missed scenario. Basically, we deployed this application for a customer and now they want some changes. It changes the schema of one item to store values in tuples instead of strings. I wrote an evolve module, 'evolve1.py' in myapp.generations, made the schema manager, registered it as a utility, bla bla bla. But my code seemed like it would never run. I'd run the debuzope script and look at the database root['zope.app.generations'], and there was 'myapp' with the value of 1. I'd keep deleting that key and committing the transaction, but my code would still never run. I tried running it manually using pdb.run() to step through it and make sure that it was finding the right objects and doing its job. My code was fine. So I looked at the code in zope.app.generations.generations and found this interesting tidbit: for key, manager in findManagers(): generation = generations.get(key) if generation == manager.generation: continue if generation is None: # This is a new database, so no old data if IInstallableSchemaManager.providedBy(manager): try: manager.install(context) except: transaction.abort() logging.getLogger('zope.app.generations').exception( Failed to install %s, key) raise generations[key] = manager.generation transaction.commit() continue (the code continues from there There's one problem here - in my situation, it's NOT A NEW DATABASE. There is old data that needs to be evolved, but there's no record of a generation for this application because there was no need for a schema manager until now. I really like the concept and general implementation of the schema manager, but this scenario is driving me crazy. I could write an 'install' script, but that doesn't really cover this situation. After install is run, the database marks the application generation. This makes sense for new applications installing themselves - there's no old data to update, so if the application is at generation 5, for example, it doesn't need to be evolved to '5' if all of the data that's installed or used is already in generation 5 form. (ie - if I were deploying my application fresh today, my fields would already be tuples instead of strings). But my situation, where I already have a deployed application, is not covered by this. I *could* write an 'install' script for the schema manager that did this first evolution that I need to do. But then that installer would have to be updated with all of the future evolutions as well - since in theory, I could update an application from before the schema manager and need to bring it up to generation 5 or 8 from essentially 0. It seems like the Schema Manager needs an 'evolve from 0' option, with '0' being set by the evolution script of no previous evolution was found but (somehow) existing data could be detected. The other solutions seem to be: * Write an install script that then manually calls all of the evolvers to bring things up to the current generation. * Always put a schema manager in your application, with the starting generation of 0, so that you can upgrade in the future. Neither option seems quite tenable - like a bad hack that goes against the Zope 3 concepts. You shouldn't need a schema manager utility until you need it, and having a script that manually does 'evolve1.evolve(context); evolve2.evolve(context)'... seems like it goes against the sort of problem that the generations system is trying to solve. Is there something about the schema manager/generations system that I missed? ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
[Zope3-Users] Denying permissions for 'everybody' - which principals to use?
For a simple content management system we're building, I've started working on a simple security interface which is supposed to enable / disable 'view' (and dublin core view). The setup that I have - or want to have - is a UI that says: Who can see this item? - Everybody - Nobody (grants view to zope.Manager and our.cms.ContentEditor roles only, for now) - Specific Users If 'specific users' is selected, users from the local principal folder are listed for selection. I seem to have my implementation working somewhat - I can go to the normal Grant screen and see specific users have 'Allow' checked for the view permissions managed by my sharing view. And 'zope.anybody' is denied: pprint(settingsForObject(jobs)) [(u'jobs', {'principalPermissions': [{'permission': 'zope.View', 'principal': u'brcmscms.user2', 'setting': PermissionSetting: Allow}, {'permission': 'zope.View', 'principal': 'zope.anybody', 'setting': PermissionSetting: Deny}, {'permission': 'zope.app.dublincore.view', 'principal': u'brcmscms.user2', 'setting': PermissionSetting: Allow}, {'permission': 'zope.app.dublincore.view', 'principal': 'zope.anybody', 'setting': PermissionSetting: Deny}], 'principalRoles': [], 'rolePermissions': []}), ... When I traverse to the object in question in another browser, I get prompted for login. But if I supply different credentials (ie, one of the users not Allowed explicit view privileges), I'll still see the page. Am I denying the right person here? Globally, the permission is set up as follows: {'permission': 'zope.View', 'role': 'zope.Anonymous', 'setting': PermissionSetting: Allow}, Should I Deny access to the zope.Anonymous role? To the Everybody group? To the Unauthenticated Group? Right now, I only deny the principal: def denyUnauthenticated(self): Explicitly deny the view permissions for unauthenticated users. anybody = zapi.getUtility(IUnauthenticatedPrincipal).id pmanager = IPrincipalPermissionManager(self.context) for permission in self._view_permissions: pmanager.denyPermissionToPrincipal(permission, anybody) This is in Zope 3.1.0 on Python 2.3.5 The point of this simple 'sharing' interface is to let our customer have a press folder that they can restrict access to by allowing only limited people in to it. We're trying to keep the user interface as simple as possible. ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
Re: [Zope3-Users] User data / metadata
On 9/28/05, James Allwyn [EMAIL PROTECTED] wrote: Hello list, A small 'conceptual' question... Both Stephan and Philipp's books recommend using principal metadata to store users' email addresses etc. If I intend to use the email addresses (and other contact information I want to store for the user) within the application (i.e., other objects will want to present it on screen), has it crossed the border from metadata to data, and would it consequently make sense to define principals with these attributes directly? You could do it directly. In fact, you could even have 'members' as regular content objects in the site and write an authentication utility which looks up those members and builds a security Principal object off of that. I believe this is what Schoolbell does. http://schooltool.org/ ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
Re: [Zope3-Users] Sending object modified event on FTP upload - best practice?
On 7/28/05, Jim Fulton [EMAIL PROTECTED] wrote: Jeff Shell wrote: In looking at how FTP support is written in zope.app.ftp, I notice that ObjectCreatedEvent notifications are sent off when new objects are created. But when zope.app.ftp.FTPView._overwrite(...) is used to write to an existing object via an IWriteFile adapter, the FTP View does not send an object modified event. I'm assuming that it's the responsibility of my IWriteFile adapter to send notifications of this event? Yes. Or is this something that should be in the FTPView's implementation? No. The FTPView isn't actually modifying the object, the IWriteFile viw is. It's possible that the write-file adapter could be modifying a different object than the one it adapts. Excellent. That's what I thought, but I wanted to ensure I understood the ethics of event notifications correctly. Thanks! -- Jeff Shell ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
[Zope3-Users] My Javascript resources aren't loading in Firefox
Safari 2.0 versus Firefox 1.0.4 Mac OS X 10.4.1 Zope 3.1b1 / Python 2.3.5 Zope and the browsers are both running on my desktop system (iMac G5). I'm getting down and dirty playing with Zope 3.1b1 with occasional Zope 3 experience. I'm also using this opportunity to play with XMLHTTPRequest / DHTML via libraries like prototype.js. I made a custom skin for my application, and its configure.zcml file looks like this: configure xmlns=http://namespaces.zope.org/browser; layer name=snippets/ skin name=snippets layers=snippets default/ resource name=snippets.css file=snippets.css layer=snippets/ resource name=prototype.js file=prototype.js layer=snippets/ resource name=snippetlib.js file=snippetlib.js layer=snippets/ resource name=favicon.png file=favicon.png layer=snippets/ page for=* name=view_macros permission=zope.View layer=snippets template=template.pt/ page for=* name=dialog_macros permission=zope.View layer=snippets template=dialog_macros.pt/ /configure I can't say that I fully comprehend all that's going on here, and I realize that there are some changes made in Zope 3.1 regarding skins (preferring an interface, it seems?). In any case, this seems to work fine with Safari with the following lines in template.pt: script type=text/javacript src=prototype.js tal:attributes=src string:${context/++resource++prototype.js}/script script type=text/javacript src=prototype.js tal:attributes=src string:${context/++resource++snippetlib.js}/script title metal:define-slot=titleSnippets/3/title style type=text/css media=all tal:content=string: @import url(${context/++resource++snippets.css}); @import url(snippets.css); /style link rel=icon type=image/png tal:attributes=href context/++resource++favicon.png / Accessed with the following URL: http://localhost:8080/++skin++snippets/snippets/ It's all protected right now, so I have to log in. That works fine in both browsers. When I use Safari and load that page, I see the following output from 'runzope': 127.0.0.1 - zope.manager [27/Jun/2005:23:06:18 -0600] GET /++skin++snippets/snippets/ HTTP/1.1 200 3162 Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en-us) AppleWebKit/412 (KHTML, like Gecko) Safari/412 127.0.0.1 - zope.manager [27/Jun/2005:23:06:18 -0600] GET /++skin++snippets/@@/prototype.js HTTP/1.1 200 21484 http://localhost:8080/++skin++snippets/snippets/; Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en-us) AppleWebKit/412 (KHTML, like Gecko) Safari/412 127.0.0.1 - zope.manager [27/Jun/2005:23:06:18 -0600] GET /++skin++snippets/@@/snippetlib.js HTTP/1.1 200 995 http://localhost:8080/++skin++snippets/snippets/; Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en-us) AppleWebKit/412 (KHTML, like Gecko) Safari/412 127.0.0.1 - zope.manager [27/Jun/2005:23:06:18 -0600] GET /++skin++snippets/@@/snippets.css HTTP/1.1 200 1211 http://localhost:8080/++skin++snippets/snippets/; Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en-us) AppleWebKit/412 (KHTML, like Gecko) Safari/412 When I access the exact same URL from Firefox on the same machine, I see the following output: 127.0.0.1 - zope.manager [27/Jun/2005:23:06:52 -0600] GET /++skin++snippets/snippets/ HTTP/1.1 200 3162 Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; en-US; rv:1.7.8) Gecko/20050511 Firefox/1.0.4 127.0.0.1 - zope.anybody [27/Jun/2005:23:06:53 -0600] GET /++skin++snippets/@@/snippets.css HTTP/1.1 304 264 http://localhost:8080/++skin++snippets/snippets/; Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; en-US; rv:1.7.8) Gecko/20050511 Firefox/1.0.4 And that's it. The CSS loads, and the 'favicon' is cached. If I clear the cache, I see the 'favicon' resource get loaded, but not the Javascript. The kicker is - javascript resources load fine in Firefox in this same setup when using the Rotterdam skin, even when using a ++skin++ url. Looking at the Rotterdam configuration and templates, I can't figure out anything substantially different. It's really vexing that the javascript resources aren't even being requested by the browser. I can view source on the page and see lines like script type=text/javacript src=http://localhost:8080/++skin++snippets/@@/prototype.js;/script and I can visit those URL's directly. I even installed the web developer toolbar for Firefox and used its View Javascript option, which loads and displays the source of all scripts in a page, including referenced ones, and it loads these libraries just fine. So Has anyone seen anything like this? any ideas on where to look? This particular application that I'm working on doesn't *need* to run on Firefox - I'm basically using it to teach myself a few things. But this is just... very vexing. Thanks -- Jeff Shell http://griddlenoise.blogspot.com/ ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org