"""スタジオ空き枠一覧のローカルサーバー。 python3 server.py # http://localhost:8000 python3 server.py 8080 # ポート指定 HOST=0.0.0.0 python3 server.py # コンテナ内など外から受ける場合 """ import json import os import sys from datetime import date from http.server import SimpleHTTPRequestHandler, ThreadingHTTPServer from pathlib import Path from urllib.parse import parse_qs, urlparse import providers ROOT = Path(__file__).resolve().parent STATIC = ROOT / "static" def load_studios(): return json.loads((ROOT / "studios.json").read_text(encoding="utf-8")) def slots_for(day): result = [] for studio in load_studios(): try: slots = providers.fetch(studio, day) error = None except Exception as e: # 1軒の取得失敗で一覧全体を落とさない slots, error = [], str(e) result.append({**studio, "slots": slots, "error": error}) return result class Handler(SimpleHTTPRequestHandler): def __init__(self, *args, **kwargs): super().__init__(*args, directory=str(STATIC), **kwargs) def do_GET(self): url = urlparse(self.path) if url.path != "/api/slots": return super().do_GET() qs = parse_qs(url.query) try: day = date.fromisoformat(qs.get("date", [date.today().isoformat()])[0]) except ValueError: return self.send_json({"error": "date は YYYY-MM-DD で指定してください"}, 400) self.send_json({"date": day.isoformat(), "studios": slots_for(day)}) def send_json(self, body, status=200): data = json.dumps(body, ensure_ascii=False).encode("utf-8") self.send_response(status) self.send_header("Content-Type", "application/json; charset=utf-8") self.send_header("Content-Length", str(len(data))) self.end_headers() self.wfile.write(data) if __name__ == "__main__": port = int(sys.argv[1]) if len(sys.argv) > 1 else 8000 host = os.environ.get("HOST", "127.0.0.1") print(f"http://{host}:{port}", flush=True) ThreadingHTTPServer((host, port), Handler).serve_forever()