werkzeug

Форк
0
/
application.py 
94 строки · 3.4 Кб
1
"""Implements the wiki WSGI application which dispatches requests to
2
specific wiki pages and actions.
3
"""
4
from os import path
5

6
from sqlalchemy import create_engine
7
from werkzeug.middleware.shared_data import SharedDataMiddleware
8
from werkzeug.utils import redirect
9
from werkzeug.wsgi import ClosingIterator
10

11
from . import actions
12
from .database import metadata
13
from .database import session
14
from .specialpages import page_not_found
15
from .specialpages import pages
16
from .utils import href
17
from .utils import local
18
from .utils import local_manager
19
from .utils import Request
20

21
#: path to shared data
22
SHARED_DATA = path.join(path.dirname(__file__), "shared")
23

24

25
class SimpleWiki:
26
    """
27
    Our central WSGI application.
28
    """
29

30
    def __init__(self, database_uri):
31
        self.database_engine = create_engine(database_uri)
32

33
        # apply our middlewares.   we apply the middlewars *inside* the
34
        # application and not outside of it so that we never lose the
35
        # reference to the `SimpleWiki` object.
36
        self._dispatch = SharedDataMiddleware(
37
            self.dispatch_request, {"/_shared": SHARED_DATA}
38
        )
39

40
        # free the context locals at the end of the request
41
        self._dispatch = local_manager.make_middleware(self._dispatch)
42

43
    def init_database(self):
44
        """Called from the management script to generate the db."""
45
        metadata.create_all(bind=self.database_engine)
46

47
    def bind_to_context(self):
48
        """
49
        Useful for the shell.  Binds the application to the current active
50
        context.  It's automatically called by the shell command.
51
        """
52
        local.application = self
53

54
    def dispatch_request(self, environ, start_response):
55
        """Dispatch an incoming request."""
56
        # set up all the stuff we want to have for this request.  That is
57
        # creating a request object, propagating the application to the
58
        # current context and instantiating the database session.
59
        self.bind_to_context()
60
        request = Request(environ)
61
        request.bind_to_context()
62

63
        # get the current action from the url and normalize the page name
64
        # which is just the request path
65
        action_name = request.args.get("action") or "show"
66
        page_name = "_".join([x for x in request.path.strip("/").split() if x])
67

68
        # redirect to the Main_Page if the user requested the index
69
        if not page_name:
70
            response = redirect(href("Main_Page"))
71

72
        # check special pages
73
        elif page_name.startswith("Special:"):
74
            if page_name[8:] not in pages:
75
                response = page_not_found(request, page_name)
76
            else:
77
                response = pages[page_name[8:]](request)
78

79
        # get the callback function for the requested action from the
80
        # action module.  It's "on_" + the action name.  If it doesn't
81
        # exists call the missing_action method from the same module.
82
        else:
83
            action = getattr(actions, f"on_{action_name}", None)
84
            if action is None:
85
                response = actions.missing_action(request, action_name)
86
            else:
87
                response = action(request, page_name)
88

89
        # make sure the session is removed properly
90
        return ClosingIterator(response(environ, start_response), session.remove)
91

92
    def __call__(self, environ, start_response):
93
        """Just forward a WSGI call to the first internal middleware."""
94
        return self._dispatch(environ, start_response)
95

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.