[LibSocial] Fixes

master
Koitharu 11 months ago
parent f066be47fe
commit 5856681753
Signed by: Koitharu
GPG Key ID: 676DEE768C17A9D7

@ -3,12 +3,15 @@ package org.koitharu.kotatsu.parsers.site.ru.rulib
import androidx.collection.*
import kotlinx.coroutines.async
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.runBlocking
import okhttp3.HttpUrl
import org.json.JSONArray
import org.json.JSONObject
import org.koitharu.kotatsu.parsers.MangaLoaderContext
import org.koitharu.kotatsu.parsers.MangaParserAuthProvider
import org.koitharu.kotatsu.parsers.config.ConfigKey
import org.koitharu.kotatsu.parsers.core.LegacyPagedMangaParser
import org.koitharu.kotatsu.parsers.exception.AuthRequiredException
import org.koitharu.kotatsu.parsers.model.*
import org.koitharu.kotatsu.parsers.util.*
import org.koitharu.kotatsu.parsers.util.json.*
@ -19,9 +22,24 @@ import java.util.*
internal abstract class LibSocialParser(
context: MangaLoaderContext,
source: MangaParserSource,
protected val siteDomain: String,
siteDomain: String,
protected val siteId: Int,
) : LegacyPagedMangaParser(context, source, pageSize = 60) {
) : LegacyPagedMangaParser(context, source, pageSize = 60), MangaParserAuthProvider {
protected val apiHost = "api.cdnlibs.org"
override val authUrl: String
get() = "https://$domain/ru/front/auth"
override val isAuthorized: Boolean
get() = runBlocking {
runCatchingCancellable { getAuthData() }.getOrNull() != null
}
override suspend fun getUsername(): String = getAuthData()
?.getJSONObject("auth")
?.getString("username")
?: throw AuthRequiredException(source)
override val availableSortOrders: Set<SortOrder> = EnumSet.of(
SortOrder.UPDATED,
@ -70,8 +88,8 @@ internal abstract class LibSocialParser(
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val urlBuilder = HttpUrl.Builder()
.scheme("https")
.host("api.lib.social")
.scheme(SCHEME_HTTPS)
.host(apiHost)
.addPathSegment("api")
.addPathSegment("manga")
.addQueryParameter("site_id[]", siteId.toString())
@ -126,8 +144,8 @@ internal abstract class LibSocialParser(
override suspend fun getDetails(manga: Manga): Manga = coroutineScope {
val chapters = async { fetchChapters(manga) }
val url = HttpUrl.Builder()
.scheme("https")
.host("api.lib.social")
.scheme(SCHEME_HTTPS)
.host(apiHost)
.addPathSegment("api")
.addPathSegment("manga")
.addPathSegment(manga.url)
@ -157,7 +175,7 @@ internal abstract class LibSocialParser(
override suspend fun getPages(chapter: MangaChapter): List<MangaPage> = coroutineScope {
val pages = async {
webClient.httpGet(
concatUrl("https://api.lib.social/api/manga/", chapter.url),
concatUrl("https://$apiHost/api/manga/", chapter.url),
).parseJson().getJSONObject("data")
}
val servers = imageServers.get()
@ -183,8 +201,8 @@ internal abstract class LibSocialParser(
override suspend fun getRelatedManga(seed: Manga): List<Manga> {
val json = webClient.httpGet(
HttpUrl.Builder()
.scheme("https")
.host("api.lib.social")
.scheme(SCHEME_HTTPS)
.host(apiHost)
.addPathSegment("api")
.addPathSegment("manga")
.addPathSegment(seed.url)
@ -196,6 +214,10 @@ internal abstract class LibSocialParser(
}
}
override suspend fun resolveLink(resolver: LinkResolver, link: HttpUrl): Manga? {
return resolver.resolveManga(this, link.pathSegments.lastOrNull() ?: return null)
}
override fun onCreateConfig(keys: MutableCollection<ConfigKey<*>>) {
super.onCreateConfig(keys)
keys.remove(configKeyDomain)
@ -211,7 +233,7 @@ internal abstract class LibSocialParser(
title = jo.getString("rus_name").ifEmpty { jo.getString("name") },
altTitles = setOfNotNull(jo.getString("name")),
url = jo.getString("slug_url"),
publicUrl = "https://$siteDomain/ru/manga/" + jo.getString("slug_url"),
publicUrl = "https://$domain/ru/manga/" + jo.getString("slug_url"),
rating = jo.optJSONObject("rating")
?.getFloatOrDefault("average", RATING_UNKNOWN * 10f)?.div(10f) ?: RATING_UNKNOWN,
contentRating = if (isNsfwSource) ContentRating.ADULT else null,
@ -236,8 +258,8 @@ internal abstract class LibSocialParser(
private suspend fun fetchChapters(manga: Manga): List<MangaChapter> {
val url = HttpUrl.Builder()
.scheme("https")
.host("api.lib.social")
.scheme(SCHEME_HTTPS)
.host(apiHost)
.addPathSegment("api")
.addPathSegment("manga")
.addPathSegment(manga.url)
@ -280,8 +302,8 @@ internal abstract class LibSocialParser(
private suspend fun fetchTags(type: String): List<MangaTag> {
val data = webClient.httpGet(
HttpUrl.Builder()
.scheme("https")
.host("api.lib.social")
.scheme(SCHEME_HTTPS)
.host(apiHost)
.addPathSegment("api").addPathSegment(type).build(),
).parseJson().getJSONArray("data")
val prefix = type.first().toString()
@ -301,8 +323,8 @@ internal abstract class LibSocialParser(
private suspend fun fetchServers(): ScatterMap<String, String> {
val json = webClient.httpGet(
HttpUrl.Builder()
.scheme("https")
.host("api.lib.social")
.scheme(SCHEME_HTTPS)
.host(apiHost)
.addPathSegment("api")
.addPathSegment("constants")
.addQueryParameter("fields[]", "imageServers")
@ -351,6 +373,10 @@ internal abstract class LibSocialParser(
return result
}
private suspend fun getAuthData(): JSONObject? {
return JSONObject(WebViewHelper(context, domain).getLocalStorageValue("auth") ?: return null)
}
protected companion object {
const val SERVER_MAIN = "main"

@ -2,6 +2,10 @@ package org.koitharu.kotatsu.parsers.site.ru.rulib
import org.koitharu.kotatsu.parsers.MangaLoaderContext
import org.koitharu.kotatsu.parsers.MangaSourceParser
import org.koitharu.kotatsu.parsers.exception.AuthRequiredException
import org.koitharu.kotatsu.parsers.exception.NotFoundException
import org.koitharu.kotatsu.parsers.model.MangaChapter
import org.koitharu.kotatsu.parsers.model.MangaPage
import org.koitharu.kotatsu.parsers.model.MangaParserSource
@MangaSourceParser("MANGALIB", "MangaLib", "ru")
@ -11,5 +15,12 @@ internal class MangaLibParser(
context = context,
source = MangaParserSource.MANGALIB,
siteId = 1,
siteDomain = "test-front.mangalib.me",
)
siteDomain = "mangalib.me",
) {
override suspend fun getPages(chapter: MangaChapter): List<MangaPage> = try {
super.getPages(chapter)
} catch (e: NotFoundException) {
throw AuthRequiredException(source, e)
}
}

@ -9,5 +9,5 @@ internal class SlashLibParser(context: MangaLoaderContext) : LibSocialParser(
context = context,
source = MangaParserSource.YAOILIB,
siteId = 2,
siteDomain = "test-front.slashlib.me",
siteDomain = "v2.slashlib.me",
)

@ -30,6 +30,10 @@ public class FaviconParser(
links.mapNotNullTo(result) { link ->
parseLink(link)
}
val touchIcons = doc.getElementsByAttributeValue("rel", "apple-touch-icon")
touchIcons.mapNotNullTo(result) { link ->
parseLink(link)
}
if (result.isEmpty()) {
result.add(createFallback())
}

@ -0,0 +1,13 @@
package org.koitharu.kotatsu.parsers.util
import org.koitharu.kotatsu.parsers.MangaLoaderContext
public class WebViewHelper(
private val context: MangaLoaderContext,
private val domain: String,
) {
public suspend fun getLocalStorageValue(key: String): String? {
return context.evaluateJs("window.localStorage.getItem(\"$key\")")
}
}
Loading…
Cancel
Save