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:
parent
8bd7ed9a90
commit
e17d796fc1
BIN
src/all/xkcd/assets/thumbnail.png
Normal file
BIN
src/all/xkcd/assets/thumbnail.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 21 KiB |
@ -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'))
|
||||||
|
}
|
||||||
|
|||||||
@ -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"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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'))
|
||||||
|
}
|
||||||
|
|||||||
@ -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 {
|
||||||
|
|||||||
@ -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'))
|
||||||
|
}
|
||||||
|
|||||||
@ -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()),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
src/en/saturdaymorningbreakfastcomics/assets/thumbnail.png
Normal file
BIN
src/en/saturdaymorningbreakfastcomics/assets/thumbnail.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
@ -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'))
|
||||||
|
}
|
||||||
|
|||||||
@ -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()
|
||||||
|
.request(request)
|
||||||
|
.protocol(Protocol.HTTP_1_1)
|
||||||
|
.code(200)
|
||||||
|
.message("OK")
|
||||||
|
.body(responseBody)
|
||||||
|
.build()
|
||||||
|
}
|
||||||
|
.build()
|
||||||
|
|
||||||
// Taken from XKCD
|
private fun makeSManga(): SManga =
|
||||||
private fun wordWrap(text: String) = buildString {
|
SManga.create().apply {
|
||||||
var charCount = 0
|
|
||||||
text.replace("\r\n", " ").split(' ').forEach { w ->
|
|
||||||
if (charCount > 25) {
|
|
||||||
append("\n")
|
|
||||||
charCount = 0
|
|
||||||
}
|
|
||||||
append(w).append(' ')
|
|
||||||
charCount += w.length + 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun fetchPopularManga(page: Int): Observable<MangasPage> {
|
|
||||||
val manga = 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
|
||||||
|
|||||||
@ -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'))
|
||||||
|
}
|
||||||
|
|||||||
@ -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()
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user