fixup! Add some webrings
Docker Build and Push / build-and-push (push) Successful in 21s

This commit is contained in:
2026-04-09 05:37:08 +03:00
parent fd22c7552c
commit 7080d30510
+22 -79
View File
@@ -1,91 +1,28 @@
from __future__ import annotations
import atexit
import json
import os
import re
import tempfile
from time import time
from urllib.parse import urlsplit
import fcntl
import requests
from apscheduler.schedulers.background import BackgroundScheduler
from apscheduler.triggers.interval import IntervalTrigger
def _cache_dir() -> str:
path = os.environ.get("LAIR_CACHE_DIR", "/tmp/lair-cache")
os.makedirs(path, exist_ok=True)
return path
from blueprints.risdeveau.modules.api.scheduler_guard import should_start_scheduler
from blueprints.risdeveau.modules.api.shared_cache import (
atomic_write_json,
cache_file,
load_json_if_newer,
)
def _cache_file(name: str) -> str:
return os.path.join(_cache_dir(), f"{name}.json")
def _atomic_write_json(path: str, payload: dict) -> None:
parent = os.path.dirname(path) or "."
fd, tmp = tempfile.mkstemp(prefix=".tmp-", dir=parent)
try:
with os.fdopen(fd, "w", encoding="utf-8") as f:
json.dump(payload, f, ensure_ascii=False, separators=(",", ":"))
os.replace(tmp, path)
finally:
try:
if os.path.exists(tmp):
os.unlink(tmp)
except Exception:
pass
_CACHE_MTIME = 0.0
_LOCK_FD: int | None = None
def _load_json_if_newer(path: str, last_mtime: float) -> tuple[dict | None, float]:
try:
stat = os.stat(path)
except FileNotFoundError:
return None, last_mtime
except Exception:
return None, last_mtime
mtime = float(stat.st_mtime)
if mtime <= float(last_mtime):
return None, last_mtime
try:
with open(path, "r", encoding="utf-8") as f:
return json.load(f), mtime
except Exception:
return None, last_mtime
def _should_start_scheduler() -> bool:
global _LOCK_FD
if _LOCK_FD is not None:
return True
lock_path = os.environ.get("LAIR_SCHED_LOCK", "/tmp/lair-scheduler.lock")
fd = os.open(lock_path, os.O_CREAT | os.O_RDWR, 0o644)
try:
fcntl.flock(fd, fcntl.LOCK_EX | fcntl.LOCK_NB)
_LOCK_FD = fd
return True
except BlockingIOError:
os.close(fd)
return False
except Exception:
try:
os.close(fd)
finally:
return False
EURORING_SOURCE_URL = "https://euroring.neocities.org/scripts/onionring-variables.js"
EURORING_SITE_URL = "https://lair.moe"
EURORING_SOURCE_URL = os.environ.get(
"EURORING_SOURCE_URL",
"https://euroring.neocities.org/scripts/onionring-variables.js",
)
EURORING_SITE_URL = os.environ.get("EURORING_SITE_URL", "https://lair.moe")
EURORING_TIMEOUT = float(os.environ.get("EURORING_TIMEOUT", "10"))
@@ -102,8 +39,9 @@ data = {
"last_updated": 0,
}
_IS_WRITER = _should_start_scheduler()
_CACHE_PATH = _cache_file("webring")
_IS_WRITER = should_start_scheduler() if data["enabled"] else False
_CACHE_PATH = cache_file("webring")
_CACHE_MTIME = 0.0
def _site_key(url: str) -> tuple[str, int | None, str, str]:
@@ -127,7 +65,10 @@ def _parse_js_string_value(text: str, variable: str) -> str | None:
def _parse_bool_value(text: str, variable: str) -> bool | None:
match = re.search(rf"var\s+{re.escape(variable)}\s*=\s*(true|false)\s*;", text)
match = re.search(
rf"var\s+{re.escape(variable)}\s*=\s*(true|false)\s*;",
text,
)
if not match:
return None
return match.group(1) == "true"
@@ -195,7 +136,7 @@ def refresh_cache() -> None:
if _IS_WRITER:
return
payload, mtime = _load_json_if_newer(_CACHE_PATH, _CACHE_MTIME)
payload, mtime = load_json_if_newer(_CACHE_PATH, _CACHE_MTIME)
if payload is None:
return
@@ -203,10 +144,12 @@ def refresh_cache() -> None:
_CACHE_MTIME = mtime
def _persist_cache() -> None:
if not _IS_WRITER:
return
_atomic_write_json(_CACHE_PATH, data)
atomic_write_json(_CACHE_PATH, data)
def fetch_webring() -> None: