Skip to content

Add Anime3rb source for anime streaming - #642

Open
3bakri0 wants to merge 1 commit into
yuzono:masterfrom
3bakri0:patch-2
Open

Add Anime3rb source for anime streaming#642
3bakri0 wants to merge 1 commit into
yuzono:masterfrom
3bakri0:patch-2

Conversation

@3bakri0

@3bakri0 3bakri0 commented Jul 13, 2026

Copy link
Copy Markdown

Checklist:

  • Updated extVersionCode value in build.gradle for individual extensions
  • Updated overrideVersionCode or baseVersionCode as needed for all multisrc extensions
  • Referenced all related issues in the PR body (e.g. "Closes #xyz")
  • Added the isNsfw = true flag in build.gradle when appropriate
  • Have not changed source names
  • Have explicitly kept the id if a source's name or language were changed
  • Have tested the modifications by compiling and running the extension through Android Studio
  • Have removed web_hi_res_512.png when adding a new extension
  • This PR is AI-assisted, I have reviewed the changes manually and confirmed they are not slop
  • Have made sure all the icons are in png format

Add a 👍 reaction to pull requests you find important.

Summary by Sourcery

Add a new Arabic Anime3rb streaming source with search, browsing, and playback support.

New Features:

  • Introduce Anime3rb Arabic anime streaming extension with popular, latest, search, and details support.
  • Support episode listing across seasons and extraction of HLS video streams with preferred quality selection.
  • Add user-configurable settings for preferred video quality and custom domain for the Anime3rb source.
  • Provide filtering options for Anime3rb search by section, category, and genre in Arabic.

@sourcery-ai

sourcery-ai Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Reviewer's Guide

Adds a new Arabic Anime3rb streaming source implementing popular/latest/search, episode and video extraction, filtering, and user preferences (quality and custom domain) for the Tachiyomi/Aniyomi anime extension system.

Sequence diagram for Anime3rb video extraction flow

sequenceDiagram
    actor User
    participant Anime3rbSource as Anime3rb
    participant Anime3rbWebsite as Anime3rb_website
    participant PlaylistUtils

    User->>Anime3rbSource: videoListParse(response)
    Anime3rbSource->>Anime3rbWebsite: GET(onclick_url, headers)
    Anime3rbWebsite-->>Anime3rbSource: Document
    Anime3rbSource->>Anime3rbSource: Deobfuscator.deobfuscateScript(script)
    Anime3rbSource->>Anime3rbSource: videoRegex.find(script)
    alt [playlist found]
        Anime3rbSource->>PlaylistUtils: extractFromHls(playlist)
        PlaylistUtils-->>Anime3rbSource: List<Video>
        Anime3rbSource->>Anime3rbSource: List<Video>.sort()
        Anime3rbSource-->>User: sorted List<Video>
    else [no playlist]
        Anime3rbSource-->>User: empty List<Video>
    end
Loading

File-Level Changes

Change Details Files
Implement Anime3rb ParsedAnimeHttpSource with popular, latest, and search listings using shared selectors and pagination.
  • Defines Anime3rb class extending ParsedAnimeHttpSource and ConfigurableAnimeSource with Arabic language and dynamic baseUrl from preferences.
  • Implements popularAnimeRequest/Selector/FromElement/NextPageSelector targeting /titles/list and common card grid markup.
  • Implements latestUpdates* methods mirroring popular anime behavior for recent updates.
  • Implements searchAnime* methods that support both text query search and filtered browsing via section, category, and genre filters, building URLs with HttpUrl builder.
src/ar/anime3rb/src/eu/kanade/tachiyomi/animeextension/ar/Anime3rb/Anime3rb.kt
Add episode list parsing with multi-season support and fallback handling for single-watch pages.
  • Implements episodeListSelector and episodeFromElement to parse episode links, titles, and derive numeric episode_number from Arabic labels.
  • Implements episodeListParse to recursively traverse seasons using a season list selector and onclick-based URL extraction, handling both regular episode lists and shortLink pages lacking standard episode markup.
  • Reverses collected episodes to ensure ascending order before returning.
src/ar/anime3rb/src/eu/kanade/tachiyomi/animeextension/ar/Anime3rb/Anime3rb.kt
Implement video extraction from obfuscated server pages using HLS playlists and quality-based sorting.
  • Implements videoListSelector and videoListParse to follow onclick server links, fetch the intermediate page, deobfuscate scripts, and extract .m3u8 URLs via regex.
  • Uses PlaylistUtils.extractFromHls to expand HLS playlists into a list of Video objects.
  • Overrides List
src/ar/anime3rb/src/eu/kanade/tachiyomi/animeextension/ar/Anime3rb/Anime3rb.kt
Parse anime details for title, thumbnail, description, genres, and status from Anime3rb pages.
  • Implements animeDetailsParse to derive title from h1 or h2.title-name, thumbnail from src or data-src, and description from several possible description containers.
  • Builds genre string from links containing genre/category in href, joined by comma.
  • Extracts and normalizes status text from Arabic/English labels, delegating to parseStatus for mapping to SAnime status constants.
src/ar/anime3rb/src/eu/kanade/tachiyomi/animeextension/ar/Anime3rb/Anime3rb.kt
Add filters, preferences, and configurable base domain/quality settings for Anime3rb.
  • Defines GenreFilter as a SingleFilter with a sorted array of Arabic genre names used in search filtering.
  • Introduces SharedPreferences-backed properties for customDomain and preferred quality via delegated helpers.
  • Implements setupPreferenceScreen to expose a list preference for preferred quality and an edit-text preference for a custom domain with URL validation and localized messages.
  • Overrides headersBuilder to always send Referer based on the (possibly customized) baseUrl.
src/ar/anime3rb/src/eu/kanade/tachiyomi/animeextension/ar/Anime3rb/Anime3rb.kt

Possibly linked issues

  • #Anime3rb: PR implements the Anime3rb Arabic source requested in the issue, adding full support and configuration.
  • #: PR fulfills the issue by implementing the Anime3rb Arabic Anime3rb.com source with full functionality.

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

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Hey - I've found 2 issues, and left some high level feedback:

  • The GenreFilter class currently contains the shared-preference properties and setupPreferenceScreen/companion object, which should instead live on the Anime3rb class implementing ConfigurableAnimeSource; as written this won’t compile and the preferences UI won’t be wired correctly.
  • searchAnimeRequest references SectionFilter, CategoryFilter, SingleFilter, and getFilterList() but only GenreFilter is defined in this file, so you’ll need to either add the missing filter classes and getFilterList() implementation or import them from a shared library to avoid unresolved symbol errors.
  • parseStatus is used in animeDetailsParse but isn’t defined anywhere in this file, so you should either implement it (mapping the Arabic/English status strings to SAnime statuses) or import an existing helper to prevent compilation failures.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The `GenreFilter` class currently contains the shared-preference properties and `setupPreferenceScreen`/companion object, which should instead live on the `Anime3rb` class implementing `ConfigurableAnimeSource`; as written this won’t compile and the preferences UI won’t be wired correctly.
- `searchAnimeRequest` references `SectionFilter`, `CategoryFilter`, `SingleFilter`, and `getFilterList()` but only `GenreFilter` is defined in this file, so you’ll need to either add the missing filter classes and `getFilterList()` implementation or import them from a shared library to avoid unresolved symbol errors.
- `parseStatus` is used in `animeDetailsParse` but isn’t defined anywhere in this file, so you should either implement it (mapping the Arabic/English status strings to `SAnime` statuses) or import an existing helper to prevent compilation failures.

## Individual Comments

### Comment 1
<location path="src/ar/anime3rb/src/eu/kanade/tachiyomi/animeextension/ar/Anime3rb/Anime3rb.kt" line_range="139-140" />
<code_context>
+override fun videoListSelector(): String =
+    "li:contains(سيرفر)"
+
+private val videoRegex by lazy {
+    Regex("""(https?:)?//[^"]+\.m3u8""")
+}
+
</code_context>
<issue_to_address>
**issue (bug_risk):** Matched HLS URLs may be scheme-less (`//...`) and not normalized before being passed to the playlist extractor.

Because the regex can return values like `//host/path.m3u8`, `playlistUtils.extractFromHls` may receive URLs without a scheme and behave unexpectedly. Consider normalizing matches to fully qualified URLs (e.g., defaulting to `https:` or reusing the page’s scheme when the scheme group is empty) before calling `extractFromHls`.
</issue_to_address>

### Comment 2
<location path="src/ar/anime3rb/src/eu/kanade/tachiyomi/animeextension/ar/Anime3rb/Anime3rb.kt" line_range="126-128" />
<code_context>
+
+    episode.name = element.text()
+
+    episode.episode_number =
+        element.text()
+            .replace("الحلقة", "")
+            .trim()
+            .toFloatOrNull() ?: -1f
</code_context>
<issue_to_address>
**suggestion:** Episode number parsing relies on a simple replace, which may fail for non-standard titles.

Stripping the literal "الحلقة" then parsing the remainder as float will break for specials or titles that include extra text (ranges, parts, descriptors), causing `-1f` even when an episode number is present. Consider using a regex to extract the numeric portion (e.g. `\d+(?:\.\d+)?`) and falling back to `-1f` only when no number is found.

Suggested implementation:

```
    val titleText = element.text()
    episode.name = titleText

    episode.episode_number =
        episodeNumberRegex.find(titleText)
            ?.value
            ?.toFloatOrNull() ?: -1f

```

```
private val episodeNumberRegex by lazy {
    Regex("""\d+(?:\.\d+)?""")
}

private val videoRegex by lazy {
    Regex("""(https?:)?//[^"]+\.m3u8""")
}

```
</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.

Comment on lines +139 to +140
private val videoRegex by lazy {
Regex("""(https?:)?//[^"]+\.m3u8""")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

issue (bug_risk): Matched HLS URLs may be scheme-less (//...) and not normalized before being passed to the playlist extractor.

Because the regex can return values like //host/path.m3u8, playlistUtils.extractFromHls may receive URLs without a scheme and behave unexpectedly. Consider normalizing matches to fully qualified URLs (e.g., defaulting to https: or reusing the page’s scheme when the scheme group is empty) before calling extractFromHls.

Comment on lines +126 to +128
episode.episode_number =
element.text()
.replace("الحلقة", "")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

suggestion: Episode number parsing relies on a simple replace, which may fail for non-standard titles.

Stripping the literal "الحلقة" then parsing the remainder as float will break for specials or titles that include extra text (ranges, parts, descriptors), causing -1f even when an episode number is present. Consider using a regex to extract the numeric portion (e.g. \d+(?:\.\d+)?) and falling back to -1f only when no number is found.

Suggested implementation:

    val titleText = element.text()
    episode.name = titleText

    episode.episode_number =
        episodeNumberRegex.find(titleText)
            ?.value
            ?.toFloatOrNull() ?: -1f

private val episodeNumberRegex by lazy {
    Regex("""\d+(?:\.\d+)?""")
}

private val videoRegex by lazy {
    Regex("""(https?:)?//[^"]+\.m3u8""")
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant