30 |
30 |
template_vars.update({'statics_hash': statics_hash.hexdigest()})
|
31 |
31 |
return template_vars
|
32 |
32 |
|
|
33 |
|
33 |
34 |
class RemoteTemplate(object):
|
34 |
35 |
def __init__(self, source):
|
35 |
|
self.source = source
|
|
36 |
self.source = urlparse.urlunparse(urlparse.urlparse(source)[:3] + ('', '', ''))
|
|
37 |
self.disable_recurse = False
|
36 |
38 |
|
37 |
39 |
@property
|
38 |
40 |
def cache_key(self):
|
39 |
|
return hashlib.md5(urlparse.urlunparse(
|
40 |
|
urlparse.urlparse(self.source)[:3] + ('', '', ''))).hexdigest()
|
|
41 |
return hashlib.md5(self.source).hexdigest()
|
41 |
42 |
|
42 |
43 |
def get_template(self):
|
43 |
44 |
item = cache.get(self.cache_key)
|
44 |
45 |
if item is None:
|
45 |
46 |
template_body = self.update_content()
|
46 |
47 |
if template_body is None:
|
|
48 |
logger.error('failed to retrieve theme')
|
47 |
49 |
raise Exception('Failed to retrieve theme')
|
48 |
50 |
else:
|
49 |
51 |
template_body, expiry_time = item
|
... | ... | |
51 |
53 |
# stale value, put it back into the cache for other consumers and
|
52 |
54 |
# update the content in a different thread
|
53 |
55 |
self.cache(template_body)
|
|
56 |
# for background refresh we do not care about retrieval miss
|
|
57 |
self.disable_recurse = True
|
54 |
58 |
threading.Thread(target=self.update_content).start()
|
55 |
59 |
return Template(template_body)
|
56 |
60 |
|
|
61 |
def recurse(self):
|
|
62 |
'''We were unable to retrieve a base template for this source URL, look for one level up.'''
|
|
63 |
if self.disable_recurse:
|
|
64 |
return None
|
|
65 |
parsed = urlparse.urlparse(self.source)
|
|
66 |
if not parsed.path or parsed.path == '/':
|
|
67 |
return None
|
|
68 |
if parsed.path.endswith('/'): # cd ..
|
|
69 |
new_path = urlparse.urljoin(parsed.path, '..')
|
|
70 |
else:
|
|
71 |
new_path = urlparse.urljoin(parsed.path, '.')
|
|
72 |
self.source = urlparse.urlunparse(parsed[:2] + (new_path, '', '', ''))
|
|
73 |
return self.get_template()
|
|
74 |
|
57 |
75 |
def update_content(self):
|
58 |
|
r = requests.get(settings.THEME_SKELETON_URL, params={'source': self.source})
|
|
76 |
try:
|
|
77 |
r = requests.get(settings.THEME_SKELETON_URL, params={'source': self.source})
|
|
78 |
except requests.RequestException:
|
|
79 |
return self.recurse()
|
59 |
80 |
if r.status_code != 200:
|
60 |
|
logger.error('failed to retrieve theme')
|
61 |
|
return None
|
|
81 |
return self.recurse()
|
62 |
82 |
self.cache(r.text)
|
63 |
83 |
return r.text
|
64 |
84 |
|
65 |
85 |
def cache(self, template_body):
|
66 |
86 |
expiry_time = datetime.datetime.now() + datetime.timedelta(seconds=CACHE_REFRESH_TIMEOUT)
|
67 |
|
cache.set(self.cache_key,
|
68 |
|
(template_body, expiry_time),
|
69 |
|
2592000) # bypass cache level expiration time
|
|
87 |
cache.set(self.cache_key, (template_body, expiry_time),
|
|
88 |
2592000) # bypass cache level expiration time
|
|
89 |
|
70 |
90 |
|
71 |
91 |
def theme_base(request):
|
72 |
92 |
# this context processor adds two variables to context:
|
73 |
|
-
|