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 e85938e35..8c191c145 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,7 +109,9 @@ abstract class Madara( protected open val useLoadMoreRequest = LoadMoreStrategy.AutoDetect enum class LoadMoreStrategy { - AutoDetect, Always, Never + AutoDetect, + Always, + Never, } /** @@ -118,7 +120,9 @@ abstract class Madara( private var loadMoreRequestDetected = LoadMoreDetection.Pending private enum class LoadMoreDetection { - Pending, True, False + Pending, + True, + False, } protected fun detectLoadMore(document: Document) { @@ -132,12 +136,10 @@ abstract class Madara( } } - protected fun useLoadMoreRequest(): Boolean { - return when (useLoadMoreRequest) { - LoadMoreStrategy.Always -> true - LoadMoreStrategy.Never -> false - else -> loadMoreRequestDetected == LoadMoreDetection.True - } + protected fun useLoadMoreRequest(): Boolean = when (useLoadMoreRequest) { + LoadMoreStrategy.Always -> true + LoadMoreStrategy.Never -> false + else -> loadMoreRequestDetected == LoadMoreDetection.True } // Popular Manga @@ -176,19 +178,17 @@ 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,12 +199,11 @@ 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() @@ -251,20 +250,16 @@ abstract class Madara( return super.fetchSearchManga(page, query, filters) } - protected open fun searchPage(page: Int): String { - return if (page == 1) { - "" - } else { - "page/$page/" - } + protected open fun searchPage(page: Int): String = if (page == 1) { + "" + } else { + "page/$page/" } - override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { - return if (useLoadMoreRequest()) { - searchLoadMoreRequest(page, query, filters) - } else { - searchRequest(page, query, filters) - } + override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request = if (useLoadMoreRequest()) { + searchLoadMoreRequest(page, query, filters) + } else { + searchRequest(page, query, filters) } protected open fun searchRequest(page: Int, query: String, filters: FilterList): Request { @@ -310,7 +305,9 @@ 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 -> {} @@ -489,8 +486,7 @@ 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 } @@ -499,21 +495,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) @@ -757,32 +753,24 @@ abstract class Madara( open val altName = intl["alt_names_heading"] open val updatingRegex = "Updating|Atualizando".toRegex(RegexOption.IGNORE_CASE) - fun String.notUpdating(): Boolean { - return this.contains(updatingRegex).not() - } + fun String.notUpdating(): Boolean = this.contains(updatingRegex).not() - private fun String.containsIn(array: Array): Boolean { - return this.lowercase() in array.map { it.lowercase() } - } + private fun String.containsIn(array: Array): Boolean = this.lowercase() in array.map { it.lowercase() } - 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") - } + 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") } /** * Get the best image quality available from srcset */ - protected fun String.getSrcSetImage(): String? { - return this.split(" ") - .filter(URL_REGEX::matches) - .maxOfOrNull(String::toString) - } + protected fun String.getSrcSetImage(): String? = this.split(" ") + .filter(URL_REGEX::matches) + .maxOfOrNull(String::toString) /** * Set it to true if the source uses the new AJAX endpoint to @@ -807,9 +795,7 @@ abstract class Madara( return POST("$baseUrl/wp-admin/admin-ajax.php", xhrHeaders, form) } - protected open fun xhrChaptersRequest(mangaUrl: String): Request { - return POST("$mangaUrl/ajax/chapters", xhrHeaders) - } + protected open fun xhrChaptersRequest(mangaUrl: String): Request = POST("$mangaUrl/ajax/chapters", xhrHeaders) override fun chapterListParse(response: Response): List { val document = response.asJsoup() @@ -880,12 +866,10 @@ abstract class Madara( open fun parseChapterDate(date: String?): Long { date ?: return 0 - fun SimpleDateFormat.tryParse(string: String): Long { - return try { - parse(string)?.time ?: 0 - } catch (_: ParseException) { - 0 - } + fun SimpleDateFormat.tryParse(string: String): Long = try { + parse(string)?.time ?: 0 + } catch (_: ParseException) { + 0 } return when { @@ -1006,9 +990,7 @@ abstract class Madara( } } - override fun imageRequest(page: Page): Request { - return GET(page.imageUrl!!, headers.newBuilder().set("Referer", page.url).build()) - } + override fun imageRequest(page: Page): Request = GET(page.imageUrl!!, headers.newBuilder().set("Referer", page.url).build()) override fun imageUrlParse(document: Document) = "" @@ -1083,26 +1065,22 @@ abstract class Madara( /** * The request to the search page (or another one) that have the genres list. */ - protected open fun genresRequest(): Request { - return GET("$baseUrl/?s=genre&post_type=wp-manga", headers) - } + protected open fun genresRequest(): Request = 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 { - return 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 = 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/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 02a974d62..68eaa5798 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,13 +6,11 @@ import org.jsoup.nodes.Element class CoffeeManga : Madara("Coffee Manga", "https://coffeemanga.io", "en") { override val useNewChapterEndpoint = false - 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") - } + 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") } } 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 a6f30741d..b3701b5b2 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,11 +2,12 @@ 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/retsu/src/eu/kanade/tachiyomi/extension/en/retsu/Retsu.kt b/src/en/retsu/src/eu/kanade/tachiyomi/extension/en/retsu/Retsu.kt index 06a30a6f5..716aedc00 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,11 +2,12 @@ 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 cff59c279..929dee077 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,12 +12,13 @@ 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 789c669e8..4f67a85da 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,7 +32,9 @@ 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" @@ -102,9 +104,7 @@ class SussyToons : HttpSource(), ConfigurableSource { // ============================= Popular ================================== - override fun popularMangaRequest(page: Int): Request { - return GET("$apiUrl/obras/top5", headers) - } + override fun popularMangaRequest(page: Int): Request = GET("$apiUrl/obras/top5", headers) override fun popularMangaParse(response: Response): MangasPage { val dto = response.parseAs>>() @@ -152,8 +152,7 @@ class SussyToons : HttpSource(), ConfigurableSource { 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() @@ -166,18 +165,16 @@ class SussyToons : HttpSource(), ConfigurableSource { override fun chapterListRequest(manga: SManga) = mangaDetailsRequest(manga) - 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() + override fun chapterListParse(response: Response): List = response.parseAs>().results.chapters.map { + SChapter.create().apply { + name = it.name + it.chapterNumber?.let { + chapter_number = it } - }.sortedBy(SChapter::chapter_number).reversed() - } + setUrlWithoutDomain("$baseUrl/capitulo/${it.id}") + date_upload = it.updateAt.toDate() + } + }.sortedBy(SChapter::chapter_number).reversed() // ============================= Pages ==================================== @@ -208,30 +205,22 @@ class SussyToons : HttpSource(), ConfigurableSource { Page(index, imageUrl = imageUrl.toString()) } } - 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 pageListParse(document: Document): List = document.select(pageUrlSelector).mapIndexed { index, element -> + Page(index, document.location(), element.absUrl("src")) } + 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 { - return 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 = 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 { - return try { - jsonContent.parseAs>().results - } catch (e: Exception) { - throw Exception("Failed to load pages: ${e.message}") - } + private fun parseJsonToChapterPageDto(jsonContent: String): ChapterPageDto = try { + jsonContent.parseAs>().results + } catch (e: Exception) { + throw Exception("Failed to load pages: ${e.message}") } override fun imageUrlParse(response: Response): String = "" @@ -345,12 +334,13 @@ class SussyToons : HttpSource(), ConfigurableSource { return json.decodeFromStream(body.byteStream()) } - private inline fun String.parseAs(): T { - return json.decodeFromString(this) - } + private inline fun String.parseAs(): T = json.decodeFromString(this) - private fun String.toDate() = - try { dateFormat.parse(this)!!.time } catch (_: Exception) { 0L } + private fun String.toDate() = try { + dateFormat.parse(this)!!.time + } catch (_: Exception) { + 0L + } /** * Normalizes path segments: 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 72889de79..c1872c075 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,13 +41,11 @@ class MangaDto( @SerialName("stt_nome") val value: String?, ) { - fun toStatus(): Int { - return when (value?.lowercase()) { - "em andamento" -> SManga.ONGOING - "completo" -> SManga.COMPLETED - "hiato" -> SManga.ON_HIATUS - else -> SManga.UNKNOWN - } + fun toStatus(): Int = when (value?.lowercase()) { + "em andamento" -> SManga.ONGOING + "completo" -> SManga.COMPLETED + "hiato" -> SManga.ON_HIATUS + else -> SManga.UNKNOWN } } } 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 767ee93e4..a6e3fd845 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,8 +93,7 @@ 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('/') @@ -116,10 +115,9 @@ 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") @@ -149,24 +147,20 @@ class HattoriManga : HttpSource() { } } - 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 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 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 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 popularMangaParse(response: Response): MangasPage { @@ -263,19 +257,18 @@ class HattoriManga : HttpSource() { setUrlWithoutDomain(REGEX_MANGA_URL.find(script)!!.groups[1]!!.value) } - private fun parseGenres(document: Document): List { - return document.select(".tags-blog a") - .map { element -> Genre(element.text()) } - } + private fun parseGenres(document: Document): List = document.select(".tags-blog a") + .map { element -> Genre(element.text()) } - private inline fun Response.parseAs(): T { - return json.decodeFromString(body.string()) - } + private inline fun Response.parseAs(): T = 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 882693d0f..8a2793107 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,7 +25,9 @@ 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" @@ -41,38 +43,30 @@ class LxHentai : ParsedHttpSource(), ConfigurableSource { 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 { - 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) + 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) } } + else -> super.fetchSearchManga(page, query, filters) } override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { @@ -168,32 +162,33 @@ class LxHentai : ParsedHttpSource(), ConfigurableSource { 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 655a251e2..1fed71d74 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,39 +34,31 @@ class TruyenTranh3Q : ParsedHttpSource() { .rateLimit(3) .build() - override fun headersBuilder(): Headers.Builder { - return super.headersBuilder().add("Referer", "$baseUrl/") - } + override fun headersBuilder(): Headers.Builder = super.headersBuilder().add("Referer", "$baseUrl/") private val dateFormat = SimpleDateFormat("dd/MM/yyyy", Locale.US) - override fun popularMangaRequest(page: Int): Request { - return GET("$baseUrl/danh-sach/truyen-yeu-thich?page=$page", headers) - } + override fun popularMangaRequest(page: Int): Request = 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 { - 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 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 popularMangaNextPageSelector(): String? = ".page_redirect > a:last-child > p:not(.active)" - override fun latestUpdatesRequest(page: Int): Request { - return GET("$baseUrl/danh-sach/truyen-moi-cap-nhat?page=$page", headers) - } + override fun latestUpdatesRequest(page: Int): Request = GET("$baseUrl/danh-sach/truyen-moi-cap-nhat?page=$page", headers) // same as popularManga override fun latestUpdatesSelector(): String = popularMangaSelector() @@ -121,21 +113,19 @@ class TruyenTranh3Q : ParsedHttpSource() { override fun searchMangaFromElement(element: Element): SManga = popularMangaFromElement(element) override fun searchMangaNextPageSelector(): String? = popularMangaNextPageSelector() - 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() } + 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 } - description = document.selectFirst(".book_detail > .story-detail-info")?.text() - thumbnail_url = document.selectFirst(".book_detail > .book_info > .book_avatar > img")?.attr("abs:src") + 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") } // chapters @@ -183,23 +173,19 @@ class TruyenTranh3Q : ParsedHttpSource() { } } - 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() ?: "") + override fun chapterFromElement(element: Element): SChapter = 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() ?: "") } // parse pages private val pageListSelector = ".chapter_content .page-chapter img" - override fun pageListParse(document: Document): List { - return document.select(pageListSelector).mapIndexed { idx, it -> - Page(idx, imageUrl = it.absUrl("data-src")) - } + override fun pageListParse(document: Document): List = document.select(pageListSelector).mapIndexed { idx, it -> + Page(idx, imageUrl = it.absUrl("data-src")) } override fun imageUrlParse(document: Document): String = throw UnsupportedOperationException() @@ -248,10 +234,8 @@ class TruyenTranh3Q : ParsedHttpSource() { private fun genresRequest() = GET("$baseUrl/$searchPath", headers) - private fun parseGenres(document: Document): List { - return document.select(".genre-item").mapIndexed { index, element -> - Genre(element.text(), index + 1) - } + private fun parseGenres(document: Document): List = 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 34bdb6422..68ce45d50 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,7 +36,9 @@ 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" @@ -107,22 +109,20 @@ class YuriNeko : HttpSource(), ConfigurableSource { override fun latestUpdatesParse(response: Response): MangasPage = throw UnsupportedOperationException() - 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) } + 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ố).") } - else -> super.fetchSearchManga(page, query, filters) + fetchMangaDetails( + SManga.create().apply { + url = "/manga/$id" + }, + ) + .map { MangasPage(listOf(it), false) } } + else -> super.fetchSearchManga(page, query, filters) } override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { @@ -182,15 +182,13 @@ class YuriNeko : HttpSource(), ConfigurableSource { 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}") @@ -202,13 +200,11 @@ class YuriNeko : HttpSource(), ConfigurableSource { 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 }