PageRenderTime 694ms CodeModel.GetById 26ms RepoModel.GetById 1ms app.codeStats 0ms

/packages/django/contrib/syndication/views.py

https://gitlab.com/gregtyka/Scryve-Webapp
Python | 209 lines | 165 code | 24 blank | 20 comment | 37 complexity | 45946f75d58b959657f50ebf5643c266 MD5 | raw file
  1. import datetime
  2. from django.conf import settings
  3. from django.contrib.sites.models import Site, RequestSite
  4. from django.core.exceptions import ImproperlyConfigured, ObjectDoesNotExist
  5. from django.http import HttpResponse, Http404
  6. from django.template import loader, Template, TemplateDoesNotExist, RequestContext
  7. from django.utils import feedgenerator, tzinfo
  8. from django.utils.encoding import force_unicode, iri_to_uri, smart_unicode
  9. from django.utils.html import escape
  10. def add_domain(domain, url):
  11. if not (url.startswith('http://')
  12. or url.startswith('https://')
  13. or url.startswith('mailto:')):
  14. # 'url' must already be ASCII and URL-quoted, so no need for encoding
  15. # conversions here.
  16. url = iri_to_uri(u'http://%s%s' % (domain, url))
  17. return url
  18. class FeedDoesNotExist(ObjectDoesNotExist):
  19. pass
  20. class Feed(object):
  21. feed_type = feedgenerator.DefaultFeed
  22. title_template = None
  23. description_template = None
  24. def __call__(self, request, *args, **kwargs):
  25. try:
  26. obj = self.get_object(request, *args, **kwargs)
  27. except ObjectDoesNotExist:
  28. raise Http404('Feed object does not exist.')
  29. feedgen = self.get_feed(obj, request)
  30. response = HttpResponse(mimetype=feedgen.mime_type)
  31. feedgen.write(response, 'utf-8')
  32. return response
  33. def item_title(self, item):
  34. # Titles should be double escaped by default (see #6533)
  35. return escape(force_unicode(item))
  36. def item_description(self, item):
  37. return force_unicode(item)
  38. def item_link(self, item):
  39. try:
  40. return item.get_absolute_url()
  41. except AttributeError:
  42. raise ImproperlyConfigured('Give your %s class a get_absolute_url() method, or define an item_link() method in your Feed class.' % item.__class__.__name__)
  43. def __get_dynamic_attr(self, attname, obj, default=None):
  44. try:
  45. attr = getattr(self, attname)
  46. except AttributeError:
  47. return default
  48. if callable(attr):
  49. # Check func_code.co_argcount rather than try/excepting the
  50. # function and catching the TypeError, because something inside
  51. # the function may raise the TypeError. This technique is more
  52. # accurate.
  53. if hasattr(attr, 'func_code'):
  54. argcount = attr.func_code.co_argcount
  55. else:
  56. argcount = attr.__call__.func_code.co_argcount
  57. if argcount == 2: # one argument is 'self'
  58. return attr(obj)
  59. else:
  60. return attr()
  61. return attr
  62. def feed_extra_kwargs(self, obj):
  63. """
  64. Returns an extra keyword arguments dictionary that is used when
  65. initializing the feed generator.
  66. """
  67. return {}
  68. def item_extra_kwargs(self, item):
  69. """
  70. Returns an extra keyword arguments dictionary that is used with
  71. the `add_item` call of the feed generator.
  72. """
  73. return {}
  74. def get_object(self, request, *args, **kwargs):
  75. return None
  76. def get_feed(self, obj, request):
  77. """
  78. Returns a feedgenerator.DefaultFeed object, fully populated, for
  79. this feed. Raises FeedDoesNotExist for invalid parameters.
  80. """
  81. if Site._meta.installed:
  82. current_site = Site.objects.get_current()
  83. else:
  84. current_site = RequestSite(request)
  85. link = self.__get_dynamic_attr('link', obj)
  86. link = add_domain(current_site.domain, link)
  87. feed = self.feed_type(
  88. title = self.__get_dynamic_attr('title', obj),
  89. subtitle = self.__get_dynamic_attr('subtitle', obj),
  90. link = link,
  91. description = self.__get_dynamic_attr('description', obj),
  92. language = settings.LANGUAGE_CODE.decode(),
  93. feed_url = add_domain(current_site.domain,
  94. self.__get_dynamic_attr('feed_url', obj) or request.path),
  95. author_name = self.__get_dynamic_attr('author_name', obj),
  96. author_link = self.__get_dynamic_attr('author_link', obj),
  97. author_email = self.__get_dynamic_attr('author_email', obj),
  98. categories = self.__get_dynamic_attr('categories', obj),
  99. feed_copyright = self.__get_dynamic_attr('feed_copyright', obj),
  100. feed_guid = self.__get_dynamic_attr('feed_guid', obj),
  101. ttl = self.__get_dynamic_attr('ttl', obj),
  102. **self.feed_extra_kwargs(obj)
  103. )
  104. title_tmp = None
  105. if self.title_template is not None:
  106. try:
  107. title_tmp = loader.get_template(self.title_template)
  108. except TemplateDoesNotExist:
  109. pass
  110. description_tmp = None
  111. if self.description_template is not None:
  112. try:
  113. description_tmp = loader.get_template(self.description_template)
  114. except TemplateDoesNotExist:
  115. pass
  116. for item in self.__get_dynamic_attr('items', obj):
  117. if title_tmp is not None:
  118. title = title_tmp.render(RequestContext(request, {'obj': item, 'site': current_site}))
  119. else:
  120. title = self.__get_dynamic_attr('item_title', item)
  121. if description_tmp is not None:
  122. description = description_tmp.render(RequestContext(request, {'obj': item, 'site': current_site}))
  123. else:
  124. description = self.__get_dynamic_attr('item_description', item)
  125. link = add_domain(current_site.domain, self.__get_dynamic_attr('item_link', item))
  126. enc = None
  127. enc_url = self.__get_dynamic_attr('item_enclosure_url', item)
  128. if enc_url:
  129. enc = feedgenerator.Enclosure(
  130. url = smart_unicode(enc_url),
  131. length = smart_unicode(self.__get_dynamic_attr('item_enclosure_length', item)),
  132. mime_type = smart_unicode(self.__get_dynamic_attr('item_enclosure_mime_type', item))
  133. )
  134. author_name = self.__get_dynamic_attr('item_author_name', item)
  135. if author_name is not None:
  136. author_email = self.__get_dynamic_attr('item_author_email', item)
  137. author_link = self.__get_dynamic_attr('item_author_link', item)
  138. else:
  139. author_email = author_link = None
  140. pubdate = self.__get_dynamic_attr('item_pubdate', item)
  141. if pubdate and not pubdate.tzinfo:
  142. ltz = tzinfo.LocalTimezone(pubdate)
  143. pubdate = pubdate.replace(tzinfo=ltz)
  144. feed.add_item(
  145. title = title,
  146. link = link,
  147. description = description,
  148. unique_id = self.__get_dynamic_attr('item_guid', item, link),
  149. enclosure = enc,
  150. pubdate = pubdate,
  151. author_name = author_name,
  152. author_email = author_email,
  153. author_link = author_link,
  154. categories = self.__get_dynamic_attr('item_categories', item),
  155. item_copyright = self.__get_dynamic_attr('item_copyright', item),
  156. **self.item_extra_kwargs(item)
  157. )
  158. return feed
  159. def feed(request, url, feed_dict=None):
  160. """Provided for backwards compatibility."""
  161. import warnings
  162. warnings.warn('The syndication feed() view is deprecated. Please use the '
  163. 'new class based view API.',
  164. category=PendingDeprecationWarning)
  165. if not feed_dict:
  166. raise Http404("No feeds are registered.")
  167. try:
  168. slug, param = url.split('/', 1)
  169. except ValueError:
  170. slug, param = url, ''
  171. try:
  172. f = feed_dict[slug]
  173. except KeyError:
  174. raise Http404("Slug %r isn't registered." % slug)
  175. try:
  176. feedgen = f(slug, request).get_feed(param)
  177. except FeedDoesNotExist:
  178. raise Http404("Invalid feed parameters. Slug %r is valid, but other parameters, or lack thereof, are not." % slug)
  179. response = HttpResponse(mimetype=feedgen.mime_type)
  180. feedgen.write(response, 'utf-8')
  181. return response