Bilibili Comics Add search from Api instead of scrapping (#7119)
* Update BilibiliComics.kt * Update build.gradle * Update BilibiliComics.kt
This commit is contained in:
parent
3d0af119ce
commit
54a7cdb041
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()
|
||||||
|
|
Loading…
Reference in New Issue