__init__.py 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. from django.apps import apps as django_apps
  2. from django.core import urlresolvers, paginator
  3. from django.core.exceptions import ImproperlyConfigured
  4. from django.utils.six.moves.urllib.parse import urlencode
  5. from django.utils.six.moves.urllib.request import urlopen
  6. PING_URL = "http://www.google.com/webmasters/tools/ping"
  7. class SitemapNotFound(Exception):
  8. pass
  9. def ping_google(sitemap_url=None, ping_url=PING_URL):
  10. """
  11. Alerts Google that the sitemap for the current site has been updated.
  12. If sitemap_url is provided, it should be an absolute path to the sitemap
  13. for this site -- e.g., '/sitemap.xml'. If sitemap_url is not provided, this
  14. function will attempt to deduce it by using urlresolvers.reverse().
  15. """
  16. if sitemap_url is None:
  17. try:
  18. # First, try to get the "index" sitemap URL.
  19. sitemap_url = urlresolvers.reverse('django.contrib.sitemaps.views.index')
  20. except urlresolvers.NoReverseMatch:
  21. try:
  22. # Next, try for the "global" sitemap URL.
  23. sitemap_url = urlresolvers.reverse('django.contrib.sitemaps.views.sitemap')
  24. except urlresolvers.NoReverseMatch:
  25. pass
  26. if sitemap_url is None:
  27. raise SitemapNotFound("You didn't provide a sitemap_url, and the sitemap URL couldn't be auto-detected.")
  28. if not django_apps.is_installed('django.contrib.sites'):
  29. raise ImproperlyConfigured("ping_google requires django.contrib.sites, which isn't installed.")
  30. Site = django_apps.get_model('sites.Site')
  31. current_site = Site.objects.get_current()
  32. url = "http://%s%s" % (current_site.domain, sitemap_url)
  33. params = urlencode({'sitemap': url})
  34. urlopen("%s?%s" % (ping_url, params))
  35. class Sitemap(object):
  36. # This limit is defined by Google. See the index documentation at
  37. # http://sitemaps.org/protocol.php#index.
  38. limit = 50000
  39. # If protocol is None, the URLs in the sitemap will use the protocol
  40. # with which the sitemap was requested.
  41. protocol = None
  42. def __get(self, name, obj, default=None):
  43. try:
  44. attr = getattr(self, name)
  45. except AttributeError:
  46. return default
  47. if callable(attr):
  48. return attr(obj)
  49. return attr
  50. def items(self):
  51. return []
  52. def location(self, obj):
  53. return obj.get_absolute_url()
  54. def _get_paginator(self):
  55. return paginator.Paginator(self.items(), self.limit)
  56. paginator = property(_get_paginator)
  57. def get_urls(self, page=1, site=None, protocol=None):
  58. # Determine protocol
  59. if self.protocol is not None:
  60. protocol = self.protocol
  61. if protocol is None:
  62. protocol = 'http'
  63. # Determine domain
  64. if site is None:
  65. if django_apps.is_installed('django.contrib.sites'):
  66. Site = django_apps.get_model('sites.Site')
  67. try:
  68. site = Site.objects.get_current()
  69. except Site.DoesNotExist:
  70. pass
  71. if site is None:
  72. raise ImproperlyConfigured("To use sitemaps, either enable the sites framework or pass a Site/RequestSite object in your view.")
  73. domain = site.domain
  74. urls = []
  75. latest_lastmod = None
  76. all_items_lastmod = True # track if all items have a lastmod
  77. for item in self.paginator.page(page).object_list:
  78. loc = "%s://%s%s" % (protocol, domain, self.__get('location', item))
  79. priority = self.__get('priority', item, None)
  80. lastmod = self.__get('lastmod', item, None)
  81. if all_items_lastmod:
  82. all_items_lastmod = lastmod is not None
  83. if (all_items_lastmod and
  84. (latest_lastmod is None or lastmod > latest_lastmod)):
  85. latest_lastmod = lastmod
  86. url_info = {
  87. 'item': item,
  88. 'location': loc,
  89. 'lastmod': lastmod,
  90. 'changefreq': self.__get('changefreq', item, None),
  91. 'priority': str(priority if priority is not None else ''),
  92. }
  93. urls.append(url_info)
  94. if all_items_lastmod and latest_lastmod:
  95. self.latest_lastmod = latest_lastmod
  96. return urls
  97. class FlatPageSitemap(Sitemap):
  98. def items(self):
  99. if not django_apps.is_installed('django.contrib.sites'):
  100. raise ImproperlyConfigured("FlatPageSitemap requires django.contrib.sites, which isn't installed.")
  101. Site = django_apps.get_model('sites.Site')
  102. current_site = Site.objects.get_current()
  103. return current_site.flatpage_set.filter(registration_required=False)
  104. class GenericSitemap(Sitemap):
  105. priority = None
  106. changefreq = None
  107. def __init__(self, info_dict, priority=None, changefreq=None):
  108. self.queryset = info_dict['queryset']
  109. self.date_field = info_dict.get('date_field', None)
  110. self.priority = priority
  111. self.changefreq = changefreq
  112. def items(self):
  113. # Make sure to return a clone; we don't want premature evaluation.
  114. return self.queryset.filter()
  115. def lastmod(self, item):
  116. if self.date_field is not None:
  117. return getattr(item, self.date_field)
  118. return None
  119. default_app_config = 'django.contrib.sitemaps.apps.SiteMapsConfig'