diff --git a/feedgen/ext/syndication.py b/feedgen/ext/syndication.py new file mode 100644 index 0000000..3b17e0c --- /dev/null +++ b/feedgen/ext/syndication.py @@ -0,0 +1,60 @@ +# -*- coding: utf-8 -*- +# +# Copyright 2015 Kenichi Sato +# + +''' +Extends FeedGenerator to support Syndication module + +See below for details +http://web.resource.org/rss/1.0/modules/syndication/ +''' + +from lxml import etree +from feedgen.ext.base import BaseExtension + +SYNDICATION_NS = 'http://purl.org/rss/1.0/modules/syndication/' +PERIOD_TYPE = ('hourly', 'daily', 'weekly', 'monthly', 'yearly') + + +def _set_value(channel, name, value): + if value: + newelem = etree.SubElement(channel, '{%s}' % SYNDICATION_NS + name) + newelem.text = value + + +class SyndicationExtension(BaseExtension): + def __init__(self): + self._update_period = None + self._update_freq = None + self._update_base = None + + def extend_ns(self): + return {'sy': SYNDICATION_NS} + + def extend_rss(self, rss_feed): + channel = rss_feed[0] + _set_value(channel, 'UpdatePeriod', self._update_period) + _set_value(channel, 'UpdateFrequency', str(self._update_freq)) + _set_value(channel, 'UpdateBase', self._update_base) + + def update_period(self, value): + if value not in PERIOD_TYPE: + raise ValueError('Invalid update period value') + self._update_period = value + return self._update_period + + def update_frequency(self, value): + if type(value) is not int or value <= 0: + raise ValueError('Invalid update frequency value') + self._update_freq = value + return self._update_freq + + def update_base(self, value): + # the value should be in W3CDTF format + self._update_base = value + return self._update_base + + +class SyndicationEntryExtension(BaseExtension): + pass diff --git a/feedgen/tests/test_extension.py b/feedgen/tests/test_extension.py index e69de29..53333b7 100644 --- a/feedgen/tests/test_extension.py +++ b/feedgen/tests/test_extension.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- + +""" +Tests for extensions +""" + +import unittest +from ..feed import FeedGenerator +from lxml import etree + + +class TestExtensionSyndication(unittest.TestCase): + + def setUp(self): + self.fg = FeedGenerator() + self.fg.load_extension('syndication') + self.fg.title('title') + self.fg.link(href='http://example.com', rel='self') + self.fg.description('description') + + def test_update_period(self): + for period_type in ('hourly', 'daily', 'weekly', + 'monthly', 'yearly'): + self.fg.syndication.update_period(period_type) + root = etree.fromstring(self.fg.rss_str()) + a = root.xpath('/rss/channel/sy:UpdatePeriod', + namespaces={ + 'sy':'http://purl.org/rss/1.0/modules/syndication/' + }) + assert a[0].text == period_type + + def test_update_frequency(self): + for frequency in (1, 100, 2000, 100000): + self.fg.syndication.update_frequency(frequency) + root = etree.fromstring(self.fg.rss_str()) + a = root.xpath('/rss/channel/sy:UpdateFrequency', + namespaces={ + 'sy':'http://purl.org/rss/1.0/modules/syndication/' + }) + assert a[0].text == str(frequency) + + def test_update_base(self): + base = '2000-01-01T12:00+00:00' + self.fg.syndication.update_base(base) + root = etree.fromstring(self.fg.rss_str()) + a = root.xpath('/rss/channel/sy:UpdateBase', + namespaces={ + 'sy':'http://purl.org/rss/1.0/modules/syndication/' + }) + assert a[0].text == base