[Pepper&Carrot] multiples fixes (#11559)
* fix: cannot retrieve mangas when framagit.org is unreachable since it is used only for translated titles, we can omit that if it is unreachable * fix: fails to retrieve chapter list because the website changed * fix: page list parsing * feat: add support for mini theather fantasy * bump version * refactor: use tryParse util * refactor: remove unnecessary !!
This commit is contained in:
parent
bd530edb7d
commit
68af18e453
@ -1,7 +1,7 @@
|
|||||||
ext {
|
ext {
|
||||||
extName = 'Pepper&Carrot'
|
extName = 'Pepper&Carrot'
|
||||||
extClass = '.PepperCarrot'
|
extClass = '.PepperCarrot'
|
||||||
extVersionCode = 3
|
extVersionCode = 4
|
||||||
}
|
}
|
||||||
|
|
||||||
apply from: "$rootDir/common.gradle"
|
apply from: "$rootDir/common.gradle"
|
||||||
|
|||||||
@ -10,8 +10,8 @@ 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.HttpSource
|
import eu.kanade.tachiyomi.source.online.HttpSource
|
||||||
import eu.kanade.tachiyomi.util.asJsoup
|
import eu.kanade.tachiyomi.util.asJsoup
|
||||||
import keiyoushi.utils.getPreferences
|
|
||||||
import keiyoushi.utils.getPreferencesLazy
|
import keiyoushi.utils.getPreferencesLazy
|
||||||
|
import keiyoushi.utils.tryParse
|
||||||
import okhttp3.CacheControl
|
import okhttp3.CacheControl
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
import okhttp3.Response
|
import okhttp3.Response
|
||||||
@ -39,7 +39,8 @@ class PepperCarrot : HttpSource(), ConfigurableSource {
|
|||||||
}
|
}
|
||||||
val langMap = preferences.langData.associateBy { langData -> langData.key }
|
val langMap = preferences.langData.associateBy { langData -> langData.key }
|
||||||
val mangas = lang.map { key -> langMap[key]!!.toSManga() }
|
val mangas = lang.map { key -> langMap[key]!!.toSManga() }
|
||||||
val result = MangasPage(mangas + getArtworkList(), false)
|
val miniFantasyTheaters = lang.map { key -> langMap[key]!!.getMiniFantasyTheaterEntry() }
|
||||||
|
val result = MangasPage(mangas + miniFantasyTheaters + getArtworkList(), false)
|
||||||
it.onSuccess(result)
|
it.onSuccess(result)
|
||||||
}.toObservable()
|
}.toObservable()
|
||||||
|
|
||||||
@ -68,6 +69,9 @@ class PepperCarrot : HttpSource(), ConfigurableSource {
|
|||||||
val key = manga.url
|
val key = manga.url
|
||||||
val result = if (key.startsWith('#')) {
|
val result = if (key.startsWith('#')) {
|
||||||
getArtworkEntry(key.substring(1))
|
getArtworkEntry(key.substring(1))
|
||||||
|
} else if (key.startsWith("miniFantasyTheater")) {
|
||||||
|
val langKey = key.substringAfter("#")
|
||||||
|
preferences.langData.find { lang -> lang.key == langKey }!!.getMiniFantasyTheaterEntry()
|
||||||
} else {
|
} else {
|
||||||
preferences.langData.find { lang -> lang.key == key }!!.toSManga()
|
preferences.langData.find { lang -> lang.key == key }!!.toSManga()
|
||||||
}
|
}
|
||||||
@ -78,8 +82,11 @@ class PepperCarrot : HttpSource(), ConfigurableSource {
|
|||||||
val key = manga.url
|
val key = manga.url
|
||||||
val url = if (key.startsWith('#')) { // artwork
|
val url = if (key.startsWith('#')) { // artwork
|
||||||
"$BASE_URL/en/files/${key.substring(1)}.html"
|
"$BASE_URL/en/files/${key.substring(1)}.html"
|
||||||
|
} else if (key.startsWith("miniFantasyTheater")) {
|
||||||
|
val langKey = key.substringAfter("#")
|
||||||
|
"$BASE_URL/$langKey/webcomics/miniFantasyTheater.html"
|
||||||
} else {
|
} else {
|
||||||
"$BASE_URL/$key/webcomics/index.html"
|
"$BASE_URL/$key/webcomics/peppercarrot.html"
|
||||||
}
|
}
|
||||||
return GET(url, headers)
|
return GET(url, headers)
|
||||||
}
|
}
|
||||||
@ -94,7 +101,19 @@ class PepperCarrot : HttpSource(), ConfigurableSource {
|
|||||||
"Language: $name\nTranslators: $translators"
|
"Language: $name\nTranslators: $translators"
|
||||||
}
|
}
|
||||||
status = SManga.ONGOING
|
status = SManga.ONGOING
|
||||||
thumbnail_url = "$BASE_URL/0_sources/0ther/artworks/low-res/2016-02-24_vertical-cover_remake_by-David-Revoy.jpg"
|
thumbnail_url =
|
||||||
|
"$BASE_URL/0_sources/0ther/artworks/low-res/2016-02-24_vertical-cover_remake_by-David-Revoy.jpg"
|
||||||
|
initialized = true
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun LangData.getMiniFantasyTheaterEntry() = SManga.create().apply {
|
||||||
|
url = "miniFantasyTheater#$key"
|
||||||
|
title = "Mini Fantasy Theater" + if (key != "en") " (${key.uppercase()})" else ""
|
||||||
|
author = AUTHOR
|
||||||
|
description =
|
||||||
|
"A webcomic series featuring short stories set in the enchanting world of Pepper&Carrot. With its playful humor and whimsical tales, this collection of gag strips is perfect for audiences of all ages."
|
||||||
|
status = SManga.ONGOING
|
||||||
|
thumbnail_url = "$BASE_URL/0_sources/0ther/artworks/low-res/2018-11-22_vertical-cover-book-three_by-David-Revoy.jpg"
|
||||||
initialized = true
|
initialized = true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,18 +130,22 @@ class PepperCarrot : HttpSource(), ConfigurableSource {
|
|||||||
initialized = true
|
initialized = true
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun fetchChapterList(manga: SManga): Observable<List<SChapter>> = Single.create<List<SChapter>> {
|
override fun fetchChapterList(manga: SManga): Observable<List<SChapter>> =
|
||||||
updateLangData(client, headers, preferences)
|
Single.create<List<SChapter>> {
|
||||||
val response = client.newCall(chapterListRequest(manga)).execute()
|
updateLangData(client, headers, preferences)
|
||||||
it.onSuccess(chapterListParse(response))
|
val response = client.newCall(chapterListRequest(manga)).execute()
|
||||||
}.toObservable()
|
it.onSuccess(chapterListParse(response))
|
||||||
|
}.toObservable()
|
||||||
|
|
||||||
override fun chapterListRequest(manga: SManga): Request {
|
override fun chapterListRequest(manga: SManga): Request {
|
||||||
val key = manga.url
|
val key = manga.url
|
||||||
val url = if (key.startsWith('#')) { // artwork
|
val url = if (key.startsWith('#')) { // artwork
|
||||||
"$BASE_URL/0_sources/0ther/${key.substring(1)}/low-res/"
|
"$BASE_URL/0_sources/0ther/${key.substring(1)}/low-res/"
|
||||||
|
} else if (key.startsWith("miniFantasyTheater")) {
|
||||||
|
val langKey = key.substringAfter("#")
|
||||||
|
"$BASE_URL/$langKey/webcomics/miniFantasyTheater.html"
|
||||||
} else {
|
} else {
|
||||||
"$BASE_URL/$key/webcomics/index.html"
|
"$BASE_URL/$key/webcomics/peppercarrot.html"
|
||||||
}
|
}
|
||||||
val lastUpdated = preferences.lastUpdated
|
val lastUpdated = preferences.lastUpdated
|
||||||
if (lastUpdated == 0L) return GET(url, headers)
|
if (lastUpdated == 0L) return GET(url, headers)
|
||||||
@ -150,10 +173,9 @@ class PepperCarrot : HttpSource(), ConfigurableSource {
|
|||||||
else -> substringBeforeLast('(').trimEnd()
|
else -> substringBeforeLast('(').trimEnd()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
date_upload = it.selectFirst(Evaluator.Tag("figcaption"))!!.ownText().let {
|
date_upload = it.selectFirst(Evaluator.Tag("figcaption"))?.text()?.let { text ->
|
||||||
val date = dateRegex.find(it)!!.value
|
dateRegex.find(text)?.value?.let { date -> dateFormat.tryParse(date) }
|
||||||
dateFormat.parse(date)!!.time
|
} ?: 0L
|
||||||
}
|
|
||||||
chapter_number = number.toFloat()
|
chapter_number = number.toFloat()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -162,7 +184,7 @@ class PepperCarrot : HttpSource(), ConfigurableSource {
|
|||||||
private fun parseArtwork(response: Response): List<SChapter> {
|
private fun parseArtwork(response: Response): List<SChapter> {
|
||||||
val baseDir = response.request.url.toString().removePrefix(BASE_URL)
|
val baseDir = response.request.url.toString().removePrefix(BASE_URL)
|
||||||
return response.asJsoup().select(Evaluator.Tag("a")).asReversed().mapNotNull {
|
return response.asJsoup().select(Evaluator.Tag("a")).asReversed().mapNotNull {
|
||||||
val filename = it.attr("href")!!
|
val filename = it.attr("href")
|
||||||
if (!filename.endsWith(".jpg")) return@mapNotNull null
|
if (!filename.endsWith(".jpg")) return@mapNotNull null
|
||||||
|
|
||||||
val file = filename.removeSuffix(".jpg").removeSuffix("_by-David-Revoy")
|
val file = filename.removeSuffix(".jpg").removeSuffix("_by-David-Revoy")
|
||||||
@ -170,11 +192,11 @@ class PepperCarrot : HttpSource(), ConfigurableSource {
|
|||||||
val date: Long
|
val date: Long
|
||||||
if (file.length >= 10 && dateRegex.matches(file.substring(0, 10))) {
|
if (file.length >= 10 && dateRegex.matches(file.substring(0, 10))) {
|
||||||
fileStripped = file.substring(10)
|
fileStripped = file.substring(10)
|
||||||
date = dateFormat.parse(file.substring(0, 10))!!.time
|
date = dateFormat.tryParse(file.substring(0, 10))
|
||||||
} else {
|
} else {
|
||||||
fileStripped = file
|
fileStripped = file
|
||||||
val lastModified = it.nextSibling() as? TextNode
|
val lastModified = it.nextSibling() as? TextNode
|
||||||
date = if (lastModified == null) 0 else dateFormat.parse(lastModified.text())!!.time
|
date = if (lastModified == null) 0 else dateFormat.tryParse(lastModified.text())
|
||||||
}
|
}
|
||||||
val fileNormalized = fileStripped
|
val fileNormalized = fileStripped
|
||||||
.replace('_', ' ')
|
.replace('_', ' ')
|
||||||
@ -202,9 +224,14 @@ class PepperCarrot : HttpSource(), ConfigurableSource {
|
|||||||
|
|
||||||
override fun pageListParse(response: Response): List<Page> {
|
override fun pageListParse(response: Response): List<Page> {
|
||||||
val document = response.asJsoup()
|
val document = response.asJsoup()
|
||||||
val urls = document.select(Evaluator.Class("comicpage")).map { it.attr("src")!! }
|
val urls = document.select(".webcomic-page img").map { it.attr("src") }
|
||||||
val thumbnail = urls[0].replace("P00.jpg", ".jpg")
|
val thumbnail =
|
||||||
return (listOf(thumbnail) + urls).mapIndexed { index, imageUrl ->
|
if (urls[0].contains("miniFantasyTheater", true)) {
|
||||||
|
emptyList()
|
||||||
|
} else {
|
||||||
|
listOf(urls[0].replace("P00.jpg", ".jpg"))
|
||||||
|
}
|
||||||
|
return (thumbnail + urls).mapIndexed { index, imageUrl ->
|
||||||
Page(index, imageUrl = imageUrl)
|
Page(index, imageUrl = imageUrl)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -63,7 +63,12 @@ fun updateLangData(client: OkHttpClient, headers: Headers, preferences: SharedPr
|
|||||||
val translatedCount = episodes.flatMap { it.translated_languages }
|
val translatedCount = episodes.flatMap { it.translated_languages }
|
||||||
.groupingBy { it }.eachCount()
|
.groupingBy { it }.eachCount()
|
||||||
|
|
||||||
val titles = fetchTitles(client, headers)
|
// framagit.org is IP blocked in some countries
|
||||||
|
val titles = try {
|
||||||
|
fetchTitles(client, headers)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
|
||||||
val langs = client.newCall(GET("$BASE_URL/0_sources/langs.json", headers))
|
val langs = client.newCall(GET("$BASE_URL/0_sources/langs.json", headers))
|
||||||
.execute().parseAs<LangsDto>().entries.map { (key, dto) ->
|
.execute().parseAs<LangsDto>().entries.map { (key, dto) ->
|
||||||
@ -81,7 +86,7 @@ fun updateLangData(client: OkHttpClient, headers: Headers, preferences: SharedPr
|
|||||||
.also { if (preferences.lang.isEmpty()) editor.chooseLang(it) }
|
.also { if (preferences.lang.isEmpty()) editor.chooseLang(it) }
|
||||||
.map {
|
.map {
|
||||||
val progress = "${it.translatedCount}/$total translated"
|
val progress = "${it.translatedCount}/$total translated"
|
||||||
LangData(it.key, it.name, progress, it.translators, titles[it.key])
|
LangData(it.key, it.name, progress, it.translators, titles?.get(it.key) ?: if (it.key == "en") TITLE else "$TITLE (${it.key.uppercase()})")
|
||||||
}
|
}
|
||||||
|
|
||||||
editor.putString(LANG_DATA_PREF, ProtoBuf.encodeToBase64(langs)).apply()
|
editor.putString(LANG_DATA_PREF, ProtoBuf.encodeToBase64(langs)).apply()
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user