diff options
| author | Danilo M. <danix@danix.xyz> | 2026-11-09 19:08:51 +0100 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-11-09 19:08:51 +0100 |
| commit | 15e384bc1d97c84df0545555bf4c298702c9eacb (patch) | |
| tree | f386400b398ebf55f9c3f2d060642e9b01255a95 /deckit/server.py | |
| parent | 4632e6183d38bfd239f066d7e9698f3d118a3f77 (diff) | |
| download | deck-it-15e384bc1d97c84df0545555bf4c298702c9eacb.tar.gz deck-it-15e384bc1d97c84df0545555bf4c298702c9eacb.zip | |
feat: card headers, music art/seek, clearer build card
Diffstat (limited to 'deckit/server.py')
| -rw-r--r-- | deckit/server.py | 25 |
1 files changed, 24 insertions, 1 deletions
diff --git a/deckit/server.py b/deckit/server.py index bddbb00..638322f 100644 --- a/deckit/server.py +++ b/deckit/server.py @@ -11,11 +11,12 @@ import mimetypes import os import secrets import socketserver +import subprocess import threading from http.cookies import CookieError, SimpleCookie from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer from pathlib import Path -from urllib.parse import parse_qs, urlsplit +from urllib.parse import parse_qs, unquote, urlparse, urlsplit from . import config, module, theme @@ -39,6 +40,25 @@ def token_path() -> Path: return config.user_config_path().parent / "token" +def _run(cmd, timeout=2): + try: + return subprocess.run(cmd, capture_output=True, text=True, timeout=timeout).stdout.strip() + except (OSError, subprocess.TimeoutExpired): + return "" + + +def art(): + """The current track's cover art, if the player exposes a local file.""" + url = _run(["playerctl", "metadata", "mpris:artUrl"]) + if not url.startswith("file://"): + return None + path = Path(unquote(urlparse(url).path)) + try: + return path.read_bytes(), mimetypes.guess_type(path)[0] or "image/png" + except OSError: + return None + + def load_token() -> str: """A per-machine secret the tablet's browser holds as a cookie.""" path = token_path() @@ -98,6 +118,9 @@ class Handler(BaseHTTPRequestHandler): if not self._authed(): return self._send(401) parts = path.strip("/").split("/") + if len(parts) == 2 and parts[1] == "art": + image = art() + return self._send(200, image[0], image[1], cache=True) if image else self._send(404) if len(parts) == 2 and parts[1] == "modules": return self._json(REGISTRY.names()) if len(parts) == 2: |
