[Zope3-checkins] CVS: Zope3/src/zope/app/dublincore - __init__.py:1.2 annotatableadapter.py:1.2 configure.zcml:1.2 general.py:1.2 timeannotators.py:1.2 zopedublincore.py:1.2

Jim Fulton jim@zope.com
Wed, 25 Dec 2002 09:13:51 -0500


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

Added Files:
	__init__.py annotatableadapter.py configure.zcml general.py 
	timeannotators.py zopedublincore.py 
Log Message:
Grand renaming:

- Renamed most files (especially python modules) to lower case.

- Moved views and interfaces into separate hierarchies within each
  project, where each top-level directory under the zope package
  is a separate project.

- Moved everything to src from lib/python.

  lib/python will eventually go away. I need access to the cvs
  repository to make this happen, however.

There are probably some bits that are broken. All tests pass
and zope runs, but I haven't tried everything. There are a number
of cleanups I'll work on tomorrow.



=== Zope3/src/zope/app/dublincore/__init__.py 1.1 => 1.2 ===
--- /dev/null	Wed Dec 25 09:13:51 2002
+++ Zope3/src/zope/app/dublincore/__init__.py	Wed Dec 25 09:12:50 2002
@@ -0,0 +1,2 @@
+#
+# This file is necessary to make this directory a package.


=== Zope3/src/zope/app/dublincore/annotatableadapter.py 1.1 => 1.2 ===
--- /dev/null	Wed Dec 25 09:13:51 2002
+++ Zope3/src/zope/app/dublincore/annotatableadapter.py	Wed Dec 25 09:12:50 2002
@@ -0,0 +1,50 @@
+##############################################################################
+#
+# Copyright (c) 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+$Id$
+"""
+
+__metaclass__ = type
+
+from zope.component import getAdapter
+from zope.app.interfaces.annotation import IAnnotations
+from zope.app.interfaces.annotation import IAnnotatable
+from zope.app.dublincore.zopedublincore import ZopeDublinCore
+from persistence.dict import PersistentDict
+
+DCkey = "zope.app.dublincore.ZopeDublinCore"
+
+class ZDCAnnotatableAdapter(ZopeDublinCore):
+    """Adapt annotatable objects to Zope Dublin Core
+    """
+
+    __used_for__ = IAnnotatable
+
+    annotations = None
+
+    def __init__(self, context):
+        annotations = getAdapter(context, IAnnotations)
+        dcdata = annotations.get(DCkey)
+        if not dcdata:
+            self.annotations = annotations
+            dcdata = PersistentDict()
+
+        super(ZDCAnnotatableAdapter, self).__init__(dcdata)
+
+    def _changed(self):
+        if self.annotations is not None:
+            self.annotations[DCkey] = self._mapping
+            self.annotations = None
+
+__doc__ = ZDCAnnotatableAdapter.__doc__ + __doc__


=== Zope3/src/zope/app/dublincore/configure.zcml 1.1 => 1.2 ===
--- /dev/null	Wed Dec 25 09:13:51 2002
+++ Zope3/src/zope/app/dublincore/configure.zcml	Wed Dec 25 09:12:50 2002
@@ -0,0 +1,21 @@
+<zopeConfigure
+   xmlns='http://namespaces.zope.org/zope'
+   xmlns:event="http://namespaces.zope.org/event"
+>
+
+  <adapter
+      factory="zope.app.dublincore.annotatableadapter.ZDCAnnotatableAdapter"
+      provides="zope.app.interfaces.dublincore.IZopeDublinCore"
+      for="zope.app.interfaces.annotation.IAnnotatable" />
+
+  <event:subscribe 
+      subscriber = ".timeannotators.ModifiedAnnotator"
+      event_types = "zope.app.interfaces.event.IObjectModifiedEvent"
+      />
+
+  <event:subscribe 
+      subscriber = ".timeannotators.CreatedAnnotator"
+      event_types = "zope.app.interfaces.event.IObjectCreatedEvent"
+      />
+
+</zopeConfigure>


=== Zope3/src/zope/app/dublincore/general.py 1.1 => 1.2 ===
--- /dev/null	Wed Dec 25 09:13:51 2002
+++ Zope3/src/zope/app/dublincore/general.py	Wed Dec 25 09:12:50 2002
@@ -0,0 +1,209 @@
+##############################################################################
+#
+# Copyright (c) 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Interfaces for getting standard dublin core data in it's full generality
+
+$Id$
+"""
+
+from zope.interface import Interface
+from zope.schema import Text, TextLine
+
+class IDublinCoreElementItem(Interface):
+    """A qualified sublin core element"""
+
+    qualification = TextLine(title = u"Qualification",
+                         description = u"The element qualification"
+                         )
+
+    value = Text(title = u"Value",
+                 description = u"The element value",
+                 )
+
+
+class IGeneralDublinCore(Interface):
+    """Dublin-core data access interface
+
+    The Dublin Core, http://dublincore.org/, is a meta data standard
+    that specifies a set of standard data elements. It provides
+    flexibility of interpretation of these elements by providing for
+    element qualifiers that specialize the meaning of specific
+    elements. For example, a date element might have a qualifier, like
+    "creation" to indicate that the date is a creation date. In
+    addition, any element may be repeated. For some elements, like
+    subject, and contributor, this is obviously necessary, but for
+    other elements, like title and description, allowing repetitions
+    is not very useful and adds complexity.
+
+    This interface provides methods for retrieving data in full
+    generality, to be complient with the dublin core standard.
+    Other interfaces will provide more convenient access methods
+    tailored to specific element usage patterns.
+    """
+
+    def getQualifiedTitles():
+        """Return a sequence of Title IDublinCoreElementItem.
+        """
+
+    def getQualifiedCreators():
+        """Return a sequence of Creator IDublinCoreElementItem.
+        """
+
+    def getQualifiedSubjects():
+        """Return a sequence of Subject IDublinCoreElementItem.
+        """
+
+    def getQualifiedDescriptions():
+        """Return a sequence of Description IDublinCoreElementItem.
+        """
+
+    def getQualifiedPublishers():
+        """Return a sequence of Publisher IDublinCoreElementItem.
+        """
+
+    def getQualifiedContributors():
+        """Return a sequence of Contributor IDublinCoreElementItem.
+        """
+
+    def getQualifiedDates():
+        """Return a sequence of Date IDublinCoreElementItem.
+        """
+
+    def getQualifiedTypes():
+        """Return a sequence of Type IDublinCoreElementItem.
+        """
+
+    def getQualifiedFormats():
+        """Return a sequence of Format IDublinCoreElementItem.
+        """
+
+    def getQualifiedIdentifiers():
+        """Return a sequence of Identifier IDublinCoreElementItem.
+        """
+
+    def getQualifiedSources():
+        """Return a sequence of Source IDublinCoreElementItem.
+        """
+
+    def getQualifiedLanguages():
+        """Return a sequence of Language IDublinCoreElementItem.
+        """
+
+    def getQualifiedRelations():
+        """Return a sequence of Relation IDublinCoreElementItem.
+        """
+
+    def getQualifiedCoverages():
+        """Return a sequence of Coverage IDublinCoreElementItem.
+        """
+
+    def getQualifiedRights():
+        """Return a sequence of Rights IDublinCoreElementItem.
+        """
+
+class IWritableGeneralDublinCore(Interface):
+    """Provide write access to dublin core data
+
+    This interface augments IStandardDublinCore with methods for
+    writing elements.
+    """
+
+    def setQualifiedTitles(qualified_titles):
+        """Set the qualified Title elements.
+
+        The argument must be a sequence of IDublinCoreElementItem.
+        """
+
+    def setQualifiedCreators(qualified_creators):
+        """Set the qualified Creator elements.
+
+        The argument must be a sequence of Creator IDublinCoreElementItem.
+        """
+
+    def setQualifiedSubjects(qualified_subjects):
+        """Set the qualified Subjects elements.
+
+        The argument must be a sequence of Subject IDublinCoreElementItem.
+        """
+
+    def setQualifiedDescriptions(qualified_descriptions):
+        """Set the qualified Descriptions elements.
+
+        The argument must be a sequence of Description IDublinCoreElementItem.
+        """
+
+    def setQualifiedPublishers(qualified_publishers):
+        """Set the qualified Publishers elements.
+
+        The argument must be a sequence of Publisher IDublinCoreElementItem.
+        """
+
+    def setQualifiedContributors(qualified_contributors):
+        """Set the qualified Contributors elements.
+
+        The argument must be a sequence of Contributor IDublinCoreElementItem.
+        """
+
+    def setQualifiedDates(qualified_dates):
+        """Set the qualified Dates elements.
+
+        The argument must be a sequence of Date IDublinCoreElementItem.
+        """
+
+    def setQualifiedTypes(qualified_types):
+        """Set the qualified Types elements.
+
+        The argument must be a sequence of Type IDublinCoreElementItem.
+        """
+
+    def setQualifiedFormats(qualified_formats):
+        """Set the qualified Formats elements.
+
+        The argument must be a sequence of Format IDublinCoreElementItem.
+        """
+
+    def setQualifiedIdentifiers(qualified_identifiers):
+        """Set the qualified Identifiers elements.
+
+        The argument must be a sequence of Identifier IDublinCoreElementItem.
+        """
+
+    def setQualifiedSources(qualified_sources):
+        """Set the qualified Sources elements.
+
+        The argument must be a sequence of Source IDublinCoreElementItem.
+        """
+
+    def setQualifiedLanguages(qualified_languages):
+        """Set the qualified Languages elements.
+
+        The argument must be a sequence of Language IDublinCoreElementItem.
+        """
+
+    def setQualifiedRelations(qualified_relations):
+        """Set the qualified Relations elements.
+
+        The argument must be a sequence of Relation IDublinCoreElementItem.
+        """
+
+    def setQualifiedCoverages(qualified_coverages):
+        """Set the qualified Coverages elements.
+
+        The argument must be a sequence of Coverage IDublinCoreElementItem.
+        """
+
+    def setQualifiedRights(qualified_rights):
+        """Set the qualified Rights elements.
+
+        The argument must be a sequence of Rights IDublinCoreElementItem.
+        """


=== Zope3/src/zope/app/dublincore/timeannotators.py 1.1 => 1.2 ===
--- /dev/null	Wed Dec 25 09:13:51 2002
+++ Zope3/src/zope/app/dublincore/timeannotators.py	Wed Dec 25 09:12:50 2002
@@ -0,0 +1,39 @@
+##############################################################################
+#
+# Copyright (c) 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Objects that take care of annotating dublin core meta data times
+
+$Id$
+"""
+__metaclass__ = type
+
+from datetime import datetime
+from zope.component import queryAdapter
+from zope.app.interfaces.dublincore import IZopeDublinCore
+from zope.interfaces.event import ISubscriber
+
+class DCTimeAnnotatorClass:
+    """Update Dublin-Core time property
+    """
+    __implements__ = ISubscriber
+
+    def __init__(self, property):
+        self.property = property
+
+    def notify(self, event):
+        dc = queryAdapter(event.object, IZopeDublinCore)
+        if dc is not None:
+            setattr(dc, self.property, datetime.utcnow())
+
+ModifiedAnnotator = DCTimeAnnotatorClass('modified')
+CreatedAnnotator = DCTimeAnnotatorClass('created')


=== Zope3/src/zope/app/dublincore/zopedublincore.py 1.1 => 1.2 ===
--- /dev/null	Wed Dec 25 09:13:51 2002
+++ Zope3/src/zope/app/dublincore/zopedublincore.py	Wed Dec 25 09:12:50 2002
@@ -0,0 +1,359 @@
+##############################################################################
+#
+# Copyright (c) 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+$Id$
+"""
+
+__metaclass__ = type
+
+from zope.app.interfaces.dublincore import IZopeDublinCore
+from zope.app.datetimeutils import parseDatetimetz
+from datetime import datetimetz
+from datetime import datetime
+
+class SimpleProperty:
+
+    def __init__(self, name):
+        self.__name__ = name
+
+class ScalarProperty(SimpleProperty):
+
+    def __get__(self, inst, klass):
+        if inst is None:
+            return self
+        data = inst._mapping.get(self.__name__, ())
+        if data:
+            return data[0]
+        else:
+            return u''
+
+    def __set__(self, inst, value):
+        if not isinstance(value, unicode):
+            raise TypeError("Element must be unicode")
+
+        dict = inst._mapping
+        __name__ = self.__name__
+        inst._changed()
+        dict[__name__] = (value, ) + dict.get(__name__, ())[1:]
+
+def _scalar_get(inst, name):
+    data = inst._mapping.get(name, ())
+    if data:
+        return data[0]
+    else:
+        return u''
+
+class DateProperty(ScalarProperty):
+
+    def __get__(self, inst, klass):
+        if inst is None:
+            return self
+        data = inst._mapping.get(self.__name__, ())
+        if data:
+            return parseDatetimetz(data[0])
+        else:
+            return None
+
+    def __set__(self, inst, value):
+        if not isinstance(value, datetime):
+            raise TypeError("Element must be %s", datetimetz)
+
+        value = unicode(value.isoformat('T'), 'ascii')
+
+        super(DateProperty, self).__set__(inst, value)
+
+
+class SequenceProperty(SimpleProperty):
+
+    def __get__(self, inst, klass):
+        if inst is None:
+            return self
+
+        return inst._mapping.get(self.__name__, ())
+
+    def __set__(self, inst, value):
+        value = tuple(value)
+        for v in value:
+            if not isinstance(v, unicode):
+                raise TypeError("Elements must be unicode")
+        inst._changed()
+        inst._mapping[self.__name__] = value
+
+class ZopeDublinCore:
+    """Zope Dublin Core Mixin
+
+    Subclasses should define either _changed() or _p_changed.
+
+    Just mix with Persistence to get a persistent version.
+    """
+
+
+    __implements__ =  IZopeDublinCore
+
+    def __init__(self, mapping=None):
+        if mapping is None:
+            mapping = {}
+        self._mapping = mapping
+
+    def _changed(self):
+        self._p_changed = 1
+
+    title = ScalarProperty(u'Title')
+
+    def Title(self):
+        "See IZopeDublinCore"
+        return self.title
+
+    creators = SequenceProperty(u'Creator')
+
+    def Creator(self):
+        "See IZopeDublinCore"
+        return self.creators
+
+    subjects = SequenceProperty(u'Subject')
+
+    def Subject(self):
+        "See IZopeDublinCore"
+        return self.subjects
+
+    description = ScalarProperty(u'Description')
+
+    def Description(self):
+        "See IZopeDublinCore"
+        return self.description
+
+    publisher = ScalarProperty(u'Publisher')
+
+    def Publisher(self):
+        "See IZopeDublinCore"
+        return self.publisher
+
+    contributors = SequenceProperty(u'Contributor')
+
+    def Contributors(self):
+        "See IZopeDublinCore"
+        return self.contributors
+
+    def Date(self):
+        "See IZopeDublinCore"
+        return _scalar_get(self, u'Date')
+
+    created = DateProperty(u'Date.Created')
+
+    def CreationDate(self):
+        "See IZopeDublinCore"
+        return _scalar_get(self, u'Date.Created')
+
+    effective = DateProperty(u'Date.Effective')
+
+    def EffectiveDate(self):
+        "See IZopeDublinCore"
+        return _scalar_get(self, u'Date.Effective')
+
+    expires = DateProperty(u'Date.Expires')
+
+    def ExpirationDate(self):
+        "See IZopeDublinCore"
+        return _scalar_get(self, u'Date.Expires')
+
+    modified = DateProperty(u'Date.Modified')
+
+    def ModificationDate(self):
+        "See IZopeDublinCore"
+        return _scalar_get(self, u'Date.Modified')
+
+    type = ScalarProperty(u'Type')
+
+    def Type(self):
+        "See IZopeDublinCore"
+        # XXX what is this?
+        return self.type
+
+    format = ScalarProperty(u'Format')
+
+    def Format(self):
+        "See IZopeDublinCore"
+        # XXX what is this?
+        return self.format
+
+    identifier = ScalarProperty(u'Identifier')
+
+    def Identifier(self):
+        "See IZopeDublinCore"
+        # XXX what is this?
+        return self.identifier
+
+    language = ScalarProperty(u'Language')
+
+    def Language(self):
+        "See IZopeDublinCore"
+        return self.language
+
+    rights = ScalarProperty(u'Rights')
+
+    def Rights(self):
+        "See IZopeDublinCore"
+        return self.rights
+
+    def setQualifiedTitles(self, qualified_titles):
+        "See IWritableDublinCore"
+        return _set_qualified(self, u'Title', qualified_titles)
+
+    def setQualifiedCreators(self, qualified_creators):
+        "See IWritableDublinCore"
+        return _set_qualified(self, u'Creator', qualified_creators)
+
+    def setQualifiedSubjects(self, qualified_subjects):
+        "See IWritableDublinCore"
+        return _set_qualified(self, u'Subject', qualified_subjects)
+
+    def setQualifiedDescriptions(self, qualified_descriptions):
+        "See IWritableDublinCore"
+        return _set_qualified(self, u'Description', qualified_descriptions)
+
+    def setQualifiedPublishers(self, qualified_publishers):
+        "See IWritableDublinCore"
+        return _set_qualified(self, u'Publisher', qualified_publishers)
+
+    def setQualifiedContributors(self, qualified_contributors):
+        "See IWritableDublinCore"
+        return _set_qualified(self, u'Contributor', qualified_contributors)
+
+    def setQualifiedDates(self, qualified_dates):
+        "See IWritableDublinCore"
+        return _set_qualified(self, u'Date', qualified_dates)
+
+    def setQualifiedTypes(self, qualified_types):
+        "See IWritableDublinCore"
+        return _set_qualified(self, u'Type', qualified_types)
+
+    def setQualifiedFormats(self, qualified_formats):
+        "See IWritableDublinCore"
+        return _set_qualified(self, u'Format', qualified_formats)
+
+    def setQualifiedIdentifiers(self, qualified_identifiers):
+        "See IWritableDublinCore"
+        return _set_qualified(self, u'Identifier', qualified_identifiers)
+
+    def setQualifiedSources(self, qualified_sources):
+        "See IWritableDublinCore"
+        return _set_qualified(self, u'Source', qualified_sources)
+
+    def setQualifiedLanguages(self, qualified_languages):
+        "See IWritableDublinCore"
+        return _set_qualified(self, u'Language', qualified_languages)
+
+    def setQualifiedRelations(self, qualified_relations):
+        "See IWritableDublinCore"
+        return _set_qualified(self, u'Relation', qualified_relations)
+
+    def setQualifiedCoverages(self, qualified_coverages):
+        "See IWritableDublinCore"
+        return _set_qualified(self, u'Coverage', qualified_coverages)
+
+    def setQualifiedRights(self, qualified_rights):
+        "See IWritableDublinCore"
+        return _set_qualified(self, u'Rights', qualified_rights)
+
+    def getQualifiedTitles(self):
+        "See IStandardDublinCore"
+        return _get_qualified(self, u'Title')
+
+    def getQualifiedCreators(self):
+        "See IStandardDublinCore"
+        return _get_qualified(self, u'Creator')
+
+    def getQualifiedSubjects(self):
+        "See IStandardDublinCore"
+        return _get_qualified(self, u'Subject')
+
+    def getQualifiedDescriptions(self):
+        "See IStandardDublinCore"
+        return _get_qualified(self, u'Description')
+
+    def getQualifiedPublishers(self):
+        "See IStandardDublinCore"
+        return _get_qualified(self, u'Publisher')
+
+    def getQualifiedContributors(self):
+        "See IStandardDublinCore"
+        return _get_qualified(self, u'Contributor')
+
+    def getQualifiedDates(self):
+        "See IStandardDublinCore"
+        return _get_qualified(self, u'Date')
+
+    def getQualifiedTypes(self):
+        "See IStandardDublinCore"
+        return _get_qualified(self, u'Type')
+
+    def getQualifiedFormats(self):
+        "See IStandardDublinCore"
+        return _get_qualified(self, u'Format')
+
+    def getQualifiedIdentifiers(self):
+        "See IStandardDublinCore"
+        return _get_qualified(self, u'Identifier')
+
+    def getQualifiedSources(self):
+        "See IStandardDublinCore"
+        return _get_qualified(self, u'Source')
+
+    def getQualifiedLanguages(self):
+        "See IStandardDublinCore"
+        return _get_qualified(self, u'Language')
+
+    def getQualifiedRelations(self):
+        "See IStandardDublinCore"
+        return _get_qualified(self, u'Relation')
+
+    def getQualifiedCoverages(self):
+        "See IStandardDublinCore"
+        return _get_qualified(self, u'Coverage')
+
+    def getQualifiedRights(self):
+        "See IStandardDublinCore"
+        return _get_qualified(self, u'Rights')
+
+
+def _set_qualified(self, name, qvalue):
+    data = {}
+    dict = self._mapping
+
+    for qualification, value in qvalue:
+        data[qualification] = data.get(qualification, ()) + (value, )
+
+    self._changed()
+    for qualification, values in data.iteritems():
+        qname = qualification and (name + '.' + qualification) or name
+        dict[qname] = values
+
+def _get_qualified(self, name):
+    result = []
+    for aname, avalue in self._mapping.iteritems():
+
+        if aname == name:
+            qualification = u''
+            for value in avalue:
+                result.append((qualification, value))
+
+        elif aname.startswith(name):
+            qualification = aname[len(name)+1:]
+            for value in avalue:
+                result.append((qualification, value))
+
+    return tuple(result)
+
+
+__doc__ = ZopeDublinCore.__doc__ + __doc__