Re: Import/export for Listen
from
ra
on Aug 01, 2008 07:36 PM
Nicholas Bergson-Shilcock wrote:
> Hi all,
>
> As I mentioned in a previous message, Rob Marianski and I have been
> working on adding import/export support to listen. The branch we've been
> working off of is here:
>
> http://dev.plone.org/collective/browser/listen/branches/export
>
> Present functionality includes exporting mailing list subscribers as a
> CSV, exporting the mailing list archive as an mbox file, and importing
> mbox files into the mailing list archive. There is also a full import
> history, which allows the user to undo any previous mbox import.
>
> While working on this today, I came across an odd bug: Replies sent via
> the web interface couldn't be exported. I tracked this down to an issue
> with the mailing list object returned by the getMailingList() method
> used in mail_message_views.py. The issue was that this mailing list
> reported its path incorrectly as, e.g.,
> /plone/listname/listname/listname instead of as /plone/listname. I
> replaced this version of getMailingList() with the version of
> getMailingList() from mail_archive_views.py and all is now working.
>
> I'm new to listen (and zope, for that matter), so I can't say I fully
> understand what's going on here, so I was hoping someone on the list
> might have an idea if this "fix" is a good idea or if it may have broken
> something else (ping me if you want any more details as to what I did
> exactly).
what you did was correct; the other implementation was changed for exactly
this reason:
http://dev.plone.org/collective/changeset/63929
the problem is that Zope2's implicit acquisition injects itself into every
attribute lookup, so that when you so "foo.bar" on objects supporting implicit
acquisition (i.e. most persistent Zope objects) you get a copy of bar that has
foo as it's aq_parent.
this causes no end of headaches. a common Z3 idiom is "self.context", where
"self" is a view. you usually get to the view in the first place by
traversing through the context object, so self.aq_parent == self.context. but
b/c of the attribute lookup stuff, self.context.aq_parent == self. lovely.
the code that wasn't working was this:
ml = getSiteManager(self.context).__parent__
self._mailing_list = [ml]
which uses self.context (thus introducing the weirdness noted above) and then
_further_ complicates matters by introducing a local site manager lookup and
Z3's __parent__-based idea of acquisition into the picture. the result was
the weird acquisition path stuff that you were seeing,
/plone/listname/listname/listname instead of /plone/listname.
the idea of the original code was a clever shortcut to retrieving the mailing
list from a message object's acquisition tree, since the presumption is that
the mailing list itself will be the nearest object w/ a site manager, so you
get the site manager and it's __parent__ will be the mailing list. the newer
code does a less exciting (but safer) climb of the acquisition tree to look
for the mailing list object, taking care to unwrap any possibly complicating
acquisition wrappers to make sure we don't see the same types of weird issues.
-r