141 lines
3.9 KiB
Python
141 lines
3.9 KiB
Python
#!/usr/bin/env python3
|
|
# -*- coding: utf-8 -*-
|
|
|
|
import argparse
|
|
from http.server import ThreadingHTTPServer, BaseHTTPRequestHandler
|
|
from pathlib import Path
|
|
from urllib.parse import urlparse
|
|
|
|
|
|
def parse_args():
|
|
p = argparse.ArgumentParser(description="CM95 local PBF Web test server")
|
|
|
|
# This script is expected to live in:
|
|
# D:\React\cm93-mysql-importer-starter\web\
|
|
#
|
|
# Therefore the project root is automatically the parent directory.
|
|
p.add_argument(
|
|
"--release-id",
|
|
default="cm95-d1-62a85bd40d3a-6bc3c1352da3",
|
|
help="CM95 production release ID",
|
|
)
|
|
p.add_argument("--host", default="127.0.0.1")
|
|
p.add_argument("--port", type=int, default=8080)
|
|
return p.parse_args()
|
|
|
|
|
|
def main():
|
|
args = parse_args()
|
|
|
|
web_root = Path(__file__).resolve().parent
|
|
project_root = web_root.parent
|
|
|
|
release_dir = (
|
|
project_root
|
|
/ "build"
|
|
/ "releases"
|
|
/ args.release_id
|
|
)
|
|
pbf_root = release_dir / "pbf" / "delivery"
|
|
|
|
index_path = web_root / "index.html"
|
|
style_path = web_root / "style.json"
|
|
|
|
if not pbf_root.is_dir():
|
|
raise SystemExit(
|
|
"PBF directory not found:\n"
|
|
f"{pbf_root}\n\n"
|
|
"Expected project layout:\n"
|
|
f"{project_root}\\build\\releases\\{args.release_id}\\pbf\\delivery"
|
|
)
|
|
|
|
if not index_path.is_file():
|
|
raise SystemExit(f"index.html not found: {index_path}")
|
|
|
|
if not style_path.is_file():
|
|
raise SystemExit(f"style.json not found: {style_path}")
|
|
|
|
class Handler(BaseHTTPRequestHandler):
|
|
def send_bytes(self, data: bytes, content_type: str, status=200):
|
|
self.send_response(status)
|
|
self.send_header("Content-Type", content_type)
|
|
self.send_header("Content-Length", str(len(data)))
|
|
self.send_header("Cache-Control", "no-cache")
|
|
self.send_header("Access-Control-Allow-Origin", "*")
|
|
self.end_headers()
|
|
self.wfile.write(data)
|
|
|
|
def do_GET(self):
|
|
path = urlparse(self.path).path
|
|
|
|
if path in ("/", "/index.html"):
|
|
self.send_bytes(
|
|
index_path.read_bytes(),
|
|
"text/html; charset=utf-8",
|
|
)
|
|
return
|
|
|
|
if path == "/style.json":
|
|
self.send_bytes(
|
|
style_path.read_bytes(),
|
|
"application/json; charset=utf-8",
|
|
)
|
|
return
|
|
|
|
if path.startswith("/pbf/") and path.endswith(".pbf"):
|
|
parts = path[len("/pbf/"):].split("/")
|
|
|
|
if len(parts) != 3:
|
|
self.send_error(404)
|
|
return
|
|
|
|
z, x, yfile = parts
|
|
y = yfile[:-4]
|
|
|
|
if not (z.isdigit() and x.isdigit() and y.isdigit()):
|
|
self.send_error(404)
|
|
return
|
|
|
|
pbf = pbf_root / z / x / yfile
|
|
|
|
if not pbf.is_file():
|
|
self.send_error(404, "PBF tile not found")
|
|
return
|
|
|
|
self.send_bytes(
|
|
pbf.read_bytes(),
|
|
"application/vnd.mapbox-vector-tile",
|
|
)
|
|
return
|
|
|
|
self.send_error(404)
|
|
|
|
def log_message(self, fmt, *args):
|
|
print(f"{self.address_string()} - {fmt % args}")
|
|
|
|
server = ThreadingHTTPServer((args.host, args.port), Handler)
|
|
|
|
print("")
|
|
print("CM95 Web Test")
|
|
print("=" * 70)
|
|
print(f"Project : {project_root}")
|
|
print(f"Web : {web_root}")
|
|
print(f"Release : {release_dir}")
|
|
print(f"PBF : {pbf_root}")
|
|
print(f"Style : {style_path}")
|
|
print(f"URL : http://{args.host}:{args.port}/")
|
|
print("")
|
|
print("Ctrl+C to stop.")
|
|
|
|
try:
|
|
server.serve_forever()
|
|
except KeyboardInterrupt:
|
|
pass
|
|
finally:
|
|
server.server_close()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|
|
|