forked from idan/gistio
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgistio.py
93 lines (75 loc) · 2.5 KB
/
gistio.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
import os
import json
import urlparse
from redis import StrictRedis
from markdown2 import markdown
import requests
import bleach
from flask import Flask, render_template, make_response, abort
app = Flask(__name__)
HEROKU = 'HEROKU' in os.environ
if HEROKU:
urlparse.uses_netloc.append('redis')
redis_url = urlparse.urlparse(os.environ['REDISTOGO_URL'])
cache = StrictRedis(host=redis_url.hostname,
port=redis_url.port,
password=redis_url.password)
PORT = int(os.environ.get('PORT', 5000))
STATIC_URL = '//static.gist.io/'
else:
cache = StrictRedis() # local development
PORT = 5000
STATIC_URL = ''
CACHE_EXPIRATION = 60 # seconds
RENDERABLE = [u'Markdown', u'Text']
ALLOWED_TAGS = [
"a", "abbr", "acronym", "b", "blockquote", "code", "em", "i", "li", "ol", "strong",
"ul", "br", "img", "span", "div", "pre", "p", "dl", "dd", "dt", "tt", "cite", "h1",
"h2", "h3", "h4", "h5", "h6", "table", "col", "tr", "td", "th", "tbody", "thead",
"colgroup", "hr",
]
ALLOWED_ATTRIBUTES = {
"a": ["href", "title"],
"acronym": ["title"],
"abbr": ["title"],
"img": ["src"],
}
@app.route('/')
def homepage():
return render_template('home.html', static_url=STATIC_URL)
@app.route('/<int:id>')
def render_gist(id):
return render_template('gist.html', gist_id=id, static_url=STATIC_URL)
@app.route('/<int:id>/content')
def gist_contents(id):
cache_hit = True
content = cache.get(id)
if not content:
cache_hit = False
content = fetch_and_render(id)
if content is None:
abort(404)
resp = make_response(content, 200)
resp.headers['Content-Type'] = 'application/json'
resp.headers['X-Cache-Hit'] = cache_hit
resp.headers['X-Expire-TTL-Seconds'] = cache.ttl(id)
return resp
def fetch_and_render(id):
"""Fetch and render a post from the Github API"""
r = requests.get('https://api.github.com/gists/{}'.format(id))
if r.status_code != 200:
return None
decoded = r.json.copy()
for f in decoded['files'].values():
if f['language'] in RENDERABLE:
f['rendered'] = bleach.clean(markdown(f['content']),
tags=ALLOWED_TAGS, attributes=ALLOWED_ATTRIBUTES)
encoded = json.dumps(decoded)
cache.setex(id, CACHE_EXPIRATION, encoded)
return encoded
if __name__ == '__main__':
if HEROKU:
app.run(host='0.0.0.0', port=PORT)
else:
cache.flushall()
app.run(host='0.0.0.0', debug=True, port=PORT)