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('///.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