forked from Arachnid/bloggart
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathutils.py
156 lines (130 loc) · 4.93 KB
/
utils.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
154
155
156
import os
import re
import unicodedata
from google.appengine.ext import webapp
from google.appengine.ext.webapp.template import _swap_settings
import django.conf
from django import template
from django.template import loader
import config
BASE_DIR = os.path.dirname(__file__)
if isinstance(config.theme, (list, tuple)):
TEMPLATE_DIRS = config.theme
else:
TEMPLATE_DIRS = [os.path.abspath(os.path.join(BASE_DIR, 'themes/default'))]
if config.theme and config.theme != 'default':
TEMPLATE_DIRS.insert(0,
os.path.abspath(os.path.join(BASE_DIR, 'themes', config.theme)))
def slugify(s):
""" takes care of converting the post title into something suitable for a URL.
It replaces non alphanumeric characters with hyphens, then strips out any
leading or trailing hyphens. """
s = unicodedata.normalize('NFKD', s).encode('ascii', 'ignore')
return re.sub('[^a-zA-Z0-9-]+', '-', s).strip('-')
def format_post_path(post, num):
""" generates the path component of a URL for the post:
It slugifies the post's title, optionally appends a unique number, and then
formats the URL using the format string defined in the config file. """
slug = slugify(post.title)
if num > 0:
slug += '-%s' % str(num)
date = post.published_tz
return config.post_path_format % {
'slug': slug,
'year': date.year,
'month': date.month,
'day': date.day,
}
def format_user_path(user, num):
""" generates the path component of a URL for the user:
It slugifies the user's name, optionally appends a unique number, and then
formats the URL using the format string defined in the config file. """
slug = slugify(user.name)
if num > 0:
slug += "-" + str(num)
return '/%(slug)s' % {
'slug': slug
}
def get_template_vals_defaults(template_vals=None):
if not template_vals:
template_vals = {}
template_vals.update({
'config': config,
'devel': os.environ['SERVER_SOFTWARE'].startswith('Devel'),
})
return template_vals
def render_template(template_name, template_vals=None, theme=None):
template_vals = get_template_vals_defaults(template_vals)
template_vals.update({'template_name': template_name})
old_settings = _swap_settings({'TEMPLATE_DIRS': TEMPLATE_DIRS})
try:
tpl = loader.get_template(template_name)
rendered = tpl.render(template.Context(template_vals))
finally:
_swap_settings(old_settings)
return rendered
def _get_all_paths():
import static
keys = []
q = static.StaticContent.all(keys_only=True).filter('indexed', True)
cur = q.fetch(1000)
while len(cur) == 1000:
keys.extend(cur)
q = static.StaticContent.all(keys_only=True)
q.filter('indexed', True)
q.filter('__key__ >', cur[-1])
cur = q.fetch(1000)
keys.extend(cur)
return [x.name() for x in keys]
def _regenerate_sitemap():
import static
import gzip
from StringIO import StringIO
paths = _get_all_paths()
rendered = render_template('sitemap.xml', {'paths': paths})
static.set('/sitemap.xml', rendered, 'application/xml', False)
s = StringIO()
gzip.GzipFile(fileobj=s,mode='wb').write(rendered)
s.seek(0)
renderedgz = s.read()
static.set('/sitemap.xml.gz',renderedgz, 'application/x-gzip', False)
if config.google_sitemap_ping:
ping_googlesitemap()
def ping_googlesitemap():
import urllib
from google.appengine.api import urlfetch
google_url = 'http://www.google.com/webmasters/tools/ping?sitemap=http://%s/sitemap.xml.gz' % config.host
response = urlfetch.fetch(google_url, '', urlfetch.GET)
if response.status_code not in range(200, 300):
raise Warning('Google Sitemap ping failed', response.status_code, response.content)
def tzinfo():
"""
Returns an instance of a tzinfo implementation, as specified in
config.tzinfo_class; else, None.
"""
if not config.__dict__.get('tzinfo_class'):
return None
str = config.tzinfo_class
i = str.rfind('.')
try:
# from str[:i] import str[i+1:]
klass_str = str[i+1:]
mod = __import__(str[:i], globals(), locals(), [klass_str])
klass = getattr(mod, klass_str)
return klass()
except ImportError:
return None
def tz_field(property):
"""
For a DateTime property, make it timezone-aware if possible.
If it already is timezone-aware, don't do anything.
"""
if property.tzinfo:
return property
tz = tzinfo()
if tz:
# delay importing, hopefully after fix_path is done
from timezones.utc import UTC
return property.replace(tzinfo=UTC()).astimezone(tz)
else:
return property