feat: Refactor TMDB API key and access token handling; update settings screen for user input and remove hardcoded secrets

This commit is contained in:
sha
2026-04-12 11:57:14 +03:00
parent 1b50d15eea
commit cff973dd94
5 changed files with 40 additions and 10 deletions
+2
View File
@@ -8,6 +8,8 @@ wheels/
# Virtual environments
.venv
venv/
# Secrets
src/secrets.py
# Test-generated files
src/test/datasets/sample_mediafiles/
.pytest_cache/
+5 -1
View File
@@ -11,7 +11,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- **GitHub Actions CI** (`ci.yml`): runs tests + mypy on Python 3.11 and 3.12 for every push to `main` and all PRs
- **GitHub Actions Release** (`release.yml`): triggered by `v*.*.*` tags — runs tests, builds wheel + tarball, publishes packages as GitHub Release assets
- **GitHub Actions Release** (`release.yml`): triggered by `v*.*.*` tags — runs tests, builds wheel + tarball, publishes packages as GitHub Release assets (`moma-X.Y.Z.whl`, `moma-latest.whl`, etc.)
- **TMDB credentials in Settings**: `tmdb_api_key` and `tmdb_access_token` are now stored in `~/.config/moma/config.json` and editable via the Settings screen (`p`)
### Changed
- Removed hardcoded TMDB API keys from `src/secrets.py`; `secrets.py` is now gitignored
### Future Plans
See [docs/REFACTORING_PROGRESS.md](docs/REFACTORING_PROGRESS.md) and [docs/ToDo.md](docs/ToDo.md) for upcoming features and improvements.
+12 -4
View File
@@ -6,7 +6,6 @@ import requests
import logging
from pathlib import Path
from typing import Dict, Optional, Tuple, Any
from ..secrets import TMDB_API_KEY, TMDB_ACCESS_TOKEN
from ..cache import Cache
from ..settings import Settings
@@ -38,14 +37,23 @@ class TMDBExtractor:
base_url = "https://api.themoviedb.org/3"
url = f"{base_url}{endpoint}"
api_key = self.settings.get("tmdb_api_key", "")
access_token = self.settings.get("tmdb_access_token", "")
if not api_key and not access_token:
logging.warning("TMDB API key and access token are not configured")
return None
headers = {
"Authorization": f"Bearer {TMDB_ACCESS_TOKEN}",
"accept": "application/json"
}
if access_token:
headers["Authorization"] = f"Bearer {access_token}"
if params is None:
params = {}
params['api_key'] = TMDB_API_KEY
if api_key:
params['api_key'] = api_key
try:
response = requests.get(url, headers=headers, params=params, timeout=10)
+10 -5
View File
@@ -16,6 +16,8 @@ class Settings:
"cache_ttl_extractors": 21600, # 6 hours in seconds
"cache_ttl_tmdb": 21600, # 6 hours in seconds
"cache_ttl_posters": 2592000, # 30 days in seconds
"tmdb_api_key": "", # TMDB API key
"tmdb_access_token": "", # TMDB Bearer access token
}
_instance: Optional['Settings'] = None
@@ -80,12 +82,15 @@ class Settings:
def set(self, key: str, value: Any) -> None:
"""Set a setting value and save."""
if key in self.DEFAULTS:
# Basic type checking
if isinstance(value, type(self.DEFAULTS[key])):
self._settings[key] = value
self.save()
else:
# Basic type checking (both empty string and non-empty string are valid for str defaults)
default = self.DEFAULTS[key]
if isinstance(default, bool):
if not isinstance(value, bool):
raise ValueError(f"Invalid type for setting {key}")
elif not isinstance(value, type(default)):
raise ValueError(f"Invalid type for setting {key}")
self._settings[key] = value
self.save()
else:
raise KeyError(f"Unknown setting: {key}")
+11
View File
@@ -78,6 +78,12 @@ Configure application settings.
yield Static("Cache TTL - Posters (days):", classes="label")
yield Input(value=str(settings.get("cache_ttl_posters") // 86400), id="ttl_posters", classes="input_field")
yield Static("TMDB API Key:", classes="label")
yield Input(value=settings.get("tmdb_api_key", ""), id="tmdb_api_key", password=False, classes="input_field")
yield Static("TMDB Access Token (Bearer):", classes="label")
yield Input(value=settings.get("tmdb_access_token", ""), id="tmdb_access_token", password=True, classes="input_field")
with Horizontal(id="buttons"):
yield Button("Save", id="save")
yield Button("Cancel", id="cancel")
@@ -146,6 +152,11 @@ Configure application settings.
self.app.settings.set("cache_ttl_tmdb", ttl_tmdb) # type: ignore
self.app.settings.set("cache_ttl_posters", ttl_posters) # type: ignore
tmdb_api_key = self.query_one("#tmdb_api_key", Input).value.strip()
tmdb_access_token = self.query_one("#tmdb_access_token", Input).value.strip()
self.app.settings.set("tmdb_api_key", tmdb_api_key) # type: ignore
self.app.settings.set("tmdb_access_token", tmdb_access_token) # type: ignore
self.app.notify("Settings saved!", severity="information", timeout=2) # type: ignore
except ValueError:
self.app.notify("Invalid TTL values. Please enter numbers only.", severity="error", timeout=3) # type: ignore