Skip to content

S.to v2 migration and provider extraction#42

Merged
Zzackllack merged 19 commits intomainfrom
sto-v2-support
Jan 31, 2026
Merged

S.to v2 migration and provider extraction#42
Zzackllack merged 19 commits intomainfrom
sto-v2-support

Conversation

@Zzackllack
Copy link
Owner

Description

This pull request implements comprehensive support for S.to v2, addressing catalog, search, episode, and provider extraction changes required due to the site's migration. The update includes new parsing logic for v2 HTML structures, introduces fallback search via the public API, and refactors slug extraction and provider resolution to align with the new URL and data formats. These changes restore AniBridge functionality for S.to and improve resilience to future site updates. This closes and fixes #37

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation update

Testing

  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes

Screenshots (if applicable)

Additional Notes

  • Added new module app/providers/sto/v2.py to parse v2 episode pages, extract provider and language data from HTML attributes, and enrich episode objects with provider info. Includes logic for building episode URLs, fetching HTML, and mapping language IDs.
  • Updated episode construction in app/core/downloader/episode.py to use the new v2 provider extraction logic when site is "s.to", including building v2 episode URLs and enriching provider data post-creation. [1] [2] [3]

Catalog and slug extraction updates:

  • Changed S.to catalog URL default in app/config.py to /serien?by=alpha (v2 format) and updated slug extraction regex in both app/providers/sto/provider.py and app/utils/title_resolver.py to match /serie/<slug>. [1] [2] [3]

Search improvements:

  • Added support for S.to's public /api/search/suggest endpoint in app/utils/title_resolver.py, with logic to normalize search terms and select the best matching slug from API results. Integrated as a fallback in site search. [1] [2]

Documentation and analysis:

  • Added a detailed findings and implementation plan document for S.to v2 migration in specs/007-sto-v2-support/findings.md, including recommended approaches, risks, and phased plan.

This commit introduces two new documentation files detailing the risks associated with the S.to "Version 2" migration and the new features that will be available. The information is crucial for understanding the impact on AniBridge's functionality and integration with the S.to platform.
This document provides a comprehensive analysis of the S.to v2 migration, detailing the changes in URL structures, API endpoints, and implications for AniBridge. It proposes multiple implementation approaches to restore functionality, including a hybrid method leveraging both HTML scraping and public API usage.
…tails

Added recommendations for handling language metadata on episode pages, including extraction and normalization of language attributes for improved provider candidate management.
Update S.to catalog URL and slug parsing for v2 URLs.
Parse v2 episode HTML to build provider/language maps and
resolve /r?t= redirects through existing extractors.

BREAKING CHANGE: S.to slug format is now /serie/<slug> and
catalog index defaults to /serien?by=alpha, replacing v1
/serie/stream/<slug> and /serien-alphabet assumptions.
- Implemented functions to normalize search terms and fetch slugs from S.to API.
- Enhanced slug resolution by integrating S.to search results into the existing slug retrieval process.
@Zzackllack Zzackllack requested a review from Copilot January 30, 2026 23:52
@Zzackllack Zzackllack self-assigned this Jan 30, 2026
@Zzackllack Zzackllack added bug Something isn't working enhancement New feature or request labels Jan 30, 2026
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 30, 2026

📝 Walkthrough

Summary by CodeRabbit

Release Notes

  • New Features

    • Added support for S.to v2 episode data extraction, including provider and language information.
    • Enhanced title resolution with API-backed matching for improved accuracy in finding series on S.to.
  • Tests

    • Added test coverage for S.to v2 provider parsing and title resolution workflows.
  • Documentation

    • Added migration analysis and implementation plan documentation for S.to v2 support.

✏️ Tip: You can customize this high-level summary in your review settings.

Walkthrough

Adds S.to v2 support: new provider module for building/fetching/parsing v2 episode pages; updates slug extraction and STO_ALPHABET_URL; integrates API-backed slug search fallback; downloader builds/enriches S.to episodes via lazy imports; adds tests, specs, and minor tooling/.gitignore updates.

Changes

Cohort / File(s) Summary
Config & Ignores
/.gitignore, app/config.py
Added /.ruff_cache/; adjusted spec ignore entries; changed STO_ALPHABET_URL default from .../serien-alphabet to .../serien?by=alpha.
S.to Provider (new v2)
app/providers/sto/v2.py
New module containing language mappings, build_episode_url, HTML fetchers (sync/async), parsing of provider buttons, and enrichment helpers for S.to v2 HTML.
Provider adjustments
app/providers/sto/provider.py
Relaxed slug-extraction regex from /serie/stream/([^/?#]+) to /serie/([^/?#]+) (changes which URLs yield slugs).
Downloader integration
app/core/downloader/episode.py
Episode construction reads site base_url; for S.to uses build_episode_url when available and invokes v2 enrichment with lazy imports and guarded warnings.
Title resolution / Search
app/utils/title_resolver.py
Added S.to API-backed slug search helpers, normalization utilities, fallback slug resolution via S.to suggest API, and updated s.to slug pattern and error handling.
Tests
tests/test_sto_v2.py, tests/test_title_resolver_sto.py, tests/specs/007-sto-v2-support/html/*
Unit tests for v2 URL construction, language parsing, provider parsing (HTML fixture), and title-resolver API fallback/error cases.
Documentation / Specs
specs/007-sto-v2-support/*
Added findings, GitHub-issue draft, and announcement/impact notes describing S.to v2 migration and migration plan.
Release tooling
scripts/release/generate_commit_context.py, scripts/release/generate_release_notes.py
Added short_hash to commit entries/normalized commit data and updated release-note prompt formatting; minor robustness tweaks.
Misc (docstring)
app/core/downloader/utils.py
Escaped backslash in docstring only; no behavioral change.

Sequence Diagram(s)

sequenceDiagram
    participant Downloader as Downloader
    participant URLBuilder as build_episode_url
    participant Episode as Episode
    participant Fetcher as fetch_episode_html
    participant Parser as parse_episode_providers

    Downloader->>URLBuilder: build_episode_url(base_url, slug, season, episode)
    URLBuilder-->>Downloader: episode_url
    Downloader->>Episode: create Episode(link=episode_url, ...)
    Downloader->>Fetcher: fetch_episode_html(episode.link)
    Fetcher-->>Downloader: html_text
    Downloader->>Parser: parse_episode_providers(html_text, base_url)
    Parser-->>Downloader: providers_map, language_ids, language_names
    Downloader->>Episode: set provider/provider_name/language fields
    Episode-->>Downloader: enriched Episode
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • Zzackllack
🚥 Pre-merge checks | ✅ 4 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 48.65% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'S.to v2 migration and provider extraction' clearly and concisely summarizes the main changes in the PR, covering the key aspects of v2 migration support and provider data extraction.
Description check ✅ Passed The PR description is comprehensive and well-structured, covering all template sections including objectives, type of changes, testing checklist, and detailed notes. It references issue #37 and explains the implementation approach across multiple modules.
Linked Issues check ✅ Passed The PR comprehensively addresses issue #37 objectives: implements v2 catalog URL changes (#37.catalog), updates slug extraction patterns (#37.search), adds v2 HTML provider parsing (#37.provider), integrates API fallback search (#37.search), and documents mitigation strategies. All coding-related requirements from the issue are met.
Out of Scope Changes check ✅ Passed All changes are directly aligned with the S.to v2 migration scope: configuration updates (config.py), provider regex adjustments (provider.py), v2 parsing logic (v2.py), episode enrichment (episode.py), API-backed search (title_resolver.py), tests, and documentation. No unrelated changes detected.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch sto-v2-support

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request implements comprehensive support for S.to v2 following the site's migration from v1 to v2. The changes address catalog discovery, search functionality, episode parsing, and provider extraction to restore AniBridge functionality for S.to users after the platform migration.

Changes:

  • Updated S.to catalog URL and slug extraction patterns to match v2 URL structure (/serie/<slug> instead of /serie/stream/<slug>)
  • Added S.to public API search integration as a fallback using /api/search/suggest endpoint
  • Implemented new v2 episode parsing module to extract provider and language data from v2 HTML attributes

Reviewed changes

Copilot reviewed 8 out of 9 changed files in this pull request and generated 15 comments.

Show a summary per file
File Description
specs/007-sto-v2-support/sto-wird-dauerhaft-abgeschaltet-2026.md Documentation of S.to v2 announcement (external content reproduction)
specs/007-sto-v2-support/github-issue.md Issue #37 context and comments documenting the migration
specs/007-sto-v2-support/findings.md Detailed technical analysis and implementation recommendations for v2 migration
app/config.py Updated S.to catalog URL to v2 format (/serien?by=alpha)
app/providers/sto/provider.py Updated slug extraction regex to match v2 URL pattern
app/providers/sto/v2.py New module for v2 episode URL building, HTML parsing, and provider extraction
app/utils/title_resolver.py Added S.to API search integration and updated slug extraction pattern
app/core/downloader/episode.py Integrated v2 provider enrichment for S.to episodes
.gitignore Added v2 support artifacts and ruff cache

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 9

🤖 Fix all issues with AI agents
In `@app/core/downloader/episode.py`:
- Around line 1-3: The module re-imports Optional twice causing an F811; remove
the duplicate import so only a single "from typing import Optional" remains
(delete the redundant "from typing import Optional" line in episode.py), leaving
the existing "from urllib.parse import urlparse" import intact and ensuring no
other typing imports are duplicated.
- Around line 107-114: The broad except around enrich_episode_from_v2_url is
intentional because enrichment is best-effort; update the except block to
include an inline suppression for BLE001 with a brief justification comment
(e.g. add "# noqa: BLE001  # enrichment is optional; swallow unexpected errors
from HTTP/parse steps so episode creation continues") adjacent to the except
line that catches Exception as err, leaving the logger.warning call intact to
record the error details.

In `@app/providers/sto/v2.py`:
- Around line 25-113: The helpers and dataclass (StoProviderEntry,
build_episode_url, fetch_episode_html, parse_language_id,
parse_episode_providers, enrich_episode_from_v2_html,
enrich_episode_from_v2_url) lack PEP 257 docstrings and proper typing for the
episode parameter; update each function and the dataclass with a short docstring
describing purpose, inputs, outputs and dependency notes (mention BeautifulSoup
and http_get usage), and add type hints: import TYPE_CHECKING, forward-declare
or import Episode under TYPE_CHECKING and annotate the episode params as
"Episode" (or Optional[Episode] if applicable); also annotate return types
(e.g., parse_episode_providers -> Tuple[Dict[str, Dict[int, str]], List[int],
List[str]]) and any internal helper signatures to satisfy linters and
documentation standards.

In `@app/utils/title_resolver.py`:
- Around line 503-567: Add PEP 257-style docstrings to the three helpers:
_normalize_alnum should have a one-line description stating it lowercases the
input and returns only alphanumeric characters (e.g., "Lowercase and filter to
alphanumeric characters."), _build_sto_search_terms should document the ordered
variants it returns (raw, compact/normalized alnum, and dashed if the compact is
numeric and length >=3) and that it deduplicates/filters empty terms, and
_search_sto_slug should describe the API lookup behavior (calls S.to suggest for
each term), the scoring logic (token overlap plus large boost for exact
normalized match), and the return semantics (returns the best matching slug or
None). Use concise docstrings (one-line summary plus brief elaboration where
needed) placed directly under each function definition.
- Around line 532-540: The try/except is too broad: narrow the except to only
handle network and JSON decoding errors from the http_get/resp.raise_for_status
and resp.json() calls by catching requests.exceptions.RequestException for the
HTTP calls and json.JSONDecodeError (or ValueError as a broader fallback) for
the JSON parse; update the block around the loop over terms (the url/http_get
call, resp.raise_for_status, and resp.json() usage) to catch only those
exceptions and keep the existing logger.debug(...) and continue behavior for
failures.

In `@specs/007-sto-v2-support/findings.md`:
- Line 1: Remove the H1 header "# S.to V2 Recovery - Findings and Plan" and
prepend required YAML front matter to the top of the file containing the fields
post_title, author1, post_slug, microsoft_alias, featured_image, categories,
tags, ai_note, summary, and post_date (populate post_title with "S.to V2
Recovery - Findings and Plan" and pick a valid category from /categories.txt);
then convert the existing main heading to an H2 (##) and ensure the file begins
with the YAML block followed by H2 headings.

In `@specs/007-sto-v2-support/github-issue.md`:
- Around line 78-112: Update the two typos in the markdown: change the
heading/text "Non public api" to "Non‑public API" (preserve capitalization and
add the hyphen) and change "availabe" to "available" in the sentence mentioning
the catalog/series list; locate the occurrences by searching for the exact
strings "Non public api" and "availabe" in the document and replace them
accordingly.
- Around line 1-59: Replace the top H1 with required YAML front matter
(including title, status, created_by, created_at, and tags) and convert the
initial "# Major Issue: S.to ..." into an H2 (e.g., "## Major Issue: S.to
\"Version 2\" migration risks"); then update all bare URLs (like
https://s.to/sto-wird-dauerhaft-abgeschaltet-2026,
https://github.com/phoenixthrush/AniWorld-Downloader, https://s.to/serien,
https://aniworld.to/animes) to descriptive Markdown links, and ensure other
headings use H2/H3 hierarchy per repo Markdown rules and include any required
front-matter fields exactly as the repo guidelines specify.

In `@specs/007-sto-v2-support/sto-wird-dauerhaft-abgeschaltet-2026.md`:
- Line 1: The file currently starts with an H1 ("# Wird S.to dauerhaft
abgeschaltet? 😱⚰️") and lacks YAML front matter; remove that H1 and prepend
required YAML front matter at the top (include at minimum a title: "Wird S.to
dauerhaft abgeschaltet? 😱⚰️" field, a valid category chosen from
/categories.txt, and any other required front-matter fields used by the
project), then replace the H1 with an H2 ("## Wird S.to dauerhaft abgeschaltet?
😱⚰️") and ensure the rest of the document uses H2/H3 as appropriate; locate the
H1 text in the file to update and add the new YAML block immediately before the
content.
🧹 Nitpick comments (1)
specs/007-sto-v2-support/findings.md (1)

82-97: Consider restructuring to avoid H4 heading depth.

The section "Language handling (v2)" uses an H4 heading (####). The markdown coding guidelines recommend restructuring content if H4 headings are needed, as deep heading nesting reduces readability. Consider promoting this to an H3 heading as a separate top-level subsection under "Detailed findings" or flattening the structure.

As per coding guidelines, avoid deep heading levels and restructure if H4 is needed.

♻️ Suggested restructure to use H3 heading
 ### 3) Episode pages (v2) and provider data
 
 Observed from `https://s.to/serie/9-1-1/staffel-1/episode-1`:
 
 - The provider list is embedded directly in the HTML as buttons with data attributes:
   - `data-play-url="/r?t=<token>"` (opaque tokenized URL)
   - `data-provider-name="VOE" | "Doodstream" | ...`
   - `data-language-label="Deutsch" | "Englisch"`
   - `data-language-id="1" | "2"` (numeric language key)
   - `data-link-id="<numeric>"`
 - The same `/r?t=...` token appears in the main player iframe `src`.
 - `window.__reactMountQueue` includes `seriesId` and `episodeId` in JSON props for the comments widget.
 - CSRF token is embedded in a `<meta name="csrf-token">` element.
 
 Implications for AniBridge:
 
 - S.to v2 no longer uses the v1 `li.episodeLink` structure or `/redirect/` URLs.
 - AniBridge can directly parse provider candidates and language mapping from HTML.
 - `/r?t=...` must be followed to obtain the provider embed URL; treat as opaque and do not attempt to decode.
 
-#### Language handling (v2)
+### 4) Language handling (v2)
+
 Episode pages expose language per provider via data attributes and visible headings (e.g., "Deutsch", "Englisch"). Recommended handling:

And renumber subsequent sections accordingly.

Zzackllack and others added 4 commits January 31, 2026 02:11
… context

- Enhance error handling in `run_git_log` to ensure proper exit on failure.
- Add `short_hash` to commit data for better reference in release notes.
- Update author information retrieval to handle missing data gracefully.
@coderabbitai coderabbitai bot added the documentation Improvements or additions to documentation label Jan 31, 2026
Zzackllack and others added 3 commits January 31, 2026 02:24
…chment

refactor exception handling to enhance resilience during episode creation
by ensuring that the logger captures warnings when enrichment fails.
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In `@app/core/downloader/episode.py`:
- Around line 113-116: The noqa directive is on the wrong line and flagged as
unused; move the "# noqa: BLE001" comment so it sits on the same line as the
"except (Exception) as err" clause that precedes the logger.warning call (i.e.,
the except Exception block wrapping logger.warning("Failed to enrich S.to v2
episode: {}", err)) so the linter recognizes the suppression.

In `@specs/007-sto-v2-support/findings.md`:
- Line 39: Update the incorrect Python version string in the spec line that
reads ".venv/lib/python3.14/site-packages/aniworld/*" to reference the baseline
runtime Python 3.12 (i.e., change "python3.14" to "python3.12") so the path
becomes ".venv/lib/python3.12/site-packages/aniworld/*".

In `@specs/007-sto-v2-support/github-issue.md`:
- Around line 1-24: The YAML front matter block (the leading '---' and the keys
like post_title/title/post_date/etc.) must be moved to the very top of the file
and become the first content; remove the current leading H1 ("# Major Issue:
S.to \"Version 2\" migration risks") and replace it with an H2 ("## Major Issue:
S.to \"Version 2\" migration risks") after the front matter; ensure the front
matter remains delimited by '---' and that no H1 lines remain in the document.
🧹 Nitpick comments (9)
scripts/release/generate_release_notes.py (2)

52-63: Prefer the explicit short_hash field when present.
This keeps the payload consistent with commit_context.json and any curated abbreviations.

Suggested update
-        short_hash = entry.get("abbrev") or (commit_hash[:7] if commit_hash else "")
+        short_hash = (
+            entry.get("short_hash")
+            or entry.get("abbrev")
+            or (commit_hash[:7] if commit_hash else "")
+        )

87-95: Explicitly instruct the model to call out migrations/API/config/compliance items.
This aligns the output with release-note expectations and reduces omission risk.

Suggested prompt tweak
     - Prefer concise summaries; expand only when the commit message is ambiguous.
     - Do not place a commit link on the summary text itself; only the hash is linked.
+    - Call out migrations, API impacts, configuration additions, and compliance notes
+      explicitly when present.
Based on learnings "Generate comprehensive release notes summarizing key changes, migrations, API impacts, and compliance notes" and "Include API changes, configuration additions, and breaking changes in release notes and docs".
specs/007-sto-v2-support/sto-wird-dauerhaft-abgeschaltet-2026.md (1)

30-44: Consider using bullet list format instead of blockquotes.

The feature list uses blockquote syntax (>) which is typically for quoted content. Per coding guidelines, bullet lists should use - prefix. This would improve semantic correctness and readability.

📝 Suggested format change
-    > Deutlich verbesserte mobile Bedienung
-    > Optimierte Serien-Empfehlungen (dynamische Bereiche, neue Serien entdecken)
-    > DE/EN Mehrsprachigkeit der Website
+- Deutlich verbesserte mobile Bedienung
+- Optimierte Serien-Empfehlungen (dynamische Bereiche, neue Serien entdecken)
+- DE/EN Mehrsprachigkeit der Website

(Apply similar changes to the remaining items)

specs/007-sto-v2-support/github-issue.md (1)

101-103: Add blank line before heading.

Static analysis indicates a missing blank line before the heading on line 101, which affects markdown rendering consistency.

📝 Fix
 ---
 
+
 ### Comment by `@Zzackllack` at 2026-01-29 23:05:49.000 UTC
tests/test_sto_v2.py (1)

10-13: Fixture path construction may be fragile.

The path resolution uses parents[1] assuming the test file is exactly one level deep from the repo root. Consider using a more robust approach or documenting this assumption.

💡 Alternative approach
def _read_episode_fixture() -> str:
    # Find repo root by looking for a known marker file
    current = Path(__file__).resolve().parent
    while current != current.parent:
        if (current / "specs").is_dir():
            break
        current = current.parent
    path = current / "specs" / "007-sto-v2-support" / "html" / "2-episode.html"
    return path.read_text(encoding="utf-8")

Or use pytest's tmp_path fixture with test data, or a conftest.py fixture.

app/utils/title_resolver.py (1)

546-581: Variable name shadowing: url is reused.

On line 548, url is the API endpoint, but on line 567 it's reassigned to the entry's URL from the response. This shadowing could cause confusion during debugging. Consider renaming one of them.

📝 Suggested fix
         for entry in shows:
             if not isinstance(entry, dict):
                 continue
             name = str(entry.get("name") or "").strip()
-            url = str(entry.get("url") or "").strip()
-            slug = _extract_slug(url, "s.to")
+            entry_url = str(entry.get("url") or "").strip()
+            slug = _extract_slug(entry_url, "s.to")
             if not slug or not name:
                 continue
app/providers/sto/v2.py (3)

51-63: Consider an async wrapper to avoid blocking I/O.

This helper is I/O-bound and synchronous; in async flows it will block the event loop. Consider adding an async wrapper (e.g., asyncio.to_thread) or migrating to an async client.
As per coding guidelines: Use asyncio or multiprocessing for I/O-bound and CPU-bound tasks respectively; avoid GIL bottlenecks in CPU-bound code.

♻️ Suggested addition
+import asyncio
+
 def fetch_episode_html(url: str) -> str:
     """Fetch raw episode HTML using the shared HTTP client.
@@
     resp.raise_for_status()
     return resp.text
+
+async def fetch_episode_html_async(url: str) -> str:
+    """Asynchronously fetch episode HTML without blocking the event loop."""
+    return await asyncio.to_thread(fetch_episode_html, url)

84-128: Use urljoin for more robust redirect URL resolution.

The current concat only handles leading slashes. urljoin cleanly supports absolute URLs and any relative path variants.

♻️ Suggested change
+from urllib.parse import urljoin
@@
-        redirect_url = play_url
-        if redirect_url.startswith("/"):
-            redirect_url = f"{base_url.rstrip('/')}{redirect_url}"
+        base = f"{base_url.rstrip('/')}/"
+        redirect_url = urljoin(base, play_url)

159-173: Consider adding exception handling for better error context.

fetch_episode_html raises on HTTP failures. While the caller in app/core/downloader/episode.py already catches exceptions from enrich_episode_from_v2_url, adding error handling at the source would provide clearer error context (knowing specifically that the HTML fetch failed). This is a defensive improvement rather than a critical fix, since enrichment already degrades gracefully at the caller level.

Suggested fix
     link = getattr(episode, "link", None)
     if not link:
         return
-    html_text = fetch_episode_html(link)
+    try:
+        html_text = fetch_episode_html(link)
+    except Exception as exc:
+        logger.warning("Failed to fetch S.to v2 HTML for {}: {}", link, exc)
+        return
     enrich_episode_from_v2_html(episode=episode, html_text=html_text, base_url=base_url)

Comment on lines +1 to +24
# Major Issue: S.to "Version 2" migration risks (AniWorld likely affected)
---
post_title: "S.to Version 2 Migration Risks"
author1: "Zzackllack"
post_slug: "sto-v2-migration-risks"
microsoft_alias: "tbd"
featured_image: ""
categories:
- "specs"
tags:
- "s.to"
- "aniworld"
- "migration"
- "risk"
ai_note: "Drafted with AI assistance."
summary: "Issue tracking notes for the S.to v2 migration and AniBridge impact."
post_date: "2026-01-31"
title: "Major Issue: S.to Version 2 migration risks"
status: "open"
created_by: "Zzackllack"
created_at: "2026-01-18 22:35:36.000 UTC"
---

## Major Issue: S.to "Version 2" migration risks
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

YAML front matter must be at the beginning of the file.

The file starts with an H1 heading on line 1, but YAML front matter must be the very first content in the file. Additionally, H1 headings should not be included per coding guidelines. Move the front matter to line 1 and convert the H1 to H2.

📝 Proposed fix
-# Major Issue: S.to "Version 2" migration risks (AniWorld likely affected)
 ---
 post_title: "S.to Version 2 Migration Risks"
 author1: "Zzackllack"
 ...
 ---
 
+## Major Issue: S.to "Version 2" migration risks (AniWorld likely affected)
-## Major Issue: S.to "Version 2" migration risks

The front matter block (--- delimiters and YAML content) should start at line 1, followed by the H2 heading.

As per coding guidelines: "Include YAML front matter at the beginning of the file" and "do not include an H1 heading."

🤖 Prompt for AI Agents
In `@specs/007-sto-v2-support/github-issue.md` around lines 1 - 24, The YAML front
matter block (the leading '---' and the keys like
post_title/title/post_date/etc.) must be moved to the very top of the file and
become the first content; remove the current leading H1 ("# Major Issue: S.to
\"Version 2\" migration risks") and replace it with an H2 ("## Major Issue: S.to
\"Version 2\" migration risks") after the front matter; ensure the front matter
remains delimited by '---' and that no H1 lines remain in the document.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@tests/test_sto_v2.py`:
- Around line 1-2: The file imports Path twice causing a duplicate definition
(Ruff F811); remove the redundant import by deleting the duplicate "from pathlib
import Path" so only a single import of Path remains (locate the duplicate in
tests/test_sto_v2.py where "from pathlib import Path" appears twice).

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@specs/007-sto-v2-support/findings.md`:
- Line 183: Replace the incorrect Python version string "python3.14" with the
project baseline "python3.12" in the findings text that lists
`.venv/lib/python3.14/site-packages/aniworld/*`; update any occurrences of the
"python3.14" token (same place that was fixed earlier at line referencing the
similar path) so all references reflect Python 3.12 as the AniBridge baseline
runtime.
🧹 Nitpick comments (3)
specs/007-sto-v2-support/findings.md (1)

101-102: Add blank line before heading per markdown lint rules.

The heading on line 102 lacks a preceding blank line, triggering MD022.

📝 Suggested fix
 ### 4) Language handling (v2)
+
 Episode pages expose language per provider via data attributes and visible headings (e.g., "Deutsch", "Englisch"). Recommended handling:
app/providers/sto/v2.py (2)

178-182: Narrow exception handling to specific types.

Catching bare Exception (BLE001) can mask unexpected failures. The fetch_episode_html call raises requests.exceptions.RequestException on network errors or HTTP failures. Narrowing the catch improves debuggability.

📝 Suggested fix
+import requests.exceptions
+
 ...
 
     try:
         html_text = fetch_episode_html(link)
-    except Exception as exc:
+    except requests.exceptions.RequestException as exc:
         logger.warning("Failed to fetch S.to v2 HTML for {}: {}", link, exc)
         return

68-70: Add docstring to async wrapper function.

The fetch_episode_html_async function lacks a docstring while all other functions in this module have them.

📝 Suggested fix
 async def fetch_episode_html_async(url: str) -> str:
-    """Asynchronously fetch episode HTML without blocking the event loop."""
+    """Asynchronously fetch episode HTML without blocking the event loop.
+
+    Parameters:
+        url: Episode page URL to fetch.
+
+    Returns:
+        HTML response body as a string.
+    """
     return await asyncio.to_thread(fetch_episode_html, url)

As per coding guidelines: "Provide docstrings following PEP 257 conventions."


### AniWorld-Downloader dependency status

Findings from `.venv/lib/python3.14/site-packages/aniworld/*`:
Copy link
Contributor

@coderabbitai coderabbitai bot Jan 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Incorrect Python version reference.

Line 183 references python3.14 but Python 3.14 doesn't exist yet, and the project baseline is Python 3.12. This appears to be an oversight since line 39 was already corrected.

📝 Suggested fix
-Findings from `.venv/lib/python3.14/site-packages/aniworld/*`:
+Findings from `.venv/lib/python3.12/site-packages/aniworld/*`:

As per coding guidelines: "Use Python 3.12 as the baseline runtime version for the AniBridge application."

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Findings from `.venv/lib/python3.14/site-packages/aniworld/*`:
Findings from `.venv/lib/python3.12/site-packages/aniworld/*`:
🤖 Prompt for AI Agents
In `@specs/007-sto-v2-support/findings.md` at line 183, Replace the incorrect
Python version string "python3.14" with the project baseline "python3.12" in the
findings text that lists `.venv/lib/python3.14/site-packages/aniworld/*`; update
any occurrences of the "python3.14" token (same place that was fixed earlier at
line referencing the similar path) so all references reflect Python 3.12 as the
AniBridge baseline runtime.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stupid? Of course python 3.14 exist. I use it locally in my dev enviroment. There is no reason to change that... It is a spec file that no one will ever look at again.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧩 Analysis chain

🌐 Web query:

Python 3.14 release January 2026

💡 Result:

Python 3.14 was not first released in January 2026.

  • Python 3.14.0 (final) released October 7, 2025. [2]
  • As of January 2026, the latest 3.14 maintenance release is Python 3.14.2, released December 5, 2025. [3]
  • The official release schedule lists Python 3.14.3 as the next bugfix release, expected February 3, 2026. [1]

Sources: PEP 745 release schedule [1], python.org release pages for 3.14.0 [2] and 3.14.2 [3].


@Zzackllack, you're absolutely right, and I apologize for the incorrect comment. Python 3.14 does exist—it was released in October 2025, with Python 3.14.2 available as of December 2025. Since you're using it in your local development environment, the path .venv/lib/python3.14/site-packages/aniworld/* accurately reflects your actual findings.

I incorrectly applied the Python 3.12 baseline (which applies to production code) to a spec document that's simply recording what you observed in your environment. Spec files should document reality, not prescribe baselines. My mistake!


✏️ Learnings added
Learnt from: Zzackllack
Repo: Zzackllack/AniBridge PR: 42
File: specs/007-sto-v2-support/findings.md:183-183
Timestamp: 2026-01-31T01:43:33.797Z
Learning: Spec and findings documents (e.g., files under specs/) record actual observations and research findings from development environments. They should reflect reality as discovered, not be constrained by production baseline versions.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.


🧠 Learnings used
Learnt from: CR
Repo: Zzackllack/AniBridge PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-27T19:00:58.975Z
Learning: Applies to **/*.{py,toml,txt,cfg} : Use Python 3.12 as the baseline runtime version for the AniBridge application

Learnt from: CR
Repo: Zzackllack/AniBridge PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-27T19:00:58.975Z
Learning: Generate comprehensive release notes summarizing key changes, migrations, API impacts, and compliance notes

Learnt from: CR
Repo: Zzackllack/AniBridge PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-27T19:00:58.975Z
Learning: Include API changes, configuration additions, and breaking changes in release notes and docs

@Zzackllack Zzackllack merged commit 4e6ab8a into main Jan 31, 2026
6 checks passed
@Zzackllack Zzackllack deleted the sto-v2-support branch January 31, 2026 02:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working documentation Improvements or additions to documentation enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Major Issue: S.to "Version 2" migration risks (AniWorld likely affected)

2 participants