feat: 增加桌面端登录、视频清单和封面缓存
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
import hashlib
|
||||
import re
|
||||
import threading
|
||||
from pathlib import Path
|
||||
|
||||
from server.services.http import http
|
||||
|
||||
CACHE_DIR = Path(__file__).resolve().parents[2] / "cache" / "covers"
|
||||
_lock = threading.Lock()
|
||||
|
||||
|
||||
class CoverCache:
|
||||
def local_url(self, remote: str) -> str:
|
||||
remote = (remote or "").strip()
|
||||
if not remote.startswith(("http://", "https://")):
|
||||
return remote
|
||||
digest = hashlib.sha256(remote.encode("utf-8")).hexdigest()
|
||||
CACHE_DIR.mkdir(parents=True, exist_ok=True)
|
||||
meta = CACHE_DIR / f"{digest}.url"
|
||||
if not meta.is_file():
|
||||
meta.write_text(remote, encoding="utf-8")
|
||||
return f"/api/covers/{digest}"
|
||||
|
||||
def read(self, digest: str) -> tuple[bytes, str]:
|
||||
if not re.fullmatch(r"[0-9a-f]{64}", digest):
|
||||
raise RuntimeError("封面不存在")
|
||||
meta = CACHE_DIR / f"{digest}.url"
|
||||
body = CACHE_DIR / digest
|
||||
if not meta.is_file():
|
||||
raise RuntimeError("封面不存在")
|
||||
if body.is_file() and body.stat().st_size > 0:
|
||||
return body.read_bytes(), _media_type(body)
|
||||
remote = meta.read_text(encoding="utf-8").strip()
|
||||
data, media = http.get_bytes(remote)
|
||||
with _lock:
|
||||
CACHE_DIR.mkdir(parents=True, exist_ok=True)
|
||||
body.write_bytes(data)
|
||||
(CACHE_DIR / f"{digest}.type").write_text(media, encoding="utf-8")
|
||||
return data, media
|
||||
|
||||
|
||||
def _media_type(path: Path) -> str:
|
||||
sidecar = Path(f"{path}.type")
|
||||
if sidecar.is_file():
|
||||
media = sidecar.read_text(encoding="utf-8").strip()
|
||||
if media.startswith("image/"):
|
||||
return media
|
||||
return "image/jpeg"
|
||||
|
||||
|
||||
covers = CoverCache()
|
||||
Reference in New Issue
Block a user