Kagane: Fix MissingFieldException Error (#10981)
* fix dto and small fixes * bump * fix authors * remove unused code and fix review comment * fix lint * fix lintx2 :(
This commit is contained in:
parent
ccbde23c1f
commit
4ac7d3559c
@ -1,7 +1,7 @@
|
||||
ext {
|
||||
extName = 'Kagane'
|
||||
extClass = '.Kagane'
|
||||
extVersionCode = 3
|
||||
extVersionCode = 4
|
||||
isNsfw = true
|
||||
}
|
||||
|
||||
|
||||
@ -31,84 +31,68 @@ class SearchDto(
|
||||
|
||||
@Serializable
|
||||
class DetailsDto(
|
||||
val data: Data,
|
||||
val source: String,
|
||||
val authors: List<String>,
|
||||
val status: String,
|
||||
val summary: String?,
|
||||
val genres: List<String>,
|
||||
@SerialName("alternate_titles")
|
||||
val alternateTitles: List<AlternateTitles>,
|
||||
) {
|
||||
@Serializable
|
||||
class Data(
|
||||
val metadata: Metadata,
|
||||
val source: String,
|
||||
) {
|
||||
@Serializable
|
||||
class Metadata(
|
||||
val genres: List<String>,
|
||||
val status: String,
|
||||
val summary: String,
|
||||
val alternateTitles: List<Title>,
|
||||
) {
|
||||
@Serializable
|
||||
class Title(
|
||||
val title: String,
|
||||
)
|
||||
class AlternateTitles(
|
||||
val title: String,
|
||||
)
|
||||
|
||||
fun toSManga(): SManga = SManga.create().apply {
|
||||
val desc = StringBuilder()
|
||||
if (!summary.isNullOrBlank()) desc.append(summary + "\n\n")
|
||||
desc.append("Source: ").append(source + "\n\n")
|
||||
|
||||
if (alternateTitles.isNotEmpty()) {
|
||||
desc.append("Associated Name(s):\n\n")
|
||||
alternateTitles.forEach { desc.append("• ${it.title}\n") }
|
||||
}
|
||||
|
||||
fun toSManga(): SManga = SManga.create().apply {
|
||||
val summary = StringBuilder()
|
||||
summary.append(metadata.summary)
|
||||
.append("\n\n")
|
||||
.append("Source: ")
|
||||
.append(source)
|
||||
author = authors.joinToString()
|
||||
description = desc.toString()
|
||||
genre = genres.joinToString()
|
||||
status = this@DetailsDto.status.toStatus()
|
||||
}
|
||||
|
||||
if (metadata.alternateTitles.isNotEmpty()) {
|
||||
summary.append("\n\nAssociated Name(s):")
|
||||
metadata.alternateTitles.forEach { summary.append("\n").append("• ${it.title}") }
|
||||
}
|
||||
|
||||
description = summary.toString()
|
||||
genre = metadata.genres.joinToString()
|
||||
status = metadata.status.toStatus()
|
||||
}
|
||||
|
||||
private fun String.toStatus(): Int {
|
||||
return when (this) {
|
||||
"ONGOING" -> SManga.ONGOING
|
||||
else -> SManga.COMPLETED
|
||||
}
|
||||
private fun String.toStatus(): Int {
|
||||
return when (this) {
|
||||
"ONGOING" -> SManga.ONGOING
|
||||
"ENDED" -> SManga.COMPLETED
|
||||
else -> SManga.UNKNOWN
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Serializable
|
||||
class ChapterDto(
|
||||
val data: Data,
|
||||
val content: List<Book>,
|
||||
) {
|
||||
@Serializable
|
||||
class Data(
|
||||
val content: List<Book>,
|
||||
class Book(
|
||||
val id: String,
|
||||
@SerialName("series_id")
|
||||
val seriesId: String,
|
||||
val title: String,
|
||||
@SerialName("release_date")
|
||||
val releaseDate: String?,
|
||||
@SerialName("pages_count")
|
||||
val pagesCount: Int,
|
||||
) {
|
||||
@Serializable
|
||||
class Book(
|
||||
val metadata: Metadata,
|
||||
val id: String,
|
||||
val seriesId: String,
|
||||
val created: String,
|
||||
) {
|
||||
@Serializable
|
||||
class Metadata(
|
||||
val title: String,
|
||||
)
|
||||
|
||||
fun toSChapter(): SChapter = SChapter.create().apply {
|
||||
url = "$seriesId;$id"
|
||||
name = metadata.title
|
||||
date_upload = dateFormat.tryParse(created)
|
||||
}
|
||||
fun toSChapter(): SChapter = SChapter.create().apply {
|
||||
url = "$seriesId;$id;$pagesCount"
|
||||
name = title
|
||||
date_upload = dateFormat.tryParse(releaseDate)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val dateFormat by lazy {
|
||||
SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH)
|
||||
}
|
||||
private val dateFormat = SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH)
|
||||
}
|
||||
}
|
||||
|
||||
@ -117,19 +101,3 @@ class ChallengeDto(
|
||||
@SerialName("access_token")
|
||||
val accessToken: String,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
class PagesCountDto(
|
||||
val data: Data,
|
||||
) {
|
||||
@Serializable
|
||||
class Data(
|
||||
val media: PagesCount,
|
||||
) {
|
||||
@Serializable
|
||||
class PagesCount(
|
||||
@SerialName("pagesCount")
|
||||
val pagesCount: Int,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -144,7 +144,7 @@ class Kagane : HttpSource(), ConfigurableSource {
|
||||
// =============================== Latest ===============================
|
||||
|
||||
override fun latestUpdatesRequest(page: Int) =
|
||||
searchMangaRequest(page, "", FilterList(SortFilter(1)))
|
||||
searchMangaRequest(page, "", FilterList(SortFilter(2)))
|
||||
|
||||
override fun latestUpdatesParse(response: Response) = searchMangaParse(response)
|
||||
|
||||
@ -188,7 +188,7 @@ class Kagane : HttpSource(), ConfigurableSource {
|
||||
|
||||
override fun mangaDetailsParse(response: Response): SManga {
|
||||
val dto = response.parseAs<DetailsDto>()
|
||||
return dto.data.toSManga()
|
||||
return dto.toSManga()
|
||||
}
|
||||
|
||||
override fun mangaDetailsRequest(manga: SManga): Request {
|
||||
@ -203,7 +203,7 @@ class Kagane : HttpSource(), ConfigurableSource {
|
||||
|
||||
override fun chapterListParse(response: Response): List<SChapter> {
|
||||
val dto = response.parseAs<ChapterDto>()
|
||||
return dto.data.content.map { it.toSChapter() }.reversed()
|
||||
return dto.content.map { it.toSChapter() }.reversed()
|
||||
}
|
||||
|
||||
override fun chapterListRequest(manga: SManga): Request {
|
||||
@ -224,15 +224,16 @@ class Kagane : HttpSource(), ConfigurableSource {
|
||||
}
|
||||
|
||||
override fun fetchPageList(chapter: SChapter): Observable<List<Page>> {
|
||||
var (seriesId, chapterId) = chapter.url.split(";")
|
||||
if (chapter.url.count { it == ';' } == 2) throw Exception("Chapter url error, please refresh chapter list.")
|
||||
var (seriesId, chapterId, pageCount) = chapter.url.split(";")
|
||||
|
||||
val challengeResp = getChallengeResponse(seriesId, chapterId)
|
||||
accessToken = challengeResp.accessToken
|
||||
val pageCount = getPageCountResponse(seriesId, chapterId)
|
||||
if (preferences.dataSaver) {
|
||||
chapterId = chapterId + "_ds"
|
||||
}
|
||||
val pages = (0 until pageCount).map { page ->
|
||||
|
||||
val pages = (0 until pageCount.toInt()).map { page ->
|
||||
val pageUrl = "$apiUrl/api/v1/books".toHttpUrl().newBuilder().apply {
|
||||
addPathSegment(seriesId)
|
||||
addPathSegment("file")
|
||||
@ -363,15 +364,6 @@ class Kagane : HttpSource(), ConfigurableSource {
|
||||
.parseAs<ChallengeDto>()
|
||||
}
|
||||
|
||||
private fun getPageCountResponse(seriesId: String, chapterId: String): Int {
|
||||
val challengeUrl = "$apiUrl/api/v1/books/$seriesId/metadata/$chapterId"
|
||||
|
||||
val dto = client.newCall(GET(challengeUrl, apiHeaders)).execute()
|
||||
.parseAs<PagesCountDto>()
|
||||
|
||||
return dto.data.media.pagesCount
|
||||
}
|
||||
|
||||
private fun concat(vararg arrays: ByteArray): ByteArray =
|
||||
arrays.reduce { acc, bytes -> acc + bytes }
|
||||
|
||||
@ -418,7 +410,7 @@ class Kagane : HttpSource(), ConfigurableSource {
|
||||
private val SharedPreferences.showNsfw
|
||||
get() = this.getBoolean(SHOW_NSFW_KEY, true)
|
||||
private val SharedPreferences.dataSaver
|
||||
get() = this.getBoolean(DATA_SAVER, true)
|
||||
get() = this.getBoolean(DATA_SAVER, false)
|
||||
|
||||
override fun setupPreferenceScreen(screen: PreferenceScreen) {
|
||||
SwitchPreferenceCompat(screen.context).apply {
|
||||
@ -429,7 +421,7 @@ class Kagane : HttpSource(), ConfigurableSource {
|
||||
SwitchPreferenceCompat(screen.context).apply {
|
||||
key = DATA_SAVER
|
||||
title = "Data saver"
|
||||
setDefaultValue(true)
|
||||
setDefaultValue(false)
|
||||
}.let(screen::addPreference)
|
||||
}
|
||||
|
||||
@ -437,7 +429,7 @@ class Kagane : HttpSource(), ConfigurableSource {
|
||||
|
||||
companion object {
|
||||
private const val SHOW_NSFW_KEY = "pref_show_nsfw"
|
||||
private const val DATA_SAVER = "data_saver"
|
||||
private const val DATA_SAVER = "data_saver_default"
|
||||
}
|
||||
|
||||
// ============================= Filters ==============================
|
||||
@ -449,7 +441,7 @@ class Kagane : HttpSource(), ConfigurableSource {
|
||||
class SortFilter(state: Int = 0) : UriPartFilter(
|
||||
"Sort By",
|
||||
arrayOf(
|
||||
Pair("Relevance", ""),
|
||||
Pair("Relevance", "avg_views,desc"),
|
||||
Pair("Latest", "updated_at"),
|
||||
Pair("Latest Descending", "updated_at,desc"),
|
||||
Pair("By Name", "series_name"),
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user