diff --git a/src/en/mangamainac/res/mipmap-hdpi/ic_launcher.png b/multisrc/overrides/mangamainac/default/res/mipmap-hdpi/ic_launcher.png similarity index 100% rename from src/en/mangamainac/res/mipmap-hdpi/ic_launcher.png rename to multisrc/overrides/mangamainac/default/res/mipmap-hdpi/ic_launcher.png diff --git a/src/en/mangamainac/res/mipmap-mdpi/ic_launcher.png b/multisrc/overrides/mangamainac/default/res/mipmap-mdpi/ic_launcher.png similarity index 100% rename from src/en/mangamainac/res/mipmap-mdpi/ic_launcher.png rename to multisrc/overrides/mangamainac/default/res/mipmap-mdpi/ic_launcher.png diff --git a/src/en/mangamainac/res/mipmap-xhdpi/ic_launcher.png b/multisrc/overrides/mangamainac/default/res/mipmap-xhdpi/ic_launcher.png similarity index 100% rename from src/en/mangamainac/res/mipmap-xhdpi/ic_launcher.png rename to multisrc/overrides/mangamainac/default/res/mipmap-xhdpi/ic_launcher.png diff --git a/src/en/mangamainac/res/mipmap-xxhdpi/ic_launcher.png b/multisrc/overrides/mangamainac/default/res/mipmap-xxhdpi/ic_launcher.png similarity index 100% rename from src/en/mangamainac/res/mipmap-xxhdpi/ic_launcher.png rename to multisrc/overrides/mangamainac/default/res/mipmap-xxhdpi/ic_launcher.png diff --git a/src/en/mangamainac/res/mipmap-xxxhdpi/ic_launcher.png b/multisrc/overrides/mangamainac/default/res/mipmap-xxxhdpi/ic_launcher.png similarity index 100% rename from src/en/mangamainac/res/mipmap-xxxhdpi/ic_launcher.png rename to multisrc/overrides/mangamainac/default/res/mipmap-xxxhdpi/ic_launcher.png diff --git a/src/en/mangamainac/res/web_hi_res_512.png b/multisrc/overrides/mangamainac/default/res/web_hi_res_512.png similarity index 100% rename from src/en/mangamainac/res/web_hi_res_512.png rename to multisrc/overrides/mangamainac/default/res/web_hi_res_512.png diff --git a/src/en/tcbscans/res/mipmap-hdpi/ic_launcher.png b/multisrc/overrides/mangamainac/tcbscans/res/mipmap-hdpi/ic_launcher.png similarity index 100% rename from src/en/tcbscans/res/mipmap-hdpi/ic_launcher.png rename to multisrc/overrides/mangamainac/tcbscans/res/mipmap-hdpi/ic_launcher.png diff --git a/src/en/tcbscans/res/mipmap-mdpi/ic_launcher.png b/multisrc/overrides/mangamainac/tcbscans/res/mipmap-mdpi/ic_launcher.png similarity index 100% rename from src/en/tcbscans/res/mipmap-mdpi/ic_launcher.png rename to multisrc/overrides/mangamainac/tcbscans/res/mipmap-mdpi/ic_launcher.png diff --git a/src/en/tcbscans/res/mipmap-xhdpi/ic_launcher.png b/multisrc/overrides/mangamainac/tcbscans/res/mipmap-xhdpi/ic_launcher.png similarity index 100% rename from src/en/tcbscans/res/mipmap-xhdpi/ic_launcher.png rename to multisrc/overrides/mangamainac/tcbscans/res/mipmap-xhdpi/ic_launcher.png diff --git a/src/en/tcbscans/res/mipmap-xxhdpi/ic_launcher.png b/multisrc/overrides/mangamainac/tcbscans/res/mipmap-xxhdpi/ic_launcher.png similarity index 100% rename from src/en/tcbscans/res/mipmap-xxhdpi/ic_launcher.png rename to multisrc/overrides/mangamainac/tcbscans/res/mipmap-xxhdpi/ic_launcher.png diff --git a/src/en/tcbscans/res/mipmap-xxxhdpi/ic_launcher.png b/multisrc/overrides/mangamainac/tcbscans/res/mipmap-xxxhdpi/ic_launcher.png similarity index 100% rename from src/en/tcbscans/res/mipmap-xxxhdpi/ic_launcher.png rename to multisrc/overrides/mangamainac/tcbscans/res/mipmap-xxxhdpi/ic_launcher.png diff --git a/src/en/tcbscans/res/web_hi_res_512.png b/multisrc/overrides/mangamainac/tcbscans/res/web_hi_res_512.png similarity index 100% rename from src/en/tcbscans/res/web_hi_res_512.png rename to multisrc/overrides/mangamainac/tcbscans/res/web_hi_res_512.png diff --git a/src/en/tcbscans/src/eu/kanade/tachiyomi/extension/en/tcbscans/TCBScans.kt b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/mangamainac/MangaMainac.kt similarity index 80% rename from src/en/tcbscans/src/eu/kanade/tachiyomi/extension/en/tcbscans/TCBScans.kt rename to multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/mangamainac/MangaMainac.kt index 4da4260e0..af7082b13 100644 --- a/src/en/tcbscans/src/eu/kanade/tachiyomi/extension/en/tcbscans/TCBScans.kt +++ b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/mangamainac/MangaMainac.kt @@ -1,4 +1,4 @@ -package eu.kanade.tachiyomi.extension.en.tcbscans +package eu.kanade.tachiyomi.multisrc.mangamainac import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.source.model.FilterList @@ -14,11 +14,15 @@ import org.jsoup.nodes.Document import org.jsoup.nodes.Element import java.util.Calendar -class TCBScans : ParsedHttpSource() { - override val name = "TCB Scans" - override val baseUrl = "https://onepiecechapters.com" - override val lang = "en" +// Based On TCBScans sources +// MangaManiac is a network of sites built by Animemaniac.co. + +abstract class MangaMainac( + override val name: String, + override val baseUrl: String, + override val lang: String, +) : ParsedHttpSource() { override val supportsLatest = false override val client: OkHttpClient = network.cloudflareClient @@ -32,7 +36,7 @@ class TCBScans : ParsedHttpSource() { override fun popularMangaFromElement(element: Element): SManga { val manga = SManga.create() manga.thumbnail_url = element.select(".mangainfo_body > img").attr("src") - manga.url = element.select("#primary-menu .menu-item:first-child").attr("href") + manga.url = "" //element.select("#primary-menu .menu-item:first-child").attr("href") manga.title = element.select(".intro_content h2").text() return manga } @@ -41,30 +45,30 @@ class TCBScans : ParsedHttpSource() { // latest override fun latestUpdatesRequest(page: Int): Request = throw UnsupportedOperationException() - override fun latestUpdatesSelector(): String = throw UnsupportedOperationException() - override fun latestUpdatesFromElement(element: Element): SManga = throw UnsupportedOperationException() - override fun latestUpdatesNextPageSelector(): String? = throw UnsupportedOperationException() // search - override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request = popularMangaRequest(page) - - override fun searchMangaSelector(): String = popularMangaSelector() - - override fun searchMangaFromElement(element: Element): SManga = popularMangaFromElement(element) - - override fun searchMangaNextPageSelector(): String? = null + override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request = throw UnsupportedOperationException() + override fun searchMangaSelector(): String = throw UnsupportedOperationException() + override fun searchMangaFromElement(element: Element): SManga = throw UnsupportedOperationException() + override fun searchMangaNextPageSelector(): String? = throw UnsupportedOperationException() // manga details override fun mangaDetailsParse(document: Document) = SManga.create().apply { + val info = document.select(".intro_content").text() thumbnail_url = document.select(".mangainfo_body > img").attr("src") title = document.select(".intro_content h2").text() + author = if ("Author" in info) substringextract(info, "Author(s):", "Released") else null + artist = author + genre = if ("Genre" in info) substringextract(info, "Genre(s):", "Status") else null status = parseStatus(document.select(".intro_content").text()) - description = document.select(".intro_content").joinToString("\n") { it.text() } + description = if ("Description" in info) info.substringAfter("Description:").trim() else null } + private fun substringextract(text: String, start: String, end: String): String = text.substringAfter(start).substringBefore(end).trim() + private fun parseStatus(element: String): Int = when { element.toLowerCase().contains("ongoing (pub") -> SManga.ONGOING element.toLowerCase().contains("completed (pub") -> SManga.COMPLETED diff --git a/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/mangamainac/MangaMainacGenerator.kt b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/mangamainac/MangaMainacGenerator.kt new file mode 100644 index 000000000..c2871e90f --- /dev/null +++ b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/mangamainac/MangaMainacGenerator.kt @@ -0,0 +1,43 @@ +package eu.kanade.tachiyomi.multisrc.mangamainac + +import generator.ThemeSourceData.SingleLang +import generator.ThemeSourceGenerator + +class MangaMainacGenerator : ThemeSourceGenerator { + + override val themePkg = "mangamainac" + + override val themeClass = "MangaMainac" + + override val baseVersionCode: Int = 1 + + override val sources = listOf( + SingleLang("Read Boku No Hero Academia Manga Online", "https://w23.readheroacademia.com/", "en"), + SingleLang("Read One Punch Man Manga Online", "https://w17.readonepunchman.net/", "en"), + SingleLang("Read One Webcomic Manga Online", "https://w1.onewebcomic.net/", "en"), + SingleLang("Read Solo Leveling", "https://w3.sololeveling.net/", "en"), + SingleLang("Read Jojolion", "https://readjojolion.com/", "en"), + SingleLang("Hajime no Ippo Manga", "https://readhajimenoippo.com/", "en"), + SingleLang("Read Berserk Manga Online", "https://berserkmanga.net/", "en"), + SingleLang("Read Kaguya-sama: Love is War", "https://kaguyasama.net/", "en", className = "ReadKaguyaSamaLoveIsWar", pkgName = "readkaguyasamaloveiswar"), + SingleLang("Read Domestic Girlfriend Manga", "https://domesticgirlfriend.net/", "en"), + SingleLang("Read Black Clover Manga", "https://w1.blackclovermanga2.com/", "en"), + SingleLang("TCB Scans", "https://onepiecechapters.com/", "en", overrideVersionCode = 2), + SingleLang("Read Shingeki no Kyojin Manga", "https://readshingekinokyojin.com/", "en"), + SingleLang("Read Nanatsu no Taizai Manga", "https://w1.readnanatsutaizai.net/", "en"), + SingleLang("Read Rent a Girlfriend Manga", "https://kanojo-okarishimasu.com/", "en"), + //Sites that are currently down from my end, should be rechecked by some one else at some point + // + //SingleLang("", "https://5-toubunnohanayome.net/", "en"), //Down at time of creating this generator + //SingleLang("", "http://beastars.net/", "en"), //Down at time of creating this generator + //SingleLang("", "https://neverlandmanga.net/", "en"), //Down at time of creating this generator + //SingleLang("", "https://ww1.readhunterxhunter.net/", "en"), //Down at time of creating this generator + ) + + companion object { + @JvmStatic + fun main(args: Array) { + MangaMainacGenerator().createAll() + } + } +} diff --git a/src/en/mangamainac/AndroidManifest.xml b/src/en/mangamainac/AndroidManifest.xml deleted file mode 100644 index 30deb7f79..000000000 --- a/src/en/mangamainac/AndroidManifest.xml +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/src/en/mangamainac/build.gradle b/src/en/mangamainac/build.gradle deleted file mode 100644 index 8f16ce4d9..000000000 --- a/src/en/mangamainac/build.gradle +++ /dev/null @@ -1,12 +0,0 @@ -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' - -ext { - extName = 'MangaMainac' - pkgNameSuffix = 'en.mangamainac' - extClass = '.MangaMainac' - extVersionCode = 2 - libVersion = '1.2' -} - -apply from: "$rootDir/common.gradle" diff --git a/src/en/mangamainac/src/eu/kanade/tachiyomi/extension/en/mangamainac/MangaMainac.kt b/src/en/mangamainac/src/eu/kanade/tachiyomi/extension/en/mangamainac/MangaMainac.kt deleted file mode 100644 index ef6eb5a3d..000000000 --- a/src/en/mangamainac/src/eu/kanade/tachiyomi/extension/en/mangamainac/MangaMainac.kt +++ /dev/null @@ -1,162 +0,0 @@ -package eu.kanade.tachiyomi.extension.en.mangamainac - -import eu.kanade.tachiyomi.network.GET -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.Request -import okhttp3.Response -import org.jsoup.nodes.Document -import org.jsoup.nodes.Element -import rx.Observable -import java.util.Calendar - -// MangaManiac is a network of sites built by Animemaniac.co. - -class MangaMainac : ParsedHttpSource() { - - companion object { - val sourceList = listOf( - Pair("Boku No Hero Academia", "https://w15.readheroacademia.com"), - Pair("One Punch Man", "https://w12.readonepunchman.net"), - Pair("One Punch Man (webcomic)", "https://onewebcomic.net"), - Pair("Solo Leveling", "https://sololeveling.net"), - Pair("Jojolion", "https://readjojolion.com"), - Pair("Hajime no Ippo", "https://readhajimenoippo.com"), - Pair("Berserk", "https://berserkmanga.net"), - Pair("The Quintessential Quintuplets", "https://5-toubunnohanayome.net"), - Pair("Kaguya Wants to be Confessed To", "https://kaguyasama.net"), - Pair("Domestic Girlfriend", "https://domesticgirlfriend.net"), - Pair("Black Clover", "https://w5.blackclovermanga.com"), - Pair("One Piece", "https://onepiecechapters.com/"), - Pair("The Promised Neverland", "https://neverlandmanga.net"), - Pair("Shingeki no Kyojin", "https://readshingekinokyojin.com"), - Pair("Nanatsu no Taizai", "https://w1.readnanatsutaizai.net") - ).sortedBy { it.first }.distinctBy { it.second } - } - - // Info - - override val name: String = "MangaMainac (Multiple Sites)" - override val baseUrl: String = "about:blank" - override val lang: String = "en" - override val supportsLatest: Boolean = false - - // Popular - - override fun fetchPopularManga(page: Int): Observable { - return Observable.just(MangasPage(sourceList.map { popularMangaFromPair(it.first, it.second) }, false)) - } - private fun popularMangaFromPair(name: String, sourceurl: String): SManga = SManga.create().apply { - title = name - url = sourceurl - } - override fun popularMangaRequest(page: Int): Request = throw Exception("Not used") - override fun popularMangaNextPageSelector(): String? = throw Exception("Not used") - override fun popularMangaSelector(): String = throw Exception("Not used") - override fun popularMangaFromElement(element: Element) = throw Exception("Not used") - - // Latest - override fun latestUpdatesRequest(page: Int): Request = throw Exception("Not used") - override fun latestUpdatesNextPageSelector(): String? = throw Exception("Not used") - override fun latestUpdatesSelector(): String = throw Exception("Not used") - override fun latestUpdatesFromElement(element: Element): SManga = throw Exception("Not used") - - // Search - - override fun searchMangaRequest(page: Int, query: String, filters: FilterList) = throw Exception("No Search Function") - override fun searchMangaNextPageSelector() = throw Exception("Not used") - override fun searchMangaSelector() = throw Exception("Not used") - override fun searchMangaFromElement(element: Element) = throw Exception("Not used") - - // Get Override - - override fun mangaDetailsRequest(manga: SManga): Request { - return GET(manga.url, headers) - } - override fun chapterListRequest(manga: SManga): Request { - return GET(manga.url, headers) - } - override fun pageListRequest(chapter: SChapter): Request { - return GET(chapter.url, headers) - } - - // Details - - override fun mangaDetailsParse(document: Document): SManga = SManga.create().apply { - val info = document.select(".intro_content").text() - title = document.select(".intro_content h2").text() - author = if ("Author" in info) substringextract(info, "Author(s):", "Released") else null - artist = author - genre = if ("Genre" in info) substringextract(info, "Genre(s):", "Status") else null - status = when (substringextract(info, "Status:", "(")) { - "Ongoing" -> SManga.ONGOING - "Completed" -> SManga.COMPLETED - else -> SManga.UNKNOWN - } - description = if ("Description" in info) info.substringAfter("Description:").trim() else null - thumbnail_url = document.select(".mangainfo_body img").attr("src") - } - private fun substringextract(text: String, start: String, end: String): String = text.substringAfter(start).substringBefore(end).trim() - - // Chapters - - override fun chapterListSelector(): String = ".chap_tab tr" - override fun chapterFromElement(element: Element): SChapter = SChapter.create().apply { - name = element.select("a").text() - url = element.select("a").attr("abs:href") - date_upload = parseRelativeDate(element.select("#time").text().substringBefore(" ago")) - } - override fun chapterListParse(response: Response): List { - val document = response.asJsoup() - val chapterList = document.select(chapterListSelector()).map { chapterFromElement(it) } - - return if (hasCountdown(chapterList[0])) - chapterList.subList(1, chapterList.size) - else - chapterList - } - private fun hasCountdown(chapter: SChapter): Boolean { - val document = client.newCall( - GET(chapter.url, headersBuilder().build()) - ).execute().asJsoup() - - return document - .select("iframe[src^=https://free.timeanddate.com/countdown/]") - .isNotEmpty() - } - - // Subtract relative date (e.g. posted 3 days ago) - private fun parseRelativeDate(date: String): Long { - val calendar = Calendar.getInstance() - - if (date.contains("yesterday")) { - calendar.apply { add(Calendar.DAY_OF_MONTH, -1) } - } else { - val trimmedDate = date.replace("one", "1").removeSuffix("s").split(" ") - - when (trimmedDate[1]) { - "year" -> calendar.apply { add(Calendar.YEAR, -trimmedDate[0].toInt()) } - "month" -> calendar.apply { add(Calendar.MONTH, -trimmedDate[0].toInt()) } - "week" -> calendar.apply { add(Calendar.WEEK_OF_MONTH, -trimmedDate[0].toInt()) } - "day" -> calendar.apply { add(Calendar.DAY_OF_MONTH, -trimmedDate[0].toInt()) } - } - } - - return calendar.timeInMillis - } - - // Pages - - override fun pageListParse(document: Document): List = mutableListOf().apply { - document.select(".img_container img").forEach { img -> - add(Page(size, "", img.attr("src"))) - } - } - - override fun imageUrlParse(document: Document): String = throw Exception("Not Used") -} diff --git a/src/en/tcbscans/AndroidManifest.xml b/src/en/tcbscans/AndroidManifest.xml deleted file mode 100644 index 30deb7f79..000000000 --- a/src/en/tcbscans/AndroidManifest.xml +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/src/en/tcbscans/build.gradle b/src/en/tcbscans/build.gradle deleted file mode 100644 index 20b9dd75c..000000000 --- a/src/en/tcbscans/build.gradle +++ /dev/null @@ -1,12 +0,0 @@ -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' - -ext { - extName = 'TCB Scans' - pkgNameSuffix = 'en.tcbscans' - extClass = '.TCBScans' - extVersionCode = 2 - libVersion = '1.2' -} - -apply from: "$rootDir/common.gradle"