Phase 2 Complete: SQL migration with SQLModel and Alembic
CI / Test (Python 3.11) (push) Has been cancelled
CI / Test (Python 3.12) (push) Has been cancelled
CI / Lint (push) Has been cancelled
CI / Type Check (push) Has been cancelled
CI / Summary (push) Has been cancelled

This commit is contained in:
root
2026-03-25 13:46:15 +00:00
parent 96b12b66e2
commit a684237725
21 changed files with 1148 additions and 466 deletions
+43 -23
View File
@@ -16,50 +16,70 @@ from app.models.watchlist import (
WatchlistItemUpdate,
WatchlistStatus,
WatchlistSettings,
WatchlistSettingsTable,
NewEpisodeInfo,
AutoDownloadResult
)
logger = logging.getLogger(__name__)
# Settings file remains JSON for simplicity for now
WATCHLIST_SETTINGS_FILE = "config/watchlist_settings.json"
class WatchlistManager:
"""Manages user watchlist for automatic episode downloads using SQL database"""
def __init__(self):
self.settings_file = WATCHLIST_SETTINGS_FILE
self.settings: Optional[WatchlistSettings] = None
self._load_settings()
def _load_settings(self):
"""Load watchlist settings from JSON file"""
"""Load watchlist settings from database"""
try:
if os.path.exists(self.settings_file):
with open(self.settings_file, 'r', encoding='utf-8') as f:
data = json.load(f)
self.settings = WatchlistSettings(**data)
logger.info(f"Loaded watchlist settings")
else:
self.settings = WatchlistSettings()
self._save_settings()
logger.info("Settings file not found, using defaults")
with Session(engine) as session:
statement = select(WatchlistSettingsTable).where(WatchlistSettingsTable.user_id == "default")
db_settings = session.exec(statement).first()
if db_settings:
self.settings = WatchlistSettings(
check_interval_hours=db_settings.check_interval_hours,
auto_download_enabled=db_settings.auto_download_enabled,
max_concurrent_auto_downloads=db_settings.max_concurrent_auto_downloads,
notify_on_new_episodes=db_settings.notify_on_new_episodes,
include_completed_anime=db_settings.include_completed_anime
)
logger.info(f"Loaded watchlist settings from database")
else:
self.settings = WatchlistSettings()
self._save_settings()
logger.info("Settings not found in database, created defaults")
except Exception as e:
logger.error(f"Error loading settings: {e}")
logger.error(f"Error loading settings from database: {e}")
self.settings = WatchlistSettings()
def _save_settings(self):
try:
os.makedirs(os.path.dirname(self.settings_file), exist_ok=True)
temp_file = f"{self.settings_file}.tmp"
with open(temp_file, 'w', encoding='utf-8') as f:
json.dump(self.settings.model_dump(mode='json'), f, indent=2, ensure_ascii=False)
os.replace(temp_file, self.settings_file)
logger.debug("Saved watchlist settings")
with Session(engine) as session:
statement = select(WatchlistSettingsTable).where(WatchlistSettingsTable.user_id == "default")
db_settings = session.exec(statement).first()
if db_settings:
db_settings.check_interval_hours = self.settings.check_interval_hours
db_settings.auto_download_enabled = self.settings.auto_download_enabled
db_settings.max_concurrent_auto_downloads = self.settings.max_concurrent_auto_downloads
db_settings.notify_on_new_episodes = self.settings.notify_on_new_episodes
db_settings.include_completed_anime = self.settings.include_completed_anime
else:
db_settings = WatchlistSettingsTable(
user_id="default",
check_interval_hours=self.settings.check_interval_hours,
auto_download_enabled=self.settings.auto_download_enabled,
max_concurrent_auto_downloads=self.settings.max_concurrent_auto_downloads,
notify_on_new_episodes=self.settings.notify_on_new_episodes,
include_completed_anime=self.settings.include_completed_anime
)
session.add(db_settings)
session.commit()
logger.debug("Saved watchlist settings to database")
except Exception as e:
logger.error(f"Error saving settings: {e}")
logger.error(f"Error saving settings to database: {e}")
def _to_api_model(self, db_item: WatchlistItemTable) -> WatchlistItem:
"""Convert database table model to API response model"""