chore: rebrand Subfeed -> Siftlode

Rename all user-facing references (UI wordmark Sift+lode, titles, app name,
legal pages, onboarding wizard, emails, README/docs) and infra paths
(/srv/subfeed -> /srv/siftlode, image tag, deploy script, backup filenames).

Internal identifiers kept on purpose: Postgres user/db "subfeed", logger
namespace, localStorage keys, and the subfeed_pgdata volume (renaming would
orphan the migrated production data).
This commit is contained in:
npeter83 2026-06-14 04:40:22 +02:00
parent 53307ea206
commit 9ace042510
20 changed files with 54 additions and 54 deletions

View file

@ -8,7 +8,7 @@ _DEFAULT_SECRET_KEY = "change-me-session-key"
class Settings(BaseSettings):
model_config = SettingsConfigDict(env_file=".env", extra="ignore")
app_name: str = "Subfeed"
app_name: str = "Siftlode"
database_url: str = "postgresql+psycopg://subfeed:subfeed@db:5432/subfeed"
@ -35,7 +35,7 @@ class Settings(BaseSettings):
smtp_port: int = 587
smtp_user: str = ""
smtp_password: str = ""
smtp_from: str = "" # e.g. "Subfeed <addr@gmail.com>"; falls back to smtp_user
smtp_from: str = "" # e.g. "Siftlode <addr@gmail.com>"; falls back to smtp_user
# --- Sync / YouTube Data API ---
# Optional API key for public reads (channels/videos/playlistItems). When set it is

View file

@ -56,20 +56,20 @@ def send_access_approved(email: str) -> bool:
admin = _admin_contact()
body = (
"Hi,\n\n"
"Your request to use Subfeed has been approved — welcome aboard.\n\n"
"Just open Subfeed and sign in with this Google account, and your YouTube\n"
"Your request to use Siftlode has been approved — welcome aboard.\n\n"
"Just open Siftlode and sign in with this Google account, and your YouTube\n"
"subscriptions feed will be ready.\n\n"
"If you weren't expecting this, you can ignore the message.\n\n"
"— Subfeed"
"— Siftlode"
+ (f"\n\nQuestions? Just reply to this email ({admin})." if admin else "")
)
return _send([email], "You're in — your Subfeed access is approved", body, reply_to=admin)
return _send([email], "You're in — your Siftlode access is approved", body, reply_to=admin)
def send_admin_new_request(admins: list[str], requester: str) -> bool:
body = (
f"{requester} just requested access to Subfeed.\n\n"
"Open Subfeed → Settings → Account → Access requests to approve or deny it.\n\n"
f"{requester} just requested access to Siftlode.\n\n"
"Open Siftlode → Settings → Account → Access requests to approve or deny it.\n\n"
"(Reply to this email to reach the requester directly.)\n"
)
return _send(admins, f"Subfeed access request from {requester}", body, reply_to=requester)
return _send(admins, f"Siftlode access request from {requester}", body, reply_to=requester)

View file

@ -32,12 +32,12 @@ from app.scheduler import shutdown_scheduler, start_scheduler
@asynccontextmanager
async def lifespan(app: FastAPI):
log.info("Subfeed starting up")
log.info("Siftlode starting up")
start_scheduler()
try:
yield
finally:
log.info("Subfeed shutting down")
log.info("Siftlode shutting down")
shutdown_scheduler()

View file

@ -3,7 +3,7 @@
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Subfeed</title>
<title>Siftlode</title>
<style>
:root { color-scheme: dark; }
* { box-sizing: border-box; }

View file

@ -11,7 +11,7 @@ RSS_URL = "https://www.youtube.com/feeds/videos.xml?channel_id={channel_id}"
def fetch_channel_feed(channel_id: str) -> list[dict]:
url = RSS_URL.format(channel_id=channel_id)
try:
resp = httpx.get(url, timeout=20.0, headers={"User-Agent": "Subfeed/1.0"})
resp = httpx.get(url, timeout=20.0, headers={"User-Agent": "Siftlode/1.0"})
except httpx.HTTPError:
return []
if resp.status_code != 200: