MMRCMS - add MangaID, nsfw annotation (#4087)

This commit is contained in:
Mike 2020-08-12 06:08:09 -04:00 committed by GitHub
parent 908d2e9d09
commit 68f7fe16c4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 194 additions and 150 deletions

View File

@ -5,8 +5,9 @@ ext {
extName = 'My Manga Reader CMS (Many sources)' extName = 'My Manga Reader CMS (Many sources)'
pkgNameSuffix = 'all.mmrcms' pkgNameSuffix = 'all.mmrcms'
extClass = '.MyMangaReaderCMSSources' extClass = '.MyMangaReaderCMSSources'
extVersionCode = 47 extVersionCode = 48
libVersion = '1.2' libVersion = '1.2'
containsNsfw = true
} }
apply from: "$rootDir/common.gradle" apply from: "$rootDir/common.gradle"

File diff suppressed because one or more lines are too long

View File

@ -34,6 +34,8 @@ class Generator {
preRunTotal = Regex("""MMRSOURCE_(\d+)""").findAll(File(relativePath).readText(Charsets.UTF_8)).last().groupValues[1] preRunTotal = Regex("""MMRSOURCE_(\d+)""").findAll(File(relativePath).readText(Charsets.UTF_8)).last().groupValues[1]
} }
data class SourceData(val lang: String, val name: String, val baseUrl: String, val isNsfw: Boolean = false)
@TargetApi(Build.VERSION_CODES.O) @TargetApi(Build.VERSION_CODES.O)
fun generate() { fun generate() {
val buffer = StringBuffer() val buffer = StringBuffer()
@ -45,21 +47,22 @@ class Generator {
sources.forEach { sources.forEach {
try { try {
val map = mutableMapOf<String, Any>() val map = mutableMapOf<String, Any>()
map["language"] = it.first map["language"] = it.lang
map["name"] = it.second map["name"] = it.name
map["base_url"] = it.third map["base_url"] = it.baseUrl
map["supports_latest"] = supportsLatest(it.third) map["supports_latest"] = supportsLatest(it.baseUrl)
map["isNsfw"] = it.isNsfw
val advancedSearchDocument = getDocument("${it.third}/advanced-search", false) val advancedSearchDocument = getDocument("${it.baseUrl}/advanced-search", false)
var parseCategories = mutableListOf<Map<String, String>>() var parseCategories = mutableListOf<Map<String, String>>()
if (advancedSearchDocument != null) { if (advancedSearchDocument != null) {
parseCategories = parseCategories(advancedSearchDocument) parseCategories = parseCategories(advancedSearchDocument)
} }
val homePageDocument = getDocument(it.third) val homePageDocument = getDocument(it.baseUrl)
val itemUrl = getItemUrl(homePageDocument, it.third) val itemUrl = getItemUrl(homePageDocument, it.baseUrl)
var prefix = itemUrl.substringAfterLast("/").substringBeforeLast("/") var prefix = itemUrl.substringAfterLast("/").substringBeforeLast("/")
@ -69,7 +72,7 @@ class Generator {
prefix = "manga" prefix = "manga"
} }
val mangaListDocument = getDocument("${it.third}/$prefix-list")!! val mangaListDocument = getDocument("${it.baseUrl}/$prefix-list")!!
if (parseCategories.isEmpty()) { if (parseCategories.isEmpty()) {
parseCategories = parseCategories(mangaListDocument) parseCategories = parseCategories(mangaListDocument)
@ -82,14 +85,14 @@ class Generator {
map["tags"] = tags map["tags"] = tags
} }
if (!itemUrl.startsWith(it.third)) println("**Note: ${it.second} URL does not match! Check for changes: \n ${it.third} vs $itemUrl") if (!itemUrl.startsWith(it.baseUrl)) println("**Note: ${it.name} URL does not match! Check for changes: \n ${it.baseUrl} vs $itemUrl")
val toJson = Gson().toJson(map) val toJson = Gson().toJson(map)
buffer.append("private const val MMRSOURCE_$number = \"\"\"$toJson\"\"\"\n") buffer.append("private const val MMRSOURCE_$number = \"\"\"$toJson\"\"\"\n")
number++ number++
} catch (e: Exception) { } catch (e: Exception) {
println("error generating source ${it.second} ${e.printStackTrace()}") println("error generating source ${it.name} ${e.printStackTrace()}")
} }
} }
@ -228,98 +231,99 @@ class Generator {
companion object { companion object {
val sources = listOf( val sources = listOf(
Triple("ar", "مانجا اون لاين", "https://onma.me"), SourceData("ar", "مانجا اون لاين", "https://onma.me"),
Triple("en", "Read Comics Online", "https://readcomicsonline.ru"), SourceData("en", "Read Comics Online", "https://readcomicsonline.ru"),
Triple("en", "Biamam Scans", "https://biamam.com"), SourceData("en", "Biamam Scans", "https://biamam.com"),
Triple("en", "Fallen Angels", "https://manga.fascans.com"), SourceData("en", "Fallen Angels", "https://manga.fascans.com"),
Triple("en", "Mangawww Reader", "https://mangawww.club"), SourceData("en", "White Cloud Pavilion", "https://www.whitecloudpavilion.com/manga/free"),
Triple("en", "White Cloud Pavilion", "https://www.whitecloudpavilion.com/manga/free"), SourceData("fr", "Scan FR", "https://www.scan-fr.co"),
Triple("fr", "Scan FR", "https://www.scan-fr.co"), SourceData("fr", "Scan VF", "https://www.scan-vf.net"),
Triple("fr", "Scan VF", "https://www.scan-vf.net"), SourceData("fr", "Scan OP", "https://scan-op.com"),
Triple("fr", "Scan OP", "https://scan-op.com"), SourceData("id", "Komikid", "https://www.komikid.com"),
Triple("id", "Komikid", "https://www.komikid.com"), SourceData("pl", "ToraScans", "http://torascans.pl"),
Triple("pl", "ToraScans", "http://torascans.pl"), SourceData("pt-BR", "Comic Space", "https://www.comicspace.com.br"),
Triple("pt-BR", "Comic Space", "https://www.comicspace.com.br"), SourceData("pt-BR", "Mangás Yuri", "https://mangasyuri.net"),
Triple("pt-BR", "Mangás Yuri", "https://mangasyuri.net"), SourceData("pl", "Dracaena", "https://dracaena.webd.pl/czytnik"),
Triple("pl", "Dracaena", "https://dracaena.webd.pl/czytnik"), SourceData("pl", "Nikushima", "http://azbivo.webd.pro"),
Triple("pl", "Nikushima", "http://azbivo.webd.pro"), SourceData("tr", "MangaHanta", "http://mangahanta.com"),
Triple("tr", "MangaHanta", "http://mangahanta.com"), SourceData("vi", "Fallen Angels Scans", "https://truyen.fascans.com"),
Triple("vi", "Fallen Angels Scans", "https://truyen.fascans.com"), SourceData("es", "LeoManga", "https://leomanga.me"),
Triple("es", "LeoManga", "https://leomanga.me"), SourceData("es", "submanga", "https://submangas.net"),
Triple("es", "submanga", "https://submangas.net"), SourceData("es", "Mangadoor", "https://mangadoor.com"),
Triple("es", "Mangadoor", "https://mangadoor.com"), SourceData("es", "Mangas.pw", "https://mangas.in"),
Triple("es", "Mangas.pw", "https://mangas.in"), SourceData("es", "Tumangaonline.co", "http://tumangaonline.uno"),
Triple("es", "Tumangaonline.co", "http://tumangaonline.uno"), SourceData("bg", "Utsukushii", "https://manga.utsukushii-bg.com"),
Triple("bg", "Utsukushii", "https://manga.utsukushii-bg.com"), SourceData("es", "Universo Yuri", "https://universoyuri.com"),
Triple("es", "Universo Yuri", "https://universoyuri.com"), SourceData("pl", "Phoenix-Scans", "https://phoenix-scans.pl"),
Triple("pl", "Phoenix-Scans", "https://phoenix-scans.pl"), SourceData("ru", "Japit Comics", "https://j-comics.ru"),
Triple("ru", "Japit Comics", "https://j-comics.ru"), SourceData("tr", "Puzzmos", "https://puzzmos.com"),
Triple("tr", "Puzzmos", "https://puzzmos.com"), SourceData("fr", "Scan-1", "https://wwv.scan-1.com"),
Triple("fr", "Scan-1", "https://wwv.scan-1.com"), SourceData("fr", "Lelscan-VF", "https://www.lelscan-vf.com"),
Triple("fr", "Lelscan-VF", "https://www.lelscan-vf.com"), SourceData("id", "MangaSusu", "https://www.mangasusu.site"),
Triple("id", "MangaSusu", "https://www.mangasusu.site"), SourceData("id", "Komik Manga", "https://adm.komikmanga.com"),
Triple("id", "Komik Manga", "https://adm.komikmanga.com"), SourceData("ko", "Mangazuki Raws", "https://raws.mangazuki.co"),
Triple("ko", "Mangazuki Raws", "https://raws.mangazuki.co"), SourceData("pt-BR", "Remangas", "https://remangas.top"),
Triple("pt-BR", "Remangas", "https://remangas.top"), SourceData("pt-BR", "AnimaRegia", "https://animaregia.net"),
Triple("pt-BR", "AnimaRegia", "https://animaregia.net"), SourceData("tr", "NoxSubs", "https://noxsubs.com"),
Triple("tr", "NoxSubs", "https://noxsubs.com"), SourceData("id", "MangaYu", "https://mangayu.com"),
Triple("id", "MangaYu", "https://mangayu.com"), SourceData("tr", "MangaVadisi", "http://manga-v2.mangavadisi.org"),
Triple("tr", "MangaVadisi", "http://manga-v2.mangavadisi.org"), SourceData("id", "MangaID", "https://mangaid.click"),
// NOTE: THIS SOURCE CONTAINS A CUSTOM LANGUAGE SYSTEM (which will be ignored)! // NOTE: THIS SOURCE CONTAINS A CUSTOM LANGUAGE SYSTEM (which will be ignored)!
Triple("other", "HentaiShark", "https://www.hentaishark.com")) SourceData("other", "HentaiShark", "https://www.hentaishark.com", true))
// Changed CMS // Changed CMS
// Triple("en", "MangaTreat Scans", "http://www.mangatreat.com"), // SourceData("en", "MangaTreat Scans", "http://www.mangatreat.com"),
// Triple("en", "Chibi Manga Reader", "https://www.cmreader.info"), // SourceData("en", "Chibi Manga Reader", "https://www.cmreader.info"),
// Triple("tr", "Epikmanga", "https://www.epikmanga.com"), // SourceData("tr", "Epikmanga", "https://www.epikmanga.com"),
// Triple("en", "Hatigarm Scans", "https://hatigarmscans.net"), // SourceData("en", "Hatigarm Scans", "https://hatigarmscans.net"),
// Went offline // Went offline
// Triple("ru", "Anigai clan", "http://anigai.ru"), // SourceData("en", "Mangawww Reader", "https://mangawww.club"),
// Triple("en", "ZXComic", "http://zxcomic.com"), // SourceData("ru", "Anigai clan", "http://anigai.ru"),
// Triple("es", "SOS Scanlation", "https://sosscanlation.com"), // SourceData("en", "ZXComic", "http://zxcomic.com"),
// Triple("es", "MangaCasa", "https://mangacasa.com")) // SourceData("es", "SOS Scanlation", "https://sosscanlation.com"),
// Triple("ja", "RAW MANGA READER", "https://rawmanga.site"), // SourceData("es", "MangaCasa", "https://mangacasa.com"))
// Triple("ar", "Manga FYI", "http://mangafyi.com/manga/arabic"), // SourceData("ja", "RAW MANGA READER", "https://rawmanga.site"),
// Triple("en", "MangaRoot", "http://mangaroot.com"), // SourceData("ar", "Manga FYI", "http://mangafyi.com/manga/arabic"),
// Triple("en", "MangaForLife", "http://manga4ever.com"), // SourceData("en", "MangaRoot", "http://mangaroot.com"),
// Triple("en", "Manga Spoil", "http://mangaspoil.com"), // SourceData("en", "MangaForLife", "http://manga4ever.com"),
// Triple("en", "MangaBlue", "http://mangablue.com"), // SourceData("en", "Manga Spoil", "http://mangaspoil.com"),
// Triple("en", "Manga Forest", "https://mangaforest.com"), // SourceData("en", "MangaBlue", "http://mangablue.com"),
// Triple("en", "DManga", "http://dmanga.website"), // SourceData("en", "Manga Forest", "https://mangaforest.com"),
// Triple("en", "DB Manga", "http://dbmanga.com"), // SourceData("en", "DManga", "http://dmanga.website"),
// Triple("en", "Mangacox", "http://mangacox.com"), // SourceData("en", "DB Manga", "http://dbmanga.com"),
// Triple("en", "GO Manhwa", "http://gomanhwa.xyz"), // SourceData("en", "Mangacox", "http://mangacox.com"),
// Triple("en", "KoManga", "https://komanga.net"), // SourceData("en", "GO Manhwa", "http://gomanhwa.xyz"),
// Triple("en", "Manganimecan", "http://manganimecan.com"), // SourceData("en", "KoManga", "https://komanga.net"),
// Triple("en", "Hentai2Manga", "http://hentai2manga.com"), // SourceData("en", "Manganimecan", "http://manganimecan.com"),
// Triple("en", "4 Manga", "http://4-manga.com"), // SourceData("en", "Hentai2Manga", "http://hentai2manga.com"),
// Triple("en", "XYXX.INFO", "http://xyxx.info"), // SourceData("en", "4 Manga", "http://4-manga.com"),
// Triple("en", "Isekai Manga Reader", "https://isekaimanga.club"), // SourceData("en", "XYXX.INFO", "http://xyxx.info"),
// Triple("fa", "TrinityReader", "http://trinityreader.pw"), // SourceData("en", "Isekai Manga Reader", "https://isekaimanga.club"),
// Triple("fr", "Manga-LEL", "https://www.manga-lel.com"), // SourceData("fa", "TrinityReader", "http://trinityreader.pw"),
// Triple("fr", "Manga Etonnia", "https://www.etonnia.com"), // SourceData("fr", "Manga-LEL", "https://www.manga-lel.com"),
// Triple("fr", "ScanFR.com"), "http://scanfr.com"), // SourceData("fr", "Manga Etonnia", "https://www.etonnia.com"),
// Triple("fr", "Manga FYI", "http://mangafyi.com/manga/french"), // SourceData("fr", "ScanFR.com"), "http://scanfr.com"),
// Triple("fr", "scans-manga", "http://scans-manga.com"), // SourceData("fr", "Manga FYI", "http://mangafyi.com/manga/french"),
// Triple("fr", "Henka no Kaze", "http://henkanokazelel.esy.es/upload"), // SourceData("fr", "scans-manga", "http://scans-manga.com"),
// Triple("fr", "Tous Vos Scans", "http://www.tous-vos-scans.com"), // SourceData("fr", "Henka no Kaze", "http://henkanokazelel.esy.es/upload"),
// Triple("id", "Manga Desu", "http://mangadesu.net"), // SourceData("fr", "Tous Vos Scans", "http://www.tous-vos-scans.com"),
// Triple("id", "Komik Mangafire.ID", "http://go.mangafire.id"), // SourceData("id", "Manga Desu", "http://mangadesu.net"),
// Triple("id", "MangaOnline", "https://mangaonline.web.id"), // SourceData("id", "Komik Mangafire.ID", "http://go.mangafire.id"),
// Triple("id", "MangaNesia", "https://manganesia.com"), // SourceData("id", "MangaOnline", "https://mangaonline.web.id"),
// Triple("id", "MangaID", "https://mangaid.me" // SourceData("id", "MangaNesia", "https://manganesia.com"),
// Triple("id", "Manga Seru", "http://www.mangaseru.top" // SourceData("id", "MangaID", "https://mangaid.me"
// Triple("id", "Manga FYI", "http://mangafyi.com/manga/indonesian" // SourceData("id", "Manga Seru", "http://www.mangaseru.top"
// Triple("id", "Bacamangaku", "http://www.bacamangaku.com"), // SourceData("id", "Manga FYI", "http://mangafyi.com/manga/indonesian"
// Triple("id", "Indo Manga Reader", "http://indomangareader.com"), // SourceData("id", "Bacamangaku", "http://www.bacamangaku.com"),
// Triple("it", "Kingdom Italia Reader", "http://kireader.altervista.org"), // SourceData("id", "Indo Manga Reader", "http://indomangareader.com"),
// Triple("ja", "IchigoBook", "http://ichigobook.com"), // SourceData("it", "Kingdom Italia Reader", "http://kireader.altervista.org"),
// Triple("ja", "Mangaraw Online", "http://mangaraw.online" // SourceData("ja", "IchigoBook", "http://ichigobook.com"),
// Triple("ja", "Mangazuki RAWS", "https://raws.mangazuki.co"), // SourceData("ja", "Mangaraw Online", "http://mangaraw.online"
// Triple("ja", "MangaRAW", "https://www.mgraw.com"), // SourceData("ja", "Mangazuki RAWS", "https://raws.mangazuki.co"),
// Triple("ja", "マンガ/漫画 マガジン/雑誌 raw", "http://netabare-manga-raw.com"), // SourceData("ja", "MangaRAW", "https://www.mgraw.com"),
// Triple("ru", "NAKAMA", "http://nakama.ru"), // SourceData("ja", "マンガ/漫画 マガジン/雑誌 raw", "http://netabare-manga-raw.com"),
// Triple("tr", "MangAoi", "http://mangaoi.com"), // SourceData("ru", "NAKAMA", "http://nakama.ru"),
// Triple("tr", "ManhuaTR", "http://www.manhua-tr.com"), // SourceData("tr", "MangAoi", "http://mangaoi.com"),
// SourceData("tr", "ManhuaTR", "http://www.manhua-tr.com"),
val relativePath = System.getProperty("user.dir") + "/src/all/mmrcms/src/eu/kanade/tachiyomi/extension/all/mmrcms/GeneratedSources.kt" val relativePath = System.getProperty("user.dir") + "/src/all/mmrcms/src/eu/kanade/tachiyomi/extension/all/mmrcms/GeneratedSources.kt"

View File

@ -7,6 +7,7 @@ import com.github.salomonbrys.kotson.array
import com.github.salomonbrys.kotson.get import com.github.salomonbrys.kotson.get
import com.github.salomonbrys.kotson.string import com.github.salomonbrys.kotson.string
import com.google.gson.JsonParser import com.google.gson.JsonParser
import eu.kanade.tachiyomi.annotations.Nsfw
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.asObservableSuccess import eu.kanade.tachiyomi.network.asObservableSuccess
import eu.kanade.tachiyomi.source.model.Filter import eu.kanade.tachiyomi.source.model.Filter
@ -28,11 +29,11 @@ import okhttp3.Response
import org.jsoup.nodes.Element import org.jsoup.nodes.Element
import rx.Observable import rx.Observable
class MyMangaReaderCMSSource( open class MyMangaReaderCMSSource(
override val lang: String, final override val lang: String,
override val name: String, final override val name: String,
override val baseUrl: String, final override val baseUrl: String,
override val supportsLatest: Boolean, final override val supportsLatest: Boolean,
private val itemUrl: String, private val itemUrl: String,
private val categoryMappings: List<Pair<String, String>>, private val categoryMappings: List<Pair<String, String>>,
private val tagMappings: List<Pair<String, String>>? private val tagMappings: List<Pair<String, String>>?
@ -137,8 +138,12 @@ class MyMangaReaderCMSSource(
if (document.location().contains("page=1")) latestTitles.clear() if (document.location().contains("page=1")) latestTitles.clear()
val mangas = document.select(latestUpdatesSelector()) val mangas = document.select(latestUpdatesSelector())
.map { element -> .let { elements ->
if (element.hasClass("manga-item")) latestUpdatesFromElement(element) else gridLatestUpdatesFromElement(element) if (elements.select("a").firstOrNull()?.hasText() == true) {
elements.map { latestUpdatesFromElement(it) }
} else {
document.select(gridLatestUpdatesSelector()).map { gridLatestUpdatesFromElement(it) }
}
} }
.distinctBy { manga -> manga.title } .distinctBy { manga -> manga.title }
.filterNot { manga -> manga.title in latestTitles } .filterNot { manga -> manga.title in latestTitles }
@ -146,14 +151,15 @@ class MyMangaReaderCMSSource(
return MangasPage(mangas, document.select(latestUpdatesNextPageSelector()) != null) return MangasPage(mangas, document.select(latestUpdatesNextPageSelector()) != null)
} }
private fun latestUpdatesSelector() = "div.mangalist div.manga-item, div.grid-manga tr" private fun latestUpdatesSelector() = "div.mangalist div.manga-item"
private fun latestUpdatesNextPageSelector() = "a[rel=next]" private fun latestUpdatesNextPageSelector() = "a[rel=next]"
private fun latestUpdatesFromElement(element: Element): SManga = SManga.create().apply { private fun latestUpdatesFromElement(element: Element): SManga = SManga.create().apply {
url = element.select("a").first().attr("abs:href").substringAfter(baseUrl) // intentionally not using setUrlWithoutDomain url = element.select("a").first().attr("abs:href").substringAfter(baseUrl) // intentionally not using setUrlWithoutDomain
title = element.select("a").first().text().trim() title = element.select("a").first().text().trim()
thumbnail_url = "$baseUrl/uploads/manga/${url.substringAfterLast('/')}/cover/cover_250x350.jpg" thumbnail_url = "$baseUrl/uploads/manga/${url.substringAfterLast('/')}/cover/cover_250x350.jpg"
} }
// MangaYu, for instance, needs this // MangaYu and MangaID needs this
private fun gridLatestUpdatesSelector() = "div.mangalist div.manga-item, div.grid-manga tr"
private fun gridLatestUpdatesFromElement(element: Element): SManga = SManga.create().apply { private fun gridLatestUpdatesFromElement(element: Element): SManga = SManga.create().apply {
element.select("a.chart-title").let { element.select("a.chart-title").let {
setUrlWithoutDomain(it.attr("href")) setUrlWithoutDomain(it.attr("href"))
@ -455,3 +461,22 @@ class MyMangaReaderCMSSource(
private val DATE_FORMAT = SimpleDateFormat("d MMM. yyyy", Locale.US) private val DATE_FORMAT = SimpleDateFormat("d MMM. yyyy", Locale.US)
} }
} }
@Nsfw
class MyMangaReaderCMSSourceNsfw(
lang: String,
name: String,
baseUrl: String,
supportsLatest: Boolean,
itemUrl: String,
categoryMappings: List<Pair<String, String>>,
tagMappings: List<Pair<String, String>>?
) : MyMangaReaderCMSSource(
lang,
name,
baseUrl,
supportsLatest,
itemUrl,
categoryMappings,
tagMappings
)

View File

@ -57,8 +57,10 @@ class MyMangaReaderCMSSources : SourceFactory {
if (jsonObject["tags"].isJsonArray) { if (jsonObject["tags"].isJsonArray) {
tags = mapToPairs(jsonObject["tags"].asJsonArray) tags = mapToPairs(jsonObject["tags"].asJsonArray)
} }
val isNsfw = jsonObject["isNsfw"].bool
MyMangaReaderCMSSource( if (isNsfw) {
MyMangaReaderCMSSourceNsfw(
language, language,
name, name,
baseUrl, baseUrl,
@ -66,7 +68,18 @@ class MyMangaReaderCMSSources : SourceFactory {
itemUrl, itemUrl,
categories, categories,
tags tags
) )
} else {
MyMangaReaderCMSSource(
language,
name,
baseUrl,
supportsLatest,
itemUrl,
categories,
tags
)
}
} }
} }