[z3-checkins] r28696 - z3/bdbxml/trunk/xmlsite

paul at codespeak.net paul at codespeak.net
Mon Jun 12 10:32:28 CEST 2006


Author: paul
Date: Mon Jun 12 10:32:22 2006
New Revision: 28696

Removed:
   z3/bdbxml/trunk/xmlsite/xmlpage.py
Modified:
   z3/bdbxml/trunk/xmlsite/__init__.py
   z3/bdbxml/trunk/xmlsite/configure.zcml
   z3/bdbxml/trunk/xmlsite/interfaces.py
   z3/bdbxml/trunk/xmlsite/xmldbcontainer.py
Log:
Refactored into parts that use Zope 3 (__init__.py) and parts that do not (xmldbcontainer.py)

Modified: z3/bdbxml/trunk/xmlsite/__init__.py
==============================================================================
--- z3/bdbxml/trunk/xmlsite/__init__.py	(original)
+++ z3/bdbxml/trunk/xmlsite/__init__.py	Mon Jun 12 10:32:22 2006
@@ -1 +1,139 @@
-# Make a Python package
+"""
+Publish content from an XML DB.
+
+This package makes a Berkeley DB XML database into a Zope 3 folder/site. URLs turn into XQuery statements
+that calculate results and retrieve documents. The documents are then converted into XHTML and a theme is
+applied.
+
+This __init__.py module provides all the Zope-specific wiring. The other modules can be run from the command
+line or via the doctests.
+
+"""
+
+from zope.app.container.contained import Contained
+from zope.component import getUtility
+from zope.component.interfaces import IFactory
+from zope.interface import implementedBy, implements
+
+from xmldbcontainer import BDBXMLContainer, openDatabase
+from interfaces import IXMLSite, IXMLPage, IBDBXMLConnection
+
+
+class BDBXMLConnectionFactory:
+    implements(IFactory)
+    title = u"Re-use BDBXML Managers and Containers across requests"
+    description = u"This utility keeps a connection open to the xml db."
+    
+    def __init__(self):
+        fn = "var/samplesite.dbxml"
+        self.environment, self.mgr, self.container = openDatabase(fn, True)
+    
+    def __call__(self):
+        return BDBXMLConnection(self.environment, self.mgr, self.container)
+        
+    def getInterfaces(self):
+        return implementedBy(BDBXMLConnection)
+
+
+class BDBXMLConnection(BDBXMLContainer):
+    implements(IBDBXMLConnection)
+
+
+class XMLSite(Contained):
+    """A very simple implementation of an xmlsite using Berkeley DB XML.
+    """
+    
+    implements(IXMLSite)
+
+    description = u''
+    docname = u"Some Document Here"
+
+    def getConnection(self):
+        bdbxml_factory = getUtility(IFactory, u"xmlsite.BDBXMLConnection")
+        connection = bdbxml_factory()
+        return connection
+
+    def keys(self):
+        '''See interface `IReadContainer`'''
+        connection = self.getConnection()
+        return connection.listDocumentIDs()
+
+    def __iter__(self):
+        connection = self.getConnection()
+        return iter(connection.getAllDocuments())
+
+    def __getitem__(self, key):
+        '''See interface `IReadContainer`'''
+
+        connection = self.getConnection()
+        xmlstring = connection.getDocument(key)
+
+        page = XMLPage()
+        page.__parent__ = self
+        page.__name__ = key
+        page.init(xmlstring)
+        return page                
+
+    def get(self, key, default=None):
+        '''See interface `IReadContainer`'''
+        
+        return self.__getitem__(key)
+
+    def values(self):
+        '''See interface `IReadContainer`'''
+        connection = self.getConnection()
+        return connection.getAllDocuments().values()
+
+    def __len__(self):
+        '''See interface `IReadContainer`'''
+        connection = self.getConnection()
+        return connection.countDocuments()
+
+    def items(self):
+        '''See interface `IReadContainer`'''
+        connection = self.getConnection()
+        return connection.getAllDocuments().items()
+
+    def __contains__(self, key):
+        '''See interface `IReadContainer`'''
+        
+        # TODO: Make a bettery XQuery than this brute force
+        connection = self.getConnection()        
+        return connection.getAllDocuments().has_key(key)
+
+    has_key = __contains__
+
+    def __setitem__(self, key, object):
+        '''See interface `IWriteContainer`'''
+        x127
+        setitem(self, self.__data.__setitem__, key, object)
+
+    def __delitem__(self, key):
+        '''See interface `IWriteContainer`'''
+        
+        x128
+        uncontained(self.__data[key], self, key)
+        del self.__data[key]
+
+
+class XMLPage(Contained):
+    """Simple representation of a page to return to the publisher."""
+
+    implements(IXMLPage)
+    xmlstring = u"<h1>Default from the class...</h1>"
+
+    def init(self, xmlstring):
+        self.xmlstring = xmlstring
+
+    def __call__(self):
+        response = self.context.xmlstring
+        return '<html><body><big>%s</big></body></html>' % response
+
+
+def main():
+    
+    xmlsite = XMLSite()
+    connection = xmlsite.getConnection()
+    connection.listDocumentIDs()
+
+if __name__ == "__main__": main()
\ No newline at end of file

Modified: z3/bdbxml/trunk/xmlsite/configure.zcml
==============================================================================
--- z3/bdbxml/trunk/xmlsite/configure.zcml	(original)
+++ z3/bdbxml/trunk/xmlsite/configure.zcml	Mon Jun 12 10:32:22 2006
@@ -7,12 +7,12 @@
       type="zope.app.content.interfaces.IContentType"
       /> 
 
-  <content class="xmlsite.xmldbcontainer.XMLSite">
+  <content class="xmlsite.XMLSite">
     <implements
         interface="zope.app.container.interfaces.IContentContainer" 
         />
     <factory
-        id="xmlsite.xmldbcontainer.XMLSite"
+        id="xmlsite.XMLSite"
         description="XML Site" 
         />
     <require
@@ -29,7 +29,7 @@
 	     />
   </content>
 
-	<content class="xmlsite.xmlpage.XMLPage">
+	<content class="xmlsite.XMLPage">
 	 <require
 	     permission="zope.Public"
 	     attributes="xmlstring"
@@ -40,13 +40,13 @@
     label="Add XML Site"
     name="AddXMLSite.html"
     schema="xmlsite.interfaces.IXMLSite"
-    content_factory="xmlsite.xmldbcontainer.XMLSite"
+    content_factory="xmlsite.XMLSite"
     fields="description"
     permission="zope.ManageContent"
     />
 
 <browser:addMenuItem
-    class="xmlsite.xmldbcontainer.XMLSite"
+    class="xmlsite.XMLSite"
     title="XML Site"
     description="A container that gets content from an XML database"
     permission="zope.ManageContent"
@@ -70,7 +70,7 @@
     />
 
 <utility
-	factory="xmlsite.xmldbcontainer.BDBXMLConnectionFactory"
+	factory="xmlsite.BDBXMLConnectionFactory"
 	name="xmlsite.BDBXMLConnection"
 	permission="zope.Public"
 	/>
@@ -78,7 +78,7 @@
   <browser:page
     	for="xmlsite.interfaces.IXMLPage"
     	name="index.html"
-  		class=".xmlpage.XMLPage"
+  		class=".XMLPage"
   		permission="zope.Public"
   		/>
 

Modified: z3/bdbxml/trunk/xmlsite/interfaces.py
==============================================================================
--- z3/bdbxml/trunk/xmlsite/interfaces.py	(original)
+++ z3/bdbxml/trunk/xmlsite/interfaces.py	Mon Jun 12 10:32:22 2006
@@ -12,6 +12,7 @@
         default=u"",
         required=False)
 
+
 class IXMLPage(IContained):
     """Take an XML document from DBXML and make a component"""
 
@@ -21,6 +22,7 @@
         default=u"",
         required=False)
 
+
 class IBDBXMLConnection(Interface):
-    """Fake stuff"""
+    """Marker for the factory"""
 

Modified: z3/bdbxml/trunk/xmlsite/xmldbcontainer.py
==============================================================================
--- z3/bdbxml/trunk/xmlsite/xmldbcontainer.py	(original)
+++ z3/bdbxml/trunk/xmlsite/xmldbcontainer.py	Mon Jun 12 10:32:22 2006
@@ -1,37 +1,43 @@
-from zope.app.container.contained import Contained
+"""
+Provide a mapping-like interface to a Berkeley DB XML database.
 
-from xmlpage import XMLPage
-from interfaces import IXMLSite, IBDBXMLConnection
-from bsddb3 import *
-from dbxml import *
+"""
 
-from zope.component import getUtility
-from zope.component.interfaces import IFactory
-from zope.interface import implementedBy, implements
+import os
+from bsddb3 import db
+from dbxml import *
 
+def openDatabase(fullfilename, makeDefaultContent=True):
+    """Open a bdbxml container and return a manager and container."""
 
-class BDBXMLConnectionFactory:
-    implements(IFactory)
-    title = u"Re-use database connections"
-    description = u"This factory instantiates"
-    
-    def __init__(self):
-        fn = "var/stuff.dbxml"
-        self.mgr = XmlManager()
-        self.container = self.mgr.openContainer(fn)
-    	self.container.addAlias("content")        
+    # TODO: Get more resilient way to grab an INSTANCE_HOME's var
+    sitedir = os.path.dirname(fullfilename)
+    dirname = os.path.join(sitedir, "sampledata")
+    os.chdir(sitedir)
+    containername = "samplesite.dbxml"
+
+    # Make a transactional connection to the database
+    environment = db.DBEnv()
+    environment.open(None, db.DB_CREATE|db.DB_INIT_LOCK|db.DB_INIT_LOG|db.DB_INIT_MPOOL|db.DB_INIT_TXN, 0)
+    mgr = XmlManager(environment, 0)
     
-    def __call__(self):
-        return BDBXMLConnection(self.mgr, self.container)
-        
-    def getInterfaces(self):
-        return implementedBy(BDBXMLConnection)
+    if not os.path.exists(containername):
+        # Load some content using the function below
+        container = mgr.createContainer(containername, DBXML_TRANSACTIONAL)
+        container.addAlias("content")        
+        if makeDefaultContent:
+            loadSampleContent(environment, mgr, container)
+    else:
+        # Database exists
+        container = mgr.openContainer(containername, DBXML_TRANSACTIONAL)
+        container.addAlias("content")        
 
+    return environment, mgr, container
 
-class BDBXMLConnection(object):
-    implements(IBDBXMLConnection)
+class BDBXMLContainer(object):
 
-    def __init__(self, mgr, container):
+    def __init__(self, environment, mgr, container):
+        self.environment = environment
         self.mgr = mgr
         self.container = container
         
@@ -74,86 +80,31 @@
 
         return data
 
-class XMLSite(Contained):
-    """A very simple implementation of an xmlsite using Berkeley DB XML.
-    """
+def loadSampleContent(environment, mgr, container):
+    """Utility function to bulk load some data"""
     
-    implements(IXMLSite)
-
-    description = u''
-    docname = u"Some Document Here"
+    sitedir = "/Users/paul/sandboxes/z3/bdbxml/trunk/examples/site1"
+    dirname = os.path.join(sitedir, "sampledata")
 
-    def getConnection(self):
-        bdbxml_factory = getUtility(IFactory, u"xmlsite.BDBXMLConnection")
-        connection = bdbxml_factory()
-        return connection
-
-    def keys(self):
-        '''See interface `IReadContainer`'''
-        connection = self.getConnection()
-        return connection.listDocumentIDs()
-
-    def __iter__(self):
-        connection = self.getConnection()
-        return iter(connection.getAllDocuments())
-
-    def __getitem__(self, key):
-        '''See interface `IReadContainer`'''
-
-        connection = self.getConnection()
-        xmlstring = connection.getDocument(key)
-
-        page = XMLPage()
-        page.__parent__ = self
-        page.__name__ = key
-        page.init(xmlstring)
-        return page                
+    uc = mgr.createUpdateContext()
 
-    def get(self, key, default=None):
-        '''See interface `IReadContainer`'''
-        
-        return self.__getitem__(key)
+    for fn in os.listdir(dirname):
+        if fn[-4:] != ".xml":
+            continue
+        fullfn = os.path.join(dirname, fn)
+        xtxn = mgr.createTransaction();
+        document = mgr.createDocument()
+        doc_content = open(fullfn).read()
+        document.setContent(doc_content)
+        document.setName(fn)
+        container.putDocument(xtxn, document, uc)
+        xtxn.commit()        
+        del document
 
-    def values(self):
-        '''See interface `IReadContainer`'''
-        connection = self.getConnection()
-        return connection.getAllDocuments().values()
-
-    def __len__(self):
-        '''See interface `IReadContainer`'''
-        connection = self.getConnection()
-        return connection.countDocuments()
-
-    def items(self):
-        '''See interface `IReadContainer`'''
-        connection = self.getConnection()
-        return connection.getAllDocuments().items()
-
-    def __contains__(self, key):
-        '''See interface `IReadContainer`'''
-        
-        # TODO: Make a bettery XQuery than this brute force
-        connection = self.getConnection()        
-        return connection.getAllDocuments().has_key(key)
-
-    has_key = __contains__
-
-    def __setitem__(self, key, object):
-        '''See interface `IWriteContainer`'''
-        x127
-        setitem(self, self.__data.__setitem__, key, object)
-
-    def __delitem__(self, key):
-        '''See interface `IWriteContainer`'''
-        
-        x128
-        uncontained(self.__data[key], self, key)
-        del self.__data[key]
+    return
 
 def main():
+    containername = "../examples/site1/var/samplesite.dbxml"
+    environment, mgr, container = openDatabase(containername, True)
     
-    xmlsite = XMLSite()
-    connection = xmlsite.getConnection()
-    connection.listDocumentIDs()
-
 if __name__ == "__main__": main()
\ No newline at end of file

Deleted: /z3/bdbxml/trunk/xmlsite/xmlpage.py
==============================================================================
--- /z3/bdbxml/trunk/xmlsite/xmlpage.py	Mon Jun 12 10:32:22 2006
+++ (empty file)
@@ -1,22 +0,0 @@
-"""
-Simple representation of a page to return to the publisher.
-
-"""
-
-from zope.app.container.contained import Contained
-from interfaces import IXMLPage
-from zope.interface import implements
-
-
-class XMLPage(Contained):
-
-    implements(IXMLPage)
-    xmlstring = u"<h1>Default from the class...</h1>"
-
-    def init(self, xmlstring):
-        self.xmlstring = xmlstring
-        
-    def __call__(self):
-        response = self.context.xmlstring
-        return '<html><body><big>%s</big></body></html>' % response
-


More information about the z3-checkins mailing list