[Zope3-Users] Zope on WSGI for Deployment - best to still use proxy behind apache? Good/bad servers?

2008-01-22 Thread Jeff Shell
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


[Zope3-Users] Buildout and the Data.fs

2008-01-22 Thread Jeff Shell
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


Re: [Zope3-Users] Re: buildout and egg depedencies

2007-12-12 Thread Jeff Shell
epresentation` installing as a zipped egg, which then gets
in the way of ZCML being able to load its configure.zcml file. I tried
to find out if there was an 'always_unzip' option for Buildout, but it
seems to only be a part of buildout's easy_install API.

> > 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.
>
> 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

2007-12-11 Thread Jeff Shell
s. In setup.py? In
buildout.cfg? Repeated in both? Our big old libraries (which I also
hope to break into smaller components as we change source code
management systems) use a LOT of Zope 3. Do I grep the source for
'from zope ...' and 'import zope.*' and list all unique dependencies
that I find?

> Lots 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


Re: [Zope3-Users] buildout and egg depedencies

2007-12-11 Thread Jeff Shell
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


Zope 3 w/ SQLAlchemy 0.4 (was Re: [Zope3-Users] Eggs and classic instance homes, again...)

2007-11-09 Thread Jeff Shell
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)

2007-11-08 Thread Jeff Shell
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)

2007-11-07 Thread Jeff Shell
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)

2007-11-07 Thread Jeff Shell
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

2007-08-20 Thread Jeff Shell
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

2007-08-17 Thread Jeff Shell



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] Re: Eggs, workingenv.py, and 'classic' instance homes

2007-08-16 Thread Jeff Shell
> 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


Re: [Zope3-Users] Eggs, workingenv.py, and 'classic' instance homes

2007-08-16 Thread Jeff Shell
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] Eggs, workingenv.py, and 'classic' instance homes

2007-08-16 Thread Jeff Shell
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


[Zope3-Users] Ahh, counters... Best practice?

2007-08-14 Thread Jeff Shell
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

2007-08-02 Thread Jeff Shell
> 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

2007-07-30 Thread Jeff Shell
On 7/30/07, Stephan Richter <[EMAIL PROTECTED]> wrote:
> On Monday 30 July 2007 09:59, Jeff Shell wrote:
> > 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.
>
> I agree we are totally lacking At the one end we push hard for people
> to use eggs -- even make the Zope 3 trunk checkout totally useless --
> and on the other hand we are providing zero documentation on how to
> get started.

Getting started as eggs is one thing. Moving code that is not in an
egg format is another, particularly in a system like CVS which is
brain dead about directories. But I think I just need to revisit the
CVS manual for this.

We're stuck with CVS for now, for better or worse. And my vague
understanding of development eggs (which is next to nil) is that
they're biased towards SVN. With good reason, I guess, since SVN
changeset numbers apply to whole checkouts versus CVS's individual
file versioning. But I may be wrong about this.

> The common answer you will get is: Look at all the SVN packages,
> there are many examples. I think this is a horrible thing to
> say. Unfortunately there is a big push behind using egg-based
> development without taking care that all bases are covered. I think
> this is because most development is driven by customer requirements
> these days and not by the "academic purity" (as people called it) with
> which we started developing Zope 3. I guess this is a good and a bad
> thing.

We have that problem too, which is why we seldom have time to keep on
top of all developments. To date, expediency and easy patching have
been the order of the day which is why our system has been in place
for so long.

But as we're stepping up in scalability and complexity of deployment
setups in order to distribute load and responsibility, I keep wanting
to check out buildout. But... it's scary.

-- 
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

2007-07-30 Thread Jeff Shell
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


Re: [Zope3-Users] Re: Unicode for Stupid Americans (like me)?

2007-03-01 Thread Jeff Shell

On 3/1/07, Paul Winkler <[EMAIL PROTECTED]> wrote:

On Wed, Feb 28, 2007 at 09:08:03PM -0500, Gary Poster wrote:
> It's been years since I dug into this, but I'm better than 90% sure
> that the browser is expected to make its requests in the encoding of
> the response (i.e., the one set by Content-Type).  It's been too long
> for me to tell you if that's in a spec or if it is simply the de
> facto rule, though I suspect the former.

That almost makes sense, except that the first request precedes the
first response :) I'll have to dig into this some more when I have
time...


By first request do you mean first form-submission? You have to do a
request to get the form. When the server sends the form, the HTTP
response containing the form should have a content type.

If the form to be submitted has an accept-charset attribute explicitly
declared, that should become the value of the Accept-Charset header.
If that field is absent, it's supposed to be understood as a special
value, 'UNKNOWN', which means that the browser or other user-agent may
submit (I don't remember if the spec says MAY or SHOULD, but I know it
doesn't say MUST) the response in the same character set as the form's
page.

I did a fair amount of spec reading and zope.publisher.http/browser
entrail reading yesterday, can you tell? :)

Anyways, without adding accept_charset to the form, this is what
Firefox sent on a form submission request's Accept-Charset header::

   ISO-8859-1,utf-8;q=0.7,*;q=0.7

Zope turned that into::

   ['utf-8', 'iso-8859-1', '*']

Zope gives UTF-8 priority over everything. The Accept-Charset header,
if present on the request, is used to establish the response character
set unless explicitly stated otherwise (or the response isn't text).
So I guess if my Firefox is sending that same accept-charset header to
Zope on each request, it will get a UTF-8 response every time (again,
unless explicitly made otherwise). If it is supposed to submit POSTs
in the same character set that it received, then it should be sending
UTF-8 each time. Hunh.

So if you had , then the browser
should send only cp437 in the Accept-Charset header and Zope should
only try to decode from that character set; and the succeeding
response should be encoded in cp437 as well. I think. That seems to be
the best I can figure out between the HTML 4.01 and HTTP 1.1 specs and
zope.publisher's http/browser request and response handlers. It seems
unlikely that you would ever need to use accept_charset like this,
though; at least not in Zope which does a good job of doing all of
this encoding/decoding work.

Well, all of this is good to finally know. This has been a mysterious
black box to me for such a long time, and it turns out that I don't
need to worry about it.

The lessons I've learned for text, as they apply to my own code, are thus:

- Work in unicode, not strings; then you won't have to worry about collisions
 between unicode and strings ('ab' + u'cdé') raising decode errors.

- When working with text, decode strings to unicode instead of encoding
 unicode to strings. I was forcably **encoding** my unicode objects when I'd
 be building up long strings, which came from my confusion over
 encode/decode. This is how I'd lose my extended characters and end up with
 garbage output.

- Be alert to what other text processing tools such as the Python
 implementations of Textile and Markdown want as input and return as output.
 In my ignorance, I wasn't paying attention to the fact that I needed to
 decode the results back to unicode, and I believe this was another systemic
 central point of pain, torture, and failure for my apps. And in my ignorance
 I tried to fix the errors that I saw with forcable *encoding* instead of
 *decoding*, which is why I would see garbage characters show up in
 certain situations. I now realize this is the right way to work with those
 tools::

   rendered = textile(content.encode('utf-8'), encoding='utf-8',
  output='utf-8')
   return rendered.decode('utf-8')

Does that all sound right?

--
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)?

2007-02-28 Thread Jeff Shell

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


[Zope3-Users] Unicode for Stupid Americans (like me)?

2007-02-28 Thread Jeff Shell

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] Using zope.component outside Zope 3-how to bootstrap the registries

2007-02-16 Thread Jeff Shell

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: [Zope3-Users] formlib widget

2006-12-01 Thread Jeff Shell

On 11/29/06, Dennis Schulz <[EMAIL PROTECTED]> wrote:

Hi,

in a formlib based form I would like to have more control over the
rendering of the widgets.
is it possible to call widget with a specific name directly instead of
running through all on a repeat loop?
for example

  

I saw that there is a get method but I can't access it form the page
template.


It certainly is possible. As another reply pointed out, you're mixing
Path and Python expressions above, which won't work.

A common technique I use is to define a local reference to widgets
(often to something short like 'w'), and then access the widgets
within that setup::

   


 
 

   


Anyways, you can use the 'python' or 'nocall' expressions if you want
to get the widget unrendered:

   
 or
   
 or
   


--
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

2006-11-01 Thread Jeff Shell

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

2006-10-31 Thread Jeff Shell

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 .  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)

2006-10-16 Thread Jeff Shell

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)?

2006-10-12 Thread Jeff Shell

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...."

2006-09-29 Thread Jeff Shell

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...."

2006-09-28 Thread Jeff Shell

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 `` 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


[Zope3-Users] "So you've just downloaded Zope 3.3...."

2006-09-28 Thread Jeff Shell

... now what?

I just tried moving some work over to Zope 3.3. Already things are
blowing up. That's fine - things can change a little bit. But is there
any information on what really changed besides CHANGES.txt and the
little list of bullet items on the release information pages? The only
major document I could find is the "Reducing the amount of ZCML
directives" page, which is in proposal form but not in "this is what
is implemented" form. I'm sure that document will help, but it's
broader reaching (it seems) than the actual changes.

Also - does anyone have an easy trick (a sed / awk / perl / python /
etc script) for easily switching an Instance Home between two core
Zope versions? I have a lot of code that I need to support back to at
least 3.2 and while I'm working with trying to migrate to Zope 3.3,
I'd like to be able to switch back and forth quickly.

Thanks,
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

2006-08-14 Thread Jeff Shell

On 8/14/06, Stephan Richter <[EMAIL PROTECTED]> wrote:

On Monday 14 August 2006 01:00, Jeff Shell wrote:
> If things slow down... uhm, ever... for us, I'd like to see if I can
> get us to open up some of the more generic toolkits we've built up in
> recent months, as they've been very empowering.

You should really do this as you code. Not only do you help out the
community, but also yourself, since people will be using the code and
make enhancements and help maintaining the code. Further, we are all
not duplicating the same stuff.


A lot of these are difficult to extract from customer libraries or
dependencies on toolkits (also built up internally) that we may not
really have license to re-distribute. I know it's probably possible to
extricate all of these, but it requires time which is a precious
precious precious resource around here lately.

I really admire people who share their work because there is a lot of
work involved, at least in the initial sharing.


Lovely Systems, Roger and I have all been in agreement to publish generic
components as we go; if you are subscribed to all check-in messages, you
probably saw already a bunch of packages landing in the z3c and lovely
namespace. We have tasks setup for this week to open/publish even more
packages and extensions.


Heh. This past weekend was the first time I actually even got to look
in the direction of the zope3-dev and zope3-users lists in two or
three months! And those are the only Zope lists I'm subscribed to.
Somwhere between working, walking the dog, and sleeping, my life has
disappeared. :\

--
Jeff Shell
___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users


Re: Re: [Zope3-Users] zalchemy integration

2006-08-14 Thread Jeff Shell

On 8/14/06, Carlo Cardelli <[EMAIL PROTECTED]> wrote:

 > I think that my company's recent experiences with Zope and SQLAlchemy
> show that the fundamentals of Zope can be terrific toolkit for rich
> object oriented RDBMS / Business Object backed applications that have
> nothing to do with content management.

Your work seems surprisingly similar to what I want to achieve in the
long run. Besides, you answered a general question I was thinking to
post about suitability of Zope for business/no-cm applications.
At the moment, I am still in a "semi-evaluation" phase, so your
experience somewhat comforts me :)

 > However, we're also massively behind schedule. This
 > project we've been working on has involved a lot more engineering than
 > we foresaw.

This somewhat discomforts me :(


The engineering involved has had more to do with a serious
re-evaluation of business situations than anything else. It's the
'Zope 3' of one of our own long-running applications that had come to
the point where in order to grow to the levels we see it growing to,
it needed to be re-implemented from the ground up. Among other things
we had to implement a deep and fairly rigorous accounting system that
wasn't foreseen. Some things just took a lot more time as we could no
longer take certain things for granted, such as datetimes. I had to
spend a couple of days coming up with some policies, a toolkit, and
some Descriptors, all to ensure that timezone conversion and
application (which didn't matter in our old versions as all times were
local) happened invisibly. This is especially applicable as MySQL
doesn't seem to store timezone information by default. So when we
realized this, and realized its implications as we're set to expand to
more markets, I had to put in the time to ensure datetimes were
accurate and applicable to some different contexts. We just didn't
even think of things like that... Which I think is a burden of the
'Version 3 Rewrite' syndrome: this system has been done twice in the
past, why is it taking so long now? Oh, because Now it's turned into a
real business and there are certain things we really shouldn't 'punt'
on.

And yes, some of that engineering time has been spent at the
framework/toolkit level to ensure that the SQLAlchemy integration is
as smooth as can be expected and that web views are easier to write as
Python classes than Templates and Scripts and that Service level code
(the real business logic) is readable and maintainable by being as
close to english as possible. That last pseudo-requirement came from
maintenance of some older applications where the data abstraction
framework was a bit more crude and the business logic was very hard to
look at. In some cases, there were up to 70 lines of preparation code
that was just loading up different pieces of data and utilities and
other tools just to get a shopping cart ready to check out. So I've
made the point to engineer heavily up front (but based on real
requirements) so that future maintenance is less frightening.

But really, the 'lot more engineering than we foresaw' phrase is a
result of us being our own customers, us foolishly using past
projections and implementations as estimations, and us not really
scoping out ahead of times what it would mean to track money through
the system with 100% reliability, or deal with complex product
offering scenarios that couldn't even be done before.

--
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

2006-08-14 Thread Jeff Shell

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] Re: zalchemy integration

2006-08-13 Thread Jeff Shell
 are all
updated at the same time::

   def updateProviders(self):
   for provider in self.contentProviders():
   provider.update()

   def renderProvider(self, name):
   provider = self.get(name)
   if provider is None:
   return u""
   return provider.render()

`updateProviders` is typically called in the `update` phase of the
view/page, and `renderProvider` is typically called in the page
template or other code (like our nevow.Stan / Seaside inspired
system). This behavior is just a little bit more predictable than
`provider:`, is usable outside of TAL/TALES, and jumps straight to
`render` since it's typically being called in the rendering phase of
the surrounding view anyways.

(although, we still use `provider:` quite a bit for most of the core
viewlet managers that are used in the main template that have become
practically invisible to us, such as the ones that load up all of the
head resources).

Anyways, I care less about default skins than I do about default
tools. `formlib` made Zope 3 a much stronger toolkit for us, although
we still struggle with advanced widgets and scenarios. `zc.table`
looks cool, but looks unfinished and we haven't had time to really
investigate it further. I'm hoping that more toolkits and like those,
however, show up so that it's fairly easy for a developer to come up
with some Django-style admins of their own, that look and feel and
behave like they and their company / client want. I think that's a
better tool to offer than a whiz-bang skin that is difficult to
customize when a client or boss goes "can we get rid of those tabs at
the top? how about sorting the menu on the side? can we add some links
to the footer for support contact? why does that say 'add ZPT page?'",
etc.

If things slow down... uhm, ever... for us, I'd like to see if I can
get us to open up some of the more generic toolkits we've built up in
recent months, as they've been very empowering.

--
Jeff Shell
___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users


Re: Re: [Zope3-Users] zalchemy integration

2006-08-12 Thread Jeff Shell

On 8/12/06, David Pratt <[EMAIL PROTECTED]> wrote:

Hi Jeff. Your approach is very interesting. There is lots room in Zope
for differences in the way applications are tackled to deliver on
requirements. My feeling is that explicit object metadata and some of
the content-management-esque concepts in Zope fit prominently into the
future of the web.


I think it may fit with _a_ future, but I don't know if there's _the_
future. Applications with very dynamic web UI's are as much of a piece
of that 'future web' as structured semantic content. And I think that
those kinds of applications can have slightly or wildly different
requirements than CMS style systems. I've played a little bit with
'Seaside', and it's absolutely outstanding how it works and how very
little code one has to write to maintain very stateful web apps.


Zope's interfaces and adapters facilitate benefits that can be derived
from hybridization with any form of storage. As much as the ZMI may
hinder, I believe it plays a role in visualizing incremental development
and utilizing what is already there. Unfortunately, time and budgets are
also business considerations and this same infrastructure allows for
some fairly quick development.


We've been building up our own basic structure that just has less
distractions, so we can get started up pretty easily. This web page /
'admin screen' structure is usually copied and pasted into each
application. The downside is that it's more work to share the
benefits. But the upside is that it's really easy to start tailoring
to the requirements and scenarios of a particular application.

With the ZMI, I end up asking "is this the UI I want to deliver to my
customer?" And the answer is rarely "yes!" I feel like I have to arm
wrestle a lot more to turn off and hide features. I still don't really
understand how the 'Add' menu works.

This isn't a criticism of the ZMI skin. It just hasn't been a fit for
any of our customers or applications, which makes it very hard to
support. Fortunately, it's fairly easy to do away with. But it also
feels very hard to migrate away from if that's where ones initial work
is.

This is why I'm really looking forward to `zc.buildout`, the
egg-ifying of Zope, etc. I look forward to the day when it's much
easier to build and re-destribute -- even if it's only internally -- a
custom configuration that leaves unwanted bits behind. I regret that I
haven't had the time to test and experiment with some of these new
developments.


It sounds that the ZMI and browser views hasn't been an impediment but a
distraction to what you describe (since you were able to find a path
with Zope). This is a demonstration that successful outcomes less
tightly bound to more traditional zope development can be achieved also.
:-)  Many thanks.


Having developed on and for Zope for nearly ten years now, I can say
that there is no such thing as "traditional zope development" :).
There are a lot of ways to get things done.

I think it's a testament to the architectures of both Zope 3 and
SQLAlchemy that we've been able to do this latest project in this
style - and with the cleanest application/business code we've ever
had. But it took a lot of work and time and experience from prior
engagements to filter out the parts of Zope 3 that we wanted, the
parts that were crucial, and all of the fluff we could leave out. Once
we got to that point (and started building up some new libraries and
frameworks of our own), our experience with Zope 3 took a turn back
towards the positive.

--
Jeff Shell
___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users


Re: Re: [Zope3-Users] zalchemy integration

2006-08-11 Thread Jeff Shell
s, and for setting
up extended properties. No ZCML required, allowing non-Zope programs
to be able to at least use our Model classes if they have the
libraries imported and establish the database connection.

At the root, we have 'ModelControllers' which are bound to our Site
objects (the few things stored in the ZODB) via Zope's adapters. These
provide the base traversal points. They implement a read container
interface, but no writes. As such, our add forms are responsible for
the full creation. Sometimes it's as simple as this, using `formlib`
::

   class TagAddForm(layout.Form):
   label = "Add New Tag"

   form_fields = form.Fields(ITagSchema)

   @form.action("Add Tag")
   def handleAdd(self, action, data):
   tag = Tag.create(**data)
   ruts.event.created(tag)
   self.flash("Tag '%s' Created" % data['title'])
   return self.redirect(self.backObject())

   def backObject(self):
   return self.context

The other benefit, some of which is seen here, is building up a bit of
our own web framework, providing features that are useful to us while
avoiding a lot of the Zope 3 elements (many in `zope.app`, at least in
Zope 3.2) that we don't need. Our most used `zope.app` imports are
ViewPageTemplateFile and zope.app.form widgets.

The main thing is just trying not to take on too many of the
expectations that Zope may have about implementation. This is actually
pretty easy since Zope 3 is so interface based. The downside is that
some of the built-in automatic tools, such as those in/for the ZMI,
may not work as expected. Personally I see the ZMI as a limited road,
useful for managing local utilities (caches, session data containers,
etc), but not a good application environment. We don't use
INameChooser, ISized, etc, etc, because our application has no need
for them. A few months ago I was crying for a Zope package that was
devoid of many of these items. They're useful items for certain kinds
of applications, but they can be a horrible distraction for others. I
think that my company's recent experiences with Zope and SQLAlchemy
show that the fundamentals of Zope can be terrific toolkit for rich
object oriented RDBMS / Business Object backed applications that have
nothing to do with content management.

So yes, it is possible to have good SQLAlchemy integration. But
'integration' may mean different things to different people. Some may
want invisible or near invisible integration with conventional Zope
content-management-esque concepts, integration with the ZMI, the
dublin core, etc. That's overkill for my needs, which is why I've
stayed away from those implementations. Having Location, Security,
Adapter binding (which yields views and URL traversal) is just about
what we need. The rest we provide through our own business logic as
Views, Utilities, and plain old Python classes and functions. And only
one new ZCML directive (yay!).

--
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!)

2006-04-26 Thread Jeff Shell
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
>
>   
> 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] Security Roles and custom authenticators and scarcely-persistent apps (HELP!)

2006-04-26 Thread Jeff Shell
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. It's very
annotations oriented (the default implementation storing data in some
internal table-like structure). I, obviously, don't have annotations
going on right now. The hard thing is that I can't even figure out at
first glance what the different security manager adapters
(PrincipalRole, RolePermission, etc) are meant to adapt - a principal?
an object? a site? I'm not sure how much of the interface I have to
provide, what I should have it adapt (my Site object, I'm guessing?),
and so on.

All I want to say is "every user returned from this authenticator has
the view access for this site".

I'm not sure which of these I have to fill in. I'm not wanting to
assign every principal coming out of the RDBMS a role mapped in the
ZODB - so do I have to straddle both ZODB and RDBMS worlds here?
"Mappings between principals and roles" - where? A local object?
Globally? Do the answers have to include all answers from higher up
the tree if there's anything? Global settings? Am I looking at the
wrong thing?

class IPrincipalRoleMap(Interface):
"""Mappings between principals and roles."""

def getPrincipalsForRole(role_id):
"""Get the principals that have been granted a role.

Return the list of (principal id, setting) who have been assigned or
removed from a role.

If no principals have been assigned this role,
then the empty list is returned.
"""

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.
"""

def getSetting(role_id, principal_id):
"""Return the setting for this principal, role combination
"""

def getPrincipalsAndRoles():
"""Get all settings.

Return all the principal/role combinations along with the
setting for each combination as a sequence of tuples with the
role id, principal id, and setting, in that order.
"""


--
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...

2006-04-06 Thread Jeff Shell
ybe wants to be a Transaction Manager for Python. If it's the
latter, it could stand to have more documentation. Trying to figure
out where to plug in (if possible) in this situation is tricky.

And I imagine I'm probably overthinking everything at this point
anyways. Maybe it'd be better to just ask 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

2006-03-29 Thread Jeff Shell
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(u"Save 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 = u"Itinerary Details Updated"
self.onSuccess()
else:
self.status = u"No 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

2006-03-20 Thread Jeff Shell
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
>
>
> http://namespaces.zope.org/zope";
>   xmlns:browser="http://namespaces.zope.org/browser";>
>
> 
>permission="zope.View"
>   interface=".IBook"
>   />
>permission="zope.ManageContent"
>   set_schema=".IBook"
>   />
> 
>
> 
>permission="zope.ManageContent"
>   interface=".ILoan"
>   />
>permission="zope.ManageContent"
>   set_schema=".ILoan"
>   />
> 
>
> 
>permission="zope.ManageContent"
>   interface=".ILibrary"
>   />
>permission="zope.ManageContent"
>   set_schema=".ILibrary"
>   />
> 
>
>name="addlibrary"
>   schema=".ILibrary"
>   content_factory=".Library"
>   permission="zope.ManageContent"
>   />
>
>class=".Library"
>   permission="zope.ManageContent"
>   view="addlibrary"
>   title="Library"
>   />
>
>for=".ILibrary"
>   index="zope.View"
>   contents="zope.View"
>   add="zope.ManageContent"
>   />
>
>name="addbook"
>   schema=".IBook"
>   content_factory=".Book"
>   permission="zope.ManageContent"
>   />
>
>class=".Book"
>   permission="zope.ManageContent"
>   view="addbook"
>   title="Book"
>   />
>
>schema=".IBook"
>   permission="zope.ManageContent"
>   menu="zmi_views"
>   title="Edit"
>   name="edit"
>   />
>
>name="addloan"
>   schema=".ILoan"
>   content_factory=".Loan"
>   permission="zope.ManageContent"
>   />
>
>class=".Loan"
>   permission="zope.ManageContent"
>   view="addloan"
>   title="Loan"
>   />
>
>schema=".ILoan"
>   permission="zope.ManageContent"
>   menu="zmi_views"
>   title="Edit"
>   name="edit"
>   />
>
> 
>
>
> ___
> 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] Creating objects in software space when making site

2006-03-07 Thread Jeff Shell
On 3/6/06, Florian Lindner <[EMAIL PROTECTED]> wrote:
> Hello,
> my content object depends on a number of utilities to be present. It is
> usually also used as a site. During development it happens often that I
> delete and recreate it.
> Can I install a hook or something so I can make that these utilies are being
> created when my objects becomes a site? How do I create utitlies in software
> space?

Check for when your root object gets added. I'm not sure if an event
is fired off when something 'becomes a site'. My pattern is to have an
Interface and Content Class for the site, and have the following in
'site.py':

from zope.app import zapi
from zope.interface import implements
from zope.app.component.interfaces import ISite
from zope.app.component.interfaces.registration import (
ActiveStatus, InactiveStatus, IRegistered)
from zope.app.component.site import (LocalSiteManager, UtilityRegistration,
setSite)
from zope.app.container.interfaces import IObjectAddedEvent
from zope.app.intid import IntIds
from zope.app.intid.interfaces import IIntIds


def setupSiteManagerSubscriber(event):
"""
event is supposed to be an IObjectAddedEvent

An event subscriber which calls setupSiteManager when a Site folder is
added. This ensures that there's enough placeful context in place for the
site configuration and utility registration to happen whenever a Site
is added and an IObjectAddedEvent is fired off.
"""
assert IObjectAddedEvent.providedBy(event)

if IMyApplicationSite.providedBy(event.object):
setupSiteManager(event.object)

def setupSiteManager(context):
"""
Configures the application manager's local utilities.
"""
if not ISite.providedBy(context):
context.setSiteManager(LocalSiteManager(context))
# Required for getUtility to work within this request
setSite(context)

# Get the default registration
default = context.getSiteManager()['default']
reg_manager = default.registrationManager

if 'intid' not in default:
# There's a shorter way to do this, but I can never remember what it is
intid = IntIds()
default['intid'] = intid
intids_reg = UtilityRegistration('', IIntIds, intid)
reg_manager.addRegistration(intids_reg)
intids_reg.status = ActiveStatus

# Set up the 'auth' utility
if 'auth' not in default:
# This is a custom function that wraps up all of the work involved
# setting up the pluggable auth utility and its sources.
from myapp.security.browser import establish
establish.createAuthenticationUtility(
default, realm='Killer App', registerAs=''
)

# etc...

And then in configure.zcml:
  


--
Jeff Shell
___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users


Re: [Zope3-Users] Visionaire! (All your problems, solved)

2006-03-02 Thread Jeff Shell
On 3/2/06, Max M <[EMAIL PROTECTED]> wrote:
> Jeff Shell wrote:
>
> >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.
>
> I think its an absolutely terrible idea!
>
> The most succesfull Zope 2 "product" out there is most likely Plone. And
> it has everything and the kitchen sink in it.

Yes it does. And I hate it. At Bottlerocket, we're a very small
company. We look at Plone and go "alright, how do we make it do less?
how do we turn this thing off, and this thing off, and this thing off,
and this thing off? why is it so slow? and it still doesn't do the
page we need to do. Let's just write our own CMS".

Real conversation, real decision. The second one made us feel more in
control. Plone is great, but it's incredibly overwhelming.

Contrast that with Zope 3, where already we've been able to take
advantage of some small components out of other projects ->
schoolbell.relationship, zc.catalog, hurry.query, hurry.file.

In Zope 2, some of those things would have ZMI interfaces. Some would
be standalone applications. Some would only be really configurable and
usable through the web. Some wouldn't.

Let Plone be Plone. But let me easily write and use things that are
not Plone. I don't need all those features. I don't need all those
features. I don't need all those features. I don't need all those
features. And the more I have to wrestle with turning them off (tell
the 353 some odd lines in my average browser zcml file that it's all
just a matter of configuration), and having to painfully extract the
core usable concepts out of other libraries, the less appeal it all
has. And again, I have to say that I'm a little grumpy as I ended up
working late chasing down how vocabularies and renderer factories get
initialized and set up so I could "do the right thing" and write a
unit test to prove, figure out, and solve a bug in my own code. That
was a long and twisty maze, and I basically lost a day of work to it.
Tell me a larger and more feature rich system is going to help me.

There's nothing wrong with having a lot of features. But there should
be simpler options with lower barriers to entry as well.

> I fear that loosely coupled libraries does not make an app server. I can
> just imagine the upgrade hell when one package requires two different
> packages, and another package requires the same two different packages,
> but in different versions.
>
> Canonical releases of compatible package collections is a *must*.
> Splitting it all up in small chunks that are out of sync would be a
> disaster.
>
> Releases that contains a *huge* compatible collection of packages is the
> most effective way to move forward in an unified way.

That's why I want three simple packages. I'd expect that most of them
would be released at the same time, with same or similar version
numbers to show that 'Zope 3 3.3 AS builds on Zope 3 CA 3.3'

A package can then say "requires Zope 3 CA", "Zope 3 AS", or "Zope
Suite". It won't be "requires zope.interface 3.25; zope.tal 1.48;
zope.tales 2.33;" I don't want that either.

> Plone products works together because Plone is so well defined.
> Sometimes this feels like a straightjacket. On the othe hand, in plain
> Zope 2 it is practically impossible to reuse other peoples products on
> your own site because the playing field was too loosely defined.

Plone is a product and a finished application. Zope 2 could be a
standalone finished application out of the box, or a base toolkit to
start building web sites, or a framework for building web
applications, or all of the above. Zope 2 serves many masters. I've
written hoardes of different applications in it over the years,
serving very different markets and customers and architectures.

If you use Plone, you're running Plone.

Plus, I've seen arguments against Plone lately as having lost focus
from content management and into being its own little development
environment. It always happens when you try to make a generic tool for
everybody that's also feature rich and complete. "Great! Awesome
product. I wouldn't change a thing. Except.. We have a double editor
process and my boss has a weird thing against tabs and we really want
it to look like our corporate branding..."

> But just like you don't have to learn every Python library to use
> Python, you should not have to know every package in the app server.
> That is not a question of making seperate releases though, it's the age
> old programmi

[Zope3-Users] Visionaire! (All your problems, solved)

2006-03-01 Thread Jeff Shell
 of both Zope 2 and Zope 3 application
  servers and offerings.

We don't need a hundred different "editions" like Microsoft. Nor do we
need a hundred different acronyms like Java development seems to have.
I think we could boil things down to these three offerings, 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

2006-02-23 Thread Jeff Shell
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

2006-02-21 Thread Jeff Shell
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] browser:form

2006-02-21 Thread Jeff Shell
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
 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 . (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
 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 s

Re: [Zope3-Users] What attributes are made persistent

2006-02-15 Thread Jeff Shell
One could, but it's really not worth it. It's just the laws of Python
and mutability and immutability :). (It took me years to understand
those terms. I kept associating them with 'mutable' in the "can be
made quiet" sense... Eventually my music brain stepped back and I went
"oh, MUTATE! Ahhh!". Seriously, it took me about four years to
understand that :).

Anyways, it comes down to this. They're just different statements:

>>> compiler.parse("a.b = [1,2,3]")
Module(None, Stmt([Assign([AssAttr(Name('a'), 'b', 'OP_ASSIGN')],
List([Const(1), Const(2), Const(3)]))]))
>>> compiler.parse("a.b.extend([1,2,3])")
Module(None, Stmt([Discard(CallFunc(Getattr(Getattr(Name('a'), 'b'),
'extend'), [List([Const(1), Const(2), Const(3)])], None, None))]))

It's just easier to set the dirty bit yourself or use the persistent
object (or use the trick to re-assign after modifying).

Personally, I seldom store lists, or even use them as attributes on
instances. Even outside of Zope/ZODB, I've found myself accidentally
losing data because I was carelessly using the reference. Tuples for
everybody!

On 2/15/06, Shaun Cutts <[EMAIL PROTECTED]> wrote:
> Well, one could have a base class along the lines of
>
> class PersistSetItemOnAttributes:
>
> def __setattr__( self, attr, val ):
> oldSI = val.__class__.__dict__.get( '__setitem__', None )
> if oldSI is not None:
> def newSI( vself, vattr, vval ):
> vself._p_changed = True # is this the right member?
> oldSI( vattr, vval )# oldSI is bound: no vself?
> val.__class__.__setitem__ = newSI
> super( PersistSetItemOnAttributes, self ).__setattr__( attr, val
> )
>
> Of course, this is really just pseudocode. For one thing, need to trap
> whether 'val' is really a class. For another if you were serious about
> this, you would want to check if the obj wasn't persistent first, and
> you might want to do it recursively. And while your are at it, you might
> want to check on other mutators as well(for instance, check first
> what sequence interface if any 'val' supports...)
>
> ... sounds like too much work, and would be problem prone even so. After
> all, some things you don't want to be persistent!
>
> - Shaun
>
> > -Original Message-
> > From: [EMAIL PROTECTED]
> [mailto:[EMAIL PROTECTED]
> > On Behalf Of Stephan Richter
> > Sent: Wednesday, February 15, 2006 8:43 AM
> > To: zope3-users@zope.org
> > Cc: Florian Lindner
> > Subject: Re: [Zope3-Users] What attributes are made persistent
> >
> > On Wednesday 15 February 2006 08:21, Peter Bengtsson wrote:
> > > class PersistentAnything(PersistentMapping, PersistentList,
> > > PersistentDict):
> >
> > AA! This is so wrong! It merges two incompatible APIs: collections
> and
> > mappings. The non-persistent equivalent to this is:
> >
> >   >>> class DoEverything(set, list, dict):
> >   ...  pass
> >
> > > Am I just trying to make it too simple?
> >
> > I think you try far too hard to not understand why the persistent
> > mechanism
> > works as it does. You make your life harder than it has to be.
> >
> > 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
>


--
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

2006-02-14 Thread Jeff Shell
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] What attributes are made persistent

2006-02-14 Thread Jeff Shell
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] How To Solve in Zope 3

2006-02-03 Thread Jeff Shell
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] Re: Please Guido, pick me, pick me!

2006-02-03 Thread Jeff Shell
tation like "Coming in Zope 3.2: formlib. What does it do?"
That can help drive interest or excitement in a coming release (and
maybe even bring in more beta testers), and also provide nice
documentation about the new feature to both existing and new
developers. Burying things like formlib and viewlets in bulleted list
of new features 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


[Zope3-Users] Trouble understanding events, handlers, subscribers (Trying to use component architecture outside of Zope)

2006-01-23 Thread Jeff Shell
I'm writing a small command line tool that uses parts of Zope 3's
component architecture (zope.component, zope.interface, zope.schema),
and just includes those packages and a couple of supporting ones found
in dependencies (zope.i18nmessageid, exceptions, texting). No
zope.app, publisher, server, etc. And (at present) no C code, so no
zope.hookable either. And no ZCML.

I'd like to use events in my tool, but I'm confused. I'm having a hard
time understanding the terminology in zope.component / zope.interface
regarding Subscribers and Handlers. I don't know if those are wired to
zope.event.notify at all.

I don't know how to translate something like:



into zope.component.provide... provideHandler? provideSubscriber?

I think I'm just not understanding the relationship of 'for' (in the
ZCML) to the provideHandler / provideSubscriber concepts of 'adapts'
and 'provides', and what that means for me looking to subscribe to an
event with a plain old function. Or class. Or instance.

--
Jeff Shell
___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users


Re: [Zope3-Users] Zope 3 Ready for Production? Really?

2006-01-14 Thread Jeff Shell
I know that Stephan Richter has responded to many of these points.
I'll add in some of my views as someone from the borderlands - I'm not
a core developer, but I am someone who has used Zope since before it
was Zope. Since before it was "before it was Zope". I worked on core
Principia and Zope a long time ago, but have not been involved much
with the core of Zope 3 besides following the conversations and
chiming in (sometimes too much, sometimes asking unanswerable
questions) on the mailing lists.

After tinkering with Zope 3 for a while, late last summer I had to
build a Zope 3 application for real, and do it real fast.

On 1/14/06, David Johnson <[EMAIL PROTECTED]> wrote:
>
> The documentation is not well defined, which makes deployment dangerous
> because one may produce an application that does not conform to future
> releases of Zope.

Documentation is better defined than any previous release of Zope.
Most of the documentation, as Stephen mentions, is at the API level
and is used as doctests. I installed Zope 3.2 final on our development
boxes the other day. Over 8000 tests ran succesfully, many of those
coming from documentation. It's not only documentation, but
documentation that works.

Interfaces are generally well defined and in apidoc. There are some
that don't make it into apidoc, and that can be frustrating. I need to
make a better list of the ones I look for that I can't find so I can
submit it as a collector issue. But generally, it is all very well
defined. ZCML is well documented, which was a huge concern I had
during Zope 3's development process.

There are two published books. They are old, covering Zope 3.0, but I
know www.worldcookery.com has updates for its book. Even though the
books are a couple of releases old, many of the core concepts still
apply. I'm trying to get back in the habit of consulting Stephan's
book before asking a question of the mailing list.

On the downside, there isn't much documentation showing how to pull a
lot of this together. But how you pull it together is up to you. A
twenty minute wiki how-to isn't going to provide you with good tips
about how to write an e-commerce solution. An e-commerce how-to isn't
going to help you write a knowledge base. There could be more
documentation in this area, but writing it is hard when you've got
full time jobs doing other things. Keeping it updated is even harder.
This is affecting TurboGears, Django, and more - they have some good
"get started quick!" tutorials. They've had issues keeping them up to
date recently.

The Wiki is terrible. But I hate wikis and if I believed in God I
believe my god would consider Wikis an abomination unto him. It's good
that there's a place for information to go that's reasonably central.
But which of the various "related objects" proposals is current? So I
never go in there. I get frustrated very quickly, and this is with a
lot of work done by others to try to keep it organized.

I like Trac, or even the Plone (I assume) based tools Schoolbell is
using to publish information. "This is the 3.2 milestone. Here are the
proposals and issues that are tied to that milestone" You can do this
with Wikis, but it's all manual and the organization is seldom as nice
and natural. Compare these (and yes, I'm aware that trac has a wiki -
but it seems nice and secondary to some of the core information):

http://trac.turbogears.org/turbogears/roadmap
http://dev.zope.org/Zope3/RoadMap

But while that would be nice, I don't have the time or experience to
contribute to setting something like that up even if it were wanted by
others, and I'm not volunteering anyone else to do it. Just wishful
thinking. It's hard for me to find a decision tree of what went into
Zope 3.2 and why, or to try to lobby support for something to go in
Zope 3.3 and see proof somehow that it does by being able to follow an
issue, a roadmap, a plan, etc.

(The bug tracker product Stephan wrote in Zope 3 was really cool with
grouping. I miss it).

Regarding configuration, Stephan provided nice responses.

> I can only find one semi real-world Zope 3 example (the SIP application),
> and it does not even run under Zope 3.2; while I've been able to wade
> through and fix many errors, I continue to get more as the interfaces and
> standards keep changing. Even the current i18n facility does not seem to
> work properly, editing messages frequently gives errors and does not update
> properly.  Errors in general seem to give unexplainable results.

I struggle with i18n, but I admit to being a stupid American that
wishes he didn't have to deal with it at all. This has nothing to do
with Zope 3's implementation - it's just not a habit that I have.
Getting used to unicode, encodings, messages, etc, was hard. But again
- a admit complete and utter ignorance here.

On the other hand - the question that I saw listed most on the "submit
a question" list for the Snakes and Rubies meeting in Chicago had to
deal with "when are you going to internationalize

Re: [Zope3-Users] Importing Lots of Objects

2006-01-08 Thread Jeff Shell
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=u"Product Name", maxlength=255, required=True)
price = zope.schema.Float(title=u"Product 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] Tagging content

2006-01-08 Thread Jeff Shell
and views that are used to manage the
traversal. Basically every time a name is traversed, a new tagmatcher
is made, with the understanding that its parent is a TagMatcher. The
parents tags plus the new name are passed into the new matcher. At the
end of the path, a default view for ITagMatcher calls 'process' which
causes the query to be run and then it gets and sorts the results for
display.

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] Access attributes of content object from view

2006-01-07 Thread Jeff Shell
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__',  )
>
> 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


[Zope3-Users] Page Notification pattern and cookies - getting cookies set in the same request?

2006-01-06 Thread Jeff Shell
Hello. Something came up today that I'm not sure how to deal with. A
long and wordy explanation follows, but the quick question I have is
this: without using sessions, or anything else tied into transactions
/ persistence but tied to the current visitor, how can I write to a
very small 'messenger' store to send messages like "Item Deleted" or
"3 Items Added to Cart" that, when read back from, removes those
message. I just tried a cookie based implementation, but since the
request and response track cookies differently, I can't selectively
write and retrieve/clear these messages as easily as I'd like. The
important thing about these messages is that (a) the user sees them
only once, and (b) they can survive redirects. I've done this using a
session based utility that I wrote a long time ago, but the session
based one has some problems with a new feature I'm trying (interfering
with "undo last") and I'm not sure that doing so much frequent writing
/ clearing to a ZODB storage is such a good thing.

I don't know if having event listeners pull data out of cookies and
putting them into a threading.local type container is a good way to
go, writing anything new and expiring anything old when the response
is written out - and in-request I just read and write from that little
transient thing. Or can a _v_attribute (don't know where it'd attach)
or request annotation work? I still don't understand the life cycles
of some of these options, nor how to ensure they don't interfere with
other transactions so that "Undo Last" doesn't undo the removing of
the notification message and nothing else.

-- LONG VERSION --

I've been using a session based Page Messenger for a while now. I
wrote about it a couple of years ago [1]. The use case is for
displaying messages to the user in a uniform way - not tacking them
onto a query string, not stuffing them into the current view or
request, but putting them somewhere that can survive the current
request so that redirects can still show the message.

[1] http://euc.cx/toulouse/archives/2003/12/22/page_messages.html

I've loved this pattern, and I've just used Zope's sessioning support
(for better or worse) to deal with it, and it's generally worked out
great. In Zope 2 I put it behind a CMF Tool-like interface and turned
it into a utility for our Zope 3 apps. Ruby on Rails calls it 'flash',
and Subway and TurboGears both sport this flash feature, often just
using cookies.

The pattern is basically this: add a message to the messenger, it
stores it ... somewhere, anywhere. Later, in the same request or
perhaps the next, the messages are retrieved (my implementation's
always allowed for multiple messages). When they are retrieved,
they're removed from the storage so the user sees the message only
once (ie - reloading the page won't bring back the "Deleted Item 'x'"
message).

Today I was working on having 'undo' messages, similar to those im
GMail. I was frustrated trying to put a javascript confirm on a
browserMenuItem ('delete'), when I remembered that Zope has this great
undoable database. So I borrowed code from zope.app.undo.browser to
just do the 'undo last', and returned a message that had a link to the
@@undolast view. So a user can visit an object directly and see a
'Delete' action. When they delete, they go back to a content listing
and now get the message "Deleted 'Foo Title' [foo id]  (Undo)".

But since my page messenger uses sessions - the 'undo last action'
would only undo the removal of the **undo message** from the messenger
container in the session. This is because the page is a redirect, and
at the time of clicking "undo last", the last action is the page view
that retrieved the notification message and removed it from the
notification store.

I've long wanted to try some alternate page messenger implementations
anyways, and went about doing a cookie based one. I've got it working
- including handling multiple messages of different styles (info,
error, warning, etc)... to a point. It works great on a redirect, but
not within the same request. Which is obvious to me now - I'm only
looking at cookies in the Request, not the Response. Likewise, items
aren't cleared from the Request until the end of the response (whereas
sessions would go immediately).

Is there a better pattern I could be using here, where cookies are
kindof the fallback? I guess I'd like to safely:

* Load all of the current messages stored in cookies at the beginning
of request handling and put them in a container that exists only for
the duration of the request.
* Access that container throughout the current request to get messages
for display and set new ones for display on the next page view,
whether it's from a call later in that request (return
self.template...) or after a redirect.
* Write undisplayed messages out to cookies at the end of the request
(again, whether it was a redirect or full page view).

Of course, no visitor should see any other visitors messages. This is
why sessions worked n

Re: [Zope3-Users] Permission required for renaming?

2006-01-05 Thread Jeff Shell
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


Viewlets (was Re: [Zope3-Users] using tal to insert zwiki content)

2006-01-05 Thread Jeff Shell
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] using tal to insert zwiki content

2006-01-04 Thread Jeff Shell
On 1/3/06, Brad Allen <[EMAIL PROTECTED]> wrote:
> At 11:52 PM -0700 1/2/06, Jeff Shell wrote:
> >There are a lot of ways one can go from there. In Zope 3.2, a good
> >solution for pages made of parts where the content of the parts comes
> >from ZWiki pages, you could probably use viewlets.
>
> I haven't seen the term "viewlet" defined thus far. In this case, would
> that be a view that I would create somewhere outside the zwiki
> package? I'd rather
> not make changes to the zwiki source code itself, because that would
> be difficult to merge with future releases.

Viewlets are a new feature in Zope 3.2. They're kindof "views for
views". There's documentation in the 'zope.viewlet' package in the 3.2
beta releases. They're a bit more of an advanced feature than regular
views, and not something that you necessarily need to concern yourself
with right now - especially if you're still new to the Zope 3 system.

One of the promises of Zope 3 is that you should be able to make
additional views and adapters for other objects without having to
touch their code. In the case of zwiki for Zope 3, you can probably
declare a new view using the ViewWikiPage class and have it use the
'render()' method, which is what draws the source code. In your own
package, you can have:

http://namespaces.zope.org/browser";>
  


This just creates a new view that calls the 'render' method of a
ViewWikiPage instance. That method is what renders the wiki page's
source. Then you can use

``tal:content="structure context/wiki/About_Downwinders/@@render_inline"``

Although, after looking at the ZWiki code quickly, the wiki links that
it renders may not be relative to the page they're being viewed from.
But you could also subclass zwiki.browser.wikipage.ViewWikiPage and
make your own view based on that, overriding the methods it defines
for rendering Wiki links.

You can do all of this in your own code. It doesn't impact ZWiki - it
shouldn't know or care about any custom views you define.
___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users


Re: [Zope3-Users] Re: sqlos, sites and local utilities

2006-01-03 Thread Jeff Shell
What about using zope.app.component.hooks.setSite? It sets the site on
a zope.thread.local based object, and I believe most utility lookups
fall back on that setting if context is not supplied. setSite is
called when a site is traversed through, via a BeforeTraverseEvent.
It's cleared at the end of a request. Maybe the tests should be
setting the site, since when accessed "through the web", 'testsite'
will be set as the local site by the event subscriber?


On 1/3/06, Stephan Richter <[EMAIL PROTECTED]> wrote:
> On Wednesday 16 November 2005 10:13, Andreas Elvers wrote:
> > Anyway I have created a functional unit test to demonstrate the problem.
> > In fact
> > the unit test shows that sqlos will always lookup global utilities and
> > never local utilities.
> >
> > Here is the test. It will fail in the last block on
> > "testsite['personcontainer'] = personcontainer".
>
> Andreas,
>
> I think this example is probably most useful to the SQLOS developers. You
> might want to resend it to them. I am not using SQLOS (I do not even have it
> installed), so I cannot help you.
>
> 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] using tal to insert zwiki content

2006-01-02 Thread Jeff Shell
``context/wiki/About_Downwinders`` wouldn't (probably) know how to
render itself as HTML. In fact, you'd probably not want it to render
itself as HTML in its default since that would render the whole page.

To do this properly in Zope 3, you'd want to define a browser view to
render the ZWiki page for this context, and then go to
'context/wiki/About_Downwinders/@@your_view' in the ZPT code.

There are a lot of ways one can go from there. In Zope 3.2, a good
solution for pages made of parts where the content of the parts comes
from ZWiki pages, you could probably use viewlets.

In short - ZPT Pages are special. They're actually content (and view)
objects whose main job is to product HTML. ZWiki pages have the job of
managing and relating structured content. So you can't just include
them directly - you need to bring in a view object whose job is to
take that Wiki page content and turn it into HTML as appropriate for
how you want it to be rendered.

tal attributes are for inserting HTML. ZPT pages render HTML out by
default. Very few other built-in objects do that on their own without
views in Zope 3.

On 1/2/06, Brad Allen <[EMAIL PROTECTED]> wrote:
>
> I had wanted to insert zwiki content into another page, in a way similar to
> the way ZPT pages can be inserted, but it doesn't seem to work. Is that
> a misuse of zwiki, and are tal attributes only for inserting ZPTs and
> nothing else?
>
> Here is what I was trying to do:
>
>  tal:content="structure context/wiki/About_Downwinders">
>
> ...where About_Downwinders was a zwiki object. I had wanted to use
> zwiki for some content pages that would be edited by site content authors,
> because zwiki offers easy wiki-style editing and notifications whenever
> a change is made.
>
> Thanks!
> ___
> 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?

2006-01-01 Thread Jeff Shell
> 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

2005-12-31 Thread Jeff Shell
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] Specialized URL traversal.. Best way?

2005-12-31 Thread Jeff Shell
On 12/31/05, Marius Gedminas <[EMAIL PROTECTED]> wrote:
> On Thu, Dec 29, 2005 at 11:22:28PM -0700, Jeff Shell wrote:
> > 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
>
> My coworker Albertas recently implemented something like this in
> SchoolTool (I've CCed him).  Unfortunately it turned out to have some
> unforeseen consequences, for example, request.URL does not contain the
> path elements you "eat" manually, breaking self-posting forms (those
> that use ) and our login
> mechanism.

Yeah, I know of that problem. Looking back, it looks like there have
been a couple of ways of doing this. In Zope 2, there are a couple of
prominent "cool path tricks" in the core content objects. Python
Scripts allow you to get at the rest of the path. But the resulting
affect is like you describe: the traversal stack is chopped off, and
all URLs are relative to the script. We did a pretty cool ECommerce
store in all Python Scripts and SQL Methods that did this to have URLs
to products and categories, building up queries along the way. We
quickly discovered that relative URLs didn't work in that scenario, so
"./product/${product_id}" wouldn't work. I can see why it does this
though - you didn't actually traverse to an object at that point in
the path, so the request.parents attribute can't really have [, , , , , ] in it, when  just takes the
rest of the path and turns it into various script/object calls and
queries.

Zope 2 SQL Methods, on the other hand, allowed you do to direct
traversal and turn a URL into a query. This may have even existed in
the pre-principia version of Aqueduct. So for a two-category
classified system you can do URLs like:

/categorylist/category1_id/34/category2_id/12/list_ads.dtml

What it does is actually create non-persistent traversable objects
that implement the __bobo_traverse__ method. It accumulates the parts
of the URL and somewhere along the way does the search. Acquisition
binding and all of that still worked since the result was ultimately
an object that was bound to the right parent.

The code (In Zope 2: Shared/DC/ZRDB/DA.py, class Traverse) is rather
old and cryptic, but it does provide an example of the other way of
doing custom maps - traverse each name individually and create new
objects along the way. This way, request.URL is not affected. If you
were trying to make a custom traverser like date based archive
searching and where at 2005/12/ in the url, you could then just have
 to go to the date.

Both situations have their uses. They also have their consequences and
side effects. Playing with the traversalStack seems fine when you
don't need to do anything relative [per say] to the current URL. I
almost always use URL generators, either absolute URL or in the case
of the tags view I made I construct the joined URL in the view, so
this hasn't affected me too much yet.

But I'd certainly like to have the second option. The underlying tools
are there, but knowing which traversal interface / adapter to apply
isn't easy right now... Is __getitem__ enough? No one seems to have a
good answer. IPublishTraverse? ITraversable? It seems like
IPublishTraverse is the best one since it's from zope.publisher and
not zope.app, and is specific to object / URL publishing. But that
comes back to my dilemma:

Is it cool to play with the traversal stack in publishTraverse? Why
isn't 'furtherPath' part of the publishTraverse interface, but part of
zope.app.traversing.interfaces.ITraversable's traverse? Why doesn't
browser traversal seem to use zope.app...ITraversable?

Oh man. Here it is, New Years Eve, I've got errands to run for my dog
that I was going to go do an hour ago, yet here I sit consumed by an
idea that I'd love to try but should put off to some other time.
Basically it would be nice to specify a map... somehow.. for long URLs
that are used to construct queries. A view object could use this map
to match a URL piece by piece by traversing it one by one and making
"proper" objects along the way that are locatable. When it gets to the
end of the match, it could call a provided factory for that particular
Map and pass in the matched URL since the start of the view as a list
or mapping. T

Re: [Zope3-Users] Re: Get classes implementing Interface

2005-12-30 Thread Jeff Shell
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 specifi

Re: [Zope3-Users] Re: Get classes implementing Interface

2005-12-30 Thread Jeff Shell
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


[Zope3-Users] Specialized URL traversal.. Best way?

2005-12-29 Thread Jeff Shell
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...")

2005-12-23 Thread Jeff Shell
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
> > igno

Re: [Zope3-Users] Re: ZCML, practicality, purity (was "Excellent perspective...")

2005-12-22 Thread Jeff Shell
nly way to make it work.

Also, I'd like to point out that Python is not the best language for
housing a lot of complex configuration data. Perl and Ruby tend to be
a lot easier to use here, as the language kindof makes it easier to
write fake little mini-languages since they're a lot more free-form
syntactically. I'm sure there are others here that remember
maintaining nested tuples of tuples of tuples for Zope things like
__ac_permissions__. Those were not always easy to read or maintain.

ZCML has the benefits of using zope.schema to define and format the
fields used in configuration and turn them into meaningful objects.
The ability to use local dotted names: 
. 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?

2005-12-19 Thread Jeff Shell
Yes, it's hurry.file. What's Tramline?

We're using hurry.file for small images, generally, and it's been
working fine. We've recently written a cache manager that writes the
images out to the file system where Apache can serve them. So when
that's in place (and working), efficient image serving from Zope is
not that big of a concern to us...

But back to the issue at hand - knowing how to better serve those out
to the response would be a big help.

On 12/19/05, Martijn Faassen <[EMAIL PROTECTED]> wrote:
> Jeff Shell wrote:
> > 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.
>
> Is HurryFile the same as hurry.file? You know of course hurry.file is
> pretty inefficient if you don't use tramline (which still needs
> integration into hurry, patches welcome :).
>
> Regards,
>
> Martijn
>
___
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?

2005-12-19 Thread Jeff Shell
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

2005-12-06 Thread Jeff Shell
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?

2005-12-02 Thread Jeff Shell
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)

2005-11-18 Thread Jeff Shell
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?

2005-11-16 Thread Jeff Shell
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

2005-09-28 Thread Jeff Shell
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?

2005-07-28 Thread Jeff Shell
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] Sending object modified event on FTP upload - best practice?

2005-07-27 Thread Jeff Shell
I'm about to get working on a project in Zope 3 that will be our first
major project for a paying customer (in fact, our marquee customer and
one of our marquee sites). This project will be replacing an aging
Zope 2 site, which relied heavily on FTP for its content management.
When content is uploaded by FTP to an existing object, the catalog is
reindexed. Nicely, in Zope 3 I can depend on object modification
events to handle cataloging.

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? Or is this something that should be
in the FTPView's implementation?

This is in Zope 3.1b1.

Thanks
--
Jeff Shell
___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users


Re: [Zope3-Users] Searching Content Objects

2005-07-24 Thread Jeff Shell
Create a browser view object with a method that looks up the catalog
utility and performs the search and returns results back to the
template. Basically take what you've learned about writing views that
combine classes and templates, and use code like the following:

def search(self, query):
"""simple example, query is just a string"""
catalog = zapi.getUtility(ICatalog, 'catalog', self.context)
return catalog.searchResults(some_index=query)

Of course, you could take in more search parameters from the form and
pass those in as well.

On 7/24/05, Jim Vine <[EMAIL PROTECTED]> wrote:
> Hi,
> 
> Thanks a lot for the pointer. I have upgraded to Zope
> 3.1b (with only minor difficulty).
> 
> I've read the readme for Catalog, and I think I more
> or less follow how it works. What I didn't pick up
> from the readme, however, was how I would actually use
> it in an application. How does one go about generating
> a search form that accepts a few criteria, and has a
> "submit" button, that would then go off and fetches
> the results?
> 
> Thanks,
> Jim
> 
> 
> --- Stephan Richter <[EMAIL PROTECTED]>
> wrote:
> 
> > On Saturday 23 July 2005 16:17, Jim Vine wrote:
> > > It seems from the documentation that ZCatalog is
> > the
> > > prefered way of doing a search in Zope 2, but that
> > > this isn't implemented in Zope 3.
> >
> > Use Zope 3.1 beta 1; it has indices and a catalog
> > implementation.
> >
> > Regards,
> > Stephan
> > --
> > Stephan Richter
> > CBU Physics & Chemistry (B.S.) / Tufts Physics
> > (Ph.D. student)
> > Web2k - Web Software Design, Development and
> > Training
> >
> 
> 
> 
> 
> 
> 
> ___
> 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


Re: [Zope3-Users] general guidance how to develop a (relational)database driven app

2005-06-28 Thread Jeff Shell
You might want to look at 'sqlos', a SQLObject support package for Zope 3. 
http://codespeak.net/z3/sqlos/

SQLObject is an object-relational mapper for Python.

Between the two of them, the SQL side of your ITrackContainer and
ITrack is taken care of transparently. So with just a little bit of
work, you can then write your application pretty much like any other
ZODB based Zope 3 application.


On 6/28/05, Christoph Frick <[EMAIL PROTECTED]> wrote:
> hiho,
> 
> i am currently in the process of rewriting an application, which is used
> to upload laptimes of racing simulations from users and allow comparing
> them. this application is done TTW using zope2.
> 
> now i want to turn this into a product and also use zope3 to see how
> things handle there for projects at work or for other freetime projects.
> 
> my genercal concern about all this is, how would a write such an
> application. using a relational database is an absolute must and its
> also no big deal. using SQLScript objects on the fly in the code by
> acquiring the name of the dba from the parent object is no big deal.
> 
> the bigger problem here is, that i need some guidance, how to design the
> application. all the things i read about zope3 (the two pdfs from
> jfulton and srichter and the examples from the worldcookery) are good
> for handling all the stuff needed to write apps, that store there stuff
> in the zodb and evolve around some certain dataobject.
> 
> for my app i have e.g. a track list - this is some sort of singleton for
> the app: it holds a list of all tracks - for which a driver, beside
> othere "keys", can register laptimes. what i did now is to define an
> ITrack and an ITrackContainer - the container handles the SELECT,
> INSERT, DELETE - the ITrack the UPDATE. i guess with some help of the
> general View class i can also add later a simple form for editing the
> tracks. using a contents-view for the container then would allow me to
> browse the tracks even without writing a new view for this.
> 
> but how do i add my "tracks" instance of the ITrackContainer to my
> "root"? i tried adding it as property - it wont get found. maybe this is
> a wrong approach how to develop and design things at all with zope3?
> 
> any url with examples, applications or code, how to develop "big"
> applications, that utilize external databases are highly appreciated.
> 
> --
> cu
> 
> 
> ___
> Zope3-users mailing list
> Zope3-users@zope.org
> http://mail.zope.org/mailman/listinfo/zope3-users
> 
> 
> 
>
___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users


[Zope3-Users] My Javascript resources aren't loading in Firefox

2005-06-27 Thread Jeff Shell
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:

http://namespaces.zope.org/browser";>
  
  

  
  
  
  
  
  

  


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:

  
  
  Snippets/3
  
@import url(snippets.css);
  
  

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

  http://localhost:8080/++skin++snippets/@@/prototype.js"</a>;>

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/mailman/listinfo/zope3-users


Re: [Zope3-Users] Compiling Zope 3 (Mac OS X 10.4.1, Xcode v2.1). Failure.

2005-06-26 Thread Jeff Shell
(btw - the skin issues... finally resolved! 'skin_macros' in Zope 3.0
seems to want to be 'view_macros' in 3.1b1)

On 6/26/05, Jeff Shell <[EMAIL PROTECTED]> wrote:
> I got the same error, although I haven't updated to XCode 2.1 yet.
> 
> Zope 3.1b1 compiled fine, but I ran into some issues with that
> regarding setting up a simple skin (I'll report that separately.. I
> was trying to get Zope 3.0 going again to try my code there to see if
> it was a difference between 3.0 and 3.1b1).
> Miette:20:27:05 ZopeX3-3.0.0> uname -v
> Darwin Kernel Version 8.1.0: Tue May 10 18:16:08 PDT 2005;
> root:xnu-792.1.5.obj~4/RELEASE_PPC
> 
> 
> Miette:20:24:40 ZopeX3-3.0.0> gcc -v
> Reading specs from /usr/lib/gcc/powerpc-apple-darwin8/4.0.0/specs
> Configured with: /private/var/tmp/gcc/gcc-4061.obj~8/src/configure
> --disable-checking --prefix=/usr --mandir=/share/man
> --enable-languages=c,objc,c++,obj-c++
> --program-transform-name=/^[cg][^+.-]*$/s/$/-4.0/
> --with-gxx-include-dir=/include/gcc/darwin/4.0/c++
> --build=powerpc-apple-darwin8 --host=powerpc-apple-darwin8
> --target=powerpc-apple-darwin8
> Thread model: posix
> gcc version 4.0.0 20041026 (Apple Computer, Inc. build 4061)
> 
> 
> On 6/23/05, Stephan Richter <[EMAIL PROTECTED]> wrote:
> > On Thursday 16 June 2005 05:49, Simon Forster wrote:
> > > Can anyone tell me what I'm doing wrong? I was hoping to do some
> > > playing with Zope 3 next week while I'm away from the office.
> >
> > What is your GCC version? We usually do not get failures from compilation. 
> > If
> > you have already solved the problem, please post you solution here 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] Compiling Zope 3 (Mac OS X 10.4.1, Xcode v2.1). Failure.

2005-06-26 Thread Jeff Shell
I got the same error, although I haven't updated to XCode 2.1 yet. 

Zope 3.1b1 compiled fine, but I ran into some issues with that
regarding setting up a simple skin (I'll report that separately.. I
was trying to get Zope 3.0 going again to try my code there to see if
it was a difference between 3.0 and 3.1b1).
Miette:20:27:05 ZopeX3-3.0.0> uname -v
Darwin Kernel Version 8.1.0: Tue May 10 18:16:08 PDT 2005;
root:xnu-792.1.5.obj~4/RELEASE_PPC


Miette:20:24:40 ZopeX3-3.0.0> gcc -v
Reading specs from /usr/lib/gcc/powerpc-apple-darwin8/4.0.0/specs
Configured with: /private/var/tmp/gcc/gcc-4061.obj~8/src/configure
--disable-checking --prefix=/usr --mandir=/share/man
--enable-languages=c,objc,c++,obj-c++
--program-transform-name=/^[cg][^+.-]*$/s/$/-4.0/
--with-gxx-include-dir=/include/gcc/darwin/4.0/c++
--build=powerpc-apple-darwin8 --host=powerpc-apple-darwin8
--target=powerpc-apple-darwin8
Thread model: posix
gcc version 4.0.0 20041026 (Apple Computer, Inc. build 4061)


On 6/23/05, Stephan Richter <[EMAIL PROTECTED]> wrote:
> On Thursday 16 June 2005 05:49, Simon Forster wrote:
> > Can anyone tell me what I'm doing wrong? I was hoping to do some 
> > playing with Zope 3 next week while I'm away from the office.
> 
> What is your GCC version? We usually do not get failures from compilation. If
> you have already solved the problem, please post you solution here 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