[Checkins] SVN: Sandbox/luciano/kirbi/src/kirbi/ moved the NameChooser to app, renaming it to QuickNameChooser

Luciano Ramalho luciano at ramalho.org
Sat Aug 18 18:30:12 EDT 2007


Log message for revision 78972:
  moved the NameChooser to app, renaming it to QuickNameChooser
  start implementing collections
  

Changed:
  U   Sandbox/luciano/kirbi/src/kirbi/app.py
  U   Sandbox/luciano/kirbi/src/kirbi/copy.py
  U   Sandbox/luciano/kirbi/src/kirbi/interfaces.py
  U   Sandbox/luciano/kirbi/src/kirbi/pac.py

-=-
Modified: Sandbox/luciano/kirbi/src/kirbi/app.py
===================================================================
--- Sandbox/luciano/kirbi/src/kirbi/app.py	2007-08-18 20:43:31 UTC (rev 78971)
+++ Sandbox/luciano/kirbi/src/kirbi/app.py	2007-08-18 22:30:11 UTC (rev 78972)
@@ -18,6 +18,7 @@
 from grok import index
 from kirbi.pac import Pac
 from kirbi.book import Book
+from kirbi.collection import Collection
 from kirbi.interfaces import IUser
 from zope.interface import Interface, implements
 from zope.component import getSiteManager
@@ -36,7 +37,11 @@
 from zope import schema
 from zope.component import getUtility
 
+from zope.app.container.contained import NameChooser
+from zope.app.container.interfaces import INameChooser
+
 PAC_NAME = u'pac'
+COLLECTIONS_FOLDER_NAME = u'u'
 
 grok.define_permission('kirbi.AddCopy')
 grok.define_permission('kirbi.ManageBook')
@@ -64,6 +69,7 @@
     def __init__(self):
         super(Kirbi, self).__init__()
         self.pac = self[PAC_NAME] = Pac()
+        self.collections = self[COLLECTIONS_FOLDER_NAME] = CollectionsFolder()
 
 @grok.subscribe(Kirbi, grok.IObjectAddedEvent)
 def grant_permissions(app, event):
@@ -72,6 +78,7 @@
     role_manager.grantPermissionToRole('kirbi.ManageBook', 'kirbi.Owner')
 
 class Index(grok.View):
+    grok.context(Kirbi)
 
     def pac_url(self):
         return self.url(self.context.pac)
@@ -87,7 +94,7 @@
     isbn13 = index.Field()
     searchableText = index.Text()
 
-    creatorsSet = index.Set()
+    creatorsSet = grok.index.Set()
 
 class Master(grok.View):
     """The master page template macro."""
@@ -128,7 +135,8 @@
         #XXX: change this method to use our UserFolder and User class instead
         #     of PrincipalFolder and InternalPrincipal
         login = data['login']
-        #self.context[login] = User(**data)
+        title = data.get('name') or login # name is blank or None, use login
+        self.context.collections[login] = Collection(title)
     
         # add principal to principal folder
         pau = getUtility(IAuthentication)
@@ -141,4 +149,45 @@
         role_manager.assignRoleToPrincipal('kirbi.Owner', 
                                principals.prefix + login)
         self.redirect(self.url('login')+'?'+urlencode({'login':login}))
+        
+class CollectionsFolder(grok.Container):
+    pass
+
+class QuickNameChooser(grok.Adapter, NameChooser):
+    """INameChooser adapter to generate sequential numeric ids without
+       resorting to a linear search."""
+    grok.context(grok.Container)
+    implements(INameChooser)
+
+    def nextId(self,fmt='%s'):
+        """Binary search to quickly find an unused numbered key.
+
+        This was designed to scale well when importing large batches of books
+        without ISBN, while keeping the ids short.
+
+        The algorithm generates a key right after the largest numbered key or
+        in some unused lower numbered slot found by the second loop.
+
+        If keys are later deleted in random order, some of the resulting slots
+        will be reused and some will not.
+        """
+        i = 1
+        while fmt%i in self.context:
+            i *= 2
+        blank = i
+        full = i//2
+        while blank > (full+1):
+            i = (blank+full)//2
+            if fmt%i in self.context:
+                full = i
+            else:
+                blank = i
+        return fmt%blank
+
+    def chooseName(self, name, object):
+        name = name or self.nextId('k%04d')
+        # Note: potential concurrency problems of nextId are (hopefully)
+        # handled by calling the super.QuickNameChooser
+        return super(QuickNameChooser, self).chooseName(name, object)
+
  
\ No newline at end of file

Modified: Sandbox/luciano/kirbi/src/kirbi/copy.py
===================================================================
--- Sandbox/luciano/kirbi/src/kirbi/copy.py	2007-08-18 20:43:31 UTC (rev 78971)
+++ Sandbox/luciano/kirbi/src/kirbi/copy.py	2007-08-18 22:30:11 UTC (rev 78972)
@@ -15,22 +15,18 @@
 """
 
 import grok
-from interfaces import ICopy, ILease
+from interfaces import IItem, ILease
 from zope.interface import Interface, implements, invariant
 from zope import schema
 
-class Copy(grok.Container):
+class Item(grok.Container):
     """An exemplar of a book.
     
-    A copy is associated to a Book instance.
-    
-    A copy can contain Lease instances, recording each time it was lent.
-    When a copy is transferred or deleted, the lease history automatically
-    goes with it.
+    See note at interfaces.IItem.
     """
 
-    implements(ICopy)
+    implements(IItem)
     
-    def __init__(self, book_id):
+    def __init__(self, manifestation_id):
         super(User, self).__init__()
         

Modified: Sandbox/luciano/kirbi/src/kirbi/interfaces.py
===================================================================
--- Sandbox/luciano/kirbi/src/kirbi/interfaces.py	2007-08-18 20:43:31 UTC (rev 78971)
+++ Sandbox/luciano/kirbi/src/kirbi/interfaces.py	2007-08-18 22:30:11 UTC (rev 78972)
@@ -88,10 +88,34 @@
         if (not book.title or not book.title.strip()) and (not book.isbn):
             raise Invalid(u'Either the title or the ISBN must be given.')
 
-class ICopy(Interface):
-    """An exemplar of a book."""
+class IItem(Interface):
+    """A physical exemplar of a manifestation (book, DVD or other medium).
     
-    book_id = schema.TextLine(title=u"Book id",
+    The terms ``ìtem`` and ``manifestation`` are borrowed from the terminology
+    of the FRBR - `Functional Requirements for Bibliographic Records`__.
+    
+    __ http://www.ifla.org/VII/s13/frbr/frbr.htm
+    
+    The FRBR defines these relationships::
+    
+        work >---is realized through---> expression
+                    expression >---is embodied in---> manifestation
+                                manifestation >---is exemplified by---> item
+    
+    For example, Hamlet is a work by Shakespeare, and has many expressions:
+    the written text of the play, performances, movies etc. A particular
+    rendition of the written text is an expression. A specific edition of an
+    expression is a manifestation (commonly identified by an ISBN). An exemplar
+    of a manifestation is an item, a physical book that sits in a shelf and
+    can be borrowed.
+    
+    Currently, Kirbi supports only one kind of manifestation: books.
+    So identifiers embedded in code use the term ``manifestation`` but
+    user-visible strings use ``book`` for now.
+    
+    """
+    
+    manifestation_id = schema.TextLine(title=u"Book id",
                     description=u"The id of the book of which this is a copy.",
                     required=True)
     description = schema.Text(title=u"Description",
@@ -103,6 +127,15 @@
                     description=u"Date when added to your collection.",
                             required=False)
     
+class ICollection(Interface):
+    """A collection of Items belonging to a User"""
+    title = schema.TextLine(title=u"Title",
+             description=u"The full name of the user who owns the collection.",
+             required=True)
+    private = schema.Bool(title=u"Private",
+             description=u"If true, items will not appear in public searches.",
+             default=True)
+    
 class ILease(Interface):
     """A book lease."""
     

Modified: Sandbox/luciano/kirbi/src/kirbi/pac.py
===================================================================
--- Sandbox/luciano/kirbi/src/kirbi/pac.py	2007-08-18 20:43:31 UTC (rev 78971)
+++ Sandbox/luciano/kirbi/src/kirbi/pac.py	2007-08-18 22:30:11 UTC (rev 78972)
@@ -16,7 +16,6 @@
 
 import grok
 from book import Book, IBook
-from zope.app.container.contained import NameChooser as BaseNameChooser
 from zope.app.container.interfaces import INameChooser
 from zope.interface import implements
 from zope.lifecycleevent import modified, Attributes
@@ -213,40 +212,6 @@
     def pendingIsbns(self):
         return list(self.sortedByTime(self.context.getPending()))
 
-class NameChooser(grok.Adapter, BaseNameChooser):
-    implements(INameChooser)
-
-    def nextId(self,fmt='%s'):
-        """Binary search to quickly find an unused numbered key.
-
-        This was designed to scale well when importing large batches of books
-        without ISBN, while keeping the ids short.
-
-        The algorithm generates a key right after the largest numbered key or
-        in some unused lower numbered slot found by the second loop.
-
-        If keys are later deleted in random order, some of the resulting slots
-        will be reused and some will not.
-        """
-        i = 1
-        while fmt%i in self.context:
-            i *= 2
-        blank = i
-        full = i//2
-        while blank > (full+1):
-            i = (blank+full)//2
-            if fmt%i in self.context:
-                full = i
-            else:
-                blank = i
-        return fmt%blank
-
-    def chooseName(self, name, object):
-        name = name or self.nextId('k%04d')
-        # Note: potential concurrency problems of nextId are (hopefully)
-        # handled by calling the super.NameChooser
-        return super(NameChooser, self).chooseName(name, object)
-
 class PacRPC(grok.XMLRPC):
 
     def list(self):
@@ -262,8 +227,6 @@
     def dumpIncomplete(self):
         return self.context.dumpIncomplete()
 
-
-
 class ImportDemo(grok.View):
 
     def render(self):



More information about the Checkins mailing list