Skip to content
Snippets Groups Projects
Select Git revision
  • 9577f8eff4771c0e5cad09c2fce35ca80610bce9
  • master default protected
2 results

task.md

Blame
  • __init__.py 4.19 KiB
    import datetime
    from mo import util_format
    import dateutil.tz
    from flask import Flask, request, g, session
    import flask.logging
    from flask_bootstrap import Bootstrap
    from flask_sqlalchemy import SQLAlchemy
    import locale
    import logging
    import os
    import werkzeug.exceptions
    
    import mo
    import mo.config as config
    import mo.db as db
    import mo.jobs
    import mo.users
    import mo.util
    from mo.util import logger
    
    # Flask interpretuje relativní cesty všelijak, tak mu vyrobíme absolutní
    mo.config.DATA_DIR = os.path.abspath(mo.config.DATA_DIR)
    static_dir = os.path.abspath('static')
    
    # Aplikační objekt
    app = Flask(__name__, instance_path=mo.config.DATA_DIR, static_folder=static_dir)
    app.config.from_object(config)
    app.jinja_options['extensions'].append('jinja2.ext.do')
    app.jinja_env.lstrip_blocks = True
    app.jinja_env.trim_blocks = True
    db.flask_db = SQLAlchemy(app, metadata=db.metadata)
    
    Bootstrap(app)  # make bootstrap libs accessible for the app
    
    # Nastavíme logování:
    #   - náš hlavní logger se jmenuje "mo"
    #   - app.logger se jmenuje "mo.web" a nepropaguje se do hlavního
    log_handler = flask.logging.default_handler
    log_formatter = logging.Formatter(fmt='%(asctime)-15s.%(msecs)03d %(levelname)-5.5s [%(process)s] (%(name)s) %(message)s', datefmt='%Y-%m-%d %H:%M:%S')
    log_handler.setFormatter(log_formatter)
    app.logger.removeHandler(log_handler)
    app.logger.setLevel(logging.DEBUG)
    root_logger = logging.getLogger()
    root_logger.addHandler(log_handler)
    
    # Budeme používat české locale
    locale.setlocale(locale.LC_COLLATE, 'cs_CZ.UTF-8')
    
    # Naše filtry pro Jinju
    
    app.jinja_env.filters.update(timeformat=util_format.timeformat)
    app.jinja_env.filters.update(inflected=util_format.inflect_number)
    app.jinja_env.filters.update(timedelta=util_format.timedelta)
    app.jinja_env.filters.update(time_and_timedelta=util_format.time_and_timedelta)
    
    
    # Inicializace požadavků a nucená autorizace
    
    class NeedLoginError(werkzeug.exceptions.Forbidden):
        description = 'Need to log in'
    
    
    def need_login():
        if not g.user:
            raise NeedLoginError()
    
    
    def init_request():
        if 'uid' in session:
            user = mo.users.user_by_uid(session['uid'])
            if not user:
                # Uživatel mezitím přestal existovat
                app.logging.error('Zrušena session pro neexistujícího uživatele uid=%s', session['uid'])
                return mo.web.main.logout()
        else:
            user = None
        g.user = user
        mo.now = mo.util.get_now()
        g.now = mo.now  # for templates
        mo.util.current_log_user = user
    
        # K některým podstromům je nutné mít speciální oprávnění
        # XXX: Když celá aplikace běží v adresáři, request.path je relativní ke kořeni aplikace, ne celého webu
        path = request.path
        if path.startswith('/org/'):
            if not user:
                raise NeedLoginError()
            if not (user.is_org or user.is_admin):
                raise werkzeug.exceptions.Forbidden()
        elif path.startswith('/user/'):
            if not user:
                raise NeedLoginError()
    
    
    app.before_request(init_request)
    
    
    ### UWSGI glue ###
    
    try:
        import uwsgi
        from uwsgidecorators import timer, signal
    
        # Čas od času se probudíme a projdeme joby pro případ, že by se ztratil signál.
        # Také při tom expirujeme zastaralé joby.
        @timer(config.JOB_GC_PERIOD, target='mule')
        def mule_timer(signum):
            app.logger.debug('Mule: Timer tick')
            with app.app_context():
                mo.now = mo.util.get_now()
                mo.jobs.process_jobs()
    
        # Obykle při vložení jobu dostaneme signál.
        @signal(42, target='mule')
        def mule_signal(signum):
            app.logger.debug('Mule: Přijat signál')
            with app.app_context():
                mo.now = mo.util.get_now()
                mo.jobs.process_jobs()
    
        def wake_up_mule():
            app.logger.debug('Mule: Posíláme signál')
            uwsgi.signal(42)
    
        mo.jobs.send_notify = wake_up_mule
    
    except ImportError:
        app.logger.warn('Nenalezeno UWSGI, takže automatické notifikace nepoběží.')
    
    
    # Většina webu je v samostatných modulech
    import mo.web.auth
    import mo.web.menu
    import mo.web.misc
    import mo.web.org
    import mo.web.org_contest
    import mo.web.org_jobs
    import mo.web.org_place
    import mo.web.org_round
    import mo.web.org_users
    import mo.web.user