Passed
Push — master ( b4193c...0c92ed )
by Jace
01:43
created

enable_cache_busting()   B

Complexity

Conditions 5

Size

Total Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 30

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 11
ccs 0
cts 0
cp 0
cc 5
crap 30
rs 8.5454
1 1
import os
2 1
import logging
3 1
from urllib.parse import urlencode, unquote
4 1
5
from flask import request, current_app
6 1
from flask_api import FlaskAPI
7 1
from flask_api.exceptions import APIException, NotFound
8 1
import bugsnag
9
from bugsnag.flask import handle_exceptions
10 1
11 1
from . import extensions
12 1
from . import services
13 1
from . import stores
14
from . import routes
15
16 1
17
log = logging.getLogger('api')
18
19 1
20 1
class TemplateNotFound(NotFound):
21
    detail = "Template not found."
22
23 1
24 1
class InvalidMaskedCode(NotFound):
25
    detail = "Masked URL does not match any image."
26
27 1
28 1
class FilenameTooLong(APIException):
29 1
    status_code = 414
30
    detail = "Filename too long."
31
32 1
33 1
class InvalidImageLink(APIException):
34 1
    status_code = 415
35
    detail = "Unsupported image type."
36
37 1
38 1
def create_app(config):
39 1
    app = FlaskAPI(__name__)
40
    app.config.from_object(config)
41 1
42
    configure_exceptions(app)
43 1
    configure_logging(app)
44 1
45 1
    register_extensions(app)
46
    register_services(app)
47 1
    register_blueprints(app)
48
49 1
    return app
50
51
52 1
def configure_exceptions(app):
53 1
    if app.config['BUGSNAG_API_KEY']:  # pragma: no cover
54
        bugsnag.configure(
55 1
            api_key=app.config['BUGSNAG_API_KEY'],
56 1
            project_root=app.config['ROOT'],
57 1
        )
58
        handle_exceptions(app)
59
60 1
61 1
def configure_logging(app):
62
    logging.basicConfig(level=app.config['LOG_LEVEL'],
63
                        format="%(levelname)s: %(message)s")
64 1
    logging.getLogger('yorm').setLevel(logging.WARNING)
65 1
    logging.getLogger('requests').setLevel(logging.WARNING)
66
    logging.getLogger('PIL').setLevel(logging.INFO)
67
68
69
def register_extensions(app):
70
    extensions.cors.init_app(app, methods=['GET', 'OPTIONS'], allow_headers='*')
71
    extensions.cache_control.init_app(app)
72 1
73 1
74
def register_services(app):
75 1
    exceptions = services.Exceptions(
76 1
        TemplateNotFound,
77
        InvalidMaskedCode,
78 1
        FilenameTooLong,
79 1
        InvalidImageLink,
80
    )
81 1
82
    templates_root = os.path.join(app.config['ROOT'], 'data', 'templates')
83
    template_store = stores.template.TemplateStore(templates_root)
84
85 1
    fonts_root = os.path.join(app.config['ROOT'], 'data', 'fonts')
86
    font_store = stores.font.FontStore(fonts_root)
87
88
    images_root = os.path.join(app.config['ROOT'], 'data', 'images')
89 1
    image_store = stores.image.ImageStore(images_root, app.config)
90
91
    app.link_service = services.link.LinkService(
92
        exceptions=exceptions,
93 1
        template_store=template_store,
94
    )
95
    app.template_service = services.template.TemplateService(
96
        exceptions=exceptions,
97
        template_store=template_store,
98
    )
99
    app.font_service = services.font.FontService(
100 1
        exceptions=exceptions,
101 1
        font_store=font_store
102 1
    )
103 1
    app.image_service = services.image.ImageService(
104 1
        exceptions=exceptions,
105 1
        template_store=template_store,
106
        font_store=font_store,
107 1
        image_store=image_store,
108
    )
109 1
110
    def log_request(response):
111
        if current_app.debug:
112 1
            path = request.path
113 1
            if request.args:
114 1
                path += "?%s" % unquote(urlencode(request.args))
115 1
            log.info("%s: %s - %i", request.method, path,
116 1
                     response.status_code)
117 1
        return response
118 1
119 1
    app.after_request(log_request)
120 1
121 1
122 1
def register_blueprints(app):
123 1
    app.register_blueprint(routes.api_aliases.blueprint)
124 1
    app.register_blueprint(routes.api_fonts.blueprint)
125
    app.register_blueprint(routes.api_legacy.blueprint)
126
    app.register_blueprint(routes.api_links.blueprint)
127 1
    app.register_blueprint(routes.api_root.blueprint)
128
    app.register_blueprint(routes.api_search.blueprint)
129 1
    app.register_blueprint(routes.api_templates.blueprint)
130 1
    app.register_blueprint(routes.custom.blueprint)
131 1
    app.register_blueprint(routes.examples.blueprint)
132 1
    app.register_blueprint(routes.image.blueprint)
133 1
    app.register_blueprint(routes.index.blueprint)
134 1
    app.register_blueprint(routes.latest.blueprint)
135
    app.register_blueprint(routes.static.blueprint)
136