def _update_syndication_info(portal): # now, go through all containers and look for syndication_info # objects from Products.CMFPlone.interfaces.syndication import IFeedSettings from Products.CMFPlone.interfaces.syndication import ISyndicatable catalog = getToolByName(portal, 'portal_catalog') # get all folder types from portal_types at_tool = getToolByName(portal, 'archetype_tool', None) folder_types = set([]) if at_tool is not None: for _type in at_tool.listPortalTypesWithInterfaces([ISyndicatable]): folder_types.add(_type.getId()) folder_types = folder_types | _getDexterityFolderTypes(portal) for brain in catalog(portal_type=tuple(folder_types)): try: obj = brain.getObject() except (AttributeError, KeyError): continue if 'syndication_information' not in obj.objectIds(): return # just having syndication info object means # syndication is enabled info = obj.syndication_information try: settings = IFeedSettings(obj) except TypeError: continue settings.enabled = True try: settings.max_items = info.max_items except AttributeError: pass settings.feed_types = ('RSS',) obj.manage_delObjects(['syndication_information'])
def enable_syndication(event_listing_block, event=None): """ Enables syndication on the given event listing block. This must be called from a subscriber when an event listing block is created so the syndication is enabled by default on the event listing blocks. """ settings = IFeedSettings(event_listing_block) settings.enabled = True settings.feed_types = ('RSS', 'rss.xml', 'atom.xml')
def enable_rss2(context): """ Enable the new-style RSS2 feed #14323 """ portal = getToolByName(context, 'portal_url').getPortalObject() catalog = getToolByName(portal, 'portal_catalog') at_tool = getToolByName(portal, 'archetype_tool') logger.info('Enabling new RSS2') registry = getUtility(IRegistry) synd_settings = registry.forInterface(ISiteSyndicationSettings) custom_rss2 = u'RSS2|RSS 2.0 EEA' current_allowed = synd_settings.allowed_feed_types if custom_rss2 not in current_allowed: new_allowed = current_allowed + (custom_rss2, ) new_allowed = tuple(unicode(x) for x in new_allowed) synd_settings.allowed_feed_types = new_allowed logger.info('Adding RSS2 to allowed views') folder_types = set([]) for _type in at_tool.listPortalTypesWithInterfaces([ISyndicatable]): folder_types.add(_type.getId()) folder_types = folder_types index = 0 for brain in catalog(portal_type=tuple(folder_types), Language='all'): obj = brain.getObject() try: settings = IFeedSettings(obj) except TypeError: continue if settings.enabled: current_feeds = list(settings.feed_types) if u'RSS2' in current_feeds: continue new_feeds = [u'RSS2'] current_feeds.extend(new_feeds) settings.feed_types = tuple(set(current_feeds)) message = 'Enabling RSS2 for %s' % brain.getURL() logger.info(message) if index % 100 == 0: transaction.commit() logger.info('Transaction commited') index += 1 logger.info('Done enable RSS2')
def enable_rss2(context): """ Enable the new-style RSS2 feed #14323 """ portal = getToolByName(context, 'portal_url').getPortalObject() catalog = getToolByName(portal, 'portal_catalog') at_tool = getToolByName(portal, 'archetype_tool') logger.info('Enabling new RSS2') registry = getUtility(IRegistry) synd_settings = registry.forInterface(ISiteSyndicationSettings) custom_rss2 = u'RSS2|RSS 2.0 EEA' current_allowed = synd_settings.allowed_feed_types if custom_rss2 not in current_allowed: new_allowed = current_allowed + (custom_rss2, ) new_allowed = tuple(unicode(x) for x in new_allowed) synd_settings.allowed_feed_types = new_allowed logger.info('Adding RSS2 to allowed views') folder_types = set([]) for _type in at_tool.listPortalTypesWithInterfaces([ISyndicatable]): folder_types.add(_type.getId()) folder_types = folder_types index = 0 for brain in catalog(portal_type=tuple(folder_types), Language='all'): obj = brain.getObject() try: settings = IFeedSettings(obj) except TypeError: continue if settings.enabled: current_feeds = list(settings.feed_types) if u'RSS2' in current_feeds: continue new_feeds = [u'RSS2'] current_feeds.extend(new_feeds) settings.feed_types = tuple(set(current_feeds)) message = 'Enabling RSS2 for %s' % brain.getURL() logger.info(message) if index % 100 == 0: transaction.commit() logger.info('Transaction commited') index += 1 logger.info('Done enable RSS2')
def test_feeds(self): # Use a browser to log into the portal: admin = testbrowser.Browser() admin.handleErrors = False portal_url = self.portal.absolute_url() admin.open(portal_url) admin.getLink('Log in').click() admin.getControl(name='__ac_name').value = ptc.portal_owner admin.getControl(name='__ac_password').value = ptc.default_password admin.getControl('Log in').click() # Create a folder to act as the blog: admin.getLink(id='folder').click() admin.getControl(name='title').value = 'A Blog' admin.getControl(name='form.button.save').click() # Publish it: admin.getLink(id='workflow-transition-publish').click() # Save this url for easy access later: blog_url = admin.url # In the folder, create four content types, a Document, a News Item, # a File and an Event: admin.getLink(id='document').click() admin.getControl(name='title').value = 'A Document Blog Entry' admin.getControl(name='text').value = 'The main body of the Document' admin.getControl(name='form.button.save').click() admin.getLink(id='workflow-transition-publish').click() admin.open(blog_url) admin.getLink(id='news-item').click() admin.getControl(name='title').value = 'A News Item Blog Entry' admin.getControl(name='text').value = 'The main body of the News Item' testfile = os.path.join(os.path.dirname(__file__), 'testlogo.jpg') thefile = admin.getControl(name='image_file') thefile.filename = 'testlogo.jpg' thefile.value = open(testfile, 'rb') admin.getControl(name='form.button.save').click() admin.getLink(id='workflow-transition-publish').click() admin.open(blog_url) admin.getLink(id='file').click() admin.getControl(name='title').value = 'A File Blog Entry' testfile = os.path.join(os.path.dirname(__file__), 'testaudio.mp3') thefile = admin.getControl(name='file_file') thefile.filename = 'testaudio.mp3' thefile.value = open(testfile, 'rb') admin.getControl(name='form.button.save').click() admin.open(blog_url) admin.getLink(id='event').click() admin.getControl(name='title').value = 'An Event Blog Entry' admin.getControl(name='text').value = 'The main body of the Event' admin.getControl(name='form.button.save').click() admin.getLink(id='workflow-transition-publish').click() # Set up the Plone 4.3 syndication: if PLONE43: admin.open(portal_url + '/@@syndication-settings') form = admin.getForm(id='form') form.getControl(name='form.widgets.default_enabled:list').value = ['selected'] form.getControl(name='form.widgets.show_syndication_button:list').value = ['selected'] form.getControl(name='form.buttons.save').click() # And on the folder: # This can't be done through the test-browser, because the form apparently # *required* javascript. Hey ho. feed_settings = IFeedSettings(self.portal['a-blog']) feed_settings.render_body = True feed_settings.feed_types = ('rss.xml', 'RSS', 'atom.xml', 'itunes.xml') ############################# ## Now, make sure things work ############################# # First, check that the feeds are listed in the header: anon = testbrowser.Browser() anon.handleErrors = False anon.open(blog_url) # Atom and RSS are the only ones that are there both for # Fatsyndication and Plone 4.3, so we test for them. # (itunes exist as well, but is off by default). self.assert_('atom.xml' in anon.contents) self.assert_('rss.xml' in anon.contents) self.assert_('itunes.xml' in anon.contents) # Now check that the correct info is in the feeds. We'll assume that # basesyndication/fatsyndication is not broken, and check only atom.xml. # (because in fact, rss.xml *is* broken in Plone 4.3). anon.open(blog_url+'/atom.xml') # The document: self.assert_('The main body of the Document' in anon.contents) # The news item with image: self.assert_('The main body of the News Item' in anon.contents) self.assert_('/image' in anon.contents) # The file: self.assert_('<link rel="enclosure" length="16486" href="' in anon.contents) if not PLONE43: # But *not* the event, as it has no feed adapter. self.assert_('The main body of the Event' not in anon.contents) else: # But in 4.3 it does self.assert_('The main body of the Event' in anon.contents)
def upgradeSyndication(context): from zope.component import getUtility, getSiteManager from plone.registry.interfaces import IRegistry from Products.CMFCore.interfaces import ISyndicationTool from Products.CMFPlone.interfaces.syndication import ISyndicatable from Products.CMFPlone.interfaces.syndication import ( ISiteSyndicationSettings, IFeedSettings) portal = getToolByName(context, 'portal_url').getPortalObject() def getDexterityFolderTypes(): try: from plone.dexterity.interfaces import IDexterityFTI from plone.dexterity.utils import resolveDottedName except ImportError: return set([]) portal_types = getToolByName(portal, 'portal_types') types = [ fti for fti in portal_types.listTypeInfo() if IDexterityFTI.providedBy(fti) ] ftypes = set([]) for _type in types: klass = resolveDottedName(_type.klass) if ISyndicatable.implementedBy(klass): ftypes.add(_type.getId()) return ftypes logger.info('Migrating syndication tool') registry = getUtility(IRegistry) synd_settings = registry.forInterface(ISiteSyndicationSettings) # default settings work fine here if all settings are not # available try: old_synd_tool = portal.portal_syndication try: synd_settings.allowed = old_synd_tool.isAllowed except AttributeError: pass try: synd_settings.max_items = old_synd_tool.max_items except AttributeError: pass portal.manage_delObjects(['portal_syndication']) except AttributeError: pass sm = getSiteManager() sm.unregisterUtility(provided=ISyndicationTool) # now, go through all containers and look for syndication_info # objects catalog = getToolByName(portal, 'portal_catalog') # get all folder types from portal_types at_tool = getToolByName(portal, 'archetype_tool') folder_types = set([]) for _type in at_tool.listPortalTypesWithInterfaces([ISyndicatable]): folder_types.add(_type.getId()) folder_types = folder_types | getDexterityFolderTypes() for brain in catalog(portal_type=tuple(folder_types)): try: obj = brain.getObject() except (AttributeError, KeyError): continue if 'syndication_information' in obj.objectIds(): # just having syndication info object means # syndication is enabled info = obj.syndication_information try: settings = IFeedSettings(obj) except TypeError: continue settings.enabled = True try: settings.max_items = info.max_items except AttributeError: pass settings.feed_types = ('RSS', ) obj.manage_delObjects(['syndication_information'])
def upgradeSyndication(context): from zope.component import getUtility, getSiteManager from plone.registry.interfaces import IRegistry from Products.CMFCore.interfaces import ISyndicationTool from Products.CMFPlone.interfaces.syndication import ISyndicatable from Products.CMFPlone.interfaces.syndication import ( ISiteSyndicationSettings, IFeedSettings) portal = getToolByName(context, 'portal_url').getPortalObject() def getDexterityFolderTypes(): try: from plone.dexterity.interfaces import IDexterityFTI from plone.dexterity.utils import resolveDottedName except ImportError: return set([]) portal_types = getToolByName(portal, 'portal_types') types = [fti for fti in portal_types.listTypeInfo() if IDexterityFTI.providedBy(fti)] ftypes = set([]) for _type in types: klass = resolveDottedName(_type.klass) if ISyndicatable.implementedBy(klass): ftypes.add(_type.getId()) return ftypes logger.info('Migrating syndication tool') registry = getUtility(IRegistry) synd_settings = registry.forInterface(ISiteSyndicationSettings) # default settings work fine here if all settings are not # available try: old_synd_tool = portal.portal_syndication try: synd_settings.allowed = old_synd_tool.isAllowed except AttributeError: pass try: synd_settings.max_items = old_synd_tool.max_items except AttributeError: pass portal.manage_delObjects(['portal_syndication']) except AttributeError: pass sm = getSiteManager() sm.unregisterUtility(provided=ISyndicationTool) # now, go through all containers and look for syndication_info # objects catalog = getToolByName(portal, 'portal_catalog') # get all folder types from portal_types at_tool = getToolByName(portal, 'archetype_tool') folder_types = set([]) for _type in at_tool.listPortalTypesWithInterfaces([ISyndicatable]): folder_types.add(_type.getId()) folder_types = folder_types | getDexterityFolderTypes() for brain in catalog(portal_type=tuple(folder_types)): try: obj = brain.getObject() except (AttributeError, KeyError): continue if 'syndication_information' in obj.objectIds(): # just having syndication info object means # syndication is enabled info = obj.syndication_information try: settings = IFeedSettings(obj) except TypeError: continue settings.enabled = True try: settings.max_items = info.max_items except AttributeError: pass settings.feed_types = ('RSS',) obj.manage_delObjects(['syndication_information'])