forked from 3n1b-com/3n1b.com
-
Notifications
You must be signed in to change notification settings - Fork 0
/
helper.py
155 lines (136 loc) · 6.54 KB
/
helper.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
#!/usr/bin/env python
# coding=utf-8
#
# Copyright 2013 3n1b.com
import json
import re
from lib.variables import *
from lib.superjson import dumps
from jinja2 import evalcontextfilter, Markup, escape
from markdown import markdown
class Filters():
def __init__(self, jinja2_env):
self.jinja2 = jinja2_env
def register(self):
self.jinja2.filters["dump_errors"] = self.dump_errors
self.jinja2.filters["pagination"] = self.pagination
self.jinja2.filters["nl2br"] = self.nl2br
self.jinja2.filters["build_uri"] = build_uri
#self.jinja2.filters["tojson"] = json.JSONEncoder().encode
self.jinja2.filters["tojson"] = dumps
self.jinja2.filters["pretty_date"] = self.pretty_date
self.jinja2.filters["content_process"] = self.content_process
self.jinja2.filters["reply_process"] = self.reply_process
self.jinja2.filters["markdown"] = self.markdown
return self.jinja2
def dump_errors(self, errors):
t = self.jinja2.from_string("""
{% if errors %}
<ul class="errors alert alert-error">
{% for error in errors %}
<li>{{ ','.join(errors[error]) }}</li>
{% endfor %}
</ul>
{% endif %}
""")
return t.render(errors = errors)
def pagination(self, page, uri, list_rows = 10):
def gen_page_list(current_page = 1, total_page = 1, list_rows = 10):
if(total_page <= list_rows):
return range(1, total_page + 1)
if(current_page + list_rows > total_page):
return range(total_page - list_rows + 1, list_rows + 1)
return range(current_page, list_rows + 1)
t = self.jinja2.from_string("""
{% if page and not page.pages == 1 %}
<ul>
<li {% if page.current == page.prev %}class="disabled"{% endif %}><a href="{{ uri|build_uri('p', page.prev) }}">«</a></li>
{% for p in gen_page_list(page.current, page.pages, list_rows) %}
<li {% if page.current == p %}class="active"{% endif %}>
{% if not page.current == p %}
<a href="{{ uri|build_uri('p', p) }}">{{ p }}</a>
{% else %}
<a href="javascript:;">{{ p }}</a>
{% endif %}
</li>
{% endfor %}
<li {% if page.current == page.next %}class="disabled"{% endif %}><a href="{{ uri|build_uri('p', page.next) }}">»</a></li>
</ul>
{% endif %}
""")
return t.render(page = page, uri = uri, gen_page_list = gen_page_list, list_rows = list_rows)
@evalcontextfilter
def nl2br(self, eval_ctx, value):
_paragraph_re = re.compile(r'(?:\r\n|\r|\n){2,}')
result = u'\n\n'.join(u'<p>%s</p>' % p.replace('\n', '<br>\n') for p in _paragraph_re.split(escape(value)))
if eval_ctx.autoescape:
result = Markup(result)
return result
def pretty_date(self, time = False):
"""
Get a datetime object or a int() Epoch timestamp and return a
pretty string like 'an hour ago', 'Yesterday', '3 months ago',
'just now', etc
"""
if time == None:
return time
from datetime import datetime
now = datetime.now()
if type(time) is str or type(time) is unicode:
time = datetime.strptime(time, '%Y-%m-%d %H:%M:%S')
elif type(time) is int:
diff = now - datetime.fromtimestamp(time)
elif isinstance(time, datetime):
diff = now - time
elif not time:
diff = now - now
second_diff = diff.seconds
day_diff = diff.days
if day_diff < 0:
return ''
if day_diff == 0:
if second_diff < 10:
return "刚刚"
if second_diff < 60:
return str(second_diff) + " 秒前"
if second_diff < 120:
return "1 分钟前"
if second_diff < 3600:
return str(second_diff / 60) + " 分钟前"
if second_diff < 7200:
return "1 小时前"
if second_diff < 86400:
return str(second_diff / 3600) + " 小时前"
if day_diff == 1:
return "昨天"
if day_diff < 7:
return str(day_diff) + " 天前"
if day_diff < 31:
return str(day_diff / 7) + " 周前"
if day_diff < 365:
return str(day_diff / 30) + " 月前"
return str(day_diff / 365) + " 天前"
def content_process(self, content):
# render content included gist
content = re.sub(r'http(s)?:\/\/gist.github.com\/(\d+)(.js)?', r'<script src="http://gist.github.com/\2.js"></script>', content)
# render sinaimg pictures
content = re.sub(r'(http:\/\/\w+.sinaimg.cn\/.*?\.(jpg|gif|png))', r'<img src="\1" />', content)
# render @ mention links
content = re.sub(ur'@(?!_)(?!.*?_$)(?!\d+)([a-zA-Z0-9_\u4e00-\u9fa5]+)(\s|)', r'@<a href="/u/\1">\1</a> ', content)
# render youku videos
content = re.sub(r'http://v.youku.com/v_show/id_(\w+).html', r'<embed src="http://player.youku.com/player.php/sid/\1/v.swf" quality="high" width="646" height="404" align="middle" allowScriptAccess="sameDomain" allowFullscreen="true" type="application/x-shockwave-flash"></embed>', content)
return content
def reply_process(self, content):
# render content included gist
content = re.sub(r'http(s)?:\/\/gist.github.com\/(\d+)(.js)?', r'<script src="http://gist.github.com/\2.js"></script>', content)
# render sinaimg pictures
content = re.sub(r'(http:\/\/\w+.sinaimg.cn\/.*?\.(jpg|gif|png))', r'<img src="\1" />', content)
# render @ mention links
content = re.sub(ur'@(?!_)(?!.*?_$)(?!\d+)([a-zA-Z0-9_\u4e00-\u9fa5]+)(\s|)', r'@<a href="/u/\1">\1</a> ', content)
# render youku videos
content = re.sub(r'http://v.youku.com/v_show/id_(\w+).html', r'<embed src="http://player.youku.com/player.php/sid/\1/v.swf" quality="high" width="593" height="375" align="middle" allowScriptAccess="sameDomain" allowFullscreen="true" type="application/x-shockwave-flash"></embed>', content)
return content
def markdown(self, content):
if not content:
return ""
return markdown(content, extensions = ['codehilite', 'fenced_code', 'mathjax'], safe_mode = 'escape')