from jinja2 import Environment, FileSystemLoader, environmentfilter from flask import Flask, request, session, g, redirect, url_for, abort, render_template, flash, send_from_directory, safe_join from docutils.core import publish_parts import os.path import os import fileinput import codecs TEMPLATE_DIR = os.path.join(os.path.dirname(__file__), 'pages') STATIC_DIR = os.path.join(os.path.dirname(__file__), 'static') BLOG_DIR = os.path.join(os.path.dirname(__file__), 'blog') MEETINGS_DIR = os.path.join(os.path.dirname(__file__), 'meetings') app = application = Flask('i2p2www', template_folder=TEMPLATE_DIR, static_url_path='/_static', static_folder=STATIC_DIR) app.debug = bool(os.environ.get('APP_DEBUG', 'False')) ########################## # Hooks - helper functions def after_this_request(f): if not hasattr(g, 'after_request_callbacks'): g.after_request_callbacks = [] g.after_request_callbacks.append(f) return f ########################### # Hooks - url preprocessing @app.url_value_preprocessor def pull_lang(endpoint, values): if not values: return g.lang=values.pop('lang', None) @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 ######################## # Hooks - before request # Detect and store chosen theme @app.before_request def detect_theme(): theme = 'duck' 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 = 'duck' g.theme = theme @after_this_request def remember_theme(resp): if g.theme == 'duck' and 'style' in request.cookies: resp.delete_cookie('style') elif g.theme != 'duck': resp.set_cookie('style', g.theme) return resp ############################ # Hooks - request processing @app.template_filter('restructuredtext') def restructuredtext(value): parts = publish_parts(source=value, writer_name="html") return parts['html_body'] ####################### # Hooks - after request @app.after_request def call_after_request_callbacks(response): for callback in getattr(g, 'after_request_callbacks', ()): response = callback(response) return response ############### # Error handlers @app.errorhandler(404) def page_not_found(error): return render_template('global/error_404.html'), 404 @app.errorhandler(500) def server_error(error): return render_template('global/error_500.html'), 500 ####################### # General page handlers # Index - redirects to en homepage @app.route('/') def main_index(): return redirect(url_for('site_show', lang='en')) # Site pages @app.route('//site/') @app.route('//site/') 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) if not os.path.exists(page_file): # Could be a directory, so try index.html name = 'site/%s/index.html' % page page_file = safe_join(TEMPLATE_DIR, name) if not os.path.exists(page_file): # bah! those damn users all the time! abort(404) # hah! return render_template(name, page=page) ################## # Meeting handlers # Meeting index @app.route('//meetings/')HTTP/1.1 200 OK Content-Disposition: inline; filename="__init__.py"; filename*=UTF-8''__init__.py Last-Modified: Fri, 14 Sep 2012 01:23:53 GMT Connection: close Content-Length: 9062 Content-Type: text/plain; charset=utf-8 X-Content-Type-Options: nosniff X-Frame-Options: SAMEORIGIN Date: Tue, 22 Jul 2025 23:25:00 GMT Cache-Control: public, max-age=21600, no-transform Etag: "f85648b8f8086b90edfe0f6483c32ad02dc28417" Access-Control-Expose-Headers: Content-Disposition X-Cache-Status: HIT X-Cache-Age: 0 from jinja2 import Environment, FileSystemLoader, environmentfilter from flask import Flask, request, session, g, redirect, url_for, abort, render_template, flash, send_from_directory, safe_join from docutils.core import publish_parts import os.path import os import fileinput import codecs TEMPLATE_DIR = os.path.join(os.path.dirname(__file__), 'pages') STATIC_DIR = os.path.join(os.path.dirname(__file__), 'static') BLOG_DIR = os.path.join(os.path.dirname(__file__), 'blog') MEETINGS_DIR = os.path.join(os.path.dirname(__file__), 'meetings') app = application = Flask('i2p2www', template_folder=TEMPLATE_DIR, static_url_path='/_static', static_folder=STATIC_DIR) app.debug = bool(os.environ.get('APP_DEBUG', 'False')) ########################## # Hooks - helper functions def after_this_request(f): if not hasattr(g, 'after_request_callbacks'): g.after_request_callbacks = [] g.after_request_callbacks.append(f) return f ########################### # Hooks - url preprocessing @app.url_value_preprocessor def pull_lang(endpoint, values): if not values: return g.lang=values.pop('lang', None) @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 ######################## # Hooks - before request # Detect and store chosen theme @app.before_request def detect_theme(): theme = 'duck' 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 = 'duck' g.theme = theme @after_this_request def remember_theme(resp): if g.theme == 'duck' and 'style' in request.cookies: resp.delete_cookie('style') elif g.theme != 'duck': resp.set_cookie('style', g.theme) return resp ############################ # Hooks - request processing @app.template_filter('restructuredtext') def restructuredtext(value): parts = publish_parts(source=value, writer_name="html") return parts['html_body'] ####################### # Hooks - after request @app.after_request def call_after_request_callbacks(response): for callback in getattr(g, 'after_request_callbacks', ()): response = callback(response) return response ############### # Error handlers @app.errorhandler(404) def page_not_found(error): return render_template('global/error_404.html'), 404 @app.errorhandler(500) def server_error(error): return render_template('global/error_500.html'), 500 ####################### # General page handlers # Index - redirects to en homepage @app.route('/') def main_index(): return redirect(url_for('site_show', lang='en')) # Site pages @app.route('//site/') @app.route('//site/') 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) if not os.path.exists(page_file): # Could be a directory, so try index.html name = 'site/%s/index.html' % page page_file = safe_join(TEMPLATE_DIR, name) if not os.path.exists(page_file): # bah! those damn users all the time! abort(404) # hah! return render_template(name, page=page) ################## # Meeting handlers # Meeting index @app.route('//meetings/')