From a3b612a9405edf1f2925f4d3e2df85799c82f569 Mon Sep 17 00:00:00 2001 From: AntsyLich <59261191+AntsyLich@users.noreply.github.com> Date: Mon, 7 Nov 2022 21:14:17 +0600 Subject: [PATCH] Bilibili (Multisrc): Refactor some codes (#14164) * Bilibili (Multisrc): Refactor some codes * Lint * Fix import --- .../bilibilicomics/AndroidManifest.xml | 22 ++----- .../src/BilibiliComicsFactory.kt | 4 ++ .../bilibilimanga/AndroidManifest.xml | 13 ++-- .../tachiyomi/multisrc/bilibili/Bilibili.kt | 62 ++++++++----------- .../multisrc/bilibili/BilibiliDto.kt | 2 +- .../multisrc/bilibili/BilibiliGenerator.kt | 2 +- .../multisrc/bilibili/BilibiliIntl.kt | 37 ++++++----- .../multisrc/bilibili/BilibiliUrlActivity.kt | 3 +- 8 files changed, 64 insertions(+), 81 deletions(-) diff --git a/multisrc/overrides/bilibili/bilibilicomics/AndroidManifest.xml b/multisrc/overrides/bilibili/bilibilicomics/AndroidManifest.xml index 47787bc19..3b9ee6b2f 100644 --- a/multisrc/overrides/bilibili/bilibilicomics/AndroidManifest.xml +++ b/multisrc/overrides/bilibili/bilibilicomics/AndroidManifest.xml @@ -14,25 +14,13 @@ - + - + + + - - - + diff --git a/multisrc/overrides/bilibili/bilibilicomics/src/BilibiliComicsFactory.kt b/multisrc/overrides/bilibili/bilibilicomics/src/BilibiliComicsFactory.kt index 22f2f3ad1..f9e8c9cc6 100644 --- a/multisrc/overrides/bilibili/bilibilicomics/src/BilibiliComicsFactory.kt +++ b/multisrc/overrides/bilibili/bilibilicomics/src/BilibiliComicsFactory.kt @@ -31,6 +31,7 @@ import okhttp3.Response import okio.Buffer import java.io.IOException import java.net.URLDecoder +import java.util.Calendar class BilibiliComicsFactory : SourceFactory { override fun createSources() = listOf( @@ -67,6 +68,9 @@ abstract class BilibiliComics(lang: String) : Bilibili( private var accessTokenCookie: BilibiliAccessTokenCookie? = null + private val dayOfWeek: Int + get() = Calendar.getInstance().get(Calendar.DAY_OF_WEEK) - 1 + override fun latestUpdatesRequest(page: Int): Request { val jsonPayload = buildJsonObject { put("day", dayOfWeek) } val requestBody = jsonPayload.toString().toRequestBody(JSON_MEDIA_TYPE) diff --git a/multisrc/overrides/bilibili/bilibilimanga/AndroidManifest.xml b/multisrc/overrides/bilibili/bilibilimanga/AndroidManifest.xml index 36b5bd4bf..5603a61fe 100644 --- a/multisrc/overrides/bilibili/bilibilimanga/AndroidManifest.xml +++ b/multisrc/overrides/bilibili/bilibilimanga/AndroidManifest.xml @@ -14,15 +14,12 @@ - + - + + + + diff --git a/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/bilibili/Bilibili.kt b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/bilibili/Bilibili.kt index 62906a1b9..ceb755e6e 100644 --- a/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/bilibili/Bilibili.kt +++ b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/bilibili/Bilibili.kt @@ -34,7 +34,6 @@ import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.api.get import uy.kohesive.injekt.injectLazy import java.text.SimpleDateFormat -import java.util.Calendar import java.util.Locale abstract class Bilibili( @@ -46,7 +45,7 @@ abstract class Bilibili( override val supportsLatest = true override val client: OkHttpClient = network.cloudflareClient.newBuilder() - .addInterceptor(::expiredTokenIntercept) + .addInterceptor(::expiredImageTokenIntercept) .rateLimitHost(baseUrl.toHttpUrl(), 1) .rateLimitHost(CDN_URL.toHttpUrl(), 2) .rateLimitHost(COVER_CDN_URL.toHttpUrl(), 2) @@ -76,9 +75,6 @@ abstract class Bilibili( protected open val signedIn: Boolean = false - protected val dayOfWeek: Int - get() = Calendar.getInstance().get(Calendar.DAY_OF_WEEK) - 1 - override fun popularMangaRequest(page: Int): Request = searchMangaRequest( page = page, query = "", @@ -100,11 +96,9 @@ abstract class Bilibili( override fun latestUpdatesParse(response: Response): MangasPage = searchMangaParse(response) override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { - if (query.startsWith(PREFIX_ID_SEARCH) && query.matches(ID_SEARCH_PATTERN)) { - val comicId = query - .removePrefix(PREFIX_ID_SEARCH) - .removePrefix("mc") - return mangaDetailsApiRequest("/detail/mc$comicId") + ID_SEARCH_PATTERN.matchEntire(query)?.let { + val (id) = it.destructured + return mangaDetailsApiRequest("/detail/mc$id") } val price = filters.firstInstanceOrNull()?.state ?: 0 @@ -144,12 +138,13 @@ abstract class Bilibili( } override fun searchMangaParse(response: Response): MangasPage { - if (response.request.url.toString().contains("ComicDetail")) { + val requestUrl = response.request.url.toString() + if (requestUrl.contains("ComicDetail")) { val comic = mangaDetailsParse(response) return MangasPage(listOf(comic), hasNextPage = false) } - if (response.request.url.toString().contains("ClassPage")) { + if (requestUrl.contains("ClassPage")) { val result = response.parseAs>() if (result.code != 0) { @@ -210,8 +205,7 @@ abstract class Bilibili( } override fun mangaDetailsParse(response: Response): SManga = SManga.create().apply { - val result = response.parseAs() - val comic = result.data!! + val comic = response.parseAs().data!! title = comic.title author = comic.authorName.joinToString() @@ -231,7 +225,7 @@ abstract class Bilibili( append("\n• ${intl.totalChapterCount}: ${intl.localize(comic.episodeList.size)}") if (comic.updateWeekdays.isNotEmpty() && status == SManga.ONGOING) { - append("\n• ${intl.updatedEvery}: ${intl.getWeekdays(comic.updateWeekdays)}") + append("\n• ${intl.getUpdateDays(comic.updateWeekdays)}") } } thumbnail_url = comic.verticalCover @@ -254,9 +248,8 @@ abstract class Bilibili( } protected open fun chapterFromObject(episode: BilibiliEpisodeDto, comicId: Int): SChapter = SChapter.create().apply { - name = intl.episodePrefix + episode.shortTitle + - (if (episode.title.isNotBlank()) " - " + episode.title else "") - date_upload = episode.publicationTime.substringBefore("T").toDate() + name = episode.shortTitle.plus(if (episode.title.isNotBlank()) " - ${episode.title}" else "") + date_upload = episode.publicationTime.toDate() url = "/mc$comicId/${episode.id}" } @@ -373,46 +366,45 @@ abstract class Bilibili( return FilterList(filters) } - private fun expiredTokenIntercept(chain: Interceptor.Chain): Response { + private fun expiredImageTokenIntercept(chain: Interceptor.Chain): Response { val response = chain.proceed(chain.request()) // Get a new image token if the current one expired. if (response.code == 403 && chain.request().url.toString().contains(CDN_URL)) { + response.close() val imagePath = chain.request().url.toString() .substringAfter(CDN_URL) .substringBefore("?token=") val imageTokenRequest = imageTokenRequest(listOf(imagePath)) val imageTokenResponse = chain.proceed(imageTokenRequest) val imageTokenResult = imageTokenResponse.parseAs>() + imageTokenResponse.close() - val newPage = imageTokenResult.data!![0] + val newPage = imageTokenResult.data!!.first() val newPageUrl = "${newPage.url}?token=${newPage.token}" val newRequest = imageRequest(Page(0, "", newPageUrl)) - imageTokenResponse.close() - response.close() return chain.proceed(newRequest) } return response } - protected val SharedPreferences.chapterImageQuality + private val SharedPreferences.chapterImageQuality get() = when (getString("${IMAGE_QUALITY_PREF_KEY}_$lang", IMAGE_QUALITY_PREF_DEFAULT_VALUE)!!) { - "raw" -> "1600w" - "hd" -> "1000w" - "sd" -> "800w_50q" - else -> "raw+" + "hd" -> "1600w" + "sd" -> "1000w" + "low" -> "800w_50q" + else -> "raw" } - protected val SharedPreferences.chapterImageFormat + private val SharedPreferences.chapterImageFormat get() = getString("${IMAGE_FORMAT_PREF_KEY}_$lang", IMAGE_FORMAT_PREF_DEFAULT_VALUE)!! - private inline fun List<*>.firstInstanceOrNull(): R? = - filterIsInstance().firstOrNull() + private inline fun List<*>.firstInstanceOrNull(): R? = firstOrNull { it is R } as? R - protected open fun HttpUrl.Builder.addCommonParameters(): HttpUrl.Builder = let { + protected open fun HttpUrl.Builder.addCommonParameters(): HttpUrl.Builder = apply { if (name == "BILIBILI COMICS") { addQueryParameter("lang", apiLang) addQueryParameter("sys_lang", apiLang) @@ -420,8 +412,6 @@ abstract class Bilibili( addQueryParameter("device", "pc") addQueryParameter("platform", "web") - - return@let it } protected inline fun Response.parseAs(): BilibiliResultDto = use { @@ -447,10 +437,10 @@ abstract class Bilibili( private const val SEARCH_PER_PAGE = 9 const val PREFIX_ID_SEARCH = "id:" - private val ID_SEARCH_PATTERN = "^id:(mc)?(\\d+)$".toRegex() + private val ID_SEARCH_PATTERN = "^${PREFIX_ID_SEARCH}mc(\\d+)$".toRegex() private const val IMAGE_QUALITY_PREF_KEY = "chapterImageQuality" - private val IMAGE_QUALITY_PREF_ENTRY_VALUES = arrayOf("raw+", "raw", "hd", "sd") + private val IMAGE_QUALITY_PREF_ENTRY_VALUES = arrayOf("raw", "hd", "sd", "low") private val IMAGE_QUALITY_PREF_DEFAULT_VALUE = IMAGE_QUALITY_PREF_ENTRY_VALUES[1] private const val IMAGE_FORMAT_PREF_KEY = "chapterImageFormat" @@ -461,7 +451,7 @@ abstract class Bilibili( const val THUMBNAIL_RESOLUTION = "@512w.jpg" private val DATE_FORMATTER by lazy { - SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH) + SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.ENGLISH) } private const val EMOJI_LOCKED = "\uD83D\uDD12" diff --git a/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/bilibili/BilibiliDto.kt b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/bilibili/BilibiliDto.kt index 970ba7372..bf267e067 100644 --- a/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/bilibili/BilibiliDto.kt +++ b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/bilibili/BilibiliDto.kt @@ -65,7 +65,7 @@ data class BilibiliImageDto( ) { fun url(quality: String, format: String): String { - val imageWidth = if (quality == "raw+") "${width}w" else quality + val imageWidth = if (quality == "raw") "${width}w" else quality return "$path@$imageWidth.$format" } diff --git a/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/bilibili/BilibiliGenerator.kt b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/bilibili/BilibiliGenerator.kt index cfe8d7565..073795dbd 100644 --- a/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/bilibili/BilibiliGenerator.kt +++ b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/bilibili/BilibiliGenerator.kt @@ -10,7 +10,7 @@ class BilibiliGenerator : ThemeSourceGenerator { override val themeClass = "Bilibili" - override val baseVersionCode: Int = 7 + override val baseVersionCode: Int = 8 override val sources = listOf( MultiLang( diff --git a/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/bilibili/BilibiliIntl.kt b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/bilibili/BilibiliIntl.kt index 09892ac58..375c51aa2 100644 --- a/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/bilibili/BilibiliIntl.kt +++ b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/bilibili/BilibiliIntl.kt @@ -43,12 +43,6 @@ class BilibiliIntl(private val lang: String) { else -> "Price" } - val episodePrefix: String = when (lang) { - CHINESE, SIMPLIFIED_CHINESE -> "" - SPANISH -> "Cap. " - else -> "Ep. " - } - fun hasPaidChaptersWarning(chapterCount: Int): String = when (lang) { CHINESE, SIMPLIFIED_CHINESE -> "${Bilibili.EMOJI_WARNING} 此漫画有 ${chapterCount.localized} 个付费章节,已在目录中隐藏。" + @@ -73,8 +67,8 @@ class BilibiliIntl(private val lang: String) { } val imageQualityPrefEntries: Array = when (lang) { - CHINESE, SIMPLIFIED_CHINESE -> arrayOf("原图+", "原图 (1600w)", "高 (1000w)", "低 (800w)") - else -> arrayOf("Raw+", "Raw (1600w)", "HD (1000w)", "SD (800w)") + CHINESE, SIMPLIFIED_CHINESE -> arrayOf("原图", "高清 (1600w)", "标清 (1000w)", "低清 (800w)") + else -> arrayOf("Raw", "HD (1600w)", "SD (1000w)", "Low (800w)") } val imageFormatPrefTitle: String = when (lang) { @@ -191,18 +185,27 @@ class BilibiliIntl(private val lang: String) { else -> "Total chapter count" } - val updatedEvery: String = when (lang) { - CHINESE, SIMPLIFIED_CHINESE -> "每周更新时间" - SPANISH -> "Actualizado en" - else -> "Updated every" + private val updatesDaily: String = when (lang) { + CHINESE, SIMPLIFIED_CHINESE -> "每日更新" + SPANISH -> "Actualizaciones diarias" + else -> "Updates daily" } - fun getWeekdays(dayIndexes: List): String { - val weekdays = dateFormatSymbols.weekdays - .filter(String::isNotBlank) - .map { dayName -> dayName.replaceFirstChar { it.uppercase(locale) } } + private fun updatesEvery(days: String): String = when (lang) { + CHINESE, SIMPLIFIED_CHINESE -> "${days}更新" + SPANISH -> "Actualizaciones todos los $days" + else -> "Updates every $days" + } - return dayIndexes.joinToString { weekdays[it] } + fun getUpdateDays(dayIndexes: List): String { + val shortWeekDays = dateFormatSymbols.shortWeekdays.filterNot(String::isBlank) + if (dayIndexes.size == shortWeekDays.size) return updatesDaily + val shortWeekDaysUpperCased = shortWeekDays.map { + it.replaceFirstChar { char -> char.uppercase(locale) } + } + + val days = dayIndexes.joinToString { shortWeekDaysUpperCased[it] } + return updatesEvery(days) } fun localize(value: Int) = value.localized diff --git a/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/bilibili/BilibiliUrlActivity.kt b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/bilibili/BilibiliUrlActivity.kt index eeb968411..88cde4983 100644 --- a/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/bilibili/BilibiliUrlActivity.kt +++ b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/bilibili/BilibiliUrlActivity.kt @@ -23,7 +23,8 @@ class BilibiliUrlActivity : Activity() { val pathSegments = intent?.data?.pathSegments if (pathSegments != null && pathSegments.size > 1) { - val titleId = if (pathSegments.size == 3) pathSegments[2] else pathSegments[1] + // Mobile site of https://manga.bilibili.com starts with path "m" + val titleId = if (pathSegments[0] == "m") pathSegments[2] else pathSegments[1] val mainIntent = Intent().apply { action = "eu.kanade.tachiyomi.SEARCH"