From 0658c1926c6dbc51280b3b603405ffd10312b07c Mon Sep 17 00:00:00 2001
From: AwkwardPeak7 <48650614+AwkwardPeak7@users.noreply.github.com>
Date: Sun, 2 Feb 2025 14:24:40 +0500
Subject: [PATCH] revert kotlin 2.1.0 and deps for now (#7468)
generated serializers seem to be missing in final apk, need further investigation
---
buildSrc/build.gradle.kts | 2 +-
.../src/main/kotlin/keiyoushi.lint.gradle.kts | 50 -----
.../src/main/kotlin/lib-android.gradle.kts | 11 --
.../src/main/kotlin/lib-multisrc.gradle.kts | 28 ++-
common.gradle | 47 +++--
gradle/libs.versions.toml | 15 +-
lib-multisrc/heancms/build.gradle.kts | 2 +-
lib-multisrc/kemono/build.gradle.kts | 2 +-
.../tachiyomi/multisrc/madara/Madara.kt | 174 ++++++++++--------
lib-multisrc/mangadventure/build.gradle.kts | 2 +-
src/all/comickfun/build.gradle | 2 +-
src/all/mangadex/build.gradle | 2 +-
.../extension/en/coffeemanga/CoffeeManga.kt | 14 +-
.../extension/en/luascans/LuaScans.kt | 11 +-
src/en/mangamo/build.gradle | 2 +-
.../extension/en/mangamo/MangamoAuth.kt | 7 +-
.../tachiyomi/extension/en/retsu/Retsu.kt | 11 +-
.../extension/id/mangkomik/SirenKomik.kt | 13 +-
.../extension/pt/sussyscan/SussyToons.kt | 76 ++++----
.../extension/pt/sussyscan/SussyToonsDto.kt | 12 +-
.../tachiyomi/extension/pt/taiyo/Taiyo.kt | 76 +++++---
.../extension/tr/hattorimanga/HattoriManga.kt | 57 +++---
.../extension/vi/lxhentai/LxHentai.kt | 83 +++++----
.../vi/truyentranh3q/TruyenTranh3Q.kt | 84 +++++----
.../extension/vi/yurineko/YuriNeko.kt | 46 ++---
25 files changed, 443 insertions(+), 386 deletions(-)
delete mode 100644 buildSrc/src/main/kotlin/keiyoushi.lint.gradle.kts
diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts
index 6a112583f..deebe960b 100644
--- a/buildSrc/build.gradle.kts
+++ b/buildSrc/build.gradle.kts
@@ -12,5 +12,5 @@ dependencies {
implementation(libs.gradle.agp)
implementation(libs.gradle.kotlin)
implementation(libs.gradle.serialization)
- implementation(libs.spotless.gradle)
+ implementation(libs.gradle.kotlinter)
}
diff --git a/buildSrc/src/main/kotlin/keiyoushi.lint.gradle.kts b/buildSrc/src/main/kotlin/keiyoushi.lint.gradle.kts
deleted file mode 100644
index 65b486e49..000000000
--- a/buildSrc/src/main/kotlin/keiyoushi.lint.gradle.kts
+++ /dev/null
@@ -1,50 +0,0 @@
-plugins {
- id("com.diffplug.spotless")
-}
-
-spotless {
- ratchetFrom = "105f615b339e681a630f21dc0d363b8ca1cb17d5"
-
- kotlin {
- target("**/*.kt", "**/*.kts")
- targetExclude("**/build/**/*.kt")
- ktlint()
- .editorConfigOverride(mapOf(
- "ktlint_standard_discouraged-comment-location" to "disabled",
- "ktlint_function_signature_body_expression_wrapping" to "default",
- "ktlint_standard_no-empty-first-line-in-class-body" to "disable",
- "ktlint_standard_chain-method-continuation" to "disable"
- ))
- trimTrailingWhitespace()
- endWithNewline()
- }
-
- format("gradle") {
- target("**/*.gradle")
- trimTrailingWhitespace()
- endWithNewline()
- }
-
- format("xml") {
- target("**/*.xml")
- targetExclude("**/build/**/*.xml")
- trimTrailingWhitespace()
- endWithNewline()
- }
-}
-
-tasks {
- named("preBuild") {
- dependsOn(
- tasks.getByName("spotlessCheck")
- )
- }
-
- if (System.getenv("CI") != "true") {
- named("spotlessCheck") {
- dependsOn(
- tasks.getByName("spotlessApply")
- )
- }
- }
-}
diff --git a/buildSrc/src/main/kotlin/lib-android.gradle.kts b/buildSrc/src/main/kotlin/lib-android.gradle.kts
index 0e1c83130..ee9eb1c22 100644
--- a/buildSrc/src/main/kotlin/lib-android.gradle.kts
+++ b/buildSrc/src/main/kotlin/lib-android.gradle.kts
@@ -2,7 +2,6 @@ plugins {
id("com.android.library")
kotlin("android")
id("kotlinx-serialization")
- id("keiyoushi.lint")
}
android {
@@ -17,16 +16,6 @@ android {
buildFeatures {
androidResources = false
}
-
- compileOptions {
- sourceCompatibility = JavaVersion.VERSION_17
- targetCompatibility = JavaVersion.VERSION_17
- }
-
- kotlinOptions {
- jvmTarget = JavaVersion.VERSION_17.toString()
- freeCompilerArgs += "-opt-in=kotlinx.serialization.ExperimentalSerializationApi"
- }
}
dependencies {
diff --git a/buildSrc/src/main/kotlin/lib-multisrc.gradle.kts b/buildSrc/src/main/kotlin/lib-multisrc.gradle.kts
index 3ed2f14b2..402ebebf6 100644
--- a/buildSrc/src/main/kotlin/lib-multisrc.gradle.kts
+++ b/buildSrc/src/main/kotlin/lib-multisrc.gradle.kts
@@ -2,7 +2,7 @@ plugins {
id("com.android.library")
kotlin("android")
id("kotlinx-serialization")
- id("keiyoushi.lint")
+ id("org.jmailen.kotlinter")
}
android {
@@ -23,21 +23,35 @@ android {
}
}
- compileOptions {
- sourceCompatibility = JavaVersion.VERSION_17
- targetCompatibility = JavaVersion.VERSION_17
- }
-
kotlinOptions {
- jvmTarget = JavaVersion.VERSION_17.toString()
freeCompilerArgs += "-opt-in=kotlinx.serialization.ExperimentalSerializationApi"
}
}
+kotlinter {
+ experimentalRules = true
+ disabledRules = arrayOf(
+ "experimental:argument-list-wrapping", // Doesn't play well with Android Studio
+ "experimental:comment-wrapping",
+ )
+}
+
dependencies {
compileOnly(versionCatalogs.named("libs").findBundle("common").get())
}
+tasks {
+ preBuild {
+ dependsOn(lintKotlin)
+ }
+
+ if (System.getenv("CI") != "true") {
+ lintKotlin {
+ dependsOn(formatKotlin)
+ }
+ }
+}
+
tasks.register("printDependentExtensions") {
doLast {
project.printDependentExtensions()
diff --git a/common.gradle b/common.gradle
index 787dcf07b..f916f509a 100644
--- a/common.gradle
+++ b/common.gradle
@@ -1,7 +1,7 @@
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlinx-serialization'
-apply plugin: 'keiyoushi.lint'
+apply plugin: 'org.jmailen.kotlinter'
assert !ext.has("pkgNameSuffix")
assert !ext.has("libVersion")
@@ -18,17 +18,6 @@ android {
sourceSets {
main {
manifest.srcFile "AndroidManifest.xml"
- if (!manifest.srcFile.exists()) {
- def buildDir = layout.buildDirectory.get().getAsFile().path
- mkdir(buildDir)
- File tempFile = new File(buildDir, "tempAndroidManifest.xml")
- if (!tempFile.exists()) {
- tempFile.withWriter {
- it.write('\n\n')
- }
- }
- manifest.srcFile(tempFile.path)
- }
java.srcDirs = ['src']
res.srcDirs = ['res']
assets.srcDirs = ['assets']
@@ -92,14 +81,22 @@ android {
}
compileOptions {
- sourceCompatibility = JavaVersion.VERSION_17
- targetCompatibility = JavaVersion.VERSION_17
+ sourceCompatibility = JavaVersion.VERSION_1_8
+ targetCompatibility = JavaVersion.VERSION_1_8
}
kotlinOptions {
- jvmTarget = JavaVersion.VERSION_17.toString()
+ jvmTarget = JavaVersion.VERSION_1_8.toString()
freeCompilerArgs += "-opt-in=kotlinx.serialization.ExperimentalSerializationApi"
}
+
+ kotlinter {
+ experimentalRules = true
+ disabledRules = [
+ "experimental:argument-list-wrapping", // Doesn't play well with Android Studio
+ "experimental:comment-wrapping",
+ ]
+ }
}
dependencies {
@@ -107,3 +104,23 @@ dependencies {
implementation(project(":core"))
compileOnly(libs.bundles.common)
}
+
+tasks.register("writeManifestFile") {
+ doLast {
+ def manifest = android.sourceSets.getByName("main").manifest
+ if (!manifest.srcFile.exists()) {
+ File tempFile = layout.buildDirectory.get().file("tempAndroidManifest.xml").getAsFile()
+ if (!tempFile.exists()) {
+ tempFile.withWriter {
+ it.write('\n\n')
+ }
+ }
+ manifest.srcFile(tempFile.path)
+ }
+ }
+}
+
+preBuild.dependsOn(writeManifestFile, lintKotlin)
+if (System.getenv("CI") != "true") {
+ lintKotlin.dependsOn(formatKotlin)
+}
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index aeea7d93c..e5127d7fd 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -1,14 +1,13 @@
[versions]
-kotlin_version = "2.1.0"
-coroutines_version = "1.10.1"
-serialization_version = "1.8.0"
+kotlin_version = "1.7.21"
+coroutines_version = "1.6.4"
+serialization_version = "1.4.0"
[libraries]
-gradle-agp = { module = "com.android.tools.build:gradle", version = "8.8.0" }
+gradle-agp = { module = "com.android.tools.build:gradle", version = "8.6.1" }
gradle-kotlin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin_version" }
gradle-serialization = { module = "org.jetbrains.kotlin:kotlin-serialization", version.ref = "kotlin_version" }
-
-spotless-gradle = { group = "com.diffplug.spotless", name = "spotless-plugin-gradle", version = "7.0.2" }
+gradle-kotlinter = { module = "org.jmailen.gradle:kotlinter-gradle", version = "3.13.0" }
tachiyomi-lib = { module = "com.github.tachiyomiorg:extensions-lib", version = "1.4.2" }
@@ -21,8 +20,8 @@ coroutines-android = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-androi
injekt-core = { module = "com.github.null2264.injekt:injekt-core", version = "4135455a2a" }
rxjava = { module = "io.reactivex:rxjava", version = "1.3.8" }
-jsoup = { module = "org.jsoup:jsoup", version = "1.18.3" }
-okhttp = { module = "com.squareup.okhttp3:okhttp", version = "5.0.0-alpha.14" }
+jsoup = { module = "org.jsoup:jsoup", version = "1.15.1" }
+okhttp = { module = "com.squareup.okhttp3:okhttp", version = "5.0.0-alpha.11" }
quickjs = { module = "app.cash.quickjs:quickjs-android", version = "0.9.2" }
[bundles]
diff --git a/lib-multisrc/heancms/build.gradle.kts b/lib-multisrc/heancms/build.gradle.kts
index 7aabb2b3d..ac3762176 100644
--- a/lib-multisrc/heancms/build.gradle.kts
+++ b/lib-multisrc/heancms/build.gradle.kts
@@ -2,7 +2,7 @@ plugins {
id("lib-multisrc")
}
-baseVersionCode = 27
+baseVersionCode = 28
dependencies {
api(project(":lib:i18n"))
diff --git a/lib-multisrc/kemono/build.gradle.kts b/lib-multisrc/kemono/build.gradle.kts
index e43682c17..92c1c905d 100644
--- a/lib-multisrc/kemono/build.gradle.kts
+++ b/lib-multisrc/kemono/build.gradle.kts
@@ -2,4 +2,4 @@ plugins {
id("lib-multisrc")
}
-baseVersionCode = 17
+baseVersionCode = 18
diff --git a/lib-multisrc/madara/src/eu/kanade/tachiyomi/multisrc/madara/Madara.kt b/lib-multisrc/madara/src/eu/kanade/tachiyomi/multisrc/madara/Madara.kt
index 8c191c145..e85938e35 100644
--- a/lib-multisrc/madara/src/eu/kanade/tachiyomi/multisrc/madara/Madara.kt
+++ b/lib-multisrc/madara/src/eu/kanade/tachiyomi/multisrc/madara/Madara.kt
@@ -109,9 +109,7 @@ abstract class Madara(
protected open val useLoadMoreRequest = LoadMoreStrategy.AutoDetect
enum class LoadMoreStrategy {
- AutoDetect,
- Always,
- Never,
+ AutoDetect, Always, Never
}
/**
@@ -120,9 +118,7 @@ abstract class Madara(
private var loadMoreRequestDetected = LoadMoreDetection.Pending
private enum class LoadMoreDetection {
- Pending,
- True,
- False,
+ Pending, True, False
}
protected fun detectLoadMore(document: Document) {
@@ -136,10 +132,12 @@ abstract class Madara(
}
}
- protected fun useLoadMoreRequest(): Boolean = when (useLoadMoreRequest) {
- LoadMoreStrategy.Always -> true
- LoadMoreStrategy.Never -> false
- else -> loadMoreRequestDetected == LoadMoreDetection.True
+ protected fun useLoadMoreRequest(): Boolean {
+ return when (useLoadMoreRequest) {
+ LoadMoreStrategy.Always -> true
+ LoadMoreStrategy.Never -> false
+ else -> loadMoreRequestDetected == LoadMoreDetection.True
+ }
}
// Popular Manga
@@ -178,17 +176,19 @@ abstract class Madara(
return manga
}
- override fun popularMangaRequest(page: Int): Request = if (useLoadMoreRequest()) {
- loadMoreRequest(page, popular = true)
- } else {
- GET("$baseUrl/$mangaSubString/${searchPage(page)}?m_orderby=views", headers)
- }
+ override fun popularMangaRequest(page: Int): Request =
+ if (useLoadMoreRequest()) {
+ loadMoreRequest(page, popular = true)
+ } else {
+ GET("$baseUrl/$mangaSubString/${searchPage(page)}?m_orderby=views", headers)
+ }
- override fun popularMangaNextPageSelector(): String? = if (useLoadMoreRequest()) {
- "body:not(:has(.no-posts))"
- } else {
- "div.nav-previous, nav.navigation-ajax, a.nextpostslink"
- }
+ override fun popularMangaNextPageSelector(): String? =
+ if (useLoadMoreRequest()) {
+ "body:not(:has(.no-posts))"
+ } else {
+ "div.nav-previous, nav.navigation-ajax, a.nextpostslink"
+ }
// Latest Updates
@@ -199,11 +199,12 @@ abstract class Madara(
return popularMangaFromElement(element)
}
- override fun latestUpdatesRequest(page: Int): Request = if (useLoadMoreRequest()) {
- loadMoreRequest(page, popular = false)
- } else {
- GET("$baseUrl/$mangaSubString/${searchPage(page)}?m_orderby=latest", headers)
- }
+ override fun latestUpdatesRequest(page: Int): Request =
+ if (useLoadMoreRequest()) {
+ loadMoreRequest(page, popular = false)
+ } else {
+ GET("$baseUrl/$mangaSubString/${searchPage(page)}?m_orderby=latest", headers)
+ }
override fun latestUpdatesNextPageSelector(): String? = popularMangaNextPageSelector()
@@ -250,16 +251,20 @@ abstract class Madara(
return super.fetchSearchManga(page, query, filters)
}
- protected open fun searchPage(page: Int): String = if (page == 1) {
- ""
- } else {
- "page/$page/"
+ protected open fun searchPage(page: Int): String {
+ return if (page == 1) {
+ ""
+ } else {
+ "page/$page/"
+ }
}
- override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request = if (useLoadMoreRequest()) {
- searchLoadMoreRequest(page, query, filters)
- } else {
- searchRequest(page, query, filters)
+ override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
+ return if (useLoadMoreRequest()) {
+ searchLoadMoreRequest(page, query, filters)
+ } else {
+ searchRequest(page, query, filters)
+ }
}
protected open fun searchRequest(page: Int, query: String, filters: FilterList): Request {
@@ -305,9 +310,7 @@ abstract class Madara(
filter.state
.filter { it.state }
.let { list ->
- if (list.isNotEmpty()) {
- list.forEach { genre -> url.addQueryParameter("genre[]", genre.id) }
- }
+ if (list.isNotEmpty()) { list.forEach { genre -> url.addQueryParameter("genre[]", genre.id) } }
}
}
else -> {}
@@ -486,7 +489,8 @@ abstract class Madara(
intl["adult_content_filter_only"] to "1",
)
- open class UriPartFilter(displayName: String, private val vals: Array>, state: Int = 0) : Filter.Select(displayName, vals.map { it.first }.toTypedArray(), state) {
+ open class UriPartFilter(displayName: String, private val vals: Array>, state: Int = 0) :
+ Filter.Select(displayName, vals.map { it.first }.toTypedArray(), state) {
fun toUriPart() = vals[state].second
}
@@ -495,21 +499,21 @@ abstract class Madara(
protected class AuthorFilter(title: String) : Filter.Text(title)
protected class ArtistFilter(title: String) : Filter.Text(title)
protected class YearFilter(title: String) : Filter.Text(title)
- protected class StatusFilter(title: String, status: List) : Filter.Group(title, status)
+ protected class StatusFilter(title: String, status: List) :
+ Filter.Group(title, status)
- protected class OrderByFilter(title: String, options: List>, state: Int = 0) : UriPartFilter(title, options.toTypedArray(), state)
+ protected class OrderByFilter(title: String, options: List>, state: Int = 0) :
+ UriPartFilter(title, options.toTypedArray(), state)
- protected class GenreConditionFilter(title: String, options: List>) :
- UriPartFilter(
- title,
- options.toTypedArray(),
- )
+ protected class GenreConditionFilter(title: String, options: List>) : UriPartFilter(
+ title,
+ options.toTypedArray(),
+ )
- protected class AdultContentFilter(title: String, options: List>) :
- UriPartFilter(
- title,
- options.toTypedArray(),
- )
+ protected class AdultContentFilter(title: String, options: List>) : UriPartFilter(
+ title,
+ options.toTypedArray(),
+ )
protected class GenreList(title: String, genres: List) : Filter.Group(title, genres.map { GenreCheckBox(it.name, it.id) })
class GenreCheckBox(name: String, val id: String = name) : Filter.CheckBox(name)
@@ -753,24 +757,32 @@ abstract class Madara(
open val altName = intl["alt_names_heading"]
open val updatingRegex = "Updating|Atualizando".toRegex(RegexOption.IGNORE_CASE)
- fun String.notUpdating(): Boolean = this.contains(updatingRegex).not()
+ fun String.notUpdating(): Boolean {
+ return this.contains(updatingRegex).not()
+ }
- private fun String.containsIn(array: Array): Boolean = this.lowercase() in array.map { it.lowercase() }
+ private fun String.containsIn(array: Array): Boolean {
+ return this.lowercase() in array.map { it.lowercase() }
+ }
- protected open fun imageFromElement(element: Element): String? = when {
- element.hasAttr("data-src") -> element.attr("abs:data-src")
- element.hasAttr("data-lazy-src") -> element.attr("abs:data-lazy-src")
- element.hasAttr("srcset") -> element.attr("abs:srcset").getSrcSetImage()
- element.hasAttr("data-cfsrc") -> element.attr("abs:data-cfsrc")
- else -> element.attr("abs:src")
+ protected open fun imageFromElement(element: Element): String? {
+ return when {
+ element.hasAttr("data-src") -> element.attr("abs:data-src")
+ element.hasAttr("data-lazy-src") -> element.attr("abs:data-lazy-src")
+ element.hasAttr("srcset") -> element.attr("abs:srcset").getSrcSetImage()
+ element.hasAttr("data-cfsrc") -> element.attr("abs:data-cfsrc")
+ else -> element.attr("abs:src")
+ }
}
/**
* Get the best image quality available from srcset
*/
- protected fun String.getSrcSetImage(): String? = this.split(" ")
- .filter(URL_REGEX::matches)
- .maxOfOrNull(String::toString)
+ protected fun String.getSrcSetImage(): String? {
+ return this.split(" ")
+ .filter(URL_REGEX::matches)
+ .maxOfOrNull(String::toString)
+ }
/**
* Set it to true if the source uses the new AJAX endpoint to
@@ -795,7 +807,9 @@ abstract class Madara(
return POST("$baseUrl/wp-admin/admin-ajax.php", xhrHeaders, form)
}
- protected open fun xhrChaptersRequest(mangaUrl: String): Request = POST("$mangaUrl/ajax/chapters", xhrHeaders)
+ protected open fun xhrChaptersRequest(mangaUrl: String): Request {
+ return POST("$mangaUrl/ajax/chapters", xhrHeaders)
+ }
override fun chapterListParse(response: Response): List {
val document = response.asJsoup()
@@ -866,10 +880,12 @@ abstract class Madara(
open fun parseChapterDate(date: String?): Long {
date ?: return 0
- fun SimpleDateFormat.tryParse(string: String): Long = try {
- parse(string)?.time ?: 0
- } catch (_: ParseException) {
- 0
+ fun SimpleDateFormat.tryParse(string: String): Long {
+ return try {
+ parse(string)?.time ?: 0
+ } catch (_: ParseException) {
+ 0
+ }
}
return when {
@@ -990,7 +1006,9 @@ abstract class Madara(
}
}
- override fun imageRequest(page: Page): Request = GET(page.imageUrl!!, headers.newBuilder().set("Referer", page.url).build())
+ override fun imageRequest(page: Page): Request {
+ return GET(page.imageUrl!!, headers.newBuilder().set("Referer", page.url).build())
+ }
override fun imageUrlParse(document: Document) = ""
@@ -1065,22 +1083,26 @@ abstract class Madara(
/**
* The request to the search page (or another one) that have the genres list.
*/
- protected open fun genresRequest(): Request = GET("$baseUrl/?s=genre&post_type=wp-manga", headers)
+ protected open fun genresRequest(): Request {
+ return GET("$baseUrl/?s=genre&post_type=wp-manga", headers)
+ }
/**
* Get the genres from the search page document.
*
* @param document The search page document
*/
- protected open fun parseGenres(document: Document): List = document.selectFirst("div.checkbox-group")
- ?.select("div.checkbox")
- .orEmpty()
- .map { li ->
- Genre(
- li.selectFirst("label")!!.text(),
- li.selectFirst("input[type=checkbox]")!!.`val`(),
- )
- }
+ protected open fun parseGenres(document: Document): List {
+ return document.selectFirst("div.checkbox-group")
+ ?.select("div.checkbox")
+ .orEmpty()
+ .map { li ->
+ Genre(
+ li.selectFirst("label")!!.text(),
+ li.selectFirst("input[type=checkbox]")!!.`val`(),
+ )
+ }
+ }
// https://stackoverflow.com/a/66614516
protected fun String.decodeHex(): ByteArray {
diff --git a/lib-multisrc/mangadventure/build.gradle.kts b/lib-multisrc/mangadventure/build.gradle.kts
index f5a077b4b..bbea4c992 100644
--- a/lib-multisrc/mangadventure/build.gradle.kts
+++ b/lib-multisrc/mangadventure/build.gradle.kts
@@ -2,4 +2,4 @@ plugins {
id("lib-multisrc")
}
-baseVersionCode = 13
+baseVersionCode = 14
diff --git a/src/all/comickfun/build.gradle b/src/all/comickfun/build.gradle
index faaa0f61e..1796e90c1 100644
--- a/src/all/comickfun/build.gradle
+++ b/src/all/comickfun/build.gradle
@@ -1,7 +1,7 @@
ext {
extName = 'Comick'
extClass = '.ComickFactory'
- extVersionCode = 51
+ extVersionCode = 52
isNsfw = true
}
diff --git a/src/all/mangadex/build.gradle b/src/all/mangadex/build.gradle
index a1cc3535c..69e45f9fc 100644
--- a/src/all/mangadex/build.gradle
+++ b/src/all/mangadex/build.gradle
@@ -1,7 +1,7 @@
ext {
extName = 'MangaDex'
extClass = '.MangaDexFactory'
- extVersionCode = 197
+ extVersionCode = 198
isNsfw = true
}
diff --git a/src/en/coffeemanga/src/eu/kanade/tachiyomi/extension/en/coffeemanga/CoffeeManga.kt b/src/en/coffeemanga/src/eu/kanade/tachiyomi/extension/en/coffeemanga/CoffeeManga.kt
index 68eaa5798..02a974d62 100644
--- a/src/en/coffeemanga/src/eu/kanade/tachiyomi/extension/en/coffeemanga/CoffeeManga.kt
+++ b/src/en/coffeemanga/src/eu/kanade/tachiyomi/extension/en/coffeemanga/CoffeeManga.kt
@@ -6,11 +6,13 @@ import org.jsoup.nodes.Element
class CoffeeManga : Madara("Coffee Manga", "https://coffeemanga.io", "en") {
override val useNewChapterEndpoint = false
- override fun imageFromElement(element: Element): String? = when {
- element.attr("data-src").isNotBlank() -> element.attr("abs:data-src")
- element.attr("data-lazy-src").isNotBlank() -> element.attr("abs:data-lazy-src")
- element.attr("srcset").isNotBlank() -> element.attr("abs:srcset").getSrcSetImage()
- element.attr("data-cfsrc").isNotBlank() -> element.attr("abs:data-cfsrc")
- else -> element.attr("abs:src")
+ override fun imageFromElement(element: Element): String? {
+ return when {
+ element.attr("data-src").isNotBlank() -> element.attr("abs:data-src")
+ element.attr("data-lazy-src").isNotBlank() -> element.attr("abs:data-lazy-src")
+ element.attr("srcset").isNotBlank() -> element.attr("abs:srcset").getSrcSetImage()
+ element.attr("data-cfsrc").isNotBlank() -> element.attr("abs:data-cfsrc")
+ else -> element.attr("abs:src")
+ }
}
}
diff --git a/src/en/luascans/src/eu/kanade/tachiyomi/extension/en/luascans/LuaScans.kt b/src/en/luascans/src/eu/kanade/tachiyomi/extension/en/luascans/LuaScans.kt
index b3701b5b2..a6f30741d 100644
--- a/src/en/luascans/src/eu/kanade/tachiyomi/extension/en/luascans/LuaScans.kt
+++ b/src/en/luascans/src/eu/kanade/tachiyomi/extension/en/luascans/LuaScans.kt
@@ -2,12 +2,11 @@ package eu.kanade.tachiyomi.extension.en.luascans
import eu.kanade.tachiyomi.multisrc.heancms.HeanCms
-class LuaScans :
- HeanCms(
- "Lua Scans",
- "https://luacomic.org",
- "en",
- ) {
+class LuaScans : HeanCms(
+ "Lua Scans",
+ "https://luacomic.org",
+ "en",
+) {
// Moved from Keyoapp to HeanCms
override val versionId = 3
diff --git a/src/en/mangamo/build.gradle b/src/en/mangamo/build.gradle
index 647332f2f..b5dd1e62a 100644
--- a/src/en/mangamo/build.gradle
+++ b/src/en/mangamo/build.gradle
@@ -1,7 +1,7 @@
ext {
extName = 'Mangamo'
extClass = '.Mangamo'
- extVersionCode = 2
+ extVersionCode = 1
isNsfw = false
}
diff --git a/src/en/mangamo/src/eu/kanade/tachiyomi/extension/en/mangamo/MangamoAuth.kt b/src/en/mangamo/src/eu/kanade/tachiyomi/extension/en/mangamo/MangamoAuth.kt
index f6d3d939b..95036d8a5 100644
--- a/src/en/mangamo/src/eu/kanade/tachiyomi/extension/en/mangamo/MangamoAuth.kt
+++ b/src/en/mangamo/src/eu/kanade/tachiyomi/extension/en/mangamo/MangamoAuth.kt
@@ -9,6 +9,7 @@ import eu.kanade.tachiyomi.network.POST
import okhttp3.Headers
import okhttp3.OkHttpClient
import okhttp3.RequestBody.Companion.toRequestBody
+import okhttp3.internal.EMPTY_HEADERS
class MangamoAuth(
private val helper: MangamoHelper,
@@ -52,7 +53,8 @@ class MangamoAuth(
val googleIdentityResponse = client.newCall(
POST(
"https://identitytoolkit.googleapis.com/v1/accounts:signInWithCustomToken?key=${MangamoConstants.FIREBASE_API_KEY}",
- body = "{\"token\":\"$customToken\",\"returnSecureToken\":true}".toRequestBody(),
+ EMPTY_HEADERS,
+ "{\"token\":\"$customToken\",\"returnSecureToken\":true}".toRequestBody(),
),
).execute()
@@ -95,7 +97,8 @@ class MangamoAuth(
val googleIdentityResponse = client.newCall(
POST(
"https://identitytoolkit.googleapis.com/v1/accounts:signUp?key=${MangamoConstants.FIREBASE_API_KEY}",
- body = "{\"returnSecureToken\":true}".toRequestBody(),
+ EMPTY_HEADERS,
+ "{\"returnSecureToken\":true}".toRequestBody(),
),
).execute()
diff --git a/src/en/retsu/src/eu/kanade/tachiyomi/extension/en/retsu/Retsu.kt b/src/en/retsu/src/eu/kanade/tachiyomi/extension/en/retsu/Retsu.kt
index 716aedc00..06a30a6f5 100644
--- a/src/en/retsu/src/eu/kanade/tachiyomi/extension/en/retsu/Retsu.kt
+++ b/src/en/retsu/src/eu/kanade/tachiyomi/extension/en/retsu/Retsu.kt
@@ -2,12 +2,11 @@ package eu.kanade.tachiyomi.extension.en.retsu
import eu.kanade.tachiyomi.multisrc.madara.Madara
-class Retsu :
- Madara(
- "Retsu",
- "https://retsu.org",
- "en",
- ) {
+class Retsu : Madara(
+ "Retsu",
+ "https://retsu.org",
+ "en",
+) {
override fun popularMangaSelector() = "div.manga__item"
override val popularMangaUrlSelector = "h4 a"
diff --git a/src/id/mangkomik/src/eu/kanade/tachiyomi/extension/id/mangkomik/SirenKomik.kt b/src/id/mangkomik/src/eu/kanade/tachiyomi/extension/id/mangkomik/SirenKomik.kt
index 929dee077..cff59c279 100644
--- a/src/id/mangkomik/src/eu/kanade/tachiyomi/extension/id/mangkomik/SirenKomik.kt
+++ b/src/id/mangkomik/src/eu/kanade/tachiyomi/extension/id/mangkomik/SirenKomik.kt
@@ -12,13 +12,12 @@ import java.io.IOException
import java.text.SimpleDateFormat
import java.util.Locale
-class SirenKomik :
- MangaThemesia(
- "Siren Komik",
- "https://sirenkomik.my.id",
- "id",
- dateFormat = SimpleDateFormat("MMMM dd, yyyy", Locale("id")),
- ) {
+class SirenKomik : MangaThemesia(
+ "Siren Komik",
+ "https://sirenkomik.my.id",
+ "id",
+ dateFormat = SimpleDateFormat("MMMM dd, yyyy", Locale("id")),
+) {
override val id = 8457447675410081142
override val hasProjectPage = true
diff --git a/src/pt/sussyscan/src/eu/kanade/tachiyomi/extension/pt/sussyscan/SussyToons.kt b/src/pt/sussyscan/src/eu/kanade/tachiyomi/extension/pt/sussyscan/SussyToons.kt
index 4f67a85da..789c669e8 100644
--- a/src/pt/sussyscan/src/eu/kanade/tachiyomi/extension/pt/sussyscan/SussyToons.kt
+++ b/src/pt/sussyscan/src/eu/kanade/tachiyomi/extension/pt/sussyscan/SussyToons.kt
@@ -32,9 +32,7 @@ import uy.kohesive.injekt.injectLazy
import java.text.SimpleDateFormat
import java.util.Locale
-class SussyToons :
- HttpSource(),
- ConfigurableSource {
+class SussyToons : HttpSource(), ConfigurableSource {
override val name = "Sussy Toons"
@@ -104,7 +102,9 @@ class SussyToons :
// ============================= Popular ==================================
- override fun popularMangaRequest(page: Int): Request = GET("$apiUrl/obras/top5", headers)
+ override fun popularMangaRequest(page: Int): Request {
+ return GET("$apiUrl/obras/top5", headers)
+ }
override fun popularMangaParse(response: Response): MangasPage {
val dto = response.parseAs>>()
@@ -152,7 +152,8 @@ class SussyToons :
return GET(url, headers)
}
- override fun mangaDetailsParse(response: Response) = response.parseAs>().results.toSManga()
+ override fun mangaDetailsParse(response: Response) =
+ response.parseAs>().results.toSManga()
private val SManga.id: String get() {
val mangaUrl = apiUrl.toHttpUrl().newBuilder()
@@ -165,16 +166,18 @@ class SussyToons :
override fun chapterListRequest(manga: SManga) = mangaDetailsRequest(manga)
- override fun chapterListParse(response: Response): List = response.parseAs>().results.chapters.map {
- SChapter.create().apply {
- name = it.name
- it.chapterNumber?.let {
- chapter_number = it
+ override fun chapterListParse(response: Response): List {
+ return response.parseAs>().results.chapters.map {
+ SChapter.create().apply {
+ name = it.name
+ it.chapterNumber?.let {
+ chapter_number = it
+ }
+ setUrlWithoutDomain("$baseUrl/capitulo/${it.id}")
+ date_upload = it.updateAt.toDate()
}
- setUrlWithoutDomain("$baseUrl/capitulo/${it.id}")
- date_upload = it.updateAt.toDate()
- }
- }.sortedBy(SChapter::chapter_number).reversed()
+ }.sortedBy(SChapter::chapter_number).reversed()
+ }
// ============================= Pages ====================================
@@ -205,22 +208,30 @@ class SussyToons :
Page(index, imageUrl = imageUrl.toString())
}
}
- private fun pageListParse(document: Document): List = document.select(pageUrlSelector).mapIndexed { index, element ->
- Page(index, document.location(), element.absUrl("src"))
+ private fun pageListParse(document: Document): List {
+ return document.select(pageUrlSelector).mapIndexed { index, element ->
+ Page(index, document.location(), element.absUrl("src"))
+ }
+ }
+ private fun extractScriptData(document: Document): String {
+ return document.select("script").map(Element::data)
+ .firstOrNull(pageRegex::containsMatchIn)
+ ?: throw Exception("Failed to load pages: Script data not found")
}
- private fun extractScriptData(document: Document): String = document.select("script").map(Element::data)
- .firstOrNull(pageRegex::containsMatchIn)
- ?: throw Exception("Failed to load pages: Script data not found")
- private fun extractJsonContent(scriptData: String): String = pageRegex.find(scriptData)
- ?.groups?.get(1)?.value
- ?.let { json.decodeFromString("\"$it\"") }
- ?: throw Exception("Failed to extract JSON from script")
+ private fun extractJsonContent(scriptData: String): String {
+ return pageRegex.find(scriptData)
+ ?.groups?.get(1)?.value
+ ?.let { json.decodeFromString("\"$it\"") }
+ ?: throw Exception("Failed to extract JSON from script")
+ }
- private fun parseJsonToChapterPageDto(jsonContent: String): ChapterPageDto = try {
- jsonContent.parseAs>().results
- } catch (e: Exception) {
- throw Exception("Failed to load pages: ${e.message}")
+ private fun parseJsonToChapterPageDto(jsonContent: String): ChapterPageDto {
+ return try {
+ jsonContent.parseAs>().results
+ } catch (e: Exception) {
+ throw Exception("Failed to load pages: ${e.message}")
+ }
}
override fun imageUrlParse(response: Response): String = ""
@@ -334,14 +345,13 @@ class SussyToons :
return json.decodeFromStream(body.byteStream())
}
- private inline fun String.parseAs(): T = json.decodeFromString(this)
-
- private fun String.toDate() = try {
- dateFormat.parse(this)!!.time
- } catch (_: Exception) {
- 0L
+ private inline fun String.parseAs(): T {
+ return json.decodeFromString(this)
}
+ private fun String.toDate() =
+ try { dateFormat.parse(this)!!.time } catch (_: Exception) { 0L }
+
/**
* Normalizes path segments:
* Ex: [ "/a/b/", "/a/b", "a/b/", "a/b" ]
diff --git a/src/pt/sussyscan/src/eu/kanade/tachiyomi/extension/pt/sussyscan/SussyToonsDto.kt b/src/pt/sussyscan/src/eu/kanade/tachiyomi/extension/pt/sussyscan/SussyToonsDto.kt
index c1872c075..72889de79 100644
--- a/src/pt/sussyscan/src/eu/kanade/tachiyomi/extension/pt/sussyscan/SussyToonsDto.kt
+++ b/src/pt/sussyscan/src/eu/kanade/tachiyomi/extension/pt/sussyscan/SussyToonsDto.kt
@@ -41,11 +41,13 @@ class MangaDto(
@SerialName("stt_nome")
val value: String?,
) {
- fun toStatus(): Int = when (value?.lowercase()) {
- "em andamento" -> SManga.ONGOING
- "completo" -> SManga.COMPLETED
- "hiato" -> SManga.ON_HIATUS
- else -> SManga.UNKNOWN
+ fun toStatus(): Int {
+ return when (value?.lowercase()) {
+ "em andamento" -> SManga.ONGOING
+ "completo" -> SManga.COMPLETED
+ "hiato" -> SManga.ON_HIATUS
+ else -> SManga.UNKNOWN
+ }
}
}
}
diff --git a/src/pt/taiyo/src/eu/kanade/tachiyomi/extension/pt/taiyo/Taiyo.kt b/src/pt/taiyo/src/eu/kanade/tachiyomi/extension/pt/taiyo/Taiyo.kt
index 0b3d89b5c..211acbf09 100644
--- a/src/pt/taiyo/src/eu/kanade/tachiyomi/extension/pt/taiyo/Taiyo.kt
+++ b/src/pt/taiyo/src/eu/kanade/tachiyomi/extension/pt/taiyo/Taiyo.kt
@@ -32,6 +32,8 @@ import okhttp3.MediaType.Companion.toMediaType
import okhttp3.Request
import okhttp3.RequestBody.Companion.toRequestBody
import okhttp3.Response
+import okhttp3.internal.http.HTTP_FORBIDDEN
+import okhttp3.internal.http.HTTP_UNAUTHORIZED
import org.jsoup.nodes.Document
import org.jsoup.nodes.Element
import org.jsoup.select.Elements
@@ -39,8 +41,6 @@ import rx.Observable
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import uy.kohesive.injekt.injectLazy
-import java.net.HttpURLConnection.HTTP_FORBIDDEN
-import java.net.HttpURLConnection.HTTP_UNAUTHORIZED
import java.text.SimpleDateFormat
import java.util.Locale
@@ -85,13 +85,15 @@ class Taiyo : ParsedHttpSource() {
// =============================== Search ===============================
- override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable = if (query.startsWith(PREFIX_SEARCH)) { // URL intent handler
- val id = query.removePrefix(PREFIX_SEARCH)
- client.newCall(GET("$baseUrl/media/$id"))
- .asObservableSuccess()
- .map(::searchMangaByIdParse)
- } else {
- super.fetchSearchManga(page, query, filters)
+ override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable {
+ return if (query.startsWith(PREFIX_SEARCH)) { // URL intent handler
+ val id = query.removePrefix(PREFIX_SEARCH)
+ client.newCall(GET("$baseUrl/media/$id"))
+ .asObservableSuccess()
+ .map(::searchMangaByIdParse)
+ } else {
+ super.fetchSearchManga(page, query, filters)
+ }
}
private fun searchMangaByIdParse(response: Response): MangasPage {
@@ -144,11 +146,17 @@ class Taiyo : ParsedHttpSource() {
return MangasPage(mangas, mangas.isNotEmpty())
}
- override fun searchMangaSelector(): String = throw UnsupportedOperationException()
+ override fun searchMangaSelector(): String {
+ throw UnsupportedOperationException()
+ }
- override fun searchMangaFromElement(element: Element): SManga = throw UnsupportedOperationException()
+ override fun searchMangaFromElement(element: Element): SManga {
+ throw UnsupportedOperationException()
+ }
- override fun searchMangaNextPageSelector(): String? = throw UnsupportedOperationException()
+ override fun searchMangaNextPageSelector(): String? {
+ throw UnsupportedOperationException()
+ }
// =========================== Manga Details ============================
override fun mangaDetailsParse(document: Document) = SManga.create().apply {
@@ -227,9 +235,13 @@ class Taiyo : ParsedHttpSource() {
return Observable.just(chapters.sortedByDescending { it.chapter_number })
}
- override fun chapterListSelector(): String = throw UnsupportedOperationException()
+ override fun chapterListSelector(): String {
+ throw UnsupportedOperationException()
+ }
- override fun chapterFromElement(element: Element): SChapter = throw UnsupportedOperationException()
+ override fun chapterFromElement(element: Element): SChapter {
+ throw UnsupportedOperationException()
+ }
// =============================== Pages ================================
override fun pageListParse(document: Document): List {
@@ -244,7 +256,9 @@ class Taiyo : ParsedHttpSource() {
}
}
- override fun imageUrlParse(document: Document): String = throw UnsupportedOperationException()
+ override fun imageUrlParse(document: Document): String {
+ throw UnsupportedOperationException()
+ }
// ============================= Utilities ==============================
private fun Element.getImageUrl() = absUrl("srcset").substringBefore(" ")
@@ -253,19 +267,23 @@ class Taiyo : ParsedHttpSource() {
json.decodeFromStream(it.body.byteStream())
}
- private fun String.toDate(): Long = runCatching { DATE_FORMATTER.parse(this)?.time }
- .getOrNull() ?: 0L
+ private fun String.toDate(): Long {
+ return runCatching { DATE_FORMATTER.parse(this)?.time }
+ .getOrNull() ?: 0L
+ }
private inline fun Document.parseJsonFromDocument(
itemName: String = "media",
crossinline transformer: String.() -> String,
- ): T? = runCatching {
- val script = selectFirst("script:containsData($itemName\\\\\":):containsData(\\\"6:\\[)")!!.data()
- val obj = script.substringAfter(",{\\\"$itemName\\\":")
- .run(transformer)
- .replace("\\", "")
- json.decodeFromString(obj)
- }.onFailure { it.printStackTrace() }.getOrNull()
+ ): T? {
+ return runCatching {
+ val script = selectFirst("script:containsData($itemName\\\\\":):containsData(\\\"6:\\[)")!!.data()
+ val obj = script.substringAfter(",{\\\"$itemName\\\":")
+ .run(transformer)
+ .replace("\\", "")
+ json.decodeFromString(obj)
+ }.onFailure { it.printStackTrace() }.getOrNull()
+ }
// ============================= Authorization ========================
@@ -286,10 +304,12 @@ class Taiyo : ParsedHttpSource() {
return chain.proceed(req)
}
- private fun getToken(): String = fetchBearerToken().also {
- preferences.edit()
- .putString(BEARER_TOKEN_PREF, it)
- .apply()
+ private fun getToken(): String {
+ return fetchBearerToken().also {
+ preferences.edit()
+ .putString(BEARER_TOKEN_PREF, it)
+ .apply()
+ }
}
private fun fetchBearerToken(): String {
diff --git a/src/tr/hattorimanga/src/eu/kanade/tachiyomi/extension/tr/hattorimanga/HattoriManga.kt b/src/tr/hattorimanga/src/eu/kanade/tachiyomi/extension/tr/hattorimanga/HattoriManga.kt
index a6e3fd845..767ee93e4 100644
--- a/src/tr/hattorimanga/src/eu/kanade/tachiyomi/extension/tr/hattorimanga/HattoriManga.kt
+++ b/src/tr/hattorimanga/src/eu/kanade/tachiyomi/extension/tr/hattorimanga/HattoriManga.kt
@@ -93,7 +93,8 @@ class HattoriManga : HttpSource() {
csrfToken = document.selectFirst("meta[name=csrf-token]")!!.attr("content")
}
- override fun chapterListParse(response: Response) = throw UnsupportedOperationException()
+ override fun chapterListParse(response: Response) =
+ throw UnsupportedOperationException()
override fun fetchChapterList(manga: SManga): Observable> {
val slug = manga.url.substringAfterLast('/')
@@ -115,9 +116,10 @@ class HattoriManga : HttpSource() {
return Observable.just(chapters)
}
- private fun fetchChapterPageableList(slug: String, page: Int, manga: SManga): HMChapterDto = client.newCall(GET("$baseUrl/load-more-chapters/$slug?page=$page", headers))
- .execute()
- .parseAs()
+ private fun fetchChapterPageableList(slug: String, page: Int, manga: SManga): HMChapterDto =
+ client.newCall(GET("$baseUrl/load-more-chapters/$slug?page=$page", headers))
+ .execute()
+ .parseAs()
override fun latestUpdatesRequest(page: Int): Request = GET("$baseUrl/latest-chapters")
@@ -147,20 +149,24 @@ class HattoriManga : HttpSource() {
}
}
- override fun pageListParse(response: Response): List = response.asJsoup().select(".image-wrapper img").mapIndexed { index, element ->
- Page(index, imageUrl = "$baseUrl${element.attr("data-src")}")
- }.takeIf { it.isNotEmpty() } ?: throw Exception("Oturum açmanız, WebView'ı açmanız ve oturum açmanız gerekir")
+ override fun pageListParse(response: Response): List {
+ return response.asJsoup().select(".image-wrapper img").mapIndexed { index, element ->
+ Page(index, imageUrl = "$baseUrl${element.attr("data-src")}")
+ }.takeIf { it.isNotEmpty() } ?: throw Exception("Oturum açmanız, WebView'ı açmanız ve oturum açmanız gerekir")
+ }
- override fun latestUpdatesParse(response: Response): MangasPage = response.use {
- val mangas = it.parseAs().chapters.map {
- SManga.create().apply {
- val manga = it.manga
- title = manga.title
- thumbnail_url = "$baseUrl/storage/${manga.thumbnail}"
- url = "/manga/${manga.slug}"
- }
- }.distinctBy { manga -> manga.title }
- MangasPage(mangas, false)
+ override fun latestUpdatesParse(response: Response): MangasPage {
+ return response.use {
+ val mangas = it.parseAs().chapters.map {
+ SManga.create().apply {
+ val manga = it.manga
+ title = manga.title
+ thumbnail_url = "$baseUrl/storage/${manga.thumbnail}"
+ url = "/manga/${manga.slug}"
+ }
+ }.distinctBy { manga -> manga.title }
+ MangasPage(mangas, false)
+ }
}
override fun popularMangaParse(response: Response): MangasPage {
@@ -257,18 +263,19 @@ class HattoriManga : HttpSource() {
setUrlWithoutDomain(REGEX_MANGA_URL.find(script)!!.groups[1]!!.value)
}
- private fun parseGenres(document: Document): List = document.select(".tags-blog a")
- .map { element -> Genre(element.text()) }
+ private fun parseGenres(document: Document): List {
+ return document.select(".tags-blog a")
+ .map { element -> Genre(element.text()) }
+ }
- private inline fun Response.parseAs(): T = json.decodeFromString(body.string())
+ private inline fun Response.parseAs(): T {
+ return json.decodeFromString(body.string())
+ }
private fun Response.isPageExpired() = code == 419
- private fun String.toDate(): Long = try {
- dateFormat.parse(trim())!!.time
- } catch (_: Exception) {
- 0L
- }
+ private fun String.toDate(): Long =
+ try { dateFormat.parse(trim())!!.time } catch (_: Exception) { 0L }
class GenreList(title: String, genres: List) : Filter.Group(title, genres.map { GenreCheckBox(it.name, it.id) })
diff --git a/src/vi/lxhentai/src/eu/kanade/tachiyomi/extension/vi/lxhentai/LxHentai.kt b/src/vi/lxhentai/src/eu/kanade/tachiyomi/extension/vi/lxhentai/LxHentai.kt
index 8a2793107..882693d0f 100644
--- a/src/vi/lxhentai/src/eu/kanade/tachiyomi/extension/vi/lxhentai/LxHentai.kt
+++ b/src/vi/lxhentai/src/eu/kanade/tachiyomi/extension/vi/lxhentai/LxHentai.kt
@@ -25,9 +25,7 @@ import uy.kohesive.injekt.api.get
import java.text.SimpleDateFormat
import java.util.Locale
-class LxHentai :
- ParsedHttpSource(),
- ConfigurableSource {
+class LxHentai : ParsedHttpSource(), ConfigurableSource {
override val name = "LXHentai"
@@ -43,30 +41,38 @@ class LxHentai :
override fun headersBuilder(): Headers.Builder = super.headersBuilder().add("Referer", baseUrl)
- override fun popularMangaRequest(page: Int) = searchMangaRequest(page, "", FilterList(SortBy(3)))
+ override fun popularMangaRequest(page: Int) =
+ searchMangaRequest(page, "", FilterList(SortBy(3)))
override fun popularMangaSelector() = searchMangaSelector()
- override fun popularMangaFromElement(element: Element) = searchMangaFromElement(element)
+ override fun popularMangaFromElement(element: Element) =
+ searchMangaFromElement(element)
- override fun popularMangaNextPageSelector() = searchMangaNextPageSelector()
+ override fun popularMangaNextPageSelector() =
+ searchMangaNextPageSelector()
- override fun latestUpdatesRequest(page: Int) = searchMangaRequest(page, "", FilterList(SortBy(0)))
+ override fun latestUpdatesRequest(page: Int) =
+ searchMangaRequest(page, "", FilterList(SortBy(0)))
override fun latestUpdatesSelector() = searchMangaSelector()
- override fun latestUpdatesFromElement(element: Element) = searchMangaFromElement(element)
+ override fun latestUpdatesFromElement(element: Element) =
+ searchMangaFromElement(element)
- override fun latestUpdatesNextPageSelector() = searchMangaNextPageSelector()
+ override fun latestUpdatesNextPageSelector() =
+ searchMangaNextPageSelector()
- override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable = when {
- query.startsWith(PREFIX_ID_SEARCH) -> {
- val slug = query.substringAfter(PREFIX_ID_SEARCH)
- val mangaUrl = "/truyen/$slug"
- fetchMangaDetails(SManga.create().apply { url = mangaUrl })
- .map { MangasPage(listOf(it), false) }
+ override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable {
+ return when {
+ query.startsWith(PREFIX_ID_SEARCH) -> {
+ val slug = query.substringAfter(PREFIX_ID_SEARCH)
+ val mangaUrl = "/truyen/$slug"
+ fetchMangaDetails(SManga.create().apply { url = mangaUrl })
+ .map { MangasPage(listOf(it), false) }
+ }
+ else -> super.fetchSearchManga(page, query, filters)
}
- else -> super.fetchSearchManga(page, query, filters)
}
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
@@ -162,33 +168,32 @@ class LxHentai :
private val dateFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.US)
- private open class UriPartFilter(displayName: String, val vals: Array>, state: Int = 0) : Filter.Select(displayName, vals.map { it.first }.toTypedArray(), state) {
+ private open class UriPartFilter(displayName: String, val vals: Array>, state: Int = 0) :
+ Filter.Select(displayName, vals.map { it.first }.toTypedArray(), state) {
fun toUriPart() = vals[state].second
}
- private class SortBy(state: Int = 0) :
- UriPartFilter(
- "Sắp xếp theo",
- arrayOf(
- Pair("Mới cập nhật", "-updated_at"),
- Pair("Mới nhất", "-created_at"),
- Pair("Cũ nhất", "created_at"),
- Pair("Xem nhiều", "-views"),
- Pair("A-Z", "name"),
- Pair("Z-A", "-name"),
- ),
- state,
- )
+ private class SortBy(state: Int = 0) : UriPartFilter(
+ "Sắp xếp theo",
+ arrayOf(
+ Pair("Mới cập nhật", "-updated_at"),
+ Pair("Mới nhất", "-created_at"),
+ Pair("Cũ nhất", "created_at"),
+ Pair("Xem nhiều", "-views"),
+ Pair("A-Z", "name"),
+ Pair("Z-A", "-name"),
+ ),
+ state,
+ )
- private class Status :
- UriPartFilter(
- "Trạng thái",
- arrayOf(
- Pair("Tất cả", "1,2"),
- Pair("Đang tiến hành", "2"),
- Pair("Đã hoàn thành", "1"),
- ),
- )
+ private class Status : UriPartFilter(
+ "Trạng thái",
+ arrayOf(
+ Pair("Tất cả", "1,2"),
+ Pair("Đang tiến hành", "2"),
+ Pair("Đã hoàn thành", "1"),
+ ),
+ )
private class Genre(name: String, val id: Int) : Filter.TriState(name)
private class GenreList(genres: List) : Filter.Group("Thể loại", genres)
diff --git a/src/vi/truyentranh3q/src/eu/kanade/tachiyomi/extension/vi/truyentranh3q/TruyenTranh3Q.kt b/src/vi/truyentranh3q/src/eu/kanade/tachiyomi/extension/vi/truyentranh3q/TruyenTranh3Q.kt
index 1fed71d74..655a251e2 100644
--- a/src/vi/truyentranh3q/src/eu/kanade/tachiyomi/extension/vi/truyentranh3q/TruyenTranh3Q.kt
+++ b/src/vi/truyentranh3q/src/eu/kanade/tachiyomi/extension/vi/truyentranh3q/TruyenTranh3Q.kt
@@ -34,31 +34,39 @@ class TruyenTranh3Q : ParsedHttpSource() {
.rateLimit(3)
.build()
- override fun headersBuilder(): Headers.Builder = super.headersBuilder().add("Referer", "$baseUrl/")
+ override fun headersBuilder(): Headers.Builder {
+ return super.headersBuilder().add("Referer", "$baseUrl/")
+ }
private val dateFormat = SimpleDateFormat("dd/MM/yyyy", Locale.US)
- override fun popularMangaRequest(page: Int): Request = GET("$baseUrl/danh-sach/truyen-yeu-thich?page=$page", headers)
+ override fun popularMangaRequest(page: Int): Request {
+ return GET("$baseUrl/danh-sach/truyen-yeu-thich?page=$page", headers)
+ }
override fun popularMangaSelector(): String = "ul.list_grid.grid > li"
- override fun popularMangaFromElement(element: Element): SManga = SManga.create().apply {
- element.select("h3 a").let {
- title = it.text()
- setUrlWithoutDomain(it.attr("abs:href"))
- }
- thumbnail_url = element.selectFirst(".book_avatar a img")
- ?.absUrl("src")
- ?.let { url ->
- url.toHttpUrlOrNull()
- ?.queryParameter("url")
- ?: url
+ override fun popularMangaFromElement(element: Element): SManga {
+ return SManga.create().apply {
+ element.select("h3 a").let {
+ title = it.text()
+ setUrlWithoutDomain(it.attr("abs:href"))
}
+ thumbnail_url = element.selectFirst(".book_avatar a img")
+ ?.absUrl("src")
+ ?.let { url ->
+ url.toHttpUrlOrNull()
+ ?.queryParameter("url")
+ ?: url
+ }
+ }
}
override fun popularMangaNextPageSelector(): String? = ".page_redirect > a:last-child > p:not(.active)"
- override fun latestUpdatesRequest(page: Int): Request = GET("$baseUrl/danh-sach/truyen-moi-cap-nhat?page=$page", headers)
+ override fun latestUpdatesRequest(page: Int): Request {
+ return GET("$baseUrl/danh-sach/truyen-moi-cap-nhat?page=$page", headers)
+ }
// same as popularManga
override fun latestUpdatesSelector(): String = popularMangaSelector()
@@ -113,19 +121,21 @@ class TruyenTranh3Q : ParsedHttpSource() {
override fun searchMangaFromElement(element: Element): SManga = popularMangaFromElement(element)
override fun searchMangaNextPageSelector(): String? = popularMangaNextPageSelector()
- override fun mangaDetailsParse(document: Document): SManga = SManga.create().apply {
- document.selectFirst(".book_info > .book_other")?.let { info ->
- title = info.selectFirst("h1[itemprop=name]")!!.text()
- author = info.selectFirst("ul.list-info li.author p.col-xs-9")?.text()
- status = when (info.selectFirst("ul.list-info li.status p.col-xs-9")?.text()) {
- "Đang Cập Nhật" -> SManga.ONGOING
- "Hoàn Thành" -> SManga.COMPLETED
- else -> SManga.UNKNOWN
+ override fun mangaDetailsParse(document: Document): SManga {
+ return SManga.create().apply {
+ document.selectFirst(".book_info > .book_other")?.let { info ->
+ title = info.selectFirst("h1[itemprop=name]")!!.text()
+ author = info.selectFirst("ul.list-info li.author p.col-xs-9")?.text()
+ status = when (info.selectFirst("ul.list-info li.status p.col-xs-9")?.text()) {
+ "Đang Cập Nhật" -> SManga.ONGOING
+ "Hoàn Thành" -> SManga.COMPLETED
+ else -> SManga.UNKNOWN
+ }
+ genre = info.select(".list01 li a").joinToString { it.text() }
}
- genre = info.select(".list01 li a").joinToString { it.text() }
+ description = document.selectFirst(".book_detail > .story-detail-info")?.text()
+ thumbnail_url = document.selectFirst(".book_detail > .book_info > .book_avatar > img")?.attr("abs:src")
}
- description = document.selectFirst(".book_detail > .story-detail-info")?.text()
- thumbnail_url = document.selectFirst(".book_detail > .book_info > .book_avatar > img")?.attr("abs:src")
}
// chapters
@@ -173,19 +183,23 @@ class TruyenTranh3Q : ParsedHttpSource() {
}
}
- override fun chapterFromElement(element: Element): SChapter = SChapter.create().apply {
- element.selectFirst(".name-chap > a")?.let {
- name = it.text()
- setUrlWithoutDomain(it.attr("abs:href"))
+ override fun chapterFromElement(element: Element): SChapter {
+ return SChapter.create().apply {
+ element.selectFirst(".name-chap > a")?.let {
+ name = it.text()
+ setUrlWithoutDomain(it.attr("abs:href"))
+ }
+ date_upload = parseChapterDate(element.selectFirst(".time-chap")?.text() ?: "")
}
- date_upload = parseChapterDate(element.selectFirst(".time-chap")?.text() ?: "")
}
// parse pages
private val pageListSelector = ".chapter_content .page-chapter img"
- override fun pageListParse(document: Document): List = document.select(pageListSelector).mapIndexed { idx, it ->
- Page(idx, imageUrl = it.absUrl("data-src"))
+ override fun pageListParse(document: Document): List {
+ return document.select(pageListSelector).mapIndexed { idx, it ->
+ Page(idx, imageUrl = it.absUrl("data-src"))
+ }
}
override fun imageUrlParse(document: Document): String = throw UnsupportedOperationException()
@@ -234,8 +248,10 @@ class TruyenTranh3Q : ParsedHttpSource() {
private fun genresRequest() = GET("$baseUrl/$searchPath", headers)
- private fun parseGenres(document: Document): List = document.select(".genre-item").mapIndexed { index, element ->
- Genre(element.text(), index + 1)
+ private fun parseGenres(document: Document): List {
+ return document.select(".genre-item").mapIndexed { index, element ->
+ Genre(element.text(), index + 1)
+ }
}
private fun fetchGenres() {
diff --git a/src/vi/yurineko/src/eu/kanade/tachiyomi/extension/vi/yurineko/YuriNeko.kt b/src/vi/yurineko/src/eu/kanade/tachiyomi/extension/vi/yurineko/YuriNeko.kt
index 68ce45d50..34bdb6422 100644
--- a/src/vi/yurineko/src/eu/kanade/tachiyomi/extension/vi/yurineko/YuriNeko.kt
+++ b/src/vi/yurineko/src/eu/kanade/tachiyomi/extension/vi/yurineko/YuriNeko.kt
@@ -36,9 +36,7 @@ import java.io.IOException
import java.net.URLDecoder
import java.util.concurrent.TimeUnit
-class YuriNeko :
- HttpSource(),
- ConfigurableSource {
+class YuriNeko : HttpSource(), ConfigurableSource {
override val name = "YuriNeko"
@@ -109,20 +107,22 @@ class YuriNeko :
override fun latestUpdatesParse(response: Response): MangasPage = throw UnsupportedOperationException()
- override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable = when {
- query.startsWith(PREFIX_ID_SEARCH) -> {
- val id = query.removePrefix(PREFIX_ID_SEARCH).trim()
- if (id.toIntOrNull() == null) {
- throw Exception("ID tìm kiếm không hợp lệ (phải là một số).")
+ override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable {
+ return when {
+ query.startsWith(PREFIX_ID_SEARCH) -> {
+ val id = query.removePrefix(PREFIX_ID_SEARCH).trim()
+ if (id.toIntOrNull() == null) {
+ throw Exception("ID tìm kiếm không hợp lệ (phải là một số).")
+ }
+ fetchMangaDetails(
+ SManga.create().apply {
+ url = "/manga/$id"
+ },
+ )
+ .map { MangasPage(listOf(it), false) }
}
- fetchMangaDetails(
- SManga.create().apply {
- url = "/manga/$id"
- },
- )
- .map { MangasPage(listOf(it), false) }
+ else -> super.fetchSearchManga(page, query, filters)
}
- else -> super.fetchSearchManga(page, query, filters)
}
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
@@ -182,13 +182,15 @@ class YuriNeko :
override fun searchMangaParse(response: Response): MangasPage = popularMangaParse(response)
- override fun fetchMangaDetails(manga: SManga): Observable = client.newCall(GET("$apiUrl${manga.url}"))
- .asObservableSuccess()
- .map { mangaDetailsParse(it) }
+ override fun fetchMangaDetails(manga: SManga): Observable =
+ client.newCall(GET("$apiUrl${manga.url}"))
+ .asObservableSuccess()
+ .map { mangaDetailsParse(it) }
override fun mangaDetailsRequest(manga: SManga): Request = GET("$baseUrl${manga.url}")
- override fun mangaDetailsParse(response: Response): SManga = response.parseAs().toSManga(storageUrl)
+ override fun mangaDetailsParse(response: Response): SManga =
+ response.parseAs().toSManga(storageUrl)
override fun chapterListRequest(manga: SManga): Request = GET("$apiUrl${manga.url}")
@@ -200,11 +202,13 @@ class YuriNeko :
override fun pageListRequest(chapter: SChapter): Request = GET("$apiUrl${chapter.url}")
- override fun pageListParse(response: Response): List = response.parseAs().toPageList(storageUrl)
+ override fun pageListParse(response: Response): List =
+ response.parseAs().toPageList(storageUrl)
override fun imageUrlParse(response: Response): String = throw UnsupportedOperationException()
- open class UriPartFilter(displayName: String, private val vals: Array>) : Filter.Select(displayName, vals.map { it.first }.toTypedArray()) {
+ open class UriPartFilter(displayName: String, private val vals: Array>) :
+ Filter.Select(displayName, vals.map { it.first }.toTypedArray()) {
fun toUriPart() = vals[state].second
}