Add lang support to webtoons (#471) (#1060)

This commit is contained in:
Rajh 2019-04-28 17:40:24 +02:00 committed by Eugene
parent 0bb2bed20f
commit 42599d9ec3
13 changed files with 142 additions and 31 deletions

View File

@ -3,8 +3,8 @@ apply plugin: 'kotlin-android'
ext {
appName = 'Tachiyomi: Webtoons'
pkgNameSuffix = 'en.webtoons'
extClass = '.Webtoons'
pkgNameSuffix = 'all.webtoons'
extClass = '.WebtoonsFactory'
extVersionCode = 6
libVersion = '1.2'
}

View File

Before

Width:  |  Height:  |  Size: 4.8 KiB

After

Width:  |  Height:  |  Size: 4.8 KiB

View File

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

Before

Width:  |  Height:  |  Size: 6.5 KiB

After

Width:  |  Height:  |  Size: 6.5 KiB

View File

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View File

Before

Width:  |  Height:  |  Size: 60 KiB

After

Width:  |  Height:  |  Size: 60 KiB

View File

@ -1,4 +1,4 @@
package eu.kanade.tachiyomi.extension.en.webtoons
package eu.kanade.tachiyomi.extension.all.webtoons
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.source.model.*
@ -9,17 +9,14 @@ import okhttp3.Request
import okhttp3.Response
import org.jsoup.nodes.Document
import org.jsoup.nodes.Element
import java.text.SimpleDateFormat
import java.util.*
class Webtoons : ParsedHttpSource() {
abstract class Webtoons(override val lang: String) : ParsedHttpSource() {
override val name = "Webtoons.com"
override val baseUrl = "http://www.webtoons.com"
override val lang = "en"
override val supportsLatest = true
val day: String
@ -45,7 +42,7 @@ class Webtoons : ParsedHttpSource() {
override fun headersBuilder() = super.headersBuilder()
.add("Referer", "http://www.webtoons.com/en/")
private val mobileHeaders = super.headersBuilder()
protected val mobileHeaders = super.headersBuilder()
.add("Referer", "http://m.webtoons.com")
.build()
@ -135,28 +132,6 @@ class Webtoons : ParsedHttpSource() {
else -> SManga.UNKNOWN
}
override fun chapterListSelector() = "ul#_episodeList > li[id*=episode]"
override fun chapterFromElement(element: Element): SChapter {
val urlElement = element.select("a")
val chapter = SChapter.create()
chapter.setUrlWithoutDomain(urlElement.attr("href"))
chapter.name = element.select("a > div.row > div.info > p.sub_title > span.ellipsis").text()
val select = element.select("a > div.row > div.num")
if (select.isNotEmpty()) {
chapter.name += " Ch. " + select.text().substringAfter("#")
}
if (element.select(".ico_bgm").isNotEmpty()) {
chapter.name += ""
}
chapter.date_upload = element.select("a > div.row > div.info > p.date").text()?.let { SimpleDateFormat("MMM d, yyyy", Locale.ENGLISH).parse(it).time } ?: 0
return chapter
}
override fun chapterListRequest(manga: SManga) = GET("http://m.webtoons.com" + manga.url, mobileHeaders)
override fun pageListParse(document: Document) = document.select("div#_imageList > img").mapIndexed { i, element -> Page(i, "", element.attr("data-url")) }
override fun imageUrlParse(document: Document) = document.select("img").first().attr("src")
}

View File

@ -0,0 +1,36 @@
package eu.kanade.tachiyomi.extension.all.webtoons
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga
import org.jsoup.nodes.Document
import org.jsoup.nodes.Element
import java.text.SimpleDateFormat
import java.util.*
open class WebtoonsDefault(override val lang: String) : Webtoons(lang) {
override fun chapterListSelector() = "ul#_episodeList > li[id*=episode]"
override fun chapterFromElement(element: Element): SChapter {
val urlElement = element.select("a")
val chapter = SChapter.create()
chapter.setUrlWithoutDomain(urlElement.attr("href"))
chapter.name = element.select("a > div.row > div.info > p.sub_title > span.ellipsis").text()
val select = element.select("a > div.row > div.num")
if (select.isNotEmpty()) {
chapter.name += " Ch. " + select.text().substringAfter("#")
}
if (element.select(".ico_bgm").isNotEmpty()) {
chapter.name += ""
}
chapter.date_upload = element.select("a > div.row > div.info > p.date").text()?.let { SimpleDateFormat("MMM d, yyyy", Locale.ENGLISH).parse(it).time } ?: 0
return chapter
}
override fun chapterListRequest(manga: SManga) = GET("http://m.webtoons.com" + manga.url, mobileHeaders)
override fun pageListParse(document: Document) = document.select("div#_imageList > img").mapIndexed { i, element -> Page(i, "", element.attr("data-url")) }
}

View File

@ -0,0 +1,17 @@
package eu.kanade.tachiyomi.extension.all.webtoons
import eu.kanade.tachiyomi.extension.en.webtoons.WebtoonsEnglish
import eu.kanade.tachiyomi.extension.fr.webtoons.WebtoonsFrench
import eu.kanade.tachiyomi.source.Source
import eu.kanade.tachiyomi.source.SourceFactory
class WebtoonsFactory : SourceFactory {
override fun createSources(): List<Source> = getAllWebtoons()
}
fun getAllWebtoons(): List<Source> {
return listOf(
WebtoonsEnglish(),
WebtoonsFrench()
)
}

View File

@ -0,0 +1,73 @@
package eu.kanade.tachiyomi.extension.all.webtoons
import android.util.Log.e
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.source.model.*
import okhttp3.Request
import okhttp3.Response
import org.json.JSONObject
import org.jsoup.nodes.Document
import org.jsoup.nodes.Element
import java.util.*
open class WebtoonsTranslate(override val lang: String, private val langCode: String) : Webtoons(lang) {
private val apiBaseUrl = "https://global.apis.naver.com"
private val chapterListUrlPattern = "/lineWebtoon/ctrans/translatedEpisodes_jsonp.json?titleNo=%d&languageCode=%s&offset=0&limit=10000"
private val pageListUrlPattern = "/lineWebtoon/ctrans/translatedEpisodeDetail_jsonp.json?titleNo=%s&episodeNo=%d&languageCode=%s&teamVersion=%d"
override fun chapterListSelector(): String = throw Exception("Not used")
override fun chapterFromElement(element: Element): SChapter = throw Exception("Not used")
override fun pageListParse(document: Document): List<Page> = throw Exception("Not used")
override fun chapterListRequest(manga: SManga): Request {
val original = manga.url;
val titleRegex = Regex("title_?[nN]o=([0-9]*)")
val titleNo = titleRegex.find(original)!!.groupValues[1].toInt()
val chapterUrl = String.format("$apiBaseUrl$chapterListUrlPattern", titleNo, langCode)
return GET(chapterUrl, headers)
}
override fun chapterListParse(response: Response): List<SChapter> {
val chapterJson = JSONObject(response.body()!!.string())
var results = chapterJson.getJSONObject("result").getJSONArray("episodes")
val ret = ArrayList<SChapter>()
for (i in 0 until results.length()) {
val result = results.getJSONObject(i)
if (result.getBoolean("translateCompleted")) {
ret.add(parseChapterJson(result))
}
}
ret.reverse()
return ret
}
private fun parseChapterJson(obj: JSONObject) = SChapter.create().apply {
name = obj.getString("title") + " #" + obj.getString("episodeSeq")
chapter_number = obj.getInt("episodeSeq").toFloat()
date_upload = obj.getLong("updateYmdt")
scanlator = obj.getString("teamVersion")
url = String.format(pageListUrlPattern, obj.getInt("titleNo"), obj.getInt("episodeNo"), obj.getString("languageCode"), obj.getInt("teamVersion"))
}
override fun pageListRequest(chapter: SChapter): Request {
return GET(apiBaseUrl + chapter.url, mobileHeaders)
}
override fun pageListParse(response: Response): List<Page> {
val pageJson = JSONObject(response.body()!!.string())
var results = pageJson.getJSONObject("result").getJSONArray("imageInfo")
val ret = ArrayList<Page>()
for (i in 0 until results.length()) {
val result = results.getJSONObject(i)
ret.add(Page(i, "", result.getString("imageUrl")))
}
return ret
}
}

View File

@ -0,0 +1,5 @@
package eu.kanade.tachiyomi.extension.en.webtoons
import eu.kanade.tachiyomi.extension.all.webtoons.WebtoonsDefault
class WebtoonsEnglish : WebtoonsDefault("en")

View File

@ -0,0 +1,5 @@
package eu.kanade.tachiyomi.extension.fr.webtoons
import eu.kanade.tachiyomi.extension.all.webtoons.WebtoonsTranslate
class WebtoonsFrench : WebtoonsTranslate("fr", "FRA")