From c94cc58e7dca07c175ac925735fcc65c86669929 Mon Sep 17 00:00:00 2001 From: TacoTheDank Date: Sat, 3 Aug 2019 21:38:05 -0400 Subject: [PATCH] Update four "all" sources (#1314) * ComiCake: Some cleanup work Signed-off-by: TacoTheDank * E-Hentai: Some cleanup work Signed-off-by: TacoTheDank * FoolSlide: Some cleanup work and source updates Signed-off-by: TacoTheDank * Genkan: Some cleanup work Signed-off-by: TacoTheDank --- src/all/comicake/build.gradle | 4 +- .../{en => all}/comicake/ComiCake.kt | 49 +++++++------ .../{en => all}/comicake/ComiCakeFactory.kt | 6 +- src/all/ehentai/build.gradle | 4 +- .../extension/all/ehentai/EHLangs.kt | 34 ++++----- .../tachiyomi/extension/all/ehentai/EHUtil.kt | 23 +++--- .../extension/all/ehentai/EHentai.kt | 71 +++++++------------ .../all/ehentai/ExGalleryMetadata.kt | 18 ++--- .../extension/all/ehentai/MetadataCopier.kt | 7 +- src/all/foolslide/build.gradle | 4 +- .../{en => all}/foolslide/FoolSlide.kt | 31 ++++---- .../{en => all}/foolslide/FoolSlideFactory.kt | 66 ++++++++--------- .../{en => all}/foolslide/HentaiCafe.kt | 28 ++++---- src/all/genkan/build.gradle | 2 +- .../tachiyomi/extension/all/genkan/Genkan.kt | 43 ++++++----- .../extension/all/genkan/GenkanFactory.kt | 12 ++-- 16 files changed, 188 insertions(+), 214 deletions(-) rename src/all/comicake/src/eu/kanade/tachiyomi/extension/{en => all}/comicake/ComiCake.kt (80%) rename src/all/comicake/src/eu/kanade/tachiyomi/extension/{en => all}/comicake/ComiCakeFactory.kt (84%) rename src/all/foolslide/src/eu/kanade/tachiyomi/extension/{en => all}/foolslide/FoolSlide.kt (90%) rename src/all/foolslide/src/eu/kanade/tachiyomi/extension/{en => all}/foolslide/FoolSlideFactory.kt (82%) rename src/all/foolslide/src/eu/kanade/tachiyomi/extension/{en => all}/foolslide/HentaiCafe.kt (92%) diff --git a/src/all/comicake/build.gradle b/src/all/comicake/build.gradle index cf1b4598d..93924b62f 100644 --- a/src/all/comicake/build.gradle +++ b/src/all/comicake/build.gradle @@ -3,9 +3,9 @@ apply plugin: 'kotlin-android' ext { appName = 'Tachiyomi: ComiCake' - pkgNameSuffix = "all.comicake" + pkgNameSuffix = 'all.comicake' extClass = '.ComiCakeFactory' - extVersionCode = 3 + extVersionCode = 4 libVersion = '1.2' } diff --git a/src/all/comicake/src/eu/kanade/tachiyomi/extension/en/comicake/ComiCake.kt b/src/all/comicake/src/eu/kanade/tachiyomi/extension/all/comicake/ComiCake.kt similarity index 80% rename from src/all/comicake/src/eu/kanade/tachiyomi/extension/en/comicake/ComiCake.kt rename to src/all/comicake/src/eu/kanade/tachiyomi/extension/all/comicake/ComiCake.kt index 390293d42..108587cbb 100644 --- a/src/all/comicake/src/eu/kanade/tachiyomi/extension/en/comicake/ComiCake.kt +++ b/src/all/comicake/src/eu/kanade/tachiyomi/extension/all/comicake/ComiCake.kt @@ -2,21 +2,24 @@ package eu.kanade.tachiyomi.extension.all.comicake import android.os.Build import eu.kanade.tachiyomi.extension.BuildConfig +import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.source.model.* import eu.kanade.tachiyomi.source.online.HttpSource import okhttp3.Headers import okhttp3.Request import okhttp3.Response -import eu.kanade.tachiyomi.network.GET import org.json.JSONArray import org.json.JSONObject import java.text.SimpleDateFormat -import kotlin.collections.ArrayList const val COMICAKE_DEFAULT_API_ENDPOINT = "/api" // Highly unlikely to change const val COMICAKE_DEFAULT_READER_ENDPOINT = "/r" // Can change based on CC config -open class ComiCake(override val name: String, override val baseUrl: String, override val lang: String, val readerEndpoint: String = COMICAKE_DEFAULT_READER_ENDPOINT, val apiEndpoint: String = COMICAKE_DEFAULT_API_ENDPOINT) : HttpSource() { +open class ComiCake(override val name: String, + final override val baseUrl: String, + override val lang: String, + readerEndpoint: String = COMICAKE_DEFAULT_READER_ENDPOINT, + apiEndpoint: String = COMICAKE_DEFAULT_API_ENDPOINT) : HttpSource() { override val versionId = 1 override val supportsLatest = true private val readerBase = baseUrl + readerEndpoint @@ -40,18 +43,18 @@ open class ComiCake(override val name: String, override val baseUrl: String, ove return getMangasPageFromComicsResponse(res) } - private fun getMangasPageFromComicsResponse(json: String, nested: Boolean = false) : MangasPage { - var response = JSONObject(json) - var results = response.getJSONArray("results") + private fun getMangasPageFromComicsResponse(json: String, nested: Boolean = false): MangasPage { + val response = JSONObject(json) + val results = response.getJSONArray("results") val mangas = ArrayList() - val ids = mutableListOf(); + val ids = mutableListOf() for (i in 0 until results.length()) { val obj = results.getJSONObject(i) - if(nested) { - val nestedComic = obj.getJSONObject("comic"); + if (nested) { + val nestedComic = obj.getJSONObject("comic") val id = nestedComic.getInt("id") - if(ids.contains(id)) + if (ids.contains(id)) continue ids.add(id) val manga = SManga.create() @@ -60,13 +63,13 @@ open class ComiCake(override val name: String, override val baseUrl: String, ove mangas.add(manga) } else { val id = obj.getInt("id") - if(ids.contains(id)) + if (ids.contains(id)) continue ids.add(id) mangas.add(parseComicJson(obj)) } } - return MangasPage(mangas, if (response.getString("next").isNullOrEmpty() || response.getString("next") == "null") false else true) + return MangasPage(mangas, !(response.getString("next").isNullOrEmpty() || response.getString("next") == "null")) } override fun mangaDetailsRequest(manga: SManga): Request { @@ -78,11 +81,11 @@ open class ComiCake(override val name: String, override val baseUrl: String, ove return parseComicJson(comicJson, true) } - private fun parseComicJson(obj: JSONObject, human: Boolean = false) = SManga.create().apply { - if(human) { - url = "$readerBase/series/${obj.getString("slug")}/" + private fun parseComicJson(obj: JSONObject, human: Boolean = false) = SManga.create().apply { + url = if (human) { + "$readerBase/series/${obj.getString("slug")}/" } else { - url = obj.getInt("id").toString() // Yeah, I know... Feel free to improve on this + obj.getInt("id").toString() // Yeah, I know... Feel free to improve on this } title = obj.getString("name") thumbnail_url = obj.getString("cover") @@ -93,9 +96,9 @@ open class ComiCake(override val name: String, override val baseUrl: String, ove status = SManga.UNKNOWN } - private fun parseListNames(arr: JSONArray) : String { - var hold = ArrayList(arr.length()) - for(i in 0 until arr.length()) + private fun parseListNames(arr: JSONArray): String { + val hold = ArrayList(arr.length()) + for (i in 0 until arr.length()) hold.add(arr.getJSONObject(i).getString("name")) return hold.sorted().joinToString(", ") } @@ -133,7 +136,7 @@ open class ComiCake(override val name: String, override val baseUrl: String, ove override fun chapterListParse(response: Response): List { val chapterJson = JSONObject(response.body()!!.string()) - var results = chapterJson.getJSONArray("results") + val results = chapterJson.getJSONArray("results") val ret = ArrayList() for (i in 0 until results.length()) { ret.add(parseChapterJson(results.getJSONObject(i))) @@ -144,13 +147,13 @@ open class ComiCake(override val name: String, override val baseUrl: String, ove override fun pageListParse(response: Response): List { val webPub = JSONObject(response.body()!!.string()) val readingOrder = webPub.getJSONArray("readingOrder") - val ret = ArrayList(); + val ret = ArrayList() for (i in 0 until readingOrder.length()) { - var pageUrl = readingOrder.getJSONObject(i).getString("href") + val pageUrl = readingOrder.getJSONObject(i).getString("href") ret.add(Page(i, "", pageUrl)) } return ret } override fun imageUrlParse(response: Response) = throw UnsupportedOperationException("This method should not be called!") -} \ No newline at end of file +} diff --git a/src/all/comicake/src/eu/kanade/tachiyomi/extension/en/comicake/ComiCakeFactory.kt b/src/all/comicake/src/eu/kanade/tachiyomi/extension/all/comicake/ComiCakeFactory.kt similarity index 84% rename from src/all/comicake/src/eu/kanade/tachiyomi/extension/en/comicake/ComiCakeFactory.kt rename to src/all/comicake/src/eu/kanade/tachiyomi/extension/all/comicake/ComiCakeFactory.kt index 799ab1ed6..6dbb982f1 100644 --- a/src/all/comicake/src/eu/kanade/tachiyomi/extension/en/comicake/ComiCakeFactory.kt +++ b/src/all/comicake/src/eu/kanade/tachiyomi/extension/all/comicake/ComiCakeFactory.kt @@ -9,11 +9,11 @@ class ComiCakeFactory : SourceFactory { fun getAllComiCake(): List { return listOf( - WhimSubs(), - ChampionScans() + WhimSubs(), + ChampionScans() ) } class WhimSubs : ComiCake("WhimSubs", "https://whimsubs.xyz", "en") -class ChampionScans : ComiCake("Champion Scans", "https://reader.championscans.com", "en", "/") \ No newline at end of file +class ChampionScans : ComiCake("Champion Scans", "https://reader.championscans.com", "en", "/") diff --git a/src/all/ehentai/build.gradle b/src/all/ehentai/build.gradle index dc8227f28..953f16a98 100644 --- a/src/all/ehentai/build.gradle +++ b/src/all/ehentai/build.gradle @@ -4,8 +4,8 @@ apply plugin: 'kotlin-android' ext { appName = 'Tachiyomi: E-Hentai' pkgNameSuffix = 'all.ehentai' - extClass = '.EHJapanese; .EHEnglish; .EHChinese; .EHDutch; .EHFrench; .EHGerman; .EHHungarian; .EHItalian; .EHKorean; .EHPolish; .EHPolish; .EHPortuguese; .EHRussian; .EHSpanish; .EHThai; .EHVietnamese; .EHSpeechless; .EHOther' - extVersionCode = 4 + extClass = '.EHJapanese; .EHEnglish; .EHChinese; .EHDutch; .EHFrench; .EHGerman; .EHHungarian; .EHItalian; .EHKorean; .EHPolish; .EHPortuguese; .EHRussian; .EHSpanish; .EHThai; .EHVietnamese; .EHSpeechless; .EHOther' + extVersionCode = 5 libVersion = '1.2' } diff --git a/src/all/ehentai/src/eu/kanade/tachiyomi/extension/all/ehentai/EHLangs.kt b/src/all/ehentai/src/eu/kanade/tachiyomi/extension/all/ehentai/EHLangs.kt index ab662ff4c..d9bda785f 100644 --- a/src/all/ehentai/src/eu/kanade/tachiyomi/extension/all/ehentai/EHLangs.kt +++ b/src/all/ehentai/src/eu/kanade/tachiyomi/extension/all/ehentai/EHLangs.kt @@ -3,23 +3,23 @@ package eu.kanade.tachiyomi.extension.all.ehentai /** * E-Hentai languages */ -class EHJapanese: EHentai("ja", "japanese") -class EHEnglish: EHentai("en", "english") -class EHChinese: EHentai("zh", "chinese") -class EHDutch: EHentai("nl", "dutch") -class EHFrench: EHentai("fr", "french") -class EHGerman: EHentai("de", "german") -class EHHungarian: EHentai("hu", "hungarian") -class EHItalian: EHentai("it", "italian") -class EHKorean: EHentai("ko", "korean") -class EHPolish: EHentai("pl", "polish") -class EHPortuguese: EHentai("pt", "portuguese") -class EHRussian: EHentai("ru", "russian") -class EHSpanish: EHentai("es", "spanish") -class EHThai: EHentai("th", "thai") -class EHVietnamese: EHentai("vi", "vietnamese") -class EHSpeechless: EHentai("none", "n/a") -class EHOther: EHentai("other", "other") +class EHJapanese : EHentai("ja", "japanese") +class EHEnglish : EHentai("en", "english") +class EHChinese : EHentai("zh", "chinese") +class EHDutch : EHentai("nl", "dutch") +class EHFrench : EHentai("fr", "french") +class EHGerman : EHentai("de", "german") +class EHHungarian : EHentai("hu", "hungarian") +class EHItalian : EHentai("it", "italian") +class EHKorean : EHentai("ko", "korean") +class EHPolish : EHentai("pl", "polish") +class EHPortuguese : EHentai("pt", "portuguese") +class EHRussian : EHentai("ru", "russian") +class EHSpanish : EHentai("es", "spanish") +class EHThai : EHentai("th", "thai") +class EHVietnamese : EHentai("vi", "vietnamese") +class EHSpeechless : EHentai("none", "n/a") +class EHOther : EHentai("other", "other") fun getAllEHentaiLanguages() = listOf( EHJapanese(), diff --git a/src/all/ehentai/src/eu/kanade/tachiyomi/extension/all/ehentai/EHUtil.kt b/src/all/ehentai/src/eu/kanade/tachiyomi/extension/all/ehentai/EHUtil.kt index 794113b8f..8db29e4ce 100644 --- a/src/all/ehentai/src/eu/kanade/tachiyomi/extension/all/ehentai/EHUtil.kt +++ b/src/all/ehentai/src/eu/kanade/tachiyomi/extension/all/ehentai/EHUtil.kt @@ -1,5 +1,8 @@ package eu.kanade.tachiyomi.extension.all.ehentai +import kotlin.math.ln +import kotlin.math.pow + /** * Various utility methods used in the E-Hentai source */ @@ -36,18 +39,18 @@ operator fun StringBuilder.plusAssign(other: String) { */ fun humanReadableByteCount(bytes: Long, si: Boolean): String { val unit = if (si) 1000 else 1024 - if (bytes < unit) return bytes.toString() + " B" - val exp = (Math.log(bytes.toDouble()) / Math.log(unit.toDouble())).toInt() + if (bytes < unit) return "$bytes B" + val exp = (ln(bytes.toDouble()) / ln(unit.toDouble())).toInt() val pre = (if (si) "kMGTPE" else "KMGTPE")[exp - 1] + if (si) "" else "i" - return String.format("%.1f %sB", bytes / Math.pow(unit.toDouble(), exp.toDouble()), pre) + return String.format("%.1f %sB", bytes / unit.toDouble().pow(exp.toDouble()), pre) } -private val KB_FACTOR = 1000 -private val KIB_FACTOR = 1024 -private val MB_FACTOR = 1000 * KB_FACTOR -private val MIB_FACTOR = 1024 * KIB_FACTOR -private val GB_FACTOR = 1000 * MB_FACTOR -private val GIB_FACTOR = 1024 * MIB_FACTOR +private const val KB_FACTOR = 1000 +private const val KIB_FACTOR = 1024 +private const val MB_FACTOR = 1000 * KB_FACTOR +private const val MIB_FACTOR = 1024 * KIB_FACTOR +private const val GB_FACTOR = 1000 * MB_FACTOR +private const val GIB_FACTOR = 1024 * MIB_FACTOR /** * Parse human readable size Strings @@ -64,4 +67,4 @@ fun parseHumanReadableByteCount(arg0: String): Double? { "KiB" -> return ret * KIB_FACTOR } return null -} \ No newline at end of file +} diff --git a/src/all/ehentai/src/eu/kanade/tachiyomi/extension/all/ehentai/EHentai.kt b/src/all/ehentai/src/eu/kanade/tachiyomi/extension/all/ehentai/EHentai.kt index fc11cf2d5..f9b5299c4 100644 --- a/src/all/ehentai/src/eu/kanade/tachiyomi/extension/all/ehentai/EHentai.kt +++ b/src/all/ehentai/src/eu/kanade/tachiyomi/extension/all/ehentai/EHentai.kt @@ -3,24 +3,15 @@ package eu.kanade.tachiyomi.extension.all.ehentai import android.net.Uri import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.asObservableSuccess -import eu.kanade.tachiyomi.source.model.Filter -import eu.kanade.tachiyomi.source.model.FilterList -import eu.kanade.tachiyomi.source.model.MangasPage -import eu.kanade.tachiyomi.source.model.Page -import eu.kanade.tachiyomi.source.model.SChapter -import eu.kanade.tachiyomi.source.model.SManga +import eu.kanade.tachiyomi.source.model.* import eu.kanade.tachiyomi.source.online.HttpSource import eu.kanade.tachiyomi.util.asJsoup -import okhttp3.CacheControl -import okhttp3.CookieJar -import okhttp3.Headers -import okhttp3.Request -import okhttp3.Response +import okhttp3.* import org.jsoup.nodes.Element import rx.Observable import java.net.URLEncoder -open class EHentai(override val lang: String, val ehLang: String) : HttpSource() { +open class EHentai(override val lang: String, private val ehLang: String) : HttpSource() { override val name = "E-Hentai" @@ -51,15 +42,13 @@ open class EHentai(override val lang: String, val ehLang: String) : HttpSource() return MangasPage(parsedMangas, hasNextPage) } - override fun fetchChapterList(manga: SManga): Observable> - = Observable.just(listOf(SChapter.create().apply { + override fun fetchChapterList(manga: SManga): Observable> = Observable.just(listOf(SChapter.create().apply { url = manga.url name = "Chapter" chapter_number = 1f })) - override fun fetchPageList(chapter: SChapter) - = fetchChapterPage(chapter, "$baseUrl/${chapter.url}").map { + override fun fetchPageList(chapter: SChapter) = fetchChapterPage(chapter, "$baseUrl/${chapter.url}").map { it.mapIndexed { i, s -> Page(i, s) } @@ -80,8 +69,7 @@ open class EHentai(override val lang: String, val ehLang: String) : HttpSource() } } - private fun parseChapterPage(response: Element) - = with(response) { + private fun parseChapterPage(response: Element) = with(response) { select(".gdtm a").map { Pair(it.child(0).attr("alt").toInt(), it.attr("href")) }.sortedBy(Pair::first).map { it.second } @@ -90,8 +78,7 @@ open class EHentai(override val lang: String, val ehLang: String) : HttpSource() private fun chapterPageCall(np: String) = client.newCall(chapterPageRequest(np)).asObservableSuccess() private fun chapterPageRequest(np: String) = exGet(np, null, headers) - private fun nextPageUrl(element: Element) - = element.select("a[onclick=return false]").last()?.let { + private fun nextPageUrl(element: Element) = element.select("a[onclick=return false]").last()?.let { if (it.text() == ">") it.attr("href") else null } @@ -115,8 +102,7 @@ open class EHentai(override val lang: String, val ehLang: String) : HttpSource() override fun searchMangaParse(response: Response) = genericMangaParse(response) override fun latestUpdatesParse(response: Response) = genericMangaParse(response) - private fun exGet(url: String, page: Int? = null, additionalHeaders: Headers? = null, cache: Boolean = true) - = GET(page?.let { + private fun exGet(url: String, page: Int? = null, additionalHeaders: Headers? = null, cache: Boolean = true) = GET(page?.let { addParam(url, "page", (it - 1).toString()) } ?: url, additionalHeaders?.let { val headers = headers.newBuilder() @@ -204,7 +190,7 @@ open class EHentai(override val lang: String, val ehLang: String) : HttpSource() Tag(it.text().trim(), it.hasClass("gtl")) } - tags.put(namespace, currentTags) + tags[namespace] = currentTags } //Copy metadata to manga @@ -214,19 +200,15 @@ open class EHentai(override val lang: String, val ehLang: String) : HttpSource() } } - override fun chapterListParse(response: Response) - = throw UnsupportedOperationException("Unused method was called somehow!") + override fun chapterListParse(response: Response) = throw UnsupportedOperationException("Unused method was called somehow!") - override fun pageListParse(response: Response) - = throw UnsupportedOperationException("Unused method was called somehow!") + override fun pageListParse(response: Response) = throw UnsupportedOperationException("Unused method was called somehow!") - override fun fetchImageUrl(page: Page) - = client.newCall(imageUrlRequest(page)) + override fun fetchImageUrl(page: Page) = client.newCall(imageUrlRequest(page)) .asObservableSuccess() .map { realImageUrlParse(it, page) }!! - private fun realImageUrlParse(response: Response, page: Page) - = with(response.asJsoup()) { + private fun realImageUrlParse(response: Response, page: Page) = with(response.asJsoup()) { val currentImage = getElementById("img").attr("src") //TODO We cannot currently do this as page.url is immutable //Each press of the retry button will choose another server @@ -236,8 +218,7 @@ open class EHentai(override val lang: String, val ehLang: String) : HttpSource() currentImage }!! - override fun imageUrlParse(response: Response) - = throw UnsupportedOperationException("Unused method was called somehow!") + override fun imageUrlParse(response: Response) = throw UnsupportedOperationException("Unused method was called somehow!") private val cookiesHeader by lazy { val cookies = mutableMapOf() @@ -253,25 +234,21 @@ open class EHentai(override val lang: String, val ehLang: String) : HttpSource() .flatMap { it.second } .joinToString("x") - cookies.put("uconfig", buildSettings(settings)) + cookies["uconfig"] = buildSettings(settings) buildCookies(cookies) } //Headers - override fun headersBuilder() - = super.headersBuilder().add("Cookie", cookiesHeader)!! + override fun headersBuilder() = super.headersBuilder().add("Cookie", cookiesHeader)!! - private fun buildSettings(settings: List) - = settings.filterNotNull().joinToString(separator = "-") + private fun buildSettings(settings: List) = settings.filterNotNull().joinToString(separator = "-") - private fun buildCookies(cookies: Map) - = cookies.entries.map { + private fun buildCookies(cookies: Map) = cookies.entries.joinToString(separator = "; ", postfix = ";") { "${URLEncoder.encode(it.key, "UTF-8")}=${URLEncoder.encode(it.value, "UTF-8")}" - }.joinToString(separator = "; ", postfix = ";") + } - private fun addParam(url: String, param: String, value: String) - = Uri.parse(url) + private fun addParam(url: String, param: String, value: String) = Uri.parse(url) .buildUpon() .appendQueryParameter(param, value) .toString() @@ -295,9 +272,9 @@ open class EHentai(override val lang: String, val ehLang: String) : HttpSource() AdvancedGroup() ) - class GenreOption(name: String, val genreId: String) : Filter.CheckBox(name, false), UriFilter { + class GenreOption(name: String, private val genreId: String) : Filter.CheckBox(name, false), UriFilter { override fun addToUri(builder: Uri.Builder) { - builder.appendQueryParameter("f_" + genreId, if (state) "1" else "0") + builder.appendQueryParameter("f_$genreId", if (state) "1" else "0") } } @@ -314,7 +291,7 @@ open class EHentai(override val lang: String, val ehLang: String) : HttpSource() GenreOption("Misc", "misc") )) - class AdvancedOption(name: String, val param: String, defValue: Boolean = false) : Filter.CheckBox(name, defValue), UriFilter { + class AdvancedOption(name: String, private val param: String, defValue: Boolean = false) : Filter.CheckBox(name, defValue), UriFilter { override fun addToUri(builder: Uri.Builder) { if (state) builder.appendQueryParameter(param, "on") @@ -329,7 +306,7 @@ open class EHentai(override val lang: String, val ehLang: String) : HttpSource() "5 stars" )), UriFilter { override fun addToUri(builder: Uri.Builder) { - if (state > 0) builder.appendQueryParameter("f_srdd", Integer.toString(state + 1)) + if (state > 0) builder.appendQueryParameter("f_srdd", (state + 1).toString()) } } diff --git a/src/all/ehentai/src/eu/kanade/tachiyomi/extension/all/ehentai/ExGalleryMetadata.kt b/src/all/ehentai/src/eu/kanade/tachiyomi/extension/all/ehentai/ExGalleryMetadata.kt index c242c40a0..11c31a773 100644 --- a/src/all/ehentai/src/eu/kanade/tachiyomi/extension/all/ehentai/ExGalleryMetadata.kt +++ b/src/all/ehentai/src/eu/kanade/tachiyomi/extension/all/ehentai/ExGalleryMetadata.kt @@ -1,4 +1,4 @@ -package eu.kanade.tachiyomi.extension.all.ehentai; +package eu.kanade.tachiyomi.extension.all.ehentai import android.net.Uri @@ -32,25 +32,21 @@ class ExGalleryMetadata { val tags: MutableMap> = mutableMapOf() companion object { - private fun splitGalleryUrl(url: String) - = url.let { + private fun splitGalleryUrl(url: String) = url.let { //Only parse URL if is full URL - val pathSegments = if(it.startsWith("http")) + val pathSegments = if (it.startsWith("http")) Uri.parse(it).pathSegments else it.split('/') pathSegments.filterNot(String::isNullOrBlank) } - fun galleryId(url: String) = splitGalleryUrl(url)[1] + private fun galleryId(url: String) = splitGalleryUrl(url)[1] - fun galleryToken(url: String) = - splitGalleryUrl(url)[2] + private fun galleryToken(url: String) = splitGalleryUrl(url)[2] - fun normalizeUrl(id: String, token: String) - = "/g/$id/$token/?nw=always" + private fun normalizeUrl(id: String, token: String) = "/g/$id/$token/?nw=always" - fun normalizeUrl(url: String) - = normalizeUrl(galleryId(url), galleryToken(url)) + fun normalizeUrl(url: String) = normalizeUrl(galleryId(url), galleryToken(url)) } } diff --git a/src/all/ehentai/src/eu/kanade/tachiyomi/extension/all/ehentai/MetadataCopier.kt b/src/all/ehentai/src/eu/kanade/tachiyomi/extension/all/ehentai/MetadataCopier.kt index 298a71b99..4bcd37e3c 100644 --- a/src/all/ehentai/src/eu/kanade/tachiyomi/extension/all/ehentai/MetadataCopier.kt +++ b/src/all/ehentai/src/eu/kanade/tachiyomi/extension/all/ehentai/MetadataCopier.kt @@ -37,8 +37,8 @@ fun ExGalleryMetadata.copyTo(manga: SManga) { manga.status = SManga.COMPLETED title?.let { t -> if (ONGOING_SUFFIX.any { - t.endsWith(it, ignoreCase = true) - }) manga.status = SManga.ONGOING + t.endsWith(it, ignoreCase = true) + }) manga.status = SManga.ONGOING } //Build a nice looking description out of what we know @@ -71,8 +71,7 @@ fun ExGalleryMetadata.copyTo(manga: SManga) { .joinToString(separator = "\n") } -private fun buildTagsDescription(metadata: ExGalleryMetadata) - = StringBuilder("Tags:\n").apply { +private fun buildTagsDescription(metadata: ExGalleryMetadata) = StringBuilder("Tags:\n").apply { //BiConsumer only available in Java 8, we have to use destructuring here metadata.tags.forEach { (namespace, tags) -> if (tags.isNotEmpty()) { diff --git a/src/all/foolslide/build.gradle b/src/all/foolslide/build.gradle index 27130482f..8f3ebd1b1 100644 --- a/src/all/foolslide/build.gradle +++ b/src/all/foolslide/build.gradle @@ -3,9 +3,9 @@ apply plugin: 'kotlin-android' ext { appName = 'Tachiyomi: FoolSlide' - pkgNameSuffix = "all.foolslide" + pkgNameSuffix = 'all.foolslide' extClass = '.FoolSlideFactory' - extVersionCode = 21 + extVersionCode = 22 libVersion = '1.2' } diff --git a/src/all/foolslide/src/eu/kanade/tachiyomi/extension/en/foolslide/FoolSlide.kt b/src/all/foolslide/src/eu/kanade/tachiyomi/extension/all/foolslide/FoolSlide.kt similarity index 90% rename from src/all/foolslide/src/eu/kanade/tachiyomi/extension/en/foolslide/FoolSlide.kt rename to src/all/foolslide/src/eu/kanade/tachiyomi/extension/all/foolslide/FoolSlide.kt index ba1fed725..1fc013034 100644 --- a/src/all/foolslide/src/eu/kanade/tachiyomi/extension/en/foolslide/FoolSlide.kt +++ b/src/all/foolslide/src/eu/kanade/tachiyomi/extension/all/foolslide/FoolSlide.kt @@ -16,7 +16,10 @@ import java.text.SimpleDateFormat import java.util.* -open class FoolSlide(override val name: String, override val baseUrl: String, override val lang: String, val urlModifier: String = "") : ParsedHttpSource() { +open class FoolSlide(override val name: String, + override val baseUrl: String, + override val lang: String, + val urlModifier: String = "") : ParsedHttpSource() { protected open val dedupeLatestUpdates = true @@ -32,7 +35,7 @@ open class FoolSlide(override val name: String, override val baseUrl: String, ov override fun latestUpdatesParse(response: Response): MangasPage { val mp = super.latestUpdatesParse(response) - return if(dedupeLatestUpdates) { + return if (dedupeLatestUpdates) { val mangas = mp.mangas.distinctBy { it.url }.filterNot { latestUpdatesUrls.contains(it.url) } latestUpdatesUrls.addAll(mangas.map { it.url }) MangasPage(mangas, mp.hasNextPage) @@ -96,8 +99,7 @@ open class FoolSlide(override val name: String, override val baseUrl: String, ov override fun searchMangaNextPageSelector() = "a:has(span.next)" - override fun mangaDetailsRequest(manga: SManga) - = allowAdult(super.mangaDetailsRequest(manga)) + override fun mangaDetailsRequest(manga: SManga) = allowAdult(super.mangaDetailsRequest(manga)) open val mangaDetailsInfoSelector = "div.info" open val mangaDetailsThumbnailSelector = "div.thumbnail img" @@ -119,14 +121,13 @@ open class FoolSlide(override val name: String, override val baseUrl: String, ov */ private fun allowAdult(request: Request) = allowAdult(request.url().toString()) - protected fun allowAdult(url: String): Request { + private fun allowAdult(url: String): Request { return POST(url, body = FormBody.Builder() .add("adult", "true") .build()) } - override fun chapterListRequest(manga: SManga) - = allowAdult(super.chapterListRequest(manga)) + override fun chapterListRequest(manga: SManga) = allowAdult(super.chapterListRequest(manga)) override fun chapterListSelector() = "div.group div.element, div.list div.element" @@ -140,7 +141,8 @@ open class FoolSlide(override val name: String, override val baseUrl: String, ov val chapter = SChapter.create() chapter.setUrlWithoutDomain(urlElement.attr("href")) chapter.name = urlElement.text() - chapter.date_upload = dateElement.text()?.let { parseChapterDate(it.substringAfter(", ")) } ?: 0 + chapter.date_upload = dateElement.text()?.let { parseChapterDate(it.substringAfter(", ")) } + ?: 0 return chapter } @@ -172,18 +174,18 @@ open class FoolSlide(override val name: String, override val baseUrl: String, ov var result = DATE_FORMAT_1.parseOrNull(date) - for(dateFormat in DATE_FORMATS_WITH_ORDINAL_SUFFIXES) { + for (dateFormat in DATE_FORMATS_WITH_ORDINAL_SUFFIXES) { if (result == null) result = dateFormat.parseOrNull(date) else break } - for(dateFormat in DATE_FORMATS_WITH_ORDINAL_SUFFIXES_NO_YEAR) { + for (dateFormat in DATE_FORMATS_WITH_ORDINAL_SUFFIXES_NO_YEAR) { if (result == null) { result = dateFormat.parseOrNull(date) - if(result != null) { + if (result != null) { // Result parsed but no year, copy current year over result = Calendar.getInstance().apply { time = result @@ -230,13 +232,12 @@ open class FoolSlide(override val name: String, override val baseUrl: String, ov private fun SimpleDateFormat.parseOrNull(string: String): Date? { return try { parse(string) - } catch(e: ParseException) { + } catch (e: ParseException) { null } } - override fun pageListRequest(chapter: SChapter) - = allowAdult(super.pageListRequest(chapter)) + override fun pageListRequest(chapter: SChapter) = allowAdult(super.pageListRequest(chapter)) override fun pageListParse(document: Document): List { val doc = document.toString() @@ -266,4 +267,4 @@ open class FoolSlide(override val name: String, override val baseUrl: String, ov SimpleDateFormat("dd'$it' MMMM", Locale.US) } } -} \ No newline at end of file +} diff --git a/src/all/foolslide/src/eu/kanade/tachiyomi/extension/en/foolslide/FoolSlideFactory.kt b/src/all/foolslide/src/eu/kanade/tachiyomi/extension/all/foolslide/FoolSlideFactory.kt similarity index 82% rename from src/all/foolslide/src/eu/kanade/tachiyomi/extension/en/foolslide/FoolSlideFactory.kt rename to src/all/foolslide/src/eu/kanade/tachiyomi/extension/all/foolslide/FoolSlideFactory.kt index 898ba1073..651d15859 100644 --- a/src/all/foolslide/src/eu/kanade/tachiyomi/extension/en/foolslide/FoolSlideFactory.kt +++ b/src/all/foolslide/src/eu/kanade/tachiyomi/extension/all/foolslide/FoolSlideFactory.kt @@ -6,7 +6,8 @@ import com.google.gson.JsonParser import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.source.Source import eu.kanade.tachiyomi.source.SourceFactory -import eu.kanade.tachiyomi.source.model.* +import eu.kanade.tachiyomi.source.model.Page +import eu.kanade.tachiyomi.source.model.SManga import okhttp3.Request import org.jsoup.nodes.Document import org.jsoup.nodes.Element @@ -17,34 +18,33 @@ class FoolSlideFactory : SourceFactory { fun getAllFoolSlide(): List { return listOf( - JaminisBox(), - HelveticaScans(), - SenseScans(), - KireiCake(), - SilentSky(), - Mangatellers(), - IskultripScans(), - AnataNoMotokare(), - DeathTollScans(), - DKThias(), - WorldThree(), - DokiFansubs(), - YuriIsm(), - AjiaNoScantrad(), - OneTimeScans(), - TsubasaSociety(), - MangaScouts(), - StormInHeaven(), - Lilyreader(), - MidnightHaven(), - Russification(), - EvilFlowers(), - AkaiYuhiMunTeam(), - LupiTeam(), - HentaiCafe(), - ShoujoSense(), - TheCatScans(), - ShoujoHearts() + JaminisBox(), + HelveticaScans(), + SenseScans(), + KireiCake(), + SilentSky(), + Mangatellers(), + IskultripScans(), + AnataNoMotokare(), + DeathTollScans(), + DKThias(), + WorldThree(), + DokiFansubs(), + YuriIsm(), + AjiaNoScantrad(), + OneTimeScans(), + TsubasaSociety(), + MangaScouts(), + StormInHeaven(), + Lilyreader(), + Russification(), + EvilFlowers(), + AkaiYuhiMunTeam(), + LupiTeam(), + HentaiCafe(), + ShoujoSense(), + TheCatScans(), + ShoujoHearts() ) } @@ -74,7 +74,7 @@ class SenseScans : FoolSlide("Sense-Scans", "https://sensescans.com", "en", "/re class KireiCake : FoolSlide("Kirei Cake", "https://reader.kireicake.com", "en") -class SilentSky : FoolSlide("Silent Sky", "http://reader.silentsky-scans.net", "en") +class SilentSky : FoolSlide("Silent Sky", "https://reader.silentsky-scans.net", "en") class Mangatellers : FoolSlide("Mangatellers", "http://www.mangatellers.gr", "en", "/reader/reader") { override fun popularMangaRequest(page: Int): Request { @@ -108,12 +108,10 @@ class TsubasaSociety : FoolSlide("Tsubasa Society", "https://www.tsubasasociety. class MangaScouts : FoolSlide("MangaScouts", "http://onlinereader.mangascouts.org", "de") -class StormInHeaven : FoolSlide("Storm in Heaven", "http://www.storm-in-heaven.net", "it", "/reader-sih") +class StormInHeaven : FoolSlide("Storm in Heaven", "https://www.storm-in-heaven.net", "it", "/reader-sih") class Lilyreader : FoolSlide("Lilyreader", "https://manga.smuglo.li", "en") -class MidnightHaven : FoolSlide("Midnight Haven", "http://midnighthaven.shounen-ai.net", "en", "/reader") - class Russification : FoolSlide("Русификация", "https://rusmanga.ru", "ru") class EvilFlowers : FoolSlide("Evil Flowers", "http://reader.evilflowers.com", "en") @@ -158,5 +156,3 @@ class ShoujoHearts : FoolSlide("ShoujoHearts", "http://shoujohearts.com", "en", return manga } } - - diff --git a/src/all/foolslide/src/eu/kanade/tachiyomi/extension/en/foolslide/HentaiCafe.kt b/src/all/foolslide/src/eu/kanade/tachiyomi/extension/all/foolslide/HentaiCafe.kt similarity index 92% rename from src/all/foolslide/src/eu/kanade/tachiyomi/extension/en/foolslide/HentaiCafe.kt rename to src/all/foolslide/src/eu/kanade/tachiyomi/extension/all/foolslide/HentaiCafe.kt index d0a0e4076..fd87ac9d3 100644 --- a/src/all/foolslide/src/eu/kanade/tachiyomi/extension/en/foolslide/HentaiCafe.kt +++ b/src/all/foolslide/src/eu/kanade/tachiyomi/extension/all/foolslide/HentaiCafe.kt @@ -63,7 +63,7 @@ class HentaiCafe : FoolSlide("Hentai Cafe", "https://hentai.cafe", "en", "/manga } filters.findInstance()?.let { f -> - if(f.state.isNotBlank()) { + if (f.state.isNotBlank()) { requireNoUrl() url = "/artist/${f.state .trim() @@ -72,19 +72,19 @@ class HentaiCafe : FoolSlide("Hentai Cafe", "https://hentai.cafe", "en", "/manga } } filters.findInstance()?.let { f -> - if(f.state) { + if (f.state) { requireNoUrl() url = "/category/book/" } } filters.findInstance()?.let { f -> - if(f.state != 0) { + if (f.state != 0) { requireNoUrl() url = "/tag/${f.values[f.state].name}/" } } - if(query.isNotBlank()) { + if (query.isNotBlank()) { requireNoUrl() url = "/" queryString = "s=" + URLEncoder.encode(query, "UTF-8") @@ -97,8 +97,8 @@ class HentaiCafe : FoolSlide("Hentai Cafe", "https://hentai.cafe", "en", "/manga private fun pagedRequest(url: String, page: Int, queryString: String? = null): Request { // The site redirects page 1 -> url-without-page so we do this redirect early for optimization - val builtUrl = if(page == 1) url else "${url}page/$page/" - return GET(if(queryString != null) "$builtUrl?$queryString" else builtUrl) + val builtUrl = if (page == 1) url else "${url}page/$page/" + return GET(if (queryString != null) "$builtUrl?$queryString" else builtUrl) } override fun searchMangaParse(response: Response) = latestUpdatesParse(response) @@ -106,7 +106,7 @@ class HentaiCafe : FoolSlide("Hentai Cafe", "https://hentai.cafe", "en", "/manga override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable { return client.newCall(searchMangaRequest(page, query, filters)) .asObservable().doOnNext { response -> - if(!response.isSuccessful) { + if (!response.isSuccessful) { response.close() // Better error message for invalid artist if (response.code() == 404 @@ -132,7 +132,6 @@ class HentaiCafe : FoolSlide("Hentai Cafe", "https://hentai.cafe", "en", "/manga class ArtistFilter : Filter.Text("Artist (must be exact match)") class BookFilter : Filter.CheckBox("Show books only", false) class TagFilter : Filter.Select("Tag", arrayOf( - Tag("all", "All"), Tag("ahegao", "Ahegao"), Tag("anal", "Anal"), Tag("big-ass", "Big ass"), @@ -155,9 +154,9 @@ class HentaiCafe : FoolSlide("Hentai Cafe", "https://hentai.cafe", "en", "/manga Tag("group", "Group"), Tag("hairy", "Hairy"), Tag("handjob", "Handjob"), + Tag("heart-pupils", "Heart pupils"), Tag("housewife", "Housewife"), Tag("incest", "Incest"), - Tag("large-breast", "Large breast"), Tag("lingerie", "Lingerie"), Tag("loli", "Loli"), Tag("masturbation", "Masturbation"), @@ -167,7 +166,7 @@ class HentaiCafe : FoolSlide("Hentai Cafe", "https://hentai.cafe", "en", "/manga Tag("pettanko", "Pettanko"), Tag("rape", "Rape"), Tag("schoolgirl", "Schoolgirl"), - Tag("sex-toys", "Sex Toys"), + Tag("sex-toys", "Sex toys"), Tag("shota", "Shota"), Tag("socks", "Socks"), Tag("stocking", "Stocking"), @@ -175,11 +174,12 @@ class HentaiCafe : FoolSlide("Hentai Cafe", "https://hentai.cafe", "en", "/manga Tag("swimsuit", "Swimsuit"), Tag("teacher", "Teacher"), Tag("tsundere", "Tsundere"), - Tag("uncensored", "uncensored"), + Tag("uncensored", "Uncensored"), Tag("vanilla", "Vanilla"), - Tag("x-ray", "X-ray") + Tag("x-ray", "X-Ray") )) - class Tag(val name: String, val displayName: String) { + + class Tag(val name: String, private val displayName: String) { override fun toString() = displayName } @@ -189,4 +189,4 @@ class HentaiCafe : FoolSlide("Hentai Cafe", "https://hentai.cafe", "en", "/manga } } -private inline fun Iterable<*>.findInstance() = find { it is T } as? T \ No newline at end of file +private inline fun Iterable<*>.findInstance() = find { it is T } as? T diff --git a/src/all/genkan/build.gradle b/src/all/genkan/build.gradle index 495cfbfa5..3ec1425cc 100644 --- a/src/all/genkan/build.gradle +++ b/src/all/genkan/build.gradle @@ -5,7 +5,7 @@ ext { appName = 'Tachiyomi: Genkan (multiple sources)' pkgNameSuffix = 'all.genkan' extClass = '.GenkanFactory' - extVersionCode = 2 + extVersionCode = 3 libVersion = '1.2' } diff --git a/src/all/genkan/src/eu/kanade/tachiyomi/extension/all/genkan/Genkan.kt b/src/all/genkan/src/eu/kanade/tachiyomi/extension/all/genkan/Genkan.kt index 5d1c2973d..6d267fc74 100644 --- a/src/all/genkan/src/eu/kanade/tachiyomi/extension/all/genkan/Genkan.kt +++ b/src/all/genkan/src/eu/kanade/tachiyomi/extension/all/genkan/Genkan.kt @@ -14,9 +14,9 @@ import java.text.SimpleDateFormat import java.util.* abstract class Genkan( - override val name: String, - override val baseUrl: String, - override val lang: String + override val name: String, + final override val baseUrl: String, + override val lang: String ) : ParsedHttpSource() { override val supportsLatest = true @@ -27,7 +27,7 @@ abstract class Genkan( private val popularMangaUrl = "$baseUrl/comics?page=" // Search is also based off this val override fun popularMangaRequest(page: Int): Request { - return GET("$popularMangaUrl$page") + return GET("$popularMangaUrl$page") } override fun latestUpdatesSelector() = popularMangaSelector() @@ -36,8 +36,8 @@ abstract class Genkan( private val latestUpdatesTitles = mutableSetOf() override fun latestUpdatesRequest(page: Int): Request { - if (page == 1) latestUpdatesTitles.clear() - return GET("$baseUrl/latest?page=$page") + if (page == 1) latestUpdatesTitles.clear() + return GET("$baseUrl/latest?page=$page") } // To prevent dupes @@ -165,10 +165,10 @@ abstract class Genkan( // If the date string contains the word "ago" send it off for relative date parsing otherwise use dateFormat private fun parseChapterDate(string: String): Long? { - if ("ago" in string) { - return parseRelativeDate(string) ?: 0 + return if ("ago" in string) { + parseRelativeDate(string) ?: 0 } else { - return dateFormat.parse(string).time + dateFormat.parse(string).time } } @@ -177,14 +177,14 @@ abstract class Genkan( val trimmedDate = date.substringBefore(" ago").removeSuffix("s").split(" ") val calendar = Calendar.getInstance() - when (trimmedDate[1]){ - "month" -> calendar.apply{add(Calendar.MONTH, -trimmedDate[0].toInt())} - "week" -> calendar.apply{add(Calendar.WEEK_OF_MONTH, -trimmedDate[0].toInt())} - "day" -> calendar.apply{add(Calendar.DAY_OF_MONTH, -trimmedDate[0].toInt())} - "hour" -> calendar.apply{add(Calendar.HOUR_OF_DAY, -trimmedDate[0].toInt())} - "minute" -> calendar.apply{add(Calendar.MINUTE, -trimmedDate[0].toInt())} - "second" -> calendar.apply{add(Calendar.SECOND, 0)} - } + when (trimmedDate[1]) { + "month" -> calendar.apply { add(Calendar.MONTH, -trimmedDate[0].toInt()) } + "week" -> calendar.apply { add(Calendar.WEEK_OF_MONTH, -trimmedDate[0].toInt()) } + "day" -> calendar.apply { add(Calendar.DAY_OF_MONTH, -trimmedDate[0].toInt()) } + "hour" -> calendar.apply { add(Calendar.HOUR_OF_DAY, -trimmedDate[0].toInt()) } + "minute" -> calendar.apply { add(Calendar.MINUTE, -trimmedDate[0].toInt()) } + "second" -> calendar.apply { add(Calendar.SECOND, 0) } + } return calendar.timeInMillis } @@ -192,10 +192,10 @@ abstract class Genkan( override fun pageListParse(document: Document): List { val pages = mutableListOf() - val allImages = document.select("div#pages-container + script").first().data() - .substringAfter("[").substringBefore("];") - .replace(Regex("""["\\]"""), "") - .split(",") + val allImages = document.select("div#pages-container + script").first().data() + .substringAfter("[").substringBefore("];") + .replace(Regex("""["\\]"""), "") + .split(",") for (i in 0 until allImages.size) { pages.add(Page(i, "", allImages[i])) @@ -207,5 +207,4 @@ abstract class Genkan( override fun imageUrlParse(document: Document): String = throw UnsupportedOperationException("Not used") override fun getFilterList() = FilterList() - } diff --git a/src/all/genkan/src/eu/kanade/tachiyomi/extension/all/genkan/GenkanFactory.kt b/src/all/genkan/src/eu/kanade/tachiyomi/extension/all/genkan/GenkanFactory.kt index 214ab211b..f13cca240 100644 --- a/src/all/genkan/src/eu/kanade/tachiyomi/extension/all/genkan/GenkanFactory.kt +++ b/src/all/genkan/src/eu/kanade/tachiyomi/extension/all/genkan/GenkanFactory.kt @@ -5,12 +5,12 @@ import eu.kanade.tachiyomi.source.SourceFactory class GenkanFactory : SourceFactory { override fun createSources(): List = listOf( - LeviatanScans(), - PsychoPlay(), - OneShotScans(), - KaguyaDex(), - KomiScans(), - HunlightScans()) + LeviatanScans(), + PsychoPlay(), + OneShotScans(), + KaguyaDex(), + KomiScans(), + HunlightScans()) } class LeviatanScans : Genkan("Leviatan Scans", "https://leviatanscans.com", "en")