Izneo: fix chapter URLs (#15388)
This commit is contained in:
parent
18a29b81c9
commit
d239e42d7c
|
@ -6,7 +6,7 @@ ext {
|
||||||
extName = 'izneo (webtoons)'
|
extName = 'izneo (webtoons)'
|
||||||
pkgNameSuffix = 'all.izneo'
|
pkgNameSuffix = 'all.izneo'
|
||||||
extClass = '.IzneoFactory'
|
extClass = '.IzneoFactory'
|
||||||
extVersionCode = 4
|
extVersionCode = 5
|
||||||
}
|
}
|
||||||
|
|
||||||
apply from: "$rootDir/common.gradle"
|
apply from: "$rootDir/common.gradle"
|
||||||
|
|
|
@ -34,6 +34,8 @@ class Izneo(override val lang: String) : ConfigurableSource, HttpSource() {
|
||||||
|
|
||||||
override val supportsLatest = true
|
override val supportsLatest = true
|
||||||
|
|
||||||
|
override val versionId = 2
|
||||||
|
|
||||||
override val client = network.client.newBuilder()
|
override val client = network.client.newBuilder()
|
||||||
.addInterceptor(ImageInterceptor).build()
|
.addInterceptor(ImageInterceptor).build()
|
||||||
|
|
||||||
|
@ -75,14 +77,18 @@ class Izneo(override val lang: String) : ConfigurableSource, HttpSource() {
|
||||||
GET("$apiUrl/free?offset=${page - 1}&order=3&abo=0", apiHeaders)
|
GET("$apiUrl/free?offset=${page - 1}&order=3&abo=0", apiHeaders)
|
||||||
|
|
||||||
override fun pageListRequest(chapter: SChapter) =
|
override fun pageListRequest(chapter: SChapter) =
|
||||||
GET(ORIGIN + "/book/" + chapter.url, apiHeaders)
|
GET(ORIGIN + "/book/" + chapter.id, apiHeaders)
|
||||||
|
|
||||||
override fun imageRequest(page: Page) =
|
override fun imageRequest(page: Page) =
|
||||||
GET(ORIGIN + "/book/" + page.imageUrl!!, apiHeaders)
|
GET(ORIGIN + "/book/" + page.imageUrl!!, apiHeaders)
|
||||||
|
|
||||||
override fun latestUpdatesParse(response: Response) =
|
override fun latestUpdatesParse(response: Response) =
|
||||||
response.parse().run {
|
response.parse().run {
|
||||||
val count = get("series_count")!!.jsonPrimitive.int
|
val count = try {
|
||||||
|
get("series_count")!!.jsonPrimitive.int
|
||||||
|
} catch (_: IllegalArgumentException) {
|
||||||
|
return@run MangasPage(emptyList(), false)
|
||||||
|
}
|
||||||
val series = get("series")!!.jsonObject.values.flatMap {
|
val series = get("series")!!.jsonObject.values.flatMap {
|
||||||
json.decodeFromJsonElement<List<Series>>(it)
|
json.decodeFromJsonElement<List<Series>>(it)
|
||||||
}.also { seriesCount += it.size }
|
}.also { seriesCount += it.size }
|
||||||
|
@ -106,17 +112,6 @@ class Izneo(override val lang: String) : ConfigurableSource, HttpSource() {
|
||||||
override fun searchMangaParse(response: Response) =
|
override fun searchMangaParse(response: Response) =
|
||||||
latestUpdatesParse(response)
|
latestUpdatesParse(response)
|
||||||
|
|
||||||
override fun chapterListParse(response: Response) =
|
|
||||||
response.parse()["albums"]!!.jsonArray.map {
|
|
||||||
val album = json.decodeFromJsonElement<Album>(it)
|
|
||||||
SChapter.create().apply {
|
|
||||||
url = album.id
|
|
||||||
name = album.toString()
|
|
||||||
date_upload = album.timestamp
|
|
||||||
chapter_number = album.number
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun pageListParse(response: Response) =
|
override fun pageListParse(response: Response) =
|
||||||
response.parse()["data"]!!.jsonObject.run {
|
response.parse()["data"]!!.jsonObject.run {
|
||||||
val id = get("id")!!.jsonPrimitive.content
|
val id = get("id")!!.jsonPrimitive.content
|
||||||
|
@ -135,26 +130,32 @@ class Izneo(override val lang: String) : ConfigurableSource, HttpSource() {
|
||||||
Observable.just(manga.apply { initialized = true })!!
|
Observable.just(manga.apply { initialized = true })!!
|
||||||
|
|
||||||
override fun fetchChapterList(manga: SManga): Observable<List<SChapter>> {
|
override fun fetchChapterList(manga: SManga): Observable<List<SChapter>> {
|
||||||
val url = "$ORIGIN/$lang/api/web/serie/" +
|
val id = manga.url.substringAfterLast('-')
|
||||||
manga.url.substringAfterLast('-') + "/volumes/old"
|
val url = "$ORIGIN/$lang/api/web/serie/$id/chapters/old"
|
||||||
val chapters = mutableListOf<SChapter>()
|
val chapters = mutableListOf<SChapter>()
|
||||||
var cutoff = 0
|
var cutoff = 0
|
||||||
var current = LIMIT
|
var current = LIMIT
|
||||||
while (current == LIMIT) {
|
while (current == LIMIT) {
|
||||||
client.newCall(GET("$url/$cutoff/$LIMIT", apiHeaders))
|
val albums = client.newCall(GET("$url/$cutoff/$LIMIT", apiHeaders))
|
||||||
.execute().run(::chapterListParse).let {
|
.execute().parse()["albums"]!!.jsonArray
|
||||||
cutoff += LIMIT
|
albums.forEach {
|
||||||
current = it.size
|
val album = json.decodeFromJsonElement<Album>(it)
|
||||||
chapters.addAll(it)
|
val chapter = SChapter.create()
|
||||||
}
|
chapter.url = manga.url + album.path
|
||||||
|
chapter.name = album.toString()
|
||||||
|
chapter.date_upload = album.timestamp
|
||||||
|
chapter.chapter_number = album.number
|
||||||
|
chapters.add(chapter)
|
||||||
|
}
|
||||||
|
cutoff += LIMIT
|
||||||
|
current = albums.size
|
||||||
}
|
}
|
||||||
return Observable.just(chapters)
|
return Observable.just(chapters)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getMangaUrl(manga: SManga) = ORIGIN + manga.url
|
override fun getMangaUrl(manga: SManga) = ORIGIN + manga.url
|
||||||
|
|
||||||
override fun getChapterUrl(chapter: SChapter) =
|
override fun getChapterUrl(chapter: SChapter) = ORIGIN + chapter.url
|
||||||
throw UnsupportedOperationException("Not implemented!")
|
|
||||||
|
|
||||||
override fun setupPreferenceScreen(screen: PreferenceScreen) {
|
override fun setupPreferenceScreen(screen: PreferenceScreen) {
|
||||||
EditTextPreference(screen.context).apply {
|
EditTextPreference(screen.context).apply {
|
||||||
|
@ -183,6 +184,9 @@ class Izneo(override val lang: String) : ConfigurableSource, HttpSource() {
|
||||||
private inline val Album.timestamp: Long
|
private inline val Album.timestamp: Long
|
||||||
get() = dateFormat.parse(publicationDate)?.time ?: 0L
|
get() = dateFormat.parse(publicationDate)?.time ?: 0L
|
||||||
|
|
||||||
|
private inline val SChapter.id: String
|
||||||
|
get() = url.substringAfterLast('-').substringBefore('/')
|
||||||
|
|
||||||
private fun String.btoa() = Base64.encode(toByteArray(), Base64.DEFAULT)
|
private fun String.btoa() = Base64.encode(toByteArray(), Base64.DEFAULT)
|
||||||
|
|
||||||
private fun Response.parse() =
|
private fun Response.parse() =
|
||||||
|
@ -204,11 +208,14 @@ class Izneo(override val lang: String) : ConfigurableSource, HttpSource() {
|
||||||
override fun mangaDetailsParse(response: Response) =
|
override fun mangaDetailsParse(response: Response) =
|
||||||
throw UnsupportedOperationException("Not used")
|
throw UnsupportedOperationException("Not used")
|
||||||
|
|
||||||
|
override fun chapterListParse(response: Response) =
|
||||||
|
throw UnsupportedOperationException("Not used")
|
||||||
|
|
||||||
override fun imageUrlParse(response: Response) =
|
override fun imageUrlParse(response: Response) =
|
||||||
throw UnsupportedOperationException("Not used")
|
throw UnsupportedOperationException("Not used")
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val ORIGIN = "https://izneo.com"
|
private const val ORIGIN = "https://www.izneo.com"
|
||||||
|
|
||||||
private const val LIMIT = 50
|
private const val LIMIT = 50
|
||||||
|
|
||||||
|
|
|
@ -35,16 +35,19 @@ data class Author(private val nickname: String) {
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class Album(
|
data class Album(
|
||||||
val id: String,
|
private val id: String,
|
||||||
private val title: String,
|
private val title: String,
|
||||||
private val volume: String,
|
private val chapter: String,
|
||||||
val publicationDate: String,
|
val publicationDate: String,
|
||||||
private val fullAvailable: Boolean,
|
private val fullAvailable: Boolean,
|
||||||
private val inUserLibrary: Boolean,
|
private val inUserLibrary: Boolean,
|
||||||
private val inUserSubscription: Boolean,
|
private val inUserSubscription: Boolean,
|
||||||
) {
|
) {
|
||||||
val number: Float
|
val number: Float
|
||||||
get() = volume.toFloat()
|
get() = chapter.toFloat()
|
||||||
|
|
||||||
|
val path: String
|
||||||
|
get() = "/episode-$chapter-$id/read/1"
|
||||||
|
|
||||||
private inline val isLocked: Boolean
|
private inline val isLocked: Boolean
|
||||||
get() = !fullAvailable && !(inUserLibrary || inUserSubscription)
|
get() = !fullAvailable && !(inUserLibrary || inUserSubscription)
|
||||||
|
|
Loading…
Reference in New Issue