fix: episodes loading in dropdown
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

- Fix ZT get_episodes: find episode links by text pattern instead of URL
- Episodes now load into #player-container instead of tiny dropdown div
- Scroll to player container after episodes load
This commit is contained in:
root
2026-03-28 01:04:32 +00:00
parent b2310249f8
commit dd1365eff9
3 changed files with 20 additions and 19 deletions
@@ -135,26 +135,29 @@ class ZoneTelechargementDownloader(BaseSeriesSite):
soup = BeautifulSoup(html, "lxml")
episodes = []
seen_urls = set()
# ZT typically lists episodes in a table or list of links
# Links often look like: /telecharger-series/.../saison-X-episode-Y.html
links = soup.find_all("a", href=re.compile(r"episode-\d+"))
# ZT lists episodes as <a> tags inside <b> inside div.postinfo
# Text matches "Episode X" pattern, URLs go through dl-protect
for link in soup.find_all("a"):
text = link.get_text(strip=True)
ep_match = re.search(r"episode\s*(\d+)", text, re.I)
if not ep_match:
continue
for i, link in enumerate(links):
href = link.get("href", "")
if not href.startswith("http"):
href = urljoin(self.base_url, href)
title = link.get_text(strip=True)
ep_match = re.search(r"episode\s*(\d+)", title.lower())
ep_number = int(ep_match.group(1)) if ep_match else i + 1
if not href or href in seen_urls:
continue
seen_urls.add(href)
ep_number = int(ep_match.group(1))
episodes.append(
{"episode_number": ep_number, "url": href, "title": title}
{"episode_number": ep_number, "url": href, "title": text}
)
# Sort by episode number
episodes.sort(key=lambda x: x["episode_number"])
logger.info(f"Found {len(episodes)} episodes on {anime_url}")
return episodes
except Exception as e:
@@ -82,13 +82,12 @@
<i class="fas fa-layer-group"></i> Saison complete
</button>
<button class="sr-dropdown-item"
hx-get="/api/anime/episodes?url={{ first_url | urlencode }}&lang={{ default_lang }}"
hx-target="#dl-episodes-{{ loop.index }}"
hx-get="/api/anime/episodes?url={{ first_url | urlencode }}&lang={{ default_lang }}&html=1"
hx-target="#player-container"
hx-swap="innerHTML"
hx-on::after-request="openDropdown = null">
hx-on::after-request="openDropdown = null; document.getElementById('player-container').scrollIntoView({behavior: 'smooth'})">
<i class="fas fa-list-ol"></i> Choisir des episodes
</button>
<div id="dl-episodes-{{ loop.index }}"></div>
</div>
</div>
<button class="sr-btn sr-btn-follow"
@@ -61,13 +61,12 @@
<i class="fas fa-layer-group"></i> Saison complete
</button>
<button class="sr-dropdown-item"
hx-get="/api/anime/episodes?url={{ first_url | urlencode }}&lang={{ default_lang }}"
hx-target="#dl-episodes-{{ loop.index }}"
hx-get="/api/anime/episodes?url={{ first_url | urlencode }}&lang={{ default_lang }}&html=1"
hx-target="#player-container"
hx-swap="innerHTML"
hx-on::after-request="openDropdown = null">
hx-on::after-request="openDropdown = null; document.getElementById('player-container').scrollIntoView({behavior: 'smooth'})">
<i class="fas fa-list-ol"></i> Choisir des episodes
</button>
<div id="dl-episodes-{{ loop.index }}"></div>
</div>
</div>
<button class="sr-btn sr-btn-follow"