forked from AustralianDisabilityLimited/unisubs
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsitemaps.py
153 lines (128 loc) · 4.89 KB
/
sitemaps.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
from django.contrib.sitemaps import Sitemap
from videos.models import Video
from django.core.urlresolvers import reverse
from django.conf import settings
from django.db.models import permalink
from django.http import HttpResponse, Http404
from django.template import loader
from django.utils.encoding import smart_str
from django.core.paginator import EmptyPage, PageNotAnInteger
from django.core.cache import cache
from django.core import urlresolvers
from django.contrib.sites.models import Site
import datetime
DEFAULT_CHANGEFREQ = "monthly"
DEFAULT_PRIORITY = 0.6
DEFAULT_LASTMOD = datetime.datetime(2011, 3, 1)
def sitemap_index(request, sitemaps):
current_site = Site.objects.get_current()
sites = []
protocol = request.is_secure() and 'https' or 'http'
for section, site in sitemaps.items():
if callable(site):
pages = site().paginator.num_pages
else:
pages = site.paginator.num_pages
sitemap_url = urlresolvers.reverse(sitemap_view, kwargs={'section': section})
sites.append('%s://%s%s' % (protocol, current_site.domain, sitemap_url))
if pages > 1:
for page in range(2, pages+1):
sites.append('%s://%s%s?p=%s' % (protocol, current_site.domain, sitemap_url, page))
xml = loader.render_to_string('sitemap_index.xml', {'sitemaps': sites})
return HttpResponse(xml, mimetype='application/xml')
def sitemap_view(request, sitemaps, section=None):
maps, urls = [], []
if section is not None:
if section not in sitemaps:
raise Http404("No sitemap available for section: %r" % section)
maps.append(sitemaps[section])
else:
maps = sitemaps.values()
page = request.GET.get("p", 1)
cache_key = 'sitemap_%s_%s' % (section, page)
xml = cache.get(cache_key)
if not xml:
for site in maps:
try:
if callable(site):
urls.extend(site().get_urls(page))
else:
urls.extend(site.get_urls(page))
except EmptyPage:
raise Http404("Page %s empty" % page)
except PageNotAnInteger:
raise Http404("No page '%s'" % page)
xml = smart_str(loader.render_to_string('sitemap.xml', {'urlset': urls}))
cache.set(cache_key, xml, 60*60*24)
return HttpResponse(xml, mimetype='application/xml')
class AbstractSitemap(object):
'''
An abstract sitemap class to be used for static pages.
'''
def __init__(self, page, changefreq=DEFAULT_CHANGEFREQ,
priority=DEFAULT_PRIORITY, lastmod=DEFAULT_LASTMOD):
self.url = page
self.changefreq = changefreq
self.priority = priority
self.lastmod = lastmod
def get_absolute_url(self):
return self.url
AS = AbstractSitemap
class StaticSitemap(Sitemap):
'''
Definition of static pages, which more or less remain the same
and are not based on the database data.
'''
def items(self):
pages = [
AS(reverse('faq_page', kwargs={'locale': ''})), #FAQ
# Add more static pages
]
for lang, _ in settings.LANGUAGES:
pages.append(AS('/%s/' % lang, "weekly", 1))
return pages
def changefreq(self, obj):
return obj.changefreq
def priority(self, obj):
return obj.priority
def lastmod(self, obj):
return obj.lastmod
class VideoSitemapValuesQuery(object):
"""Wraps the queryset for VideoSitemap to make it more efficient.
To efficently retrieve items from the queryset, we want to use a values
query, (Video.objects.values('video_id', 'edited')). However, if we
simply use that, then when django calls count() on that query, it creates
the following terribly query:
SELECT COUNT(*) FROM (SELECT `videos_video`.`video_id` AS `video_id`,
`videos_video`.`edited` AS `edited` FROM `videos_video`)
This query moves columns from the entire videos table into a tmp table,
and has brought down our site.
"""
def __init__(self, *values):
self._qs = Video.objects.values(*values)
def count(self):
return Video.objects.count()
def __getitem__(self, index_or_slice):
return self._qs.__getitem__(index_or_slice)
def __len__(self):
return len(self._qs)
class VideoSitemap(Sitemap):
'''
Definition of video pages, based on the videos available on site.
TODO: Set video last modification time according to latest subtitle edition
'''
limit = 5000
changefreq = "weekly"
priority = 0.8
def items(self):
return VideoSitemapValuesQuery('video_id', 'edited')
@permalink
def location(self, obj):
return ('videos:video', [obj['video_id']], {'locale': ''})
def lastmod(self, obj):
edited = obj['edited']
return edited
sitemaps = {
'video':VideoSitemap,
'static':StaticSitemap,
}