-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathpypew.py
126 lines (101 loc) · 4.14 KB
/
pypew.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
import argparse
import os
import sys
import webbrowser
from threading import Thread
from typing import Optional, Sequence
from dotenv import load_dotenv
from flask import Flask, url_for, redirect, request
from jinja2 import StrictUndefined
import filters
import views
from utils import logger
load_dotenv()
class PyPew:
def __init__(self) -> None:
self.app: Optional[Flask] = None
self.thread: Optional[Thread] = None
def create_app(pypew: Optional[PyPew] = None, **kwargs) -> Flask:
# https://stackoverflow.com/a/50132788
base_dir = '.'
if hasattr(sys, '_MEIPASS'):
base_dir = os.path.join(sys._MEIPASS)
app = Flask(
__name__,
static_folder=os.path.join(base_dir, 'static'),
template_folder=os.path.join(base_dir, 'templates'),
**kwargs
)
app.jinja_env.undefined = StrictUndefined
app.config['SERVER_NAME'] = os.environ.get('SERVER_NAME', 'localhost:5000')
app.config['SECRET_KEY'] = os.environ.get('SECRET_KEY', 'password')
# store session information server-side to avoid large cookies
# https://stackoverflow.com/questions/53551637/session-cookie-is-too-large-flask-application
app.config['SESSION_TYPE'] = 'filesystem'
app.add_url_rule(
'/', 'index_view', views.index_view, methods=['GET', 'POST']
)
app.add_url_rule('/acknowledgements', 'acknowledgements_view', views.acknowledgements_view)
app.add_url_rule('/feasts', 'feast_index_view', views.feast_index_view)
app.add_url_rule('/feasts/api', 'feast_index_api', views.feast_index_api)
app.add_url_rule('/feasts/api/upcoming', 'feast_upcoming_api', views.feast_upcoming_api)
app.add_url_rule('/feast/<slug>', 'feast_detail_view', views.feast_detail_view)
app.add_url_rule('/feast/api/<slug>', 'feast_detail_api', views.feast_detail_api)
app.add_url_rule('/feast/api/<slug>/date', 'feast_date_api', views.feast_date_api)
app.add_url_rule('/feast/<slug>/docx', 'feast_docx_view', views.feast_docx_view)
app.add_url_rule('/pewSheet', 'pew_sheet_create_view', views.pew_sheet_create_view, methods=['GET'])
app.add_url_rule('/pewSheet/docx', 'pew_sheet_docx_view', views.pew_sheet_docx_view, methods=['GET'])
app.add_url_rule('/pewSheet/clearHistory',
'pew_sheet_clear_history_endpoint',
views.pew_sheet_clear_history_endpoint,
methods=['DELETE'])
app.url_map.strict_slashes = False
@app.before_request
def clear_trailing_slashes():
"""https://stackoverflow.com/questions/40365390/trailing-slash-in-flask-route#40365514"""
rp = request.path
if rp != '/' and rp.endswith('/'):
return redirect(rp[:-1])
app.errorhandler(404)(views.not_found_handler)
app.errorhandler(Exception)(views.internal_error_handler)
for filter_name, filter_func in filters.filters_context.items():
app.template_filter(filter_name)(filter_func)
app.jinja_env.globals.update(len=len)
if pypew is not None:
pypew.app = app
app.app_context().push()
return app
def main(argv: Optional[Sequence[str]] = None) -> None:
"""
Start PyPew.
"""
parser = argparse.ArgumentParser()
parser.add_argument(
"--debug", help="Run in debug mode", action="store_true"
)
parser.add_argument(
"--no-launch",
help="Don't launch web browser automatically",
action="store_true"
)
args = parser.parse_args(argv)
pypew = PyPew()
app = create_app(pypew)
if args.debug:
# noinspection FlaskDebugMode
app.run(debug=True, load_dotenv=True)
else:
logger.info('Starting Flask app thread...')
# TODO use werkzeug server instead
pypew.thread = Thread(
target=lambda: app.run(debug=False, load_dotenv=True)
)
pypew.thread.start()
logger.info('Started Flask app. Close this terminal window to terminate PyPew.')
logger.info('Opening web browser...')
if not args.no_launch:
with app.app_context():
webbrowser.open(url_for('index_view'))
pypew.thread.join()
if __name__ == '__main__':
main()