kamiyama-map/server.py

43 lines
1.7 KiB
Python

import logging
from pathlib import Path
import urllib.error
import urllib.request
from flask import Flask, send_file
def create_app(debug_mode: bool = False):
app = Flask('map_server', static_folder='public', static_url_path='/')
osm_timeout = 3
http_code_ok = 200
if not debug_mode:
log = logging.getLogger('werkzeug')
log.setLevel(logging.WARNING)
@app.route('/')
def _index():
return app.send_static_file('index.html')
@app.route('/<int:zoom>/<int:x>/<int:y>.png')
def _tile(zoom: int, x: int, y: int):
tile_path = Path('data', str(zoom), str(x), f'{y}.png')
if tile_path.exists():
return send_file(tile_path)
if not tile_path.parent.exists():
tile_path.parent.mkdir(parents=True, exist_ok=True)
request = urllib.request.Request(f'https://tile.openstreetmap.org/{zoom}/{x}/{y}.png')
request.add_header('User-Agent', 'Mozilla/5.0 (X11; Linux x86_64; rv:138.0) Gecko/20100101 Firefox/138.0')
request.add_header('Accept', 'image/avif,image/webp,image/png,image/svg+xml,image/*;q=0.8,*/*;q=0.5')
request.add_header('Accept-Language', 'en-US,en;q=0.5')
request.add_header('Accept-Encoding', 'gzip, deflate, br, zstd')
try:
with urllib.request.urlopen(request, timeout=osm_timeout) as response:
if response.status != http_code_ok:
return (f'tile.openstreetmap.org answer is not OK (status: {response.status}) : {response.read()}',
501)
tile_path.write_bytes(response.read())
return send_file(tile_path)
except urllib.error.URLError as error:
return f'Cannot retrieve tile: {error}', 501
return app