Track posted photos. Cache images.
This commit is contained in:
parent
9fbe130841
commit
dc32cc7222
7 changed files with 78 additions and 10 deletions
|
|
@ -27,12 +27,17 @@ def create_app() -> Flask:
|
|||
secret_key = app.config.get("SECRET_KEY") or "dev-secret-key"
|
||||
app.config["SECRET_KEY"] = secret_key
|
||||
|
||||
db_path = app.config.get("ALT_TEXT_DB")
|
||||
if not db_path:
|
||||
db_path = str(Path(app.instance_path) / "alt_text_cache.db")
|
||||
app.config["ALT_TEXT_DB"] = db_path
|
||||
instance_dir = Path(app.instance_path)
|
||||
instance_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
Path(app.instance_path).mkdir(parents=True, exist_ok=True)
|
||||
db_path = app.config.get("STATION_DB")
|
||||
if not db_path:
|
||||
old_db = instance_dir / "alt_text_cache.db"
|
||||
new_db = instance_dir / "station_announcer.db"
|
||||
if old_db.exists() and not new_db.exists():
|
||||
old_db.rename(new_db)
|
||||
db_path = str(new_db)
|
||||
app.config["STATION_DB"] = db_path
|
||||
|
||||
app.immich_client = ImmichClient(
|
||||
base_url=app.config["IMMICH_API_URL"],
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ from __future__ import annotations
|
|||
import sqlite3
|
||||
from datetime import datetime, timezone
|
||||
from pathlib import Path
|
||||
from typing import Optional
|
||||
from typing import Dict, Iterable, Optional
|
||||
|
||||
|
||||
class AltTextCache:
|
||||
|
|
@ -33,6 +33,15 @@ class AltTextCache:
|
|||
)
|
||||
"""
|
||||
)
|
||||
conn.execute(
|
||||
"""
|
||||
CREATE TABLE IF NOT EXISTS asset_usage (
|
||||
asset_id TEXT PRIMARY KEY,
|
||||
last_posted_at TEXT NOT NULL,
|
||||
last_post_url TEXT
|
||||
)
|
||||
"""
|
||||
)
|
||||
conn.commit()
|
||||
|
||||
def get(self, asset_id: str) -> Optional[str]:
|
||||
|
|
@ -57,3 +66,31 @@ class AltTextCache:
|
|||
(asset_id, alt_text, timestamp),
|
||||
)
|
||||
conn.commit()
|
||||
|
||||
def mark_posted(self, asset_id: str, post_url: Optional[str] = None) -> None:
|
||||
timestamp = datetime.now(timezone.utc).isoformat()
|
||||
with self._connect() as conn:
|
||||
conn.execute(
|
||||
"""
|
||||
INSERT INTO asset_usage(asset_id, last_posted_at, last_post_url)
|
||||
VALUES(?, ?, ?)
|
||||
ON CONFLICT(asset_id)
|
||||
DO UPDATE SET last_posted_at = excluded.last_posted_at,
|
||||
last_post_url = excluded.last_post_url
|
||||
""",
|
||||
(asset_id, timestamp, post_url),
|
||||
)
|
||||
conn.commit()
|
||||
|
||||
def get_usage_map(self, asset_ids: Iterable[str]) -> Dict[str, sqlite3.Row]:
|
||||
ids = [asset_id for asset_id in asset_ids if asset_id]
|
||||
if not ids:
|
||||
return {}
|
||||
placeholders = ",".join(["?"] * len(ids))
|
||||
query = (
|
||||
"SELECT asset_id, last_posted_at, last_post_url FROM asset_usage"
|
||||
f" WHERE asset_id IN ({placeholders})"
|
||||
)
|
||||
with self._connect() as conn:
|
||||
rows = conn.execute(query, ids).fetchall()
|
||||
return {row["asset_id"]: row for row in rows}
|
||||
|
|
|
|||
|
|
@ -19,13 +19,15 @@ def load_settings() -> Dict[str, str]:
|
|||
|
||||
load_dotenv()
|
||||
|
||||
db_path = os.getenv("STATION_DB", "")
|
||||
|
||||
settings: Dict[str, str] = {
|
||||
"IMMICH_API_URL": os.getenv("IMMICH_API_URL", DEFAULT_IMMICH_URL).rstrip("/"),
|
||||
"IMMICH_API_KEY": os.getenv("IMMICH_API_KEY", ""),
|
||||
"OPENAI_API_KEY": os.getenv("OPENAI_API_KEY", ""),
|
||||
"RECENT_DAYS": int(os.getenv("RECENT_DAYS", "3")),
|
||||
"OPENAI_MODEL": os.getenv("OPENAI_MODEL", "gpt-4o-mini"),
|
||||
"ALT_TEXT_DB": os.getenv("ALT_TEXT_DB", ""),
|
||||
"STATION_DB": db_path,
|
||||
"SECRET_KEY": os.getenv("SECRET_KEY", ""),
|
||||
"MASTODON_BASE_URL": os.getenv(
|
||||
"MASTODON_BASE_URL", "http://localhost:3000"
|
||||
|
|
|
|||
|
|
@ -205,14 +205,21 @@ def compose_select():
|
|||
except ImmichError as exc:
|
||||
error_message = str(exc)
|
||||
|
||||
usage_map = alt_cache.get_usage_map(asset.id for asset in asset_objs)
|
||||
|
||||
assets = []
|
||||
for asset in asset_objs:
|
||||
usage = usage_map.get(asset.id)
|
||||
assets.append(
|
||||
{
|
||||
"id": asset.id,
|
||||
"file_name": asset.file_name,
|
||||
"captured_display": _humanize_timestamp(asset.captured_at),
|
||||
"alt_text": alt_cache.get(asset.id),
|
||||
"posted": bool(usage),
|
||||
"last_posted_display": _humanize_timestamp(
|
||||
usage["last_posted_at"] if usage else None
|
||||
),
|
||||
}
|
||||
)
|
||||
|
||||
|
|
@ -369,6 +376,8 @@ def compose_draft():
|
|||
post_text.strip(), media_ids, in_reply_to_id=reply_id
|
||||
)
|
||||
status_url = status.get("url")
|
||||
for asset in assets:
|
||||
alt_cache.mark_posted(asset.id, status_url)
|
||||
if status_url:
|
||||
flash(
|
||||
f'Post sent to Mastodon: <a href="{status_url}" target="_blank" rel="noopener">{status_url}</a>',
|
||||
|
|
@ -407,4 +416,6 @@ def asset_proxy(asset_id: str, variant: str):
|
|||
content, mimetype = immich_client.fetch_asset_content(asset_id, variant)
|
||||
except ImmichError as exc:
|
||||
abort(404, description=str(exc))
|
||||
return Response(content, mimetype=mimetype)
|
||||
response = Response(content, mimetype=mimetype)
|
||||
response.headers.setdefault("Cache-Control", "public, max-age=3600")
|
||||
return response
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue