products/CPSRSS

changeset 177:9c93ad333884

implemented XML I/O for RSS channels
author div
date Tue, 24 Jan 2006 10:55:37 +0000
parents 3f425c42a81b
children c478d30a9b2f
files RSSChannel.py RSSTool.py configure.zcml exportimport.py interfaces.py
diffstat 5 files changed, 111 insertions(+), 3 deletions(-) [+]
line diff
     1.1 --- a/RSSChannel.py
     1.2 +++ b/RSSChannel.py
     1.3 @@ -39,6 +39,10 @@
     1.4  
     1.5  from Products.CPSCore.EventServiceTool import getEventService
     1.6  
     1.7 +from zope.interface import implements
     1.8 +
     1.9 +from Products.CPSRSS.interfaces import IRSSChannel
    1.10 +
    1.11  # (Ultraliberal RSS Parser) referred to as URP in this code
    1.12  # http://feedparser.org/
    1.13  # This parser is required for RSSChannel to function properly
    1.14 @@ -85,6 +89,8 @@
    1.15      Restructuring gets rid of irrelevant data.
    1.16      """
    1.17  
    1.18 +    implements(IRSSChannel)
    1.19 +    
    1.20      meta_type = RSSChannel_meta_type
    1.21      portal_type = RSSChannel_meta_type # to be able to add CMF object via ZMI
    1.22  
     2.1 --- a/RSSTool.py
     2.2 +++ b/RSSTool.py
     2.3 @@ -26,7 +26,6 @@
     2.4  
     2.5  from Products.CMFCore.permissions import View, ManagePortal
     2.6  from Products.CMFCore.utils import UniqueObject
     2.7 -from Products.CMFCore.ActionProviderBase import ActionProviderBase
     2.8  
     2.9  from RSSChannel import addRSSChannel, RSSChannel_meta_type
    2.10  
     3.1 --- a/configure.zcml
     3.2 +++ b/configure.zcml
     3.3 @@ -8,4 +8,11 @@
     3.4             Products.GenericSetup.interfaces.ISetupEnviron"
     3.5        />
     3.6  
     3.7 +  <adapter
     3.8 +      factory=".exportimport.RSSXMLAdapter"
     3.9 +      provides="Products.GenericSetup.interfaces.IBody"
    3.10 +      for=".interfaces.IRSSChannel
    3.11 +           Products.GenericSetup.interfaces.ISetupEnviron"
    3.12 +      />
    3.13 +
    3.14  </configure>
     4.1 --- a/exportimport.py
     4.2 +++ b/exportimport.py
     4.3 @@ -32,6 +32,7 @@
     4.4  
     4.5  from Products.CMFCore.utils import getToolByName
     4.6  
     4.7 +from Products.GenericSetup.interfaces import INode
     4.8  from Products.GenericSetup.interfaces import IBody
     4.9  from Products.GenericSetup.interfaces import ISetupEnviron
    4.10  
    4.11 @@ -39,7 +40,10 @@
    4.12  from Products.CPSUtil.genericsetup import getExactNodeText
    4.13  
    4.14  from Products.CPSRSS.interfaces import IRSSTool
    4.15 +from Products.CPSRSS.interfaces import IRSSChannel
    4.16  
    4.17 +from Products.CPSRSS.RSSChannel import RSSChannel_meta_type
    4.18 +from Products.CPSRSS.RSSChannel import RSSChannel
    4.19  
    4.20  TOOL = 'portal_rss'
    4.21  NAME = 'rss'
    4.22 @@ -63,6 +67,42 @@
    4.23      importObjects(tool, '', context)
    4.24  
    4.25  
    4.26 +class RSSXMLAdapter(XMLAdapterBase, PropertyManagerHelpers):
    4.27 +
    4.28 +    """XML im- and exporter for RSS feeds.
    4.29 +    """
    4.30 +
    4.31 +    adapts(IRSSChannel, ISetupEnviron)
    4.32 +    implements(IBody)
    4.33 +
    4.34 +    __used_for__ = IRSSChannel
    4.35 +
    4.36 +    _LOGGER_ID = 'rss'
    4.37 +
    4.38 +    def _exportNode(self):
    4.39 +        """Export the object as a DOM node.
    4.40 +        """
    4.41 +        node = self._getObjectNode('object')
    4.42 +        node.appendChild(self._extractProperties())
    4.43 +
    4.44 +        self._logger.info('%r rss feed exported.' % self.context.getId())
    4.45 +        return node
    4.46 +
    4.47 +    def _importNode(self, node):
    4.48 +        """Import the object from the DOM node.
    4.49 +        """
    4.50 +        if self.environ.shouldPurge():
    4.51 +            self._purgeProperties()
    4.52 +
    4.53 +        self._initProperties(node)
    4.54 +
    4.55 +        obj_id = str(node.getAttribute('name'))
    4.56 +        if not obj_id:
    4.57 +            # BBB: for CMF 1.5 profiles
    4.58 +            obj_id = str(node.getAttribute('id'))
    4.59 +        self._logger.info('%r rss feed imported.' % obj_id)
    4.60 +
    4.61 +
    4.62  class RSSToolXMLAdapter(XMLAdapterBase, ObjectManagerHelpers,
    4.63                                    PropertyManagerHelpers):
    4.64      """XML importer and exporter for RSSTool.
    4.65 @@ -87,8 +127,6 @@
    4.66      def _importNode(self, node):
    4.67          """Import the object from the DOM node.
    4.68          """
    4.69 -        self.context._p_changed = 1
    4.70 -
    4.71          if self.environ.shouldPurge():
    4.72              self._purgeProperties()
    4.73              self._purgeObjects()
    4.74 @@ -98,3 +136,58 @@
    4.75  
    4.76          self._logger.info("RSS tool imported.")
    4.77  
    4.78 +    def _initObjects(self, node):
    4.79 +        """Initialize subobjects from node children.
    4.80 +        """
    4.81 +        for child in node.childNodes:
    4.82 +            if child.nodeName != 'object':
    4.83 +                continue
    4.84 +            if child.hasAttribute('deprecated'):
    4.85 +                continue
    4.86 +            parent = self.context
    4.87 +
    4.88 +            obj_id = str(child.getAttribute('name'))
    4.89 +            if obj_id not in parent.objectIds():
    4.90 +                meta_type = str(child.getAttribute('meta_type'))
    4.91 +                if meta_type != RSSChannel_meta_type:
    4.92 +                    raise ValueError(meta_type)
    4.93 +                ob = RSSChannel(obj_id)
    4.94 +                parent._setObject(obj_id, ob)
    4.95 +                
    4.96 +            if child.hasAttribute('insert-before'):
    4.97 +                insert_before = child.getAttribute('insert-before')
    4.98 +                if insert_before == '*':
    4.99 +                    parent.moveObjectsToTop(obj_id)
   4.100 +                else:
   4.101 +                    try:
   4.102 +                        position = parent.getObjectPosition(insert_before)
   4.103 +                        parent.moveObjectToPosition(obj_id, position)
   4.104 +                    except ValueError:
   4.105 +                        pass
   4.106 +            elif child.hasAttribute('insert-after'):
   4.107 +                insert_after = child.getAttribute('insert-after')
   4.108 +                if insert_after == '*':
   4.109 +                    parent.moveObjectsToBottom(obj_id)
   4.110 +                else:
   4.111 +                    try:
   4.112 +                        position = parent.getObjectPosition(insert_after)
   4.113 +                        parent.moveObjectToPosition(obj_id, position+1)
   4.114 +                    except ValueError:
   4.115 +                        pass
   4.116 +
   4.117 +            obj = getattr(self.context, obj_id)
   4.118 +            importer = zapi.queryMultiAdapter((obj, self.environ), INode)
   4.119 +            if importer:
   4.120 +                importer.node = child
   4.121 +
   4.122 +    def _extractObjects(self):
   4.123 +        fragment = self._doc.createDocumentFragment()
   4.124 +        items = self.context.objectItems()
   4.125 +        items.sort()
   4.126 +        for id, ob in items:
   4.127 +            exporter = zapi.queryMultiAdapter((ob, self.environ), INode)
   4.128 +            if not exporter:
   4.129 +                raise ValueError("RSS Feed %s cannot be adapted to INode" % ob)
   4.130 +            child = exporter._getObjectNode('object', False)
   4.131 +            fragment.appendChild(child)
   4.132 +        return fragment
     5.1 --- a/interfaces.py
     5.2 +++ b/interfaces.py
     5.3 @@ -27,3 +27,6 @@
     5.4      """RSS Tool.
     5.5      """
     5.6  
     5.7 +class IRSSChannel(Interface):
     5.8 +    """RSS Channel.
     5.9 +    """