初始化奇妙小屏幕控制器项目
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import logging
|
||||
from pathlib import Path
|
||||
from uuid import uuid4
|
||||
|
||||
from PIL import Image, ImageDraw
|
||||
|
||||
from app.persistence import atomic_write_bytes
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
STARTUP_BRIGHTNESS = 50
|
||||
OPEN_EYE_SECONDS = 1.3
|
||||
CLOSED_EYE_SECONDS = 0.2
|
||||
BACKGROUND = (255, 255, 255)
|
||||
PINK = (255, 79, 163)
|
||||
_PROCESS_BOOT_ID = f"process-{uuid4()}"
|
||||
|
||||
|
||||
def render_startup_smile(*, eyes_closed: bool = False) -> Image.Image:
|
||||
image = Image.new("RGB", (64, 64), BACKGROUND)
|
||||
draw = ImageDraw.Draw(image)
|
||||
|
||||
if eyes_closed:
|
||||
draw.rectangle((14, 23, 25, 26), fill=PINK)
|
||||
draw.rectangle((38, 23, 49, 26), fill=PINK)
|
||||
else:
|
||||
draw.rectangle((16, 18, 23, 29), fill=PINK)
|
||||
draw.rectangle((40, 18, 47, 29), fill=PINK)
|
||||
|
||||
for box in (
|
||||
(14, 36, 17, 39),
|
||||
(18, 40, 21, 43),
|
||||
(22, 44, 25, 47),
|
||||
(26, 48, 37, 51),
|
||||
(38, 44, 41, 47),
|
||||
(42, 40, 45, 43),
|
||||
(46, 36, 49, 39),
|
||||
):
|
||||
draw.rectangle(box, fill=PINK)
|
||||
|
||||
return image
|
||||
|
||||
|
||||
def read_boot_id() -> str:
|
||||
try:
|
||||
value = Path("/proc/sys/kernel/random/boot_id").read_text(encoding="ascii").strip()
|
||||
if value:
|
||||
return value
|
||||
except (OSError, UnicodeError):
|
||||
logger.info("Linux boot ID is unavailable; using the current process session")
|
||||
return _PROCESS_BOOT_ID
|
||||
|
||||
|
||||
class StartupSessionStore:
|
||||
def __init__(self, data_dir: Path, boot_id: str | None = None) -> None:
|
||||
self.path = data_dir / "startup_indicator.json"
|
||||
self.boot_id = boot_id or read_boot_id()
|
||||
|
||||
def should_show(self) -> bool:
|
||||
if not self.path.exists():
|
||||
return True
|
||||
try:
|
||||
raw = json.loads(self.path.read_text(encoding="utf-8"))
|
||||
if not isinstance(raw, dict):
|
||||
raise ValueError("startup indicator state must be an object")
|
||||
return raw.get("dismissed_boot_id") != self.boot_id
|
||||
except (OSError, ValueError, TypeError):
|
||||
logger.exception("Startup indicator state is invalid; showing the indicator")
|
||||
return True
|
||||
|
||||
def mark_dismissed(self) -> None:
|
||||
atomic_write_bytes(
|
||||
self.path,
|
||||
(
|
||||
json.dumps(
|
||||
{"dismissed_boot_id": self.boot_id},
|
||||
ensure_ascii=False,
|
||||
indent=2,
|
||||
)
|
||||
+ "\n"
|
||||
).encode("utf-8"),
|
||||
)
|
||||
Reference in New Issue
Block a user