From 49c2298233986d1f0bdbaa990aa477d09b683a03 Mon Sep 17 00:00:00 2001 From: Benjamin Port Date: Wed, 2 Apr 2014 16:14:38 +0200 Subject: [PATCH] Add lang-tag feeds generation. This new functionnality allow user to generate feeds for a specified tag and a specified language. The most traditional use case is for country based/international planet subscription. --- docs/settings.rst | 8 ++++++++ pelican/generators.py | 26 ++++++++++++++++++++++++++ pelican/tests/test_generators.py | 21 +++++++++++++++++++-- 3 files changed, 53 insertions(+), 2 deletions(-) diff --git a/docs/settings.rst b/docs/settings.rst index 0c16db3c..f5fe1ef7 100644 --- a/docs/settings.rst +++ b/docs/settings.rst @@ -594,6 +594,14 @@ Setting name (default value) What does it do? `DEFAULT_LANG` (``'en'``) The default language to use. `TRANSLATION_FEED_ATOM` ('feeds/all-%s.atom.xml'[3]_) Where to put the Atom feed for translations. `TRANSLATION_FEED_RSS` (``None``, i.e. no RSS) Where to put the RSS feed for translations. +`LANG_TAG_FEED_ATOM` (``None``, i.e. no Atom feed) Where to put the Atom feed for a given lang and a + given tag. For example: + ``'feeds/%(lang)s-%(tag)s.atom.xml'`` +`LANG_TAG_FEED_RSS` (``None``, i.e. no RSS)` Where to put the RSS feed for a given lang and a + given tag. +`LANG_TAG_FEED_FILTER` (``None``, i.e. no filter Allow to filter which lang and tag you want + to generate. You need to use tuple list. + For example: ``{('fr, 'myTag'), (en, myTag)}`` ===================================================== ===================================================== .. [3] %s is the language diff --git a/pelican/generators.py b/pelican/generators.py index bfdac1a5..c4053bbe 100644 --- a/pelican/generators.py +++ b/pelican/generators.py @@ -266,6 +266,32 @@ class ArticlesGenerator(Generator): self.settings['TRANSLATION_FEED_RSS'] % lang, feed_type='rss') + if (self.settings.get('LANG_TAG_FEED_ATOM') + or self.settings.get('LANG_TAG_FEED_RSS')): + translations_tag_feeds = defaultdict(list) + all_articles = list(self.articles) + for article in self.articles: + all_articles.extend(article.translations) + all_articles.sort(key=attrgetter('date'), reverse=True) + + lang_tag_feeds = defaultdict(list) + for article in all_articles: + if hasattr(article, 'tags'): + for tag in article.tags: + lang_tag_feeds[(article.lang, tag.slug)].append(article) + if self.settings.get('LANG_TAG_FEED_FILTER'): + lt_filter = self.settings['LANG_TAG_FEED_FILTER'] + for lang_tag, items in lang_tag_feeds.items(): + if lang_tag not in lt_filter: + continue + items.sort(key=attrgetter('date'), reverse=True) + if self.settings.get('LANG_TAG_FEED_ATOM'): + writer.write_feed(items, self.context, + self.settings['LANG_TAG_FEED_ATOM'] % {"lang": lang_tag[0], "tag": lang_tag[1]}) + if self.settings.get('LANG_TAG_FEED_RSS'): + writer.write_feed(items, self.context, + self.settings['LANG_TAG_FEED_RSS'] % {"lang": lang_tag[0], "tag": lang_tag[1]}, feed_type='rss') + def generate_articles(self, write): """Generate the articles.""" for article in chain(self.translations, self.articles): diff --git a/pelican/tests/test_generators.py b/pelican/tests/test_generators.py index 6f13aeb6..1b47bbd1 100644 --- a/pelican/tests/test_generators.py +++ b/pelican/tests/test_generators.py @@ -4,9 +4,9 @@ from __future__ import unicode_literals import os from codecs import open try: - from unittest.mock import MagicMock + from unittest.mock import MagicMock, ANY except ImportError: - from mock import MagicMock + from mock import MagicMock, ANY from shutil import rmtree from tempfile import mkdtemp @@ -268,6 +268,23 @@ class TestArticlesGenerator(unittest.TestCase): authors_expected = ['alexis-metaireau', 'first-author', 'second-author'] self.assertEqual(sorted(authors), sorted(authors_expected)) + def test_generate_lang_tag_feeds(self): + settings = get_settings(filenames={}) + settings['LANG_TAG_FEED_FILTER'] = {('en', 'bar'), } + settings['LANG_TAG_FEED_ATOM'] = 'feeds/%(lang)s-%(tag)s.atom.xml' + settings['FEED_ALL_ATOM'] = None + settings['TRANSLATION_FEED_ATOM'] = None + settings['CATEGORY_FEED_ATOM'] = None + + generator = ArticlesGenerator( + context=settings, settings=settings, + path=CONTENT_DIR, theme=settings['THEME'], output_path=None) + generator.generate_context() + writer = MagicMock() + generator.generate_feeds(writer) + writer.write_feed.assert_called_with(ANY, ANY, + 'feeds/en-bar.atom.xml') + class TestPageGenerator(unittest.TestCase): # Note: Every time you want to test for a new field; Make sure the test