Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit fed0234

Browse files
authoredDec 25, 2020
Merge pull request mediacms-io#3 from mediacms-io/feat-search-rss
introduce rss and custom rss
2 parents dc0eeae + 10d5d8f commit fed0234

File tree

6 files changed

+173
-14
lines changed

6 files changed

+173
-14
lines changed
 

‎files/context_processors.py

+1
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,5 @@ def stuff(request):
3737
ret[
3838
"VIDEO_PLAYER_FEATURED_VIDEO_ON_INDEX_PAGE"
3939
] = settings.VIDEO_PLAYER_FEATURED_VIDEO_ON_INDEX_PAGE
40+
ret["RSS_URL"] = "/rss"
4041
return ret

‎files/feeds.py

+150-6
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,170 @@
11
from django.contrib.syndication.views import Feed
2+
from django.utils.feedgenerator import Rss201rev2Feed
23
from django.urls import reverse
34
from django.db.models import Q
5+
from django.conf import settings
6+
from django.contrib.postgres.search import SearchQuery
47

5-
from .models import Media
8+
from .models import Media, Category
9+
from . import helpers
10+
from .stop_words import STOP_WORDS
611

712

8-
class RssMediaFeed(Feed):
13+
class MediaRSSFeed(Rss201rev2Feed):
14+
def rss_attributes(self):
15+
attrs = super(MediaRSSFeed, self).rss_attributes()
16+
attrs["xmlns:media"] = "http://search.yahoo.com/mrss/"
17+
attrs["xmlns:atom"] = "http://www.w3.org/2005/Atom"
18+
return attrs
19+
20+
def add_item_elements(self, handler, item):
21+
"""Callback to add elements to each item (item/entry) element."""
22+
super(MediaRSSFeed, self).add_item_elements(handler, item)
23+
24+
if "media:title" in item:
25+
handler.addQuickElement("media:title", item["title"])
26+
if "media:description" in item:
27+
handler.addQuickElement("media:description", item["description"])
28+
29+
if "content_url" in item:
30+
content = dict(url=item["content_url"])
31+
if "content_width" in item:
32+
content["width"] = str(item["content_width"])
33+
if "content_height" in item:
34+
content["height"] = str(item["content_height"])
35+
handler.addQuickElement("media:content", "", content)
36+
37+
if "thumbnail_url" in item:
38+
thumbnail = dict(url=item["thumbnail_url"])
39+
if "thumbnail_width" in item:
40+
thumbnail["width"] = str(item["thumbnail_width"])
41+
if "thumbnail_height" in item:
42+
thumbnail["height"] = str(item["thumbnail_height"])
43+
handler.addQuickElement("media:thumbnail", "", thumbnail)
44+
45+
if "keywords" in item:
46+
handler.addQuickElement("media:keywords", item["keywords"])
47+
48+
def add_root_elements(self, handler):
49+
super().add_root_elements(handler)
50+
if self.feed["author_name"] is not None:
51+
handler.startElement("author", {})
52+
handler.addQuickElement("name", self.feed["author_name"])
53+
handler.endElement("author")
54+
if self.feed.get("published") is not None:
55+
handler.startElement("published", {})
56+
handler.addQuickElement("name", self.feed["published"])
57+
handler.endElement("published")
58+
59+
60+
class IndexRSSFeed(Feed):
61+
feed_type = MediaRSSFeed
962
title = "Latest Media"
10-
link = "/media"
63+
link = "/rss"
1164
description = "Latest Media RSS feed"
1265

1366
def items(self):
14-
basic_query = Q(listable=True)
15-
media = Media.objects.filter(basic_query).order_by("-add_date")
67+
media = Media.objects.filter(listable=True).order_by("-add_date")
1668
media = media.prefetch_related("user")
17-
return media[:40]
69+
return media[:20]
1870

1971
def item_title(self, item):
2072
return item.title
2173

2274
def item_description(self, item):
2375
return item.description
2476

77+
def item_author_name(self, item):
78+
return item.user.username
79+
80+
def item_pubdate(self, item):
81+
return item.add_date
82+
83+
def item_updateddate(self, item):
84+
return item.edit_date
85+
2586
def item_link(self, item):
2687
return reverse("get_media") + "?m={0}".format(item.friendly_token)
88+
89+
def item_extra_kwargs(self, item):
90+
item = {
91+
"media:title": item.title,
92+
"media:description": item.description,
93+
"content_width": 720,
94+
"thumbnail_url": f"{settings.SSL_FRONTEND_HOST}/{item.poster_url}",
95+
"content_url": f"{settings.SSL_FRONTEND_HOST}/{item.get_absolute_url()}",
96+
"thumbnail_width": 720,
97+
}
98+
return item
99+
100+
101+
class SearchRSSFeed(Feed):
102+
feed_type = MediaRSSFeed
103+
description = "Latest Media RSS feed"
104+
105+
def link(self, obj):
106+
return f"/rss/search"
107+
108+
def get_object(self, request):
109+
category = request.GET.get("c", "")
110+
tag = request.GET.get("t", "")
111+
query = request.GET.get("q", "")
112+
113+
media = Media.objects.filter(listable=True)
114+
115+
if category:
116+
media = media.filter(category__title=category)
117+
elif tag:
118+
media = media.filter(tags__title=tag)
119+
elif query:
120+
# same as on files.views.MediaSearch: move this processing to a prepare_query function
121+
query = helpers.clean_query(query)
122+
q_parts = [
123+
q_part.rstrip("y")
124+
for q_part in query.split()
125+
if q_part not in STOP_WORDS
126+
]
127+
if q_parts:
128+
query = SearchQuery(q_parts[0] + ":*", search_type="raw")
129+
for part in q_parts[1:]:
130+
query &= SearchQuery(part + ":*", search_type="raw")
131+
else:
132+
query = None
133+
if query:
134+
media = media.filter(search=query)
135+
136+
media = media.order_by("-add_date").prefetch_related("user")
137+
138+
return media
139+
140+
def items(self, objects):
141+
return objects[:20]
142+
143+
def item_title(self, item):
144+
return item.title
145+
146+
def item_description(self, item):
147+
return item.description
148+
149+
def item_author_name(self, item):
150+
return item.user.username
151+
152+
def item_pubdate(self, item):
153+
return item.add_date
154+
155+
def item_updateddate(self, item):
156+
return item.edit_date
157+
158+
def item_link(self, item):
159+
return reverse("get_media") + "?m={0}".format(item.friendly_token)
160+
161+
def item_extra_kwargs(self, item):
162+
item = {
163+
"media:title": item.title,
164+
"media:description": item.description,
165+
"content_width": 720,
166+
"thumbnail_url": f"{settings.SSL_FRONTEND_HOST}/{item.poster_url}",
167+
"content_url": f"{settings.SSL_FRONTEND_HOST}/{item.get_absolute_url()}",
168+
"thumbnail_width": 720,
169+
}
170+
return item

‎files/management_views.py

+10-5
Original file line numberDiff line numberDiff line change
@@ -137,11 +137,10 @@ def get(self, request, format=None):
137137
serializer = CommentSerializer(page, many=True, context={"request": request})
138138
return paginator.get_paginated_response(serializer.data)
139139

140-
141140
def delete(self, request, format=None):
142-
comment_ids = request.GET.get('comment_ids')
141+
comment_ids = request.GET.get("comment_ids")
143142
if comment_ids:
144-
comments = comment_ids.split(',')
143+
comments = comment_ids.split(",")
145144
Comment.objects.filter(uid__in=comments).delete()
146145
return Response(status=status.HTTP_204_NO_CONTENT)
147146

@@ -161,6 +160,7 @@ def get(self, request, format=None):
161160
params = self.request.query_params
162161
ordering = params.get("ordering", "").strip()
163162
sort_by = params.get("sort_by", "").strip()
163+
role = params.get("role", "all").strip()
164164

165165
sort_by_options = ["date_added", "name"]
166166
if sort_by not in sort_by_options:
@@ -173,11 +173,16 @@ def get(self, request, format=None):
173173
pagination_class = api_settings.DEFAULT_PAGINATION_CLASS
174174

175175
qs = User.objects.filter()
176-
media = qs.order_by(f"{ordering}{sort_by}")
176+
if role == "manager":
177+
qs = qs.filter(is_manager=True)
178+
elif role == "editor":
179+
qs = qs.filter(is_editor=True)
180+
181+
users = qs.order_by(f"{ordering}{sort_by}")
177182

178183
paginator = pagination_class()
179184

180-
page = paginator.paginate_queryset(media, request)
185+
page = paginator.paginate_queryset(users, request)
181186

182187
serializer = UserSerializer(page, many=True, context={"request": request})
183188
return paginator.get_paginated_response(serializer.data)

‎files/urls.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
from . import views
77
from . import management_views
8-
from .feeds import RssMediaFeed
8+
from .feeds import IndexRSSFeed, SearchRSSFeed
99

1010
urlpatterns = [
1111
url(r"^$", views.index),
@@ -33,7 +33,8 @@
3333
),
3434
url(r"^popular$", views.recommended_media),
3535
url(r"^recommended$", views.recommended_media),
36-
path("rss/", RssMediaFeed()),
36+
path("rss/", IndexRSSFeed()),
37+
url("^rss/search", SearchRSSFeed()),
3738
url(r"^search", views.search, name="search"),
3839
url(r"^scpublisher", views.upload_media, name="upload_media"),
3940
url(r"^tags", views.tags, name="tags"),

‎files/views.py

+8-1
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,8 @@ def search(request):
296296
"""Search view"""
297297

298298
context = {}
299+
RSS_URL = f"/rss{request.environ['REQUEST_URI']}"
300+
context["RSS_URL"] = RSS_URL
299301
return render(request, "cms/search.html", context)
300302

301303

@@ -730,8 +732,13 @@ def get(self, request, format=None):
730732
media = Media.objects.filter(state="public", is_reviewed=True)
731733

732734
if query:
735+
# move this processing to a prepare_query function
733736
query = clean_query(query)
734-
q_parts = [q_part for q_part in query.split() if q_part not in STOP_WORDS]
737+
q_parts = [
738+
q_part.rstrip("y")
739+
for q_part in query.split()
740+
if q_part not in STOP_WORDS
741+
]
735742
if q_parts:
736743
query = SearchQuery(q_parts[0] + ":*", search_type="raw")
737744
for part in q_parts[1:]:

‎templates/common/head-links.html

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
<link rel="manifest" href="{% static "favicons/site.webmanifest" %}">
66
<link rel="mask-icon" href="{% static "favicons/safari-pinned-tab.svg" %}" color="#009933">
77
<link rel="shortcut icon" href="{% static "favicons/favicon.ico" %}">
8+
<link rel="alternate" type="application/rss+xml" title="RSS feeds" href="{{RSS_URL}}" />
89
<meta name="msapplication-TileColor" content="#ffffff">
910
<meta name="msapplication-config" content="{% static "favicons/browserconfig.xml" %}">
1011
<meta name="theme-color" content="#ffffff">

0 commit comments

Comments
 (0)
Please sign in to comment.