Bilibili Comics Add search from Api instead of scrapping (#7119)

* Update BilibiliComics.kt

* Update build.gradle

* Update BilibiliComics.kt
This commit is contained in:
FourTOne5 2021-05-24 16:12:39 +06:00 committed by GitHub
parent 3d0af119ce
commit 54a7cdb041
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 17 additions and 35 deletions

View File

@ -5,7 +5,7 @@ ext {
extName = 'Bilibili Comics' extName = 'Bilibili Comics'
pkgNameSuffix = 'en.bilibilicomics' pkgNameSuffix = 'en.bilibilicomics'
extClass = '.BilibiliComics' extClass = '.BilibiliComics'
extVersionCode = 1 extVersionCode = 2
libVersion = '1.2' libVersion = '1.2'
containsNsfw = true containsNsfw = true
} }

View File

@ -22,11 +22,13 @@ import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.HttpSource import eu.kanade.tachiyomi.source.online.HttpSource
import okhttp3.Headers import okhttp3.Headers
import okhttp3.HttpUrl.Companion.toHttpUrl
import okhttp3.MediaType.Companion.toMediaType import okhttp3.MediaType.Companion.toMediaType
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import okhttp3.RequestBody.Companion.toRequestBody import okhttp3.RequestBody.Companion.toRequestBody
import okhttp3.Response import okhttp3.Response
import org.jsoup.Jsoup
import rx.Observable import rx.Observable
import java.text.ParseException import java.text.ParseException
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
@ -48,8 +50,6 @@ class BilibiliComics : HttpSource() {
.addInterceptor(RateLimitInterceptor(1, 1, TimeUnit.SECONDS)) .addInterceptor(RateLimitInterceptor(1, 1, TimeUnit.SECONDS))
.build() .build()
private val comicList: MutableList<SManga> = mutableListOf()
override fun headersBuilder(): Headers.Builder = Headers.Builder() override fun headersBuilder(): Headers.Builder = Headers.Builder()
.add("Accept", ACCEPT_JSON) .add("Accept", ACCEPT_JSON)
.add("Origin", baseUrl) .add("Origin", baseUrl)
@ -95,71 +95,53 @@ class BilibiliComics : HttpSource() {
url = "/detail/mc" + obj["comic_id"].int url = "/detail/mc" + obj["comic_id"].int
} }
override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable<MangasPage> {
return if (comicList.isEmpty()) {
super.fetchSearchManga(page, query, filters)
.map { result ->
val filteredComics = result.mangas.filter { it.title.contains(query, true) }
MangasPage(filteredComics, result.hasNextPage)
}
} else {
val filteredComics = comicList.filter { it.title.contains(query, true) }
Observable.just(MangasPage(filteredComics, hasNextPage = false))
}
}
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
val jsonPayload = jsonObject( val jsonPayload = jsonObject(
"area_id" to -1, "area_id" to -1,
"is_finish" to -1, "is_finish" to -1,
"is_free" to 1, "is_free" to 1,
"key_word" to query,
"order" to 0, "order" to 0,
"page_num" to page, "page_num" to page,
"page_size" to 18, "page_size" to 9,
"style_id" to -1 "style_id" to -1
) )
val requestBody = jsonPayload.toString().toRequestBody(JSON_CONTENT_TYPE) val requestBody = jsonPayload.toString().toRequestBody(JSON_CONTENT_TYPE)
val refererUrl = "$baseUrl/search".toHttpUrl().newBuilder()
.addQueryParameter("keyword", query)
.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())
.add("X-Page", page.toString()) .add("X-Page", page.toString())
.set("Referer", "$baseUrl/genre") .set("Referer", refererUrl)
.build() .build()
return POST( return POST(
"$baseUrl/$BASE_API_ENDPOINT/ClassPage?device=pc&platform=web", "$baseUrl/$BASE_API_ENDPOINT/Search?device=pc&platform=web",
headers = newHeaders, headers = newHeaders,
body = requestBody body = requestBody
) )
} }
// Site does not have search in the API, so we need to fetch all the pages
// and then filter to find the query provided by the user.
override fun searchMangaParse(response: Response): MangasPage { override fun searchMangaParse(response: Response): MangasPage {
var request = response.request val jsonResponse = response.asJson().obj
var currentPage = request.headers["X-Page"]!!.toInt()
var jsonResponse = response.asJson().obj
if (jsonResponse["code"].int != 0) { if (jsonResponse["code"].int != 0) {
return MangasPage(emptyList(), hasNextPage = false) return MangasPage(emptyList(), hasNextPage = false)
} }
while (jsonResponse["data"].array.size() > 0) { val comicList = jsonResponse["data"]["list"].array
comicList += jsonResponse["data"].array .map(::searchMangaFromObject)
.map(::searchMangaFromObject)
request = searchMangaRequest(++currentPage, "", FilterList())
jsonResponse = client.newCall(request).execute().asJson().obj
}
return MangasPage(comicList, hasNextPage = false) return MangasPage(comicList, hasNextPage = false)
} }
private fun searchMangaFromObject(obj: JsonElement): SManga = SManga.create().apply { private fun searchMangaFromObject(obj: JsonElement): SManga = SManga.create().apply {
title = obj["title"].string title = Jsoup.parse(obj["title"].string).text()
thumbnail_url = obj["vertical_cover"].string thumbnail_url = obj["vertical_cover"].string
url = "/detail/mc" + obj["season_id"].int url = "/detail/mc" + obj["id"].int
} }
// Workaround to allow "Open in browser" use the real URL. // Workaround to allow "Open in browser" use the real URL.
@ -225,9 +207,9 @@ class BilibiliComics : HttpSource() {
} }
override fun pageListRequest(chapter: SChapter): Request { override fun pageListRequest(chapter: SChapter): Request {
val comicId = chapter.url.substringAfterLast("/").toInt() val chapterId = chapter.url.substringAfterLast("/").toInt()
val jsonPayload = jsonObject("ep_id" to comicId) val jsonPayload = jsonObject("ep_id" to chapterId)
val requestBody = jsonPayload.toString().toRequestBody(JSON_CONTENT_TYPE) val requestBody = jsonPayload.toString().toRequestBody(JSON_CONTENT_TYPE)
val newHeaders = headersBuilder() val newHeaders = headersBuilder()