feeds.py 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. from django.contrib.syndication.views import Feed
  2. from django.utils.feedgenerator import Rss201rev2Feed
  3. from django.urls import reverse
  4. from django.db.models import Q
  5. from django.conf import settings
  6. from django.contrib.postgres.search import SearchQuery
  7. from .models import Media, Category
  8. from . import helpers
  9. from .stop_words import STOP_WORDS
  10. class MediaRSSFeed(Rss201rev2Feed):
  11. def rss_attributes(self):
  12. attrs = super(MediaRSSFeed, self).rss_attributes()
  13. attrs["xmlns:media"] = "http://search.yahoo.com/mrss/"
  14. attrs["xmlns:atom"] = "http://www.w3.org/2005/Atom"
  15. return attrs
  16. def add_item_elements(self, handler, item):
  17. """Callback to add elements to each item (item/entry) element."""
  18. super(MediaRSSFeed, self).add_item_elements(handler, item)
  19. if "media:title" in item:
  20. handler.addQuickElement("media:title", item["title"])
  21. if "media:description" in item:
  22. handler.addQuickElement("media:description", item["description"])
  23. if "content_url" in item:
  24. content = dict(url=item["content_url"])
  25. if "content_width" in item:
  26. content["width"] = str(item["content_width"])
  27. if "content_height" in item:
  28. content["height"] = str(item["content_height"])
  29. handler.addQuickElement("media:content", "", content)
  30. if "thumbnail_url" in item:
  31. thumbnail = dict(url=item["thumbnail_url"])
  32. if "thumbnail_width" in item:
  33. thumbnail["width"] = str(item["thumbnail_width"])
  34. if "thumbnail_height" in item:
  35. thumbnail["height"] = str(item["thumbnail_height"])
  36. handler.addQuickElement("media:thumbnail", "", thumbnail)
  37. if "keywords" in item:
  38. handler.addQuickElement("media:keywords", item["keywords"])
  39. def add_root_elements(self, handler):
  40. super().add_root_elements(handler)
  41. if self.feed["author_name"] is not None:
  42. handler.startElement("author", {})
  43. handler.addQuickElement("name", self.feed["author_name"])
  44. handler.endElement("author")
  45. if self.feed.get("published") is not None:
  46. handler.startElement("published", {})
  47. handler.addQuickElement("name", self.feed["published"])
  48. handler.endElement("published")
  49. class IndexRSSFeed(Feed):
  50. feed_type = MediaRSSFeed
  51. title = "Latest Media"
  52. link = "/rss"
  53. description = "Latest Media RSS feed"
  54. def items(self):
  55. media = Media.objects.filter(listable=True).order_by("-add_date")
  56. media = media.prefetch_related("user")
  57. return media[:20]
  58. def item_title(self, item):
  59. return item.title
  60. def item_description(self, item):
  61. return item.summary
  62. def item_author_name(self, item):
  63. return item.user.username
  64. def item_pubdate(self, item):
  65. return item.add_date
  66. def item_updateddate(self, item):
  67. return item.edit_date
  68. def item_link(self, item):
  69. return reverse("get_media") + "?m={0}".format(item.friendly_token)
  70. def item_extra_kwargs(self, item):
  71. item = {
  72. "media:title": item.title,
  73. "media:description": item.summary,
  74. "content_width": 720,
  75. "thumbnail_url": f"{settings.SSL_FRONTEND_HOST}/{item.poster_url}",
  76. "content_url": f"{settings.SSL_FRONTEND_HOST}/{item.get_absolute_url()}",
  77. "thumbnail_width": 720,
  78. }
  79. return item
  80. class SearchRSSFeed(Feed):
  81. feed_type = MediaRSSFeed
  82. description = "Latest Media RSS feed"
  83. def link(self, obj):
  84. return f"/rss/search"
  85. def get_object(self, request):
  86. category = request.GET.get("c", "")
  87. tag = request.GET.get("t", "")
  88. query = request.GET.get("q", "")
  89. media = Media.objects.filter(listable=True)
  90. if category:
  91. media = media.filter(category__title=category)
  92. elif tag:
  93. media = media.filter(tags__title=tag)
  94. elif query:
  95. # same as on files.views.MediaSearch: move this processing to a prepare_query function
  96. query = helpers.clean_query(query)
  97. q_parts = [
  98. q_part.strip("y")
  99. for q_part in query.split()
  100. if q_part not in STOP_WORDS
  101. ]
  102. if q_parts:
  103. query = SearchQuery(q_parts[0] + ":*", search_type="raw")
  104. for part in q_parts[1:]:
  105. query &= SearchQuery(part + ":*", search_type="raw")
  106. else:
  107. query = None
  108. if query:
  109. media = media.filter(search=query)
  110. media = media.order_by("-add_date").prefetch_related("user")
  111. return media
  112. def items(self, objects):
  113. return objects[:20]
  114. def item_title(self, item):
  115. return item.title
  116. def item_description(self, item):
  117. return item.summary
  118. def item_author_name(self, item):
  119. return item.user.username
  120. def item_pubdate(self, item):
  121. return item.add_date
  122. def item_updateddate(self, item):
  123. return item.edit_date
  124. def item_link(self, item):
  125. return reverse("get_media") + "?m={0}".format(item.friendly_token)
  126. def item_extra_kwargs(self, item):
  127. item = {
  128. "media:title": item.title,
  129. "media:description": item.summary,
  130. "content_width": 720,
  131. "thumbnail_url": f"{settings.SSL_FRONTEND_HOST}/{item.poster_url}",
  132. "content_url": f"{settings.SSL_FRONTEND_HOST}/{item.get_absolute_url()}",
  133. "thumbnail_width": 720,
  134. }
  135. return item