xkcd: add more translations (#9793)

* Spanish

* French

* Russian

* Korean
This commit is contained in:
ObserverOfTime 2021-11-12 15:40:55 +02:00 committed by GitHub
parent e210beeca4
commit 8c16b03bb9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 210 additions and 23 deletions

View File

@ -6,7 +6,7 @@ ext {
extName = 'xkcd'
pkgNameSuffix = 'all.xkcd'
extClass = '.XkcdFactory'
extVersionCode = 11
extVersionCode = 12
}
apply from: "$rootDir/common.gradle"

View File

@ -27,7 +27,7 @@ open class Xkcd(
protected open val creator = "Randall Munroe"
protected open val synopsis =
"A webcomic of romance, sarcasm, math and language"
"A webcomic of romance, sarcasm, math and language."
protected open val interactiveText =
"To experience the interactive version of this comic," +
@ -47,6 +47,25 @@ open class Xkcd(
protected open fun String.numbered(number: Any) = "$number - $this"
// TODO: maybe use BreakIterator
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 {
title = name
@ -88,27 +107,7 @@ open class Xkcd(
}
// create a text image for the alt text
val titleWords = img.attr("alt").split(' ')
val altTextWords = img.attr("title").split(' ')
// TODO: maybe use BreakIterator
val text = buildString {
titleWords.forEachIndexed { i, w ->
if (i != 0 && i % 7 == 0) append("\n")
append(w).append(' ')
}
append("\n\n")
var charCount = 0
altTextWords.forEach { w ->
if (charCount > 25) {
append("\n")
charCount = 0
}
append(w).append(' ')
charCount += w.length + 1
}
}
val text = wordWrap(img.attr("alt"), img.attr("title"))
return listOf(Page(0, "", image), Page(1, "", text.image()))
}

View File

@ -1,11 +1,19 @@
package eu.kanade.tachiyomi.extension.all.xkcd
import eu.kanade.tachiyomi.extension.all.xkcd.translations.XkcdES
import eu.kanade.tachiyomi.extension.all.xkcd.translations.XkcdFR
import eu.kanade.tachiyomi.extension.all.xkcd.translations.XkcdKO
import eu.kanade.tachiyomi.extension.all.xkcd.translations.XkcdRU
import eu.kanade.tachiyomi.extension.all.xkcd.translations.XkcdZH
import eu.kanade.tachiyomi.source.SourceFactory
class XkcdFactory : SourceFactory {
override fun createSources() = listOf(
Xkcd("https://xkcd.com", "en"),
XkcdES(),
XkcdZH(),
XkcdFR(),
XkcdRU(),
XkcdKO(),
)
}

View File

@ -0,0 +1,36 @@
package eu.kanade.tachiyomi.extension.all.xkcd.translations
import eu.kanade.tachiyomi.extension.all.xkcd.Xkcd
import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.Response
class XkcdES : Xkcd("https://es.xkcd.com", "es") {
override val synopsis =
"Un webcómic sobre romance, sarcasmo, mates y lenguaje."
// Google translated, sorry
override val interactiveText =
"Para experimentar la versión interactiva de este cómic," +
"\nábralo en WebView/navegador."
override val chapterListSelector = "#archive-ul > ul > li > a"
override val imageSelector = "#middleContent .strip"
override fun chapterListParse(response: Response) =
response.asJsoup().select(chapterListSelector).mapIndexed { idx, el ->
SChapter.create().apply {
name = el.text()
// convert relative path to absolute
url = el.attr("href").substring(2)
// not accurate to the original ¯\_(ツ)_/¯
chapter_number = idx + 1f
// no dates available
date_upload = 0L
}
}
override fun String.numbered(number: Any) =
throw UnsupportedOperationException("Not used")
}

View File

@ -0,0 +1,46 @@
package eu.kanade.tachiyomi.extension.all.xkcd.translations
import eu.kanade.tachiyomi.extension.all.xkcd.Xkcd
import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.Response
class XkcdFR : Xkcd("https://xkcd.lapin.org", "fr") {
override val archive = "/tous-episodes.php"
override val synopsis =
"Un webcomic sarcastique qui parle de romance, de maths et de langage."
override val chapterListSelector = "#content .s > a:not(:last-of-type)"
override val imageSelector = "#content .s"
override fun String.numbered(number: Any) = "$number. $this"
override fun chapterListParse(response: Response) =
response.asJsoup().select(chapterListSelector).map {
SChapter.create().apply {
url = "/" + it.attr("href")
val number = url.substringAfter('=')
name = it.text().numbered(number)
chapter_number = number.toFloat()
// no dates available
date_upload = 0L
}
}
override fun pageListParse(response: Response) =
response.asJsoup().selectFirst(imageSelector).let {
// no interactive comics here
val img = it.child(2).child(0).child(0)
// create a text image for the alt text
val text = wordWrap(it.child(0).text(), img.attr("alt"))
listOf(Page(0, "", img.attr("abs:src")), Page(1, "", text.image()))
}
override val interactiveText: String
get() = throw UnsupportedOperationException("Not used")
}

View File

@ -0,0 +1,50 @@
package eu.kanade.tachiyomi.extension.all.xkcd.translations
import eu.kanade.tachiyomi.extension.all.xkcd.Xkcd
import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.Response
class XkcdKO : Xkcd("https://xkcdko.com", "ko") {
override val creator = "랜들 먼로"
override val synopsis = "사랑, 풍자, 수학, 그리고 언어에 관한 웹 만화."
// Google translated, sorry
override val interactiveText =
"이 만화의 대화형 버전을 경험하려면\nWebView/브라우저에서 엽니다."
override val altTextUrl = CJK_ALT_TEXT_URL
override val chapterListSelector = "#comicList > ol > li > a"
override fun chapterListParse(response: Response) =
response.asJsoup().select(chapterListSelector).map {
SChapter.create().apply {
url = it.attr("href")
val number = it.attr("title")
name = it.text().numbered(number)
chapter_number = number.toFloat()
// no dates available
date_upload = 0L
}
}
override fun pageListParse(response: Response): List<Page> {
// if the img tag is empty then it is an interactive comic
val img = response.asJsoup().selectFirst(imageSelector)
?: return listOf(Page(0, "", interactiveText.image()))
// if an HD image is available it'll be the srcset attribute
val image = when {
!img.hasAttr("srcset") -> img.attr("abs:src")
else -> img.attr("abs:srcset").substringBefore(' ')
}
// create a text image for the alt text
val text = img.attr("alt") + "\n\n" + img.attr("title")
return listOf(Page(0, "", image), Page(1, "", text.image()))
}
}

View File

@ -0,0 +1,48 @@
package eu.kanade.tachiyomi.extension.all.xkcd.translations
import eu.kanade.tachiyomi.extension.all.xkcd.Xkcd
import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.Response
class XkcdRU : Xkcd("https://xkcd.ru", "ru") {
override val archive = "/img"
override val creator = "Рэндел Манро"
override val synopsis = "о романтике, сарказме, математике и языке"
override val altTextUrl = super.altTextUrl.replace("museo", "noto")
override val chapterListSelector = ".main > a"
override val imageSelector = ".main"
override fun String.numbered(number: Any) = "$number: $this"
override fun chapterListParse(response: Response) =
response.asJsoup().select(chapterListSelector).map {
SChapter.create().apply {
url = it.attr("href")
name = it.child(0).attr("title")
chapter_number = url.removeSurrounding("/").toFloat()
// no dates available
date_upload = 0L
}
}
override fun pageListParse(response: Response) =
response.asJsoup().selectFirst(imageSelector).let {
// no interactive comics here
val img = it.child(5).child(0)
// create a text image for the alt text
val text = wordWrap(img.attr("alt"), it.child(7).text())
listOf(Page(0, "", img.attr("abs:src")), Page(1, "", text.image()))
}
override val interactiveText: String
get() = throw UnsupportedOperationException("Not used")
}