Add more languages to Bilibili (#10494)
* Add more languages to Bilibili. * Review some Indonesian strings.
This commit is contained in:
		
							parent
							
								
									f2fc5a98e1
								
							
						
					
					
						commit
						2e5a28d854
					
				| @ -6,7 +6,7 @@ ext { | |||||||
|     extName = 'BILIBILI' |     extName = 'BILIBILI' | ||||||
|     pkgNameSuffix = 'all.bilibili' |     pkgNameSuffix = 'all.bilibili' | ||||||
|     extClass = '.BilibiliFactory' |     extClass = '.BilibiliFactory' | ||||||
|     extVersionCode = 3 |     extVersionCode = 4 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| dependencies { | dependencies { | ||||||
|  | |||||||
| @ -2,7 +2,6 @@ package eu.kanade.tachiyomi.extension.all.bilibili | |||||||
| 
 | 
 | ||||||
| import android.app.Application | import android.app.Application | ||||||
| import android.content.SharedPreferences | import android.content.SharedPreferences | ||||||
| import android.util.Log |  | ||||||
| import androidx.preference.ListPreference | import androidx.preference.ListPreference | ||||||
| import androidx.preference.PreferenceScreen | import androidx.preference.PreferenceScreen | ||||||
| import eu.kanade.tachiyomi.lib.ratelimit.SpecificHostRateLimitInterceptor | 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.buildJsonObject | ||||||
| import kotlinx.serialization.json.put | import kotlinx.serialization.json.put | ||||||
| import okhttp3.Headers | import okhttp3.Headers | ||||||
|  | import okhttp3.HttpUrl | ||||||
| import okhttp3.HttpUrl.Companion.toHttpUrl | import okhttp3.HttpUrl.Companion.toHttpUrl | ||||||
| import okhttp3.Interceptor | import okhttp3.Interceptor | ||||||
| import okhttp3.MediaType.Companion.toMediaType | import okhttp3.MediaType.Companion.toMediaType | ||||||
| @ -39,7 +39,7 @@ import java.util.Locale | |||||||
| abstract class Bilibili( | abstract class Bilibili( | ||||||
|     override val name: String, |     override val name: String, | ||||||
|     final override val baseUrl: String, |     final override val baseUrl: String, | ||||||
|     override val lang: String |     final override val lang: String | ||||||
| ) : HttpSource(), ConfigurableSource { | ) : HttpSource(), ConfigurableSource { | ||||||
| 
 | 
 | ||||||
|     override val supportsLatest = true |     override val supportsLatest = true | ||||||
| @ -56,31 +56,70 @@ abstract class Bilibili( | |||||||
|         .add("Origin", baseUrl) |         .add("Origin", baseUrl) | ||||||
|         .add("Referer", "$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 defaultPopularSort: Int = 1 | ||||||
| 
 | 
 | ||||||
|     protected open val defaultLatestSort: Int = 2 |     protected open val defaultLatestSort: Int = 2 | ||||||
| 
 | 
 | ||||||
|     protected open val hasPaidChaptersWarning: String = "This series has paid chapters that " + |     protected open val hasPaidChaptersWarning: String = when (lang) { | ||||||
|         "were filtered out from the chapter list. Use the BILIBILI website or the official app " + |         "zh", "zh-Hans" -> "此漫画的付费章节已从章节列表中过滤,暂时请用网页端或官方app阅读。" | ||||||
|         "to read them for now." |         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 { |     private val preferences: SharedPreferences by lazy { | ||||||
|         Injekt.get<Application>().getSharedPreferences("source_$id", 0x0000) |         Injekt.get<Application>().getSharedPreferences("source_$id", 0x0000) | ||||||
| @ -112,11 +151,13 @@ abstract class Bilibili( | |||||||
|             .add("Content-Type", requestBody.contentType().toString()) |             .add("Content-Type", requestBody.contentType().toString()) | ||||||
|             .build() |             .build() | ||||||
| 
 | 
 | ||||||
|         return POST( |         val apiUrl = "$baseUrl/$BASE_API_ENDPOINT/ClassPage".toHttpUrl().newBuilder() | ||||||
|             "$baseUrl/$BASE_API_ENDPOINT/ClassPage?device=pc&platform=web", |             .addQueryParameter("device", "pc") | ||||||
|             headers = newHeaders, |             .addQueryParameter("platform", "web") | ||||||
|             body = requestBody |             .addLanguageParameters() | ||||||
|         ) |             .toString() | ||||||
|  | 
 | ||||||
|  |         return POST(apiUrl, newHeaders, requestBody) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun popularMangaParse(response: Response): MangasPage { |     override fun popularMangaParse(response: Response): MangasPage { | ||||||
| @ -156,11 +197,13 @@ abstract class Bilibili( | |||||||
|             .add("Content-Type", requestBody.contentType().toString()) |             .add("Content-Type", requestBody.contentType().toString()) | ||||||
|             .build() |             .build() | ||||||
| 
 | 
 | ||||||
|         return POST( |         val apiUrl = "$baseUrl/$BASE_API_ENDPOINT/ClassPage".toHttpUrl().newBuilder() | ||||||
|             "$baseUrl/$BASE_API_ENDPOINT/ClassPage?device=pc&platform=web", |             .addQueryParameter("device", "pc") | ||||||
|             headers = newHeaders, |             .addQueryParameter("platform", "web") | ||||||
|             body = requestBody |             .addLanguageParameters() | ||||||
|         ) |             .toString() | ||||||
|  | 
 | ||||||
|  |         return POST(apiUrl, newHeaders, requestBody) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun latestUpdatesParse(response: Response): MangasPage { |     override fun latestUpdatesParse(response: Response): MangasPage { | ||||||
| @ -223,25 +266,26 @@ abstract class Bilibili( | |||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         val requestBody = jsonPayload.toString().toRequestBody(JSON_MEDIA_TYPE) |         val requestBody = jsonPayload.toString().toRequestBody(JSON_MEDIA_TYPE) | ||||||
|         Log.d("Bilibili", jsonPayload.toString()) |  | ||||||
| 
 | 
 | ||||||
|         val refererUrl = if (query.isBlank()) "$baseUrl/genre" else |         val refererUrl = if (query.isBlank()) "$baseUrl/genre" else | ||||||
|             "$baseUrl/search".toHttpUrl().newBuilder() |             "$baseUrl/search".toHttpUrl().newBuilder() | ||||||
|                 .addQueryParameter("keyword", query) |                 .addQueryParameter("keyword", query) | ||||||
|                 .toString() |                 .toString() | ||||||
|  | 
 | ||||||
|         val newHeaders = headersBuilder() |         val newHeaders = headersBuilder() | ||||||
|             .add("Content-Length", requestBody.contentLength().toString()) |             .add("Content-Length", requestBody.contentLength().toString()) | ||||||
|             .add("Content-Type", requestBody.contentType().toString()) |             .add("Content-Type", requestBody.contentType().toString()) | ||||||
|             .set("Referer", refererUrl) |             .set("Referer", refererUrl) | ||||||
|             .build() |             .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( |         return POST(apiUrl, newHeaders, requestBody) | ||||||
|             "$baseUrl/$BASE_API_ENDPOINT/$apiPath?device=pc&platform=web", |  | ||||||
|             headers = newHeaders, |  | ||||||
|             body = requestBody |  | ||||||
|         ) |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun searchMangaParse(response: Response): MangasPage { |     override fun searchMangaParse(response: Response): MangasPage { | ||||||
| @ -304,11 +348,13 @@ abstract class Bilibili( | |||||||
|             .set("Referer", baseUrl + mangaUrl) |             .set("Referer", baseUrl + mangaUrl) | ||||||
|             .build() |             .build() | ||||||
| 
 | 
 | ||||||
|         return POST( |         val apiUrl = "$baseUrl/$BASE_API_ENDPOINT/ComicDetail".toHttpUrl().newBuilder() | ||||||
|             "$baseUrl/$BASE_API_ENDPOINT/ComicDetail?device=pc&platform=web", |             .addQueryParameter("device", "pc") | ||||||
|             headers = newHeaders, |             .addQueryParameter("platform", "web") | ||||||
|             body = requestBody |             .addLanguageParameters() | ||||||
|         ) |             .toString() | ||||||
|  | 
 | ||||||
|  |         return POST(apiUrl, newHeaders, requestBody) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun mangaDetailsParse(response: Response): SManga = SManga.create().apply { |     override fun mangaDetailsParse(response: Response): SManga = SManga.create().apply { | ||||||
| @ -364,11 +410,13 @@ abstract class Bilibili( | |||||||
|             .set("Referer", baseUrl + chapter.url) |             .set("Referer", baseUrl + chapter.url) | ||||||
|             .build() |             .build() | ||||||
| 
 | 
 | ||||||
|         return POST( |         val apiUrl = "$baseUrl/$BASE_API_ENDPOINT/GetImageIndex".toHttpUrl().newBuilder() | ||||||
|             "$baseUrl/$BASE_API_ENDPOINT/GetImageIndex?device=pc&platform=web", |             .addQueryParameter("device", "pc") | ||||||
|             headers = newHeaders, |             .addQueryParameter("platform", "web") | ||||||
|             body = requestBody |             .addLanguageParameters() | ||||||
|         ) |             .toString() | ||||||
|  | 
 | ||||||
|  |         return POST(apiUrl, newHeaders, requestBody) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun pageListParse(response: Response): List<Page> { |     override fun pageListParse(response: Response): List<Page> { | ||||||
| @ -401,11 +449,13 @@ abstract class Bilibili( | |||||||
|             .add("Content-Type", requestBody.contentType().toString()) |             .add("Content-Type", requestBody.contentType().toString()) | ||||||
|             .build() |             .build() | ||||||
| 
 | 
 | ||||||
|         return POST( |         val apiUrl = "$baseUrl/$BASE_API_ENDPOINT/ImageToken".toHttpUrl().newBuilder() | ||||||
|             "$baseUrl/$BASE_API_ENDPOINT/ImageToken?device=pc&platform=web", |             .addQueryParameter("device", "pc") | ||||||
|             headers = newHeaders, |             .addQueryParameter("platform", "web") | ||||||
|             body = requestBody |             .addLanguageParameters() | ||||||
|         ) |             .toString() | ||||||
|  | 
 | ||||||
|  |         return POST(apiUrl, newHeaders, requestBody) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun imageUrlParse(response: Response): String = "" |     override fun imageUrlParse(response: Response): String = "" | ||||||
| @ -504,6 +554,15 @@ abstract class Bilibili( | |||||||
|         return response |         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 { |     private inline fun <reified T> Response.parseAs(): BilibiliResultDto<T> = use { | ||||||
|         json.decodeFromString(it.body?.string().orEmpty()) |         json.decodeFromString(it.body?.string().orEmpty()) | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -5,12 +5,17 @@ import eu.kanade.tachiyomi.source.SourceFactory | |||||||
| 
 | 
 | ||||||
| class BilibiliFactory : SourceFactory { | class BilibiliFactory : SourceFactory { | ||||||
|     override fun createSources(): List<Source> = listOf( |     override fun createSources(): List<Source> = listOf( | ||||||
|         BilibiliComics(), |         BilibiliComicsEn(), | ||||||
|  |         BilibiliComicsCn(), | ||||||
|  |         BilibiliComicsId(), | ||||||
|         BilibiliManga() |         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( |     override fun getAllGenres(): Array<BilibiliTag> = arrayOf( | ||||||
|         BilibiliTag("All", -1), |         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 defaultPopularSort: Int = 0 | ||||||
| 
 | 
 | ||||||
|     override val defaultLatestSort: Int = 1 |     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 getAllStatus(): Array<String> = arrayOf("全部", "连载", "完结") | ||||||
| 
 | 
 | ||||||
|     override fun getAllSortOptions(): Array<String> = arrayOf("人气推荐", "更新时间", "追漫人数", "上架时间") |     override fun getAllSortOptions(): Array<String> = arrayOf("人气推荐", "更新时间", "追漫人数", "上架时间") | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Alessandro Jean
						Alessandro Jean