Debugging the TEN service
This commit is contained in:
+6
-4
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import sys
|
import sys
|
||||||
|
import json
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from services.iview import iViewService
|
from services.iview import iViewService
|
||||||
from services.ten import TenService
|
from services.ten import TenService
|
||||||
@@ -24,7 +25,7 @@ class AutoGrabber:
|
|||||||
self.config_dir = Path(config_dir)
|
self.config_dir = Path(config_dir)
|
||||||
|
|
||||||
self.history_file = self.config_dir / "history"
|
self.history_file = self.config_dir / "history"
|
||||||
self.series_file = self.config_dir / "series"
|
self.series_file = self.config_dir / "series.json"
|
||||||
|
|
||||||
self.dry_run = dry_run
|
self.dry_run = dry_run
|
||||||
self.mark_existing = mark_existing
|
self.mark_existing = mark_existing
|
||||||
@@ -80,6 +81,7 @@ class AutoGrabber:
|
|||||||
def process_show(self, config):
|
def process_show(self, config):
|
||||||
service_name = config.get("service")
|
service_name = config.get("service")
|
||||||
source_title = config.get("source_title")
|
source_title = config.get("source_title")
|
||||||
|
source_url = config.get("source_url")
|
||||||
|
|
||||||
if not service_name or not source_title:
|
if not service_name or not source_title:
|
||||||
print(f"❌ Skipping invalid entry: {config} (Missing service or source_title)")
|
print(f"❌ Skipping invalid entry: {config} (Missing service or source_title)")
|
||||||
@@ -103,7 +105,7 @@ class AutoGrabber:
|
|||||||
print("==============================")
|
print("==============================")
|
||||||
|
|
||||||
# 3. Discovery (Ten will handle its own requirement for source_season)
|
# 3. Discovery (Ten will handle its own requirement for source_season)
|
||||||
seasons = service.discover_seasons(source_title, source_season=source_season)
|
seasons = service.discover_seasons(source_title, source_season=source_season, source_url=source_url)
|
||||||
|
|
||||||
if not seasons:
|
if not seasons:
|
||||||
# Service will have already printed its specific error message
|
# Service will have already printed its specific error message
|
||||||
@@ -146,8 +148,8 @@ class AutoGrabber:
|
|||||||
self.save_history()
|
self.save_history()
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
for service, source, output in self.series_list:
|
for show_config in self.series_list:
|
||||||
self.process_show(service, source, output)
|
self.process_show(show_config)
|
||||||
print("\n✅ Done.")
|
print("\n✅ Done.")
|
||||||
|
|
||||||
# -------------------------
|
# -------------------------
|
||||||
|
|||||||
+17
-1
@@ -3,7 +3,22 @@ from pathlib import Path
|
|||||||
from abc import ABC, abstractmethod
|
from abc import ABC, abstractmethod
|
||||||
|
|
||||||
class BaseService(ABC):
|
class BaseService(ABC):
|
||||||
# ... your existing abstract methods ...
|
|
||||||
|
@abstractmethod
|
||||||
|
def name(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def slugify(self, text):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def discover_seasons(self, show_title, source_season=None, source_url=None):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def normalize_episode(self, source_title, output_title, entry):
|
||||||
|
pass
|
||||||
|
|
||||||
def download_episode(self, episode, entry, download_dir):
|
def download_episode(self, episode, entry, download_dir):
|
||||||
"""
|
"""
|
||||||
@@ -32,3 +47,4 @@ class BaseService(ABC):
|
|||||||
|
|
||||||
result = subprocess.run(cmd)
|
result = subprocess.run(cmd)
|
||||||
return result.returncode == 0
|
return result.returncode == 0
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -125,7 +125,7 @@ class iViewService(BaseService):
|
|||||||
# -------------------------
|
# -------------------------
|
||||||
# Season discovery
|
# Season discovery
|
||||||
# -------------------------
|
# -------------------------
|
||||||
def discover_seasons(self, show_title):
|
def discover_seasons(self, show_title, source_season=None, source_url=None):
|
||||||
|
|
||||||
slug = self.slugify(show_title)
|
slug = self.slugify(show_title)
|
||||||
|
|
||||||
@@ -161,7 +161,7 @@ class iViewService(BaseService):
|
|||||||
# -------------------------
|
# -------------------------
|
||||||
# Episode normalization
|
# Episode normalization
|
||||||
# -------------------------
|
# -------------------------
|
||||||
def normalize_episode(self, show_title, entry):
|
def normalize_episode(self, show_title, entry, season_num):
|
||||||
|
|
||||||
season = entry.get("season_number") or 1
|
season = entry.get("season_number") or 1
|
||||||
episode = entry.get("episode_number") or 1
|
episode = entry.get("episode_number") or 1
|
||||||
|
|||||||
+13
-10
@@ -34,12 +34,19 @@ class TenService(BaseService):
|
|||||||
print(f"❌ Error: Ten requires 'source_season' in series.json for '{show_title}'")
|
print(f"❌ Error: Ten requires 'source_season' in series.json for '{show_title}'")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
if config.get("source_url"):
|
if source_url:
|
||||||
url = config["source_url"]
|
url = source_url
|
||||||
else:
|
else:
|
||||||
slug = self.slugify(show_title)
|
slug = self.slugify(show_title)
|
||||||
# Ten URL structure: /v/show-name/season-YYYY or /v/show-name/season-X
|
# Ten URL structure: /v/show-name/episodes/YYYY or /v/show-name/episodes/season-X
|
||||||
url = f"https://10play.com.au/{slug}/episodes/season-{source_season}"
|
s_str = str(source_season)
|
||||||
|
|
||||||
|
if len(s_str) == 4:
|
||||||
|
season_path = s_str
|
||||||
|
else:
|
||||||
|
season_path = f"season-{s_str}"
|
||||||
|
|
||||||
|
url = f"https://10play.com.au/{slug}/episodes/{season_path}"
|
||||||
|
|
||||||
print(f"🔎 Querying Ten: {url}")
|
print(f"🔎 Querying Ten: {url}")
|
||||||
data = self.run_ytdlp_json(url)
|
data = self.run_ytdlp_json(url)
|
||||||
@@ -72,15 +79,11 @@ class TenService(BaseService):
|
|||||||
show_clean = output_title.replace(" ", ".")
|
show_clean = output_title.replace(" ", ".")
|
||||||
title_clean = clean_title.replace(" ", ".")
|
title_clean = clean_title.replace(" ", ".")
|
||||||
|
|
||||||
filename = f"{show_clean}.S{s_val:02d}E{episode_idx:02d}.{title_clean}".strip(".")
|
# filename = f"{show_clean}.S{s_val:02d}E{episode_idx:02d}.{title_clean}".strip(".") # With episode title
|
||||||
|
filename = f"{show_clean}.S{s_val:02d}E{episode_idx:02d}".strip(".") # Without episode title
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"show": show_clean,
|
"show": show_clean,
|
||||||
"episode_id": episode_id,
|
"episode_id": episode_id,
|
||||||
"filename": filename
|
"filename": filename
|
||||||
}
|
}
|
||||||
|
|
||||||
def download_episode(self, episode, entry, download_dir):
|
|
||||||
# You can reuse the logic from your iViewService here
|
|
||||||
# Just ensure --netrc is included in the final subprocess call
|
|
||||||
pass
|
|
||||||
|
|||||||
Reference in New Issue
Block a user