diff --git a/multisrc/overrides/mangahub/mangafoxfun/src/MangaFoxFun.kt b/multisrc/overrides/mangahub/mangafoxfun/src/MangaFoxFun.kt new file mode 100644 index 000000000..5313d716e --- /dev/null +++ b/multisrc/overrides/mangahub/mangafoxfun/src/MangaFoxFun.kt @@ -0,0 +1,5 @@ +package eu.kanade.tachiyomi.extension.en.mangafoxfun + +import eu.kanade.tachiyomi.multisrc.mangahub.MangaHub + +class MangaFoxFun : MangaHub("MangaFox.fun", "https://mangafox.fun", "en", "mf01") diff --git a/multisrc/overrides/mangahub/mangahereonl/src/MangaHereOnl.kt b/multisrc/overrides/mangahub/mangahereonl/src/MangaHereOnl.kt new file mode 100644 index 000000000..f3bd84003 --- /dev/null +++ b/multisrc/overrides/mangahub/mangahereonl/src/MangaHereOnl.kt @@ -0,0 +1,5 @@ +package eu.kanade.tachiyomi.extension.en.mangahereonl + +import eu.kanade.tachiyomi.multisrc.mangahub.MangaHub + +class MangaHereOnl : MangaHub("MangaHere.onl", "https://mangahere.onl", "en", "mh01") diff --git a/multisrc/overrides/mangahub/mangahubio/src/MangaHubIo.kt b/multisrc/overrides/mangahub/mangahubio/src/MangaHubIo.kt new file mode 100644 index 000000000..7cc3ac0fb --- /dev/null +++ b/multisrc/overrides/mangahub/mangahubio/src/MangaHubIo.kt @@ -0,0 +1,5 @@ +package eu.kanade.tachiyomi.extension.en.mangahubio + +import eu.kanade.tachiyomi.multisrc.mangahub.MangaHub + +class MangaHubIo : MangaHub("MangaHub", "https://mangahub.io", "en", "m01") diff --git a/multisrc/overrides/mangahub/mangakakalotfun/src/MangakakalotFun.kt b/multisrc/overrides/mangahub/mangakakalotfun/src/MangakakalotFun.kt new file mode 100644 index 000000000..138b590af --- /dev/null +++ b/multisrc/overrides/mangahub/mangakakalotfun/src/MangakakalotFun.kt @@ -0,0 +1,5 @@ +package eu.kanade.tachiyomi.extension.en.mangakakalotfun + +import eu.kanade.tachiyomi.multisrc.mangahub.MangaHub + +class MangakakalotFun : MangaHub("Mangakakalot.fun", "https://mangakakalot.fun", "en", "mn01") diff --git a/multisrc/overrides/mangahub/manganel/src/MangaNel.kt b/multisrc/overrides/mangahub/manganel/src/MangaNel.kt new file mode 100644 index 000000000..0e6613513 --- /dev/null +++ b/multisrc/overrides/mangahub/manganel/src/MangaNel.kt @@ -0,0 +1,5 @@ +package eu.kanade.tachiyomi.extension.en.manganel + +import eu.kanade.tachiyomi.multisrc.mangahub.MangaHub + +class MangaNel : MangaHub("MangaNel", "https://manganel.me", "en", "mn05") diff --git a/multisrc/overrides/mangahub/mangaonlinefun/src/MangaOnlineFun.kt b/multisrc/overrides/mangahub/mangaonlinefun/src/MangaOnlineFun.kt new file mode 100644 index 000000000..52a55f6c5 --- /dev/null +++ b/multisrc/overrides/mangahub/mangaonlinefun/src/MangaOnlineFun.kt @@ -0,0 +1,5 @@ +package eu.kanade.tachiyomi.extension.en.mangaonlinefun + +import eu.kanade.tachiyomi.multisrc.mangahub.MangaHub + +class MangaOnlineFun : MangaHub("MangaOnline.fun", "https://mangaonline.fun", "en", "m02") diff --git a/multisrc/overrides/mangahub/mangapandaonl/src/MangaPandaOnl.kt b/multisrc/overrides/mangahub/mangapandaonl/src/MangaPandaOnl.kt new file mode 100644 index 000000000..03dd17d4d --- /dev/null +++ b/multisrc/overrides/mangahub/mangapandaonl/src/MangaPandaOnl.kt @@ -0,0 +1,5 @@ +package eu.kanade.tachiyomi.extension.en.mangapandaonl + +import eu.kanade.tachiyomi.multisrc.mangahub.MangaHub + +class MangaPandaOnl : MangaHub("MangaPanda.onl", "https://mangapanda.onl", "en", "mr02") diff --git a/multisrc/overrides/mangahub/mangareadersite/src/MangaReaderSite.kt b/multisrc/overrides/mangahub/mangareadersite/src/MangaReaderSite.kt new file mode 100644 index 000000000..9e9401871 --- /dev/null +++ b/multisrc/overrides/mangahub/mangareadersite/src/MangaReaderSite.kt @@ -0,0 +1,5 @@ +package eu.kanade.tachiyomi.extension.en.mangareadersite + +import eu.kanade.tachiyomi.multisrc.mangahub.MangaHub + +class MangaReaderSite : MangaHub("MangaReader.site", "https://mangareader.site", "en", "mr01") diff --git a/multisrc/overrides/mangahub/mangatoday/src/MangaToday.kt b/multisrc/overrides/mangahub/mangatoday/src/MangaToday.kt new file mode 100644 index 000000000..eb2e385ac --- /dev/null +++ b/multisrc/overrides/mangahub/mangatoday/src/MangaToday.kt @@ -0,0 +1,5 @@ +package eu.kanade.tachiyomi.extension.en.mangatoday + +import eu.kanade.tachiyomi.multisrc.mangahub.MangaHub + +class MangaToday : MangaHub("MangaToday", "https://mangatoday.fun", "en", "m03") diff --git a/multisrc/overrides/mangahub/onemangaco/src/OneMangaCo.kt b/multisrc/overrides/mangahub/onemangaco/src/OneMangaCo.kt new file mode 100644 index 000000000..d4ecafb05 --- /dev/null +++ b/multisrc/overrides/mangahub/onemangaco/src/OneMangaCo.kt @@ -0,0 +1,5 @@ +package eu.kanade.tachiyomi.extension.en.onemangaco + +import eu.kanade.tachiyomi.multisrc.mangahub.MangaHub + +class OneMangaCo : MangaHub("1Manga.co", "https://1manga.co", "en", "mn03") diff --git a/multisrc/overrides/mangahub/onemangainfo/src/OneMangaInfo.kt b/multisrc/overrides/mangahub/onemangainfo/src/OneMangaInfo.kt new file mode 100644 index 000000000..b8349da36 --- /dev/null +++ b/multisrc/overrides/mangahub/onemangainfo/src/OneMangaInfo.kt @@ -0,0 +1,5 @@ +package eu.kanade.tachiyomi.extension.en.onemangainfo + +import eu.kanade.tachiyomi.multisrc.mangahub.MangaHub + +class OneMangaInfo : MangaHub("OneManga.info", "https://onemanga.info", "en", "mh01") diff --git a/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/mangahub/MangaHub.kt b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/mangahub/MangaHub.kt index 9a7eee38c..78712b207 100644 --- a/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/mangahub/MangaHub.kt +++ b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/mangahub/MangaHub.kt @@ -41,6 +41,7 @@ abstract class MangaHub( override val name: String, final override val baseUrl: String, override val lang: String, + private val mangaSource: String, private val dateFormat: SimpleDateFormat = SimpleDateFormat("MM-dd-yyyy", Locale.US), ) : ParsedHttpSource() { @@ -131,19 +132,57 @@ abstract class MangaHub( client.newCall(request).execute() } + data class SMangaDTO( + val url: String, + val title: String, + val thumbnailUrl: String, + val signature: String, + ) + + private fun Element.toSignature(): String { + val author = this.select("small").text() + val chNum = this.select(".col-sm-6 a:contains(#)").text() + val genres = this.select(".genre-label").joinToString { it.text() } + + return author + chNum + genres + } + // popular override fun popularMangaRequest(page: Int): Request { return GET("$baseUrl/popular/page/$page", headers) } + // often enough there will be nearly identical entries with slightly different + // titles, URLs, and image names. in order to cut these "duplicates" down, + // assign a "signature" based on author name, chapter number, and genres + // if all of those are the same, then it it's the same manga + override fun popularMangaParse(response: Response): MangasPage { + val doc = response.asJsoup() + + val mangas = doc.select(popularMangaSelector()) + .map { + SMangaDTO( + it.select("h4 a").attr("abs:href"), + it.select("h4 a").text(), + it.select("img").attr("abs:src"), + it.toSignature(), + ) + } + .distinctBy { it.signature } + .map { + SManga.create().apply { + setUrlWithoutDomain(it.url) + title = it.title + thumbnail_url = it.thumbnailUrl + } + } + return MangasPage(mangas, doc.select(popularMangaNextPageSelector()).isNotEmpty()) + } + override fun popularMangaSelector() = ".col-sm-6:not(:has(a:contains(Yaoi)))" override fun popularMangaFromElement(element: Element): SManga { - return SManga.create().apply { - setUrlWithoutDomain(element.select("h4 a").attr("abs:href")) - title = element.select("h4 a").text() - thumbnail_url = element.select("img").attr("abs:src") - } + throw UnsupportedOperationException() } override fun popularMangaNextPageSelector() = "ul.pager li.next > a" @@ -153,10 +192,14 @@ abstract class MangaHub( return GET("$baseUrl/updates/page/$page", headers) } + override fun latestUpdatesParse(response: Response): MangasPage { + return popularMangaParse(response) + } + override fun latestUpdatesSelector() = popularMangaSelector() override fun latestUpdatesFromElement(element: Element): SManga { - return popularMangaFromElement(element) + throw UnsupportedOperationException() } override fun latestUpdatesNextPageSelector() = popularMangaNextPageSelector() @@ -184,34 +227,11 @@ abstract class MangaHub( override fun searchMangaSelector() = popularMangaSelector() override fun searchMangaFromElement(element: Element): SManga { - return popularMangaFromElement(element) + throw UnsupportedOperationException() } - // not sure if this still works, some duplicates i found is also using different thumbnail_url override fun searchMangaParse(response: Response): MangasPage { - val document = response.asJsoup() - - /* - * To remove duplicates we group by the thumbnail_url, which is - * common between duplicates. The duplicates have a suffix in the - * url "-by-{name}". Here we select the shortest url, to avoid - * removing manga that has "by" in the title already. - * Example: - * /manga/tales-of-demons-and-gods (kept) - * /manga/tales-of-demons-and-gods-by-mad-snail (removed) - * /manga/leveling-up-by-only-eating (kept) - */ - val mangas = document.select(searchMangaSelector()).map { element -> - searchMangaFromElement(element) - }.groupBy { it.thumbnail_url }.mapValues { (_, values) -> - values.minByOrNull { it.url.length }!! - }.values.toList() - - val hasNextPage = searchMangaNextPageSelector().let { selector -> - document.select(selector).first() - } != null - - return MangasPage(mangas, hasNextPage) + return popularMangaParse(response) } override fun searchMangaNextPageSelector() = popularMangaNextPageSelector() @@ -326,12 +346,6 @@ abstract class MangaHub( put( "variables", buildJsonObject { - val mangaSource = when (name) { - "MangaHub" -> "m01" - "MangaReader.site" -> "mr01" - "MangaPanda.onl" -> "mr02" - else -> null - } val chapterUrl = chapter.url.split("/") put("mangaSource", mangaSource) diff --git a/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/mangahub/MangaHubGenerator.kt b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/mangahub/MangaHubGenerator.kt index 77f8ecd8d..ea3d6b5d4 100644 --- a/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/mangahub/MangaHubGenerator.kt +++ b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/mangahub/MangaHubGenerator.kt @@ -9,22 +9,20 @@ class MangaHubGenerator : ThemeSourceGenerator { override val themeClass = "MangaHub" - override val baseVersionCode: Int = 25 + override val baseVersionCode: Int = 26 override val sources = listOf( -// SingleLang("1Manga.co", "https://1manga.co", "en", isNsfw = true, className = "OneMangaCo"), -// SingleLang("MangaFox.fun", "https://mangafox.fun", "en", isNsfw = true, className = "MangaFoxFun"), -// SingleLang("MangaHere.onl", "https://mangahere.onl", "en", isNsfw = true, className = "MangaHereOnl"), + SingleLang("1Manga.co", "https://1manga.co", "en", isNsfw = true, className = "OneMangaCo"), + SingleLang("MangaFox.fun", "https://mangafox.fun", "en", isNsfw = true, className = "MangaFoxFun"), + SingleLang("MangaHere.onl", "https://mangahere.onl", "en", isNsfw = true, className = "MangaHereOnl"), SingleLang("MangaHub", "https://mangahub.io", "en", isNsfw = true, overrideVersionCode = 10, className = "MangaHubIo"), -// SingleLang("Mangakakalot.fun", "https://mangakakalot.fun", "en", isNsfw = true, className = "MangakakalotFun"), -// SingleLang("MangaNel", "https://manganel.me", "en", isNsfw = true), -// SingleLang("MangaOnline.fun", "https://mangaonline.fun", "en", isNsfw = true, className = "MangaOnlineFun"), + SingleLang("Mangakakalot.fun", "https://mangakakalot.fun", "en", isNsfw = true, className = "MangakakalotFun"), + SingleLang("MangaNel", "https://manganel.me", "en", isNsfw = true), + SingleLang("MangaOnline.fun", "https://mangaonline.fun", "en", isNsfw = true, className = "MangaOnlineFun"), SingleLang("MangaPanda.onl", "https://mangapanda.onl", "en", className = "MangaPandaOnl"), SingleLang("MangaReader.site", "https://mangareader.site", "en", className = "MangaReaderSite"), -// SingleLang("MangaToday", "https://mangatoday.fun", "en", isNsfw = true), -// SingleLang("MangaTown (unoriginal)", "https://manga.town", "en", isNsfw = true, className = "MangaTownHub"), - // SingleLang("MF Read Online", "https://mangafreereadonline.com", "en", isNsfw = true), // different pageListParse logic - // SingleLang("OneManga.info", "https://onemanga.info", "en", isNsfw = true, className = "OneMangaInfo"), // Some chapters link to 1manga.co, hard to filter + SingleLang("MangaToday", "https://mangatoday.fun", "en", isNsfw = true), + SingleLang("OneManga.info", "https://onemanga.info", "en", isNsfw = true, className = "OneMangaInfo"), // Some chapters link to 1manga.co, hard to filter ) companion object {