Skip to content

/ Zope / gocept svn checkins / Archive / 2008 / 2008-10 / SVN: r6779 - gocept.objectquery/trunk/src/gocept/objectquery

[ << ] [ >> ]

[ SVN: r6778 - in gocept.infrastructure/feature_netw... ] [ SVN: r6783 - gocept.reference/tags/0.5.1 / ... ]

SVN: r6779 - gocept.objectquery/trunk/src/gocept/objectquery
Sebastian Wehrmann <sw(at)gocept.com>
2008-10-07 12:04:44 [ FULL ]
Author: sweh
Date: Tue Oct  7 12:04:43 2008
New Revision: 6779

Log:
prevent adding a second root to the ObjectCollection



Modified:
   gocept.objectquery/trunk/src/gocept/objectquery/collection.py
   gocept.objectquery/trunk/src/gocept/objectquery/collection.txt

Modified: gocept.objectquery/trunk/src/gocept/objectquery/collection.py
==============================================================================
--- gocept.objectquery/trunk/src/gocept/objectquery/collection.py	(original)
+++ gocept.objectquery/trunk/src/gocept/objectquery/collection.py	Tue Oct  7
12:04:43 2008
(at)(at) -38,6 +38,8 (at)(at)
             return
         if cycle_prev is None:
             cycle_prev = []
+        if parent is None and self.root():
+            raise ValueError('There is already a root object present.')
         parent_oid = None
         if parent:
             parent_oid = parent._p_oid
(at)(at) -57,7 +59,10 (at)(at)
 
     def root(self):
         """ Return the root object. """
-        root = self._structureindex.root()
+        try:
+            root = self._structureindex.root()
+        except KeyError:
+            return None
         return (root, root)
 
     def all(self):

Modified: gocept.objectquery/trunk/src/gocept/objectquery/collection.txt
==============================================================================
--- gocept.objectquery/trunk/src/gocept/objectquery/collection.txt	(original)
+++ gocept.objectquery/trunk/src/gocept/objectquery/collection.txt	Tue Oct  7
12:04:43 2008
(at)(at) -66,6 +66,13 (at)(at)
 
     >>> oc.add(dbroot['test'])
 
+Adding another root object is no longer possible:
+
+    >>> oc.add(dbroot['test'])
+    Traceback (most recent call last):
+    ...
+    ValueError: There is already a root object present.
+
 
 Internal representation of the indexes
 --------------------------------------
(at)(at) -211,25 +218,21 (at)(at)
     >>> import zope.component
     >>> zope.component.provideUtility(oc)
 
-    >>> dbroot['person'] = testobjects.Person(name='Christian')
-    >>> transaction.commit()
-    >>> len(oc.by_class("Person"))
-    2
-
-But what still does not work, is adding objects under existing ones:
+We add a new Person, Christian, as a contributor of the Zope book:
 
+    >>> mark = testobjects.Person(name='Christian')
     >>> zope_book.authors.append(mark)
-    >>> transaction.commit()
+    >>> dbroot['person'] = mark
 
-Mark is now added (thats good, of course):
+XXX Committing the transaction causes an error, cause the automatic index
+updates currently do not know Christian's parent object (which is the Zoe
+book). He is added as another root for fallback reason which causes the
+ObjectCollection to raise an exception.
 
-    >>> len(oc.by_class("Person"))
-    3
-
-But he is not added as a child of the zope_book (which is bad):
-
-    >>> oc.is_child(mark._p_oid, zope_book._p_oid)
-    False
+    >>> transaction.commit()
+    Traceback (most recent call last):
+    ...
+    ValueError: There is already a root object present.
 
 Automatic updates stop when disabling the index synchronizer again:

SVN: r6780 - gocept.objectquery/trunk/src/gocept/objectquery
Sebastian Wehrmann <sw(at)gocept.com>
2008-10-07 14:31:46 [ FULL ]
Author: sweh
Date: Tue Oct  7 14:31:44 2008
New Revision: 6780

Log:
ObjectCollections add method excepts oids instead of objects
first working code for automatic index updates when adding objects



Modified:
   gocept.objectquery/trunk/src/gocept/objectquery/collection.py
   gocept.objectquery/trunk/src/gocept/objectquery/collection.txt
   gocept.objectquery/trunk/src/gocept/objectquery/indexsupport.py
   gocept.objectquery/trunk/src/gocept/objectquery/processor.txt
   gocept.objectquery/trunk/src/gocept/objectquery/testobjects.py
   gocept.objectquery/trunk/src/gocept/objectquery/testobjects.txt

Modified: gocept.objectquery/trunk/src/gocept/objectquery/collection.py
==============================================================================
--- gocept.objectquery/trunk/src/gocept/objectquery/collection.py	(original)
+++ gocept.objectquery/trunk/src/gocept/objectquery/collection.py	Tue Oct  7
14:31:44 2008
(at)(at) -32,30 +32,25 (at)(at)
         self._kcjoin = KCJoin(self._structureindex)
         self._union = Union()
 
-    def add(self, obj, parent=None, cycle_prev=None):
+    def add(self, obj_oid, parent_oid=None, cycle_prev=None):
         """ Index the object to the ObjectCollection. """
-        if not hasattr(obj, '_p_oid'):
-            return
         if cycle_prev is None:
             cycle_prev = []
-        if parent is None and self.root():
+        if parent_oid is None and self.root():
             raise ValueError('There is already a root object present.')
-        parent_oid = None
-        if parent:
-            parent_oid = parent._p_oid
-        if obj._p_oid in cycle_prev:
-            if not self._structureindex.is_successor(obj._p_oid, parent_oid):
-                self._structureindex.insert(obj._p_oid, parent_oid)
+        if obj_oid in cycle_prev:
+            if not self._structureindex.is_successor(obj_oid, parent_oid):
+                self._structureindex.insert(obj_oid, parent_oid)
             return
         op = ObjectParser()
-        classname = self._get_classname(obj)
-        self._classindex.insert(classname, obj._p_oid)
-        for attr in op.get_attributes(obj):
-            self._attributeindex.insert(attr, obj._p_oid)
-        self._structureindex.insert(obj._p_oid, parent_oid)
-        cycle_prev.append(obj._p_oid)
-        for desc in op.get_descendants(obj):
-            self.add(desc, obj, cycle_prev[:])
+        classname = self._get_classname(self._get_object(obj_oid))
+        self._classindex.insert(classname, obj_oid)
+        for attr in op.get_attributes(self._get_object(obj_oid)):
+            self._attributeindex.insert(attr, obj_oid)
+        self._structureindex.insert(obj_oid, parent_oid)
+        cycle_prev.append(obj_oid)
+        for desc in op.get_descendants(self._get_object(obj_oid)):
+            self.add(desc._p_oid, obj_oid, cycle_prev[:])
 
     def root(self):
         """ Return the root object. """
(at)(at) -65,6 +60,10 (at)(at)
             return None
         return (root, root)
 
+    def get_parents(self, elem):
+        """ Return the parents for an element. """
+        return self._structureindex.index['parents'][elem]
+
     def all(self):
         """ Return all objects. """
         return [ (elem, elem) for elem in self._classindex.all() ]
(at)(at) -88,15 +87,15 (at)(at)
     def union(self, *args):
         return self._union(*args)
 
-    def _get_classname(self, object):
+    def _get_classname(self, obj):
         """ Return the classname of object. """
-        return object.__class__.__name__
+        return obj.__class__.__name__
 
     def _get_object(self, oid):
         """ Return the object corresponding to oid. """
         return self.conn.get(oid)
 
-    def delete(self, object_oid, parent_oid=None, pdb=None):
+    def delete(self, object_oid, parent_oid=None):
         """ Main remove method. """
         obj = self._get_object(object_oid)
         classname = self._get_classname(obj)

Modified: gocept.objectquery/trunk/src/gocept/objectquery/collection.txt
==============================================================================
--- gocept.objectquery/trunk/src/gocept/objectquery/collection.txt	(original)
+++ gocept.objectquery/trunk/src/gocept/objectquery/collection.txt	Tue Oct  7
14:31:44 2008
(at)(at) -46,7 +46,7 (at)(at)
     >>> hans = testobjects.Person(name="Hans")
     >>> marie = testobjects.Person(name="Marie")
     >>> zodb_book = testobjects.Book(
-    ...                 authors=[],
+    ...                 author=hans,
     ...                 title='Ad-hoc Anfragen an die ZODB',
     ...                 written=2004,
     ...                 isbn=3404159063)
(at)(at) -56,19 +56,18 (at)(at)
 forget to commit the transaction, because the ObjectCollection needs the OID
of
 your peristant objects for internal storage:
 
-    >>> zodb_book.authors.extend([hans, marie])
-    >>> halle.books.append(zodb_book)
+    >>> halle.add_book(zodb_book)
     >>> dbroot['test'] = halle
     >>> transaction.commit()
 
 To index our test-db, we add the root object to the ObjectCollection. For
large
 databases, this process can last some time:
 
-    >>> oc.add(dbroot['test'])
+    >>> oc.add(dbroot['test']._p_oid)
 
 Adding another root object is no longer possible:
 
-    >>> oc.add(dbroot['test'])
+    >>> oc.add(dbroot['test']._p_oid)
     Traceback (most recent call last):
     ...
     ValueError: There is already a root object present.
(at)(at) -81,32 +80,22 (at)(at)
 classnames to OIDs of this class. It returns a generator object with all found
 results.
 
-We added two Person objects to the database:
-
     >>> persons = oc._classindex.get("Person")
     >>> persons
     <generator object at 0x...>
     
     >>> persons = list(persons)
     >>> len(persons)
-    2
+    1
 
 As shortly mentioned above, the ObjectCollection stores OID instead of
objects.
 To have a look at these objects, we have to ask the connection object:
 
-    >>> person1 = conn.get(persons[0])
-    >>> person1
-    <gocept.objectquery.testobjects.Person object at 0x...>
-    >>> person2 = conn.get(persons[1])
-    >>> person2
+    >>> person = conn.get(persons[0])
+    >>> person
     <gocept.objectquery.testobjects.Person object at 0x...>
-
-    >>> person1 == hans 
-    True
-    >>> person2 == marie
+    >>> person == hans
     True
-    >>> person1 == person2
-    False
 
 There is also an index available, which maps attribute names to OIDs of
 classes, which have that attribute. It returns a generator object, too:
(at)(at) -117,13 +106,10 (at)(at)
 
     >>> names = list(names)
     >>> len(names)
-    2
+    1
     >>> hans = conn.get(names[0])
     >>> hans.name
     'Hans'
-    >>> marie = conn.get(names[1])
-    >>> marie.name
-    'Marie'
 
 
 Adding some more objects to the ObjectCollection
(at)(at) -133,30 +119,23 (at)(at)
 mentioned above:
 
     >>> zope_book = testobjects.Book(
-    ...         authors=[hans],
+    ...         author=marie,
     ...         title='Zope in action',
     ...         written=2003,
     ...         isbn=123456789)
-    >>> halle.books.append(zope_book)
+    >>> halle.add_book(zope_book)
     >>> transaction.commit()
-    >>> oc.add(zope_book, halle)        # XXX: should be obsolete
soon
+    >>> oc.add(zope_book._p_oid, halle._p_oid)        # XXX: should
be obsolete soon
 
 There are now two books inside the database:
 
     >>> len(oc.by_class("Book"))
     2
 
-The Zope book now gets a second author:
-
-    >>> mark = testobjects.Person(name='Mark')
-    >>> zope_book.authors.append(mark)
-    >>> transaction.commit()
-    >>> oc.add(mark, zope_book)         # XXX: should be obsolete
soon
-
-There are now three persons available:
+There are now two persons available:
 
     >>> len(oc.by_class("Person"))
-    3
+    2
 
 
 Testing the database hierarchie
(at)(at) -168,12 +147,12 (at)(at)
 objects. Because it is only used internally, we must provide the OIDs here
 instead of objects:
 
-    >>> oc.is_child(zope_book._p_oid, mark._p_oid)
+    >>> oc.is_child(zope_book._p_oid, marie._p_oid)
     False
-    >>> oc.is_child(mark._p_oid, zope_book._p_oid)
+    >>> oc.is_child(marie._p_oid, zope_book._p_oid)
+    True
+    >>> oc.is_child(hans._p_oid, zodb_book._p_oid)
     True
-    >>> oc.is_child(mark._p_oid, zodb_book._p_oid)
-    False
 
 
 Removing objects from the ObjectCollection
(at)(at) -182,22 +161,13 (at)(at)
 When removing objects, all child objects, which are no longer referenced by
 others, are removed as well.
 
-    >>> zope_book.authors.remove(mark)
-    >>> oc.delete(mark._p_oid)          # XXX: should be obsolete
soon
+    >>> halle.delete_book(zope_book)
+    >>> oc.delete(zope_book._p_oid)          # XXX: should be
obsolete soon
     >>> transaction.commit()
 
-There are two persons remaining:
+There is one person and one book remaining:
 
     >>> len(oc.by_class("Person"))
-    2
-
-When removing a book, all its authors are removed, too, *if* there are no more
-books left, which they wrote:
-
-    >>> halle.books.remove(zodb_book)
-    >>> oc.delete(zodb_book._p_oid)
-    >>> transaction.commit()
-    >>> len(oc.by_class("Person"))
     1
     >>> len(oc.by_class("Book"))
     1
(at)(at) -220,9 +190,10 (at)(at)
 
 We add a new Person, Christian, as a contributor of the Zope book:
 
-    >>> mark = testobjects.Person(name='Christian')
-    >>> zope_book.authors.append(mark)
-    >>> dbroot['person'] = mark
+    >>> chris = testobjects.Person(name='Christian')
+    >>> zodb_book.author = chris
+    >>> zope_book.author
+    <gocept.objectquery.testobjects.Person object at 0x...>
 
 XXX Committing the transaction causes an error, cause the automatic index
 updates currently do not know Christian's parent object (which is the Zoe
(at)(at) -230,9 +201,12 (at)(at)
 ObjectCollection to raise an exception.
 
     >>> transaction.commit()
-    Traceback (most recent call last):
-    ...
-    ValueError: There is already a root object present.
+
+    >>> len(oc.by_class("Person"))
+    2
+
+    >>> oc.is_child(chris._p_oid, zodb_book._p_oid)
+    True
 
 Automatic updates stop when disabling the index synchronizer again:
 
(at)(at) -256,11 +230,11 (at)(at)
 
     >>> dbroot['test'] = first
     >>> transaction.commit()
-    >>> oc.add(first)                   # XXX: should be obsolete
soon
+    >>> oc.add(first._p_oid)                   # XXX: should be
obsolete soon
 
-    >>> first.ref.append(second)
+    >>> first.add_item(second)
     >>> transaction.commit()
-    >>> oc.add(second, first)           # XXX: should be obsolete
soon
+    >>> oc.add(second._p_oid, first._p_oid)           # XXX: should
be obsolete soon
 
 There are now no Telephone objects inside the ObjectCollection:
 
(at)(at) -276,9 +250,9 (at)(at)
 
 Adding first under second will create a cycle, which is possible at all:
 
-    >>> second.ref.append(first)
+    >>> second.add_item(first)
     >>> transaction.commit()
-    >>> oc.add(first, second)           # XXX: should be obsolete
soon
+    >>> oc.add(first._p_oid, second._p_oid)           # XXX: should
be obsolete soon
 
 To test the cycle, second should be a child of first and vice versa:
 

Modified: gocept.objectquery/trunk/src/gocept/objectquery/indexsupport.py
==============================================================================
--- gocept.objectquery/trunk/src/gocept/objectquery/indexsupport.py	(original)
+++ gocept.objectquery/trunk/src/gocept/objectquery/indexsupport.py	Tue Oct  7
14:31:44 2008
(at)(at) -86,11 +86,17 (at)(at)
     def __init__(self, dbroot):
         super(StructureIndex, self).__init__(dbroot)
         self.index['childs'] = OOBTree()    # Childindex, needed for deletion
+        self.index['parents'] = OOBTree()    # Parentindex, needed for
+                                             # automated insertion
 
     def insert(self, key, parent=None):
         """ Insert key under parent. """
         if parent is None:
             parent = 0
+        else:
+            if not self.index['parents'].has_key(key):
+                self.index['parents'][key] = IndexItem()
+            self.index['parents'][key].insert(parent)
         tail = (key, )
         new_path = []
         if self.index.has_key(parent):
(at)(at) -205,6 +211,9 (at)(at)
 
     zope.interface.implements(transaction.interfaces.ISynchronizer)
 
+    def __init__(self):
+        self._before_after_storage = []
+
     def beforeCompletion(self, transaction):
         """Hook that is called by the transaction at the start of a commit.
         """
(at)(at) -214,13 +223,21 (at)(at)
             collection = zope.component.getUtility(
                 gocept.objectquery.interfaces.IObjectCollection)
             for obj in data_manager._registered_objects:
-                collection.add(obj)
+                self._before_after_storage.append(obj._p_oid)
 
 
     def afterCompletion(self, transaction):
         """Hook that is called by the transaction after completing a commit.
         """
-        pass
+        collection = zope.component.getUtility(
+            gocept.objectquery.interfaces.IObjectCollection)
+        for obj in self._before_after_storage:
+            parents = collection.get_parents(obj)
+            for parent in parents:
+                collection.delete(obj, parent)
+            for parent in parents:
+                collection.add(obj, parent)
+        self._before_after_storage = []
 
     def newTransaction(self, transaction):
         """Hook that is called at the start of a transaction.

Modified: gocept.objectquery/trunk/src/gocept/objectquery/processor.txt
==============================================================================
--- gocept.objectquery/trunk/src/gocept/objectquery/processor.txt	(original)
+++ gocept.objectquery/trunk/src/gocept/objectquery/processor.txt	Tue Oct  7
14:31:44 2008
(at)(at) -27,7 +27,7 (at)(at)
 
 Now fill the indexes with the data from the test database:
 
-    >>> objects.add(librarydb)
+    >>> objects.add(librarydb._p_oid)
 
 Some example usecases
 ---------------------
(at)(at) -68,12 +68,9 (at)(at)
 
     >>> r = query('/Library/Book[(at)written>=2000]/Person')
     >>> len(r)
-    4
+    3
     >>> pprint(sorted(elem.name for elem in r))
-    ['George Orwell',
-     'Jan Ulrich Hasecke',
-     'Philipp von Weitershausen',
-     'Thomas Lotze']
+    ['George Orwell', 'Philipp von Weitershausen', 'Thomas Lotze']
 
 Search for all Books, that have are located in Halle and have been written in
 2007:
(at)(at) -87,7 +84,6 (at)(at)
     >>> r = query('/Library/_/Person')
     >>> pprint(sorted(elem.name for elem in r))
     ['George Orwell',
-     'Jan Ulrich Hasecke',
      'Johann Wolfgang von Goethe',
      'Philipp von Weitershausen',
      'Thomas Lotze']
(at)(at) -96,17 +92,11 (at)(at)
 
     >>> r = query('/Library[(at)location="Halle"]/Book/Person')
     >>> pprint(sorted(elem.name for elem in r))
-    ['George Orwell',
-     'Jan Ulrich Hasecke',
-     'Philipp von Weitershausen',
-     'Thomas Lotze']
+    ['George Orwell', 'Philipp von Weitershausen', 'Thomas Lotze']
 
     >>> r = query('(/Library[(at)location="Halle"]/Book)/Person')
     >>> pprint(sorted(elem.name for elem in r))
-    ['George Orwell',
-     'Jan Ulrich Hasecke',
-     'Philipp von Weitershausen',
-     'Thomas Lotze']
+    ['George Orwell', 'Philipp von Weitershausen', 'Thomas Lotze']
 
     >>> r = query('/Library[(at)location="Halle"]/(Book/Person)')
     >>> len(r)
(at)(at) -129,13 +119,12 (at)(at)
 
     >>> r = query('(/Library[(at)location="Halle"])|(Book/Person)')
     >>> len(r)
-    6
+    5
     >>> pprint(sorted(elem for elem in r))
     [<gocept.objectquery.testobjects.Library object at 0x...>,
      <gocept.objectquery.testobjects.Person object at 0x...>,
      <gocept.objectquery.testobjects.Person object at 0x...>,
      <gocept.objectquery.testobjects.Person object at 0x...>,
-     <gocept.objectquery.testobjects.Person object at 0x...>,
      <gocept.objectquery.testobjects.Person object at 0x...>]
 
     >>> r = query('(/Library)|(Book[(at)written=1990])')
(at)(at) -171,7 +160,7 (at)(at)
 
     >>> dbroot['test'] = root
     >>> transaction.commit()
-    >>> objects.add(root)
+    >>> objects.add(root._p_oid)
 
 Now there should be one Plone object under root:
 
(at)(at) -241,7 +230,7 (at)(at)
     >>> len(r) == 1 and r[0] == doc1
     True
 
-A special case is the combination of wildcard and ``*'' closure:
+A special case is the combination of wildcard and '*' closure:
 
     >>> r = query('Plone/_*/Document')
     >>> len(r) == 3

Modified: gocept.objectquery/trunk/src/gocept/objectquery/testobjects.py
==============================================================================
--- gocept.objectquery/trunk/src/gocept/objectquery/testobjects.py	(original)
+++ gocept.objectquery/trunk/src/gocept/objectquery/testobjects.py	Tue Oct  7
14:31:44 2008
(at)(at) -15,16 +15,24 (at)(at)
 
     def __init__(self, location, books=[]):
         self.location = location
-        self.books = persistent.list.PersistentList()
-        self.books.extend(books)
+        self.books = []
+        for book in books:
+            self.add_book(book)
+
+    def add_book(self, book):
+        self.books.append(book)
+        self._p_changed = True
+
+    def delete_book(self, book):
+        self.books.remove(book)
+        self._p_changed = True
 
 
 class Book(persistent.Persistent):
     """ """
 
-    def __init__(self, authors, title, written, isbn):
-        self.authors = persistent.list.PersistentList()
-        self.authors.extend(authors)
+    def __init__(self, author, title, written, isbn):
+        self.author = author
         self.title = title
         self.written = written
         self.isbn = isbn
(at)(at) -46,33 +54,32 (at)(at)
 
 p_orwell = Person(name="George Orwell")
 p_lotze = Person(name="Thomas Lotze")
-p_hasecke = Person(name="Jan Ulrich Hasecke")
 p_goethe = Person(name="Johann Wolfgang von Goethe")
 p_weitershausen = Person(name="Philipp von Weitershausen")
 
 # Books
 
-b_1984 = Book(authors=[p_orwell],
+b_1984 = Book(author=p_orwell,
               title="1984",
               written=1990,
               isbn=3548234100)
 
-b_plone = Book(authors=[p_lotze, p_hasecke],
+b_plone = Book(author=p_lotze,
                title="Plone-Benutzerhandbuch",
                written=2008,
                isbn=3939471038)
 
-b_faust = Book(authors=[p_goethe],
+b_faust = Book(author=p_goethe,
                title="Faust",
                written=1811,
                isbn=3406552501)
 
-b_farm = Book(authors=[p_orwell],
+b_farm = Book(author=p_orwell,
               title="Farm der Tiere",
               written=2002,
               isbn=3257201184)
 
-b_zope = Book(authors=[p_weitershausen],
+b_zope = Book(author=p_weitershausen,
               title="Web Component Development with Zope 3",
               written=2007,
               isbn=3540338071)
(at)(at) -100,9 +107,14 (at)(at)
     """An object with an id and a reference list."""
     def __init__(self, id=None, ref=[]):
         self.id = id
-        self.ref = persistent.list.PersistentList()
+        self.ref = []
         self.ref.extend(ref)
 
+    def add_item(self, item):
+        self.ref.append(item)
+        self._p_changed = True
+
+
 # needed for kleen closure tests in processor.txt
 
 class Root(Dummy):

Modified: gocept.objectquery/trunk/src/gocept/objectquery/testobjects.txt
==============================================================================
--- gocept.objectquery/trunk/src/gocept/objectquery/testobjects.txt	(original)
+++ gocept.objectquery/trunk/src/gocept/objectquery/testobjects.txt	Tue Oct  7
14:31:44 2008
(at)(at) -33,17 +33,17 (at)(at)
 >>> testobjects.Person
 <class 'gocept.objectquery.testobjects.Person'>
 
-Books need a list of authors, a title and an isbn number:
+Books need an authors, a title and an isbn number:
 
 >>> gier = testobjects.Book(
-...         authors=[testobjects.Person(name='Kerstin Gier')],
+...         author=testobjects.Person(name='Kerstin Gier'),
 ...         title='Gegensätze ziehen sich aus',
 ...         written=2008,
 ...         isbn=3404159063)
 
 >>> gier
 <gocept.objectquery.testobjects.Book object at 0x...>
->>> gier.authors[0].name
+>>> gier.author.name
 'Kerstin Gier'
 >>> gier.title
 'Gegens\xc3\xa4tze ziehen sich aus'
(at)(at) -76,9 +76,7 (at)(at)
 which returns us some details for a book:
 
 >>> def show_book_info(book):
-...     return '%s: %s' % (
-...         book.title,
-...         '; '.join([author.name for author in book.authors]))
+...     return '%s: %s' % (book.title, book.author.name)
 
 The libraries have the following books:
 
(at)(at) -89,7 +87,7 (at)(at)
 4
 >>> pprint([show_book_info(book) for book in halle.books])
 ['1984: George Orwell',
- 'Plone-Benutzerhandbuch: Thomas Lotze; Jan Ulrich Hasecke',
+ 'Plone-Benutzerhandbuch: Thomas Lotze',
  'Farm der Tiere: George Orwell',
  'Web Component Development with Zope 3: Philipp von Weitershausen']
 
(at)(at) -100,7 +98,7 (at)(at)
 5
 >>> pprint([show_book_info(book) for book in berlin.books])
 ['1984: George Orwell',
- 'Plone-Benutzerhandbuch: Thomas Lotze; Jan Ulrich Hasecke',
+ 'Plone-Benutzerhandbuch: Thomas Lotze',
  'Faust: Johann Wolfgang von Goethe',
  'Farm der Tiere: George Orwell',
  'Web Component Development with Zope 3: Philipp von Weitershausen']

SVN: r6781 - gocept.objectquery/trunk/src/gocept/objectquery
Sebastian Wehrmann <sw(at)gocept.com>
2008-10-07 16:26:34 [ FULL ]
Author: sweh
Date: Tue Oct  7 16:26:33 2008
New Revision: 6781

Log:
bugfix in deleting objects



Modified:
   gocept.objectquery/trunk/src/gocept/objectquery/collection.py
   gocept.objectquery/trunk/src/gocept/objectquery/collection.txt
   gocept.objectquery/trunk/src/gocept/objectquery/indexsupport.py

Modified: gocept.objectquery/trunk/src/gocept/objectquery/collection.py
==============================================================================
--- gocept.objectquery/trunk/src/gocept/objectquery/collection.py	(original)
+++ gocept.objectquery/trunk/src/gocept/objectquery/collection.py	Tue Oct  7
16:26:33 2008
(at)(at) -64,6 +64,10 (at)(at)
         """ Return the parents for an element. """
         return self._structureindex.index['parents'][elem]
 
+    def get_childs(self, elem):
+        """ Return the childs for an element. """
+        return self._structureindex.index['childs'][elem]
+
     def all(self):
         """ Return all objects. """
         return [ (elem, elem) for elem in self._classindex.all() ]
(at)(at) -100,11 +104,15 (at)(at)
         obj = self._get_object(object_oid)
         classname = self._get_classname(obj)
         op = ObjectParser()
+        try:
+            childs = self.get_childs(object_oid)
+        except KeyError:
+            childs = []
         if self._structureindex.has_key(object_oid):
             self._structureindex.delete(object_oid, parent_oid)
         if not self._structureindex.has_key(object_oid):
              self._classindex.delete(classname, object_oid)
         for attr in op.get_attributes(obj):
              self._attributeindex.delete(attr, object_oid)
-        for desc in op.get_descendants(obj):
-            self.delete(desc._p_oid, object_oid)
+        for desc in childs:
+            self.delete(desc, object_oid)

Modified: gocept.objectquery/trunk/src/gocept/objectquery/collection.txt
==============================================================================
--- gocept.objectquery/trunk/src/gocept/objectquery/collection.txt	(original)
+++ gocept.objectquery/trunk/src/gocept/objectquery/collection.txt	Tue Oct  7
16:26:33 2008
(at)(at) -192,19 +192,20 (at)(at)
 
     >>> chris = testobjects.Person(name='Christian')
     >>> zodb_book.author = chris
-    >>> zope_book.author
-    <gocept.objectquery.testobjects.Person object at 0x...>
-
-XXX Committing the transaction causes an error, cause the automatic index
-updates currently do not know Christian's parent object (which is the Zoe
-book). He is added as another root for fallback reason which causes the
-ObjectCollection to raise an exception.
-
     >>> transaction.commit()
 
-    >>> len(oc.by_class("Person"))
-    2
-
+    >>> books = oc.by_class("Book")
+    >>> len(books)
+    1
+    >>> book = conn.get(books[0][0])
+    >>> book.title
+    'Ad-hoc Anfragen an die ZODB'
+    >>> persons = oc.by_class("Person")
+    >>> len(persons)
+    1
+    >>> person = conn.get(persons[0][0])
+    >>> book.author == person
+    True
     >>> oc.is_child(chris._p_oid, zodb_book._p_oid)
     True
 

Modified: gocept.objectquery/trunk/src/gocept/objectquery/indexsupport.py
==============================================================================
--- gocept.objectquery/trunk/src/gocept/objectquery/indexsupport.py	(original)
+++ gocept.objectquery/trunk/src/gocept/objectquery/indexsupport.py	Tue Oct  7
16:26:33 2008
(at)(at) -212,7 +212,7 (at)(at)
     zope.interface.implements(transaction.interfaces.ISynchronizer)
 
     def __init__(self):
-        self._before_after_storage = []
+        self._store = []
 
     def beforeCompletion(self, transaction):
         """Hook that is called by the transaction at the start of a commit.
(at)(at) -223,7 +223,14 (at)(at)
             collection = zope.component.getUtility(
                 gocept.objectquery.interfaces.IObjectCollection)
             for obj in data_manager._registered_objects:
-                self._before_after_storage.append(obj._p_oid)
+                obj = obj._p_oid
+                try:
+                    parents = collection.get_parents(obj)
+                except KeyError:
+                    parents = []
+                for parent in parents:
+                    collection.delete(obj, parent)
+                self._store.append([obj, parents])
 
 
     def afterCompletion(self, transaction):
(at)(at) -231,13 +238,10 (at)(at)
         """
         collection = zope.component.getUtility(
             gocept.objectquery.interfaces.IObjectCollection)
-        for obj in self._before_after_storage:
-            parents = collection.get_parents(obj)
-            for parent in parents:
-                collection.delete(obj, parent)
+        for obj, parents in self._store:
             for parent in parents:
                 collection.add(obj, parent)
-        self._before_after_storage = []
+        self._store = []
 
     def newTransaction(self, transaction):
         """Hook that is called at the start of a transaction.

SVN: r6782 - in gocept.reference/trunk: . src/gocept/reference
Michael Howitz <mh(at)gocept.com>
2008-10-10 14:35:02 [ FULL ]
Author: mac
Date: Fri Oct 10 14:35:01 2008
New Revision: 6782

Log:
Made sure that the reference manager is installed using zope.app.generations
before packages depending on gocept.reference.



Modified:
   gocept.reference/trunk/CHANGES.txt
   gocept.reference/trunk/src/gocept/reference/configure.zcml

Modified: gocept.reference/trunk/CHANGES.txt
==============================================================================
--- gocept.reference/trunk/CHANGES.txt	(original)
+++ gocept.reference/trunk/CHANGES.txt	Fri Oct 10 14:35:01 2008
(at)(at) -2,10 +2,11 (at)(at)
 Changes
 =======
 
-0.6 (unreleased)
-================
+0.5.1 (2008-10-10)
+==================
 [...]

SVN: r6787 - in gocept.country/trunk: . src/gocept/country
Sebastian Wehrmann <sw(at)gocept.com>
2008-10-13 14:13:20 [ FULL ]
Author: sweh
Date: Mon Oct 13 14:13:19 2008
New Revision: 6787

Log:
- Added security declarations for token.
- Bugfix in comparison of db objects, where `isinstance` returns False
  for objects of the same type



Modified:
   gocept.country/trunk/CHANGES.txt
   gocept.country/trunk/src/gocept/country/configure.zcml
   gocept.country/trunk/src/gocept/country/db.py

Modified: gocept.country/trunk/CHANGES.txt
==============================================================================
--- gocept.country/trunk/CHANGES.txt	(original)
+++ gocept.country/trunk/CHANGES.txt	Mon Oct 13 14:13:19 2008
(at)(at) -6,6 +6,13 (at)(at)
 
 - 
 
+0.6.2 (2008-10-13)
+------------------
+
+- Added security declarations for token.
+- Bugfix in comparison of db objects, where `isinstance` returns False
+  for objects of the same type
+
 0.6.1 (2008-09-13)
 ------------------
 

Modified: gocept.country/trunk/src/gocept/country/configure.zcml
==============================================================================
--- gocept.country/trunk/src/gocept/country/configure.zcml	(original)
+++ gocept.country/trunk/src/gocept/country/configure.zcml	Mon Oct 13 14:13:19
2008
(at)(at) -5,24 +5,23 (at)(at)
   <include package="zope.i18n" file="meta.zcml" />
 
   <class class=".db.Country">
-    <allow attributes="name alpha2" />
+    <allow attributes="token name alpha2" />
   </class>
 
   <class class=".db.Subdivision">
-    <allow attributes="name code" />
+    <allow attributes="token name code" />
   </class>
 
-
   <class class=".db.Script">
-    <allow attributes="name alpha4" />
+    <allow attributes="token name alpha4" />
   </class>
 
   <class class=".db.Currency">
-    <allow attributes="name letter" />
+    <allow attributes="token name letter" />
   </class>
 
   <class class=".db.Language">
-    <allow attributes="name bibliographic" />
+    <allow attributes="token name bibliographic" />
   </class>
 
   <configure package="pycountry">

Modified: gocept.country/trunk/src/gocept/country/db.py
==============================================================================
--- gocept.country/trunk/src/gocept/country/db.py	(original)
+++ gocept.country/trunk/src/gocept/country/db.py	Mon Oct 13 14:13:19 2008
(at)(at) -25,7 +25,7 (at)(at)
     def __eq__(self, other):
         if not other:
             return False
-        if not isinstance(other, self.__class__):
+        if other.__class__ != self.__class__:
             return False
         return self.token == other.token

SVN: r6792 - gocept.plone.oodocument/trunk/gocept/plone/oodocument/browser
Christian Zagrodnick <cz(at)gocept.com>
2008-10-13 18:57:28 [ FULL ]
Author: zagy
Date: Mon Oct 13 18:57:27 2008
New Revision: 6792

Log:
aus naiven datetimes welche mit tzinfo machen



Modified:
   gocept.plone.oodocument/trunk/gocept/plone/oodocument/browser/oodocument.py

Modified:
gocept.plone.oodocument/trunk/gocept/plone/oodocument/browser/oodocument.py
==============================================================================
---
gocept.plone.oodocument/trunk/gocept/plone/oodocument/browser/oodocument.py	(original)
+++
gocept.plone.oodocument/trunk/gocept/plone/oodocument/browser/oodocument.py	Mon
Oct 13 18:57:27 2008
(at)(at) -4,6 +4,7 (at)(at)
 import zope.component
 
 import DateTime
+import pytz
 
 import Products.Five.browser
 import Products.Five.browser.pagetemplatefile
(at)(at) -96,10 +97,13 (at)(at)
             # like <br/> by <br />.
             self.context.edit(text=result.body.replace('/>', ' />'),
title=result.title,
                               description=result.description)
-            self.context.setCreationDate(result.created.isoformat())
+            self.context.setCreationDate(
+               
result.created.replace(tzinfo=pytz.timezone('Europe/Berlin')).isoformat())
             self.context.setContributors((result.creator, ))
             self.context.reindexObject()
-            self.context.setModificationDate(result.modified.isoformat())
+            self.context.setModificationDate(
+               
result.modified.replace(tzinfo=pytz.timezone('Europe/Berlin')).isoformat())
+
         textnumber = self.request.get('textnumber')
         id_util = zope.component.getUtility(
             jugendprogramm.theme.interfaces.IIdUtility)

SVN: r6793 - gocept.ooo2html/trunk/src/gocept/ooo2html
Christian Zagrodnick <cz(at)gocept.com>
2008-10-13 19:07:50 [ FULL ]
Author: zagy
Date: Mon Oct 13 19:07:49 2008
New Revision: 6793

Log:
use open instead of file


Modified:
   gocept.ooo2html/trunk/src/gocept/ooo2html/convert.py

Modified: gocept.ooo2html/trunk/src/gocept/ooo2html/convert.py
==============================================================================
--- gocept.ooo2html/trunk/src/gocept/ooo2html/convert.py	(original)
+++ gocept.ooo2html/trunk/src/gocept/ooo2html/convert.py	Mon Oct 13 19:07:49
2008
(at)(at) -38,7 +38,7 (at)(at)
     def get_template(self, title, description, section):
         """Return template."""
         odt = tempfile.TemporaryFile()
-        odt.write(file(TEMPLATE, 'rb').read())
+        odt.write(open(TEMPLATE, 'rb').read())
         odt.seek(0, 0)
         convert = Convert(odt, mode='a')
         convert.set_title(title)

SVN: r6794 - gocept.ooo2html/trunk/src/gocept/ooo2html
Christian Zagrodnick <cz(at)gocept.com>
2008-10-13 19:40:41 [ FULL ]
Author: zagy
Date: Mon Oct 13 19:40:38 2008
New Revision: 6794

Log:
added method to set the section



Modified:
   gocept.ooo2html/trunk/src/gocept/ooo2html/README.txt
   gocept.ooo2html/trunk/src/gocept/ooo2html/convert.py

Modified: gocept.ooo2html/trunk/src/gocept/ooo2html/README.txt
==============================================================================
--- gocept.ooo2html/trunk/src/gocept/ooo2html/README.txt	(original)
+++ gocept.ooo2html/trunk/src/gocept/ooo2html/README.txt	Mon Oct 13 19:40:38
2008
(at)(at) -833,6 +833,19 (at)(at)
 True
 
 
+Setting the section
+-------------------
+
+It is possible to set the section:
+
+>>> odt = converter.get_template('Lorem ipsum', 'dolor', 'foo / bar')
+>>> odt.seek(0, 0)
+>>> odt = converter.set_section(odt, 'bla blub')
+>>> result = converter.to_html(odt)
+>>> result.section
+'bla blub'
+
+
 Bugs
 ----
 

Modified: gocept.ooo2html/trunk/src/gocept/ooo2html/convert.py
==============================================================================
--- gocept.ooo2html/trunk/src/gocept/ooo2html/convert.py	(original)
+++ gocept.ooo2html/trunk/src/gocept/ooo2html/convert.py	Mon Oct 13 19:40:38
2008
(at)(at) -50,6 +50,15 (at)(at)
         convert.write()
         return odt
 
+    def set_section(self, infile, section):
+        odt = tempfile.TemporaryFile()
+        odt.write(infile.read())
+        odt.seek(0, 0)
+        convert = Convert(odt, mode='a')
+        convert.set_section(section)
+        convert.write()
+        return odt
+
 
 class Convert(object):
     """Internal convert class."""

SVN: r6819 - gocept.restmail/trunk/gocept/restmail/browser
Roman Joost <rj(at)gocept.com>
2008-10-15 18:12:16 [ FULL ]
Author: roman
Date: Wed Oct 15 18:12:15 2008
New Revision: 6819

Log:
- added delete for IMAPAccounts



Modified:
   gocept.restmail/trunk/gocept/restmail/browser/account.py
   gocept.restmail/trunk/gocept/restmail/browser/configure.zcml

Modified: gocept.restmail/trunk/gocept/restmail/browser/account.py
==============================================================================
--- gocept.restmail/trunk/gocept/restmail/browser/account.py	(original)
+++ gocept.restmail/trunk/gocept/restmail/browser/account.py	Wed Oct 15
18:12:15 2008
(at)(at) -10,4 +10,14 (at)(at)
 class WebAPI(object):
     """Web API for accounts."""
 
-    pass
+    def delete(self):
+        parent = self.context.aq_inner.getParentNode()
+        message = "Account deleted."
+        try:
+            parent.manage_delObjects(self.context.id)
+        except KeyError:
+            message = (
+                'Given account id (%s) was not found.' % self.context.id)
+        return cjson.encode(message)
+
+

Modified: gocept.restmail/trunk/gocept/restmail/browser/configure.zcml
==============================================================================
--- gocept.restmail/trunk/gocept/restmail/browser/configure.zcml	(original)
+++ gocept.restmail/trunk/gocept/restmail/browser/configure.zcml	Wed Oct 15
18:12:15 2008
(at)(at) -286,4 +286,16 (at)(at)
 
   </browser:pages>
 
+  <browser:pages
+    for="gocept.restmail.interfaces.IIMAPAccount"
+    permission="zope2.View"
+    class=".account.WebAPI">
+
+    <browser:page
+      name="delete"
+      attribute="delete"
+      />
+
+  </browser:pages>
+
 </configure>

SVN: r6832 - gocept.restmail/trunk/gocept/restmail/browser
Sebastian Wehrmann <sw(at)gocept.com>
2008-10-17 14:04:36 [ FULL ]
Author: sweh
Date: Fri Oct 17 14:04:35 2008
New Revision: 6832

Log:
added an API view which lists all accounts with their setup details



Modified:
   gocept.restmail/trunk/gocept/restmail/browser/README.txt
   gocept.restmail/trunk/gocept/restmail/browser/configure.zcml
   gocept.restmail/trunk/gocept/restmail/browser/profile.py

Modified: gocept.restmail/trunk/gocept/restmail/browser/README.txt
==============================================================================
--- gocept.restmail/trunk/gocept/restmail/browser/README.txt	(original)
+++ gocept.restmail/trunk/gocept/restmail/browser/README.txt	Fri Oct 17
14:04:35 2008
(at)(at) -133,6 +133,15 (at)(at)
 >>> print browser.contents
 [{"url": "http://localhost/profile/account",
"children": 2, "name": "account"}]
 
+Account listing with details
+----------------------------
+
+Each profile can list the accounts with their setup details:
+
+>>> browser.open('http://localhost/profile/(at)(at)accounts_details')
+>>> print browser.contents
+[{"user": "test", "host": "localhost", "password": "bsdf", "id": "account",
"port": 10143}]
+
 
 Account API
 ===========

Modified: gocept.restmail/trunk/gocept/restmail/browser/configure.zcml
==============================================================================
--- gocept.restmail/trunk/gocept/restmail/browser/configure.zcml	(original)
+++ gocept.restmail/trunk/gocept/restmail/browser/configure.zcml	Fri Oct 17
14:04:35 2008
(at)(at) -265,11 +265,21 (at)(at)
     class=".profile.WebAPI">
 
     <browser:page
+      name="save_account"
+      attribute="save_account"
+      />
+
+    <browser:page
       name="accounts"
       attribute="accounts"
       />
 
     <browser:page
+      name="accounts_details"
+      attribute="accounts_details"
+      />
+
+    <browser:page
       name="new_draft"
       attribute="new_draft"
       />

Modified: gocept.restmail/trunk/gocept/restmail/browser/profile.py
==============================================================================
--- gocept.restmail/trunk/gocept/restmail/browser/profile.py	(original)
+++ gocept.restmail/trunk/gocept/restmail/browser/profile.py	Fri Oct 17
14:04:35 2008
(at)(at) -6,6 +6,9 (at)(at)
 import cjson
 import xml.sax.saxutils
 import zope.app.zapi
+import zope.app.container.contained
+
+import gocept.restmail.imapaccount
 
 
 class WebAPI(object):
(at)(at) -19,6 +22,35 (at)(at)
                 for account in self.context.objectValues('IMAP Account')]
         return cjson.encode(data)
 
+    def save_account(self, account_id, host, port, user, password):
+        """Save an IMAP account.
+
+        Create one, if id is empty, update existing else.
+        """
+        if account_id == '':
+            chooser = zope.app.container.contained.INameChooser(self.context)
+            new_id = chooser.chooseName(host, self.context)
+            account = (gocept.restmail.imapaccount.
+                       IMAPAccount(new_id, host, port, user, password))
+            self.context._setObject(new_id, account)
+            return cjson.encode('created')
+        account = self.context[account_id]
+        account.host = host
+        account.port = port
+        account.user = user
+        account.password = password
+        return cjson.encode('updated')
+
+    def accounts_details(self):
+        """List all accounts with their property values."""
+        data = [{'id': account.id,
+                 'host': account.host,
+                 'port': account.port,
+                 'user': account.user,
+                 'password':account.password}
+                for account in self.context.objectValues('IMAP Account')]
+        return cjson.encode(data)
+
     def new_draft(self, message=None):
         """Create a new draft message."""
         draft = self.context.new_draft(message)

SVN: r6849 - gocept.recipe.updatercd/trunk/src/gocept/recipe/updatercd
Christian Zagrodnick <cz(at)gocept.com>
2008-10-20 15:15:05 [ FULL ]
Author: zagy
Date: Mon Oct 20 15:15:04 2008
New Revision: 6849

Log:
fixed tests


Modified:
   gocept.recipe.updatercd/trunk/src/gocept/recipe/updatercd/README.txt

Modified: gocept.recipe.updatercd/trunk/src/gocept/recipe/updatercd/README.txt
==============================================================================
---
gocept.recipe.updatercd/trunk/src/gocept/recipe/updatercd/README.txt	(original)
+++ gocept.recipe.updatercd/trunk/src/gocept/recipe/updatercd/README.txt	Mon
Oct 20 15:15:04 2008
(at)(at) -50,6 +50,7 (at)(at)
 ... """)
 >>> print system('bin/buildout'),
 Uninstalling updatercd.
+Running uninstall recipe.
 -f test-deploy-zeo remove
 -f test-deploy-instance remove

SVN: r6869 - gocept.restmail/trunk/gocept/restmail/browser
Sebastian Wehrmann <sw(at)gocept.com>
2008-10-21 15:53:49 [ FULL ]
Author: sweh
Date: Tue Oct 21 15:53:48 2008
New Revision: 6869

Log:
add an account status flag (can we connect to the server or not)



Modified:
   gocept.restmail/trunk/gocept/restmail/browser/README.txt
   gocept.restmail/trunk/gocept/restmail/browser/profile.py

Modified: gocept.restmail/trunk/gocept/restmail/browser/README.txt
==============================================================================
--- gocept.restmail/trunk/gocept/restmail/browser/README.txt	(original)
+++ gocept.restmail/trunk/gocept/restmail/browser/README.txt	Tue Oct 21
15:53:48 2008
(at)(at) -140,7 +140,7 (at)(at)
 
 >>> browser.open('http://localhost/profile/(at)(at)identities_details')
 >>> print browser.contents
-[{"sent_folder": "account/+INBOX", "account_id": "account", "ident_id":
"default-identity", "default": false, "smtp_server": "default-smtp", "host":
"localhost", "user": "test", "address": "ben(at)example.com", "password":
"bsdf", "port": 10143, "name": "Ben Utzer"}, {"sent_folder": "account/+INBOX",
"account_id": "account", "ident_id": "basti", "default": true, "smtp_server":
"default-smtp", "host": "localhost", "user": "test", "address":
"sw(at)gocept.com", "password": "bsdf", "port": 10143, "name": "Basti"}]
+[{"status": "ok", "sent_folder": "account/+INBOX", "account_id": "account",
"ident_id": "default-identity", "default": false, "smtp_server":
"default-smtp", "host": "localhost", "user": "test", "address":
"ben(at)example.com", "password": "bsdf", "port": 10143, "name": "Ben Utzer"},
{"status": "ok", "sent_folder": "account/+INBOX", "account_id": "account",
"ident_id": "basti", "default": true, "smtp_server": "default-smtp", "host":
"localhost", "user": "test", "address": "sw(at)gocept.com", "password": "bsdf",
"port": 10143, "name": "Basti"}]
 
 
 Account API

Modified: gocept.restmail/trunk/gocept/restmail/browser/profile.py
==============================================================================
--- gocept.restmail/trunk/gocept/restmail/browser/profile.py	(original)
+++ gocept.restmail/trunk/gocept/restmail/browser/profile.py	Tue Oct 21
15:53:48 2008
(at)(at) -4,6 +4,7 (at)(at)
 """Profile methods."""
 
 import cjson
+import socket
 import xml.sax.saxutils
 import zope.app.zapi
 
(at)(at) -15,10 +16,20 (at)(at)
 
     def accounts(self):
         """List the accounts in this profile."""
-        data = [{'url': zope.app.zapi.absoluteURL(account, self.request),
-                 'children': len(account.folders()),
-                 'name': account.title_or_id()}
-                for account in self.context.objectValues('IMAP Account')]
+        data = []
+        for account in self.context.objectValues('IMAP Account'):
+            try:
+                # Prevent raising an exception if the server is not available
+                # (e.g. because of a wrong configuration). Available accounts
+                # should be listet although.
+                children = len(account.folders())
+                data.append(
+                    {'url': zope.app.zapi.absoluteURL(account, self.request),
+                     'children': children,
+                     'name': account.title_or_id()})
+            except socket.gaierror:
+                # XXX Log an error for the user
+                pass
         return cjson.encode(data)
 
     def save_identity(self, ident_id, name, address, smtp_server, sent_folder,
(at)(at) -51,18 +62,27 (at)(at)
 
     def identities_details(self):
         """List all accounts with their property values."""
-        data = [{'account_id': identity.account_id,
-                 'host': identity.get_account().host,
-                 'port': identity.get_account().port,
-                 'user': identity.get_account().user,
-                 'password': identity.get_account().password, 
+        data = []
+        for identity in self.context.objectValues('Webmail Identity'):
+            account = identity.get_account()
+            status = 'ok'
+            try:
+                account.folders()
+            except:
+                status = 'failure'
+            data.append(
+                {'status': status,
+                 'account_id': identity.account_id,
+                 'host': account.host,
+                 'port': account.port,
+                 'user': account.user,
+                 'password': account.password, 
                  'ident_id': identity.id,
                  'name': identity.name,
                  'address': identity.address,
                  'sent_folder': identity.sent_folder,
                  'smtp_server': identity.smtp_server,
-                 'default': identity.id == self.context.default_identity}
-                for identity in self.context.objectValues('Webmail Identity')]
+                 'default': identity.id == self.context.default_identity})
         return cjson.encode(data)
 
     def new_draft(self, message=None):

SVN: r6915 - gocept.pagewithimage/trunk/gocept/pagewithimage
Daniel Havlik <dh(at)gocept.com>
2008-10-27 11:11:12 [ FULL ]
Author: nilo
Date: Mon Oct 27 11:11:11 2008
New Revision: 6915

Log:
added condition to only include image tag when there is an image


Modified:
   gocept.pagewithimage/trunk/gocept/pagewithimage/viewlet.py

Modified: gocept.pagewithimage/trunk/gocept/pagewithimage/viewlet.py
==============================================================================
--- gocept.pagewithimage/trunk/gocept/pagewithimage/viewlet.py	(original)
+++ gocept.pagewithimage/trunk/gocept/pagewithimage/viewlet.py	Mon Oct 27
11:11:11 2008
(at)(at) -476,7 +476,8 (at)(at)
     def render(self):
         if Products.ATContentTypes.interface.document.IATDocument.providedBy(
                 self.context):
-            return u'<script
type="text/javascript">%s</script><style
type="text/css">%s</style><a href="%s" rel="lightbox"
title="%s"><div style="float:right; margin-left:20px;
margin-bottom:20px;"><img src="%s/docimage_mini2" />'\
+            if self.context.getDocimage():
+                return u'<script
type="text/javascript">%s</script><style
type="text/css">%s</style><a href="%s" rel="lightbox" title="%s"
class="docimage_link"><div style="float:right; margin-left:20px;
margin-bottom:20px;"><img src="%s/docimage_mini2" />'\
                         '<p style="font-weight:
bold;">%s</p></div></a>' % (
 				JS,
 				CSS,

SVN: r6916 - gocept.pagewithimage/trunk/gocept/pagewithimage
Daniel Havlik <dh(at)gocept.com>
2008-10-27 11:11:43 [ FULL ]
Author: nilo
Date: Mon Oct 27 11:11:42 2008
New Revision: 6916

Log:
folder now does get an image field, too


Modified:
   gocept.pagewithimage/trunk/gocept/pagewithimage/__init__.py

Modified: gocept.pagewithimage/trunk/gocept/pagewithimage/__init__.py
==============================================================================
--- gocept.pagewithimage/trunk/gocept/pagewithimage/__init__.py	(original)
+++ gocept.pagewithimage/trunk/gocept/pagewithimage/__init__.py	Mon Oct 27
11:11:42 2008
(at)(at) -9,6 +9,7 (at)(at)
 def initialize(context):
     """Initializer called when used as a Zope 2 product."""
     from Products.ATContentTypes.content import document
+    from Products.ATContentTypes.content import folder
     image_field = ImageField('docimage',
             required = False,
             schemata = 'image',
(at)(at) -41,4 +42,7 (at)(at)
             )
     document.ATDocument.schema.addField(image_field)
     document.ATDocument.schema.addField(image_caption_field)
+    folder.ATFolder.schema.addField(image_field)
+    folder.ATFolder.schema.addField(image_caption_field)
     registerATCT(document.ATDocument, PROJECTNAME)
+    registerATCT(folder.ATFolder, PROJECTNAME)

SVN: r6963 - gocept.pagewithimage/trunk/gocept/pagewithimage
Daniel Havlik <dh(at)gocept.com>
2008-10-30 15:37:35 [ FULL ]
Author: nilo
Date: Thu Oct 30 15:37:34 2008
New Revision: 6963

Log:
added new size for the image



Modified:
   gocept.pagewithimage/trunk/gocept/pagewithimage/__init__.py

Modified: gocept.pagewithimage/trunk/gocept/pagewithimage/__init__.py
==============================================================================
--- gocept.pagewithimage/trunk/gocept/pagewithimage/__init__.py	(original)
+++ gocept.pagewithimage/trunk/gocept/pagewithimage/__init__.py	Thu Oct 30
15:37:34 2008
(at)(at) -20,6 +20,7 (at)(at)
                     'mini'    : (200, 200),
                     'mini2'   : (200, 768),
                     'thumb'   : (128, 128),
+                    'tile2'    :  (100, 100),
                     'tile'    :  (64, 64),
                     'icon'    :  (32, 32),
                     'listing' :  (16, 16),

MailBoxer