1from os import path
2
3from sqlalchemy import create_engine
4from werkzeug.exceptions import HTTPException
5from werkzeug.middleware.shared_data import SharedDataMiddleware
6from werkzeug.wrappers import Request
7from werkzeug.wsgi import ClosingIterator
8
9from . import views  # noqa: F401
10from .database import metadata
11from .database import session
12from .utils import endpoints
13from .utils import local
14from .utils import local_manager
15from .utils import url_map
16
17#: path to shared data
18SHARED_DATA = path.join(path.dirname(__file__), "shared")
19
20
21class Plnt:
22    def __init__(self, database_uri):
23        self.database_engine = create_engine(database_uri)
24
25        self._dispatch = local_manager.middleware(self.dispatch_request)
26        self._dispatch = SharedDataMiddleware(self._dispatch, {"/shared": SHARED_DATA})
27
28    def init_database(self):
29        metadata.create_all(self.database_engine)
30
31    def bind_to_context(self):
32        local.application = self
33
34    def dispatch_request(self, environ, start_response):
35        self.bind_to_context()
36        local.request = request = Request(environ, start_response)
37        local.url_adapter = adapter = url_map.bind_to_environ(environ)
38        try:
39            endpoint, values = adapter.match(request.path)
40            response = endpoints[endpoint](request, **values)
41        except HTTPException as e:
42            response = e
43        return ClosingIterator(response(environ, start_response), session.remove)
44
45    def __call__(self, environ, start_response):
46        return self._dispatch(environ, start_response)
47