summaryrefslogtreecommitdiff
path: root/providers/__init__.py
diff options
context:
space:
mode:
authoryyamashita <yyamashita@hetzner.yyamashita.com>2026-11-01 09:19:55 +0900
committeryyamashita <yyamashita@hetzner.yyamashita.com>2026-11-01 09:19:55 +0900
commitdcb35334905f914dfd3eaa7453f0b019bd777588 (patch)
tree2a78d999c28b40abf682b0c2b7c3f1802b98c4f3 /providers/__init__.py
parentf0044f886359d942fe479a9a8a940af17c7047ac (diff)
スタジオセットごとにリンキィディンクの実際の空き枠を表示する
ダミーデータをやめ、Reserve Mart の会員ページから日別状況を読む。 取得結果は 5 分キャッシュし、ノアなど取れないスタジオは電話番号とリンクを出す。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'providers/__init__.py')
-rw-r--r--providers/__init__.py44
1 files changed, 35 insertions, 9 deletions
diff --git a/providers/__init__.py b/providers/__init__.py
index a32ed09..b9b07fc 100644
--- a/providers/__init__.py
+++ b/providers/__init__.py
@@ -1,18 +1,44 @@
"""空き枠の取得元。
-各 provider は fetch(studio, date) -> list[dict] を持つモジュール。
-返す dict は {"room": str, "hour": int, "status": "free" | "booked"}。
-hour は開始時刻(1時間枠)。studios.json の "provider" で使う provider を選ぶ。
+各 provider は fetch(studio, date) -> [{"name": 部屋名, "slots": [{"start": 分, "status"}]}]
+と booking_url(studio) を持つモジュール。status は "free" | "booked" | "closed"。
+studios.json の "provider" で使う provider を選ぶ(null ならオンラインで見られないスタジオ)。
+
+取得結果は CACHE_SECONDS の間メモリに置き、同じ日付を何度開いても相手サイトに負荷をかけない。
"""
-from . import manual, sample
+import threading
+import time
+
+from . import rinky
PROVIDERS = {
- "sample": sample,
- "manual": manual,
+ "rinky": rinky,
}
+CACHE_SECONDS = 300
+
+_cache = {}
+_cache_lock = threading.Lock()
+
+
+def booking_url(studio):
+ provider = PROVIDERS.get(studio.get("provider"))
+ return provider.booking_url(studio) if provider else None
+
-def fetch(studio, date):
- provider = PROVIDERS[studio["provider"]]
- return provider.fetch(studio, date)
+def fetch(studio_id, studio, day):
+ """(rooms, fetched_at) を返す。provider が無ければ (None, None)。"""
+ provider = PROVIDERS.get(studio.get("provider"))
+ if not provider:
+ return None, None
+ key = (studio_id, day.isoformat())
+ with _cache_lock:
+ hit = _cache.get(key)
+ if hit and time.time() - hit[1] < CACHE_SECONDS:
+ return hit
+ rooms = provider.fetch(studio, day)
+ entry = (rooms, time.time())
+ with _cache_lock:
+ _cache[key] = entry
+ return entry