Skip to content

feat(de/aniworld): More hosters, faster video loading & fix preferences#71

Merged
cuong-tran merged 16 commits intomasterfrom
de/aniworld
Mar 14, 2026
Merged

feat(de/aniworld): More hosters, faster video loading & fix preferences#71
cuong-tran merged 16 commits intomasterfrom
de/aniworld

Conversation

@cuong-tran
Copy link
Contributor

@cuong-tran cuong-tran commented Mar 14, 2026

Summary by Sourcery

Update the AniWorld extension to use async utilities, broaden supported hosters, and modernize search, episode parsing, and preference handling.

New Features:

  • Add support for Filemoon and Vidmoly hosters to the AniWorld video extractor pipeline.
  • Introduce a per-hoster exclusion preference alongside preferred hoster and language settings.

Bug Fixes:

  • Fix preference handling for hoster and language selection by delegating to shared utilities and validating stored values.
  • Correct DDoS-Guard cookie fetching by properly consuming response bodies.

Enhancements:

  • Improve search handling by using the newer seriesSearch endpoint and parsing JSON results directly without extra page fetches.
  • Speed up episode list and video extraction by parallelizing season loading and hoster resolution with awaitable utilities.
  • Modernize anime, episode, and video parsing to use absolute URLs, safer parsing helpers, and cleaner language mapping.
  • Adjust video sorting to prioritize entries based on preferred hoster and language using a combined comparator.

Build:

  • Bump the AniWorld extension version code to 33 and add dependencies for Filemoon and Vidmoly extractor libraries.

Copilot AI review requested due to automatic review settings March 14, 2026 16:41
@sourcery-ai
Copy link

sourcery-ai bot commented Mar 14, 2026

Reviewer's Guide

Refactors the AniWorld extension to use modern utilities, speeds up episode and video loading with parallel/suspend-based networking, adds Filemoon and Vidmoly hosters plus per-language/hoster preferences (including exclusions), fixes Vidoza and DDoS-Guard handling, and updates build dependencies and version code.

Sequence diagram for parallel video extraction and preferences-aware hoster selection

sequenceDiagram
    actor User
    participant AniWorldSource
    participant OkHttpClient
    participant VoeExtractor
    participant DoodExtractor
    participant StreamTapeExtractor
    participant VidozaExtractor
    participant FilemoonExtractor
    participant VidMolyExtractor

    User->>AniWorldSource: openEpisodePage()
    AniWorldSource->>OkHttpClient: GET episodePage
    OkHttpClient-->>AniWorldSource: Response html
    AniWorldSource->>AniWorldSource: videoListParse(response)

    AniWorldSource->>AniWorldSource: select redirectLinks (ul.row li)
    par forEach redirectLink in parallel
        AniWorldSource->>AniWorldSource: getLanguage(langKey)
        AniWorldSource->>OkHttpClient: GET redirectUrl
        OkHttpClient-->>AniWorldSource: Redirected response
        AniWorldSource->>AniWorldSource: getRedirectedUrl(url)
        AniWorldSource->>AniWorldSource: match hoster in PREF_HOSTER_NAMES - excludedHosters

        alt matchedHoster is VOE
            AniWorldSource->>VoeExtractor: videosFromUrl(finalUrl, "(language) ")
            VoeExtractor-->>AniWorldSource: List Video
        else matchedHoster is Doodstream
            AniWorldSource->>DoodExtractor: videoFromUrl(finalUrl, "(language)", false)
            DoodExtractor-->>AniWorldSource: Video or null
        else matchedHoster is Streamtape
            AniWorldSource->>StreamTapeExtractor: videoFromUrl(finalUrl, "(language) Streamtape")
            StreamTapeExtractor-->>AniWorldSource: Video or null
        else matchedHoster is Vidoza
            AniWorldSource->>VidozaExtractor: videoFromUrl(finalUrl, "(language) Vidoza")
            VidozaExtractor-->>AniWorldSource: Video or null
        else matchedHoster is Filemoon
            AniWorldSource->>FilemoonExtractor: videosFromUrl(finalUrl, "(language) Filemoon ", headers)
            FilemoonExtractor-->>AniWorldSource: List Video
        else matchedHoster is Vidmoly
            AniWorldSource->>VidMolyExtractor: videosFromUrl(finalUrl, "(language) ")
            VidMolyExtractor-->>AniWorldSource: List Video
        else no supported hoster or excluded
            AniWorldSource-->>AniWorldSource: ignore link
        end
    and
    end

    AniWorldSource->>AniWorldSource: merge all Video lists
    AniWorldSource->>AniWorldSource: sort Videos by preferredHoster then preferredLang
    AniWorldSource-->>User: sorted List Video
Loading

Updated class diagram for AniWorld source, VidozaExtractor, and DdosGuardInterceptor

classDiagram
    class ParsedAnimeHttpSource
    class ConfigurableAnimeSource

    class AniWorld {
        -voeExtractor: VoeExtractor
        -doodExtractor: DoodExtractor
        -streamTapeExtractor: StreamTapeExtractor
        -vidozaExtractor: VidozaExtractor
        -filemoonExtractor: FilemoonExtractor
        -vidmolyExtractor: VidMolyExtractor
        -preferredLang: String
        -preferredHosterPref: String
        -preferredHoster: String
        -excludedHosters: Set_String
        +popularAnimeRequest(page: Int): Request
        +popularAnimeFromElement(element: Element): SAnime
        +latestUpdatesRequest(page: Int): Request
        +latestUpdatesFromElement(element: Element): SAnime
        +searchAnimeRequest(page: Int, query: String, filters: AnimeFilterList): Request
        +searchAnimeParse(response: Response): AnimesPage
        +animeDetailsParse(document: Document): SAnime
        +episodeListParse(response: Response): List_SEpisode
        +episodeFromElement(element: Element): SEpisode
        +videoListParse(response: Response): List_Video
        +getRedirectedUrl(url: String): String
        +getLanguage(langKey: String): String
        +sort(videos: List_Video): List_Video
        +setupPreferenceScreen(screen: PreferenceScreen): void
        <<companion_object>>
        -PREF_HOSTER_KEY: String
        -PREF_EXCLUDED_HOSTERS_KEY: String
        -NAME_DOOD: String
        -NAME_STAPE: String
        -NAME_VOE: String
        -NAME_VIZ: String
        -NAME_FILEMOON: String
        -NAME_VIDMOLY: String
        -PREF_HOSTER_NAMES: List_String
        -PREF_HOSTER_DEFAULT: String
        -PREF_LANG_KEY: String
        -LANGS: Map_String_String
        -PREF_LANGS: List_String
        -PREF_LANG_DEFAULT: String
    }

    class VidozaExtractor {
        -client: OkHttpClient
        +videoFromUrl(url: String, quality: String): Video
    }

    class DdosGuardInterceptor {
        -client: OkHttpClient
        +intercept(chain: Interceptor_Chain): Response
        -getDdgCookie(url: HttpUrl): Cookie
    }

    class VoeExtractor
    class DoodExtractor
    class StreamTapeExtractor
    class FilemoonExtractor
    class VidMolyExtractor

    class PreferenceScreen
    class OkHttpClient

    AniWorld ..|> ParsedAnimeHttpSource
    AniWorld ..|> ConfigurableAnimeSource

    AniWorld --> VoeExtractor
    AniWorld --> DoodExtractor
    AniWorld --> StreamTapeExtractor
    AniWorld --> VidozaExtractor
    AniWorld --> FilemoonExtractor
    AniWorld --> VidMolyExtractor

    AniWorld --> PreferenceScreen

    VidozaExtractor --> OkHttpClient
    DdosGuardInterceptor --> OkHttpClient

    ParsedAnimeHttpSource <|-- AniWorld
    ConfigurableAnimeSource <|-- AniWorld

    note for VidozaExtractor "Uses awaitSuccess and useAsJsoup to safely build Video(videoUrl, quality, videoUrl)"
Loading

File-Level Changes

Change Details Files
Modernize anime listing, search, and details parsing to use absolute URLs, new search endpoint, and safer null handling.
  • Refactor popular and latest anime element parsers to build SAnime via apply, use abs:href/abs:data-src, and reuse popular parser for latest updates.
  • Replace legacy POST /ajax/search with query-based GET /ajax/seriesSearch and simplified headers.
  • Parse search results directly from JSON fields (name, link, cover, description) without issuing extra per-result HTTP requests.
  • Use UrlUtils.fixUrl to normalize cover URLs and replace thumbnail size 150x225 with 220x330.
  • Update animeDetailsParse to use abs:data-src, nullable description, and more idiomatic SAnime.apply construction while keeping status UNKNOWN.
src/de/aniworld/src/eu/kanade/tachiyomi/animeextension/de/aniworld/AniWorld.kt
Speed up episode list and video loading via suspend-based helpers and parallelized network calls, while making episode parsing more robust.
  • Switch episodeListParse to use Response.useAsJsoup and parallelCatchingFlatMapBlocking over season links, dropping the separate movie parser and reversing at the end.
  • Change parseEpisodesFromSeries to a suspend function using awaitSuccess + useAsJsoup and safe episodeFromElement mapping with runCatching.
  • Tighten episodeFromElement to compute season/film naming based on URL, guard numeric parsing with toFloatOrNull, and reuse common extraction logic.
  • Use useAsJsoup in videoListParse and parallelCatchingFlatMapBlocking over hoster elements for concurrent extraction of videos.
  • Introduce suspend getRedirectedUrl using awaitSuccess to resolve final hoster URLs without leaking responses.
src/de/aniworld/src/eu/kanade/tachiyomi/animeextension/de/aniworld/AniWorld.kt
Extend and refactor hoster extraction pipeline to support additional hosters and cleaner mapping, including preference-based filtering and sorting.
  • Add lazy extractor instances for Voe, Dood, StreamTape, Vidoza, Filemoon, and Vidmoly using injected OkHttp client and headers.
  • Replace old hosterSelection set and manual per-hoster branching with a normalized hoster name matching against PREF_HOSTER_NAMES minus excludedHosters.
  • Map matched hoster names to the appropriate extractor calls (including new Filemoon and Vidmoly), using language-prefixed quality strings and null-safe video list construction.
  • Introduce getLanguage that maps language keys via a LANGS map, defaulting to '?', and use it for consistent language labels in quality strings.
  • Simplify List
src/de/aniworld/src/eu/kanade/tachiyomi/animeextension/de/aniworld/AniWorld.kt
Redesign user preferences to use modern helpers, separate preferred hoster from exclusions, and fix language/hoster preference handling.
  • Remove AWConstants and replace its usages with a companion object defining hoster name constants, language key-to-label map, and default values.
  • Introduce delegated preferences for preferredLang, preferredHosterPref, and excludedHosters using keiyoushi.utils.delegate; derive preferredHoster by validating against allowed names.
  • Replace manual ListPreference/MultiSelectListPreference construction and onChange handlers with addListPreference and addSetPreference helpers on PreferenceScreen.
  • Add new "Ausgeschlossene Hoster" multi-select preference to allow users to opt out of specific hosters, feeding into excludedHosters read by videoListParse.
  • Ensure language preference uses the LANGS.values list for entries/values and that preferred hoster defaults to the first defined hoster name (currently VOE).
src/de/aniworld/src/eu/kanade/tachiyomi/animeextension/de/aniworld/AniWorld.kt
src/de/aniworld/src/eu/kanade/tachiyomi/animeextension/de/aniworld/AWConstants.kt
Make Vidoza extractor networking suspend-friendly and fix video object construction.
  • Change VidozaExtractor.videoFromUrl to a suspend function using awaitSuccess and useAsJsoup instead of execute().asJsoup().
  • Refactor script parsing to safely obtain the script body, extract the sourcesCode URL, and return a Video whose url and videoUrl both point to the direct media URL rather than the page URL.
  • Update call site in AniWorld.videoListParse to call the new suspend videoFromUrl signature and wrap the single returned Video in a list when non-null.
src/de/aniworld/src/eu/kanade/tachiyomi/animeextension/de/aniworld/extractors/VidozaExtractor.kt
src/de/aniworld/src/eu/kanade/tachiyomi/animeextension/de/aniworld/AniWorld.kt
Harden DDoS-Guard cookie retrieval to avoid leaking bodies and use shared body reading utilities.
  • Replace direct Response.body.string() usage with bodyString() when fetching the .well-known path content to avoid manual resource management.
  • Wrap the follow-up GET(checkUrl) call in use { } when reading the set-cookie header to ensure the response body is closed.
  • Keep the existing cookie parsing logic but ensure all network responses are properly consumed/closed for reliability.
src/de/aniworld/src/eu/kanade/tachiyomi/animeextension/de/aniworld/DdosGuardInterceptor.kt
Update build metadata and dependencies for new hosters.
  • Bump AniWorld extension extVersionCode from 32 to 33 in build.gradle to reflect the new release.
  • Add Filemoon and Vidmoly extractor library dependencies to the AniWorld module so the new hosters can be used at runtime.
src/de/aniworld/build.gradle

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly upgrades the AniWorld anime extension by introducing two new video hosters, Filemoon and Vidmoly, which provides users with more viewing options. It also focuses on enhancing the user experience by optimizing video loading times through parallel and asynchronous processing. Furthermore, the internal architecture for managing user preferences has been modernized, and the search mechanism has been updated for improved reliability and performance.

Highlights

  • Added New Video Hosters: Integrated support for Filemoon and Vidmoly, expanding the available video sources for AniWorld content.
  • Improved Video Loading Performance: Refactored video source parsing to utilize parallel processing and asynchronous network calls, leading to faster retrieval of video links.
  • Modernized Preference Management: Migrated preference handling to use keiyoushi.utils helper functions and a companion object for constants, simplifying the preference setup and removing the deprecated AWConstants.kt file.
  • Updated Search Functionality: Modified the anime search request from a POST to a GET method with simplified headers, aligning with potential AniWorld site changes and improving search efficiency.
  • General Code Refinements: Applied various code improvements across the extension, including more robust error handling, clearer object creation, and better URL parsing for anime details and episodes.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • src/de/aniworld/build.gradle
    • Updated the extension version code to 33.
    • Added new dependencies for filemoonextractor and vidmolyextractor.
  • src/de/aniworld/src/eu/kanade/tachiyomi/animeextension/de/aniworld/AWConstants.kt
    • Removed the file, as its constants were migrated to the AniWorld.kt companion object.
  • src/de/aniworld/src/eu/kanade/tachiyomi/animeextension/de/aniworld/AniWorld.kt
    • Removed deprecated preference imports and added new imports for FilemoonExtractor, VidMolyExtractor, and keiyoushi.utils.
    • Refactored popularAnimeFromElement and animeDetailsParse for more concise SAnime object creation.
    • Simplified latestUpdatesFromElement to reuse popularAnimeFromElement logic.
    • Updated searchAnimeRequest to use a GET request with query parameters and streamlined headers.
    • Refactored searchAnimeParse to directly map JSON results to SAnime objects.
    • Modified episodeListParse to use parallelCatchingFlatMapBlocking for efficient episode retrieval.
    • Updated parseEpisodesFromSeries to be a suspend function and use awaitSuccess().useAsJsoup().
    • Refined episodeFromElement for improved parsing of episode names and numbers.
    • Initialized all video extractors as lazy properties for better resource management.
    • Rewrote videoListParse to leverage parallel processing and dynamically select hosters based on user preferences.
    • Introduced getRedirectedUrl and getLanguage helper functions.
    • Updated List<Video>.sort() to use a more efficient compareByDescending for sorting.
    • Refactored setupPreferenceScreen to use keiyoushi.utils for preference creation and moved all related constants into a companion object.
  • src/de/aniworld/src/eu/kanade/tachiyomi/animeextension/de/aniworld/DdosGuardInterceptor.kt
    • Added keiyoushi.utils.bodyString import.
    • Updated network call handling to use bodyString() and use { it.header("set-cookie") } for improved resource management.
  • src/de/aniworld/src/eu/kanade/tachiyomi/animeextension/de/aniworld/extractors/VidozaExtractor.kt
    • Added eu.kanade.tachiyomi.network.awaitSuccess and keiyoushi.utils.useAsJsoup imports.
    • Converted videoFromUrl to a suspend function and updated its network call to be asynchronous.
    • Corrected the Video object creation to use the extracted videoUrl for both URL fields.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey - I've found 1 issue, and left some high level feedback:

  • The new video sorting logic checks quality.contains(preferredHoster, true), but some qualities (e.g., VOE, where labels are just ($language)) don’t contain the hoster name, so either include the hoster name in all quality strings or switch the hoster preference matching to use another field (like the URL) to keep sorting consistent.
  • In videoListParse, hoster detection relies on hoster.contains(PREF_HOSTER_NAME, true), which is somewhat brittle; consider mapping the raw hoster label values to constants (e.g., via a when on normalized hoster text) to make extractor selection more robust to small naming changes on the site.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The new video sorting logic checks `quality.contains(preferredHoster, true)`, but some qualities (e.g., VOE, where labels are just `($language)`) don’t contain the hoster name, so either include the hoster name in all quality strings or switch the hoster preference matching to use another field (like the URL) to keep sorting consistent.
- In `videoListParse`, hoster detection relies on `hoster.contains(PREF_HOSTER_NAME, true)`, which is somewhat brittle; consider mapping the raw hoster label values to constants (e.g., via a `when` on normalized hoster text) to make extractor selection more robust to small naming changes on the site.

## Individual Comments

### Comment 1
<location path="src/de/aniworld/src/eu/kanade/tachiyomi/animeextension/de/aniworld/AniWorld.kt" line_range="214-215" />
<code_context>
-
-        return newList
-    }
+    override fun List<Video>.sort() = sortedWith(
+        compareByDescending<Video> { it.quality.contains(preferredHoster, true) }
+            .thenByDescending { it.quality.contains(preferredLang, true) },
+    )
</code_context>
<issue_to_address>
**issue (bug_risk):** Hoster preference is ineffective because quality strings no longer contain the hoster name.

The sort now checks `it.quality.contains(preferredHoster, true)`, but `quality` only holds strings like `"($language)"`, so the hoster name is never present and `preferredHoster` has no effect. Either include the hoster in `quality` (e.g. `"$hoster ($language)"`) or sort using `video.url` or another field that actually contains the hoster identifier.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This is a great pull request that brings significant improvements to the AniWorld extension. The addition of new hosters, the performance enhancements through parallel and asynchronous network calls, and the modernization of the codebase are all excellent changes. The code is now more idiomatic, robust, and efficient. I've identified a couple of high-severity issues in the new implementation that should be addressed: a potential resource leak and a bug in the video sorting logic. My detailed comments are below.

Copy link
Contributor

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

Enhances the AniWorld (de) extension by adding additional supported hosters, reducing blocking I/O during extraction, and reworking hoster/language preferences to improve video loading and sorting behavior.

Changes:

  • Added Filemoon and VidMoly hosters and refactored video extraction to run in parallel.
  • Migrated some network calls to coroutine-friendly helpers (awaitSuccess, useAsJsoup, bodyString) and improved resource closing.
  • Reworked preference UI and internal preference handling for hoster/language selection.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/de/aniworld/.../extractors/VidozaExtractor.kt Converts extraction to suspend + coroutine-friendly response handling; adjusts Video construction.
src/de/aniworld/.../DdosGuardInterceptor.kt Uses bodyString() and closes responses via use for safer networking.
src/de/aniworld/.../AniWorld.kt Major refactor: parallel hoster extraction, new hosters, updated search endpoint, and reworked preferences + sorting.
src/de/aniworld/.../AWConstants.kt Removes the old constants container (values moved inline into AniWorld).
src/de/aniworld/build.gradle Bumps extension version and adds new extractor library dependencies.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Copy link
Contributor

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

Updates the AniWorld anime extension to expand supported video hosters, speed up episode/video retrieval, and modernize preference handling and network utilities.

Changes:

  • Added new hosters (Filemoon, Vidmoly) and refactored video extraction to use parallel network calls.
  • Modernized parsing/networking utilities (e.g., awaitSuccess, useAsJsoup, bodyString) and improved search endpoint usage.
  • Reworked preferences to support preferred language/hoster plus an excluded-hoster system, removing the previous constants-based preference setup.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/de/aniworld/.../extractors/VidozaExtractor.kt Makes Vidoza extraction suspend-based and adjusts Video construction.
src/de/aniworld/.../DdosGuardInterceptor.kt Uses safer response-body handling and closes responses reliably.
src/de/aniworld/.../AniWorld.kt Main refactor: parallel loading, new hosters, updated search/details parsing, and new preferences.
src/de/aniworld/.../AWConstants.kt Removes legacy constants (including old preference keys/values).
src/de/aniworld/build.gradle Bumps versionCode and adds extractor library dependencies.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

@cuong-tran
Copy link
Contributor Author

/gemini review

@cuong-tran
Copy link
Contributor Author

@sourcery-ai review

Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey - I've found 1 issue, and left some high level feedback:

  • The new video sort logic relies on Video.quality containing the preferred hoster name, but some extractors (e.g. VOE and Vidmoly) build qualities without the hoster label, so either adjust their quality strings to include the hoster name or change the sort predicate to use a more reliable hoster indicator (like URL or an added metadata field).
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The new video sort logic relies on `Video.quality` containing the preferred hoster name, but some extractors (e.g. VOE and Vidmoly) build qualities without the hoster label, so either adjust their quality strings to include the hoster name or change the sort predicate to use a more reliable hoster indicator (like URL or an added metadata field).

## Individual Comments

### Comment 1
<location path="src/de/aniworld/src/eu/kanade/tachiyomi/animeextension/de/aniworld/AniWorld.kt" line_range="197-201" />
<code_context>
+            val url = getRedirectedUrl(redirectgs)
+            when (matchedHoster) {
+                NAME_VOE -> voeExtractor.videosFromUrl(url, "($language) ")
+                NAME_DOOD -> doodExtractor.videoFromUrl(url, "($language)", false)?.let(::listOf)
+                NAME_STAPE -> streamTapeExtractor.videoFromUrl(url, "($language) $NAME_STAPE")?.let(::listOf)
+                NAME_VIZ -> vidozaExtractor.videoFromUrl(url, "($language) $NAME_VIZ")?.let(::listOf)
+                NAME_FILEMOON -> filemoonExtractor.videosFromUrl(url, "($language) $NAME_FILEMOON ", headers)
+                NAME_VIDMOLY -> vidmolyExtractor.videosFromUrl(url, "($language) ")
+                else -> null
+            } ?: emptyList()
</code_context>
<issue_to_address>
**issue (bug_risk):** Doodstream (and Vidmoly) video qualities no longer contain the hoster name, which undermines the new sorting logic.

Because the sort relies on `quality.contains(preferredHoster, true)`, entries for Doodstream and Vidmoly will never be prioritized when selected as the preferred hoster: their quality strings are only `"($language)"`/`"($language) "` and don’t include the hoster name, unlike STAPE/FILEMOON/VIZ. Please align these to the others (e.g. `"($language) $NAME_DOOD"`, `"($language) $NAME_VIDMOLY"`) so preferred hoster sorting works consistently.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request significantly improves the AniWorld extension by adding new hosters, speeding up video and episode loading through parallelization, and modernizing the preference handling. The code is much cleaner, more performant, and robust.

I've added a couple of suggestions: one is a minor performance optimization to avoid repeated calculations within a loop, and the other is a fix for a potential parsing issue in the Vidoza extractor to make it more resilient.

Overall, this is an excellent update with substantial improvements across the board.

…dling

* Delete `AWConstants.kt` and move relevant constants into `AniWorld` companion object.
* Refactor `videoListParse` to use new hoster constants and simplified language mapping.
* Optimize video sorting using `sortedWith` and `compareByDescending`.
* Modernize preferences setup using `keiyoushi.utils` delegates and helper functions (`addListPreference`, `addSetPreference`).
* Rename and clean up preference keys and internal language mapping logic.
@cuong-tran cuong-tran merged commit 5e3834d into master Mar 14, 2026
2 checks passed
@github-actions github-actions bot deleted the de/aniworld branch March 14, 2026 17:45
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Mar 17, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants