Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SussyToons: Fix thumbnail, loading pages and update domain #7461

Merged
merged 2 commits into from
Feb 2, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/pt/sussyscan/build.gradle
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
ext {
extName = 'Sussy Toons'
extClass = '.SussyToons'
extVersionCode = 49
extVersionCode = 50
isNsfw = true
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,17 @@ import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.HttpSource
import eu.kanade.tachiyomi.util.asJsoup
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.decodeFromStream
import okhttp3.HttpUrl.Companion.toHttpUrl
import okhttp3.Interceptor
import okhttp3.Request
import okhttp3.Response
import org.jsoup.Jsoup
import org.jsoup.nodes.Document
import org.jsoup.nodes.Element
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import uy.kohesive.injekt.injectLazy
Expand Down Expand Up @@ -61,7 +65,7 @@ class SussyToons : HttpSource(), ConfigurableSource {
else -> preferences.getString(BASE_URL_PREF, defaultBaseUrl)!!
}

private val defaultBaseUrl: String = "https://www.sussytoons.site"
private val defaultBaseUrl: String = "https://www.sussytoons.wtf"
private val defaultApiUrl: String = "https://api-dev.sussytoons.site"

override val client = network.cloudflareClient.newBuilder()
Expand Down Expand Up @@ -144,7 +148,6 @@ class SussyToons : HttpSource(), ConfigurableSource {
override fun mangaDetailsRequest(manga: SManga): Request {
val url = "$apiUrl/obras".toHttpUrl().newBuilder()
.addPathSegment(manga.id)
.fragment("$mangaPagePrefix${getMangaUrl(manga)}")
.build()
return GET(url, headers)
}
Expand Down Expand Up @@ -178,14 +181,17 @@ class SussyToons : HttpSource(), ConfigurableSource {

// ============================= Pages ====================================

override fun pageListRequest(chapter: SChapter): Request {
val request = super.pageListRequest(chapter)
val chapterPageId = request.url.pathSegments.last()
return GET("$apiUrl/capitulos/$chapterPageId", headers)
}
private val pageUrlSelector = "img.chakra-image"

override fun pageListParse(response: Response): List<Page> {
val dto = response.parseAs<WrapperDto<ChapterPageDto>>().results
val document = response.asJsoup()

pageListParse(document).takeIf(List<Page>::isNotEmpty)?.let { return it }

val dto = extractScriptData(document)
.let(::extractJsonContent)
.let(::parseJsonToChapterPageDto)

return dto.pages.mapIndexed { index, image ->
val imageUrl = when {
image.isWordPressContent() -> {
Expand All @@ -202,6 +208,31 @@ class SussyToons : HttpSource(), ConfigurableSource {
Page(index, imageUrl = imageUrl.toString())
}
}
private fun pageListParse(document: Document): List<Page> {
return document.select(pageUrlSelector).mapIndexed { index, element ->
Page(index, document.location(), element.absUrl("src"))
}
}
private fun extractScriptData(document: Document): String {
return document.select("script").map(Element::data)
.firstOrNull(pageRegex::containsMatchIn)
?: throw Exception("Failed to load pages: Script data not found")
}

private fun extractJsonContent(scriptData: String): String {
return pageRegex.find(scriptData)
?.groups?.get(1)?.value
?.let { json.decodeFromString<String>("\"$it\"") }
?: throw Exception("Failed to extract JSON from script")
}

private fun parseJsonToChapterPageDto(jsonContent: String): ChapterPageDto {
return try {
jsonContent.parseAs<WrapperDto<ChapterPageDto>>().results
} catch (e: Exception) {
throw Exception("Failed to load pages: ${e.message}")
}
}

override fun imageUrlParse(response: Response): String = ""

Expand Down Expand Up @@ -290,7 +321,12 @@ class SussyToons : HttpSource(), ConfigurableSource {
private fun MangaDto.toSManga(): SManga {
val sManga = SManga.create().apply {
title = name
thumbnail_url = thumbnail
thumbnail_url = thumbnail?.let {
when {
it.startsWith("http") -> thumbnail
else -> "$OLDI_URL/scans/$scanId/obras/${[email protected]}/$thumbnail"
}
}
initialized = true
val mangaUrl = "$baseUrl/obra".toHttpUrl().newBuilder()
.addPathSegment([email protected]())
Expand All @@ -309,6 +345,10 @@ class SussyToons : HttpSource(), ConfigurableSource {
return json.decodeFromStream(body.byteStream())
}

private inline fun <reified T> String.parseAs(): T {
return json.decodeFromString(this)
}

private fun String.toDate() =
try { dateFormat.parse(this)!!.time } catch (_: Exception) { 0L }

Expand All @@ -324,7 +364,8 @@ class SussyToons : HttpSource(), ConfigurableSource {
companion object {
const val CDN_URL = "https://cdn.sussytoons.site"
const val OLDI_URL = "https://oldi.sussytoons.site"
const val mangaPagePrefix = "mangaPage:"

val pageRegex = """capituloInicial.{3}(.*?)(\}\]\})""".toRegex()

private const val URL_PREF_SUMMARY = "Para uso temporário, se a extensão for atualizada, a alteração será perdida."

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ class MangaDto(
val slug: String?,
@SerialName("status")
val status: MangaStatus,
@SerialName("scan_id")
val scanId: Int,
) {
@Serializable
class MangaStatus(
Expand Down
Loading