Files
I2P_Website/app.py

272 lines
7.3 KiB
Python
Raw Normal View History

2012-06-01 23:15:41 +00:00
from jinja2 import Environment, FileSystemLoader, environmentfilter
2012-06-01 21:15:42 +00:00
from flask import Flask, request, session, g, redirect, url_for, abort, render_template, flash, send_from_directory, safe_join
2012-06-03 01:06:09 +00:00
from docutils.core import publish_parts
2012-06-01 21:15:42 +00:00
import os.path
2012-06-01 23:15:41 +00:00
import os
2012-06-01 21:15:42 +00:00
import fileinput
2012-06-01 23:15:41 +00:00
import codecs
2012-06-01 21:15:42 +00:00
TEMPLATE_DIR = os.path.join(os.path.dirname(__file__), 'pages')
2012-06-01 23:15:41 +00:00
STATIC_DIR = os.path.join(os.path.dirname(__file__), 'static')
2012-06-03 01:06:09 +00:00
BLOG_DIR = os.path.join(os.path.dirname(__file__), 'blog')
2012-06-01 21:15:42 +00:00
MEETINGS_DIR = os.path.join(os.path.dirname(__file__), 'meetings')
2012-06-01 23:15:41 +00:00
app = application = Flask(__name__, template_folder=TEMPLATE_DIR, static_url_path='/_static', static_folder=STATIC_DIR)
2012-06-01 21:15:42 +00:00
app.debug = bool(os.environ.get('APP_DEBUG', 'False'))
@app.after_request
def call_after_request_callbacks(response):
for callback in getattr(g, 'after_request_callbacks', ()):
response = callback(response)
return response
def after_this_request(f):
if not hasattr(g, 'after_request_callbacks'):
g.after_request_callbacks = []
g.after_request_callbacks.append(f)
return f
2012-06-01 23:15:41 +00:00
@app.template_filter('restructuredtext')
def restructuredtext(value):
2012-06-01 23:15:41 +00:00
parts = publish_parts(source=value, writer_name="html")
return parts['html_body']
@app.url_value_preprocessor
def pull_lang(endpoint, values):
if not values:
return
g.lang=values.pop('lang', None)
2012-06-03 01:06:09 +00:00
@app.url_defaults
def set_lang(endpoint, values):
if not values:
return
if 'lang' in values:
return
if hasattr(g, 'lang'):
values['lang'] = g.lang
@app.before_request
def detect_theme():
theme = 'light'
if 'style' in request.cookies:
theme = request.cookies['style']
if 'theme' in request.args.keys():
theme = request.args['theme']
if not os.path.isfile(safe_join('static/styles', '%s.css' % theme)):
theme = 'light'
g.theme = theme
@after_this_request
def remember_theme(resp):
if g.theme == 'light' and 'style' in request.cookies:
resp.delete_cookie('style')
elif g.theme != 'light':
resp.set_cookie('style', g.theme)
return resp
2012-06-01 23:15:41 +00:00
2012-06-03 01:06:09 +00:00
@app.errorhandler(404)
def page_not_found(error):
return render_template('global/error_404.html'), 404
2012-09-10 11:28:34 +00:00
2012-06-01 21:15:42 +00:00
@app.route('/')
def main_index():
2012-06-01 21:15:42 +00:00
return redirect(url_for('site_show', lang='en'))
2012-06-03 01:06:09 +00:00
2012-06-01 21:15:42 +00:00
@app.route('/<string:lang>/site/')
@app.route('/<string:lang>/site/<path:page>')
2012-06-03 01:06:09 +00:00
def site_show(page='index'):
if page.endswith('.html'):
return redirect(url_for('site_show', page=page[:-5]))
name = 'site/%s.html' % page
page_file = safe_join(TEMPLATE_DIR, name)
2012-09-10 11:28:34 +00:00
2012-06-03 01:06:09 +00:00
# bah! those damn users all the time!
if not os.path.exists(page_file):
abort(404)
2012-09-10 11:28:34 +00:00
2012-06-03 01:06:09 +00:00
# hah!
return render_template(name, page=page)
2012-06-01 21:15:42 +00:00
@app.route('/<string:lang>/meetings/')
def meetings_index():
return render_template('meetings/index.html')
2012-06-01 21:15:42 +00:00
@app.route('/<string:lang>/meetings/<int:id>')
2012-06-01 23:15:41 +00:00
def meetings_show(id, log=False, rst=False):
2012-06-01 21:15:42 +00:00
"""
Render the meeting X.
Either display the raw IRC .log or render as html and include .rst as header if it exists
"""
# generate file name for the raw meeting file(and header)
lname = str(id) + '.log'
hname = str(id) + '.rst'
lfile = safe_join(MEETINGS_DIR, lname)
hfile = safe_join(MEETINGS_DIR, hname)
2012-09-10 11:28:34 +00:00
2012-06-01 21:15:42 +00:00
# check if meeting file exists and throw error if it does not..
if not os.path.exists(lfile):
abort(404)
2012-09-10 11:28:34 +00:00
2012-06-01 23:15:41 +00:00
# if the user just wanted the .log
if log:
# hmm... maybe replace with something non-render_template like?
# return render_template('meetings/show_raw.html', log=log)
return send_from_directory(MEETINGS_DIR, lname, mimetype='text/plain')
2012-09-10 11:28:34 +00:00
2012-06-01 21:15:42 +00:00
log=''
header=None
2012-09-10 11:28:34 +00:00
2012-06-01 23:15:41 +00:00
# try to load header if that makes sense
2012-06-01 21:15:42 +00:00
if os.path.exists(hfile):
2012-06-01 23:15:41 +00:00
# if the user just wanted the .rst...
if rst:
return send_from_directory(MEETINGS_DIR, hname, mimetype='text/plain')
2012-09-10 11:28:34 +00:00
2012-06-01 23:15:41 +00:00
# open the file as utf-8 file
with codecs.open(hfile, encoding='utf-8') as fd:
2012-06-01 21:15:42 +00:00
header = fd.read()
2012-06-01 23:15:41 +00:00
elif rst:
abort(404)
2012-09-10 11:28:34 +00:00
2012-06-01 23:15:41 +00:00
# load log
with codecs.open(lfile, encoding='utf-8') as fd:
log = fd.read()
2012-09-10 11:28:34 +00:00
2012-06-01 23:15:41 +00:00
return render_template('meetings/show.html', log=log, header=header, id=id)
2012-09-10 11:28:34 +00:00
2012-06-01 21:15:42 +00:00
2012-06-01 23:15:41 +00:00
@app.route('/<string:lang>/meetings/<int:id>.log')
def meetings_show_log(id):
return meetings_show(id, log=True)
@app.route('/<string:lang>/meetings/<int:id>.rst')
def meetings_show_rst(id):
return meetings_show(id, rst=True)
2012-06-01 21:15:42 +00:00
@app.route('/<string:lang>/download')
def downloads_list():
2012-06-03 01:06:09 +00:00
# TODO: read mirror list or list of available files
return render_template('downloads/list.html')
2012-06-01 21:15:42 +00:00
@app.route('/<string:lang>/download/<path:file>')
def downloads_select(file):
# TODO: implement
2012-06-01 21:15:42 +00:00
pass
2012-06-01 21:15:42 +00:00
@app.route('/download/<string:protocol>/any/<path:file>')
@app.route('/download/<string:protocol>/<string:mirror>/<path:file>')
def downloads_redirect(protocol, file, mirror=None):
# TODO: implement
2012-06-01 21:15:42 +00:00
pass
2012-06-03 01:06:09 +00:00
2012-09-10 09:38:42 +00:00
def get_blog_index():
"""
Returns list of valid slugs sorted by date
"""
ret=[]
2012-09-10 11:28:34 +00:00
2012-09-10 09:38:42 +00:00
# list of slugs(not sorted in any way)
entries=[]
# walk over all directories/files
for v in os.walk(BLOG_DIR):
# iterate over all files
for f in v[2]:
# ignore all non-.rst files
if not f.endswith('.rst'):
continue
2012-06-03 01:06:09 +00:00
def render_blog_entry(slug):
"""
Render the blog entry
TODO:
- caching
- move to own file
"""
# check if that file actually exists
path = safe_join(BLOG_DIR, slug + ".rst")
if not os.path.exists(path):
abort(404)
# read file
with codecs.open(path, encoding='utf-8') as fd:
content = fd.read()
2012-09-10 11:28:34 +00:00
2012-06-03 01:06:09 +00:00
return publish_parts(source=content, source_path=BLOG_DIR, writer_name="html")
2012-06-01 21:15:42 +00:00
@app.route('/<string:lang>/blog/')
@app.route('/<string:lang>/blog/page/<int:page>')
def blog_index(page=0):
# TODO: implement
2012-06-01 21:15:42 +00:00
pass
2012-06-01 21:15:42 +00:00
@app.route('/<string:lang>/blog/entry/<path:slug>')
def blog_entry(slug):
2012-06-03 01:06:09 +00:00
# try to render that blog entry.. throws 404 if it does not exist
parts = render_blog_entry(slug)
2012-09-10 11:28:34 +00:00
2012-06-03 01:06:09 +00:00
if parts:
# now just pass to simple template file and we are done
return render_template('blog/entry.html', parts=parts, title=parts['title'], body=parts['fragment'])
else:
abort(404)
2012-09-10 11:28:34 +00:00
2012-06-01 21:15:42 +00:00
@app.route('/feed/blog/rss')
def blog_rss():
# TODO: implement
2012-06-01 21:15:42 +00:00
pass
2012-06-01 21:15:42 +00:00
@app.route('/feed/blog/atom')
def blog_atom():
# TODO: implement
2012-06-01 21:15:42 +00:00
pass
2012-06-01 21:15:42 +00:00
## legacy stuff:
@app.route('/meeting<int:id>')
@app.route('/meeting<int:id>.html')
def legacy_meeting(id):
2012-06-01 23:15:41 +00:00
return redirect(url_for('meetings_show', id=id, lang='en'))
2012-06-01 21:15:42 +00:00
@app.route('/status-<int:year>-<int:month>-<int:day>')
@app.route('/status-<int:year>-<int:month>-<int:day>.html')
def legacy_status(year, month, day):
2012-06-01 23:15:41 +00:00
return redirect(url_for('blog_entry', lang='en', slug=('%s/%s/%s/status' % (year, month, day))))
2012-06-01 21:15:42 +00:00
2012-06-03 01:06:09 +00:00
LEGACY_MAP={
'download': 'downloads_list'
}
2012-06-01 21:15:42 +00:00
2012-06-03 01:06:09 +00:00
@app.route('/<string:f>_<string:lang>')
@app.route('/<string:f>_<string:lang>.html')
2012-06-01 21:15:42 +00:00
@app.route('/<string:f>')
2012-06-03 01:06:09 +00:00
@app.route('/<string:f>.html')
2012-06-01 21:15:42 +00:00
def legacy_show(f):
2012-06-03 01:06:09 +00:00
lang = 'en'
if hasattr(g, 'lang') and g.lang:
lang = g.lang
if f in LEGACY_MAP:
return redirect(url_for(LEGACY_MAP[f], lang=lang))
else:
return redirect(url_for('site_show', lang=lang, page=f))
if __name__ == '__main__':
app.run(debug=True)