1: from zope.formlib import form
1: from zope.interface import implements
1: from zope import schema
1: from plone.app.portlets.portlets.rss import RSSFeed
1: from Products.Five.browser.pagetemplatefile import ZopeTwoPageTemplateFile
1: from plone.portlets.interfaces import IPortletDataProvider
1: from plone.app.portlets.portlets import base
1: from vnccollab.theme import messageFactory as _
2: class ISpecialRSSPortlet(IPortletDataProvider):
1: header = schema.TextLine(
1: title=_(u"Header"),
1: description=_(u"Header of the portlet."),
1: required=True,
1: default=u'New in the Cloud')
1: source = schema.List(
1: title=_(u"RSS Sources"),
1: description=u'Please select links that point to RSS feeds',
1: required=True,
1: value_type=schema.Choice(
1: vocabulary='vnccollab.theme.vocabularies.ATLinkVocabulary',))
1: count = schema.Int(title=_(u'Number of items to display'),
1: description=_(u'How many items to list.'),
1: required=True,
1: default=5)
1: timeout = schema.Int(title=_(u'Feed reload timeout'),
1: description=_(u'Time in minutes for the feeds should be reloaded.'),
1: required=True,
1: default=15)
2: class Assignment(base.Assignment):
1: implements(ISpecialRSSPortlet)
1: header = u'New in the Cloud'
1: source = []
1: count = 5
1: timeout = 15
1: @property
def title(self):
"""Return portlet header"""
>>>>>> return self.header
1: def __init__(self, header=u'New in the Cloud', source=[],
1: count=5, timeout=15):
>>>>>> self.header = header
>>>>>> self.source = source
>>>>>> self.count = count
>>>>>> self.timeout = timeout
2: class Renderer(base.DeferredRenderer):
# This is an adaptation of plone.app.portlets.portlets.rss.Renderer
# modified to handle several feeds
1: render = ZopeTwoPageTemplateFile('templates/special_rss.pt')
1: MAX_SUMMARY_LEN = 80
1: @property
def initializing(self):
"""should return True if deferred template should be displayed"""
>>>>>> if any([not x.loaded for x in self.feeds]):
>>>>>> return True
>>>>>> if any([x.needs_update for x in self.feeds]):
>>>>>> return True
>>>>>> return False
1: def deferred_update(self):
"""refresh data for serving via KSS"""
>>>>>> for feed in self.data.feeds:
>>>>>> feed.update()
1: def update(self):
"""update data before rendering. We can not wait for KSS since users
may not be using KSS."""
>>>>>> self.feeds = []
>>>>>> for link in self.data.source:
>>>>>> rss = RSSFeed(link.remote_url(), self.data.timeout)
>>>>>> rss.id = link.id
>>>>>> self.feeds.append(rss)
>>>>>> self.deferred_update()
1: def items(self, feed):
"""Return postprocessed items"""
>>>>>> return (self.sanitize(item) for item in feed.items[:self.data.count])
1: def sanitize(self, item):
"""return a news feed item sanitized."""
>>>>>> new = dict(**item)
# Convert HTML to plain text.
# We won't use portal_transforms due to potential problems with
# encoding on the summary text.
>>>>>> s = MLStripper()
>>>>>> s.feed(new['summary'])
>>>>>> summary = s.get_data()
>>>>>> if len(summary) > self.MAX_SUMMARY_LEN:
>>>>>> summary = summary[:self.MAX_SUMMARY_LEN] + '...'
>>>>>> new['summary'] = summary
>>>>>> return new
2: class AddForm(base.AddForm):
1: form_fields = form.Fields(ISpecialRSSPortlet)
1: label = _(u"Add Special RSS portlet")
1: description = _(u"A portlet displaying multiple RSS sources.")
1: def create(self, data):
>>>>>> return Assignment(**data)
2: class EditForm(base.EditForm):
1: form_fields = form.Fields(ISpecialRSSPortlet)
1: label = _(u"Edit Special RSS portlet")
1: description = _(u"A portlet displaying multiple RSS sources.")
1: from HTMLParser import HTMLParser
2: class MLStripper(HTMLParser):
1: '''Support class to convert HTML to ASCII'''
1: def __init__(self):
>>>>>> self.reset()
>>>>>> self.fed = []
1: def handle_data(self, d):
>>>>>> self.fed.append(d)
1: def get_data(self):
>>>>>> return ''.join(self.fed)