summaryrefslogtreecommitdiff
path: root/providers/__init__.py
diff options
context:
space:
mode:
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