Dynasty: original covers & chapter metadata (#9604)
* original covers & chapter metadata * use cached cover if new one is same
This commit is contained in:
parent
ea34656edf
commit
aedd777371
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,7 +1,7 @@
|
|||||||
ext {
|
ext {
|
||||||
extName = 'Dynasty'
|
extName = 'Dynasty'
|
||||||
extClass = '.DynastyFactory'
|
extClass = '.DynastyFactory'
|
||||||
extVersionCode = 26
|
extVersionCode = 27
|
||||||
isNsfw = true
|
isNsfw = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,6 +74,7 @@ class MangaEntry(
|
|||||||
class MangaResponse(
|
class MangaResponse(
|
||||||
val name: String,
|
val name: String,
|
||||||
val type: String,
|
val type: String,
|
||||||
|
val permalink: String,
|
||||||
val tags: List<BrowseTag>,
|
val tags: List<BrowseTag>,
|
||||||
val cover: String?,
|
val cover: String?,
|
||||||
val description: String?,
|
val description: String?,
|
||||||
@ -81,7 +82,15 @@ class MangaResponse(
|
|||||||
@Serializable(with = ChapterItemListSerializer::class)
|
@Serializable(with = ChapterItemListSerializer::class)
|
||||||
val taggings: List<ChapterItem>,
|
val taggings: List<ChapterItem>,
|
||||||
@SerialName("total_pages") val totalPages: Int = 0,
|
@SerialName("total_pages") val totalPages: Int = 0,
|
||||||
)
|
) {
|
||||||
|
val directory get() = when (type) {
|
||||||
|
SERIES_TYPE -> SERIES_DIR
|
||||||
|
ANTHOLOGY_TYPE -> ANTHOLOGIES_DIR
|
||||||
|
DOUJIN_TYPE -> DOUJINS_DIR
|
||||||
|
ISSUE_TYPE -> ISSUES_DIR
|
||||||
|
else -> throw Exception("Unsupported Type for directory: $type")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
sealed class ChapterItem
|
sealed class ChapterItem
|
||||||
@ -122,6 +131,7 @@ object ChapterItemListSerializer : JsonTransformingSerializer<List<ChapterItem>>
|
|||||||
@Serializable
|
@Serializable
|
||||||
class ChapterResponse(
|
class ChapterResponse(
|
||||||
val title: String,
|
val title: String,
|
||||||
|
val permalink: String,
|
||||||
val tags: List<BrowseTag>,
|
val tags: List<BrowseTag>,
|
||||||
val pages: List<Page>,
|
val pages: List<Page>,
|
||||||
@SerialName("released_on") val releasedOn: String,
|
@SerialName("released_on") val releasedOn: String,
|
||||||
|
@ -50,7 +50,7 @@ open class Dynasty : HttpSource(), ConfigurableSource {
|
|||||||
override val client = network.cloudflareClient.newBuilder()
|
override val client = network.cloudflareClient.newBuilder()
|
||||||
.addInterceptor(::fetchCoverUrlInterceptor)
|
.addInterceptor(::fetchCoverUrlInterceptor)
|
||||||
.addInterceptor(::coverInterceptor)
|
.addInterceptor(::coverInterceptor)
|
||||||
.rateLimit(1, 2)
|
.rateLimit(1)
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
private val coverClient = network.cloudflareClient
|
private val coverClient = network.cloudflareClient
|
||||||
@ -74,7 +74,7 @@ open class Dynasty : HttpSource(), ConfigurableSource {
|
|||||||
MangaEntry(
|
MangaEntry(
|
||||||
url = "/${tag.directory}/${tag.permalink}",
|
url = "/${tag.directory}/${tag.permalink}",
|
||||||
title = tag.name,
|
title = tag.name,
|
||||||
cover = getCoverUrl(tag.directory, tag.permalink),
|
cover = getCachedCoverUrl(tag.directory, tag.permalink),
|
||||||
).also(entries::add)
|
).also(entries::add)
|
||||||
|
|
||||||
// true if an associated series is found
|
// true if an associated series is found
|
||||||
@ -115,7 +115,7 @@ open class Dynasty : HttpSource(), ConfigurableSource {
|
|||||||
val entry = MangaEntry(
|
val entry = MangaEntry(
|
||||||
url = "/$directory/$permalink",
|
url = "/$directory/$permalink",
|
||||||
title = permalink.permalinkToTitle(),
|
title = permalink.permalinkToTitle(),
|
||||||
cover = getCoverUrl(directory, permalink),
|
cover = getCachedCoverUrl(directory, permalink),
|
||||||
).toSManga()
|
).toSManga()
|
||||||
|
|
||||||
return Observable.just(
|
return Observable.just(
|
||||||
@ -280,7 +280,7 @@ open class Dynasty : HttpSource(), ConfigurableSource {
|
|||||||
val entry = MangaEntry(
|
val entry = MangaEntry(
|
||||||
url = "/$directory/$permalink",
|
url = "/$directory/$permalink",
|
||||||
title = title,
|
title = title,
|
||||||
cover = getCoverUrl(directory, permalink),
|
cover = getCachedCoverUrl(directory, permalink),
|
||||||
)
|
)
|
||||||
|
|
||||||
if (firstEntry == null) {
|
if (firstEntry == null) {
|
||||||
@ -422,7 +422,29 @@ open class Dynasty : HttpSource(), ConfigurableSource {
|
|||||||
.any { publishingStatus.contains(it) } -> SManga.CANCELLED
|
.any { publishingStatus.contains(it) } -> SManga.CANCELLED
|
||||||
else -> SManga.UNKNOWN
|
else -> SManga.UNKNOWN
|
||||||
}
|
}
|
||||||
thumbnail_url = data.cover?.let { buildCoverUrl(it) }
|
// if new cover is same as cached cover, use cached cover
|
||||||
|
// to avoid making HEAD requests in `getHDCoverUrlIfAvailable`
|
||||||
|
thumbnail_url = run {
|
||||||
|
val newCover = data.cover?.let { buildCoverUrl(it) }
|
||||||
|
val cachedCover = getCachedCoverUrl(data.directory, data.permalink)
|
||||||
|
|
||||||
|
if (newCover == null || cachedCover == null) {
|
||||||
|
newCover?.let { getHDCoverUrlIfAvailable(it) } ?: cachedCover
|
||||||
|
} else {
|
||||||
|
val path = cachedCover.toHttpUrl().pathSegments
|
||||||
|
val tmpSDCover = cachedCover.toHttpUrl().newBuilder().apply {
|
||||||
|
val file = path.last().substringBeforeLast(".") + ".jpg"
|
||||||
|
setPathSegment(5, "medium")
|
||||||
|
setPathSegment(path.size - 1, file)
|
||||||
|
}.toString()
|
||||||
|
|
||||||
|
if (tmpSDCover == newCover) {
|
||||||
|
cachedCover
|
||||||
|
} else {
|
||||||
|
getHDCoverUrlIfAvailable(newCover)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -470,30 +492,15 @@ open class Dynasty : HttpSource(), ConfigurableSource {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun fetchChapterList(manga: SManga): Observable<List<SChapter>> {
|
|
||||||
return if (manga.url.contains("/$CHAPTERS_DIR/")) {
|
|
||||||
Observable.just(
|
|
||||||
listOf(
|
|
||||||
SChapter.create().apply {
|
|
||||||
url = manga.url
|
|
||||||
name = "Chapter"
|
|
||||||
date_upload = dateFormat.tryParse(
|
|
||||||
manga.description
|
|
||||||
?.substringAfter("Released:", ""),
|
|
||||||
)
|
|
||||||
},
|
|
||||||
),
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
super.fetchChapterList(manga)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun chapterListRequest(manga: SManga): Request {
|
override fun chapterListRequest(manga: SManga): Request {
|
||||||
return mangaDetailsRequest(manga)
|
return mangaDetailsRequest(manga)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun chapterListParse(response: Response): List<SChapter> {
|
override fun chapterListParse(response: Response): List<SChapter> {
|
||||||
|
if (response.request.url.pathSegments[0] == CHAPTERS_DIR) {
|
||||||
|
return listOf(individualChapterParse(response))
|
||||||
|
}
|
||||||
|
|
||||||
val data = response.parseAs<MangaResponse>()
|
val data = response.parseAs<MangaResponse>()
|
||||||
val chapters = data.taggings.toMutableList()
|
val chapters = data.taggings.toMutableList()
|
||||||
|
|
||||||
@ -542,6 +549,17 @@ open class Dynasty : HttpSource(), ConfigurableSource {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun individualChapterParse(response: Response): SChapter {
|
||||||
|
val data = response.parseAs<ChapterResponse>()
|
||||||
|
|
||||||
|
return SChapter.create().apply {
|
||||||
|
url = "/$CHAPTERS_DIR/${data.permalink}"
|
||||||
|
name = "Chapter"
|
||||||
|
scanlator = data.tags.filter { it.type == "Scanlator" }.joinToString { it.name }
|
||||||
|
date_upload = dateFormat.tryParse(data.releasedOn)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun getChapterUrl(chapter: SChapter): String {
|
override fun getChapterUrl(chapter: SChapter): String {
|
||||||
return baseUrl + chapter.url
|
return baseUrl + chapter.url
|
||||||
}
|
}
|
||||||
@ -606,7 +624,7 @@ open class Dynasty : HttpSource(), ConfigurableSource {
|
|||||||
.parseAs()
|
.parseAs()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getCoverUrl(directory: String?, permalink: String): String? {
|
private fun getCachedCoverUrl(directory: String?, permalink: String): String? {
|
||||||
directory ?: return null
|
directory ?: return null
|
||||||
|
|
||||||
if (directory == CHAPTERS_DIR) {
|
if (directory == CHAPTERS_DIR) {
|
||||||
@ -619,17 +637,44 @@ open class Dynasty : HttpSource(), ConfigurableSource {
|
|||||||
return buildCoverUrl(file)
|
return buildCoverUrl(file)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun getHDCoverUrlIfAvailable(coverUrl: String): String {
|
||||||
|
val path = coverUrl.toHttpUrl().pathSegments
|
||||||
|
|
||||||
|
if (path.size == 7 && path[5] == "medium") {
|
||||||
|
listOf("jpg", "png", "jpeg", "webp").forEach { format ->
|
||||||
|
val newUrl = coverUrl.toHttpUrl().newBuilder().apply {
|
||||||
|
val file = path.last().substringBeforeLast(".") + ".$format"
|
||||||
|
setPathSegment(5, "original")
|
||||||
|
setPathSegment(path.size - 1, file)
|
||||||
|
}.build()
|
||||||
|
|
||||||
|
val request = Request.Builder()
|
||||||
|
.url(newUrl)
|
||||||
|
.headers(headers)
|
||||||
|
.head()
|
||||||
|
.build()
|
||||||
|
|
||||||
|
if (coverClient.newCall(request).execute().isSuccessful) {
|
||||||
|
return newUrl.toString()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return coverUrl
|
||||||
|
}
|
||||||
|
|
||||||
private fun buildCoverUrl(file: String): String {
|
private fun buildCoverUrl(file: String): String {
|
||||||
val path = "$baseUrl$file".toHttpUrl()
|
val path = "$baseUrl$file".toHttpUrl()
|
||||||
.encodedPath
|
.encodedPath
|
||||||
.removePrefix("/")
|
.removePrefix("/")
|
||||||
|
|
||||||
return baseUrl.toHttpUrl()
|
return baseUrl.toHttpUrl().newBuilder().apply {
|
||||||
.newBuilder()
|
if (!path.startsWith("system/")) {
|
||||||
.addEncodedPathSegments(path)
|
addEncodedPathSegments("system/tag_contents_covers/000")
|
||||||
.fragment(COVER_URL_FRAGMENT)
|
}
|
||||||
.build()
|
addEncodedPathSegments(path)
|
||||||
.toString()
|
fragment(COVER_URL_FRAGMENT)
|
||||||
|
}.toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun buildChapterCoverFetchUrl(permalink: String): String {
|
private fun buildChapterCoverFetchUrl(permalink: String): String {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user