-
Notifications
You must be signed in to change notification settings - Fork 17
/
filters.py
202 lines (175 loc) · 6.27 KB
/
filters.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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
# -*- coding: utf-8 -*-
import os
from datetime import datetime, timedelta
from flask import Markup, request
from pytz import utc
import six
from coaster.utils import md5sum
from coaster.gfm import markdown
from coaster.utils import text_blocks
from . import b_ as _, cache
from . import baseframe, current_app, get_timezone
from .utils import request_timestamp
from .views import ext_assets
@baseframe.app_template_filter('age')
def age(dt):
delta = request_timestamp() - dt
if delta.days == 0:
# < 1 day
if delta.seconds < 1:
return _(u"now")
if delta.seconds < 10:
return _(u"seconds ago")
elif delta.seconds < 60:
return _(u"%(num)s seconds ago", num=delta.seconds)
elif delta.seconds < 120:
return _(u"a minute ago")
elif delta.seconds < 3600: # < 1 hour
return _(u"%(num)s minutes ago", num=int(delta.seconds / 60))
elif delta.seconds < 7200: # < 2 hours
return _(u"an hour ago")
else:
return _("%(num)s hours ago", num=int(delta.seconds / 3600))
elif delta.days == 1:
return _(u"a day ago")
elif delta.days < 30:
return _(u"%(num)s days ago", num=delta.days)
elif delta.days < 60:
return _(u"a month ago")
elif delta.days < 365:
return _(u"%(num)s months ago", num=int(delta.days / 30))
elif delta.days < 730: # < 2 years
return _(u"a year ago")
else:
return _(u"%(num)s years ago", num=int(delta.days / 365))
@baseframe.app_template_filter('usessl')
def usessl(url):
"""
Convert a URL to https:// if SSL is enabled in site config
"""
if not current_app.config.get('USE_SSL'):
return url
if url.startswith('//'): # //www.example.com/path
return 'https:' + url
if url.startswith('/'): # /path
url = os.path.join(request.url_root, url[1:])
if url.startswith('http:'): # http://www.example.com
url = 'https:' + url[5:]
return url
@baseframe.app_template_filter('nossl')
def nossl(url):
"""
Convert a URL to http:// if using SSL
"""
if url.startswith('//'):
return 'http:' + url
if url.startswith('/') and request.url.startswith('https:'): # /path and SSL is on
url = os.path.join(request.url_root, url[1:])
if url.startswith('https://'):
return 'http:' + url[6:]
return url
@baseframe.app_template_filter('avatar_url')
def avatar_url(user, size=None):
if isinstance(size, (list, tuple)):
size = u'x'.join(size)
if user.avatar:
if size:
# TODO: Use a URL parser
if u'?' in user.avatar:
return user.avatar + u'&size=' + six.text_type(size)
else:
return user.avatar + u'?size=' + six.text_type(size)
else:
return user.avatar
email = user.email
if email:
if isinstance(email, six.string_types):
hash = md5sum(user.email) # Flask-Lastuser's User model has email as a string
else:
hash = email.md5sum # Lastuser's User model has email as a UserEmail object
gravatar = u'//www.gravatar.com/avatar/' + hash + u'?d=mm'
if size:
gravatar += u'&s=' + six.text_type(size)
return gravatar
# Return Gravatar's missing man image
return u'//www.gravatar.com/avatar/00000000000000000000000000000000?d=mm'
@baseframe.app_template_filter('render_field_options')
def render_field_options(field, **kwargs):
"""
Remove HTML attributes with a value of None or False before rendering a field.
"""
d = dict((k, v) for k, v in kwargs.items() if v is not None and v is not False)
if hasattr(field, 'widget_attrs'):
d.update(field.widget_attrs)
return field(**d)
@baseframe.app_template_filter('to_json')
def form_field_to_json(field, **kwargs):
d = {}
d['id'] = field.id
d['label'] = field.label.text
d['has_errors'] = bool(field.errors)
d['errors'] = list(dict(error=e) for e in field.errors)
d['is_listwidget'] = bool(hasattr(field.widget, 'html_tag') and field.widget.html_tag in ['ul', 'ol'])
try:
d['is_checkbox'] = (field.widget.input_type == 'checkbox')
except AttributeError:
d['is_checkbox'] = False
d['is_required'] = bool(field.flags.required)
d['render_html'] = Markup(render_field_options(field, **kwargs))
return d
@baseframe.app_template_filter('markdown')
def field_markdown(field):
html = markdown(field)
return Markup(html)
@baseframe.app_template_filter('ext_asset_url')
def ext_asset_url(asset):
"""
This filter makes ext_assets available to templates.
"""
if isinstance(asset, six.string_types):
return ext_assets([asset])
else:
return ext_assets(asset)
@baseframe.app_template_filter('firstline')
@cache.memoize(timeout=600)
def firstline(html):
"""
Returns the first line from a HTML blob as plain text
"""
result = text_blocks(html)
if result:
return result[0]
@baseframe.app_template_filter('cdata')
def cdata(text):
"""
Convert text to a CDATA sequence
"""
return Markup('<![CDATA[' + text.replace(']]>', ']]]]><![CDATA[>') + ']]>')
@baseframe.app_template_filter('shortdate')
def shortdate(value):
if isinstance(value, datetime):
tz = get_timezone()
if value.tzinfo is None:
dt = utc.localize(value).astimezone(tz)
else:
dt = value.astimezone(tz)
utc_now = utc.localize(request_timestamp()).astimezone(tz)
else:
dt = value
utc_now = request_timestamp().date()
if dt > (utc_now - timedelta(days=int(current_app.config.get('SHORTDATE_THRESHOLD_DAYS', 0)))):
return dt.strftime('%e %b')
else:
# The string replace hack is to deal with inconsistencies in the underlying
# implementation of strftime. See https://bugs.python.org/issue8304
return six.text_type(dt.strftime("%e %b '%y")).replace(u"'", u"’")
@baseframe.app_template_filter('longdate')
def longdate(value):
if isinstance(value, datetime):
if value.tzinfo is None:
dt = utc.localize(value).astimezone(get_timezone())
else:
dt = value.astimezone(get_timezone())
else:
dt = value
return dt.strftime('%e %B %Y')