From 40de8b9723f3f775c863a91cb9f346ab9a22f5eb Mon Sep 17 00:00:00 2001 From: Eugene Date: Sun, 27 Oct 2019 15:41:40 -0400 Subject: [PATCH] Misc code cleanup --- src/all/comicake/build.gradle | 2 +- .../extension/all/comicake/ComiCake.kt | 33 +- .../extension/all/comicake/ComiCakeFactory.kt | 16 +- src/all/fmreader/build.gradle | 2 +- .../extension/all/fmreader/FMReader.kt | 38 +- .../extension/all/fmreader/FMReaderFactory.kt | 58 ++- src/all/foolslide/build.gradle | 2 +- .../extension/all/foolslide/FoolSlide.kt | 34 +- .../all/foolslide/FoolSlideFactory.kt | 58 ++- .../extension/all/foolslide/HentaiCafe.kt | 150 ++++---- src/all/genkan/build.gradle | 2 +- .../tachiyomi/extension/all/genkan/Genkan.kt | 34 +- .../extension/all/genkan/GenkanFactory.kt | 16 +- src/all/madara/build.gradle | 2 +- .../tachiyomi/extension/all/madara/Madara.kt | 98 ++--- .../extension/all/madara/MadaraFactory.kt | 38 +- src/all/mangacards/build.gradle | 2 +- .../extension/all/mangacards/MangaCards.kt | 18 +- .../all/mangacards/MangaCardsFactory.kt | 1 - src/all/mangadex/build.gradle | 2 +- .../extension/all/mangadex/Mangadex.kt | 342 +++++++++--------- .../extension/all/mangadex/MangadexFactory.kt | 80 +++- .../all/mangadex/MangadexLanguages.kt | 84 ----- .../all/mangadex/MangadexUrlActivity.kt | 3 +- src/all/mangadventure/build.gradle | 2 +- .../all/mangadventure/MangAdventure.kt | 2 +- .../mangadventure/MangAdventureActivity.kt | 4 +- .../all/mangadventure/MangAdventureFactory.kt | 35 +- src/all/mangatensei/build.gradle | 2 +- .../extension/all/mangatensei/Mangatensei.kt | 200 +++++----- .../all/mangatensei/MangatenseiFactory.kt | 53 ++- .../all/mangatensei/MangatenseiLanguages.kt | 55 --- 32 files changed, 777 insertions(+), 691 deletions(-) delete mode 100644 src/all/mangadex/src/eu/kanade/tachiyomi/extension/all/mangadex/MangadexLanguages.kt delete mode 100644 src/all/mangatensei/src/eu/kanade/tachiyomi/extension/all/mangatensei/MangatenseiLanguages.kt diff --git a/src/all/comicake/build.gradle b/src/all/comicake/build.gradle index fc266a19e..e19bf8575 100644 --- a/src/all/comicake/build.gradle +++ b/src/all/comicake/build.gradle @@ -5,7 +5,7 @@ ext { appName = 'Tachiyomi: ComiCake' pkgNameSuffix = 'all.comicake' extClass = '.ComiCakeFactory' - extVersionCode = 6 + extVersionCode = 7 libVersion = '1.2' } diff --git a/src/all/comicake/src/eu/kanade/tachiyomi/extension/all/comicake/ComiCake.kt b/src/all/comicake/src/eu/kanade/tachiyomi/extension/all/comicake/ComiCake.kt index 108587cbb..8b1a0da35 100644 --- a/src/all/comicake/src/eu/kanade/tachiyomi/extension/all/comicake/ComiCake.kt +++ b/src/all/comicake/src/eu/kanade/tachiyomi/extension/all/comicake/ComiCake.kt @@ -1,9 +1,13 @@ package eu.kanade.tachiyomi.extension.all.comicake import android.os.Build -import eu.kanade.tachiyomi.extension.BuildConfig +import eu.kanade.tachiyomi.extensions.BuildConfig import eu.kanade.tachiyomi.network.GET -import eu.kanade.tachiyomi.source.model.* +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.online.HttpSource import okhttp3.Headers import okhttp3.Request @@ -12,23 +16,22 @@ import org.json.JSONArray import org.json.JSONObject import java.text.SimpleDateFormat -const val COMICAKE_DEFAULT_API_ENDPOINT = "/api" // Highly unlikely to change -const val COMICAKE_DEFAULT_READER_ENDPOINT = "/r" // Can change based on CC config +abstract 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() { -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 private var apiBase = baseUrl + apiEndpoint - private val userAgent = "Mozilla/5.0 (" + - "Android ${Build.VERSION.RELEASE}; Mobile) " + - "Tachiyomi/${BuildConfig.VERSION_NAME}" + "Android ${Build.VERSION.RELEASE}; Mobile) " + + "Tachiyomi/${BuildConfig.VERSION_NAME}" override fun headersBuilder() = Headers.Builder().apply { add("User-Agent", userAgent) @@ -69,6 +72,7 @@ open class ComiCake(override val name: String, mangas.add(parseComicJson(obj)) } } + return MangasPage(mangas, !(response.getString("next").isNullOrEmpty() || response.getString("next") == "null")) } @@ -156,4 +160,9 @@ open class ComiCake(override val name: String, } override fun imageUrlParse(response: Response) = throw UnsupportedOperationException("This method should not be called!") + + companion object { + private const val COMICAKE_DEFAULT_API_ENDPOINT = "/api" // Highly unlikely to change + private const val COMICAKE_DEFAULT_READER_ENDPOINT = "/r" // Can change based on CC config + } } diff --git a/src/all/comicake/src/eu/kanade/tachiyomi/extension/all/comicake/ComiCakeFactory.kt b/src/all/comicake/src/eu/kanade/tachiyomi/extension/all/comicake/ComiCakeFactory.kt index 081bbcda6..34541018e 100644 --- a/src/all/comicake/src/eu/kanade/tachiyomi/extension/all/comicake/ComiCakeFactory.kt +++ b/src/all/comicake/src/eu/kanade/tachiyomi/extension/all/comicake/ComiCakeFactory.kt @@ -4,19 +4,13 @@ import eu.kanade.tachiyomi.source.Source import eu.kanade.tachiyomi.source.SourceFactory class ComiCakeFactory : SourceFactory { - override fun createSources(): List = getAllComiCake() -} - -fun getAllComiCake(): List { - return listOf( - WhimSubs(), + override fun createSources(): List = listOf( + LetItGoScans(), PTScans(), - LetItGoScans() + WhimSubs() ) } -class WhimSubs : ComiCake("WhimSubs", "https://whimsubs.xyz", "en") - -class PTScans : ComiCake("ProjectTime Scans", "https://read.ptscans.com", "en", "/") - class LetItGoScans : ComiCake("LetItGo Scans", "https://reader.letitgo.scans.today", "en", "/") +class PTScans : ComiCake("ProjectTime Scans", "https://read.ptscans.com", "en", "/") +class WhimSubs : ComiCake("WhimSubs", "https://whimsubs.xyz", "en") diff --git a/src/all/fmreader/build.gradle b/src/all/fmreader/build.gradle index 5fe23fd40..3e27ec1fe 100644 --- a/src/all/fmreader/build.gradle +++ b/src/all/fmreader/build.gradle @@ -5,7 +5,7 @@ ext { appName = 'Tachiyomi: FMReader (multiple aggregators)' pkgNameSuffix = 'all.fmreader' extClass = '.FMReaderFactory' - extVersionCode = 2 + extVersionCode = 3 libVersion = '1.2' } diff --git a/src/all/fmreader/src/eu/kanade/tachiyomi/extension/all/fmreader/FMReader.kt b/src/all/fmreader/src/eu/kanade/tachiyomi/extension/all/fmreader/FMReader.kt index 73dc63516..39235d33a 100644 --- a/src/all/fmreader/src/eu/kanade/tachiyomi/extension/all/fmreader/FMReader.kt +++ b/src/all/fmreader/src/eu/kanade/tachiyomi/extension/all/fmreader/FMReader.kt @@ -1,17 +1,27 @@ package eu.kanade.tachiyomi.extension.all.fmreader -// For sites based on the Flat-Manga CMS - import eu.kanade.tachiyomi.network.GET -import eu.kanade.tachiyomi.source.model.* +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.online.ParsedHttpSource +import eu.kanade.tachiyomi.util.asJsoup +import okhttp3.Headers +import okhttp3.HttpUrl +import okhttp3.OkHttpClient +import okhttp3.Request +import okhttp3.Response import org.jsoup.nodes.Document import org.jsoup.nodes.Element -import eu.kanade.tachiyomi.util.asJsoup -import okhttp3.* -import java.util.* +import java.util.Calendar -abstract class FMReader ( +/** + * For sites based on the Flat-Manga CMS + */ +abstract class FMReader( override val name: String, override val baseUrl: String, override val lang: String @@ -43,10 +53,8 @@ abstract class FMReader ( } is TextField -> url.addQueryParameter(filter.key, filter.state) is GenreList -> { - var genre = String() var ungenre = String() - filter.state.forEach { if (it.isIncluded()) genre += ",${it.name}" if (it.isExcluded()) ungenre += ",${it.name}" @@ -79,7 +87,7 @@ abstract class FMReader ( val mangas = mutableListOf() var hasNextPage = true - document.select(popularMangaSelector()).map{ mangas.add(popularMangaFromElement(it)) } + document.select(popularMangaSelector()).map { mangas.add(popularMangaFromElement(it)) } // check if there's a next page document.select(popularMangaNextPageSelector()).first().text().split(" ").let { @@ -108,7 +116,7 @@ abstract class FMReader ( manga.setUrlWithoutDomain(it.attr("abs:href")) manga.title = it.text() } - manga.thumbnail_url = element.select("img").let{ + manga.thumbnail_url = element.select("img").let { if (it.hasAttr("src")) { it.attr("abs:src") } else { @@ -160,11 +168,11 @@ abstract class FMReader ( override fun chapterFromElement(element: Element): SChapter { val chapter = SChapter.create() - element.select(chapterUrlSelector).first().let{ + element.select(chapterUrlSelector).first().let { chapter.setUrlWithoutDomain(it.attr("abs:href")) chapter.name = it.text() } - chapter.date_upload = element.select(chapterTimeSelector).let{ if(it.hasText()) parseChapterDate(it.text()) else 0 } + chapter.date_upload = element.select(chapterTimeSelector).let { if (it.hasText()) parseChapterDate(it.text()) else 0 } return chapter } @@ -177,7 +185,7 @@ abstract class FMReader ( private fun parseChapterDate(date: String): Long { val value = date.split(' ')[dateValueIndex].toInt() - val dateWord = date.split(' ')[dateWordIndex].let{ + val dateWord = date.split(' ')[dateWordIndex].let { if (it.contains("(")) { it.substringBefore("(") } else { @@ -227,7 +235,7 @@ abstract class FMReader ( val pages = mutableListOf() document.select("img.chapter-img").forEachIndexed { i, img -> - pages.add(Page(i, "", img.attr("abs:data-src").let{ if (it.isNotEmpty()) it else img.attr("abs:src") })) + pages.add(Page(i, "", img.attr("abs:data-src").let { if (it.isNotEmpty()) it else img.attr("abs:src") })) } return pages } diff --git a/src/all/fmreader/src/eu/kanade/tachiyomi/extension/all/fmreader/FMReaderFactory.kt b/src/all/fmreader/src/eu/kanade/tachiyomi/extension/all/fmreader/FMReaderFactory.kt index 2b29f8ce2..aa0dda462 100644 --- a/src/all/fmreader/src/eu/kanade/tachiyomi/extension/all/fmreader/FMReaderFactory.kt +++ b/src/all/fmreader/src/eu/kanade/tachiyomi/extension/all/fmreader/FMReaderFactory.kt @@ -5,9 +5,17 @@ import eu.kanade.tachiyomi.network.POST import eu.kanade.tachiyomi.network.asObservableSuccess import eu.kanade.tachiyomi.source.Source import eu.kanade.tachiyomi.source.SourceFactory -import eu.kanade.tachiyomi.source.model.* +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.util.asJsoup -import okhttp3.* +import okhttp3.FormBody +import okhttp3.Interceptor +import okhttp3.OkHttpClient +import okhttp3.Request +import okhttp3.Response import org.jsoup.nodes.Document import org.jsoup.nodes.Element import rx.Observable @@ -40,6 +48,7 @@ class FMReaderFactory : SourceFactory { * most likely the fix is to override popularMangaNextPageSelector() */ class LHTranslation : FMReader("LHTranslation", "https://lhtranslation.net", "en") + class MangaHato : FMReader("MangaHato", "https://mangahato.com", "ja") class ManhwaScan : FMReader("ManhwaScan", "https://manhwascan.com", "en") class MangaTiki : FMReader("MangaTiki", "https://mangatiki.com", "ja") @@ -47,16 +56,20 @@ class MangaBone : FMReader("MangaBone", "https://mangabone.com", "en") class YoloManga : FMReader("Yolo Manga", "https://yolomanga.ca", "es") { override fun chapterListSelector() = "div#tab-chapper ~ div#tab-chapper table tr" } + class MangaLeer : FMReader("MangaLeer", "https://mangaleer.com", "es") { override val dateValueIndex = 1 override val dateWordIndex = 2 } + class AiLoveManga : FMReader("AiLoveManga", "https://ailovemanga.com", "vi") { override val requestPath = "danh-sach-truyen.html" // TODO: could add a genre search (different URL paths for genres) override fun getFilterList() = FilterList() + // I don't know why, but I have to override searchMangaRequest to make it work for this source override fun searchMangaRequest(page: Int, query: String, filters: FilterList) = GET("$baseUrl/$requestPath?name=$query&page=$page") + override fun chapterListSelector() = "div#tab-chapper table tr" override fun mangaDetailsParse(document: Document): SManga { val manga = SManga.create() @@ -72,10 +85,12 @@ class AiLoveManga : FMReader("AiLoveManga", "https://ailovemanga.com", "vi") { return manga } } + class ReadComicOnlineOrg : FMReader("ReadComicOnline.org", "https://readcomiconline.org", "en") { override val client: OkHttpClient = network.cloudflareClient.newBuilder() .addInterceptor { requestIntercept(it) } .build() + private fun requestIntercept(chain: Interceptor.Chain): Response { val request = chain.request() val response = chain.proceed(request) @@ -85,46 +100,55 @@ class ReadComicOnlineOrg : FMReader("ReadComicOnline.org", "https://readcomiconl .add("dqh_firewall", "%2F") .build() val cookie = mutableListOf() - response.headers("set-cookie").map{ cookie.add(it.substringBefore(" ")) } + response.headers("set-cookie").map { cookie.add(it.substringBefore(" ")) } headers.newBuilder().add("Cookie", cookie.joinToString { " " }).build() client.newCall(POST(request.url().toString(), headers, body)).execute() } else { response } } + override val requestPath = "comic-list.html" override fun pageListParse(document: Document): List { val pages = mutableListOf() - document.select("div#divImage > select:first-of-type option").forEachIndexed{ i, imgPage -> + document.select("div#divImage > select:first-of-type option").forEachIndexed { i, imgPage -> pages.add(Page(i, imgPage.attr("value"), "")) } return pages.dropLast(1) // last page is a comments page } + override fun imageUrlRequest(page: Page): Request = GET(baseUrl + page.url, headers) override fun imageUrlParse(document: Document): String = document.select("img.chapter-img").attr("abs:src").trim() override fun getGenreList() = getComicsGenreList() } + class MangaWeek : FMReader("MangaWeek", "https://mangaweek.com", "en") class HanaScan : FMReader("HanaScan (RawQQ)", "http://rawqq.com", "ja") { override fun popularMangaNextPageSelector() = "div.col-md-8 button" } + class RawLH : FMReader("RawLH", "https://lhscan.net", "ja") { override fun popularMangaNextPageSelector() = "div.col-md-8 button" } + class Manhwa18 : FMReader("Manhwa18", "https://manhwa18.com", "en") { override fun getGenreList() = getAdultGenreList() } + class TruyenTranhLH : FMReader("TruyenTranhLH", "https://truyentranhlh.net", "vi") { override val requestPath = "danh-sach-truyen.html" } + class EighteenLHPlus : FMReader("18LHPlus", "https://18lhplus.com", "en") { override fun getGenreList() = getAdultGenreList() } + class MangaTR : FMReader("Manga-TR", "https://manga-tr.com", "tr") { override fun popularMangaNextPageSelector() = "div.btn-group:not(div.btn-block) button.btn-info" // TODO: genre search possible but a bit of a pain override fun getFilterList() = FilterList() + override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request = GET("$baseUrl/arama.html?icerik=$query", headers) override fun searchMangaParse(response: Response): MangasPage { val mangas = mutableListOf() @@ -135,6 +159,7 @@ class MangaTR : FMReader("Manga-TR", "https://manga-tr.com", "tr") { return MangasPage(mangas, false) } + override fun searchMangaFromElement(element: Element): SManga { val manga = SManga.create() @@ -143,6 +168,7 @@ class MangaTR : FMReader("Manga-TR", "https://manga-tr.com", "tr") { return manga } + override fun mangaDetailsParse(document: Document): SManga { val manga = SManga.create() val infoElement = document.select("div#tab1").first() @@ -156,6 +182,7 @@ class MangaTR : FMReader("Manga-TR", "https://manga-tr.com", "tr") { return manga } + override fun chapterListSelector() = "tr.table-bordered" override val chapterUrlSelector = "td[align=left] > a" override val chapterTimeSelector = "td[align=right]" @@ -172,6 +199,7 @@ class MangaTR : FMReader("Manga-TR", "https://manga-tr.com", "tr") { Observable.error(Exception("Licensed - No chapters to show")) } } + private fun chapterListParse(response: Response, requestUrl: String): List { val chapters = mutableListOf() var document = response.asJsoup() @@ -180,7 +208,7 @@ class MangaTR : FMReader("Manga-TR", "https://manga-tr.com", "tr") { // chapters are paginated while (moreChapters) { - document.select(chapterListSelector()).map{ chapters.add(chapterFromElement(it)) } + document.select(chapterListSelector()).map { chapters.add(chapterFromElement(it)) } if (document.select("a[data-page=$nextPage]").isNotEmpty()) { val body = FormBody.Builder() .add("page", nextPage.toString()) @@ -193,21 +221,25 @@ class MangaTR : FMReader("Manga-TR", "https://manga-tr.com", "tr") { } return chapters } + override fun pageListRequest(chapter: SChapter): Request = GET("$baseUrl/${chapter.url.substringAfter("cek/")}", headers) override fun pageListParse(document: Document): List { val pages = mutableListOf() - document.select("div.chapter-content select:first-of-type option").forEachIndexed{ i, imgPage -> + document.select("div.chapter-content select:first-of-type option").forEachIndexed { i, imgPage -> pages.add(Page(i, "$baseUrl/${imgPage.attr("value")}", "")) } return pages.dropLast(1) // last page is a comments page } + override fun imageUrlParse(document: Document): String = document.select("img.chapter-img").attr("abs:src").trim() } + class Comicastle : FMReader("Comicastle", "https://www.comicastle.org", "en") { override val requestPath = "comic-dir" // this source doesn't have the "page x of y" element override fun popularMangaNextPageSelector() = "li:contains(»)" + override fun popularMangaParse(response: Response) = defaultMangaParse(response) override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request = GET("$baseUrl/comic-dir?q=$query", headers) override fun searchMangaParse(response: Response): MangasPage = defaultMangaParse(response) @@ -224,39 +256,43 @@ class Comicastle : FMReader("Comicastle", "https://www.comicastle.org", "en") { return manga } + override fun chapterListSelector() = "div.col-md-9 table:last-of-type tr" override fun chapterListParse(response: Response): List = super.chapterListParse(response).reversed() override fun pageListParse(document: Document): List { val pages = mutableListOf() - document.select("div.text-center select option").forEachIndexed{ i, imgPage -> + document.select("div.text-center select option").forEachIndexed { i, imgPage -> pages.add(Page(i, imgPage.attr("value"), "")) } return pages } + override fun imageUrlParse(document: Document): String = document.select("img.chapter-img").attr("abs:src").trim() override fun getGenreList() = getComicsGenreList() } + class Manhwa18Net : FMReader("Manhwa18.net", "https://manhwa18.net", "en") { override fun popularMangaRequest(page: Int): Request = GET("$baseUrl/$requestPath?listType=pagination&page=$page&sort=views&sort_type=DESC&ungenre=raw", headers) + override fun latestUpdatesRequest(page: Int): Request = GET("$baseUrl/$requestPath?listType=pagination&page=$page&sort=last_update&sort_type=DESC&ungenre=raw", headers) + override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { val noRawsUrl = super.searchMangaRequest(page, query, filters).url().newBuilder().addQueryParameter("ungenre", "raw").toString() return GET(noRawsUrl, headers) } + override fun getGenreList() = getAdultGenreList() } + class Manhwa18NetRaw : FMReader("Manhwa18.net Raw", "https://manhwa18.net", "ko") { override val requestPath = "manga-list-genre-raw.html" override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { val onlyRawsUrl = super.searchMangaRequest(page, query, filters).url().newBuilder().addQueryParameter("genre", "raw").toString() return GET(onlyRawsUrl, headers) } + override fun getFilterList() = FilterList(super.getFilterList().filterNot { it == GenreList(getGenreList()) }) } - - - - diff --git a/src/all/foolslide/build.gradle b/src/all/foolslide/build.gradle index 4f708a168..8f972b34d 100644 --- a/src/all/foolslide/build.gradle +++ b/src/all/foolslide/build.gradle @@ -5,7 +5,7 @@ ext { appName = 'Tachiyomi: FoolSlide (multiple sources)' pkgNameSuffix = 'all.foolslide' extClass = '.FoolSlideFactory' - extVersionCode = 28 + extVersionCode = 29 libVersion = '1.2' } diff --git a/src/all/foolslide/src/eu/kanade/tachiyomi/extension/all/foolslide/FoolSlide.kt b/src/all/foolslide/src/eu/kanade/tachiyomi/extension/all/foolslide/FoolSlide.kt index 1fc013034..0998423cb 100644 --- a/src/all/foolslide/src/eu/kanade/tachiyomi/extension/all/foolslide/FoolSlide.kt +++ b/src/all/foolslide/src/eu/kanade/tachiyomi/extension/all/foolslide/FoolSlide.kt @@ -4,7 +4,11 @@ import com.github.salomonbrys.kotson.get import com.google.gson.JsonParser import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.POST -import eu.kanade.tachiyomi.source.model.* +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.online.ParsedHttpSource import okhttp3.FormBody import okhttp3.Request @@ -13,13 +17,17 @@ import org.jsoup.nodes.Document import org.jsoup.nodes.Element import java.text.ParseException import java.text.SimpleDateFormat -import java.util.* +import java.util.Calendar +import java.util.Date +import java.util.HashSet +import java.util.Locale - -open class FoolSlide(override val name: String, - override val baseUrl: String, - override val lang: String, - val urlModifier: String = "") : ParsedHttpSource() { +abstract class FoolSlide( + override val name: String, + override val baseUrl: String, + override val lang: String, + val urlModifier: String = "" +) : ParsedHttpSource() { protected open val dedupeLatestUpdates = true @@ -81,7 +89,7 @@ open class FoolSlide(override val name: String, override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { val form = FormBody.Builder() - .add("search", query) + .add("search", query) return POST("$baseUrl$urlModifier/search/", headers, form.build()) } @@ -123,8 +131,8 @@ open class FoolSlide(override val name: String, private fun allowAdult(url: String): Request { return POST(url, body = FormBody.Builder() - .add("adult", "true") - .build()) + .add("adult", "true") + .build()) } override fun chapterListRequest(manga: SManga) = allowAdult(super.chapterListRequest(manga)) @@ -142,7 +150,7 @@ open class FoolSlide(override val name: String, chapter.setUrlWithoutDomain(urlElement.attr("href")) chapter.name = urlElement.text() chapter.date_upload = dateElement.text()?.let { parseChapterDate(it.substringAfter(", ")) } - ?: 0 + ?: 0 return chapter } @@ -247,8 +255,8 @@ open class FoolSlide(override val name: String, json.forEach { // Create dummy element to resolve relative URL val absUrl = document.createElement("a") - .attr("href", it["url"].asString) - .absUrl("href") + .attr("href", it["url"].asString) + .absUrl("href") pages.add(Page(pages.size, "", absUrl)) } diff --git a/src/all/foolslide/src/eu/kanade/tachiyomi/extension/all/foolslide/FoolSlideFactory.kt b/src/all/foolslide/src/eu/kanade/tachiyomi/extension/all/foolslide/FoolSlideFactory.kt index 6fb100608..2067dab7c 100644 --- a/src/all/foolslide/src/eu/kanade/tachiyomi/extension/all/foolslide/FoolSlideFactory.kt +++ b/src/all/foolslide/src/eu/kanade/tachiyomi/extension/all/foolslide/FoolSlideFactory.kt @@ -12,41 +12,36 @@ import okhttp3.Request import org.jsoup.nodes.Document class FoolSlideFactory : SourceFactory { - override fun createSources(): List = getAllFoolSlide() -} - -fun getAllFoolSlide(): List { - return listOf( - JaminisBox(), - SenseScans(), - KireiCake(), - SilentSky(), - Mangatellers(), - IskultripScans(), - AnataNoMotokare(), - DeathTollScans(), - DKThias(), - WorldThree(), - DokiFansubs(), - YuriIsm(), - AjiaNoScantrad(), - OneTimeScans(), - TsubasaSociety(), - MangaScouts(), - StormInHeaven(), - Lilyreader(), - Russification(), - EvilFlowers(), - AkaiYuhiMunTeam(), - LupiTeam(), - HentaiCafe(), - TheCatScans(), - ZandynoFansub() + override fun createSources(): List = listOf( + JaminisBox(), + SenseScans(), + KireiCake(), + SilentSky(), + Mangatellers(), + IskultripScans(), + AnataNoMotokare(), + DeathTollScans(), + DKThias(), + WorldThree(), + DokiFansubs(), + YuriIsm(), + AjiaNoScantrad(), + OneTimeScans(), + TsubasaSociety(), + MangaScouts(), + StormInHeaven(), + Lilyreader(), + Russification(), + EvilFlowers(), + AkaiYuhiMunTeam(), + LupiTeam(), + HentaiCafe(), + TheCatScans(), + ZandynoFansub() ) } class JaminisBox : FoolSlide("Jaimini's Box", "https://jaiminisbox.com", "en", "/reader") { - override fun pageListParse(document: Document): List { val doc = document.toString() var jsonstr = doc.substringAfter("var pages = ").substringBefore(";") @@ -132,7 +127,6 @@ class LupiTeam : FoolSlide("LupiTeam", "https://lupiteam.net", "it", "/reader") return manga } - } class ZandynoFansub : FoolSlide("Zandy no Fansub", "http://zandynofansub.aishiteru.org", "en", "/reader") diff --git a/src/all/foolslide/src/eu/kanade/tachiyomi/extension/all/foolslide/HentaiCafe.kt b/src/all/foolslide/src/eu/kanade/tachiyomi/extension/all/foolslide/HentaiCafe.kt index f64112d23..32449aefd 100644 --- a/src/all/foolslide/src/eu/kanade/tachiyomi/extension/all/foolslide/HentaiCafe.kt +++ b/src/all/foolslide/src/eu/kanade/tachiyomi/extension/all/foolslide/HentaiCafe.kt @@ -2,7 +2,11 @@ package eu.kanade.tachiyomi.extension.all.foolslide import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.asObservable -import eu.kanade.tachiyomi.source.model.* +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.SChapter +import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.util.asJsoup import okhttp3.Request import okhttp3.Response @@ -56,11 +60,11 @@ class HentaiCafe : FoolSlide("Hentai Cafe", "https://hentai.cafe", "en", "/manga // we still need to parse the manga info page // Example: https://hentai.cafe/aiya-youngest-daughters-circumstances/ override fun chapterListParse(response: Response) = listOf( - SChapter.create().apply { - setUrlWithoutDomain(response.asJsoup().select("[title=Read]").attr("href")) - name = "Chapter" - chapter_number = 1f - } + SChapter.create().apply { + setUrlWithoutDomain(response.asJsoup().select("[title=Read]").attr("href")) + name = "Chapter" + chapter_number = 1f + } ) override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { @@ -74,9 +78,9 @@ class HentaiCafe : FoolSlide("Hentai Cafe", "https://hentai.cafe", "en", "/manga if (f.state.isNotBlank()) { requireNoUrl() url = "/hc.fyi/artist/${f.state - .trim() - .toLowerCase() - .replace(ARTIST_INVALID_CHAR_REGEX, "-")}/" + .trim() + .toLowerCase() + .replace(ARTIST_INVALID_CHAR_REGEX, "-")}/" } } filters.findInstance()?.let { f -> @@ -113,79 +117,79 @@ 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) { - response.close() - // Better error message for invalid artist - if (response.code() == 404 - && !filters.findInstance()?.state.isNullOrBlank()) - error("Invalid artist!") - else throw Exception("HTTP error ${response.code()}") - } - } - .map { response -> - searchMangaParse(response) + .asObservable().doOnNext { response -> + if (!response.isSuccessful) { + response.close() + // Better error message for invalid artist + if (response.code() == 404 + && !filters.findInstance()?.state.isNullOrBlank()) + error("Invalid artist!") + else throw Exception("HTTP error ${response.code()}") } + } + .map { response -> + searchMangaParse(response) + } } override fun getFilterList() = FilterList( - Filter.Header("Filters cannot be used while searching."), - Filter.Header("Only one filter may be used at a time."), - Filter.Separator(), - ArtistFilter(), - BookFilter(), - TagFilter() + Filter.Header("Filters cannot be used while searching."), + Filter.Header("Only one filter may be used at a time."), + Filter.Separator(), + ArtistFilter(), + BookFilter(), + TagFilter() ) class ArtistFilter : Filter.Text("Artist (must be exact match)") class BookFilter : Filter.CheckBox("Show books only", false) class TagFilter : Filter.Select("Tag", arrayOf( - Tag("", ""), + Tag("ahegao", "Ahegao"), + Tag("anal", "Anal"), + Tag("big-ass", "Big ass"), + Tag("big-breast", "Big breast"), + Tag("big-dick", "Big dick"), + Tag("bondage", "Bondage"), + Tag("cheating", "Cheating"), + Tag("chubby", "Chubby"), + Tag("color", "Color"), + Tag("condom", "Condom"), + Tag("cosplay", "Cosplay"), + Tag("cunnilingus", "Cunnilingus"), + Tag("dark-skin", "Dark skin"), + Tag("exhibitionism", "Exhibitionism"), + Tag("fellatio", "Fellatio"), + Tag("femdom", "Femdom"), + Tag("flat-chest", "Flat chest"), + Tag("full-color", "Full color"), + Tag("glasses", "Glasses"), + Tag("group", "Group"), + Tag("hairy", "Hairy"), + Tag("handjob", "Handjob"), + Tag("heart-pupils", "Heart pupils"), + Tag("housewife", "Housewife"), + Tag("incest", "Incest"), + Tag("lingerie", "Lingerie"), + Tag("loli", "Loli"), + Tag("masturbation", "Masturbation"), + Tag("nakadashi", "Nakadashi"), + Tag("osananajimi", "Osananajimi"), + Tag("paizuri", "Paizuri"), + Tag("pettanko", "Pettanko"), + Tag("rape", "Rape"), + Tag("schoolgirl", "Schoolgirl"), + Tag("sex-toys", "Sex toys"), + Tag("shota", "Shota"), + Tag("socks", "Socks"), + Tag("stocking", "Stocking"), + Tag("stockings", "Stockings"), + Tag("swimsuit", "Swimsuit"), + Tag("teacher", "Teacher"), + Tag("tsundere", "Tsundere"), + Tag("uncensored", "Uncensored"), + Tag("vanilla", "Vanilla"), + Tag("x-ray", "X-Ray") )) class Tag(val name: String, private val displayName: String) { diff --git a/src/all/genkan/build.gradle b/src/all/genkan/build.gradle index f46f5b3dc..15ce14803 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 = 7 + extVersionCode = 8 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 ea84de2c1..a65b27047 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 @@ -1,7 +1,11 @@ package eu.kanade.tachiyomi.extension.all.genkan import eu.kanade.tachiyomi.network.GET -import eu.kanade.tachiyomi.source.model.* +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.online.ParsedHttpSource import eu.kanade.tachiyomi.util.asJsoup import okhttp3.OkHttpClient @@ -11,12 +15,13 @@ import org.jsoup.nodes.Document import org.jsoup.nodes.Element import org.jsoup.select.Elements import java.text.SimpleDateFormat -import java.util.* +import java.util.Calendar +import java.util.Locale abstract class Genkan( - override val name: String, - override val baseUrl: String, - override val lang: String + override val name: String, + override val baseUrl: String, + override val lang: String ) : ParsedHttpSource() { override val supportsLatest = true @@ -88,7 +93,7 @@ abstract class Genkan( private fun styleToUrl(element: Element): String { return element.attr("style").substringAfter("(").substringBefore(")") - .let{ if (it.startsWith("http")) it else baseUrl + it } + .let { if (it.startsWith("http")) it else baseUrl + it } } override fun mangaDetailsParse(document: Document): SManga { @@ -155,11 +160,11 @@ abstract class Genkan( val pages = mutableListOf() val allImages = document.select("div#pages-container + script").first().data() - .substringAfter("[").substringBefore("];") - .replace(Regex("""["\\]"""), "") - .split(",") + .substringAfter("[").substringBefore("];") + .replace(Regex("""["\\]"""), "") + .split(",") - for (i in 0 until allImages.size) { + for (i in allImages.indices) { pages.add(Page(i, "", allImages[i])) } @@ -178,9 +183,9 @@ abstract class Genkan( // For sites using the older Genkan CMS that didn't have a search function abstract class GenkanOriginal( - override val name: String, - override val baseUrl: String, - override val lang: String + override val name: String, + override val baseUrl: String, + override val lang: String ) : Genkan(name, baseUrl, lang) { private var searchQuery = "" @@ -223,7 +228,7 @@ abstract class GenkanOriginal( // search additional pages if called private fun searchMorePages(): MutableList { searchPage++ - val nextPage = client.newCall(popularMangaRequest(searchPage)).execute().asJsoup() + val nextPage = client.newCall(popularMangaRequest(searchPage)).execute().asJsoup() val searchMatches = mutableListOf() searchMatches.addAll(getMatchesFrom(nextPage)) nextPageSelectorElement = nextPage.select(searchMangaNextPageSelector()) @@ -238,4 +243,3 @@ abstract class GenkanOriginal( override fun searchMangaNextPageSelector() = popularMangaNextPageSelector() } - 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 f35a5c962..effde6d4b 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,14 +5,14 @@ import eu.kanade.tachiyomi.source.SourceFactory class GenkanFactory : SourceFactory { override fun createSources(): List = listOf( - LeviatanScans(), - LeviatanScansES(), - PsychoPlay(), - OneShotScans(), - KaguyaDex(), - KomiScans(), - HunlightScans(), - WoweScans() + LeviatanScans(), + LeviatanScansES(), + PsychoPlay(), + OneShotScans(), + KaguyaDex(), + KomiScans(), + HunlightScans(), + WoweScans() ) } diff --git a/src/all/madara/build.gradle b/src/all/madara/build.gradle index c5f371e04..96bc613a8 100644 --- a/src/all/madara/build.gradle +++ b/src/all/madara/build.gradle @@ -5,7 +5,7 @@ ext { appName = 'Tachiyomi: Madara (multiple sources)' pkgNameSuffix = "all.madara" extClass = '.MadaraFactory' - extVersionCode = 22 + extVersionCode = 23 libVersion = '1.2' } diff --git a/src/all/madara/src/eu/kanade/tachiyomi/extension/all/madara/Madara.kt b/src/all/madara/src/eu/kanade/tachiyomi/extension/all/madara/Madara.kt index 01fe97395..0834f2c0b 100644 --- a/src/all/madara/src/eu/kanade/tachiyomi/extension/all/madara/Madara.kt +++ b/src/all/madara/src/eu/kanade/tachiyomi/extension/all/madara/Madara.kt @@ -3,31 +3,43 @@ package eu.kanade.tachiyomi.extension.all.madara import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.POST import eu.kanade.tachiyomi.network.asObservable -import eu.kanade.tachiyomi.source.model.* +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.online.ParsedHttpSource -import okhttp3.* -import java.text.ParseException -import java.text.SimpleDateFormat -import java.util.* -import java.util.concurrent.TimeUnit +import okhttp3.CacheControl +import okhttp3.FormBody +import okhttp3.HttpUrl +import okhttp3.OkHttpClient +import okhttp3.Request +import okhttp3.Response import org.jsoup.nodes.Document import org.jsoup.nodes.Element import rx.Observable +import java.text.ParseException +import java.text.SimpleDateFormat +import java.util.Calendar +import java.util.Date +import java.util.Locale +import java.util.concurrent.TimeUnit -open class Madara( - override val name: String, - override val baseUrl: String, - override val lang: String, - private val dateFormat: SimpleDateFormat = SimpleDateFormat("MMMM dd, yyyy", Locale.US) +abstract class Madara( + override val name: String, + override val baseUrl: String, + override val lang: String, + private val dateFormat: SimpleDateFormat = SimpleDateFormat("MMMM dd, yyyy", Locale.US) ) : ParsedHttpSource() { + override val supportsLatest = true + override val client: OkHttpClient = network.cloudflareClient.newBuilder() .connectTimeout(10, TimeUnit.SECONDS) .readTimeout(30, TimeUnit.SECONDS) .build() - override val supportsLatest = true - // Popular Manga override fun popularMangaSelector() = "div.page-item-detail" @@ -42,7 +54,7 @@ open class Madara( } select("img").first()?.let { - manga.thumbnail_url = it.absUrl(if(it.hasAttr("data-src")) "data-src" else "src") + manga.thumbnail_url = it.absUrl(if (it.hasAttr("data-src")) "data-src" else "src") } } @@ -52,7 +64,7 @@ open class Madara( override fun popularMangaRequest(page: Int): Request { val form = FormBody.Builder().apply { add("action", "madara_load_more") - add("page", (page-1).toString()) + add("page", (page - 1).toString()) add("template", "madara-core/content/content-archive") add("vars[orderby]", "meta_value_num") add("vars[paged]", "1") @@ -81,7 +93,7 @@ open class Madara( override fun latestUpdatesRequest(page: Int): Request { val form = FormBody.Builder().apply { add("action", "madara_load_more") - add("page", (page-1).toString()) + add("page", (page - 1).toString()) add("template", "madara-core/content/content-archive") add("vars[orderby]", "meta_value_num") add("vars[paged]", "1") @@ -107,7 +119,7 @@ open class Madara( 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() // Error message for exceeding last page if (response.code() == 404) @@ -129,17 +141,17 @@ open class Madara( filters.forEach { filter -> when (filter) { is AuthorFilter -> { - if(filter.state.isNotBlank()) { + if (filter.state.isNotBlank()) { url.addQueryParameter("author", filter.state) } } is ArtistFilter -> { - if(filter.state.isNotBlank()) { + if (filter.state.isNotBlank()) { url.addQueryParameter("artist", filter.state) } } is YearFilter -> { - if(filter.state.isNotBlank()) { + if (filter.state.isNotBlank()) { url.addQueryParameter("release", filter.state) } } @@ -151,7 +163,7 @@ open class Madara( } } is OrderByFilter -> { - if(filter.state != 0) { + if (filter.state != 0) { url.addQueryParameter("m_orderby", filter.toUriPart()) } } @@ -165,28 +177,28 @@ open class Madara( private class YearFilter : Filter.Text("Year of Released") private class StatusFilter(status: List) : Filter.Group("Status", status) private class OrderByFilter : UriPartFilter("Order By", arrayOf( - Pair("", ""), + Pair("Latest", "latest"), + Pair("A-Z", "alphabet"), + Pair("Rating", "rating"), + Pair("Trending", "trending"), + Pair("Most Views", "views"), + Pair("New", "new-manga") )) override fun getFilterList() = FilterList( - AuthorFilter(), - ArtistFilter(), - YearFilter(), - StatusFilter(getStatusList()), - OrderByFilter() + AuthorFilter(), + ArtistFilter(), + YearFilter(), + StatusFilter(getStatusList()), + OrderByFilter() ) private fun getStatusList() = listOf( - Tag("end" , "Completed"), - Tag("on-going" , "Ongoing"), - Tag("canceled" , "Canceled"), - Tag("on-hold" , "On Hold") + Tag("end", "Completed"), + Tag("on-going", "Ongoing"), + Tag("canceled", "Canceled"), + Tag("on-hold", "On Hold") ) private open class UriPartFilter(displayName: String, val vals: Array>) : @@ -207,7 +219,7 @@ open class Madara( manga.title = it.ownText() } select("img").first()?.let { - manga.thumbnail_url = it.absUrl(if(it.hasAttr("data-src")) "data-src" else "src") + manga.thumbnail_url = it.absUrl(if (it.hasAttr("data-src")) "data-src" else "src") } } @@ -241,10 +253,10 @@ open class Madara( } } select("div.summary_image img").first()?.let { - manga.thumbnail_url = it.absUrl(if(it.hasAttr("data-src")) "data-src" else "src") + manga.thumbnail_url = it.absUrl(if (it.hasAttr("data-src")) "data-src" else "src") } select("div.summary-content").last()?.let { - manga.status = when(it.text()) { + manga.status = when (it.text()) { // I don't know what's the corresponding for COMPLETED and LICENSED // There's no support for "Canceled" or "On Hold" "Completed" -> SManga.COMPLETED @@ -271,7 +283,7 @@ open class Madara( with(element) { select("a").first()?.let { urlElement -> chapter.url = urlElement.attr("abs:href").let { - it.substringBefore("?style=paged") + if(!it.endsWith("?style=list")) "?style=list" else "" + it.substringBefore("?style=paged") + if (!it.endsWith("?style=list")) "?style=list" else "" } chapter.name = urlElement.text() } @@ -353,8 +365,8 @@ open class Madara( override fun pageListParse(document: Document): List { return document.select(pageListParseSelector).mapIndexed { index, element -> - Page(index, "", element.select("img").first()?.let{ - it.absUrl(if(it.hasAttr("data-src")) "data-src" else "src") + Page(index, "", element.select("img").first()?.let { + it.absUrl(if (it.hasAttr("data-src")) "data-src" else "src") }) } } diff --git a/src/all/madara/src/eu/kanade/tachiyomi/extension/all/madara/MadaraFactory.kt b/src/all/madara/src/eu/kanade/tachiyomi/extension/all/madara/MadaraFactory.kt index 00f5bba55..8a5c14322 100644 --- a/src/all/madara/src/eu/kanade/tachiyomi/extension/all/madara/MadaraFactory.kt +++ b/src/all/madara/src/eu/kanade/tachiyomi/extension/all/madara/MadaraFactory.kt @@ -1,6 +1,5 @@ package eu.kanade.tachiyomi.extension.all.madara - import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.source.Source import eu.kanade.tachiyomi.source.SourceFactory @@ -11,10 +10,10 @@ import eu.kanade.tachiyomi.source.model.SChapter import eu.kanade.tachiyomi.util.asJsoup import okhttp3.Headers import okhttp3.HttpUrl +import okhttp3.Request +import okhttp3.Response import java.text.SimpleDateFormat import java.util.Locale -import okhttp3.Response -import okhttp3.Request class MadaraFactory : SourceFactory { override fun createSources(): List = listOf( @@ -56,11 +55,13 @@ class MadaraFactory : SourceFactory { class Mangasushi : Madara("Mangasushi", "https://mangasushi.net", "en") { override fun searchMangaNextPageSelector() = "nav.navigation-ajax" } + class NinjaScans : Madara("NinjaScans", "https://ninjascans.com", "en") class ReadManhua : Madara("ReadManhua", "https://readmanhua.net", "en", dateFormat = SimpleDateFormat("dd MMM yy", Locale.US)) { override fun searchMangaNextPageSelector() = "nav.navigation-ajax" } + class ZeroScans : Madara("ZeroScans", "https://zeroscans.com", "en") class IsekaiScanCom : Madara("IsekaiScan.com", "https://isekaiscan.com/", "en") class HappyTeaScans : Madara("Happy Tea Scans", "https://happyteascans.com/", "en") @@ -68,7 +69,8 @@ class JustForFun : Madara("Just For Fun", "https://just-for-fun.ru/", "ru", dateFormat = SimpleDateFormat("dd/MM/yy", Locale.US)) { override fun searchMangaNextPageSelector() = "nav.navigation-ajax" } -class AoCTranslations : Madara("Agent of Change Translations", "https://aoc.moe/", "en"){ + +class AoCTranslations : Madara("Agent of Change Translations", "https://aoc.moe/", "en") { override fun chapterListParse(response: Response): List { val chapters = mutableListOf() val document = response.asJsoup() @@ -80,7 +82,7 @@ class AoCTranslations : Madara("Agent of Change Translations", "https://aoc.moe/ } else { // For their "fancy" volume/chapter lists document.select("div.wpb_wrapper:contains(volume) a") - .filter { it.attr("href").contains(baseUrl) && !it.attr("href").contains("imgur")} + .filter { it.attr("href").contains(baseUrl) && !it.attr("href").contains("imgur") } .map { it -> val chapter = SChapter.create() if (it.attr("href").contains("volume")) { @@ -99,9 +101,11 @@ class AoCTranslations : Madara("Agent of Change Translations", "https://aoc.moe/ return chapters.reversed() } } + class KomikGo : Madara("KomikGo", "https://komikgo.com", "id") { override fun searchMangaNextPageSelector() = "nav.navigation-ajax" } + class LuxyScans : Madara("Luxy Scans", "https://luxyscans.com/", "en") class TritiniaScans : Madara("Tritinia Scans", "http://ghajik.ml/", "en", dateFormat = SimpleDateFormat("dd/MM/yy", Locale.US)) { @@ -110,25 +114,32 @@ class TritiniaScans : Madara("Tritinia Scans", "http://ghajik.ml/", "en", override fun latestUpdatesNextPageSelector(): String? = null override fun popularMangaNextPageSelector(): String? = null } + class TsubakiNoScan : Madara("Tsubaki No Scan", "https://tsubakinoscan.com/", "fr", dateFormat = SimpleDateFormat("dd/MM/yy", Locale.US)) + class YokaiJump : Madara("Yokai Jump", "https://yokaijump.fr/", "fr", dateFormat = SimpleDateFormat("dd/MM/yy", Locale.US)) { override fun searchMangaNextPageSelector() = "nav.navigation-ajax" } + class ZManga : Madara("ZManga", "https://zmanga.org/", "es") { override fun searchMangaNextPageSelector() = "nav.navigation-ajax" } + class MangazukiMe : Madara("Mangazuki.me", "https://mangazuki.me/", "en") class MangazukiOnline : Madara("Mangazuki.online", "https://www.mangazuki.online/", "en") { override fun searchMangaNextPageSelector() = "nav.navigation-ajax" } + class MangazukiClubJP : Madara("Mangazuki.club", "https://mangazuki.club/", "ja") { override fun searchMangaNextPageSelector() = "nav.navigation-ajax" } + class MangazukiClubKO : Madara("Mangazuki.club", "https://mangazuki.club/", "ko") { override fun searchMangaNextPageSelector() = "nav.navigation-ajax" } + class FirstKissManga : Madara("1st Kiss", "https://1stkissmanga.com/", "en") { override val pageListParseSelector = "div.reading-content img" override fun searchMangaNextPageSelector() = "nav.navigation-ajax" @@ -141,12 +152,15 @@ class FirstKissManga : Madara("1st Kiss", "https://1stkissmanga.com/", "en") { return if (page.imageUrl!!.contains(cdnUrl)) GET(page.imageUrl!!, cdnHeaders) else GET(page.imageUrl!!, headers) } } + class MangaKomi : Madara("MangaKomi", "https://mangakomi.com/", "en") { override fun searchMangaNextPageSelector() = "nav.navigation-ajax" } + class MangaSY : Madara("Manga SY", "https://www.mangasy.com/", "en") { override fun searchMangaNextPageSelector() = "nav.navigation-ajax" } + class ManwhaClub : Madara("Manwha Club", "https://manhwa.club/", "en") class WuxiaWorld : Madara("WuxiaWorld", "https://wuxiaworld.site/", "en") { override fun popularMangaRequest(page: Int): Request = GET("$baseUrl/tag/webcomic/page/$page/?m_orderby=views", headers) @@ -154,6 +168,7 @@ class WuxiaWorld : Madara("WuxiaWorld", "https://wuxiaworld.site/", "en") { override fun searchMangaRequest(page: Int, query: String, filters: FilterList) = super.searchMangaRequest(page, "$query comics", filters) override fun popularMangaNextPageSelector() = "div.nav-previous.float-left" } + class WordRain : Madara("WordRain Translation", "https://wordrain69.com", "en") { override fun popularMangaRequest(page: Int): Request = GET("$baseUrl/manga-genre/manga/page/$page/?m_orderby=views", headers) override fun latestUpdatesRequest(page: Int): Request = GET("$baseUrl/manga-genre/manga/page/$page/?m_orderby=latest", headers) @@ -167,24 +182,31 @@ class WordRain : Madara("WordRain Translation", "https://wordrain69.com", "en") return super.searchMangaParse(res) } } + class YoManga : Madara("Yo Manga", "https://yomanga.info/", "en") { override fun searchMangaNextPageSelector() = "nav.navigation-ajax" } + class ManyToon : Madara("ManyToon", "https://manytoon.com/", "en") { override fun searchMangaNextPageSelector() = "nav.navigation-ajax" } + class ChibiManga : Madara("Chibi Manga", "http://www.cmreader.info/", "en") { override fun searchMangaNextPageSelector() = "nav.navigation-ajax" } + class ZinManga : Madara("Zin Translator", "https://zinmanga.com/", "en") { override fun searchMangaNextPageSelector() = "nav.navigation-ajax" } + class ManwahentaiMe : Madara("Manwahentai.me", "https://manhwahentai.me", "en") -class Manga3asq: Madara("مانجا العاشق", "https://3asq.org", "ar") { +class Manga3asq : Madara("مانجا العاشق", "https://3asq.org", "ar") { override fun searchMangaNextPageSelector() = "nav.navigation-ajax" } -class NManhwa: Madara("N Manhwa", "https://nmanhwa.com", "en") { + +class NManhwa : Madara("N Manhwa", "https://nmanhwa.com", "en") { override fun searchMangaNextPageSelector() = "nav.navigation-ajax" } -class Indiancomicsonline: Madara("Indian Comics Online", "http://www.indiancomicsonline.com", "hi") + +class Indiancomicsonline : Madara("Indian Comics Online", "http://www.indiancomicsonline.com", "hi") diff --git a/src/all/mangacards/build.gradle b/src/all/mangacards/build.gradle index ae12ba983..a46723758 100644 --- a/src/all/mangacards/build.gradle +++ b/src/all/mangacards/build.gradle @@ -5,7 +5,7 @@ ext { appName = 'Tachiyomi: MangaCards (Valhalla, NANI?)' pkgNameSuffix = 'all.mangacards' extClass = '.MangaCardsFactory' - extVersionCode = 4 + extVersionCode = 5 libVersion = '1.2' } diff --git a/src/all/mangacards/src/eu/kanade/tachiyomi/extension/all/mangacards/MangaCards.kt b/src/all/mangacards/src/eu/kanade/tachiyomi/extension/all/mangacards/MangaCards.kt index 1e223b928..3ad295de5 100644 --- a/src/all/mangacards/src/eu/kanade/tachiyomi/extension/all/mangacards/MangaCards.kt +++ b/src/all/mangacards/src/eu/kanade/tachiyomi/extension/all/mangacards/MangaCards.kt @@ -2,19 +2,23 @@ package eu.kanade.tachiyomi.extension.all.mangacards import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.POST -import eu.kanade.tachiyomi.source.model.* +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.online.ParsedHttpSource -import okhttp3.OkHttpClient -import okhttp3.Request -import org.jsoup.nodes.Document -import org.jsoup.nodes.Element import eu.kanade.tachiyomi.util.asJsoup import okhttp3.FormBody +import okhttp3.OkHttpClient +import okhttp3.Request import okhttp3.Response +import org.jsoup.nodes.Document +import org.jsoup.nodes.Element import java.text.SimpleDateFormat -import java.util.* +import java.util.Locale -abstract class MangaCards ( +abstract class MangaCards( override val name: String, override val baseUrl: String, override val lang: String diff --git a/src/all/mangacards/src/eu/kanade/tachiyomi/extension/all/mangacards/MangaCardsFactory.kt b/src/all/mangacards/src/eu/kanade/tachiyomi/extension/all/mangacards/MangaCardsFactory.kt index 3cea41e75..b0a9bbb86 100644 --- a/src/all/mangacards/src/eu/kanade/tachiyomi/extension/all/mangacards/MangaCardsFactory.kt +++ b/src/all/mangacards/src/eu/kanade/tachiyomi/extension/all/mangacards/MangaCardsFactory.kt @@ -14,4 +14,3 @@ class MangaCardsFactory : SourceFactory { class ValhallaScans : MangaCards("Valhalla Scans", "https://valhallascans.com", "en") class NaniScans : MangaCards("NANI? Scans", "https://naniscans.xyz", "en") class IneptBastards : MangaCards("Inept Bastards", "https://ineptbastards.xyz", "en") - diff --git a/src/all/mangadex/build.gradle b/src/all/mangadex/build.gradle index 5c9c5d13a..71ca6b1b7 100644 --- a/src/all/mangadex/build.gradle +++ b/src/all/mangadex/build.gradle @@ -5,7 +5,7 @@ ext { appName = 'Tachiyomi: MangaDex' pkgNameSuffix = 'all.mangadex' extClass = '.MangadexFactory' - extVersionCode = 68 + extVersionCode = 69 libVersion = '1.2' } diff --git a/src/all/mangadex/src/eu/kanade/tachiyomi/extension/all/mangadex/Mangadex.kt b/src/all/mangadex/src/eu/kanade/tachiyomi/extension/all/mangadex/Mangadex.kt index eba22c15f..4b7e5cecc 100644 --- a/src/all/mangadex/src/eu/kanade/tachiyomi/extension/all/mangadex/Mangadex.kt +++ b/src/all/mangadex/src/eu/kanade/tachiyomi/extension/all/mangadex/Mangadex.kt @@ -43,7 +43,11 @@ import java.util.Date import java.util.concurrent.TimeUnit import kotlin.collections.set -open class Mangadex(override val lang: String, private val internalLang: String, private val langCode: Int) : ConfigurableSource, ParsedHttpSource() { +abstract class Mangadex( + override val lang: String, + private val internalLang: String, + private val langCode: Int +) : ConfigurableSource, ParsedHttpSource() { override val name = "MangaDex" @@ -60,27 +64,27 @@ open class Mangadex(override val lang: String, private val internalLang: String, private val rateLimitInterceptor = RateLimitInterceptor(4) override val client: OkHttpClient = network.cloudflareClient.newBuilder() - .addNetworkInterceptor(rateLimitInterceptor) - .build() + .addNetworkInterceptor(rateLimitInterceptor) + .build() private fun clientBuilder(): OkHttpClient = clientBuilder(getShowR18()) private fun clientBuilder(r18Toggle: Int): OkHttpClient = network.cloudflareClient.newBuilder() - .connectTimeout(10, TimeUnit.SECONDS) - .readTimeout(30, TimeUnit.SECONDS) - .addNetworkInterceptor(rateLimitInterceptor) - .addNetworkInterceptor { chain -> - val originalCookies = chain.request().header("Cookie") ?: "" - val newReq = chain - .request() - .newBuilder() - .header("Cookie", "$originalCookies; ${cookiesHeader(r18Toggle, langCode)}") - .build() - chain.proceed(newReq) - }.build()!! + .connectTimeout(10, TimeUnit.SECONDS) + .readTimeout(30, TimeUnit.SECONDS) + .addNetworkInterceptor(rateLimitInterceptor) + .addNetworkInterceptor { chain -> + val originalCookies = chain.request().header("Cookie") ?: "" + val newReq = chain + .request() + .newBuilder() + .header("Cookie", "$originalCookies; ${cookiesHeader(r18Toggle, langCode)}") + .build() + chain.proceed(newReq) + }.build()!! override fun headersBuilder() = Headers.Builder().apply { - add("User-Agent", "Tachiyomi "+ System.getProperty("http.agent")) + add("User-Agent", "Tachiyomi " + System.getProperty("http.agent")) } private fun cookiesHeader(r18Toggle: Int, langCode: Int): String { @@ -150,36 +154,36 @@ open class Mangadex(override val lang: String, private val internalLang: String, override fun fetchPopularManga(page: Int): Observable { return clientBuilder().newCall(popularMangaRequest(page)) - .asObservableSuccess() - .map { response -> - popularMangaParse(response) - } + .asObservableSuccess() + .map { response -> + popularMangaParse(response) + } } override fun fetchLatestUpdates(page: Int): Observable { return clientBuilder().newCall(latestUpdatesRequest(page)) - .asObservableSuccess() - .map { response -> - latestUpdatesParse(response) - } + .asObservableSuccess() + .map { response -> + latestUpdatesParse(response) + } } override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable { return if (query.startsWith(PREFIX_ID_SEARCH)) { val realQuery = query.removePrefix(PREFIX_ID_SEARCH) client.newCall(searchMangaByIdRequest(realQuery)) - .asObservableSuccess() - .map { response -> - val details = mangaDetailsParse(response) - details.url = "/manga/$realQuery/" - MangasPage(listOf(details), false) - } + .asObservableSuccess() + .map { response -> + val details = mangaDetailsParse(response) + details.url = "/manga/$realQuery/" + MangasPage(listOf(details), false) + } } else { getSearchClient(filters).newCall(searchMangaRequest(page, query, filters)) - .asObservableSuccess() - .map { response -> - searchMangaParse(response) - } + .asObservableSuccess() + .map { response -> + searchMangaParse(response) + } } } @@ -205,8 +209,8 @@ open class Mangadex(override val lang: String, private val internalLang: String, // Do traditional search val url = HttpUrl.parse("$baseUrl/?page=search")!!.newBuilder() - .addQueryParameter("p", page.toString()) - .addQueryParameter("title", query.replace(WHITESPACE_REGEX, " ")) + .addQueryParameter("p", page.toString()) + .addQueryParameter("title", query.replace(WHITESPACE_REGEX, " ")) filters.forEach { filter -> when (filter) { @@ -323,10 +327,10 @@ open class Mangadex(override val lang: String, private val internalLang: String, override fun fetchMangaDetails(manga: SManga): Observable { return clientBuilder().newCall(apiRequest(manga)) - .asObservableSuccess() - .map { response -> - mangaDetailsParse(response).apply { initialized = true } - } + .asObservableSuccess() + .map { response -> + mangaDetailsParse(response).apply { initialized = true } + } } private fun apiRequest(manga: SManga): Request { @@ -362,14 +366,14 @@ open class Mangadex(override val lang: String, private val internalLang: String, val finalChapterNumber = getFinalChapter(mangaJson) if ((status == 2 || status == 3) && chapterJson != null && isMangaCompleted(chapterJson, finalChapterNumber)) { manga.status = SManga.COMPLETED - } else if (status == 2 && chapterJson != null && isOneshot(chapterJson, finalChapterNumber)){ + } else if (status == 2 && chapterJson != null && isOneshot(chapterJson, finalChapterNumber)) { manga.status = SManga.COMPLETED } else { manga.status = parseStatus(status) } val genres = (if (mangaJson.get("hentai").int == 1) listOf("Hentai") else listOf()) + - mangaJson.get("genres").asJsonArray.mapNotNull { GENRES[it.toString()] } + mangaJson.get("genres").asJsonArray.mapNotNull { GENRES[it.toString()] } manga.genre = genres.joinToString(", ") return manga @@ -395,10 +399,10 @@ open class Mangadex(override val lang: String, private val internalLang: String, override fun fetchChapterList(manga: SManga): Observable> { return clientBuilder().newCall(apiRequest(manga)) - .asObservableSuccess() - .map { response -> - chapterListParse(response) - } + .asObservableSuccess() + .map { response -> + chapterListParse(response) + } } private fun getFinalChapter(jsonObj: JsonObject): String = jsonObj.get("last_chapter").string.trim() @@ -414,8 +418,8 @@ open class Mangadex(override val lang: String, private val internalLang: String, private fun isMangaCompleted(chapterJson: JsonObject, finalChapterNumber: String): Boolean { val count = chapterJson.entrySet() - .filter { it.value.asJsonObject.get("lang_code").string == internalLang } - .filter { doesFinalChapterExist(finalChapterNumber, it.value) }.count() + .filter { it.value.asJsonObject.get("lang_code").string == internalLang } + .filter { doesFinalChapterExist(finalChapterNumber, it.value) }.count() return count != 0 } @@ -460,7 +464,7 @@ open class Mangadex(override val lang: String, private val internalLang: String, chapterName.add(chapterJson.get("title").string) } //if volume, chapter and title is empty its a oneshot - if(chapterName.isEmpty()){ + if (chapterName.isEmpty()) { chapterName.add("Oneshot") } if ((status == 2 || status == 3) && doesFinalChapterExist(finalChapterNumber, chapterJson)) { @@ -611,17 +615,17 @@ open class Mangadex(override val lang: String, private val internalLang: String, private class R18 : Filter.Select("R18+", arrayOf("Default", "Show all", "Show only", "Show none")) private fun getDemographic() = listOf( - Tag("1", "Shounen"), - Tag("2", "Shoujo"), - Tag("3", "Seinen"), - Tag("4", "Josei") + Tag("1", "Shounen"), + Tag("2", "Shoujo"), + Tag("3", "Seinen"), + Tag("4", "Josei") ).sortedWith(compareBy { it.name }) private fun getPublicationStatus() = listOf( - Tag("1", "Ongoing"), - Tag("2", "Completed"), - Tag("3", "Cancelled"), - Tag("4", "Hiatus") + Tag("1", "Ongoing"), + Tag("2", "Completed"), + Tag("3", "Cancelled"), + Tag("4", "Hiatus") ).sortedWith(compareBy { it.name }) private class ThemeList(themes: List) : Filter.Group("Themes", themes) @@ -630,115 +634,115 @@ open class Mangadex(override val lang: String, private val internalLang: String, // default selection (Rating Descending) matches popularMangaRequest url class SortFilter : Filter.Sort("Sort", - sortables.map { it.first }.toTypedArray(), - Selection(3, false)) + sortables.map { it.first }.toTypedArray(), + Selection(3, false)) private class OriginalLanguage : Filter.Select("Original Language", SOURCE_LANG_LIST.map { it.first }.toTypedArray()) override fun getFilterList() = FilterList( - TextField("Author", "author"), - TextField("Artist", "artist"), - R18(), - SortFilter(), - Demographic(getDemographic()), - PublicationStatus(getPublicationStatus()), - OriginalLanguage(), - ContentList(getContentList()), - FormatList(getFormatList()), - GenreList(getGenreList()), - ThemeList(getThemeList()), - TagInclusionMode(), - TagExclusionMode() + TextField("Author", "author"), + TextField("Artist", "artist"), + R18(), + SortFilter(), + Demographic(getDemographic()), + PublicationStatus(getPublicationStatus()), + OriginalLanguage(), + ContentList(getContentList()), + FormatList(getFormatList()), + GenreList(getGenreList()), + ThemeList(getThemeList()), + TagInclusionMode(), + TagExclusionMode() ) private fun getContentList() = listOf( - Tag("9", "Ecchi"), - Tag("32", "Smut"), - Tag("49", "Gore"), - Tag("50", "Sexual Violence") + Tag("9", "Ecchi"), + Tag("32", "Smut"), + Tag("49", "Gore"), + Tag("50", "Sexual Violence") ).sortedWith(compareBy { it.name }) private fun getFormatList() = listOf( - Tag("1", "4-koma"), - Tag("4", "Award Winning"), - Tag("7", "Doujinshi"), - Tag("21", "Oneshot"), - Tag("36", "Long Strip"), - Tag("42", "Adaptation"), - Tag("43", "Anthology"), - Tag("44", "Web Comic"), - Tag("45", "Full Color"), - Tag("46", "User Created"), - Tag("47", "Official Colored"), - Tag("48", "Fan Colored") + Tag("1", "4-koma"), + Tag("4", "Award Winning"), + Tag("7", "Doujinshi"), + Tag("21", "Oneshot"), + Tag("36", "Long Strip"), + Tag("42", "Adaptation"), + Tag("43", "Anthology"), + Tag("44", "Web Comic"), + Tag("45", "Full Color"), + Tag("46", "User Created"), + Tag("47", "Official Colored"), + Tag("48", "Fan Colored") ).sortedWith(compareBy { it.name }) private fun getGenreList() = listOf( - Tag("2", "Action"), - Tag("3", "Adventure"), - Tag("5", "Comedy"), - Tag("8", "Drama"), - Tag("10", "Fantasy"), - Tag("13", "Historical"), - Tag("14", "Horror"), - Tag("17", "Mecha"), - Tag("18", "Medical"), - Tag("20", "Mystery"), - Tag("22", "Psychological"), - Tag("23", "Romance"), - Tag("25", "Sci-Fi"), - Tag("28", "Shoujo Ai"), - Tag("30", "Shounen Ai"), - Tag("31", "Slice of Life"), - Tag("33", "Sports"), - Tag("35", "Tragedy"), - Tag("37", "Yaoi"), - Tag("38", "Yuri"), - Tag("41", "Isekai"), - Tag("51", "Crime"), - Tag("52", "Magical Girls"), - Tag("53", "Philosophical"), - Tag("54", "Superhero"), - Tag("55", "Thriller"), - Tag("56", "Wuxia") + Tag("2", "Action"), + Tag("3", "Adventure"), + Tag("5", "Comedy"), + Tag("8", "Drama"), + Tag("10", "Fantasy"), + Tag("13", "Historical"), + Tag("14", "Horror"), + Tag("17", "Mecha"), + Tag("18", "Medical"), + Tag("20", "Mystery"), + Tag("22", "Psychological"), + Tag("23", "Romance"), + Tag("25", "Sci-Fi"), + Tag("28", "Shoujo Ai"), + Tag("30", "Shounen Ai"), + Tag("31", "Slice of Life"), + Tag("33", "Sports"), + Tag("35", "Tragedy"), + Tag("37", "Yaoi"), + Tag("38", "Yuri"), + Tag("41", "Isekai"), + Tag("51", "Crime"), + Tag("52", "Magical Girls"), + Tag("53", "Philosophical"), + Tag("54", "Superhero"), + Tag("55", "Thriller"), + Tag("56", "Wuxia") ).sortedWith(compareBy { it.name }) private fun getThemeList() = listOf( - Tag("6", "Cooking"), - Tag("11", "Gyaru"), - Tag("12", "Harem"), - Tag("16", "Martial Arts"), - Tag("19", "Music"), - Tag("24", "School Life"), - Tag("34", "Supernatural"), - Tag("40", "Video Games"), - Tag("57", "Aliens"), - Tag("58", "Animals"), - Tag("59", "Crossdressing"), - Tag("60", "Demons"), - Tag("61", "Delinquents"), - Tag("62", "Genderswap"), - Tag("63", "Ghosts"), - Tag("64", "Monster Girls"), - Tag("65", "Loli"), - Tag("66", "Magic"), - Tag("67", "Military"), - Tag("68", "Monsters"), - Tag("69", "Ninja"), - Tag("70", "Office Workers"), - Tag("71", "Police"), - Tag("72", "Post-Apocalyptic"), - Tag("73", "Reincarnation"), - Tag("74", "Reverse Harem"), - Tag("75", "Samurai"), - Tag("76", "Shota"), - Tag("77", "Survival"), - Tag("78", "Time Travel"), - Tag("79", "Vampires"), - Tag("80", "Traditional Games"), - Tag("81", "Virtual Reality"), - Tag("82", "Zombies"), - Tag("83", "Incest") + Tag("6", "Cooking"), + Tag("11", "Gyaru"), + Tag("12", "Harem"), + Tag("16", "Martial Arts"), + Tag("19", "Music"), + Tag("24", "School Life"), + Tag("34", "Supernatural"), + Tag("40", "Video Games"), + Tag("57", "Aliens"), + Tag("58", "Animals"), + Tag("59", "Crossdressing"), + Tag("60", "Demons"), + Tag("61", "Delinquents"), + Tag("62", "Genderswap"), + Tag("63", "Ghosts"), + Tag("64", "Monster Girls"), + Tag("65", "Loli"), + Tag("66", "Magic"), + Tag("67", "Military"), + Tag("68", "Monsters"), + Tag("69", "Ninja"), + Tag("70", "Office Workers"), + Tag("71", "Police"), + Tag("72", "Post-Apocalyptic"), + Tag("73", "Reincarnation"), + Tag("74", "Reverse Harem"), + Tag("75", "Samurai"), + Tag("76", "Shota"), + Tag("77", "Survival"), + Tag("78", "Time Travel"), + Tag("79", "Vampires"), + Tag("80", "Traditional Games"), + Tag("81", "Virtual Reality"), + Tag("82", "Zombies"), + Tag("83", "Incest") ).sortedWith(compareBy { it.name }) private val GENRES = (getContentList() + getFormatList() + getGenreList() + getThemeList()).map { it.id to it.name }.toMap() @@ -768,26 +772,26 @@ open class Mangadex(override val lang: String, private val internalLang: String, const val PREFIX_ID_SEARCH = "id:" private val sortables = listOf( - Triple("Update date", 0, 1), - Triple("Alphabetically", 2, 3), - Triple("Number of comments", 4, 5), - Triple("Rating", 6, 7), - Triple("Views", 8, 9), - Triple("Follows", 10, 11)) + Triple("Update date", 0, 1), + Triple("Alphabetically", 2, 3), + Triple("Number of comments", 4, 5), + Triple("Rating", 6, 7), + Triple("Views", 8, 9), + Triple("Follows", 10, 11)) private val SOURCE_LANG_LIST = listOf( - Pair("All", "0"), - Pair("Japanese", "2"), - Pair("English", "1"), - Pair("Polish", "3"), - Pair("German", "8"), - Pair("French", "10"), - Pair("Vietnamese", "12"), - Pair("Chinese", "21"), - Pair("Indonesian", "27"), - Pair("Korean", "28"), - Pair("Spanish (LATAM)", "29"), - Pair("Thai", "32"), - Pair("Filipino", "34")) + Pair("All", "0"), + Pair("Japanese", "2"), + Pair("English", "1"), + Pair("Polish", "3"), + Pair("German", "8"), + Pair("French", "10"), + Pair("Vietnamese", "12"), + Pair("Chinese", "21"), + Pair("Indonesian", "27"), + Pair("Korean", "28"), + Pair("Spanish (LATAM)", "29"), + Pair("Thai", "32"), + Pair("Filipino", "34")) } } diff --git a/src/all/mangadex/src/eu/kanade/tachiyomi/extension/all/mangadex/MangadexFactory.kt b/src/all/mangadex/src/eu/kanade/tachiyomi/extension/all/mangadex/MangadexFactory.kt index 803c1dc0e..493f2032b 100644 --- a/src/all/mangadex/src/eu/kanade/tachiyomi/extension/all/mangadex/MangadexFactory.kt +++ b/src/all/mangadex/src/eu/kanade/tachiyomi/extension/all/mangadex/MangadexFactory.kt @@ -3,7 +3,83 @@ package eu.kanade.tachiyomi.extension.all.mangadex import eu.kanade.tachiyomi.source.Source import eu.kanade.tachiyomi.source.SourceFactory - class MangadexFactory : SourceFactory { - override fun createSources(): List = getAllMangaDexLanguages() + override fun createSources(): List = listOf( + MangaDexEnglish(), + MangaDexPolish(), + MangaDexItalian(), + MangaDexRussian(), + MangaDexGerman(), + MangaDexFrench(), + MangaDexVietnamese(), + MangaDexSpanishSpain(), + MangaDexSpanishLTAM(), + MangaDexCatalan(), + MangaDexPortuguesePortugal(), + MangaDexPortugueseBrazil(), + MangaDexSwedish(), + MangaDexTurkish(), + MangaDexIndonesian(), + MangaDexHungarian(), + MangaDexBulgarian(), + MangaDexFilipino(), + MangaDexDutch(), + MangaDexArabic(), + MangaDexChineseSimp(), + MangaDexChineseTrad(), + MangaDexThai(), + MangaDexBengali(), + MangaDexBurmese(), + MangaDexCzech(), + MangaDexDanish(), + MangaDexFinnish(), + MangaDexGreek(), + MangaDexJapanese(), + MangaDexKorean(), + MangaDexLithuanian(), + MangaDexMalay(), + MangaDexMongolian(), + MangaDexPersian(), + MangaDexRomanian(), + MangaDexSerboCroatian(), + MangaDexUkrainian() + ) } + +class MangaDexPolish : Mangadex("pl", "pl", 3) +class MangaDexItalian : Mangadex("it", "it", 6) +class MangaDexRussian : Mangadex("ru", "ru", 7) +class MangaDexGerman : Mangadex("de", "de", 8) +class MangaDexFrench : Mangadex("fr", "fr", 10) +class MangaDexVietnamese : Mangadex("vi", "vn", 12) +class MangaDexSpanishSpain : Mangadex("es", "es", 15) +class MangaDexSpanishLTAM : Mangadex("es-419", "mx", 29) +class MangaDexCatalan : Mangadex("ca", "ct", 33) +class MangaDexPortuguesePortugal : Mangadex("pt", "pt", 17) +class MangaDexPortugueseBrazil : Mangadex("pt-BR", "br", 16) +class MangaDexSwedish : Mangadex("sv", "se", 18) +class MangaDexTurkish : Mangadex("tr", "tr", 26) +class MangaDexIndonesian : Mangadex("id", "id", 27) +class MangaDexHungarian : Mangadex("hu", "hu", 9) +class MangaDexBulgarian : Mangadex("bg", "bg", 14) +class MangaDexFilipino : Mangadex("fil", "ph", 34) +class MangaDexDutch : Mangadex("nl", "nl", 5) +class MangaDexArabic : Mangadex("ar", "sa", 19) +class MangaDexChineseSimp : Mangadex("zh-Hans", "cn", 21) +class MangaDexChineseTrad : Mangadex("zh-Hant", "hk", 35) +class MangaDexThai : Mangadex("th", "th", 32) +class MangaDexBengali : Mangadex("bn", "bd", 22) +class MangaDexBurmese : Mangadex("my", "mm", 37) +class MangaDexCzech : Mangadex("cs", "cz", 24) +class MangaDexDanish : Mangadex("da", "dk", 20) +class MangaDexFinnish : Mangadex("fi", "fi", 11) +class MangaDexGreek : Mangadex("el", "gr", 13) +class MangaDexJapanese : Mangadex("ja", "jp", 2) +class MangaDexKorean : Mangadex("ko", "kr", 28) +class MangaDexLithuanian : Mangadex("lt", "lt", 38) +class MangaDexMalay : Mangadex("ms", "my", 31) +class MangaDexMongolian : Mangadex("mn", "mn", 25) +class MangaDexPersian : Mangadex("fa", "ir", 30) +class MangaDexRomanian : Mangadex("ro", "ro", 23) +class MangaDexSerboCroatian : Mangadex("sh", "rs", 4) +class MangaDexUkrainian : Mangadex("uk", "ua", 36) diff --git a/src/all/mangadex/src/eu/kanade/tachiyomi/extension/all/mangadex/MangadexLanguages.kt b/src/all/mangadex/src/eu/kanade/tachiyomi/extension/all/mangadex/MangadexLanguages.kt deleted file mode 100644 index 22f5ad4e0..000000000 --- a/src/all/mangadex/src/eu/kanade/tachiyomi/extension/all/mangadex/MangadexLanguages.kt +++ /dev/null @@ -1,84 +0,0 @@ -package eu.kanade.tachiyomi.extension.all.mangadex - -/** - * Mangadex languages - */ - -class MangaDexPolish : Mangadex("pl", "pl", 3) -class MangaDexItalian : Mangadex("it", "it", 6) -class MangaDexRussian : Mangadex("ru", "ru", 7) -class MangaDexGerman : Mangadex("de", "de", 8) -class MangaDexFrench : Mangadex("fr", "fr", 10) -class MangaDexVietnamese : Mangadex("vi", "vn", 12) -class MangaDexSpanishSpain : Mangadex("es", "es", 15) -class MangaDexSpanishLTAM : Mangadex("es-419", "mx", 29) -class MangaDexCatalan : Mangadex("ca", "ct", 33) -class MangaDexPortuguesePortugal : Mangadex("pt", "pt", 17) -class MangaDexPortugueseBrazil : Mangadex("pt-BR", "br", 16) -class MangaDexSwedish : Mangadex("sv", "se", 18) -class MangaDexTurkish : Mangadex("tr", "tr", 26) -class MangaDexIndonesian : Mangadex("id", "id", 27) -class MangaDexHungarian : Mangadex("hu", "hu", 9) -class MangaDexBulgarian : Mangadex("bg", "bg", 14) -class MangaDexFilipino : Mangadex("fil", "ph", 34) -class MangaDexDutch : Mangadex("nl", "nl", 5) -class MangaDexArabic : Mangadex("ar", "sa", 19) -class MangaDexChineseSimp : Mangadex("zh-Hans", "cn", 21) -class MangaDexChineseTrad : Mangadex("zh-Hant", "hk", 35) -class MangaDexThai : Mangadex("th", "th", 32) -class MangaDexBengali : Mangadex("bn", "bd", 22) -class MangaDexBurmese : Mangadex("my", "mm", 37) -class MangaDexCzech : Mangadex("cs", "cz", 24) -class MangaDexDanish : Mangadex("da", "dk", 20) -class MangaDexFinnish : Mangadex("fi", "fi", 11) -class MangaDexGreek : Mangadex("el", "gr", 13) -class MangaDexJapanese : Mangadex("ja", "jp", 2) -class MangaDexKorean : Mangadex("ko", "kr", 28) -class MangaDexLithuanian : Mangadex("lt", "lt", 38) -class MangaDexMalay : Mangadex("ms", "my", 31) -class MangaDexMongolian : Mangadex("mn", "mn", 25) -class MangaDexPersian : Mangadex("fa", "ir", 30) -class MangaDexRomanian : Mangadex("ro", "ro", 23) -class MangaDexSerboCroatian : Mangadex("sh", "rs", 4) -class MangaDexUkrainian : Mangadex("uk", "ua", 36) - -fun getAllMangaDexLanguages() = listOf( - MangaDexEnglish(), - MangaDexPolish(), - MangaDexItalian(), - MangaDexRussian(), - MangaDexGerman(), - MangaDexFrench(), - MangaDexVietnamese(), - MangaDexSpanishSpain(), - MangaDexSpanishLTAM(), - MangaDexCatalan(), - MangaDexPortuguesePortugal(), - MangaDexPortugueseBrazil(), - MangaDexSwedish(), - MangaDexTurkish(), - MangaDexIndonesian(), - MangaDexHungarian(), - MangaDexBulgarian(), - MangaDexFilipino(), - MangaDexDutch(), - MangaDexArabic(), - MangaDexChineseSimp(), - MangaDexChineseTrad(), - MangaDexThai(), - MangaDexBengali(), - MangaDexBurmese(), - MangaDexCzech(), - MangaDexDanish(), - MangaDexFinnish(), - MangaDexGreek(), - MangaDexJapanese(), - MangaDexKorean(), - MangaDexLithuanian(), - MangaDexMalay(), - MangaDexMongolian(), - MangaDexPersian(), - MangaDexRomanian(), - MangaDexSerboCroatian(), - MangaDexUkrainian() -) diff --git a/src/all/mangadex/src/eu/kanade/tachiyomi/extension/all/mangadex/MangadexUrlActivity.kt b/src/all/mangadex/src/eu/kanade/tachiyomi/extension/all/mangadex/MangadexUrlActivity.kt index cccbafb13..dc7667704 100644 --- a/src/all/mangadex/src/eu/kanade/tachiyomi/extension/all/mangadex/MangadexUrlActivity.kt +++ b/src/all/mangadex/src/eu/kanade/tachiyomi/extension/all/mangadex/MangadexUrlActivity.kt @@ -5,6 +5,7 @@ import android.content.ActivityNotFoundException import android.content.Intent import android.os.Bundle import android.util.Log +import kotlin.system.exitProcess /** * Springboard that accepts https://mangadex.com/title/xxx intents and redirects them to @@ -38,7 +39,7 @@ class MangadexUrlActivity : Activity() { } finish() - System.exit(0) + exitProcess(0) } } diff --git a/src/all/mangadventure/build.gradle b/src/all/mangadventure/build.gradle index f4386eebe..df2121eac 100644 --- a/src/all/mangadventure/build.gradle +++ b/src/all/mangadventure/build.gradle @@ -5,7 +5,7 @@ ext { appName = 'Tachiyomi: MangAdventure' pkgNameSuffix = 'all.mangadventure' extClass = '.MangAdventureFactory' - extVersionCode = 3 + extVersionCode = 4 libVersion = '1.2' } diff --git a/src/all/mangadventure/src/eu/kanade/tachiyomi/extension/all/mangadventure/MangAdventure.kt b/src/all/mangadventure/src/eu/kanade/tachiyomi/extension/all/mangadventure/MangAdventure.kt index fbd67b871..abf300d71 100644 --- a/src/all/mangadventure/src/eu/kanade/tachiyomi/extension/all/mangadventure/MangAdventure.kt +++ b/src/all/mangadventure/src/eu/kanade/tachiyomi/extension/all/mangadventure/MangAdventure.kt @@ -26,7 +26,7 @@ import java.util.Locale * * @property categories the available manga categories of the site. */ -open class MangAdventure( +abstract class MangAdventure( override val name: String, override val baseUrl: String, val categories: Array = DEFAULT_CATEGORIES diff --git a/src/all/mangadventure/src/eu/kanade/tachiyomi/extension/all/mangadventure/MangAdventureActivity.kt b/src/all/mangadventure/src/eu/kanade/tachiyomi/extension/all/mangadventure/MangAdventureActivity.kt index 62e953d9b..1cdd7c66b 100644 --- a/src/all/mangadventure/src/eu/kanade/tachiyomi/extension/all/mangadventure/MangAdventureActivity.kt +++ b/src/all/mangadventure/src/eu/kanade/tachiyomi/extension/all/mangadventure/MangAdventureActivity.kt @@ -31,7 +31,7 @@ class MangAdventureActivity : Activity() { } private fun logInvalidIntent(intent: Intent) { - val msg = "Failed to parse URI from intent" - Log.e("MangAdventureActivity", "$msg $intent") + Log.e("MangAdventureActivity", "Failed to parse URI from intent: $intent") } + } diff --git a/src/all/mangadventure/src/eu/kanade/tachiyomi/extension/all/mangadventure/MangAdventureFactory.kt b/src/all/mangadventure/src/eu/kanade/tachiyomi/extension/all/mangadventure/MangAdventureFactory.kt index d6c66a404..345fcfcb3 100644 --- a/src/all/mangadventure/src/eu/kanade/tachiyomi/extension/all/mangadventure/MangAdventureFactory.kt +++ b/src/all/mangadventure/src/eu/kanade/tachiyomi/extension/all/mangadventure/MangAdventureFactory.kt @@ -2,7 +2,6 @@ package eu.kanade.tachiyomi.extension.all.mangadventure import eu.kanade.tachiyomi.source.SourceFactory -/** [MangAdventure] source factory. */ class MangAdventureFactory : SourceFactory { override fun createSources() = listOf( ArcRelight() @@ -11,22 +10,22 @@ class MangAdventureFactory : SourceFactory { /** Arc-Relight source. */ class ArcRelight : MangAdventure( "Arc-Relight", "https://arc-relight.com", arrayOf( - "4-Koma", - "Chaos;Head", - "Collection", - "Comedy", - "Drama", - "Jubilee", - "Mystery", - "Psychological", - "Robotics;Notes", - "Romance", - "Sci-Fi", - "Seinen", - "Shounen", - "Steins;Gate", - "Supernatural", - "Tragedy" - ) + "4-Koma", + "Chaos;Head", + "Collection", + "Comedy", + "Drama", + "Jubilee", + "Mystery", + "Psychological", + "Robotics;Notes", + "Romance", + "Sci-Fi", + "Seinen", + "Shounen", + "Steins;Gate", + "Supernatural", + "Tragedy" + ) ) } diff --git a/src/all/mangatensei/build.gradle b/src/all/mangatensei/build.gradle index 9baeb5346..60fa3241a 100644 --- a/src/all/mangatensei/build.gradle +++ b/src/all/mangatensei/build.gradle @@ -5,7 +5,7 @@ ext { appName = 'Tachiyomi: Mangatensei' pkgNameSuffix = 'all.mangatensei' extClass = '.MangatenseiFactory' - extVersionCode = 2 + extVersionCode = 3 libVersion = '1.2' } diff --git a/src/all/mangatensei/src/eu/kanade/tachiyomi/extension/all/mangatensei/Mangatensei.kt b/src/all/mangatensei/src/eu/kanade/tachiyomi/extension/all/mangatensei/Mangatensei.kt index fe45e5d17..16b2c5b89 100644 --- a/src/all/mangatensei/src/eu/kanade/tachiyomi/extension/all/mangatensei/Mangatensei.kt +++ b/src/all/mangatensei/src/eu/kanade/tachiyomi/extension/all/mangatensei/Mangatensei.kt @@ -1,7 +1,11 @@ package eu.kanade.tachiyomi.extension.all.mangatensei import eu.kanade.tachiyomi.network.GET -import eu.kanade.tachiyomi.source.model.* +import eu.kanade.tachiyomi.source.model.Filter +import eu.kanade.tachiyomi.source.model.FilterList +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.online.ParsedHttpSource import okhttp3.HttpUrl import okhttp3.OkHttpClient @@ -9,7 +13,7 @@ import okhttp3.Request import org.json.JSONObject import org.jsoup.nodes.Document import org.jsoup.nodes.Element -import java.util.* +import java.util.Calendar import java.util.concurrent.TimeUnit open class Mangatensei(override val lang: String, private val Mtlang: String) : ParsedHttpSource() { @@ -25,7 +29,7 @@ open class Mangatensei(override val lang: String, private val Mtlang: String) : .readTimeout(30, TimeUnit.SECONDS) .build() - override fun latestUpdatesRequest(page: Int): Request { + override fun latestUpdatesRequest(page: Int): Request { // The site redirects page 1 -> url-without-page so we do this redirect early for optimization val builtUrl = "$baseUrl/browse?langs=$Mtlang&sort=update&page=$page" return GET(builtUrl) @@ -45,7 +49,7 @@ open class Mangatensei(override val lang: String, private val Mtlang: String) : override fun latestUpdatesNextPageSelector() = "div.browse-pager:contains(order) a.page-link:contains(»)" - override fun popularMangaRequest(page: Int): Request { + override fun popularMangaRequest(page: Int): Request { val builtUrl = "$baseUrl/browse?langs=$Mtlang&sort=views_w&page=$page" return GET(builtUrl) } @@ -64,7 +68,7 @@ open class Mangatensei(override val lang: String, private val Mtlang: String) : filters.forEach { filter -> when (filter) { is AuthorFilter -> { - author = filter.state + author = filter.state } is StyleFilter -> { val styleToInclude = mutableListOf() @@ -96,7 +100,7 @@ open class Mangatensei(override val lang: String, private val Mtlang: String) : Filter.TriState.STATE_EXCLUDE -> "0" else -> "" } - if(status.isNotEmpty()) { + if (status.isNotEmpty()) { url.addQueryParameter("status", status) } } @@ -113,23 +117,23 @@ open class Mangatensei(override val lang: String, private val Mtlang: String) : } } is StarFilter -> { - if(filter.state != 0) { + if (filter.state != 0) { url.addQueryParameter("stars", filter.toUriPart()) } } is ChapterFilter -> { - if(filter.state != 0) { + if (filter.state != 0) { url.addQueryParameter("chapters", filter.toUriPart()) } } is SortBy -> { - if(filter.state != 0) { + if (filter.state != 0) { url.addQueryParameter("sort", filter.toUriPart()) } } } } - return if(query.isNotBlank() || author!!.isNotBlank()) { + return if (query.isNotBlank() || author!!.isNotBlank()) { GET("$baseUrl/search?q=$query&a=$author") } else GET(url.build().toString(), headers) } @@ -257,7 +261,7 @@ open class Mangatensei(override val lang: String, private val Mtlang: String) : val imgJson = JSONObject(script) val imgNames = imgJson.names() - for( i in 0 until imgNames.length()) { + for (i in 0 until imgNames.length()) { val imgKey = imgNames.getString(i) val imgUrl = imgJson.getString(imgKey) pages.add(Page(i, "", imgUrl)) @@ -275,111 +279,111 @@ open class Mangatensei(override val lang: String, private val Mtlang: String) : private class StatusFilter : Filter.TriState("Completed") private class StarFilter : UriPartFilter("Stars", arrayOf( - Pair("", ""), + Pair("5 Stars", "5"), + Pair("4 Stars", "4"), + Pair("3 Stars", "3"), + Pair("2 Stars", "2"), + Pair("1 Stars", "1") )) private class ChapterFilter : UriPartFilter("Chapters", arrayOf( - Pair("", ""), + Pair("1 ~ 9", "1-9"), + Pair("10 ~ 29", "10-29"), + Pair("30 ~ 99", "30-99"), + Pair("100 ~ 199", "100-199"), + Pair("200+", "200"), + Pair("100+", "100"), + Pair("50+", "50"), + Pair("10+", "10"), + Pair("1+", "1") )) private class SortBy : UriPartFilter("Sorts By", arrayOf( - Pair("", ""), + Pair("Totally", "views_t"), + Pair("365 days", "views_y"), + Pair("30 days", "views_m"), + Pair("7 days", "views_w"), + Pair("24 hours", "views_d"), + Pair("60 minutes", "views_h"), + Pair("A-Z", "title"), + Pair("Update time", "update"), + Pair("Add time", "create") )) override fun getFilterList() = FilterList( - Filter.Header("NOTE: Ignored if using text search!"), - AuthorFilter(), - Filter.Separator(), - StatusFilter(), - StarFilter(), - ChapterFilter(), - SortBy(), - StyleFilter(getStyleList()), - DemographicFilter(getDemographicList()), - GenreFilter(getGenreList()) + Filter.Header("NOTE: Ignored if using text search!"), + AuthorFilter(), + Filter.Separator(), + StatusFilter(), + StarFilter(), + ChapterFilter(), + SortBy(), + StyleFilter(getStyleList()), + DemographicFilter(getDemographicList()), + GenreFilter(getGenreList()) ) private fun getStyleList() = listOf( - Tag("manga"), - Tag("manhwa"), - Tag("manhua"), - Tag("webtoon") + Tag("manga"), + Tag("manhwa"), + Tag("manhua"), + Tag("webtoon") ) private fun getDemographicList() = listOf( - Tag("josei"), - Tag("seinen"), - Tag("shoujo"), - Tag("shoujo ai"), - Tag("shounen"), - Tag("shounen ai"), - Tag("yaoi"), - Tag("yuri") + Tag("josei"), + Tag("seinen"), + Tag("shoujo"), + Tag("shoujo ai"), + Tag("shounen"), + Tag("shounen ai"), + Tag("yaoi"), + Tag("yuri") ) private fun getGenreList() = listOf( - Tag("action"), - Tag("adventure"), - Tag("award winning"), - Tag("comedy"), - Tag("cooking"), - Tag("demons"), - Tag("doujinshi"), - Tag("drama"), - Tag("ecchi"), - Tag("fantasy"), - Tag("gender bender"), - Tag("harem"), - Tag("historical"), - Tag("horror"), - Tag("isekai"), - Tag("magic"), - Tag("martial arts"), - Tag("mature"), - Tag("mecha"), - Tag("medical"), - Tag("military"), - Tag("music"), - Tag("mystery"), - Tag("one shot"), - Tag("psychological"), - Tag("reverse harem"), - Tag("romance"), - Tag("school life"), - Tag("sci fi"), - Tag("shotacon"), - Tag("slice of life"), - Tag("smut"), - Tag("sports"), - Tag("super power"), - Tag("supernatural"), - Tag("tragedy"), - Tag("uncategorized"), - Tag("vampire"), - Tag("youkai") + Tag("action"), + Tag("adventure"), + Tag("award winning"), + Tag("comedy"), + Tag("cooking"), + Tag("demons"), + Tag("doujinshi"), + Tag("drama"), + Tag("ecchi"), + Tag("fantasy"), + Tag("gender bender"), + Tag("harem"), + Tag("historical"), + Tag("horror"), + Tag("isekai"), + Tag("magic"), + Tag("martial arts"), + Tag("mature"), + Tag("mecha"), + Tag("medical"), + Tag("military"), + Tag("music"), + Tag("mystery"), + Tag("one shot"), + Tag("psychological"), + Tag("reverse harem"), + Tag("romance"), + Tag("school life"), + Tag("sci fi"), + Tag("shotacon"), + Tag("slice of life"), + Tag("smut"), + Tag("sports"), + Tag("super power"), + Tag("supernatural"), + Tag("tragedy"), + Tag("uncategorized"), + Tag("vampire"), + Tag("youkai") ) private open class UriPartFilter(displayName: String, val vals: Array>) : diff --git a/src/all/mangatensei/src/eu/kanade/tachiyomi/extension/all/mangatensei/MangatenseiFactory.kt b/src/all/mangatensei/src/eu/kanade/tachiyomi/extension/all/mangatensei/MangatenseiFactory.kt index d599b5895..3ba6c93c8 100644 --- a/src/all/mangatensei/src/eu/kanade/tachiyomi/extension/all/mangatensei/MangatenseiFactory.kt +++ b/src/all/mangatensei/src/eu/kanade/tachiyomi/extension/all/mangatensei/MangatenseiFactory.kt @@ -3,7 +3,54 @@ package eu.kanade.tachiyomi.extension.all.mangatensei import eu.kanade.tachiyomi.source.Source import eu.kanade.tachiyomi.source.SourceFactory - class MangatenseiFactory : SourceFactory { - override fun createSources(): List = getAllMangatenseiLanguages() -} \ No newline at end of file + override fun createSources(): List = listOf( + MangatenseiArabic(), + MangatenseiBrazilian(), + MangatenseiCzech(), + MangatenseiDanish(), + MangatenseiDutch(), + MangatenseiEnglish(), + MangatenseiFilipino(), + MangatenseiFrench(), + MangatenseiGerman(), + MangatenseiGreek(), + MangatenseiHebrew(), + MangatenseiHungarian(), + MangatenseiIndonesian(), + MangatenseiItalian(), + MangatenseiMalay(), + MangatenseiPolish(), + MangatenseiPortuguese(), + MangatenseiRomanian(), + MangatenseiRussian(), + MangatenseiSpanish(), + MangatenseiThai(), + MangatenseiTurkish(), + MangatenseiVietnamese() + ) +} + +class MangatenseiArabic : Mangatensei("ar", "arabic") +class MangatenseiBrazilian : Mangatensei("pt-BR", "brazilian") +class MangatenseiCzech : Mangatensei("cs", "czech") +class MangatenseiDanish : Mangatensei("da", "danish") +class MangatenseiDutch : Mangatensei("nl", "dutch") +class MangatenseiEnglish : Mangatensei("en", "english") +class MangatenseiFilipino : Mangatensei("fil", "filipino") +class MangatenseiFrench : Mangatensei("fr", "french") +class MangatenseiGerman : Mangatensei("de", "german") +class MangatenseiGreek : Mangatensei("el", "greek") +class MangatenseiHebrew : Mangatensei("iw", "hebrew") +class MangatenseiHungarian : Mangatensei("hu", "hungarian") +class MangatenseiIndonesian : Mangatensei("id", "indonesian") +class MangatenseiItalian : Mangatensei("it", "italian") +class MangatenseiMalay : Mangatensei("ms", "malay") +class MangatenseiPolish : Mangatensei("pl", "polish") +class MangatenseiPortuguese : Mangatensei("pt", "portuguese") +class MangatenseiRomanian : Mangatensei("ro", "romanian") +class MangatenseiRussian : Mangatensei("ru", "russian") +class MangatenseiSpanish : Mangatensei("es", "spanish") +class MangatenseiThai : Mangatensei("th", "thai") +class MangatenseiTurkish : Mangatensei("tr", "turkish") +class MangatenseiVietnamese : Mangatensei("vi", "vietnamese") diff --git a/src/all/mangatensei/src/eu/kanade/tachiyomi/extension/all/mangatensei/MangatenseiLanguages.kt b/src/all/mangatensei/src/eu/kanade/tachiyomi/extension/all/mangatensei/MangatenseiLanguages.kt deleted file mode 100644 index b7e86db1f..000000000 --- a/src/all/mangatensei/src/eu/kanade/tachiyomi/extension/all/mangatensei/MangatenseiLanguages.kt +++ /dev/null @@ -1,55 +0,0 @@ -package eu.kanade.tachiyomi.extension.all.mangatensei - -/** - * Mangatensei languages - */ - -class MangatenseiArabic : Mangatensei("ar", "arabic") -class MangatenseiBrazilian : Mangatensei("pt-BR", "brazilian") -class MangatenseiCzech : Mangatensei("cs", "czech") -class MangatenseiDanish : Mangatensei("da", "danish") -class MangatenseiDutch : Mangatensei("nl", "dutch") -class MangatenseiEnglish : Mangatensei("en", "english") -class MangatenseiFilipino : Mangatensei("fil", "filipino") -class MangatenseiFrench : Mangatensei("fr", "french") -class MangatenseiGerman : Mangatensei("de", "german") -class MangatenseiGreek : Mangatensei("el", "greek") -class MangatenseiHebrew : Mangatensei("iw", "hebrew") -class MangatenseiHungarian : Mangatensei("hu", "hungarian") -class MangatenseiIndonesian : Mangatensei("id", "indonesian") -class MangatenseiItalian : Mangatensei("it", "italian") -class MangatenseiMalay : Mangatensei("ms", "malay") -class MangatenseiPolish : Mangatensei("pl", "polish") -class MangatenseiPortuguese : Mangatensei("pt", "portuguese") -class MangatenseiRomanian : Mangatensei("ro", "romanian") -class MangatenseiRussian : Mangatensei("ru", "russian") -class MangatenseiSpanish : Mangatensei("es", "spanish") -class MangatenseiThai : Mangatensei("th", "thai") -class MangatenseiTurkish : Mangatensei("tr", "turkish") -class MangatenseiVietnamese : Mangatensei("vi", "vietnamese") - -fun getAllMangatenseiLanguages() = listOf( - MangatenseiArabic(), - MangatenseiBrazilian(), - MangatenseiCzech(), - MangatenseiDanish(), - MangatenseiDutch(), - MangatenseiEnglish(), - MangatenseiFilipino(), - MangatenseiFrench(), - MangatenseiGerman(), - MangatenseiGreek(), - MangatenseiHebrew(), - MangatenseiHungarian(), - MangatenseiIndonesian(), - MangatenseiItalian(), - MangatenseiMalay(), - MangatenseiPolish(), - MangatenseiPortuguese(), - MangatenseiRomanian(), - MangatenseiRussian(), - MangatenseiSpanish(), - MangatenseiThai(), - MangatenseiTurkish(), - MangatenseiVietnamese() -)