forked from ScooloV/StrataScribe
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.py
More file actions
135 lines (109 loc) · 4.23 KB
/
main.py
File metadata and controls
135 lines (109 loc) · 4.23 KB
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
127
128
129
130
131
132
133
134
135
import os.path
import pathlib
import threading
import uuid
from flask import Flask, jsonify, render_template, request
from sublib import wahapedia_db, battle_parse, prepare_html
# File Extensions
FILE_EXT_ROS = ".ros"
FILE_EXT_ROSZ = ".rosz"
app = Flask(__name__)
upload_directory = os.path.abspath("./battlescribe")
_data_init_lock = threading.Lock()
_data_initialized = False
def ensure_data_initialized():
"""Lazily initialize Wahapedia data when needed."""
global _data_initialized
if _data_initialized:
return
with _data_init_lock:
if _data_initialized:
return
wahapedia_db.init_db()
battle_parse.init_parse()
_data_initialized = True
@app.route("/", methods=["GET", "POST"])
def upload_file():
# adding file filter for mobile requests
accept = 'accept = ".ros, .rosz"'
user_agent = request.headers.get("User-Agent", "").lower()
is_mobile = "mobile" in user_agent or "android" in user_agent
if is_mobile:
accept = ""
if request.method == "POST":
ensure_data_initialized()
f = request.files["file"]
file_ext = pathlib.Path(f.filename).suffix
if file_ext == FILE_EXT_ROS or file_ext == FILE_EXT_ROSZ:
random_filename = str(uuid.uuid4()) + file_ext
try:
# Ensure upload directory exists
os.makedirs(upload_directory, exist_ok=True)
f.save(os.path.join(upload_directory, random_filename))
# Parse the battlescribe file
json_phase, json_units, json_stratagems = (
battle_parse.parse_battlescribe(random_filename, request.form)
)
# Generate HTML output
html_phase = prepare_html.convert_to_table(json_phase)
# Handle multi-detachment: json_units is a list of dicts
if isinstance(json_units, list):
html_units = "".join(
[
prepare_html.convert_units_to_divs(units_dict)
for units_dict in json_units
if isinstance(units_dict, dict)
]
)
else:
html_units = prepare_html.convert_units_to_divs(json_units)
html_stratagems = prepare_html.convert_to_stratagem_list(
json_stratagems
)
return render_template(
"report.html",
html_phase=html_phase,
html_units=html_units,
html_stratagems=html_stratagems,
)
except (ValueError, FileNotFoundError) as e:
print(f"Error processing roster file: {e}")
return render_template(
"upload.html",
accept=accept,
error=f"Error processing roster file: {e}",
)
except ConnectionError as e:
print(f"Network error: {e}")
return render_template(
"upload.html",
accept=accept,
error="Network error: Unable to download game data. Please try again later.",
)
except Exception as e:
print(f"Unexpected error processing roster: {e}")
return render_template(
"upload.html",
accept=accept,
error="An unexpected error occurred. Please check your roster file and try again.",
)
else:
return render_template("upload.html", accept=accept)
if request.method == "GET":
return render_template("upload.html", accept=accept)
@app.route("/about", methods=["GET", "POST"])
def about_html():
return render_template("about.html")
@app.route("/health", methods=["GET"])
def health_check():
"""Simple health endpoint for monitoring."""
return jsonify(
{
"status": "ok",
"service": "StrataScribe",
"data_initialized": _data_initialized,
}
)
if __name__ == "__main__":
ensure_data_initialized()
app.run(host="0.0.0.0", debug=False)