Flix: update api (#384)

* Flix multisrc: update api

* fix search
This commit is contained in:
AwkwardPeak7 2024-01-19 19:15:06 +05:00 committed by Draff
parent f45bc4cc4d
commit 1f1753d047
10 changed files with 37 additions and 43 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.0 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 17 KiB

View File

@ -1,5 +0,0 @@
package eu.kanade.tachiyomi.extension.en.flixscans
import eu.kanade.tachiyomi.multisrc.flixscans.FlixScans
class FlixScansNet : FlixScans("Flix Scans", "https://flixscans.org", "en", cdnUrl = "https://media.flixscans.org/")

View File

@ -1,13 +1,7 @@
package eu.kanade.tachiyomi.extension.ar.galaxymanga package eu.kanade.tachiyomi.extension.ar.galaxymanga
import eu.kanade.tachiyomi.multisrc.flixscans.FlixScans import eu.kanade.tachiyomi.multisrc.flixscans.FlixScans
import eu.kanade.tachiyomi.network.GET
import okhttp3.Request
class GalaxyManga : FlixScans("جالاكسي مانجا", "https://flixscans.com", "ar") { class GalaxyManga : FlixScans("جالاكسي مانجا", "https://flixscans.com", "ar") {
override val versionId = 2 override val versionId = 2
override fun popularMangaRequest(page: Int): Request {
return GET("$apiUrl/webtoon/pages/home/action", headers)
}
} }

View File

@ -1,7 +1,6 @@
package eu.kanade.tachiyomi.multisrc.flixscans package eu.kanade.tachiyomi.multisrc.flixscans
import android.util.Log import android.util.Log
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.POST import eu.kanade.tachiyomi.network.POST
import eu.kanade.tachiyomi.network.interceptor.rateLimit import eu.kanade.tachiyomi.network.interceptor.rateLimit
import eu.kanade.tachiyomi.source.model.Filter import eu.kanade.tachiyomi.source.model.Filter
@ -16,7 +15,6 @@ import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import okhttp3.Call import okhttp3.Call
import okhttp3.Callback import okhttp3.Callback
import okhttp3.HttpUrl.Companion.toHttpUrl
import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.Request import okhttp3.Request
import okhttp3.RequestBody.Companion.toRequestBody import okhttp3.RequestBody.Companion.toRequestBody
@ -28,8 +26,8 @@ abstract class FlixScans(
override val name: String, override val name: String,
override val baseUrl: String, override val baseUrl: String,
override val lang: String, override val lang: String,
protected val apiUrl: String = baseUrl.replace("://", "://api.").plus("/api/v1"), protected val apiUrl: String = "$baseUrl/api/__api_party/noxApi",
protected val cdnUrl: String = baseUrl.replace("://", "://api.").plus("/storage/"), protected val cdnUrl: String = baseUrl.replace("://", "://media.").plus("/"),
) : HttpSource() { ) : HttpSource() {
override val supportsLatest = true override val supportsLatest = true
@ -43,6 +41,12 @@ abstract class FlixScans(
override fun headersBuilder() = super.headersBuilder() override fun headersBuilder() = super.headersBuilder()
.add("Referer", baseUrl) .add("Referer", baseUrl)
protected open fun postPath(path: String): Request {
val payload = """{"path":"$path","headers":{}}""".toRequestBody(JSON_MEDIA_TYPE)
return POST(apiUrl, headers, payload)
}
override fun fetchPopularManga(page: Int): Observable<MangasPage> { override fun fetchPopularManga(page: Int): Observable<MangasPage> {
runCatching { fetchGenre() } runCatching { fetchGenre() }
@ -50,7 +54,7 @@ abstract class FlixScans(
} }
override fun popularMangaRequest(page: Int): Request { override fun popularMangaRequest(page: Int): Request {
return GET("$apiUrl/webtoon/homepage/home", headers) return postPath("webtoon/pages/home/romance")
} }
override fun popularMangaParse(response: Response): MangasPage { override fun popularMangaParse(response: Response): MangasPage {
@ -70,16 +74,14 @@ abstract class FlixScans(
} }
override fun latestUpdatesRequest(page: Int): Request { override fun latestUpdatesRequest(page: Int): Request {
return GET("$apiUrl/search/advance?page=$page&serie_type=webtoon", headers) return postPath("search/advance?page=$page&serie_type=webtoon")
} }
override fun latestUpdatesParse(response: Response): MangasPage { override fun latestUpdatesParse(response: Response): MangasPage {
val result = response.parseAs<ApiResponse<BrowseSeries>>() val result = response.parseAs<ApiResponse<BrowseSeries>>()
val currentPage = response.request.url.queryParameter("page")
?.toIntOrNull() ?: 1
val entries = result.data.map { it.toSManga(cdnUrl) } val entries = result.data.map { it.toSManga(cdnUrl) }
val hasNextPage = result.meta.lastPage > currentPage val hasNextPage = result.meta.lastPage > result.meta.currentPage
return MangasPage(entries, hasNextPage) return MangasPage(entries, hasNextPage)
} }
@ -131,7 +133,7 @@ abstract class FlixScans(
} }
private fun fetchGenreRequest(): Request { private fun fetchGenreRequest(): Request {
return GET("$apiUrl/search/genres", headers) return postPath("search/genres")
} }
private fun fetchGenreParse(response: Response): List<GenreHolder> { private fun fetchGenreParse(response: Response): List<GenreHolder> {
@ -168,53 +170,55 @@ abstract class FlixScans(
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
if (query.isNotEmpty()) { if (query.isNotEmpty()) {
val requestBody = SearchInput(query.trim()) val searchBody = SearchInput(query.trim())
.let(json::encodeToString) .let(json::encodeToString)
.toRequestBody(JSON_MEDIA_TYPE) .replace("\"", "\\\"")
val newHeaders = headersBuilder() val requestBody = """{
.add("Content-Length", requestBody.contentLength().toString()) |"path":"search/serie?page=$page",
.add("Content-Type", requestBody.contentType().toString()) |"headers":{"Content-type":"application/json"},
.build() |"method":"POST","body":"$searchBody"
|}
""".trimMargin().toRequestBody(JSON_MEDIA_TYPE)
return POST("$apiUrl/search/serie?page=$page", newHeaders, requestBody) return POST(apiUrl, headers, requestBody)
} }
val advSearchUrl = apiUrl.toHttpUrl().newBuilder().apply { val advSearchBody = buildString {
addPathSegments("search/advance") append("search/advance")
addQueryParameter("page", page.toString()) append("?page=", page)
addQueryParameter("serie_type", "webtoon") append("&serie_type=webtoon")
filters.forEach { filter -> filters.forEach { filter ->
when (filter) { when (filter) {
is GenreFilter -> { is GenreFilter -> {
filter.checked.let { filter.checked.let {
if (it.isNotEmpty()) { if (it.isNotEmpty()) {
addQueryParameter("genres", it.joinToString(",")) append("&genres=", it.joinToString(","))
} }
} }
} }
is MainGenreFilter -> { is MainGenreFilter -> {
if (filter.state > 0) { if (filter.state > 0) {
addQueryParameter("main_genres", filter.selected) append("&main_genres=", filter.selected)
} }
} }
is TypeFilter -> { is TypeFilter -> {
if (filter.state > 0) { if (filter.state > 0) {
addQueryParameter("type", filter.selected) append("&type=", filter.selected)
} }
} }
is StatusFilter -> { is StatusFilter -> {
if (filter.state > 0) { if (filter.state > 0) {
addQueryParameter("status", filter.selected) append("&status=", filter.selected)
} }
} }
else -> {} else -> {}
} }
} }
}.build() }
return GET(advSearchUrl, headers) return postPath(advSearchBody)
} }
override fun searchMangaParse(response: Response) = latestUpdatesParse(response) override fun searchMangaParse(response: Response) = latestUpdatesParse(response)
@ -222,7 +226,7 @@ abstract class FlixScans(
override fun mangaDetailsRequest(manga: SManga): Request { override fun mangaDetailsRequest(manga: SManga): Request {
val id = manga.url.split("-")[1] val id = manga.url.split("-")[1]
return GET("$apiUrl/webtoon/series/$id", headers) return postPath("webtoon/series/$id")
} }
override fun getMangaUrl(manga: SManga) = baseUrl + manga.url override fun getMangaUrl(manga: SManga) = baseUrl + manga.url
@ -236,7 +240,7 @@ abstract class FlixScans(
override fun chapterListRequest(manga: SManga): Request { override fun chapterListRequest(manga: SManga): Request {
val id = manga.url.split("-")[1] val id = manga.url.split("-")[1]
return GET("$apiUrl/webtoon/chapters/$id-desc", headers) return postPath("webtoon/chapters/$id-desc")
} }
override fun chapterListParse(response: Response): List<SChapter> { override fun chapterListParse(response: Response): List<SChapter> {
@ -250,7 +254,7 @@ abstract class FlixScans(
.substringAfterLast("/") .substringAfterLast("/")
.substringBefore("-") .substringBefore("-")
return GET("$apiUrl/webtoon/chapters/chapter/$id", headers) return postPath("webtoon/chapters/chapter/$id")
} }
override fun getChapterUrl(chapter: SChapter) = baseUrl + chapter.url override fun getChapterUrl(chapter: SChapter) = baseUrl + chapter.url
@ -269,6 +273,6 @@ abstract class FlixScans(
use { body.string() }.let(json::decodeFromString) use { body.string() }.let(json::decodeFromString)
companion object { companion object {
private val JSON_MEDIA_TYPE = "application/json; charset=utf-8".toMediaTypeOrNull() private val JSON_MEDIA_TYPE = "application/json".toMediaTypeOrNull()
} }
} }

View File

@ -17,6 +17,7 @@ data class ApiResponse<T>(
@Serializable @Serializable
data class PageInfo( data class PageInfo(
@SerialName("last_page") val lastPage: Int, @SerialName("last_page") val lastPage: Int,
@SerialName("current_page") val currentPage: Int,
) )
@Serializable @Serializable

View File

@ -9,7 +9,7 @@ class FlixScansGenerator : ThemeSourceGenerator {
override val themeClass = "FlixScans" override val themeClass = "FlixScans"
override val baseVersionCode: Int = 3 override val baseVersionCode: Int = 4
override val sources = listOf( override val sources = listOf(
SingleLang("Flix Scans", "https://flixscans.org", "en", className = "FlixScansNet", pkgName = "flixscans"), SingleLang("Flix Scans", "https://flixscans.org", "en", className = "FlixScansNet", pkgName = "flixscans"),