Add TMDBExtractor class for movie information extraction

- Implement TMDBExtractor to fetch movie details from The Movie Database (TMDB) API.
- Include caching mechanism for API responses to reduce redundant requests.
- Extract movie database ID from filenames using regex patterns.
- Add methods to extract TMDB ID, title, original title, release year, and TMDB URL.
- Create secrets.py to store TMDB API key and access token.
- Add a sample MKV file for testing purposes.
This commit is contained in:
sha
2025-12-28 09:02:42 +00:00
parent 97bacf602c
commit 9a78dc2540
10 changed files with 439 additions and 5 deletions
+1
View File
@@ -64,6 +64,7 @@ class FormatterApplier:
TextFormatter.blue,
TextFormatter.grey,
TextFormatter.dim,
TextFormatter.format_url,
]
@staticmethod
+48 -1
View File
@@ -22,6 +22,7 @@ class MediaFormatter:
sections = [
self.file_info(),
self.selected_data(),
self.tmdb_data(),
self.tracks_info(),
self.filename_extracted_data(),
self.metadata_extracted_data(),
@@ -76,6 +77,52 @@ class MediaFormatter:
]
return FormatterApplier.format_data_items(data)
def tmdb_data(self) -> list[str]:
"""Return formatted TMDB data"""
data = [
{
"label": "TMDB Data",
"label_formatters": [TextFormatter.bold, TextFormatter.uppercase],
},
{
"label": "ID",
"label_formatters": [TextFormatter.bold, TextFormatter.blue],
"value": self.extractor.get("tmdb_id", "TMDB") or "<None>",
"value_formatters": [TextFormatter.yellow],
},
{
"label": "Title",
"label_formatters": [TextFormatter.bold, TextFormatter.blue],
"value": self.extractor.get("title", "TMDB") or "<None>",
"value_formatters": [TextFormatter.yellow],
},
{
"label": "Original Title",
"label_formatters": [TextFormatter.bold, TextFormatter.blue],
"value": self.extractor.get("original_title", "TMDB") or "<None>",
"value_formatters": [TextFormatter.yellow],
},
{
"label": "Year",
"label_formatters": [TextFormatter.bold, TextFormatter.blue],
"value": self.extractor.get("year", "TMDB") or "<None>",
"value_formatters": [TextFormatter.yellow,],
},
{
"label": "Database Info",
"label_formatters": [TextFormatter.bold, TextFormatter.blue],
"value": self.extractor.get("movie_db", "TMDB") or "<None>",
"value_formatters": [SpecialInfoFormatter.format_database_info, TextFormatter.yellow],
},
{
"label": "URL",
"label_formatters": [TextFormatter.bold, TextFormatter.blue],
"value": self.extractor.get("tmdb_url", "TMDB") or "<None>",
"value_formatters": [TextFormatter.format_url],
}
]
return FormatterApplier.format_data_items(data)
def tracks_info(self) -> list[str]:
"""Return formatted tracks information"""
data = [
@@ -350,7 +397,7 @@ class MediaFormatter:
"value_formatters": [TextFormatter.yellow],
},
{
"label": "DBid",
"label": "Database Info",
"label_formatters": [TextFormatter.bold, TextFormatter.blue],
"value": self.extractor.get("movie_db") or "<None>",
"value_formatters": [SpecialInfoFormatter.format_database_info, TextFormatter.yellow],
+16 -1
View File
@@ -100,4 +100,19 @@ class TextFormatter:
@staticmethod
def dim(text: str) -> str:
return f"[dim]{text}[/dim]"
return f"[dim]{text}[/dim]"
@staticmethod
def link(url: str, text: str | None = None) -> str:
"""Create a clickable link. If text is None, uses the URL as text."""
if text is None:
text = url
return f"[link={url}]{text}[/link]"
@staticmethod
def format_url(url: str) -> str:
"""Format a URL as a clickable link using OSC 8 if it's a valid URL, otherwise return as-is."""
if url and url != "<None>" and url.startswith("http"):
# Use OSC 8 hyperlink escape sequence for clickable links
return f"\x1b]8;;{url}\x1b\\Open in TMDB\x1b]8;;\x1b\\"
return url