Funktionierender Prototyp des Serious Games zur Vermittlung von Wissen zu Software-Engineering-Arbeitsmodellen.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

views.py 4.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. import datetime
  2. import warnings
  3. from dataclasses import dataclass
  4. from functools import wraps
  5. from django.contrib.sites.shortcuts import get_current_site
  6. from django.core.paginator import EmptyPage, PageNotAnInteger
  7. from django.http import Http404
  8. from django.template.response import TemplateResponse
  9. from django.urls import reverse
  10. from django.utils import timezone
  11. from django.utils.deprecation import RemovedInDjango50Warning
  12. from django.utils.http import http_date
  13. @dataclass
  14. class SitemapIndexItem:
  15. location: str
  16. last_mod: bool = None
  17. # RemovedInDjango50Warning
  18. def __str__(self):
  19. msg = (
  20. "Calling `__str__` on SitemapIndexItem is deprecated, use the `location` "
  21. "attribute instead."
  22. )
  23. warnings.warn(msg, RemovedInDjango50Warning, stacklevel=2)
  24. return self.location
  25. def x_robots_tag(func):
  26. @wraps(func)
  27. def inner(request, *args, **kwargs):
  28. response = func(request, *args, **kwargs)
  29. response.headers["X-Robots-Tag"] = "noindex, noodp, noarchive"
  30. return response
  31. return inner
  32. def _get_latest_lastmod(current_lastmod, new_lastmod):
  33. """
  34. Returns the latest `lastmod` where `lastmod` can be either a date or a
  35. datetime.
  36. """
  37. if not isinstance(new_lastmod, datetime.datetime):
  38. new_lastmod = datetime.datetime.combine(new_lastmod, datetime.time.min)
  39. if timezone.is_naive(new_lastmod):
  40. new_lastmod = timezone.make_aware(new_lastmod, datetime.timezone.utc)
  41. return new_lastmod if current_lastmod is None else max(current_lastmod, new_lastmod)
  42. @x_robots_tag
  43. def index(
  44. request,
  45. sitemaps,
  46. template_name="sitemap_index.xml",
  47. content_type="application/xml",
  48. sitemap_url_name="django.contrib.sitemaps.views.sitemap",
  49. ):
  50. req_protocol = request.scheme
  51. req_site = get_current_site(request)
  52. sites = [] # all sections' sitemap URLs
  53. all_indexes_lastmod = True
  54. latest_lastmod = None
  55. for section, site in sitemaps.items():
  56. # For each section label, add links of all pages of its sitemap
  57. # (usually generated by the `sitemap` view).
  58. if callable(site):
  59. site = site()
  60. protocol = req_protocol if site.protocol is None else site.protocol
  61. sitemap_url = reverse(sitemap_url_name, kwargs={"section": section})
  62. absolute_url = "%s://%s%s" % (protocol, req_site.domain, sitemap_url)
  63. site_lastmod = site.get_latest_lastmod()
  64. if all_indexes_lastmod:
  65. if site_lastmod is not None:
  66. latest_lastmod = _get_latest_lastmod(latest_lastmod, site_lastmod)
  67. else:
  68. all_indexes_lastmod = False
  69. sites.append(SitemapIndexItem(absolute_url, site_lastmod))
  70. # Add links to all pages of the sitemap.
  71. for page in range(2, site.paginator.num_pages + 1):
  72. sites.append(
  73. SitemapIndexItem("%s?p=%s" % (absolute_url, page), site_lastmod)
  74. )
  75. # If lastmod is defined for all sites, set header so as
  76. # ConditionalGetMiddleware is able to send 304 NOT MODIFIED
  77. if all_indexes_lastmod and latest_lastmod:
  78. headers = {"Last-Modified": http_date(latest_lastmod.timestamp())}
  79. else:
  80. headers = None
  81. return TemplateResponse(
  82. request,
  83. template_name,
  84. {"sitemaps": sites},
  85. content_type=content_type,
  86. headers=headers,
  87. )
  88. @x_robots_tag
  89. def sitemap(
  90. request,
  91. sitemaps,
  92. section=None,
  93. template_name="sitemap.xml",
  94. content_type="application/xml",
  95. ):
  96. req_protocol = request.scheme
  97. req_site = get_current_site(request)
  98. if section is not None:
  99. if section not in sitemaps:
  100. raise Http404("No sitemap available for section: %r" % section)
  101. maps = [sitemaps[section]]
  102. else:
  103. maps = sitemaps.values()
  104. page = request.GET.get("p", 1)
  105. lastmod = None
  106. all_sites_lastmod = True
  107. urls = []
  108. for site in maps:
  109. try:
  110. if callable(site):
  111. site = site()
  112. urls.extend(site.get_urls(page=page, site=req_site, protocol=req_protocol))
  113. if all_sites_lastmod:
  114. site_lastmod = getattr(site, "latest_lastmod", None)
  115. if site_lastmod is not None:
  116. lastmod = _get_latest_lastmod(lastmod, site_lastmod)
  117. else:
  118. all_sites_lastmod = False
  119. except EmptyPage:
  120. raise Http404("Page %s empty" % page)
  121. except PageNotAnInteger:
  122. raise Http404("No page '%s'" % page)
  123. # If lastmod is defined for all sites, set header so as
  124. # ConditionalGetMiddleware is able to send 304 NOT MODIFIED
  125. if all_sites_lastmod:
  126. headers = {"Last-Modified": http_date(lastmod.timestamp())} if lastmod else None
  127. else:
  128. headers = None
  129. return TemplateResponse(
  130. request,
  131. template_name,
  132. {"urlset": urls},
  133. content_type=content_type,
  134. headers=headers,
  135. )