This commit is contained in:
+92
-1
@@ -133,6 +133,29 @@ class NFOGuardDatabase:
|
||||
END IF;
|
||||
END $$;
|
||||
""")
|
||||
|
||||
# Add skipped and skip_reason columns if they don't exist (migration for skip tracking)
|
||||
cursor.execute("""
|
||||
DO $$
|
||||
BEGIN
|
||||
IF NOT EXISTS (SELECT 1 FROM information_schema.columns
|
||||
WHERE table_name='movies' AND column_name='skipped') THEN
|
||||
ALTER TABLE movies ADD COLUMN skipped BOOLEAN DEFAULT FALSE;
|
||||
END IF;
|
||||
IF NOT EXISTS (SELECT 1 FROM information_schema.columns
|
||||
WHERE table_name='movies' AND column_name='skip_reason') THEN
|
||||
ALTER TABLE movies ADD COLUMN skip_reason TEXT;
|
||||
END IF;
|
||||
IF NOT EXISTS (SELECT 1 FROM information_schema.columns
|
||||
WHERE table_name='episodes' AND column_name='skipped') THEN
|
||||
ALTER TABLE episodes ADD COLUMN skipped BOOLEAN DEFAULT FALSE;
|
||||
END IF;
|
||||
IF NOT EXISTS (SELECT 1 FROM information_schema.columns
|
||||
WHERE table_name='episodes' AND column_name='skip_reason') THEN
|
||||
ALTER TABLE episodes ADD COLUMN skip_reason TEXT;
|
||||
END IF;
|
||||
END $$;
|
||||
""")
|
||||
|
||||
# Processing history table
|
||||
cursor.execute("""
|
||||
@@ -301,7 +324,75 @@ class NFOGuardDatabase:
|
||||
import os
|
||||
if os.environ.get("DEBUG", "false").lower() == "true":
|
||||
print(f"🔍 DATABASE VERIFY: After upsert, found dateadded={result['dateadded'] if result else 'NOT_FOUND'}, source={result['source'] if result else 'NOT_FOUND'}")
|
||||
|
||||
|
||||
def mark_movie_skipped(self, imdb_id: str, title: str, year: int, path: str, reason: str):
|
||||
"""Mark a movie as skipped with reason"""
|
||||
with self.get_connection() as conn:
|
||||
cursor = conn.cursor()
|
||||
timestamp = datetime.utcnow()
|
||||
cursor.execute("""
|
||||
INSERT INTO movies (imdb_id, title, year, path, skipped, skip_reason, has_video_file, last_updated)
|
||||
VALUES (%s, %s, %s, %s, TRUE, %s, FALSE, %s)
|
||||
ON CONFLICT (imdb_id) DO UPDATE SET
|
||||
title = EXCLUDED.title,
|
||||
year = EXCLUDED.year,
|
||||
path = EXCLUDED.path,
|
||||
skipped = TRUE,
|
||||
skip_reason = EXCLUDED.skip_reason,
|
||||
last_updated = EXCLUDED.last_updated
|
||||
""", (imdb_id, title, year, path, reason, timestamp))
|
||||
|
||||
def mark_episode_skipped(self, imdb_id: str, season: int, episode: int, reason: str):
|
||||
"""Mark an episode as skipped with reason"""
|
||||
with self.get_connection() as conn:
|
||||
cursor = conn.cursor()
|
||||
timestamp = datetime.utcnow()
|
||||
cursor.execute("""
|
||||
INSERT INTO episodes (imdb_id, season, episode, skipped, skip_reason, has_video_file, last_updated)
|
||||
VALUES (%s, %s, %s, TRUE, %s, FALSE, %s)
|
||||
ON CONFLICT (imdb_id, season, episode) DO UPDATE SET
|
||||
skipped = TRUE,
|
||||
skip_reason = EXCLUDED.skip_reason,
|
||||
last_updated = EXCLUDED.last_updated
|
||||
""", (imdb_id, season, episode, reason, timestamp))
|
||||
|
||||
def clear_movie_skipped(self, imdb_id: str):
|
||||
"""Clear skipped flag for a movie"""
|
||||
with self.get_connection() as conn:
|
||||
cursor = conn.cursor()
|
||||
cursor.execute("""
|
||||
UPDATE movies SET skipped = FALSE, skip_reason = NULL
|
||||
WHERE imdb_id = %s
|
||||
""", (imdb_id,))
|
||||
|
||||
def clear_episode_skipped(self, imdb_id: str, season: int, episode: int):
|
||||
"""Clear skipped flag for an episode"""
|
||||
with self.get_connection() as conn:
|
||||
cursor = conn.cursor()
|
||||
cursor.execute("""
|
||||
UPDATE episodes SET skipped = FALSE, skip_reason = NULL
|
||||
WHERE imdb_id = %s AND season = %s AND episode = %s
|
||||
""", (imdb_id, season, episode))
|
||||
|
||||
def get_skipped_counts(self) -> Dict:
|
||||
"""Get counts of skipped movies and episodes"""
|
||||
with self.get_connection() as conn:
|
||||
cursor = conn.cursor()
|
||||
|
||||
# Count skipped movies
|
||||
cursor.execute("SELECT COUNT(*) as count FROM movies WHERE skipped = TRUE")
|
||||
skipped_movies = cursor.fetchone()['count']
|
||||
|
||||
# Count skipped episodes
|
||||
cursor.execute("SELECT COUNT(*) as count FROM episodes WHERE skipped = TRUE")
|
||||
skipped_episodes = cursor.fetchone()['count']
|
||||
|
||||
return {
|
||||
'movies': skipped_movies,
|
||||
'episodes': skipped_episodes,
|
||||
'total': skipped_movies + skipped_episodes
|
||||
}
|
||||
|
||||
def get_series_episodes(self, imdb_id: str, has_video_file_only: bool = False) -> List[Dict]:
|
||||
"""Get all episodes for a series"""
|
||||
with self.get_connection() as conn:
|
||||
|
||||
+38
-30
@@ -82,29 +82,24 @@ class DatabasePopulator:
|
||||
_log("DEBUG", f"Extracted IMDb ID {imdb_id} from path for: {movie.get('title')}")
|
||||
|
||||
if not imdb_id:
|
||||
skip_reason = 'No IMDb ID found'
|
||||
skip_info = {
|
||||
'title': movie.get('title', 'Unknown'),
|
||||
'year': movie.get('year'),
|
||||
'path': path,
|
||||
'reason': 'No IMDb ID found'
|
||||
'reason': skip_reason
|
||||
}
|
||||
stats['skipped_items'].append(skip_info)
|
||||
_log("DEBUG", f"Skipping movie without IMDb ID: {movie.get('title')} (path: {path})")
|
||||
# Note: Cannot mark in DB because no IMDb ID (primary key)
|
||||
stats['skipped'] += 1
|
||||
continue
|
||||
|
||||
# Check if movie already exists in database
|
||||
existing = self.db.get_movie_dates(imdb_id)
|
||||
if existing and existing.get('dateadded'):
|
||||
skip_info = {
|
||||
'title': movie.get('title', 'Unknown'),
|
||||
'year': movie.get('year'),
|
||||
'imdb_id': imdb_id,
|
||||
'reason': 'Already in database'
|
||||
}
|
||||
stats['skipped_items'].append(skip_info)
|
||||
# Already in database - skip silently (not an error)
|
||||
_log("DEBUG", f"Movie {imdb_id} already in database, skipping")
|
||||
stats['skipped'] += 1
|
||||
continue
|
||||
|
||||
# Get release date
|
||||
@@ -134,14 +129,24 @@ class DatabasePopulator:
|
||||
dateadded = released
|
||||
source = f'{source_type}_fallback'
|
||||
else:
|
||||
skip_reason = 'No import date in Radarr history and no release dates available'
|
||||
skip_info = {
|
||||
'title': movie.get('title', 'Unknown'),
|
||||
'year': movie.get('year'),
|
||||
'imdb_id': imdb_id,
|
||||
'reason': 'No import date in Radarr history and no release dates available'
|
||||
'reason': skip_reason
|
||||
}
|
||||
stats['skipped_items'].append(skip_info)
|
||||
_log("DEBUG", f"No date available for movie {imdb_id}, skipping")
|
||||
|
||||
# Mark as skipped in database for troubleshooting
|
||||
self.db.mark_movie_skipped(
|
||||
imdb_id=imdb_id,
|
||||
title=movie.get('title', 'Unknown'),
|
||||
year=movie.get('year', 0),
|
||||
path=path or 'unknown',
|
||||
reason=skip_reason
|
||||
)
|
||||
stats['skipped'] += 1
|
||||
continue
|
||||
elif released:
|
||||
@@ -149,14 +154,24 @@ class DatabasePopulator:
|
||||
dateadded = released
|
||||
source = f'{source_type}_fallback'
|
||||
else:
|
||||
skip_reason = 'No Radarr movie ID and no release dates available'
|
||||
skip_info = {
|
||||
'title': movie.get('title', 'Unknown'),
|
||||
'year': movie.get('year'),
|
||||
'imdb_id': imdb_id,
|
||||
'reason': 'No Radarr movie ID and no release dates available'
|
||||
'reason': skip_reason
|
||||
}
|
||||
stats['skipped_items'].append(skip_info)
|
||||
_log("DEBUG", f"No date available for movie {imdb_id}, skipping")
|
||||
|
||||
# Mark as skipped in database for troubleshooting
|
||||
self.db.mark_movie_skipped(
|
||||
imdb_id=imdb_id,
|
||||
title=movie.get('title', 'Unknown'),
|
||||
year=movie.get('year', 0),
|
||||
path=path or 'unknown',
|
||||
reason=skip_reason
|
||||
)
|
||||
stats['skipped'] += 1
|
||||
continue
|
||||
|
||||
@@ -278,29 +293,13 @@ class DatabasePopulator:
|
||||
# Check if episode already exists
|
||||
existing = self.db.get_episode_date(imdb_id, season_num, episode_num)
|
||||
if existing and existing.get('dateadded'):
|
||||
skip_info = {
|
||||
'title': series_title,
|
||||
'episode_title': episode_title,
|
||||
'season': season_num,
|
||||
'episode': episode_num,
|
||||
'reason': 'Already in database'
|
||||
}
|
||||
stats['skipped_items'].append(skip_info)
|
||||
stats['skipped'] += 1
|
||||
# Already in database - skip silently (not an error)
|
||||
continue
|
||||
|
||||
# Only process episodes that have video files
|
||||
has_file = episode.get('hasFile', False)
|
||||
if not has_file:
|
||||
skip_info = {
|
||||
'title': series_title,
|
||||
'episode_title': episode_title,
|
||||
'season': season_num,
|
||||
'episode': episode_num,
|
||||
'reason': 'No video file'
|
||||
}
|
||||
stats['skipped_items'].append(skip_info)
|
||||
stats['skipped'] += 1
|
||||
# No video file - skip silently (intentionally filtered)
|
||||
continue
|
||||
|
||||
# Get air date
|
||||
@@ -328,14 +327,23 @@ class DatabasePopulator:
|
||||
source = 'sonarr:aired_fallback'
|
||||
elif not dateadded:
|
||||
# No date available
|
||||
skip_reason = 'No import date from Sonarr history and no air date available'
|
||||
skip_info = {
|
||||
'title': series_title,
|
||||
'episode_title': episode_title,
|
||||
'season': season_num,
|
||||
'episode': episode_num,
|
||||
'reason': 'No import date from Sonarr history and no air date available'
|
||||
'reason': skip_reason
|
||||
}
|
||||
stats['skipped_items'].append(skip_info)
|
||||
|
||||
# Mark as skipped in database for troubleshooting
|
||||
self.db.mark_episode_skipped(
|
||||
imdb_id=imdb_id,
|
||||
season=season_num,
|
||||
episode=episode_num,
|
||||
reason=skip_reason
|
||||
)
|
||||
stats['skipped'] += 1
|
||||
continue
|
||||
|
||||
|
||||
Reference in New Issue
Block a user