feat(de/aniworld): More hosters, faster video loading & fix preferences#71
feat(de/aniworld): More hosters, faster video loading & fix preferences#71cuong-tran merged 16 commits intomasterfrom
Conversation
Reviewer's GuideRefactors 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 selectionsequenceDiagram
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
Updated class diagram for AniWorld source, VidozaExtractor, and DdosGuardInterceptorclassDiagram
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)"
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
Summary of ChangesHello, 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
🧠 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
Using Gemini Code AssistThe 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
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 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
|
There was a problem hiding this comment.
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 onhoster.contains(PREF_HOSTER_NAME, true), which is somewhat brittle; consider mapping the raw hoster label values to constants (e.g., via awhenon 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>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
src/de/aniworld/src/eu/kanade/tachiyomi/animeextension/de/aniworld/AniWorld.kt
Show resolved
Hide resolved
There was a problem hiding this comment.
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.
src/de/aniworld/src/eu/kanade/tachiyomi/animeextension/de/aniworld/AniWorld.kt
Outdated
Show resolved
Hide resolved
src/de/aniworld/src/eu/kanade/tachiyomi/animeextension/de/aniworld/AniWorld.kt
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
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.
src/de/aniworld/src/eu/kanade/tachiyomi/animeextension/de/aniworld/AniWorld.kt
Outdated
Show resolved
Hide resolved
src/de/aniworld/src/eu/kanade/tachiyomi/animeextension/de/aniworld/AniWorld.kt
Outdated
Show resolved
Hide resolved
src/de/aniworld/src/eu/kanade/tachiyomi/animeextension/de/aniworld/AniWorld.kt
Outdated
Show resolved
Hide resolved
src/de/aniworld/src/eu/kanade/tachiyomi/animeextension/de/aniworld/AniWorld.kt
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
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.
src/de/aniworld/src/eu/kanade/tachiyomi/animeextension/de/aniworld/AniWorld.kt
Show resolved
Hide resolved
src/de/aniworld/src/eu/kanade/tachiyomi/animeextension/de/aniworld/AniWorld.kt
Show resolved
Hide resolved
src/de/aniworld/src/eu/kanade/tachiyomi/animeextension/de/aniworld/AniWorld.kt
Show resolved
Hide resolved
...de/aniworld/src/eu/kanade/tachiyomi/animeextension/de/aniworld/extractors/VidozaExtractor.kt
Show resolved
Hide resolved
|
/gemini review |
|
@sourcery-ai review |
There was a problem hiding this comment.
Hey - I've found 1 issue, and left some high level feedback:
- The new video sort logic relies on
Video.qualitycontaining 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>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
src/de/aniworld/src/eu/kanade/tachiyomi/animeextension/de/aniworld/AniWorld.kt
Show resolved
Hide resolved
There was a problem hiding this comment.
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.
...de/aniworld/src/eu/kanade/tachiyomi/animeextension/de/aniworld/extractors/VidozaExtractor.kt
Show resolved
Hide resolved
src/de/aniworld/src/eu/kanade/tachiyomi/animeextension/de/aniworld/AniWorld.kt
Show resolved
Hide resolved
…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.
Summary by Sourcery
Update the AniWorld extension to use async utilities, broaden supported hosters, and modernize search, episode parsing, and preference handling.
New Features:
Bug Fixes:
Enhancements:
Build: