first commit
This commit is contained in:
55
pytorrent/services/torrent_cache.py
Normal file
55
pytorrent/services/torrent_cache.py
Normal file
@@ -0,0 +1,55 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from threading import RLock
|
||||
from time import time
|
||||
from . import rtorrent
|
||||
|
||||
_VOLATILE = {"down_rate", "down_rate_h", "up_rate", "up_rate_h", "progress", "completed_bytes", "peers", "seeds", "ratio", "state", "status", "message", "down_total", "down_total_h", "up_total", "up_total_h"}
|
||||
|
||||
|
||||
class TorrentCache:
|
||||
def __init__(self):
|
||||
self._lock = RLock()
|
||||
self._data: dict[int, dict[str, dict]] = {}
|
||||
self._errors: dict[int, str] = {}
|
||||
self._updated_at: dict[int, float] = {}
|
||||
|
||||
def snapshot(self, profile_id: int) -> list[dict]:
|
||||
with self._lock:
|
||||
return list(self._data.get(profile_id, {}).values())
|
||||
|
||||
def error(self, profile_id: int) -> str:
|
||||
with self._lock:
|
||||
return self._errors.get(profile_id, "")
|
||||
|
||||
def refresh(self, profile: dict) -> dict:
|
||||
profile_id = int(profile["id"])
|
||||
try:
|
||||
rows = rtorrent.list_torrents(profile)
|
||||
fresh = {t["hash"]: t for t in rows}
|
||||
with self._lock:
|
||||
old = self._data.get(profile_id, {})
|
||||
added = [v for h, v in fresh.items() if h not in old]
|
||||
removed = [h for h in old.keys() if h not in fresh]
|
||||
updated = []
|
||||
for h, new in fresh.items():
|
||||
prev = old.get(h)
|
||||
if not prev:
|
||||
continue
|
||||
patch = {"hash": h}
|
||||
for key, value in new.items():
|
||||
if prev.get(key) != value:
|
||||
patch[key] = value
|
||||
if len(patch) > 1:
|
||||
updated.append(patch)
|
||||
self._data[profile_id] = fresh
|
||||
self._errors[profile_id] = ""
|
||||
self._updated_at[profile_id] = time()
|
||||
return {"ok": True, "profile_id": profile_id, "added": added, "updated": updated, "removed": removed}
|
||||
except Exception as exc:
|
||||
with self._lock:
|
||||
self._errors[profile_id] = str(exc)
|
||||
return {"ok": False, "profile_id": profile_id, "error": str(exc), "added": [], "updated": [], "removed": []}
|
||||
|
||||
|
||||
torrent_cache = TorrentCache()
|
||||
Reference in New Issue
Block a user