MyHentaiComics: fix extension (#7198)

* MyHentaiComics: fix extension

* fix

* use httpurl builder

* fetch only once
This commit is contained in:
dngonz 2025-01-18 19:32:24 +01:00 committed by Draff
parent dfb448cbff
commit 05c0051c32
No known key found for this signature in database
GPG Key ID: E8A89F3211677653
2 changed files with 141 additions and 105 deletions

View File

@ -1,7 +1,7 @@
ext { ext {
extName = 'MyHentaiComics' extName = 'MyHentaiComics'
extClass = '.MyHentaiComics' extClass = '.MyHentaiComics'
extVersionCode = 2 extVersionCode = 3
isNsfw = true isNsfw = true
} }

View File

@ -6,8 +6,9 @@ import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.Page 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.model.UpdateStrategy
import eu.kanade.tachiyomi.source.online.ParsedHttpSource import eu.kanade.tachiyomi.source.online.ParsedHttpSource
import eu.kanade.tachiyomi.util.asJsoup import okhttp3.HttpUrl.Companion.toHttpUrl
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import org.jsoup.nodes.Document import org.jsoup.nodes.Document
@ -22,85 +23,68 @@ class MyHentaiComics : ParsedHttpSource() {
override val lang = "en" override val lang = "en"
override val supportsLatest = true override val supportsLatest = false
override val client: OkHttpClient = network.cloudflareClient override val client: OkHttpClient = network.cloudflareClient
// Popular // Popular
override fun popularMangaRequest(page: Int) = searchMangaRequest(page, "", FilterList())
override fun popularMangaRequest(page: Int): Request { override fun popularMangaSelector() = searchMangaSelector()
return GET("$baseUrl/index.php/tag/2402?page=$page", headers) override fun popularMangaFromElement(element: Element) = searchMangaFromElement(element)
} override fun popularMangaNextPageSelector() = searchMangaNextPageSelector()
override fun popularMangaSelector() = "li.g-item"
override fun popularMangaFromElement(element: Element): SManga {
return SManga.create().apply {
title = element.select("h2").text()
setUrlWithoutDomain(element.select("a").attr("href"))
thumbnail_url = element.select("img").attr("abs:src")
}
}
override fun popularMangaNextPageSelector() = "a.ui-state-default span.ui-icon-seek-next"
// Latest // Latest
override fun latestUpdatesRequest(page: Int) = throw UnsupportedOperationException()
override fun latestUpdatesRequest(page: Int): Request { override fun latestUpdatesSelector() = throw UnsupportedOperationException()
return GET("$baseUrl/index.php/?page=$page", headers) override fun latestUpdatesFromElement(element: Element) = throw UnsupportedOperationException()
} override fun latestUpdatesNextPageSelector() = throw UnsupportedOperationException()
override fun latestUpdatesSelector() = popularMangaSelector()
override fun latestUpdatesFromElement(element: Element): SManga = popularMangaFromElement(element)
override fun latestUpdatesNextPageSelector() = popularMangaNextPageSelector()
// Search // Search
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
return if (query.isNotBlank()) { if (query.isNotEmpty()) {
GET("$baseUrl/index.php/search?q=$query&page=$page", headers) val url = baseUrl.toHttpUrl().newBuilder()
} else { .addPathSegment("search")
.addPathSegment("$page")
.addQueryParameter("query", query)
.build()
return GET(url, headers)
}
var url = baseUrl var url = baseUrl
for (filter in if (filters.isEmpty()) getFilterList() else filters) { filters.forEach {
when (filter) { when (it) {
is GenreFilter -> url += filter.toUriPart() + "?page=$page" is GenreFilter -> url += it.toUriPart() + "/$page"
else -> {} else -> {}
} }
} }
GET(url, headers) return GET(url, headers)
}
} }
override fun searchMangaSelector() = popularMangaSelector() override fun searchMangaSelector() = "li.item"
override fun searchMangaFromElement(element: Element): SManga { override fun searchMangaFromElement(element: Element): SManga {
return SManga.create().apply { return SManga.create().apply {
title = element.select("h2, p").text() title = element.select("h2").text()
setUrlWithoutDomain(element.select("a").attr("href")) url = element.select("a").attr("href")
thumbnail_url = element.select("img").attr("abs:src") thumbnail_url = element.select("img").attr("abs:src")
} }
} }
override fun searchMangaNextPageSelector() = popularMangaNextPageSelector() override fun searchMangaNextPageSelector() = "li.next a"
// Details // Details
override fun mangaDetailsParse(document: Document): SManga { override fun mangaDetailsParse(document: Document): SManga {
val tags = document.select("div.g-description a").partition { tag -> val tags = document.selectFirst("div.comic-description")
tag.text().startsWith("Artist: ")
}
return SManga.create().apply { return SManga.create().apply {
artist = tags.first.joinToString { it.text().substringAfter(" ") } author = tags?.selectFirst("div:containsOwn(Artists) a")?.text()
author = artist genre = tags?.select("div:containsOwn(Categories) a")?.joinToString { it.text() }
genre = tags.second.joinToString { it.text() } status = SManga.COMPLETED
thumbnail_url = document.select("img.g-thumbnail").first()!!.attr("abs:src").replace("/thumbs/", "/resizes/") update_strategy = UpdateStrategy.ONLY_FETCH_ONCE
} }
} }
// Chapters // Chapters
override fun fetchChapterList(manga: SManga): Observable<List<SChapter>> { override fun fetchChapterList(manga: SManga): Observable<List<SChapter>> {
return Observable.just( return Observable.just(
listOf( listOf(
@ -113,77 +97,129 @@ class MyHentaiComics : ParsedHttpSource() {
} }
override fun chapterListSelector() = throw UnsupportedOperationException() override fun chapterListSelector() = throw UnsupportedOperationException()
override fun chapterFromElement(element: Element): SChapter = throw UnsupportedOperationException() override fun chapterFromElement(element: Element): SChapter = throw UnsupportedOperationException()
// Pages // Pages
override fun pageListParse(document: Document): List<Page> { override fun pageListParse(document: Document): List<Page> {
val pages = mutableListOf<Page>() return document.select("div.comic-thumb > img").mapIndexed { i, e ->
Page(i, imageUrl = e.attr("data-cfsrc").replace("/thumbnail/", "/original/"))
// recursively parse paginated pages
fun parsePage(document: Document) {
document.select("img.g-thumbnail").map { img ->
pages.add(Page(pages.size, "", img.attr("abs:src").replace("/thumbs/", "/resizes/")))
} }
document.select("ul.g-paginator a.ui-state-default:contains(Next)").firstOrNull()?.let { a ->
parsePage(client.newCall(GET(a.attr("abs:href"), headers)).execute().asJsoup())
}
}
parsePage(document)
return pages
} }
override fun imageUrlParse(document: Document): String = throw UnsupportedOperationException() override fun imageUrlParse(document: Document): String = throw UnsupportedOperationException()
// Filters // Filters
override fun getFilterList() = FilterList( override fun getFilterList() = FilterList(
Filter.Header("Cannot combine search types!"), Filter.Header("Cannot combine search types!"),
Filter.Separator("-----------------"), Filter.Separator("-----------------"),
GenreFilter(), GenreFilter(),
) )
// [...document.querySelectorAll('.catagory-inner a')].map(a => `Pair("${a.querySelector("h2").textContent}", "${a.getAttribute('href')}")`).join(',\n')
private class GenreFilter : UriPartFilter( private class GenreFilter : UriPartFilter(
"Genres", "Genres",
arrayOf( arrayOf(
Pair("<Choose a genre>", ""), Pair("<Choose a genre>", ""),
Pair("3D", "/index.php/tag/2403"), Pair("3D Comic", "/gallery/category/3"),
Pair("Asian", "/index.php/tag/2404"), Pair("Ahegao", "/gallery/category/23"),
Pair("Ass Expansion", "/index.php/tag/2405"), Pair("Anal", "/gallery/category/25"),
Pair("BBW", "/index.php/tag/2406"), Pair("Animated", "/gallery/category/10"),
Pair("Beastiality", "/index.php/tag/2407"), Pair("Asian", "/gallery/category/54"),
Pair("Bisexual", "/index.php/tag/2408"), Pair("Ass Expansion", "/gallery/category/5"),
Pair("Body Swap", "/index.php/tag/2410"), Pair("Aunt", "/gallery/category/6"),
Pair("Breast Expansion", "/index.php/tag/2413"), Pair("BBW", "/gallery/category/7"),
Pair("Bukakke", "/index.php/tag/2412"), Pair("Beastiality", "/gallery/category/8"),
Pair("Cheating", "/index.php/tag/2414"), Pair("Bimbofication", "/gallery/category/2049"),
Pair("Crossdressing", "/index.php/tag/2415"), Pair("Bisexual", "/gallery/category/9"),
Pair("Femdom", "/index.php/tag/2417"), Pair("Black | Interracial", "/gallery/category/20"),
Pair("Furry", "/index.php/tag/2418"), Pair("Body Swap", "/gallery/category/11"),
Pair("Futanari", "/index.php/tag/2419"), Pair("Bondage", "/gallery/category/12"),
Pair("Futanari On Male", "/index.php/tag/2430"), Pair("Breast Expansion", "/gallery/category/13"),
Pair("Gangbang", "/index.php/tag/2421"), Pair("Brother", "/gallery/category/1012"),
Pair("Gay", "/index.php/tag/2422"), Pair("Bukkake", "/gallery/category/15"),
Pair("Gender Bending", "/index.php/tag/2423"), Pair("Catgirl", "/gallery/category/1201"),
Pair("Giantess", "/index.php/tag/2424"), Pair("Cbt", "/gallery/category/8133"),
Pair("Gloryhole", "/index.php/tag/2425"), Pair("Censored", "/gallery/category/5136"),
Pair("Hardcore", "/index.php/tag/2426"), Pair("Cheating", "/gallery/category/49"),
Pair("Harem", "/index.php/tag/2427"), Pair("Cosplay", "/gallery/category/8157"),
Pair("Incest", "/index.php/tag/2450"), Pair("Cousin", "/gallery/category/17"),
Pair("Interracial", "/index.php/tag/2409"), Pair("Crossdressing", "/gallery/category/43"),
Pair("Lactation", "/index.php/tag/2428"), Pair("Cuntboy", "/gallery/category/8134"),
Pair("Lesbian", "/index.php/tag/3167"), Pair("Dad | Father", "/gallery/category/788"),
Pair("Milf", "/index.php/tag/2431"), Pair("Daughter", "/gallery/category/546"),
Pair("Mind Control & Hypnosis", "/index.php/tag/2432"), Pair("Dick Growth", "/gallery/category/21"),
Pair("Muscle Girl", "/index.php/tag/2434"), Pair("Double Penetration", "/gallery/category/8135"),
Pair("Pegging", "/index.php/tag/2437"), Pair("Ebony", "/gallery/category/29"),
Pair("Pregnant", "/index.php/tag/2438"), Pair("Elf", "/gallery/category/1714"),
Pair("Rape", "/index.php/tag/2433"), Pair("Exhibitionism", "/gallery/category/1838"),
Pair("Strap-On", "/index.php/tag/2441"), Pair("Family", "/gallery/category/2094"),
Pair("Superheroes", "/index.php/tag/2443"), Pair("Femboy | Tomgirl | Sissy", "/gallery/category/8136"),
Pair("Tentacles", "/index.php/tag/2444"), Pair("Femdom", "/gallery/category/24"),
Pair("Foot Fetish", "/gallery/category/1873"),
Pair("Forced", "/gallery/category/18"),
Pair("Furry", "/gallery/category/14"),
Pair("Futanari | Shemale | Dickgirl", "/gallery/category/19"),
Pair("Futanari X Female", "/gallery/category/1951"),
Pair("Futanari X Futanari", "/gallery/category/1885"),
Pair("Futanari X Male", "/gallery/category/26"),
Pair("Gangbang", "/gallery/category/27"),
Pair("Gay | Yaoi", "/gallery/category/28"),
Pair("Gender Bender", "/gallery/category/16"),
Pair("Giant", "/gallery/category/8137"),
Pair("Giantess", "/gallery/category/452"),
Pair("Gilf", "/gallery/category/8138"),
Pair("Gloryhole", "/gallery/category/31"),
Pair("Group", "/gallery/category/101"),
Pair("Hairy Female", "/gallery/category/1986"),
Pair("Hardcore", "/gallery/category/36"),
Pair("Harem", "/gallery/category/53"),
Pair("Inflation | Stomach Bulge", "/gallery/category/57"),
Pair("Inseki", "/gallery/category/1978"),
Pair("Kemonomimi", "/gallery/category/1875"),
Pair("Lactation", "/gallery/category/39"),
Pair("Lesbian | Yuri | Girls Only", "/gallery/category/41"),
Pair("Milf", "/gallery/category/30"),
Pair("Mind Break", "/gallery/category/2023"),
Pair("Mind Control | Hypnosis", "/gallery/category/42"),
Pair("Mom | Mother", "/gallery/category/56"),
Pair("Monster", "/gallery/category/8140"),
Pair("Monster Girl", "/gallery/category/8139"),
Pair("Most Popular", "/gallery/category/52"),
Pair("Muscle Girl", "/gallery/category/45"),
Pair("Muscle Growth", "/gallery/category/46"),
Pair("Nephew", "/gallery/category/47"),
Pair("Niece", "/gallery/category/48"),
Pair("Nipple Fuck | Nipple Penetration", "/gallery/category/8141"),
Pair("Pegging", "/gallery/category/50"),
Pair("Possession", "/gallery/category/51"),
Pair("Pregnant | Impregnation", "/gallery/category/55"),
Pair("Public Use", "/gallery/category/8142"),
Pair("Selfcest", "/gallery/category/8143"),
Pair("Sister", "/gallery/category/58"),
Pair("Slave", "/gallery/category/8144"),
Pair("Smegma", "/gallery/category/8145"),
Pair("Solo", "/gallery/category/1865"),
Pair("Solo Futa", "/gallery/category/8154"),
Pair("Solo Girl", "/gallery/category/8146"),
Pair("Solo Male", "/gallery/category/8147"),
Pair("Son", "/gallery/category/62"),
Pair("Spanking", "/gallery/category/38"),
Pair("Speechless", "/gallery/category/8148"),
Pair("Strap-On", "/gallery/category/61"),
Pair("Stuck In Wall", "/gallery/category/8149"),
Pair("Superheroes", "/gallery/category/59"),
Pair("Tentacles", "/gallery/category/60"),
Pair("Threesome", "/gallery/category/40"),
Pair("Tickling", "/gallery/category/2065"),
Pair("Titty Fuck | Paizuri", "/gallery/category/8150"),
Pair("Tomboy", "/gallery/category/8153"),
Pair("Transformation", "/gallery/category/37"),
Pair("Uncle", "/gallery/category/63"),
Pair("Urination", "/gallery/category/64"),
Pair("Vanilla | Wholesome", "/gallery/category/8151"),
Pair("Variant Set", "/gallery/category/8152"),
Pair("Vore | Unbirth", "/gallery/category/65"),
Pair("Weight Gain", "/gallery/category/66"),
), ),
) )