# HG changeset patch # User Mads Kiilerich # Date 1576787013 -3600 # Node ID 68e802950fe486e6235ac7b43ef6fb67de39f433 # Parent dfd528520236f85d6c88af34b605ba581a3ab18f feeds: introduce kallithea.lib.feeds to encapsulate webhelpers.feedgenerator diff -r dfd528520236 -r 68e802950fe4 kallithea/controllers/feed.py --- a/kallithea/controllers/feed.py Sat Dec 07 04:20:58 2019 +0100 +++ b/kallithea/controllers/feed.py Thu Dec 19 21:23:33 2019 +0100 @@ -32,9 +32,9 @@ from tg import response from tg import tmpl_context as c from tg.i18n import ugettext as _ -from webhelpers.feedgenerator import Atom1Feed, Rss201rev2Feed from kallithea import CONFIG +from kallithea.lib import feeds from kallithea.lib import helpers as h from kallithea.lib.auth import HasRepoPermissionLevelDecorator, LoginRequired from kallithea.lib.base import BaseRepoController @@ -45,10 +45,6 @@ log = logging.getLogger(__name__) -language = 'en-us' -ttl = "5" - - class FeedController(BaseRepoController): @LoginRequired(allow_default_user=True) @@ -102,39 +98,37 @@ desc_msg.append('') return [safe_unicode(chunk) for chunk in desc_msg] - def _feed(self, repo_name, kind, feed_factory): + def _feed(self, repo_name, feeder): """Produce a simple feed""" @cache_region('long_term', '_get_feed_from_cache') def _get_feed_from_cache(*_cache_keys): # parameters are not really used - only as caching key - feed = feed_factory( + header = dict( title=_('%s %s feed') % (c.site_name, repo_name), link=h.canonical_url('summary_home', repo_name=repo_name), description=_('Changes on %s repository') % repo_name, - language=language, - ttl=ttl, # rss only ) rss_items_per_page = safe_int(CONFIG.get('rss_items_per_page', 20)) + entries=[] for cs in reversed(list(c.db_repo_scm_instance[-rss_items_per_page:])): - feed.add_item(title=self._get_title(cs), - link=h.canonical_url('changeset_home', repo_name=repo_name, - revision=cs.raw_id), - author_email=cs.author_email, - author_name=cs.author_name, - description=''.join(self.__get_desc(cs)), - pubdate=cs.date, - ) + entries.append(dict( + title=self._get_title(cs), + link=h.canonical_url('changeset_home', repo_name=repo_name, revision=cs.raw_id), + author_email=cs.author_email, + author_name=cs.author_name, + description=''.join(self.__get_desc(cs)), + pubdate=cs.date, + )) + return feeder.render(header, entries) - response.content_type = feed.mime_type - return feed.writeString('utf-8') - - return _get_feed_from_cache(repo_name, kind, c.db_repo.changeset_cache.get('raw_id')) + response.content_type = feeder.content_type + return _get_feed_from_cache(repo_name, feeder.__name__) def atom(self, repo_name): """Produce a simple atom-1.0 feed""" - return self._feed(repo_name, 'ATOM', Atom1Feed) + return self._feed(repo_name, feeds.AtomFeed) def rss(self, repo_name): - """Produce an rss2 feed via feedgenerator module""" - return self._feed(repo_name, 'RSS', Rss201rev2Feed) + """Produce a simple rss2 feed""" + return self._feed(repo_name, feeds.RssFeed) diff -r dfd528520236 -r 68e802950fe4 kallithea/controllers/journal.py --- a/kallithea/controllers/journal.py Sat Dec 07 04:20:58 2019 +0100 +++ b/kallithea/controllers/journal.py Thu Dec 19 21:23:33 2019 +0100 @@ -23,7 +23,6 @@ :author: marcink :copyright: (c) 2013 RhodeCode GmbH, and others. :license: GPLv3, see LICENSE.md for more details. - """ import logging @@ -35,11 +34,11 @@ from tg import request, response from tg import tmpl_context as c from tg.i18n import ugettext as _ -from webhelpers.feedgenerator import Atom1Feed, Rss201rev2Feed from webob.exc import HTTPBadRequest import kallithea.lib.helpers as h from kallithea.controllers.admin.admin import _journal_filter +from kallithea.lib import feeds from kallithea.lib.auth import LoginRequired from kallithea.lib.base import BaseController, render from kallithea.lib.page import Page @@ -104,17 +103,17 @@ return journal - def _feed(self, repos, feed_factory, link, desc): + def _feed(self, repos, feeder, link, desc): + response.content_type = feeder.content_type journal = self._get_journal_data(repos) - feed = feed_factory( + header = dict( title=desc, link=link, description=desc, - language=language, - ttl=ttl, ) + entries=[] for entry in journal[:feed_nr]: user = entry.user if user is None: @@ -130,15 +129,16 @@ _url = h.canonical_url('changelog_home', repo_name=entry.repository.repo_name) - feed.add_item(title=title, - pubdate=entry.action_date, - link=_url or h.canonical_url(''), - author_email=user.email, - author_name=user.full_name_or_username, - description=action_extra()) + entries.append(dict( + title=title, + pubdate=entry.action_date, + link=_url or h.canonical_url(''), + author_email=user.email, + author_name=user.full_name_or_username, + description=action_extra(), + )) - response.content_type = feed.mime_type - return feed.writeString('utf-8') + return feeder.render(header, entries) def _atom_feed(self, repos, public=True): if public: @@ -149,7 +149,7 @@ link = h.canonical_url('journal_atom') desc = '%s %s %s' % (c.site_name, _('Journal'), 'atom feed') - return self._feed(repos, Atom1Feed, link, desc) + return self._feed(repos, feeds.AtomFeed, link, desc) def _rss_feed(self, repos, public=True): if public: @@ -160,7 +160,7 @@ link = h.canonical_url('journal_atom') desc = '%s %s %s' % (c.site_name, _('Journal'), 'rss feed') - return self._feed(repos, Rss201rev2Feed, link, desc) + return self._feed(repos, feeds.RssFeed, link, desc) @LoginRequired() def index(self): @@ -192,9 +192,7 @@ @LoginRequired() def journal_atom(self): - """ - Produce an atom-1.0 feed via feedgenerator module - """ + """Produce a simple atom-1.0 feed""" following = UserFollowing.query() \ .filter(UserFollowing.user_id == request.authuser.user_id) \ .options(joinedload(UserFollowing.follows_repository)) \ @@ -203,9 +201,7 @@ @LoginRequired() def journal_rss(self): - """ - Produce an rss feed via feedgenerator module - """ + """Produce a simple rss2 feed""" following = UserFollowing.query() \ .filter(UserFollowing.user_id == request.authuser.user_id) \ .options(joinedload(UserFollowing.follows_repository)) \ @@ -261,9 +257,7 @@ @LoginRequired(allow_default_user=True) def public_journal_atom(self): - """ - Produce an atom-1.0 feed via feedgenerator module - """ + """Produce a simple atom-1.0 feed""" c.following = UserFollowing.query() \ .filter(UserFollowing.user_id == request.authuser.user_id) \ .options(joinedload(UserFollowing.follows_repository)) \ @@ -273,9 +267,7 @@ @LoginRequired(allow_default_user=True) def public_journal_rss(self): - """ - Produce an rss2 feed via feedgenerator module - """ + """Produce a simple rss2 feed""" c.following = UserFollowing.query() \ .filter(UserFollowing.user_id == request.authuser.user_id) \ .options(joinedload(UserFollowing.follows_repository)) \ diff -r dfd528520236 -r 68e802950fe4 kallithea/lib/feeds.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kallithea/lib/feeds.py Thu Dec 19 21:23:33 2019 +0100 @@ -0,0 +1,59 @@ +# -*- coding: utf-8 -*- +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +""" +kallithea.lib.feeds +~~~~~~~~~~~~~~~~~~~ + +Shared code for providing RSS and ATOM feeds. +""" + +import datetime +import re + +from webhelpers import feedgenerator + + +language = 'en-us' +ttl = "5" + +class _Feeder(object): + + content_type = None + feed_factory = None # a webhelpers.feedgenerator + + @classmethod + def render(cls, header, entries): + feed = cls.feed_factory( + language=language, + ttl=ttl, # rss only + **header + ) + for e in entries: + feed.add_item(**e) + return feed.writeString('utf-8') + + +class AtomFeed(_Feeder): + + content_type = 'application/atom+xml' + + feed_factory = feedgenerator.Atom1Feed + + +class RssFeed(_Feeder): + + content_type = 'application/rss+xml' + + feed_factory = feedgenerator.Rss201rev2Feed