Mercurial > wikked
view wikked/web.py @ 499:e75b39a762fd
web: Fixes for new version of werkzeug.
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Sun, 07 Jun 2020 00:15:07 -0700 |
parents | 0b696e838559 |
children |
line wrap: on
line source
import os import os.path import logging import urllib.parse from flask import Flask, abort, g from werkzeug.middleware.shared_data import SharedDataMiddleware from wikked.wiki import Wiki, WikiParameters # Create the main app. static_folder = os.path.join(os.path.dirname(__file__), 'static') app = Flask( 'wikked', static_folder=static_folder, static_url_path='/static') app.config.from_object('wikked.settings') app.config.from_envvar('WIKKED_SETTINGS', silent=True) # Setup some config defaults. app.config.setdefault('SQL_DEBUG', False) app.config.setdefault('SQL_COMMIT_ON_TEARDOWN', False) app.config.setdefault('WIKI_ROOT', None) app.config.setdefault('WIKI_UPDATE_ON_START', True) app.config.setdefault('WIKI_AUTO_RELOAD', False) app.config.setdefault('WIKI_ASYNC_UPDATE', False) app.config.setdefault('WIKI_SERVE_FILES', False) app.config.setdefault('WIKI_BROKER_URL', 'sqla+sqlite:///%(root)s/.wiki/broker.db') app.config.setdefault('WIKI_NO_FLASK_LOGGER', False) app.config.setdefault('WIKI_STYLESHEET', None) app.config.setdefault('PROFILE', False) app.config.setdefault('PROFILE_DIR', None) app.config.setdefault('INFLUXDB_HOST', None) app.config.setdefault('INFLUXDB_PORT', 8086) app.config.setdefault('INFLUXDB_USERNAME', 'root') app.config.setdefault('INFLUXDB_PASSWORD', 'root') app.config.setdefault('INFLUXDB_DATABASE', 'database') if app.config['WIKI_NO_FLASK_LOGGER']: app.logger.handlers = [] # Find the wiki root, and further configure the app if there's a # config file in there. wiki_root = app.config['WIKI_ROOT'] if wiki_root is None: from wikked.utils import find_wiki_root wiki_root = find_wiki_root() if wiki_root is None: raise Exception("Can't find the wiki root to use.") config_path = os.path.join(wiki_root, '.wiki', 'app.cfg') if os.path.isfile(config_path): app.config.from_pyfile(config_path) # Make the app serve static content and wiki assets in DEBUG mode. app.config['WIKI_ROOT'] = wiki_root app.config['WIKI_FILES_DIR'] = os.path.join(wiki_root, '_files') if app.config['WIKI_SERVE_FILES']: app.wsgi_app = SharedDataMiddleware( app.wsgi_app, {'/files': app.config['WIKI_FILES_DIR']}) # Add a special route for the `.well-known` directory. app.wsgi_app = SharedDataMiddleware( app.wsgi_app, {'/.well-known': os.path.join(wiki_root, '.well-known')}) # Profiling if app.config['PROFILE']: profile_dir = app.config['PROFILE_DIR'] from werkzeug.contrib.profiler import ProfilerMiddleware app.wsgi_app = ProfilerMiddleware(app.wsgi_app, profile_dir=profile_dir) # Customize logging. if app.config['DEBUG']: lg = logging.getLogger('wikked') lg.setLevel(logging.DEBUG) if app.config['SQL_DEBUG']: lg = logging.getLogger('sqlalchemy') lg.setLevel(logging.DEBUG) app.logger.debug("Creating Flask application...") # This lets components further modify the wiki that's created for # each request. app.wikked_post_init = [] # When requested, set the wiki as a request global. def get_wiki(): wiki = getattr(g, '_wiki', None) if wiki is None: wiki = Wiki(app.wiki_params) for i in app.wikked_post_init: i(wiki) wiki.start() g.wiki = wiki return wiki # Set the default wiki parameters. app.wiki_params = app.config.get('WIKI_FACTORY_PARAMETERS', None) if app.wiki_params is None: app.wiki_params = WikiParameters(wiki_root) # Just uncache pages when the user has edited one. def uncaching_wiki_updater(wiki, url): app.logger.debug("Uncaching all pages because %s was edited." % url) wiki.db.uncachePages(except_url=url, only_required=True) app.wiki_params.wiki_updater = uncaching_wiki_updater # Login extension. def user_loader(username): wiki = get_wiki() return wiki.auth.getUser(username) # Setup the Jinja environment. def get_read_url(url): return '/read/' + url.lstrip('/') def get_edit_url(url): return '/edit/' + url.lstrip('/') def get_rev_url(url, rev): return '/rev/%s?%s' % (url.lstrip('/'), urllib.parse.urlencode({'rev': rev})) def get_diff_url(url, rev1=None, rev2=None): args = {} if rev1 is not None: args['rev1'] = rev1 if rev2 is not None: args['rev2'] = rev2 if len(args) > 0: return '/diff/%s?%s' % (url.lstrip('/'), urllib.parse.urlencode(args)) return '/diff/%s' % url.lstrip('/') app.jinja_env.globals.update({ 'get_read_url': get_read_url, 'get_edit_url': get_edit_url, 'get_rev_url': get_rev_url, 'get_diff_url': get_diff_url }) from flask_login import LoginManager # NOQA login_manager = LoginManager() login_manager.init_app(app) login_manager.user_loader(user_loader) login_manager.unauthorized_handler(lambda: abort(401)) # Bcrypt extension. from wikked.bcryptfallback import Bcrypt # NOQA app.bcrypt = Bcrypt(app) # Import the views. import wikked.commonroutes # NOQA import wikked.api.admin # NOQA import wikked.api.edit # NOQA import wikked.api.history # NOQA import wikked.api.read # NOQA import wikked.api.special # NOQA import wikked.api.user # NOQA import wikked.views.admin # NOQA import wikked.views.edit # NOQA import wikked.views.error # NOQA import wikked.views.history # NOQA import wikked.views.read # NOQA import wikked.views.special # NOQA import wikked.views.user # NOQA # Async wiki update. if app.config['WIKI_ASYNC_UPDATE']: app.logger.debug("Will use Celery tasks to update the wiki...") from wikked.tasks import celery_app, update_wiki # Configure Celery. app.config['WIKI_BROKER_URL'] = app.config['WIKI_BROKER_URL'] % ( {'root': wiki_root}) celery_app.conf.update(app.config) app.logger.debug("Using Celery broker: %s" % app.config['WIKI_BROKER_URL']) # Make the wiki use the background update task. def async_updater(wiki): app.logger.debug("Running update task on Celery.") update_wiki.delay(wiki.root) app.wiki_params.wiki_updater = async_updater # InfluxDB metrics. if app.config['INFLUXDB_HOST']: try: import influxdb except ImportError: raise Exception("Please install the `influxdb` package if you need " "analytics for your Wikked app.") host = app.config['INFLUXDB_HOST'] port = app.config['INFLUXDB_PORT'] username = app.config['INFLUXDB_USERNAME'] password = app.config['INFLUXDB_PASSWORD'] database = app.config['INFLUXDB_DATABASE'] metrics_db = influxdb.InfluxDBClient(host, port, username, password, database) app.logger.info("Opening InfluxDB %s on %s:%s as %s." % ( database, host, port, username)) import time from flask import request, request_started, request_tearing_down def on_request_started(sender, **extra): g.metrics_start_time = time.clock() def on_request_tearing_down(sender, **extra): duration = time.clock() - g.metrics_start_time data = [ { "name": "requests", "columns": ["request_path", "compute_time"], "points": [ [str(request.path), duration] ] } ] metrics_db.write_points(data) request_started.connect(on_request_started, app) request_tearing_down.connect(on_request_tearing_down, app)