from django.contrib.syndication.views import Feed from django.utils.feedgenerator import Rss201rev2Feed from django.urls import reverse from django.db.models import Q from django.conf import settings from django.contrib.postgres.search import SearchQuery from .models import Media, Category from . import helpers from .stop_words import STOP_WORDS class MediaRSSFeed(Rss201rev2Feed): def rss_attributes(self): attrs = super(MediaRSSFeed, self).rss_attributes() attrs["xmlns:media"] = "http://search.yahoo.com/mrss/" attrs["xmlns:atom"] = "http://www.w3.org/2005/Atom" return attrs def add_item_elements(self, handler, item): """Callback to add elements to each item (item/entry) element.""" super(MediaRSSFeed, self).add_item_elements(handler, item) if "media:title" in item: handler.addQuickElement("media:title", item["title"]) if "media:description" in item: handler.addQuickElement("media:description", item["description"]) if "content_url" in item: content = dict(url=item["content_url"]) if "content_width" in item: content["width"] = str(item["content_width"]) if "content_height" in item: content["height"] = str(item["content_height"]) handler.addQuickElement("media:content", "", content) if "thumbnail_url" in item: thumbnail = dict(url=item["thumbnail_url"]) if "thumbnail_width" in item: thumbnail["width"] = str(item["thumbnail_width"]) if "thumbnail_height" in item: thumbnail["height"] = str(item["thumbnail_height"]) handler.addQuickElement("media:thumbnail", "", thumbnail) if "keywords" in item: handler.addQuickElement("media:keywords", item["keywords"]) def add_root_elements(self, handler): super().add_root_elements(handler) if self.feed["author_name"] is not None: handler.startElement("author", {}) handler.addQuickElement("name", self.feed["author_name"]) handler.endElement("author") if self.feed.get("published") is not None: handler.startElement("published", {}) handler.addQuickElement("name", self.feed["published"]) handler.endElement("published") class IndexRSSFeed(Feed): feed_type = MediaRSSFeed title = "Latest Media" link = "/rss" description = "Latest Media RSS feed" def items(self): media = Media.objects.filter(listable=True).order_by("-add_date") media = media.prefetch_related("user") return media[:20] def item_title(self, item): return item.title def item_description(self, item): return item.description def item_author_name(self, item): return item.user.username def item_pubdate(self, item): return item.add_date def item_updateddate(self, item): return item.edit_date def item_link(self, item): return reverse("get_media") + "?m={0}".format(item.friendly_token) def item_extra_kwargs(self, item): item = { "media:title": item.title, "media:description": item.description, "content_width": 720, "thumbnail_url": f"{settings.SSL_FRONTEND_HOST}/{item.poster_url}", "content_url": f"{settings.SSL_FRONTEND_HOST}/{item.get_absolute_url()}", "thumbnail_width": 720, } return item class SearchRSSFeed(Feed): feed_type = MediaRSSFeed description = "Latest Media RSS feed" def link(self, obj): return f"/rss/search" def get_object(self, request): category = request.GET.get("c", "") tag = request.GET.get("t", "") query = request.GET.get("q", "") media = Media.objects.filter(listable=True) if category: media = media.filter(category__title=category) elif tag: media = media.filter(tags__title=tag) elif query: # same as on files.views.MediaSearch: move this processing to a prepare_query function query = helpers.clean_query(query) q_parts = [ q_part.rstrip("y") for q_part in query.split() if q_part not in STOP_WORDS ] if q_parts: query = SearchQuery(q_parts[0] + ":*", search_type="raw") for part in q_parts[1:]: query &= SearchQuery(part + ":*", search_type="raw") else: query = None if query: media = media.filter(search=query) media = media.order_by("-add_date").prefetch_related("user") return media def items(self, objects): return objects[:20] def item_title(self, item): return item.title def item_description(self, item): return item.description def item_author_name(self, item): return item.user.username def item_pubdate(self, item): return item.add_date def item_updateddate(self, item): return item.edit_date def item_link(self, item): return reverse("get_media") + "?m={0}".format(item.friendly_token) def item_extra_kwargs(self, item): item = { "media:title": item.title, "media:description": item.description, "content_width": 720, "thumbnail_url": f"{settings.SSL_FRONTEND_HOST}/{item.poster_url}", "content_url": f"{settings.SSL_FRONTEND_HOST}/{item.get_absolute_url()}", "thumbnail_width": 720, } return item