From 5a9383dffbc3c347857bafc20cca0d35384f2bd3 Mon Sep 17 00:00:00 2001
From: AlphaBoom <30779939+AlphaBoom@users.noreply.github.com>
Date: Tue, 19 Nov 2024 14:53:56 +0800
Subject: [PATCH] Add Jable (#378)

---
 src/all/jable/build.gradle                    |   8 +
 src/all/jable/res/mipmap-hdpi/ic_launcher.png | Bin 0 -> 2759 bytes
 src/all/jable/res/mipmap-mdpi/ic_launcher.png | Bin 0 -> 1579 bytes
 .../jable/res/mipmap-xhdpi/ic_launcher.png    | Bin 0 -> 3721 bytes
 .../jable/res/mipmap-xxhdpi/ic_launcher.png   | Bin 0 -> 6850 bytes
 .../jable/res/mipmap-xxxhdpi/ic_launcher.png  | Bin 0 -> 9659 bytes
 .../animeextension/all/jable/Jable.kt         | 248 ++++++++++++++++++
 .../animeextension/all/jable/JableFactory.kt  |  14 +
 .../animeextension/all/jable/JableFilters.kt  |  25 ++
 .../animeextension/all/jable/JableIntl.kt     |  76 ++++++
 10 files changed, 371 insertions(+)
 create mode 100644 src/all/jable/build.gradle
 create mode 100644 src/all/jable/res/mipmap-hdpi/ic_launcher.png
 create mode 100644 src/all/jable/res/mipmap-mdpi/ic_launcher.png
 create mode 100644 src/all/jable/res/mipmap-xhdpi/ic_launcher.png
 create mode 100644 src/all/jable/res/mipmap-xxhdpi/ic_launcher.png
 create mode 100644 src/all/jable/res/mipmap-xxxhdpi/ic_launcher.png
 create mode 100644 src/all/jable/src/eu/kanade/tachiyomi/animeextension/all/jable/Jable.kt
 create mode 100644 src/all/jable/src/eu/kanade/tachiyomi/animeextension/all/jable/JableFactory.kt
 create mode 100644 src/all/jable/src/eu/kanade/tachiyomi/animeextension/all/jable/JableFilters.kt
 create mode 100644 src/all/jable/src/eu/kanade/tachiyomi/animeextension/all/jable/JableIntl.kt

diff --git a/src/all/jable/build.gradle b/src/all/jable/build.gradle
new file mode 100644
index 00000000..f9304496
--- /dev/null
+++ b/src/all/jable/build.gradle
@@ -0,0 +1,8 @@
+ext {
+    extName = 'Jable'
+    extClass = '.JableFactory'
+    extVersionCode = 1
+    isNsfw = true
+}
+
+apply from: "$rootDir/common.gradle"
diff --git a/src/all/jable/res/mipmap-hdpi/ic_launcher.png b/src/all/jable/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000000000000000000000000000000000000..dc1e73268bbff8af920f08b6151fb3dfb13a9b68
GIT binary patch
literal 2759
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
N002ovPDHLkV1j(^4VM4_

literal 0
HcmV?d00001

diff --git a/src/all/jable/res/mipmap-mdpi/ic_launcher.png b/src/all/jable/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000000000000000000000000000000000000..6d68c4e1dca351ab198cfab9fd62e96f2d77c18b
GIT binary patch
literal 1579
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

literal 0
HcmV?d00001

diff --git a/src/all/jable/res/mipmap-xhdpi/ic_launcher.png b/src/all/jable/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000000000000000000000000000000000000..f46a55392dd6234fbffc086a7c79d3cf71619bfb
GIT binary patch
literal 3721
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

literal 0
HcmV?d00001

diff --git a/src/all/jable/res/mipmap-xxhdpi/ic_launcher.png b/src/all/jable/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000000000000000000000000000000000000..78f0ad3b51bc0227abf16220d24725080042214a
GIT binary patch
literal 6850
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
Wv2=T6%3L<308Mp0wQ?29*Z%|9Rvte9

literal 0
HcmV?d00001

diff --git a/src/all/jable/res/mipmap-xxxhdpi/ic_launcher.png b/src/all/jable/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 0000000000000000000000000000000000000000..5b55e575c9419182004f7d610704663eab258a9d
GIT binary patch
literal 9659
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

literal 0
HcmV?d00001

diff --git a/src/all/jable/src/eu/kanade/tachiyomi/animeextension/all/jable/Jable.kt b/src/all/jable/src/eu/kanade/tachiyomi/animeextension/all/jable/Jable.kt
new file mode 100644
index 00000000..d8b3bc20
--- /dev/null
+++ b/src/all/jable/src/eu/kanade/tachiyomi/animeextension/all/jable/Jable.kt
@@ -0,0 +1,248 @@
+package eu.kanade.tachiyomi.animeextension.all.jable
+
+import android.app.Application
+import android.content.SharedPreferences
+import eu.kanade.tachiyomi.animesource.model.AnimeFilterList
+import eu.kanade.tachiyomi.animesource.model.AnimeUpdateStrategy
+import eu.kanade.tachiyomi.animesource.model.AnimesPage
+import eu.kanade.tachiyomi.animesource.model.SAnime
+import eu.kanade.tachiyomi.animesource.model.SEpisode
+import eu.kanade.tachiyomi.animesource.model.Video
+import eu.kanade.tachiyomi.animesource.online.AnimeHttpSource
+import eu.kanade.tachiyomi.network.GET
+import eu.kanade.tachiyomi.util.asJsoup
+import kotlinx.serialization.encodeToString
+import kotlinx.serialization.json.Json
+import okhttp3.HttpUrl.Companion.toHttpUrl
+import okhttp3.Request
+import okhttp3.Response
+import uy.kohesive.injekt.Injekt
+import uy.kohesive.injekt.api.get
+import uy.kohesive.injekt.injectLazy
+
+class Jable(override val lang: String) : AnimeHttpSource() {
+    override val baseUrl: String
+        get() = "https://jable.tv"
+    override val name: String
+        get() = "Jable"
+    override val supportsLatest: Boolean
+        get() = true
+
+    private val preferences by lazy {
+        Injekt.get<Application>().getSharedPreferences("source_$id", 0x0000)
+    }
+    private val json by injectLazy<Json>()
+    private var tagsUpdated = false
+
+    override fun animeDetailsRequest(anime: SAnime): Request {
+        return GET("$baseUrl${anime.url}?lang=$lang", headers)
+    }
+
+    override fun animeDetailsParse(response: Response): SAnime {
+        val doc = response.asJsoup()
+        return SAnime.create().apply {
+            val info = doc.select(".info-header")
+            title = info.select(".header-left h4").text()
+            author = info.select(".header-left .model")
+                .joinToString { it.select("span[title]").attr("title") }
+            genre = doc.select(".tags a").joinToString { it.text() }
+            update_strategy = AnimeUpdateStrategy.ONLY_FETCH_ONCE
+            status = SAnime.COMPLETED
+            description = info.select(".header-right").text()
+        }
+    }
+
+    override fun episodeListParse(response: Response) = throw UnsupportedOperationException()
+
+    override suspend fun getEpisodeList(anime: SAnime): List<SEpisode> {
+        return listOf(
+            SEpisode.create().apply {
+                name = "Episode"
+                url = anime.url
+            },
+        )
+    }
+
+    override fun videoListParse(response: Response): List<Video> {
+        val doc = response.asJsoup()
+        val videoUrl = doc.selectFirst("script:containsData(var hlsUrl)")!!.data()
+            .substringAfter("var hlsUrl = '").substringBefore("'")
+        return listOf(Video(videoUrl, "Default", videoUrl))
+    }
+
+    override fun latestUpdatesParse(response: Response): AnimesPage {
+        val doc = response.asJsoup()
+        if (!tagsUpdated) {
+            tagsUpdated = preferences.saveTags(
+                doc.select("a.tag").associate {
+                    it.ownText() to it.attr("href").substringAfter(baseUrl).removePrefix("/")
+                        .removeSuffix("/")
+                },
+            )
+        }
+        return AnimesPage(
+            doc.select(".container .video-img-box").map {
+                SAnime.create().apply {
+                    setUrlWithoutDomain(it.select(".img-box a").attr("href"))
+                    thumbnail_url = it.select(".img-box img").attr("data-src")
+                    title = it.select(".detail .title").text()
+                }
+            },
+            doc.select(".container .pagination .page-item .page-link.disabled").isNullOrEmpty(),
+        )
+    }
+
+    override fun latestUpdatesRequest(page: Int) =
+        searchRequest("latest-updates", page, latestFilter)
+
+    override fun popularAnimeParse(response: Response): AnimesPage = latestUpdatesParse(response)
+
+    override fun popularAnimeRequest(page: Int) =
+        searchRequest("hot", page, popularFilter)
+
+    override fun searchAnimeParse(response: Response) = latestUpdatesParse(response)
+
+    override fun searchAnimeRequest(page: Int, query: String, filters: AnimeFilterList): Request {
+        return if (query.isNotEmpty()) {
+            searchRequest(
+                "search/$query",
+                page,
+                AnimeFilterList(filters.list + defaultSearchFunctionFilter),
+                query = query,
+            )
+        } else {
+            val path = filters.list.filterIsInstance<TagFilter>()
+                .firstOrNull()?.selected?.second?.takeUnless { it.isEmpty() } ?: "hot"
+            searchRequest(path, page, AnimeFilterList(filters.list + commonVideoListFuncFilter))
+        }
+    }
+
+    private fun searchRequest(
+        path: String,
+        page: Int,
+        filters: AnimeFilterList = AnimeFilterList(),
+        query: String = "",
+    ): Request {
+        val urlBuilder = baseUrl.toHttpUrl().newBuilder()
+            .addPathSegments("$path/")
+            .addQueryParameter("lang", lang)
+        if (tagsUpdated) {
+            // load whole page for update filter tags info
+            urlBuilder.addQueryParameter("mode", "async")
+        }
+        filters.list.forEach {
+            when (it) {
+                is BlockFunctionFilter -> {
+                    urlBuilder.addQueryParameter("function", it.selected.functionName)
+                        .addQueryParameter("block_id", it.selected.blockId)
+                }
+
+                is SortFilter -> {
+                    if (it.selected.second.isNotEmpty()) {
+                        urlBuilder.addQueryParameter("sort_by", it.selected.second)
+                    }
+                }
+
+                else -> {}
+            }
+        }
+        if (query.isNotEmpty()) {
+            urlBuilder.addQueryParameter("q", query)
+        }
+        urlBuilder.addQueryParameter("from", "%02d".format(page))
+            .addQueryParameter("_", System.currentTimeMillis().toString())
+        return GET(urlBuilder.build())
+    }
+
+    override fun getFilterList(): AnimeFilterList {
+        return AnimeFilterList(
+            SortFilter(
+                intl.filterPopularSortTitle,
+                arrayOf(
+                    "" to "",
+                    intl.hotMonth to "video_viewed_month",
+                    intl.hotWeek to "video_viewed_week",
+                    intl.hotDay to "video_viewed_today",
+                    intl.hotAll to "video_viewed",
+                ),
+            ),
+            TagFilter(
+                intl.filterTagTitle,
+                buildList {
+                    add("" to "")
+                    preferences.getTags()?.forEach {
+                        add(it.key to it.value)
+                    }
+                }.toTypedArray(),
+            ),
+            SortFilter(
+                intl.filterTagsSortTitle,
+                arrayOf(
+                    "" to "",
+                    intl.sortLatestUpdate to "post_date",
+                    intl.sortMostView to "video_viewed",
+                    intl.sortMostFavorite to "most_favourited",
+                    intl.sortRecentBest to "post_date_and_popularity",
+                ),
+            ),
+        )
+    }
+
+    private fun SharedPreferences.getTags(): Map<String, String>? {
+        val savedStr = getString("${lang}_$PREF_KEY_TAGS", null)
+        if (savedStr.isNullOrEmpty()) {
+            return null
+        }
+        return json.decodeFromString<Map<String, String>>(savedStr)
+    }
+
+    private fun SharedPreferences.saveTags(tags: Map<String, String>): Boolean {
+        if (tags.isNotEmpty()) {
+            edit().putString("${lang}_$PREF_KEY_TAGS", json.encodeToString(tags)).apply()
+            return true
+        }
+        return false
+    }
+
+    private val intl by lazy {
+        JableIntl(lang)
+    }
+
+    private val commonVideoListFuncFilter by lazy {
+        BlockFunctionFilter(
+            intl.popular,
+            arrayOf(BlockFunction(intl.popular, "list_videos_common_videos_list")),
+        )
+    }
+
+    private val defaultSearchFunctionFilter by lazy {
+        BlockFunctionFilter("", arrayOf(BlockFunction("", "list_videos_videos_list_search_result")))
+    }
+
+    private val popularFilter by lazy {
+        AnimeFilterList(
+            commonVideoListFuncFilter,
+            SortFilter(
+                intl.hotWeek,
+                arrayOf(intl.hotWeek to "video_viewed_week"),
+            ),
+        )
+    }
+
+    private val latestFilter by lazy {
+        AnimeFilterList(
+            BlockFunctionFilter(
+                intl.latestUpdate,
+                arrayOf(BlockFunction(intl.latestUpdate, "list_videos_latest_videos_list")),
+            ),
+            SortFilter(
+                intl.sortLatestUpdate,
+                arrayOf(intl.sortLatestUpdate to "post_date"),
+            ),
+        )
+    }
+
+    companion object {
+        const val PREF_KEY_TAGS = "pref_key_tags"
+    }
+}
diff --git a/src/all/jable/src/eu/kanade/tachiyomi/animeextension/all/jable/JableFactory.kt b/src/all/jable/src/eu/kanade/tachiyomi/animeextension/all/jable/JableFactory.kt
new file mode 100644
index 00000000..6faa9a12
--- /dev/null
+++ b/src/all/jable/src/eu/kanade/tachiyomi/animeextension/all/jable/JableFactory.kt
@@ -0,0 +1,14 @@
+package eu.kanade.tachiyomi.animeextension.all.jable
+
+import eu.kanade.tachiyomi.animesource.AnimeSource
+import eu.kanade.tachiyomi.animesource.AnimeSourceFactory
+
+class JableFactory : AnimeSourceFactory {
+    override fun createSources(): List<AnimeSource> {
+        return listOf(
+            Jable("zh"),
+            Jable("en"),
+            Jable("jp"),
+        )
+    }
+}
diff --git a/src/all/jable/src/eu/kanade/tachiyomi/animeextension/all/jable/JableFilters.kt b/src/all/jable/src/eu/kanade/tachiyomi/animeextension/all/jable/JableFilters.kt
new file mode 100644
index 00000000..133731b0
--- /dev/null
+++ b/src/all/jable/src/eu/kanade/tachiyomi/animeextension/all/jable/JableFilters.kt
@@ -0,0 +1,25 @@
+package eu.kanade.tachiyomi.animeextension.all.jable
+
+import eu.kanade.tachiyomi.animesource.model.AnimeFilter
+
+data class BlockFunction(
+    val name: String,
+    val blockId: String,
+    val functionName: String = "get_block",
+)
+
+class BlockFunctionFilter(name: String, private val functions: Array<BlockFunction>) :
+    AnimeFilter.Select<String>(name, functions.map { it.name }.toTypedArray()) {
+    val selected
+        get() = functions[state]
+}
+
+open class UriPartFilter(name: String, private val pairs: Array<Pair<String, String>>) :
+    AnimeFilter.Select<String>(name, pairs.map { it.first }.toTypedArray()) {
+    val selected
+        get() = pairs[state]
+}
+
+class SortFilter(name: String, pairs: Array<Pair<String, String>>) : UriPartFilter(name, pairs)
+
+class TagFilter(name: String, pairs: Array<Pair<String, String>>) : UriPartFilter(name, pairs)
diff --git a/src/all/jable/src/eu/kanade/tachiyomi/animeextension/all/jable/JableIntl.kt b/src/all/jable/src/eu/kanade/tachiyomi/animeextension/all/jable/JableIntl.kt
new file mode 100644
index 00000000..9fe6f869
--- /dev/null
+++ b/src/all/jable/src/eu/kanade/tachiyomi/animeextension/all/jable/JableIntl.kt
@@ -0,0 +1,76 @@
+package eu.kanade.tachiyomi.animeextension.all.jable
+
+internal interface Intl {
+    val popular: String
+    val latestUpdate: String
+    val sortLatestUpdate: String
+    val sortMostView: String
+    val sortMostFavorite: String
+    val sortRecentBest: String
+    val hotDay: String
+    val hotWeek: String
+    val hotMonth: String
+    val hotAll: String
+    val filterPopularSortTitle: String
+    val filterTagsSortTitle: String
+    val filterTagTitle: String
+}
+
+internal class JableIntl private constructor(delegate: Intl) : Intl by delegate {
+    constructor(lang: String) : this(
+        when (lang) {
+            "zh" -> ZH()
+            "jp" -> JP()
+            "en" -> EN()
+            else -> ZH()
+        },
+    )
+}
+
+internal class ZH : Intl {
+    override val popular: String = "熱度優先"
+    override val latestUpdate: String = "新片優先"
+    override val sortLatestUpdate: String = "最近更新"
+    override val sortMostView: String = "最多觀看"
+    override val sortMostFavorite: String = "最高收藏"
+    override val sortRecentBest: String = "近期最佳"
+    override val hotDay: String = "今日熱門"
+    override val hotWeek: String = "本周熱門"
+    override val hotMonth: String = "本月熱門"
+    override val hotAll: String = "所有時間"
+    override val filterPopularSortTitle: String = "熱門排序"
+    override val filterTagsSortTitle: String = "通用排序"
+    override val filterTagTitle: String = "標籤"
+}
+
+internal class JP : Intl {
+    override val popular: String = "人気優先"
+    override val latestUpdate: String = "新作優先"
+    override val sortLatestUpdate: String = "最近更新"
+    override val sortMostView: String = "最も見ら"
+    override val sortMostFavorite: String = "最もお気に入"
+    override val sortRecentBest: String = "最近ベスト"
+    override val hotDay: String = "今日のヒット"
+    override val hotWeek: String = "今週のヒット"
+    override val hotMonth: String = "今月のヒット"
+    override val hotAll: String = "全ての時間"
+    override val filterPopularSortTitle: String = "人気ソート"
+    override val filterTagsSortTitle: String = "一般ソート"
+    override val filterTagTitle: String = "タグ"
+}
+
+internal class EN : Intl {
+    override val popular: String = "Hot"
+    override val latestUpdate: String = "Newest"
+    override val sortLatestUpdate: String = "Recent Update"
+    override val sortMostView: String = "Most Viewed"
+    override val sortMostFavorite: String = "Most Favorite"
+    override val sortRecentBest: String = "Best Recently"
+    override val hotDay: String = "Today"
+    override val hotWeek: String = "This Week"
+    override val hotMonth: String = "This Month"
+    override val hotAll: String = "All Time"
+    override val filterPopularSortTitle: String = "Popular Sorting"
+    override val filterTagsSortTitle: String = "General Sorting"
+    override val filterTagTitle: String = "Tag"
+}