Maid Manga - site changed theme (#3310)

This commit is contained in:
Mike
2020-05-25 04:39:04 -04:00
committed by GitHub
parent 34a1f446ea
commit 3e62147b6b
2 changed files with 41 additions and 115 deletions

View File

@ -5,7 +5,7 @@ ext {
appName = 'Tachiyomi: Maid - Manga' appName = 'Tachiyomi: Maid - Manga'
pkgNameSuffix = 'id.maidmanga' pkgNameSuffix = 'id.maidmanga'
extClass = '.MaidManga' extClass = '.MaidManga'
extVersionCode = 2 extVersionCode = 3
libVersion = '1.2' libVersion = '1.2'
} }

View File

@ -7,13 +7,11 @@ import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.ParsedHttpSource import eu.kanade.tachiyomi.source.online.ParsedHttpSource
import eu.kanade.tachiyomi.util.asJsoup
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Locale
import okhttp3.HttpUrl import okhttp3.HttpUrl
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import okhttp3.Response
import org.json.JSONObject
import org.jsoup.nodes.Document import org.jsoup.nodes.Document
import org.jsoup.nodes.Element import org.jsoup.nodes.Element
@ -29,50 +27,32 @@ class MaidManga : ParsedHttpSource() {
override val client: OkHttpClient = network.cloudflareClient override val client: OkHttpClient = network.cloudflareClient
override fun latestUpdatesSelector() = "h2:contains(Update Chapter) + div.row div.col-12" private fun pagePathSegment(page: Int): String = if (page > 1) "page/$page/" else ""
override fun latestUpdatesSelector() = searchMangaSelector()
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 return GET("$baseUrl/advanced-search/${pagePathSegment(page)}?order=popular")
val builtUrl = if (page == 1) baseUrl else "$baseUrl/page/$page/"
return GET(builtUrl)
} }
override fun latestUpdatesFromElement(element: Element): SManga { override fun latestUpdatesFromElement(element: Element): SManga = searchMangaFromElement(element)
val manga = SManga.create()
val item = element.select("h3 a")
val imgurl = element.select("div.limit img").attr("src").replace("?resize=100,140", "")
manga.url = item.attr("href")
manga.title = item.text()
manga.thumbnail_url = imgurl
return manga
}
override fun latestUpdatesNextPageSelector() = "a:containsOwn(Berikutnya)" override fun latestUpdatesNextPageSelector() = searchMangaNextPageSelector()
override fun popularMangaRequest(page: Int): Request { override fun popularMangaRequest(page: Int): Request {
val builtUrl = if (page == 1) "$baseUrl/advanced-search/?order=popular" else "$baseUrl/advanced-search/page/$page/?order=popular" return GET("$baseUrl/advanced-search/${pagePathSegment(page)}?order=update")
return GET(builtUrl)
} }
override fun popularMangaSelector() = "div.row div.col-6" override fun popularMangaSelector() = searchMangaSelector()
override fun popularMangaFromElement(element: Element): SManga { override fun popularMangaFromElement(element: Element): SManga = searchMangaFromElement(element)
val manga = SManga.create()
val imgurl = element.select("div.card img").attr("src").replace("?resize=165,225", "")
manga.url = element.select("div.card a").attr("href")
manga.title = element.select("div.card img").attr("title")
manga.thumbnail_url = imgurl
return manga
}
override fun popularMangaNextPageSelector() = latestUpdatesNextPageSelector() override fun popularMangaNextPageSelector() = searchMangaNextPageSelector()
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
val builtUrl = if (page == 1) "$baseUrl/advanced-search/" else "$baseUrl/advanced-search/page/$page/" val url = HttpUrl.parse("$baseUrl/advanced-search/${pagePathSegment(page)}")!!.newBuilder()
val url = HttpUrl.parse(builtUrl)!!.newBuilder()
url.addQueryParameter("title", query) url.addQueryParameter("title", query)
url.addQueryParameter("page", page.toString()) (if (filters.isEmpty()) getFilterList() else filters).forEach { filter ->
filters.forEach { filter ->
when (filter) { when (filter) {
is AuthorFilter -> { is AuthorFilter -> {
url.addQueryParameter("author", filter.state) url.addQueryParameter("author", filter.state)
@ -96,115 +76,61 @@ class MaidManga : ParsedHttpSource() {
} }
is GenreList -> { is GenreList -> {
filter.state filter.state
.filter { it.state != Filter.TriState.STATE_IGNORE } .filter { it.state }
.forEach { url.addQueryParameter("genre[]", it.id) } .forEach { url.addQueryParameter("genre[]", it.id) }
} }
} }
} }
return GET(url.build().toString(), headers) return GET(url.toString(), headers)
} }
override fun searchMangaSelector() = popularMangaSelector() override fun searchMangaSelector() = "div.flexbox2-item"
override fun searchMangaFromElement(element: Element) = popularMangaFromElement(element) override fun searchMangaFromElement(element: Element): SManga {
return SManga.create().apply {
override fun searchMangaNextPageSelector() = latestUpdatesNextPageSelector() setUrlWithoutDomain(element.select("div.flexbox2-content a").attr("href"))
title = element.select("div.flexbox2-title > span").first().text()
override fun mangaDetailsRequest(manga: SManga): Request { thumbnail_url = element.select("img").attr("abs:src")
if (manga.url.startsWith("http")) {
return GET(manga.url, headers)
} }
return super.mangaDetailsRequest(manga)
} }
override fun searchMangaNextPageSelector() = "div.pagination span.current + a"
override fun mangaDetailsParse(document: Document): SManga { override fun mangaDetailsParse(document: Document): SManga {
val stringBuilder = StringBuilder() return SManga.create().apply {
val infoElement = document.select("div.infox") genre = document.select("div.series-genres a").joinToString { it.text() }
val author = document.select("span:contains(author)").text().substringAfter("Author: ").substringBefore(" (") description = document.select("div.series-synops").text()
val manga = SManga.create() thumbnail_url = document.select("div.series-thumb img").attr("abs:src")
val genres = mutableListOf<String>() status = parseStatus(document.select("div.block span.status").text())
val status = document.select("span:contains(Status)").text() author = document.select("ul.series-infolist li b:contains(Author) + span").text()
val desc = document.select("div.sinopsis p")
infoElement.select("div.gnr a").forEach { element ->
val genre = element.text()
genres.add(genre)
} }
if (desc.size > 0) {
desc.forEach {
stringBuilder.append(it.text())
if (it != desc.last())
stringBuilder.append("\n\n")
}
manga.description = stringBuilder.toString()
} else
manga.description = document.select("div.sinopsis").text()
manga.title = infoElement.select("h1").text()
manga.author = author
manga.artist = author
manga.status = parseStatus(status)
manga.genre = genres.joinToString(", ")
manga.description = stringBuilder.toString()
manga.thumbnail_url = document.select("div.bigcontent img").attr("src")
return manga
} }
private fun parseStatus(status: String?) = when { private fun parseStatus(status: String?) = when {
status == null -> SManga.UNKNOWN status == null -> SManga.UNKNOWN
status.contains("Status: Ongoing") -> SManga.ONGOING status.contains("Ongoing") -> SManga.ONGOING
status.contains("Status: Completed") -> SManga.COMPLETED status.contains("Completed") -> SManga.COMPLETED
else -> SManga.UNKNOWN else -> SManga.UNKNOWN
} }
override fun chapterListRequest(manga: SManga): Request {
if (manga.url.startsWith("http")) {
return GET(manga.url, headers)
}
return super.chapterListRequest(manga)
}
override fun chapterListParse(response: Response): List<SChapter> {
val document = response.asJsoup()
val chapters = mutableListOf<SChapter>()
document.select(chapterListSelector()).map { chapters.add(chapterFromElement(it)) }
// Add date for latest chapter only
document.select("script.yoast-schema-graph").html()
.let {
val date = JSONObject(it).getJSONArray("@graph")
.getJSONObject(3).getString("dateModified")
chapters[0].date_upload = parseDate(date)
}
return chapters
}
private fun parseDate(date: String): Long { private fun parseDate(date: String): Long {
return SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX").parse(date).time return SimpleDateFormat("MMM d, yyyy", Locale("id")).parse(date).time
} }
override fun chapterListSelector() = "ul#chapter_list li a:contains(chapter)" override fun chapterListSelector() = "ul.series-chapterlist div.flexch a"
override fun chapterFromElement(element: Element): SChapter { override fun chapterFromElement(element: Element): SChapter {
val urlElement = element.select("a:contains(chapter)") return SChapter.create().apply {
val chapter = SChapter.create() setUrlWithoutDomain(element.attr("href"))
chapter.url = urlElement.attr("href") name = element.select("span").first().ownText()
chapter.name = urlElement.text() date_upload = parseDate(element.select("span.date").text())
return chapter
} }
override fun pageListRequest(chapter: SChapter): Request {
if (chapter.url.startsWith("http")) {
return GET(chapter.url, headers)
}
return super.pageListRequest(chapter)
} }
override fun pageListParse(document: Document): List<Page> { override fun pageListParse(document: Document): List<Page> {
val pages = mutableListOf<Page>() return document.select("div.reader-area img").mapIndexed { i, img ->
document.select("div#readerarea img").forEach { Page(i, "", img.attr("abs:src"))
val url = it.attr("src")
pages.add(Page(pages.size, "", url))
} }
return pages
} }
override fun imageUrlParse(document: Document): String = throw UnsupportedOperationException("Not used") override fun imageUrlParse(document: Document): String = throw UnsupportedOperationException("Not used")
@ -307,7 +233,7 @@ class MaidManga : ParsedHttpSource() {
fun toUriPart() = vals[state].second fun toUriPart() = vals[state].second
} }
private class Tag(val id: String, name: String) : Filter.TriState(name) private class Tag(val id: String, name: String) : Filter.CheckBox(name)
private class GenreList(genres: List<Tag>) : Filter.Group<Tag>("Genres", genres) private class GenreList(genres: List<Tag>) : Filter.Group<Tag>("Genres", genres)
} }