75d3bd6 by Anon Ray at 2014-02-19 1
# -*-  coding: utf-8 -*-
2
"""
3
    __init__.py
4
"""
5
6
from flask import Flask, request, jsonify, render_template, make_response, g
7
import os
8fe0bbc by Anon Ray at 2014-05-10 8
import logging
ce66e4e by Anon Ray at 2014-05-11 9
from logging.handlers import RotatingFileHandler
75d3bd6 by Anon Ray at 2014-02-19 10
11
from classes.database import db
12
from config import DefaultConfig
13
from classes import views
14
#from classes import models
f867edb by Anon Ray at 2014-04-10 15
from classes import oauth
75d3bd6 by Anon Ray at 2014-02-19 16
17
__all__ = ['create_app', 'getDBInstance']
18
19
DEFAULT_APP_NAME = __name__
20
21
DEFAULT_MODULES = (
22
    (views.frontend, ''),
d120774 by Anon Ray at 2014-03-08 23
    (views.api, '/api'),
24
    (views.user, '/users'),
25
    (views.context, '/contexts'),
8fe0bbc by Anon Ray at 2014-05-10 26
    (views.sweet, '/sweets'),
f867edb by Anon Ray at 2014-04-10 27
    (views.app, '/apps'),
28
    (views.Oauth, '/oauth')
75d3bd6 by Anon Ray at 2014-02-19 29
)
30
31
32
def create_app(config=None, app_name=None, modules=None):
33
34
    if app_name is None:
35
        app_name = DEFAULT_APP_NAME
36
37
    if modules is None:
38
        modules = DEFAULT_MODULES
39
40
    app = Flask(app_name)
41
42
    configure_app(app, config)
43
44
    configure_logging(app)
45
    configure_errorhandlers(app)
46
    configure_extensions(app)
47
    #configure_beforehandlers(app)
48
    configure_modules(app, modules)
49
50
    return app
51
52
53
def configure_app(app, config):
54
55
    app.config.from_object(DefaultConfig())
56
57
    if config is not None:
58
        app.config.from_object(config)
59
60
    app.config.from_envvar('APP_CONFIG', silent=True)
61
62
63
def configure_modules(app, modules):
64
    for module, url_prefix in modules:
65
        app.register_module(module, url_prefix=url_prefix)
66
67
68
def configure_extensions(app):
69
    db.init_app(app)
70
    db.app = app
f867edb by Anon Ray at 2014-04-10 71
    oauth.init_app(app)
75d3bd6 by Anon Ray at 2014-02-19 72
73
# return the current db instance
74
# TODO: is this needed so much?
75
def getDBInstance():
76
    return db
77
78
79
def configure_errorhandlers(app):
80
81
    if app.testing:
82
        return
83
84
    # TODO: with all these request can we send back the respective HTTP status
85
    # codes instead of 200?
86
    @app.errorhandler(404)
87
    def not_found(error):
88
        response = make_response()
89
        response.status_code = 404
90
91
        if request.is_xhr:
92
            response.data = jsonify(error=error)
93
        else:
94
            response.data = render_template('errors/404.html')
95
96
        return response
97
98
    @app.errorhandler(403)
99
    def forbidden(error):
100
        response = make_response()
101
        response.status_code = 403
102
103
        if request.is_xhr:
104
            response.data = jsonify(error=error)
105
        else:
106
            response.data = render_template('errors/403.html')
107
108
        return response
109
110
    @app.errorhandler(401)
111
    def unauthorized(error):
112
        response = make_response()
113
        response.status_code = 401
114
115
        if request.is_xhr:
116
            response.data = jsonify(error=error)
117
        else:
118
            response.data = render_template('errors/401.html')
119
120
        return response
121
122
    @app.errorhandler(400)
123
    def bad_request(error):
124
        response = make_response()
125
        response.status_code = 400
126
127
        # Check if we have any custom error messages
d120774 by Anon Ray at 2014-03-08 128
        #if g.error:
129
        #    print 'g.error:'
130
        #    print g.error
131
        #    error = g.error
75d3bd6 by Anon Ray at 2014-02-19 132
133
        if request.is_xhr:
134
            response.data = jsonify(error=error)
135
        else:
136
            response.data = render_template('errors/400.html', error=error)
137
138
        return response
139
140
    @app.errorhandler(500)
141
    def server_error(error):
142
        response = make_response()
143
        response.status_code = 500
144
145
        if request.is_xhr:
146
            response.data = jsonify(error=error)
147
        else:
148
            response.data = render_template('errors/500.html')
149
150
        return response
151
152
153
def configure_logging(app):
8fe0bbc by Anon Ray at 2014-05-10 154
155
    formatter = logging.Formatter('%(asctime)s %(levelname)s: %(message)s '
156
                                  '[in %(pathname)s:%(lineno)d]')
157
158
    # Also error can be sent out via email. So we can also have a SMTPHandler?
d574b02 by Anon Ray at 2014-06-09 159
    log_file = os.path.join(os.path.dirname(__file__), '..',
160
                            app.config['LOG_FILE'])
161
162
    max_size = 1024 * 1024 * 20  # Max Size for a log file: 20MB
ce66e4e by Anon Ray at 2014-05-11 163
    log_handler = RotatingFileHandler(log_file, maxBytes=max_size,
164
                                      backupCount=10)
8fe0bbc by Anon Ray at 2014-05-10 165
166
    if app.config.has_key('LOG_LEVEL'):
167
        log_level = app.config['LOG_LEVEL'] or 'ERROR'
168
    else:
169
        log_level = 'ERROR'
170
171
    log_handler.setLevel(log_level)
172
    log_handler.setFormatter(formatter)
173
174
    app.logger.addHandler(log_handler)
75d3bd6 by Anon Ray at 2014-02-19 175