This repository was archived by the owner on Apr 9, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathserver.py
195 lines (137 loc) · 5.49 KB
/
server.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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
from urllib.parse import parse_qs, parse_qsl
from flask import Flask, render_template, request
from implementation.quadtree import QuadTree
from tasdia import Map
from tasdia.layer import AreaData, AreaLayer
from tasdia.layer.area_layer import AreaDelta
from util import reveal_color
app = Flask(__name__)
maps: dict[int, Map] = {map_.id: map_ for map_ in (
Map.load('example/sat_map.json'),
Map.load('example/damegasique_map.json')
)}
def parse_data(request_) -> dict:
if request_.content_type == 'application/json':
return request_.get_json()
data = request_.get_data(as_text=True)
if not data:
return dict()
return dict(parse_qsl(data, strict_parsing=True))
@app.route('/')
def get_index():
return render_template('index.html')
@app.route('/map')
def get_map():
data = parse_qs(request.query_string.decode())
map_id = data.get('map')
if isinstance(map_id, list):
try:
map_id = int(map_id[0])
except ValueError:
return '올바르지 않은 지도 ID 형태', 400
else:
return '지도 아이디 주어지지 않음', 400
if map_id not in maps:
return '지도 아이디에 해당하는 지도 없음', 404
return render_template('map.html', map=maps[map_id])
@app.route('/api/map')
def get_api_map():
return {k: v.jsonify() for k, v in maps.items()}, 200
@app.route('/api/map/<int:map_id>')
def get_api_map_id(map_id: int):
if map_id not in maps:
return '지도 아이디에 해당하는 지도 없음', 404
return maps[map_id].jsonify(), 200
@app.route('/api/map/<int:map_id>/area')
def get_api_map_id_area(map_id: int):
if map_id not in maps:
return '지도 아이디에 해당하는 지도 없음', 404
return [layer.jsonify() for layer in maps[map_id].area_layers], 200
@app.route('/api/map/<int:map_id>/area/new', methods=['POST'])
def post_api_map_id_area_new(map_id: int):
map_ = maps.get(map_id)
if map_ is None:
return '지도 아이디에 해당하는 지도 없음', 404
data = parse_data(request)
description = data.get('description')
if description is None:
return '설명 지정되지 않음', 400
id_ = map_.get_new_area_id()
area_layer = AreaLayer(id_, description, dict(), QuadTree(None), QuadTree(None), list())
map_.add_area(area_layer)
map_.save()
return area_layer.jsonify(), 200
@app.route('/api/map/<int:map_id>/area/<int:area_id>')
def get_api_map_id_area_id(map_id: int, area_id: int):
if map_id not in maps:
return '지도 아이디에 해당하는 지도 없음', 404
layer = maps[map_id].get_area_layer(area_id)
if layer is None:
return '영역 아이디에 해당하는 영역 없음', 404
return layer.jsonify(), 200
@app.route('/api/map/<int:map_id>/area/<int:area_id>/new', methods=['POST'])
def post_api_map_id_area_id_new(map_id: int, area_id: int):
map_ = maps.get(map_id)
if map_ is None:
return '지도 아이디에 해당하는 지도 없음', 404
area = map_.get_area_layer(area_id)
if area is None:
return '영역 아이디에 해당하는 지도 없음', 404
data = parse_data(request)
time = data.get('time')
if time is None:
return '시점 지정되지 않음', 400
try:
time = float(time)
except ValueError:
return '올바르지 않은 시점 형태', 400
delta = data.get('delta')
if delta is None:
return '변경사항 지정되지 않음', 400
delta = QuadTree.loads(delta)
area_delta = AreaDelta(time, delta)
area.add_delta(area_delta)
map_.save()
return 'OK', 200
@app.route('/api/map/<int:map_id>/area/<int:area_id>/data')
def get_api_map_id_area_id_data(map_id: int, area_id: int):
if map_id not in maps:
return '지도 아이디에 해당하는 지도 없음', 404
layer = maps[map_id].get_area_layer(area_id)
if layer is None:
return '영역 아이디에 해당하는 영역 없음', 404
return dict(map(lambda x: (x[0], x[1].jsonify()), layer.metadata.items()))
@app.route('/api/map/<int:map_id>/area/<int:area_id>/data/new', methods=['POST'])
def post_api_map_id_area_id_data_new(map_id: int, area_id: int):
map_ = maps.get(map_id)
if map_ is None:
return '지도 아이디에 해당하는 지도 없음', 404
area_layer = map_.get_area_layer(area_id)
if area_layer is None:
return '영역 레이어 아이디에 해당하는 레이어 없음', 404
data = parse_data(request)
color = data.get('color')
description = data.get('description')
if not color:
return '색 지정되지 않음', 400
if not description:
return '설명 지정되지 않음', 400
try:
color = reveal_color(color)
except ValueError:
return '색 형태 올바르지 않음 ("#RRGGBB" 형태로 주어져야 함)', 400
id_ = area_layer.get_new_data_id()
area_data = AreaData(id_, description, color)
area_layer.add_data(area_data)
map_.save()
return area_data.jsonify(), 200
@app.route('/api/map/<int:map_id>/area/<int:area_id>/tree')
def get_api_map_id_area_id_tree(map_id: int, area_id: int):
if map_id not in maps:
return '지도 아이디에 해당하는 지도 없음', 404
layer = maps[map_id].get_area_layer(area_id)
if layer is None:
return '영역 아이디에 해당하는 영역 없음', 404
return layer.tree.saves(), 200
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0')