[Zope3-checkins] CVS: Zope3/src/zope/app/fssync - committer.py:1.21 syncer.py:1.32

Fred L. Drake, Jr. fred at zope.com
Tue Jan 13 17:29:17 EST 2004


Update of /cvs-repository/Zope3/src/zope/app/fssync
In directory cvs.zope.org:/tmp/cvs-serv16405/src/zope/app/fssync

Modified Files:
	committer.py syncer.py 
Log Message:
- move the fssync "Syner" and serialization adapter interfaces into
  the zope.fssync.server package

- remove annotations() from IObjectEntry, implementations
  (should be near-free since these should not used anymore)

- make the syncer, checker, committer parameterizable with three
  functions that operate on content objects:
  - get the serialization adapter
  - get the annotations adapter
  - get the object identifier


=== Zope3/src/zope/app/fssync/committer.py 1.20 => 1.21 ===
--- Zope3/src/zope/app/fssync/committer.py:1.20	Tue Jan 13 14:32:20 2004
+++ Zope3/src/zope/app/fssync/committer.py	Tue Jan 13 17:28:46 2004
@@ -46,13 +46,20 @@
     The public API consists of __init__(), check() and errors() only.
     """
 
-    def __init__(self, metadata=None, raise_on_conflicts=False):
+    def __init__(self,
+                 getSerializer,
+                 metadata=None,
+                 raise_on_conflicts=False,
+                 getAnnotations=lambda obj: None,
+                 ):
         """Constructor.  Optionally pass a metadata database."""
         if metadata is None:
             metadata = Metadata()
         self.metadata = metadata
         self.raise_on_conflicts = raise_on_conflicts
         self.conflicts = []
+        self.getSerializer = getSerializer
+        self.getAnnotations = getAnnotations
 
     def errors(self):
         """Return a list of errors (conflicts).
@@ -115,19 +122,19 @@
             except:
                 pass
             else:
-                adapter = get_adapter(obj)
+                adapter = self.getSerializer(obj)
                 extra = adapter.extra()
                 extrapath = fsutil.getextra(fspath)
                 if extra is not None and os.path.exists(extrapath):
                     self.check_dir(extra, extrapath)
-                ann = adapter.annotations()
+                ann = self.getAnnotations(obj)
                 annpath = fsutil.getannotations(fspath)
                 if ann is not None and os.path.exists(annpath):
                     self.check_dir(ann, annpath)
 
     def check_dir(self, container, fspath):
         """Helper to check a directory."""
-        adapter = get_adapter(container)
+        adapter = self.getSerializer(container)
         nameset = {}
         if IObjectDirectory.isImplementedBy(adapter):
             for name, obj in adapter.contents():
@@ -172,7 +179,7 @@
             if not os.path.exists(fspath):
                 self.conflict(fspath)
         obj = traverseName(container, name)
-        adapter = get_adapter(obj)
+        adapter = self.getSerializer(obj)
         if IObjectDirectory.isImplementedBy(adapter):
             if flag != "removed" or os.path.exists(fspath):
                 self.check_dir(obj, fspath)
@@ -198,8 +205,11 @@
     The public API consists of __init__() and synch() only.
     """
 
-    def __init__(self, metadata=None):
+    def __init__(self, getSerializer, metadata=None,
+                 getAnnotations=lambda obj: None):
         """Constructor.  Optionally pass a metadata database."""
+        self.getSerializer = getSerializer
+        self.getAnnotations = getAnnotations
         if metadata is None:
             metadata = Metadata()
         self.metadata = metadata
@@ -239,19 +249,19 @@
             except:
                 pass
             else:
-                adapter = get_adapter(obj)
+                adapter = self.getSerializer(obj)
                 extra = adapter.extra()
                 extrapath = fsutil.getextra(fspath)
                 if extra is not None and os.path.exists(extrapath):
                     self.synch_dir(extra, extrapath)
-                ann = adapter.annotations()
+                ann = self.getAnnotations(obj)
                 annpath = fsutil.getannotations(fspath)
                 if ann is not None and os.path.exists(annpath):
                     self.synch_dir(ann, annpath)
 
     def synch_dir(self, container, fspath):
         """Helper to synchronize a directory."""
-        adapter = get_adapter(container)
+        adapter = self.getSerializer(container)
         nameset = {} # name --> absolute path
         if IObjectDirectory.isImplementedBy(adapter):
             for name, obj in adapter.contents():
@@ -282,9 +292,9 @@
         """Helper to synchronize a new object."""
         entry = self.metadata.getentry(fspath)
         if entry:
-            create_object(container, name, entry, fspath)
+            self.create_object(container, name, entry, fspath)
             obj = traverseName(container, name)
-            adapter = get_adapter(obj)
+            adapter = self.getSerializer(obj)
             if IObjectDirectory.isImplementedBy(adapter):
                 self.synch_dir(obj, fspath)
 
@@ -298,12 +308,13 @@
             # This object was not included on the filesystem; skip it
             return
         obj = traverseName(container, name)
-        adapter = get_adapter(obj)
+        adapter = self.getSerializer(obj)
         if IObjectDirectory.isImplementedBy(adapter):
             self.synch_dir(obj, fspath)
         else:
             if adapter.typeIdentifier() != entry.get("type"):
-                create_object(container, name, entry, fspath, replace=True)
+                self.create_object(container, name, entry, fspath,
+                                   replace=True)
             else:
                 original_fn = fsutil.getoriginal(fspath)
                 if os.path.exists(original_fn):
@@ -320,7 +331,8 @@
                 if newdata != olddata:
                     if not entry.get("factory"):
                         # If there's no factory, we can't call setBody()
-                        create_object(container, name, entry, fspath, True)
+                        self.create_object(container, name, entry, fspath,
+                                           True)
                         obj = traverseName(container, name)
                     else:
                         adapter.setBody(newdata)
@@ -334,61 +346,61 @@
                     else:
                         publish(obj, ObjectModifiedEvent(obj))
 
-# Functions below this point are all helpers and not part of the
-# API offered by this module.  They can be functions because they
-# don't use the metadata database or add to the list of conflicts.
-
-def create_object(container, name, entry, fspath, replace=False):
-    """Helper to create an item in a container or mapping."""
-    factory_name = entry.get("factory")
-    if factory_name:
-        # A given factory overrides everything
-        factory = resolve(factory_name)
-        obj = factory()
-        obj = contained(obj, container, name=name)
-        adapter = get_adapter(obj)
-        if IObjectFile.isImplementedBy(adapter):
-            data = read_file(fspath)
-            adapter.setBody(data)
-    else:
-        # No factory; try using IFileFactory or IDirectoryFactory
-        as = getService(container, "Adapters")
-        isuffix = name.rfind(".")
-        if isuffix >= 0:
-            suffix = name[isuffix:]
+    def create_object(self, container, name, entry, fspath, replace=False):
+        """Helper to create an item in a container or mapping."""
+        factory_name = entry.get("factory")
+        if factory_name:
+            # A given factory overrides everything
+            factory = resolve(factory_name)
+            obj = factory()
+            obj = contained(obj, container, name=name)
+            adapter = self.getSerializer(obj)
+            if IObjectFile.isImplementedBy(adapter):
+                data = read_file(fspath)
+                adapter.setBody(data)
         else:
-            suffix = "."
+            # No factory; try using IFileFactory or IDirectoryFactory
+            as = getService(container, "Adapters")
+            isuffix = name.rfind(".")
+            if isuffix >= 0:
+                suffix = name[isuffix:]
+            else:
+                suffix = "."
 
-        if os.path.isdir(fspath):
-            iface = IDirectoryFactory
-        else:
-            iface = IFileFactory
+            if os.path.isdir(fspath):
+                iface = IDirectoryFactory
+            else:
+                iface = IFileFactory
 
-        factory = as.queryNamedAdapter(container, iface, suffix)
-        if factory is None:
-            factory = as.queryAdapter(container, iface)
-
-        if iface is IDirectoryFactory:
-            if factory:
-                obj = factory(name)
-                obj = removeAllProxies(obj)
-            else:
-                raise SynchronizationError(
-                    "don't know how to create a directory",
-                    container,
-                    name)
-        else:
-            if factory:
-                data = read_file(fspath)
-                obj = factory(name, None, data)
-                obj = removeAllProxies(obj)
+            factory = as.queryNamedAdapter(container, iface, suffix)
+            if factory is None:
+                factory = as.queryAdapter(container, iface)
+
+            if iface is IDirectoryFactory:
+                if factory:
+                    obj = factory(name)
+                    obj = removeAllProxies(obj)
+                else:
+                    raise SynchronizationError(
+                        "don't know how to create a directory",
+                        container,
+                        name)
             else:
-                # The file must contain an xml pickle, or we can't load it:
-                s = read_file(fspath)
-                s = fromxml(s)
-                obj = fspickle.loads(s, container)
+                if factory:
+                    data = read_file(fspath)
+                    obj = factory(name, None, data)
+                    obj = removeAllProxies(obj)
+                else:
+                    # The file must contain an xml pickle, or we can't load it:
+                    s = read_file(fspath)
+                    s = fromxml(s)
+                    obj = fspickle.loads(s, container)
 
-    set_item(container, name, obj, replace)
+        set_item(container, name, obj, replace)
+
+# Functions below this point are all helpers and not part of the
+# API offered by this module.  They can be functions because they
+# don't use the metadata database or add to the list of conflicts.
 
 def set_item(container, name, obj, replace=False):
     """Helper to set an item in a container or mapping."""
@@ -412,8 +424,3 @@
     finally:
         f.close()
     return data
-
-def get_adapter(obj):
-    """Helper to get the special fssync adapter."""
-    syncService = getService(obj, 'FSRegistryService')
-    return syncService.getSynchronizer(obj)


=== Zope3/src/zope/app/fssync/syncer.py 1.31 => 1.32 ===
--- Zope3/src/zope/app/fssync/syncer.py:1.31	Tue Jan 13 14:32:20 2004
+++ Zope3/src/zope/app/fssync/syncer.py	Tue Jan 13 17:28:46 2004
@@ -16,125 +16,24 @@
 $Id$
 """
 
-import os
-
-from zope.component import getService
-from zope.fssync import metadata
-from zope.fssync.server.interfaces import IObjectDirectory, IObjectFile
+from zope.component import getService, queryAdapter
+from zope.fssync.server.syncer import Syncer
 
+from zope.app.interfaces.annotation import IAnnotations
 from zope.app.traversing import getPath
 
 
-def writeFile(data, path, mode="wb"):
-    f = open(path, mode)
-    try:
-        f.write(data)
-    finally:
-        f.close()
-
-
-class Syncer:
-
-    def __init__(self):
-        self._metadata = metadata.Metadata()
-
-    def toFS(self, ob, name, location):
-        """Check an object out to the file system
-
-        ob -- The object to be checked out
-
-        name -- The name of the object
-
-        location -- The directory on the file system where the object will go
-        """
-
-        # Get name path and check that name is not an absolute path
-        path = os.path.join(location, name)
-        if path == name:
-            raise ValueError("Invalid absolute path name")
-
-        mdmanager = self._metadata.getmanager(location)
-
-        # Look for location admin dir
-        if not os.path.exists(mdmanager.zdir):
-            os.mkdir(mdmanager.zdir)
-
-        self.dumpTree(ob, name, path, mdmanager)
-
-    def dumpTree(self, ob, name, path, mdmanager):
-        entry = mdmanager.getentry(name)
-
-        # Get the object adapter
-        syncService = getService(ob, 'FSRegistryService')
-        adapter = syncService.getSynchronizer(ob)
-
-        entry.clear()
-        entry['type'] = adapter.typeIdentifier()
-        entry['factory'] = adapter.factory()
-
-        try:
-            objectPath = str(getPath(ob))
-        except (TypeError, KeyError):
-            # this case can be triggered for persistent objects that don't
-            # have a name in the content space (annotations, extras)
-            pass
-        else:
-            entry['path'] = objectPath
-
-        # Write entries file
-        mdmanager.flush()
-
-        # Handle extras
-        extra = adapter.extra()
-        if extra:
-            extra_dir, mdextra = self.createManagedDirectory(
-                mdmanager.zdir, 'Extra', name)
-            for ename in extra:
-                # @@Zope/Extra/<name>/<ename>
-                edata = extra[ename]
-                self.dumpTree(edata,
-                              ename,
-                              os.path.join(extra_dir, ename),
-                              mdextra)
-
-        # Handle annotations
-        annotations = adapter.annotations()
-        if annotations is not None:
-            annotation_dir, mdannotations = self.createManagedDirectory(
-                mdmanager.zdir, 'Annotations', name)
-            for key in annotations:
-                # @@Zope/Annotations/<name>/<key>
-                annotation = annotations[key]
-                self.dumpTree(annotation,
-                              key,
-                              os.path.join(annotation_dir, key),
-                              mdannotations)
-
-        # Handle data
-        if IObjectFile.isImplementedBy(adapter):
-            # File
-            assert not IObjectDirectory.isImplementedBy(adapter)
-            writeFile(adapter.getBody(), path)
-        else:
-            # Directory
-            assert IObjectDirectory.isImplementedBy(adapter)
-            if not os.path.exists(path):
-                os.mkdir(path)
-            mdmanager = self._metadata.getmanager(path)
-            mdmanager.ensure()
-
-            for cname, cob in adapter.contents():
-                cpath = os.path.join(path, cname)
-                self.dumpTree(cob, cname, cpath, mdmanager)
-
-    def createManagedDirectory(self, base, *parts):
-        dir = base
-        for p in parts:
-            dir = os.path.join(dir, p)
-            if not os.path.exists(dir):
-                os.mkdir(dir)
-        return dir, self._metadata.getmanager(dir)
+def getObjectId(obj):
+    return str(getPath(obj))
+
+def getSerializer(obj):
+    syncService = getService(obj, 'FSRegistryService')
+    return syncService.getSynchronizer(obj)
+
+def getAnnotations(obj):
+    return queryAdapter(obj, IAnnotations)
 
 
-def toFS(ob, name, location):
-    Syncer().toFS(ob, name, location)
+def toFS(obj, name, location):
+    syncer = Syncer(getObjectId, getSynchronizer, getAnnotations)
+    return syncer.toFS(obj, name, location)




More information about the Zope3-Checkins mailing list