Drop fakeimg (#11743)

* xkcd: drop fakeimg

* smbc: drop fakeimg

* mehgazone: drop fakeimg

* swordscomic: drop fakeimg

* buttsmithy: drop fakeimg

* xkcd: better thumbnail

It's unclear what the original source for it is but it's all over the
web.

Link: https://libguides.davenportlibrary.com/comicsforallages/xkcd

* smbc, xkcd: implement fetchMangaDetails properly

* Update src/en/saturdaymorningbreakfastcomics/build.gradle

* Update src/all/xkcd/build.gradle

---------

Co-authored-by: Vetle Ledaal <vetle.ledaal@gmail.com>
This commit is contained in:
novenary 2025-11-22 00:25:48 +02:00 committed by Draff
parent 8bd7ed9a90
commit e17d796fc1
Signed by: Draff
GPG Key ID: E8A89F3211677653
15 changed files with 114 additions and 114 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

View File

@ -1,7 +1,11 @@
ext { ext {
extName = 'xkcd' extName = 'xkcd'
extClass = '.XkcdFactory' extClass = '.XkcdFactory'
extVersionCode = 14 extVersionCode = 15
} }
apply from: "$rootDir/common.gradle" apply from: "$rootDir/common.gradle"
dependencies {
implementation(project(':lib:textinterceptor'))
}

View File

@ -1,6 +1,7 @@
package eu.kanade.tachiyomi.extension.all.xkcd package eu.kanade.tachiyomi.extension.all.xkcd
import android.net.Uri.encode import eu.kanade.tachiyomi.lib.textinterceptor.TextInterceptor
import eu.kanade.tachiyomi.lib.textinterceptor.TextInterceptorHelper
import eu.kanade.tachiyomi.source.model.FilterList import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.MangasPage import eu.kanade.tachiyomi.source.model.MangasPage
import eu.kanade.tachiyomi.source.model.Page import eu.kanade.tachiyomi.source.model.Page
@ -8,7 +9,11 @@ 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 eu.kanade.tachiyomi.util.asJsoup import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.OkHttpClient
import okhttp3.Protocol
import okhttp3.Response import okhttp3.Response
import okhttp3.ResponseBody.Companion.toResponseBody
import rx.Observable import rx.Observable
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Locale import java.util.Locale
@ -21,6 +26,26 @@ open class Xkcd(
final override val name = "xkcd" final override val name = "xkcd"
final override val supportsLatest = false final override val supportsLatest = false
override val client: OkHttpClient = network.client.newBuilder()
.addInterceptor(TextInterceptor())
.addInterceptor { chain ->
val request = chain.request()
val url = request.url
if (url.host != "thumbnail") return@addInterceptor chain.proceed(request)
val image = this::class.java
.getResourceAsStream("/assets/thumbnail.png")!!
.readBytes()
val responseBody = image.toResponseBody("image/png".toMediaType())
Response.Builder()
.request(request)
.protocol(Protocol.HTTP_1_1)
.code(200)
.message("OK")
.body(responseBody)
.build()
}
.build()
protected open val archive = "/archive" protected open val archive = "/archive"
@ -32,8 +57,6 @@ open class Xkcd(
protected open val interactiveText = protected open val interactiveText =
"To experience the interactive version of this comic, open it in WebView/browser." "To experience the interactive version of this comic, open it in WebView/browser."
protected open val altTextUrl = LATIN_ALT_TEXT_URL
protected open val chapterListSelector = "#middleContainer > a" protected open val chapterListSelector = "#middleContainer > a"
protected open val imageSelector = "#comic > img" protected open val imageSelector = "#comic > img"
@ -42,45 +65,27 @@ open class Xkcd(
protected fun String.timestamp() = dateFormat.parse(this)?.time ?: 0L protected fun String.timestamp() = dateFormat.parse(this)?.time ?: 0L
protected fun String.image() = altTextUrl + "&text=" + encode(this)
protected open fun String.numbered(number: Any) = "$number - $this" protected open fun String.numbered(number: Any) = "$number - $this"
// TODO: maybe use BreakIterator private fun makeSManga(): SManga =
protected fun wordWrap(title: String, altText: String) = buildString {
title.split(' ').forEachIndexed { i, w ->
if (i != 0 && i % 7 == 0) append("\n")
append(w).append(' ')
}
append("\n\n")
var charCount = 0
altText.replace("\r\n", " ").split(' ').forEach { w ->
if (charCount > 25) {
append("\n")
charCount = 0
}
append(w).append(' ')
charCount += w.length + 1
}
}
final override fun fetchPopularManga(page: Int) =
SManga.create().apply { SManga.create().apply {
title = name title = name
artist = creator artist = creator
author = creator author = creator
description = synopsis description = synopsis
status = SManga.ONGOING status = SManga.ONGOING
thumbnail_url = THUMBNAIL_URL thumbnail_url = "https://thumbnail/xkcd.png"
setUrlWithoutDomain(archive) setUrlWithoutDomain(archive)
}.let { Observable.just(MangasPage(listOf(it), false))!! } }
final override fun fetchPopularManga(page: Int) =
Observable.just(MangasPage(listOf(makeSManga()), false))
final override fun fetchSearchManga(page: Int, query: String, filters: FilterList) = final override fun fetchSearchManga(page: Int, query: String, filters: FilterList) =
Observable.just(MangasPage(emptyList(), false))!! Observable.just(MangasPage(emptyList(), false))!!
final override fun fetchMangaDetails(manga: SManga) = final override fun fetchMangaDetails(manga: SManga) =
Observable.just(manga.apply { initialized = true })!! Observable.just(makeSManga())!!
override fun chapterListParse(response: Response) = override fun chapterListParse(response: Response) =
response.asJsoup().select(chapterListSelector).map { response.asJsoup().select(chapterListSelector).map {
@ -106,9 +111,9 @@ open class Xkcd(
} }
// create a text image for the alt text // create a text image for the alt text
val text = wordWrap(img.attr("alt"), img.attr("title")) val text = TextInterceptorHelper.createUrl(img.attr("alt"), img.attr("title"))
return listOf(Page(0, "", image), Page(1, "", text.image())) return listOf(Page(0, "", image), Page(1, "", text))
} }
final override fun imageUrlParse(response: Response) = final override fun imageUrlParse(response: Response) =
@ -134,16 +139,4 @@ open class Xkcd(
final override fun searchMangaRequest(page: Int, query: String, filters: FilterList) = final override fun searchMangaRequest(page: Int, query: String, filters: FilterList) =
throw UnsupportedOperationException() throw UnsupportedOperationException()
companion object {
private const val THUMBNAIL_URL =
"https://fakeimg.ryd.tools/550x780/ffffff/6e7b91/?font=museo&text=xkcd"
const val LATIN_ALT_TEXT_URL =
"https://fakeimg.ryd.tools/1500x2126/ffffff/000000/?font=museo&font_size=42"
const val CJK_ALT_TEXT_URL =
"https://placehold.jp/42/ffffff/000000/1500x2126.png?css=" +
"%7B%22padding%22%3A%22300px%22%2C%22text-align%22%3A%22left%22%7D"
}
} }

View File

@ -1,6 +1,7 @@
package eu.kanade.tachiyomi.extension.all.xkcd.translations package eu.kanade.tachiyomi.extension.all.xkcd.translations
import eu.kanade.tachiyomi.extension.all.xkcd.Xkcd import eu.kanade.tachiyomi.extension.all.xkcd.Xkcd
import eu.kanade.tachiyomi.lib.textinterceptor.TextInterceptorHelper
import eu.kanade.tachiyomi.source.model.Page import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.util.asJsoup import eu.kanade.tachiyomi.util.asJsoup
@ -36,9 +37,9 @@ class XkcdFR : Xkcd("https://xkcd.lapin.org", "fr") {
val img = it.child(2).child(0).child(0) val img = it.child(2).child(0).child(0)
// create a text image for the alt text // create a text image for the alt text
val text = wordWrap(it.child(0).text(), img.attr("alt")) val text = TextInterceptorHelper.createUrl(it.child(0).text(), img.attr("alt"))
listOf(Page(0, "", img.attr("abs:src")), Page(1, "", text.image())) listOf(Page(0, "", img.attr("abs:src")), Page(1, "", text))
} }
override val interactiveText: String override val interactiveText: String

View File

@ -1,6 +1,7 @@
package eu.kanade.tachiyomi.extension.all.xkcd.translations package eu.kanade.tachiyomi.extension.all.xkcd.translations
import eu.kanade.tachiyomi.extension.all.xkcd.Xkcd import eu.kanade.tachiyomi.extension.all.xkcd.Xkcd
import eu.kanade.tachiyomi.lib.textinterceptor.TextInterceptorHelper
import eu.kanade.tachiyomi.source.model.Page import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.util.asJsoup import eu.kanade.tachiyomi.util.asJsoup
@ -13,8 +14,6 @@ class XkcdRU : Xkcd("https://xkcd.ru", "ru") {
override val synopsis = "о романтике, сарказме, математике и языке" override val synopsis = "о романтике, сарказме, математике и языке"
override val altTextUrl = super.altTextUrl.replace("museo", "noto")
override val chapterListSelector = ".main > a" override val chapterListSelector = ".main > a"
override val imageSelector = ".main" override val imageSelector = ".main"
@ -38,9 +37,9 @@ class XkcdRU : Xkcd("https://xkcd.ru", "ru") {
val img = it.child(5).child(0) val img = it.child(5).child(0)
// create a text image for the alt text // create a text image for the alt text
val text = wordWrap(img.attr("alt"), it.child(7).text()) val text = TextInterceptorHelper.createUrl(img.attr("alt"), it.child(7).text())
listOf(Page(0, "", img.attr("abs:src")), Page(1, "", text.image())) listOf(Page(0, "", img.attr("abs:src")), Page(1, "", text))
} }
override val interactiveText: String override val interactiveText: String

View File

@ -1,6 +1,7 @@
package eu.kanade.tachiyomi.extension.all.xkcd.translations package eu.kanade.tachiyomi.extension.all.xkcd.translations
import eu.kanade.tachiyomi.extension.all.xkcd.Xkcd import eu.kanade.tachiyomi.extension.all.xkcd.Xkcd
import eu.kanade.tachiyomi.lib.textinterceptor.TextInterceptorHelper
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.source.model.Page import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter import eu.kanade.tachiyomi.source.model.SChapter
@ -23,8 +24,6 @@ class XkcdZH : Xkcd("https://xkcd.tw", "zh", "yyyy-MM-dd HH:mm:ss") {
override val interactiveText = override val interactiveText =
"要體驗本漫畫的互動版請在WebView/瀏覽器中打開。" "要體驗本漫畫的互動版請在WebView/瀏覽器中打開。"
override val altTextUrl = CJK_ALT_TEXT_URL
override val imageSelector = "#content > img:not([id])" override val imageSelector = "#content > img:not([id])"
private val json by injectLazy<Json>() private val json by injectLazy<Json>()
@ -54,9 +53,9 @@ class XkcdZH : Xkcd("https://xkcd.tw", "zh", "yyyy-MM-dd HH:mm:ss") {
val image = img.attr("abs:src") val image = img.attr("abs:src")
// create a text image for the alt text // create a text image for the alt text
val text = img.attr("alt") + "\n\n" + img.attr("title") val text = TextInterceptorHelper.createUrl(img.attr("alt"), img.attr("title"))
return listOf(Page(0, "", image), Page(1, "", text.image())) return listOf(Page(0, "", image), Page(1, "", text))
} }
override val chapterListSelector: String override val chapterListSelector: String

View File

@ -1,8 +1,12 @@
ext { ext {
extName = 'buttsmithy' extName = 'buttsmithy'
extClass = '.Buttsmithy' extClass = '.Buttsmithy'
extVersionCode = 3 extVersionCode = 4
isNsfw = true isNsfw = true
} }
apply from: "$rootDir/common.gradle" apply from: "$rootDir/common.gradle"
dependencies {
implementation(project(':lib:textinterceptor'))
}

View File

@ -1,6 +1,8 @@
package eu.kanade.tachiyomi.extension.en.buttsmithy package eu.kanade.tachiyomi.extension.en.buttsmithy
import android.app.Application import android.app.Application
import eu.kanade.tachiyomi.lib.textinterceptor.TextInterceptor
import eu.kanade.tachiyomi.lib.textinterceptor.TextInterceptorHelper
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.source.model.FilterList import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.MangasPage import eu.kanade.tachiyomi.source.model.MangasPage
@ -9,6 +11,7 @@ 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 eu.kanade.tachiyomi.util.asJsoup import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import okhttp3.Response import okhttp3.Response
import org.jsoup.nodes.Document import org.jsoup.nodes.Document
@ -36,6 +39,7 @@ class Buttsmithy : HttpSource() {
private val alfieDateParser = SimpleDateFormat("HH:mm MMMM dd, yyyy", Locale.US) private val alfieDateParser = SimpleDateFormat("HH:mm MMMM dd, yyyy", Locale.US)
override val supportsLatest: Boolean = false override val supportsLatest: Boolean = false
override val client: OkHttpClient = network.client.newBuilder().addInterceptor(TextInterceptor()).build()
override fun fetchChapterList(manga: SManga): Observable<List<SChapter>> { override fun fetchChapterList(manga: SManga): Observable<List<SChapter>> {
val chapters: List<SChapter> = val chapters: List<SChapter> =
@ -255,7 +259,7 @@ class Buttsmithy : HttpSource() {
} }
private fun generateImageUrlWithText(text: String): String { private fun generateImageUrlWithText(text: String): String {
return "https://fakeimg.ryd.tools/800x1236/?text=$text&font=lobster" return TextInterceptorHelper.createUrl(text, "")
} }
private fun generateMangasPage(): MangasPage { private fun generateMangasPage(): MangasPage {

View File

@ -1,8 +1,12 @@
ext { ext {
extName = 'Mehgazone' extName = 'Mehgazone'
extClass = '.Mehgazone' extClass = '.Mehgazone'
extVersionCode = 1 extVersionCode = 2
isNsfw = true isNsfw = true
} }
apply from: "$rootDir/common.gradle" apply from: "$rootDir/common.gradle"
dependencies {
implementation(project(':lib:textinterceptor'))
}

View File

@ -14,6 +14,8 @@ import androidx.preference.PreferenceScreen
import eu.kanade.tachiyomi.extension.en.mehgazone.interceptors.BasicAuthInterceptor import eu.kanade.tachiyomi.extension.en.mehgazone.interceptors.BasicAuthInterceptor
import eu.kanade.tachiyomi.extension.en.mehgazone.serialization.ChapterListDto import eu.kanade.tachiyomi.extension.en.mehgazone.serialization.ChapterListDto
import eu.kanade.tachiyomi.extension.en.mehgazone.serialization.PageListDto import eu.kanade.tachiyomi.extension.en.mehgazone.serialization.PageListDto
import eu.kanade.tachiyomi.lib.textinterceptor.TextInterceptor
import eu.kanade.tachiyomi.lib.textinterceptor.TextInterceptorHelper
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.source.ConfigurableSource import eu.kanade.tachiyomi.source.ConfigurableSource
import eu.kanade.tachiyomi.source.model.FilterList import eu.kanade.tachiyomi.source.model.FilterList
@ -55,6 +57,7 @@ class Mehgazone : ConfigurableSource, HttpSource() {
override val client: OkHttpClient by lazy { override val client: OkHttpClient by lazy {
network.cloudflareClient network.cloudflareClient
.newBuilder() .newBuilder()
.addInterceptor(TextInterceptor())
.addInterceptor(authInterceptor) .addInterceptor(authInterceptor)
.build() .build()
} }
@ -63,10 +66,6 @@ class Mehgazone : ConfigurableSource, HttpSource() {
SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.US) SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.US)
} }
private val textToImageURL = "https://fakeimg.ryd.tools/1500x2126/ffffff/000000/?font=museo&font_size=42".toHttpUrl()
private fun String.image() = textToImageURL.newBuilder().setQueryParameter("text", this).build().toString()
private fun String.unescape() = unescapeEntities(this, false) private fun String.unescape() = unescapeEntities(this, false)
private fun String.linkify() = SpannableString(this).apply { Linkify.addLinks(this, Linkify.WEB_URLS) } private fun String.linkify() = SpannableString(this).apply { Linkify.addLinks(this, Linkify.WEB_URLS) }
@ -172,19 +171,6 @@ class Mehgazone : ConfigurableSource, HttpSource() {
}.reversed() }.reversed()
} }
// Adapted from the xkcd source's wordWrap function
private fun wordWrap(text: String) = buildString {
var charCount = 0
text.replace('\n', ' ').split(' ').forEach { w ->
if (charCount > 25) {
append("\n")
charCount = 0
}
append(w).append(' ')
charCount += w.length + 1
}
}
override fun pageListRequest(chapter: SChapter): Request { override fun pageListRequest(chapter: SChapter): Request {
val chapterUrl = chapter.url.toHttpUrl() val chapterUrl = chapter.url.toHttpUrl()
val pageListUrl = chapterUrl val pageListUrl = chapterUrl
@ -208,7 +194,7 @@ class Mehgazone : ConfigurableSource, HttpSource() {
Page( Page(
images.size, images.size,
"", "",
wordWrap(Jsoup.parseBodyFragment(apiResponse.excerpt.rendered.unescape()).text()).image(), TextInterceptorHelper.createUrl("", Jsoup.parseBodyFragment(apiResponse.excerpt.rendered.unescape()).text()),
), ),
) )
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -1,8 +1,12 @@
ext { ext {
extName = 'Saturday Morning Breakfast Comics' extName = 'Saturday Morning Breakfast Comics'
extClass = '.SaturdayMorningBreakfastComics' extClass = '.SaturdayMorningBreakfastComics'
extVersionCode = 1 extVersionCode = 2
isNsfw = false isNsfw = false
} }
apply from: "$rootDir/common.gradle" apply from: "$rootDir/common.gradle"
dependencies {
implementation(project(':lib:textinterceptor'))
}

View File

@ -1,6 +1,7 @@
package eu.kanade.tachiyomi.extension.en.saturdaymorningbreakfastcomics package eu.kanade.tachiyomi.extension.en.saturdaymorningbreakfastcomics
import android.net.Uri.encode import eu.kanade.tachiyomi.lib.textinterceptor.TextInterceptor
import eu.kanade.tachiyomi.lib.textinterceptor.TextInterceptorHelper
import eu.kanade.tachiyomi.network.asObservable import eu.kanade.tachiyomi.network.asObservable
import eu.kanade.tachiyomi.source.model.FilterList import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.MangasPage import eu.kanade.tachiyomi.source.model.MangasPage
@ -10,8 +11,12 @@ import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.HttpSource import eu.kanade.tachiyomi.source.online.HttpSource
import eu.kanade.tachiyomi.util.asJsoup import eu.kanade.tachiyomi.util.asJsoup
import keiyoushi.utils.tryParse import keiyoushi.utils.tryParse
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.OkHttpClient
import okhttp3.Protocol
import okhttp3.Request import okhttp3.Request
import okhttp3.Response import okhttp3.Response
import okhttp3.ResponseBody.Companion.toResponseBody
import rx.Observable import rx.Observable
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Locale import java.util.Locale
@ -28,27 +33,29 @@ class SaturdayMorningBreakfastComics : HttpSource() {
override val lang = "en" override val lang = "en"
override val supportsLatest = false override val supportsLatest = false
override val client: OkHttpClient = network.client.newBuilder()
.addInterceptor(TextInterceptor())
.addInterceptor { chain ->
val request = chain.request()
val url = request.url
if (url.host != "thumbnail") return@addInterceptor chain.proceed(request)
private fun String.image() = val image = this::class.java
"https://fakeimg.ryd.tools/1500x2126/ffffff/000000/?font=museo&font_size=42&text=" + encode( .getResourceAsStream("/assets/thumbnail.png")!!
this, .readBytes()
) val responseBody = image.toResponseBody("image/png".toMediaType())
Response.Builder()
// Taken from XKCD .request(request)
private fun wordWrap(text: String) = buildString { .protocol(Protocol.HTTP_1_1)
var charCount = 0 .code(200)
text.replace("\r\n", " ").split(' ').forEach { w -> .message("OK")
if (charCount > 25) { .body(responseBody)
append("\n") .build()
charCount = 0
}
append(w).append(' ')
charCount += w.length + 1
} }
} .build()
override fun fetchPopularManga(page: Int): Observable<MangasPage> { private fun makeSManga(): SManga =
val manga = SManga.create().apply { SManga.create().apply {
title = "Saturday Morning Breakfast Comics" title = "Saturday Morning Breakfast Comics"
artist = "Zach Weinersmith" artist = "Zach Weinersmith"
author = "Zach Weinersmith" author = "Zach Weinersmith"
@ -56,9 +63,11 @@ class SaturdayMorningBreakfastComics : HttpSource() {
url = "/comic/archive" url = "/comic/archive"
description = description =
"SMBC is a daily comic strip about life, philosophy, science, mathematics, and dirty jokes." "SMBC is a daily comic strip about life, philosophy, science, mathematics, and dirty jokes."
thumbnail_url = "https://fakeimg.ryd.tools/550x780/ffffff/6e7b91/?font=museo&text=SMBC" thumbnail_url = "https://thumbnail/smbc.png"
} }
override fun fetchPopularManga(page: Int): Observable<MangasPage> {
val manga = makeSManga()
return Observable.just(MangasPage(listOf(manga), false)) return Observable.just(MangasPage(listOf(manga), false))
} }
@ -68,7 +77,7 @@ class SaturdayMorningBreakfastComics : HttpSource() {
filters: FilterList, filters: FilterList,
): Observable<MangasPage> = Observable.just(MangasPage(emptyList(), false)) ): Observable<MangasPage> = Observable.just(MangasPage(emptyList(), false))
override fun fetchMangaDetails(manga: SManga): Observable<SManga> = Observable.just(manga) override fun fetchMangaDetails(manga: SManga): Observable<SManga> = Observable.just(makeSManga())
override fun fetchChapterList(manga: SManga): Observable<List<SChapter>> { override fun fetchChapterList(manga: SManga): Observable<List<SChapter>> {
return client.newCall(chapterListRequest(manga)) return client.newCall(chapterListRequest(manga))
@ -98,7 +107,7 @@ class SaturdayMorningBreakfastComics : HttpSource() {
val image = document.select("img#cc-comic") val image = document.select("img#cc-comic")
pages.add(Page(0, "", image.attr("abs:src"))) pages.add(Page(0, "", image.attr("abs:src")))
if (image.hasAttr("title")) { if (image.hasAttr("title")) {
pages.add(Page(1, "", wordWrap(image.attr("title")).image())) pages.add(Page(1, "", TextInterceptorHelper.createUrl("", image.attr("title"))))
} }
pages.add(Page(2, "", document.select("#aftercomic > img").attr("abs:src"))) pages.add(Page(2, "", document.select("#aftercomic > img").attr("abs:src")))
return pages return pages

View File

@ -1,7 +1,11 @@
ext { ext {
extName = 'Swords Comic' extName = 'Swords Comic'
extClass = '.SwordsComic' extClass = '.SwordsComic'
extVersionCode = 4 extVersionCode = 5
} }
apply from: "$rootDir/common.gradle" apply from: "$rootDir/common.gradle"
dependencies {
implementation(project(':lib:textinterceptor'))
}

View File

@ -1,6 +1,7 @@
package eu.kanade.tachiyomi.extension.en.swordscomic package eu.kanade.tachiyomi.extension.en.swordscomic
import android.net.Uri import eu.kanade.tachiyomi.lib.textinterceptor.TextInterceptor
import eu.kanade.tachiyomi.lib.textinterceptor.TextInterceptorHelper
import eu.kanade.tachiyomi.source.model.FilterList import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.MangasPage import eu.kanade.tachiyomi.source.model.MangasPage
import eu.kanade.tachiyomi.source.model.Page import eu.kanade.tachiyomi.source.model.Page
@ -25,7 +26,7 @@ class SwordsComic : HttpSource() {
override val supportsLatest = false override val supportsLatest = false
override val client: OkHttpClient = network.cloudflareClient override val client: OkHttpClient = network.cloudflareClient.newBuilder().addInterceptor(TextInterceptor()).build()
private fun createManga(): SManga { private fun createManga(): SManga {
return SManga.create().apply { return SManga.create().apply {
@ -92,21 +93,9 @@ class SwordsComic : HttpSource() {
if (!imageElement.hasAttr("title")) { if (!imageElement.hasAttr("title")) {
return listOf(Page(0, "", imageElement.attr("abs:src"))) return listOf(Page(0, "", imageElement.attr("abs:src")))
} }
val titleText = TextInterceptorHelper.createUrl("", imageElement.attr("title"))
val builder = StringBuilder() return listOf(Page(0, "", imageElement.attr("abs:src")), Page(1, "", titleText))
var charCount = 0
for (word in imageElement.attr("title").splitToSequence(" ")) {
if (charCount + word.length > 45) {
builder.append("%0A")
charCount = 0
}
charCount += word.length + 1
builder.append(Uri.encode(word.uppercase()))
builder.append("+")
}
return listOf(Page(0, "", imageElement.attr("abs:src")), Page(1, "", "https://fakeimg.ryd.tools/1800x2252/978B65/000000/?text=$builder&font_size=60&font=comic+sans"))
} }
override fun imageUrlParse(response: Response): String = throw UnsupportedOperationException() override fun imageUrlParse(response: Response): String = throw UnsupportedOperationException()