Add more languages to Bilibili (#10494)

* Add more languages to Bilibili.

* Review some Indonesian strings.
This commit is contained in:
Alessandro Jean 2022-01-18 12:34:27 -03:00 committed by GitHub
parent f2fc5a98e1
commit 2e5a28d854
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 163 additions and 65 deletions

View File

@ -6,7 +6,7 @@ ext {
extName = 'BILIBILI'
pkgNameSuffix = 'all.bilibili'
extClass = '.BilibiliFactory'
extVersionCode = 3
extVersionCode = 4
}
dependencies {

View File

@ -2,7 +2,6 @@ package eu.kanade.tachiyomi.extension.all.bilibili
import android.app.Application
import android.content.SharedPreferences
import android.util.Log
import androidx.preference.ListPreference
import androidx.preference.PreferenceScreen
import eu.kanade.tachiyomi.lib.ratelimit.SpecificHostRateLimitInterceptor
@ -21,6 +20,7 @@ import kotlinx.serialization.json.Json
import kotlinx.serialization.json.buildJsonObject
import kotlinx.serialization.json.put
import okhttp3.Headers
import okhttp3.HttpUrl
import okhttp3.HttpUrl.Companion.toHttpUrl
import okhttp3.Interceptor
import okhttp3.MediaType.Companion.toMediaType
@ -39,7 +39,7 @@ import java.util.Locale
abstract class Bilibili(
override val name: String,
final override val baseUrl: String,
override val lang: String
final override val lang: String
) : HttpSource(), ConfigurableSource {
override val supportsLatest = true
@ -56,31 +56,70 @@ abstract class Bilibili(
.add("Origin", baseUrl)
.add("Referer", "$baseUrl/")
protected open val statusLabel: String = "Status"
private val apiLang: String = when (lang) {
"zh-Hans" -> "cn"
else -> lang
}
protected open val sortLabel: String = "Sort by"
protected open val statusLabel: String = when (lang) {
"zh", "zh-Hans" -> "进度"
else -> "Status"
}
protected open val genreLabel: String = "Genre"
protected open val sortLabel: String = when (lang) {
"zh", "zh-Hans" -> "排序"
"id" -> "Urutkan dengan"
else -> "Sort by"
}
protected open val areaLabel: String = "Area"
protected open val genreLabel: String = when (lang) {
"zh", "zh-Hans" -> "题材"
else -> "Genre"
}
protected open val priceLabel: String = "Price"
protected open val areaLabel: String = when (lang) {
"zh", "zh-Hans" -> "地区"
else -> "Area"
}
protected open val episodePrefix: String = "Ep. "
protected open val priceLabel: String = when (lang) {
"zh", "zh-Hans" -> "收费"
"id" -> "Harga"
else -> "Price"
}
protected open val episodePrefix: String = when (lang) {
"zh", "zh-Hans" -> ""
else -> "Ep. "
}
protected open val defaultPopularSort: Int = 1
protected open val defaultLatestSort: Int = 2
protected open val hasPaidChaptersWarning: String = "This series has paid chapters that " +
"were filtered out from the chapter list. Use the BILIBILI website or the official app " +
"to read them for now."
protected open val hasPaidChaptersWarning: String = when (lang) {
"zh", "zh-Hans" -> "此漫画的付费章节已从章节列表中过滤暂时请用网页端或官方app阅读。"
else ->
"This series has paid chapters that were filtered out from the chapter list. " +
"Use the BILIBILI website or the official app to read them for now."
}
protected open val imageQualityPrefTitle: String = "Chapter image quality"
protected open val imageQualityPrefTitle: String = when (lang) {
"zh", "zh-Hans" -> "章节图片质量"
"id" -> "Kualitas gambar"
else -> "Chapter image quality"
}
protected open val imageQualityPrefEntries: Array<String> = arrayOf("Raw", "HD", "SD")
protected open val imageQualityPrefEntries: Array<String> = when (lang) {
"zh", "zh-Hans" -> arrayOf("原图", "", "")
else -> arrayOf("Raw", "HD", "SD")
}
protected open val imageFormatPrefTitle: String = "Chapter image format"
protected open val imageFormatPrefTitle: String = when (lang) {
"zh", "zh-Hans" -> "章节图片格式"
"id" -> "Format gambar"
else -> "Chapter image format"
}
private val preferences: SharedPreferences by lazy {
Injekt.get<Application>().getSharedPreferences("source_$id", 0x0000)
@ -112,11 +151,13 @@ abstract class Bilibili(
.add("Content-Type", requestBody.contentType().toString())
.build()
return POST(
"$baseUrl/$BASE_API_ENDPOINT/ClassPage?device=pc&platform=web",
headers = newHeaders,
body = requestBody
)
val apiUrl = "$baseUrl/$BASE_API_ENDPOINT/ClassPage".toHttpUrl().newBuilder()
.addQueryParameter("device", "pc")
.addQueryParameter("platform", "web")
.addLanguageParameters()
.toString()
return POST(apiUrl, newHeaders, requestBody)
}
override fun popularMangaParse(response: Response): MangasPage {
@ -156,11 +197,13 @@ abstract class Bilibili(
.add("Content-Type", requestBody.contentType().toString())
.build()
return POST(
"$baseUrl/$BASE_API_ENDPOINT/ClassPage?device=pc&platform=web",
headers = newHeaders,
body = requestBody
)
val apiUrl = "$baseUrl/$BASE_API_ENDPOINT/ClassPage".toHttpUrl().newBuilder()
.addQueryParameter("device", "pc")
.addQueryParameter("platform", "web")
.addLanguageParameters()
.toString()
return POST(apiUrl, newHeaders, requestBody)
}
override fun latestUpdatesParse(response: Response): MangasPage {
@ -223,25 +266,26 @@ abstract class Bilibili(
}
}
val requestBody = jsonPayload.toString().toRequestBody(JSON_MEDIA_TYPE)
Log.d("Bilibili", jsonPayload.toString())
val refererUrl = if (query.isBlank()) "$baseUrl/genre" else
"$baseUrl/search".toHttpUrl().newBuilder()
.addQueryParameter("keyword", query)
.toString()
val newHeaders = headersBuilder()
.add("Content-Length", requestBody.contentLength().toString())
.add("Content-Type", requestBody.contentType().toString())
.set("Referer", refererUrl)
.build()
val apiPath = if (query.isBlank()) "ClassPage" else "Search"
val apiUrl = "$baseUrl/$BASE_API_ENDPOINT/".toHttpUrl().newBuilder()
.addPathSegment(if (query.isBlank()) "ClassPage" else "Search")
.addQueryParameter("device", "pc")
.addQueryParameter("platform", "web")
.addLanguageParameters()
.toString()
return POST(
"$baseUrl/$BASE_API_ENDPOINT/$apiPath?device=pc&platform=web",
headers = newHeaders,
body = requestBody
)
return POST(apiUrl, newHeaders, requestBody)
}
override fun searchMangaParse(response: Response): MangasPage {
@ -304,11 +348,13 @@ abstract class Bilibili(
.set("Referer", baseUrl + mangaUrl)
.build()
return POST(
"$baseUrl/$BASE_API_ENDPOINT/ComicDetail?device=pc&platform=web",
headers = newHeaders,
body = requestBody
)
val apiUrl = "$baseUrl/$BASE_API_ENDPOINT/ComicDetail".toHttpUrl().newBuilder()
.addQueryParameter("device", "pc")
.addQueryParameter("platform", "web")
.addLanguageParameters()
.toString()
return POST(apiUrl, newHeaders, requestBody)
}
override fun mangaDetailsParse(response: Response): SManga = SManga.create().apply {
@ -364,11 +410,13 @@ abstract class Bilibili(
.set("Referer", baseUrl + chapter.url)
.build()
return POST(
"$baseUrl/$BASE_API_ENDPOINT/GetImageIndex?device=pc&platform=web",
headers = newHeaders,
body = requestBody
)
val apiUrl = "$baseUrl/$BASE_API_ENDPOINT/GetImageIndex".toHttpUrl().newBuilder()
.addQueryParameter("device", "pc")
.addQueryParameter("platform", "web")
.addLanguageParameters()
.toString()
return POST(apiUrl, newHeaders, requestBody)
}
override fun pageListParse(response: Response): List<Page> {
@ -401,11 +449,13 @@ abstract class Bilibili(
.add("Content-Type", requestBody.contentType().toString())
.build()
return POST(
"$baseUrl/$BASE_API_ENDPOINT/ImageToken?device=pc&platform=web",
headers = newHeaders,
body = requestBody
)
val apiUrl = "$baseUrl/$BASE_API_ENDPOINT/ImageToken".toHttpUrl().newBuilder()
.addQueryParameter("device", "pc")
.addQueryParameter("platform", "web")
.addLanguageParameters()
.toString()
return POST(apiUrl, newHeaders, requestBody)
}
override fun imageUrlParse(response: Response): String = ""
@ -504,6 +554,15 @@ abstract class Bilibili(
return response
}
private fun HttpUrl.Builder.addLanguageParameters(): HttpUrl.Builder = let {
if (name == "BILIBILI COMICS") {
addQueryParameter("lang", apiLang)
addQueryParameter("sys_lang", apiLang)
}
return@let it
}
private inline fun <reified T> Response.parseAs(): BilibiliResultDto<T> = use {
json.decodeFromString(it.body?.string().orEmpty())
}

View File

@ -5,12 +5,17 @@ import eu.kanade.tachiyomi.source.SourceFactory
class BilibiliFactory : SourceFactory {
override fun createSources(): List<Source> = listOf(
BilibiliComics(),
BilibiliComicsEn(),
BilibiliComicsCn(),
BilibiliComicsId(),
BilibiliManga()
)
}
class BilibiliComics : Bilibili("BILIBILI COMICS", "https://www.bilibilicomics.com", "en") {
abstract class BilibiliComics(lang: String) :
Bilibili("BILIBILI COMICS", "https://www.bilibilicomics.com", lang)
class BilibiliComicsEn : BilibiliComics("en") {
override fun getAllGenres(): Array<BilibiliTag> = arrayOf(
BilibiliTag("All", -1),
@ -32,33 +37,67 @@ class BilibiliComics : Bilibili("BILIBILI COMICS", "https://www.bilibilicomics.c
)
}
class BilibiliManga : Bilibili("哔哩哔哩漫画", "https://manga.bilibili.com", "zh") {
class BilibiliComicsCn : BilibiliComics("zh-Hans") {
override val statusLabel: String = "进度"
override fun getAllSortOptions(): Array<String> = arrayOf("为你推荐", "人气推荐", "更新时间")
override val sortLabel: String = "排序"
override fun getAllStatus(): Array<String> = arrayOf("全部", "连载中", "已完结")
override val genreLabel: String = "题材"
override fun getAllPrices(): Array<String> = arrayOf("全部", "免费", "付费")
override val areaLabel: String = "地区"
override fun getAllGenres(): Array<BilibiliTag> = arrayOf(
BilibiliTag("全部", -1),
BilibiliTag("校园", 18),
BilibiliTag("都市", 9),
BilibiliTag("耽美", 3),
BilibiliTag("少女", 20),
BilibiliTag("恋爱", 13),
BilibiliTag("奇幻", 11),
BilibiliTag("热血", 19),
BilibiliTag("冒险", 22),
BilibiliTag("古风", 12),
BilibiliTag("百合", 16),
BilibiliTag("玄幻", 30),
BilibiliTag("悬疑", 41),
BilibiliTag("科幻", 8)
)
}
override val priceLabel: String = "收费"
class BilibiliComicsId : BilibiliComics("id") {
override val episodePrefix: String = ""
override fun getAllSortOptions(): Array<String> = arrayOf("Kamu Mungkin Suka", "Populer", "Terbaru")
override fun getAllStatus(): Array<String> = arrayOf("Semua", "Berlangsung", "Tamat")
override fun getAllPrices(): Array<String> = arrayOf("Semua", "Bebas", "Dibayar")
override fun getAllGenres(): Array<BilibiliTag> = arrayOf(
BilibiliTag("Semua", -1),
BilibiliTag("Aksi", 19),
BilibiliTag("Fantasi Timur", 30),
BilibiliTag("Fantasi", 11),
BilibiliTag("Historis", 12),
BilibiliTag("Horror", 23),
BilibiliTag("Kampus", 18),
BilibiliTag("Komedi", 14),
BilibiliTag("Menegangkan", 41),
BilibiliTag("Remaja", 20),
BilibiliTag("Romantis", 13)
)
}
class BilibiliManga : Bilibili(
"哔哩哔哩漫画",
"https://manga.bilibili.com",
"zh-Hans"
) {
override val id: Long = 3561131545129718586
override val defaultPopularSort: Int = 0
override val defaultLatestSort: Int = 1
override val hasPaidChaptersWarning: String = "此漫画的付费章节已从章节列表中过滤," +
"暂时请用网页端或官方app阅读。"
override val imageQualityPrefTitle: String = "章节图片质量"
override val imageQualityPrefEntries: Array<String> = arrayOf("原图", "", "")
override val imageFormatPrefTitle: String = "章节图片格式"
override fun getAllStatus(): Array<String> = arrayOf("全部", "连载", "完结")
override fun getAllSortOptions(): Array<String> = arrayOf("人气推荐", "更新时间", "追漫人数", "上架时间")