From 9339443ddf0d730c3108e42e6760d18f2960ef38 Mon Sep 17 00:00:00 2001 From: Markos Gogoulos Date: Fri, 25 Dec 2020 00:49:38 +0200 Subject: [PATCH] introduce rss and custom rss --- files/context_processors.py | 1 + files/feeds.py | 157 +++++++++++++++++++++++++++++-- files/urls.py | 5 +- files/views.py | 2 + templates/common/head-links.html | 1 + 5 files changed, 157 insertions(+), 9 deletions(-) diff --git a/files/context_processors.py b/files/context_processors.py index 0fd883f..d11aa1d 100644 --- a/files/context_processors.py +++ b/files/context_processors.py @@ -37,4 +37,5 @@ def stuff(request): ret[ "VIDEO_PLAYER_FEATURED_VIDEO_ON_INDEX_PAGE" ] = settings.VIDEO_PLAYER_FEATURED_VIDEO_ON_INDEX_PAGE + ret["RSS_URL"] = "/rss" return ret diff --git a/files/feeds.py b/files/feeds.py index 46aedb5..7d3b306 100644 --- a/files/feeds.py +++ b/files/feeds.py @@ -1,26 +1,169 @@ 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 +from .models import Media, Category +from . import helpers +from .stop_words import STOP_WORDS -class RssMediaFeed(Feed): +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 = "/media" + link = "/rss" description = "Latest Media RSS feed" def items(self): - basic_query = Q(listable=True) - media = Media.objects.filter(basic_query).order_by("-add_date") + media = Media.objects.filter(listable=True).order_by("-add_date") media = media.prefetch_related("user") - return media[:40] + return media[:20] def item_title(self, item): return item.title def item_description(self, item): - return item.description + return item.summary + + 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.summary, + "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: + query = helpers.clean_query(query) + q_parts = [ + q_part.strip("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.summary + + 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.summary, + "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 diff --git a/files/urls.py b/files/urls.py index 561242c..4470c31 100644 --- a/files/urls.py +++ b/files/urls.py @@ -5,7 +5,7 @@ from django.urls import path from . import views from . import management_views -from .feeds import RssMediaFeed +from .feeds import IndexRSSFeed, SearchRSSFeed urlpatterns = [ url(r"^$", views.index), @@ -33,7 +33,8 @@ urlpatterns = [ ), url(r"^popular$", views.recommended_media), url(r"^recommended$", views.recommended_media), - path("rss/", RssMediaFeed()), + path("rss/", IndexRSSFeed()), + url("^rss/search", SearchRSSFeed()), url(r"^search", views.search, name="search"), url(r"^scpublisher", views.upload_media, name="upload_media"), url(r"^tags", views.tags, name="tags"), diff --git a/files/views.py b/files/views.py index 3905ddf..c286876 100644 --- a/files/views.py +++ b/files/views.py @@ -296,6 +296,8 @@ def search(request): """Search view""" context = {} + RSS_URL = f"/rss{request.environ['REQUEST_URI']}" + context["RSS_URL"] = RSS_URL return render(request, "cms/search.html", context) diff --git a/templates/common/head-links.html b/templates/common/head-links.html index 2f23cb3..37e37fe 100644 --- a/templates/common/head-links.html +++ b/templates/common/head-links.html @@ -5,6 +5,7 @@ +