Source code for distro_tracker.core.news_feed

# Copyright 2013-2018 The Distro Tracker Developers
# See the COPYRIGHT file at the top-level directory of this distribution and
# at https://deb.li/DTAuthors
#
# This file is part of Distro Tracker. It is subject to the license terms
# in the LICENSE file found in the top-level directory of this
# distribution and at https://deb.li/DTLicense. No part of Distro Tracker,
# including this file, may be copied, modified, propagated, or distributed
# except according to the terms contained in the LICENSE file.
"""Implements the RSS news feed."""

import re
from itertools import chain

from django.conf import settings
from django.contrib.syndication.views import Feed
from django.http import Http404

from distro_tracker.core.models import (
    ActionItem,
    News,
    NewsRenderer,
    get_web_package
)


[docs]def filter_control_chars(method): """Filter out undesirable control characters.""" # We have to filter out control chars otherwise the FeedGenerator # raises UnserializableContentError (see django/utils/xmlutils.py) def wrapped(self, obj): result = method(self, obj) return re.sub(r'[\x00-\x08\x0B-\x0C\x0E-\x1F]', '', result) return wrapped
[docs]class PackageNewsFeed(Feed): _DEFAULT_LIMIT = 30
[docs] def get_object(self, request, package_name): package = get_web_package(package_name) if package is None: raise Http404 return package
[docs] @filter_control_chars def title(self, obj): return "{vendor} package news for {pkg}".format( vendor=settings.DISTRO_TRACKER_VENDOR_NAME, pkg=obj.name)
[docs] @filter_control_chars def description(self, obj): return ( "Latest developer's news for {vendor} source package {pkg}" .format(vendor=settings.DISTRO_TRACKER_VENDOR_NAME, pkg=obj.name) )
[docs] def items(self, obj): item_limit = getattr(settings, 'DISTRO_TRACKER_RSS_ITEM_LIMIT', self._DEFAULT_LIMIT) news = obj.news_set.all() action_items = obj.action_items.all() def item_key(item): if isinstance(item, ActionItem): return item.last_updated_timestamp elif isinstance(item, News): return item.datetime_created all_items = chain(news, action_items) return sorted(all_items, key=item_key, reverse=True)[:item_limit]
[docs] @filter_control_chars def item_title(self, item): if isinstance(item, News): return item.title elif isinstance(item, ActionItem): return item.short_description
[docs] @filter_control_chars def item_description(self, item): if isinstance(item, News): renderer_class = NewsRenderer.get_renderer_for_content_type( item.content_type) if renderer_class is None: renderer_class = NewsRenderer.get_renderer_for_content_type( 'text/plain') renderer = renderer_class(item) return renderer.render_to_string() elif isinstance(item, ActionItem): return item.full_description
[docs] def item_pubdate(self, item): if isinstance(item, ActionItem): return item.last_updated_timestamp elif isinstance(item, News): return item.datetime_created