Roumanwu: chapter upload date logic and cleanup (#12169)

This commit is contained in:
kasperskier 2022-06-12 22:17:41 +08:00 committed by GitHub
parent 4ed2c3d31e
commit cff72ef4ce
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 32 additions and 14 deletions

View File

@ -6,7 +6,7 @@ ext {
extName = 'Roumanwu' extName = 'Roumanwu'
pkgNameSuffix = 'zh.roumanwu' pkgNameSuffix = 'zh.roumanwu'
extClass = '.Roumanwu' extClass = '.Roumanwu'
extVersionCode = 1 extVersionCode = 2
isNsfw = true isNsfw = true
} }

View File

@ -12,6 +12,7 @@ import eu.kanade.tachiyomi.source.online.HttpSource
import eu.kanade.tachiyomi.util.asJsoup import eu.kanade.tachiyomi.util.asJsoup
import kotlinx.serialization.decodeFromString import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import kotlinx.serialization.json.decodeFromStream
import okhttp3.Response import okhttp3.Response
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
@ -23,15 +24,14 @@ class Roumanwu : HttpSource(), ConfigurableSource {
override val lang = "zh" override val lang = "zh"
override val supportsLatest = true override val supportsLatest = true
private val preferences: SharedPreferences by lazy { private val preferences: SharedPreferences =
Injekt.get<Application>().getSharedPreferences("source_$id", 0x0000) Injekt.get<Application>().getSharedPreferences("source_$id", 0x0000)
}
override val baseUrl = MIRRORS[ override val baseUrl = MIRRORS[
max(MIRRORS.size - 1, preferences.getString(MIRROR_PREF, MIRROR_DEFAULT)!!.toInt()) max(MIRRORS.size - 1, preferences.getString(MIRROR_PREF, MIRROR_DEFAULT)!!.toInt())
] ]
override val client = network.client.newBuilder().addInterceptor(ScrambledImageInterceptor()).build() override val client = network.client.newBuilder().addInterceptor(ScrambledImageInterceptor).build()
private val json: Json by injectLazy() private val json: Json by injectLazy()
@ -60,9 +60,10 @@ class Roumanwu : HttpSource(), ConfigurableSource {
return if (chapter.images != null) { return if (chapter.images != null) {
chapter.getPageList() chapter.getPageList()
} else { } else {
@Suppress("NAME_SHADOWING")
val response = client.newCall(GET(baseUrl + chapter.chapterAPIPath!!, headers)).execute() val response = client.newCall(GET(baseUrl + chapter.chapterAPIPath!!, headers)).execute()
if (!response.isSuccessful) throw Exception("服务器错误: ${response.code}") if (!response.isSuccessful) throw Exception("服务器错误: ${response.code}")
json.decodeFromString<ChapterWrapper>(response.body!!.string()).chapter.getPageList() response.parseAs<ChapterWrapper>().chapter.getPageList()
} }
} }
@ -125,6 +126,8 @@ class Roumanwu : HttpSource(), ConfigurableSource {
private val TAGS = arrayOf("全部", "正妹", "恋爱", "出版漫画", "肉慾", "浪漫", "大尺度", "巨乳", "有夫之婦", "女大生", "狗血劇", "同居", "好友", "調教", "动作", "後宮", "不倫") private val TAGS = arrayOf("全部", "正妹", "恋爱", "出版漫画", "肉慾", "浪漫", "大尺度", "巨乳", "有夫之婦", "女大生", "狗血劇", "同居", "好友", "調教", "动作", "後宮", "不倫")
} }
private inline fun <reified T> Response.parseAs(): T = json.decodeFromStream(this.body!!.byteStream())
private inline fun <reified T> Response.nextjsData() = private inline fun <reified T> Response.nextjsData() =
json.decodeFromString<NextData<T>>(this.asJsoup().select("#__NEXT_DATA__").html()).props.pageProps json.decodeFromString<NextData<T>>(this.asJsoup().select("#__NEXT_DATA__").html()).props.pageProps
} }

View File

@ -1,10 +1,13 @@
package eu.kanade.tachiyomi.extension.zh.roumanwu package eu.kanade.tachiyomi.extension.zh.roumanwu
import eu.kanade.tachiyomi.AppInfo
import eu.kanade.tachiyomi.source.model.MangasPage import eu.kanade.tachiyomi.source.model.MangasPage
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 kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import java.text.SimpleDateFormat
import java.util.Locale
import java.util.UUID import java.util.UUID
@Serializable @Serializable
@ -23,7 +26,7 @@ data class Book(
val author: String, val author: String,
val continued: Boolean, val continued: Boolean,
val tags: List<String>, val tags: List<String>,
val updatedAt: String? = null, // TODO: 2022-06-02T00:00:00.000Z val updatedAt: String? = null,
val activeResource: Resource? = null, val activeResource: Resource? = null,
) { ) {
fun toSManga() = SManga.create().apply { fun toSManga() = SManga.create().apply {
@ -42,11 +45,26 @@ data class Book(
url = "/books/$id/$i" url = "/books/$id/$i"
name = it name = it
} }
}.apply {
if (isNewDateLogic && !updatedAt.isNullOrBlank()) {
this[lastIndex].date_upload = DATE_FORMAT.parse(updatedAt)?.time ?: 0L
}
} }
private val uuid by lazy { UUID.fromString(id) } private val uuid by lazy { UUID.fromString(id) }
override fun hashCode() = uuid.hashCode() override fun hashCode() = uuid.hashCode()
override fun equals(other: Any?) = other is Book && uuid == other.uuid override fun equals(other: Any?) = other is Book && uuid == other.uuid
companion object {
private val DATE_FORMAT = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.ENGLISH)
private val isNewDateLogic = run {
val commitCount = AppInfo.getVersionName().substringAfter('-', "")
if (commitCount.isNotEmpty()) // Preview
commitCount.toInt() >= 4442
else // Stable
AppInfo.getVersionCode() >= 81
}
}
} }
@Serializable @Serializable
@ -81,7 +99,7 @@ data class Chapter(
val chapterAPIPath: String? = null, val chapterAPIPath: String? = null,
) { ) {
fun getPageList() = images!!.mapIndexed { i, it -> fun getPageList() = images!!.mapIndexed { i, it ->
Page(i, imageUrl = it.src + if (it.scramble) SCRAMBLED_SUFFIX else "") Page(i, imageUrl = it.src + if (it.scramble) ScrambledImageInterceptor.SCRAMBLED_SUFFIX else "")
} }
} }
@ -90,5 +108,3 @@ data class ChapterWrapper(val chapter: Chapter)
@Serializable @Serializable
data class Image(val src: String, val scramble: Boolean) data class Image(val src: String, val scramble: Boolean)
const val SCRAMBLED_SUFFIX = "?scrambled"

View File

@ -12,7 +12,7 @@ import okhttp3.ResponseBody.Companion.toResponseBody
import java.io.ByteArrayOutputStream import java.io.ByteArrayOutputStream
import java.security.MessageDigest import java.security.MessageDigest
class ScrambledImageInterceptor : Interceptor { object ScrambledImageInterceptor : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response { override fun intercept(chain: Interceptor.Chain): Response {
val request = chain.request() val request = chain.request()
val response = chain.proceed(request) val response = chain.proceed(request)
@ -48,8 +48,7 @@ class ScrambledImageInterceptor : Interceptor {
return response.newBuilder().body(responseBody).build() return response.newBuilder().body(responseBody).build()
} }
companion object { private val jpegMediaType = "image/jpeg".toMediaType()
private val jpegMediaType = "image/jpeg".toMediaType() private fun Byte.toPositiveInt() = toInt() and 0xFF
private fun Byte.toPositiveInt() = toInt() and 0xFF const val SCRAMBLED_SUFFIX = "#scrambled"
}
} }