Add year support to anime folder names
- Add year property to Serie entity with name_with_year - Add year column to AnimeSeries database model - Add get_year() method to AniworldLoader provider - Extract year from folder names before fetching from API - Update SerieScanner to populate year during rescan - Update add_series endpoint to fetch and store year - Optimize: check folder name for year before API call
This commit is contained in:
@@ -117,6 +117,44 @@ class SerieScanner:
|
||||
if handler in self.events.on_progress:
|
||||
self.events.on_progress.remove(handler)
|
||||
|
||||
def _extract_year_from_folder_name(self, folder_name: str) -> int | None:
|
||||
"""Extract year from folder name if present.
|
||||
|
||||
Looks for year in format "(YYYY)" at the end of folder name.
|
||||
|
||||
Args:
|
||||
folder_name: The folder name to check
|
||||
|
||||
Returns:
|
||||
int or None: Year if found, None otherwise
|
||||
|
||||
Example:
|
||||
>>> _extract_year_from_folder_name("Dororo (2025)")
|
||||
2025
|
||||
>>> _extract_year_from_folder_name("Dororo")
|
||||
None
|
||||
"""
|
||||
if not folder_name:
|
||||
return None
|
||||
|
||||
# Look for year in format (YYYY) - typically at end of name
|
||||
match = re.search(r'\((\d{4})\)', folder_name)
|
||||
if match:
|
||||
try:
|
||||
year = int(match.group(1))
|
||||
# Validate year is reasonable (between 1900 and 2100)
|
||||
if 1900 <= year <= 2100:
|
||||
logger.debug(
|
||||
"Extracted year from folder name: %s -> %d",
|
||||
folder_name,
|
||||
year
|
||||
)
|
||||
return year
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
return None
|
||||
|
||||
def subscribe_on_error(self, handler):
|
||||
"""
|
||||
Subscribe a handler to an event.
|
||||
@@ -235,6 +273,33 @@ class SerieScanner:
|
||||
and serie.key
|
||||
and serie.key.strip()
|
||||
):
|
||||
# Try to extract year from folder name first
|
||||
if not hasattr(serie, 'year') or not serie.year:
|
||||
year_from_folder = self._extract_year_from_folder_name(folder)
|
||||
if year_from_folder:
|
||||
serie.year = year_from_folder
|
||||
logger.info(
|
||||
"Using year from folder name: %s (year=%d)",
|
||||
folder,
|
||||
year_from_folder
|
||||
)
|
||||
else:
|
||||
# If not in folder name, fetch from provider
|
||||
try:
|
||||
serie.year = self.loader.get_year(serie.key)
|
||||
if serie.year:
|
||||
logger.info(
|
||||
"Fetched year from provider: %s (year=%d)",
|
||||
serie.key,
|
||||
serie.year
|
||||
)
|
||||
except Exception as e:
|
||||
logger.warning(
|
||||
"Could not fetch year for %s: %s",
|
||||
serie.key,
|
||||
str(e)
|
||||
)
|
||||
|
||||
# Delegate the provider to compare local files with
|
||||
# remote metadata, yielding missing episodes per
|
||||
# season. Results are saved back to disk so that both
|
||||
@@ -611,19 +676,46 @@ class SerieScanner:
|
||||
sum(len(eps) for eps in missing_episodes.values())
|
||||
)
|
||||
else:
|
||||
# Try to extract year from folder name first
|
||||
year = self._extract_year_from_folder_name(folder)
|
||||
if year:
|
||||
logger.info(
|
||||
"Using year from folder name: %s (year=%d)",
|
||||
folder,
|
||||
year
|
||||
)
|
||||
else:
|
||||
# If not in folder name, fetch from provider
|
||||
try:
|
||||
year = self.loader.get_year(key)
|
||||
if year:
|
||||
logger.info(
|
||||
"Fetched year from provider: %s (year=%d)",
|
||||
key,
|
||||
year
|
||||
)
|
||||
except Exception as e:
|
||||
logger.warning(
|
||||
"Could not fetch year for %s: %s",
|
||||
key,
|
||||
str(e)
|
||||
)
|
||||
|
||||
# Create new serie entry
|
||||
serie = Serie(
|
||||
key=key,
|
||||
name="", # Will be populated by caller if needed
|
||||
site=site,
|
||||
folder=folder,
|
||||
episodeDict=missing_episodes
|
||||
episodeDict=missing_episodes,
|
||||
year=year
|
||||
)
|
||||
self.keyDict[key] = serie
|
||||
logger.debug(
|
||||
"Created new series entry for %s with %d missing episodes",
|
||||
"Created new series entry for %s with %d missing episodes (year=%s)",
|
||||
key,
|
||||
sum(len(eps) for eps in missing_episodes.values())
|
||||
sum(len(eps) for eps in missing_episodes.values()),
|
||||
year
|
||||
)
|
||||
|
||||
# Notify completion
|
||||
|
||||
Reference in New Issue
Block a user