Add cookies file support for Docker; auto-detect /data/cookies.txt

This commit is contained in:
inputnoise
2026-05-25 20:57:04 +02:00
parent bcc425b6fb
commit 56dd5f8360
5 changed files with 48 additions and 2 deletions

View File

@@ -66,6 +66,7 @@ def on_startup():
key TEXT PRIMARY KEY,
value TEXT NOT NULL
)""",
"ALTER TABLE user_settings ADD COLUMN cookies_file TEXT DEFAULT ''",
"ALTER TABLE user_settings ADD COLUMN feed_weight_recency REAL DEFAULT 5.0",
"ALTER TABLE user_settings ADD COLUMN feed_weight_affinity REAL DEFAULT 5.0",
"ALTER TABLE user_settings ADD COLUMN feed_weight_channel REAL DEFAULT 5.0",
@@ -142,6 +143,7 @@ def on_startup():
if first_user_settings:
ytdlp_service.set_max_concurrent(first_user_settings.max_concurrent_downloads)
ytdlp_service.set_cookies_browser(first_user_settings.cookies_browser or "")
ytdlp_service.set_cookies_file(first_user_settings.cookies_file or "")
finally:
db.close()

View File

@@ -109,6 +109,7 @@ class UserSettings(Base):
mark_watched_at_percent = Column(Integer, default=90) # 50100
auto_download_on_sync = Column(Boolean, default=False)
cookies_browser = Column(String, default="") # chrome / firefox / etc., "" = disabled
cookies_file = Column(String, default="") # path to Netscape cookies.txt, "" = disabled
theater_mode = Column(Boolean, default=False)
discovery_regions = Column(String, default="US,SE") # comma-separated ISO country codes
calm_mode = Column(Boolean, default=False)

View File

@@ -22,6 +22,7 @@ class SettingsOut(BaseModel):
mark_watched_at_percent: int
auto_download_on_sync: bool
cookies_browser: str = ""
cookies_file: str = ""
theater_mode: bool = False
discovery_regions: str = "US,SE"
calm_mode: bool = False
@@ -41,6 +42,7 @@ class SettingsPatch(BaseModel):
mark_watched_at_percent: Optional[int] = Field(None, ge=50, le=100)
auto_download_on_sync: Optional[bool] = None
cookies_browser: Optional[str] = None
cookies_file: Optional[str] = None
theater_mode: Optional[bool] = None
discovery_regions: Optional[str] = None
calm_mode: Optional[bool] = None
@@ -91,6 +93,9 @@ def update_settings(
if body.cookies_browser is not None and body.cookies_browser in VALID_BROWSERS:
s.cookies_browser = body.cookies_browser
ytdlp.set_cookies_browser(body.cookies_browser)
if body.cookies_file is not None:
s.cookies_file = body.cookies_file.strip()
ytdlp.set_cookies_file(body.cookies_file)
if body.theater_mode is not None:
s.theater_mode = body.theater_mode
if body.discovery_regions is not None:

View File

@@ -401,8 +401,11 @@ def predicted_file_path(video_id: str) -> Path:
_SEMAPHORE = threading.Semaphore(3)
_semaphore_lock = threading.Lock()
_cookies_browser: str = ""
_cookies_file: str = ""
_cookies_lock = threading.Lock()
_AUTO_COOKIES_PATHS = ["/data/cookies.txt"]
def set_max_concurrent(n: int) -> None:
global _SEMAPHORE
@@ -416,10 +419,27 @@ def set_cookies_browser(browser: str) -> None:
_cookies_browser = browser.strip().lower()
def set_cookies_file(path: str) -> None:
global _cookies_file
with _cookies_lock:
_cookies_file = path.strip()
def _cookie_args() -> list[str]:
with _cookies_lock:
cf = _cookies_file
b = _cookies_browser
return ["--cookies-from-browser", b] if b else []
# Prefer explicit cookies file
if cf and Path(cf).exists():
return ["--cookies", cf]
# Auto-detect cookies.txt in well-known Docker locations
for candidate in _AUTO_COOKIES_PATHS:
if Path(candidate).exists():
return ["--cookies", candidate]
# Fall back to browser (works in local dev, not in Docker)
if b:
return ["--cookies-from-browser", b]
return []
def start_download(