diff --git a/src/all/webtoons/res/mipmap-hdpi/ic_launcher.png b/multisrc/overrides/webtoons/default/res/mipmap-hdpi/ic_launcher.png similarity index 100% rename from src/all/webtoons/res/mipmap-hdpi/ic_launcher.png rename to multisrc/overrides/webtoons/default/res/mipmap-hdpi/ic_launcher.png diff --git a/src/all/webtoons/res/mipmap-mdpi/ic_launcher.png b/multisrc/overrides/webtoons/default/res/mipmap-mdpi/ic_launcher.png similarity index 100% rename from src/all/webtoons/res/mipmap-mdpi/ic_launcher.png rename to multisrc/overrides/webtoons/default/res/mipmap-mdpi/ic_launcher.png diff --git a/src/all/webtoons/res/mipmap-xhdpi/ic_launcher.png b/multisrc/overrides/webtoons/default/res/mipmap-xhdpi/ic_launcher.png similarity index 100% rename from src/all/webtoons/res/mipmap-xhdpi/ic_launcher.png rename to multisrc/overrides/webtoons/default/res/mipmap-xhdpi/ic_launcher.png diff --git a/src/all/webtoons/res/mipmap-xxhdpi/ic_launcher.png b/multisrc/overrides/webtoons/default/res/mipmap-xxhdpi/ic_launcher.png similarity index 100% rename from src/all/webtoons/res/mipmap-xxhdpi/ic_launcher.png rename to multisrc/overrides/webtoons/default/res/mipmap-xxhdpi/ic_launcher.png diff --git a/src/all/webtoons/res/mipmap-xxxhdpi/ic_launcher.png b/multisrc/overrides/webtoons/default/res/mipmap-xxxhdpi/ic_launcher.png similarity index 100% rename from src/all/webtoons/res/mipmap-xxxhdpi/ic_launcher.png rename to multisrc/overrides/webtoons/default/res/mipmap-xxxhdpi/ic_launcher.png diff --git a/src/all/webtoons/res/web_hi_res_512.png b/multisrc/overrides/webtoons/default/res/web_hi_res_512.png similarity index 100% rename from src/all/webtoons/res/web_hi_res_512.png rename to multisrc/overrides/webtoons/default/res/web_hi_res_512.png diff --git a/multisrc/overrides/webtoons/dongmanmanhua/res/mipmap-hdpi/ic_launcher.png b/multisrc/overrides/webtoons/dongmanmanhua/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 000000000..f1783975f Binary files /dev/null and b/multisrc/overrides/webtoons/dongmanmanhua/res/mipmap-hdpi/ic_launcher.png differ diff --git a/multisrc/overrides/webtoons/dongmanmanhua/res/mipmap-mdpi/ic_launcher.png b/multisrc/overrides/webtoons/dongmanmanhua/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 000000000..2472ef7f3 Binary files /dev/null and b/multisrc/overrides/webtoons/dongmanmanhua/res/mipmap-mdpi/ic_launcher.png differ diff --git a/multisrc/overrides/webtoons/dongmanmanhua/res/mipmap-xhdpi/ic_launcher.png b/multisrc/overrides/webtoons/dongmanmanhua/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 000000000..3d25950db Binary files /dev/null and b/multisrc/overrides/webtoons/dongmanmanhua/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/multisrc/overrides/webtoons/dongmanmanhua/res/mipmap-xxhdpi/ic_launcher.png b/multisrc/overrides/webtoons/dongmanmanhua/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 000000000..a5e52be3e Binary files /dev/null and b/multisrc/overrides/webtoons/dongmanmanhua/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/multisrc/overrides/webtoons/dongmanmanhua/res/mipmap-xxxhdpi/ic_launcher.png b/multisrc/overrides/webtoons/dongmanmanhua/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 000000000..fce9306a8 Binary files /dev/null and b/multisrc/overrides/webtoons/dongmanmanhua/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/multisrc/overrides/webtoons/dongmanmanhua/res/web_hi_res_512.png b/multisrc/overrides/webtoons/dongmanmanhua/res/web_hi_res_512.png new file mode 100644 index 000000000..d7c91223f Binary files /dev/null and b/multisrc/overrides/webtoons/dongmanmanhua/res/web_hi_res_512.png differ diff --git a/src/all/webtoons/src/eu/kanade/tachiyomi/extension/all/webtoons/DongmanManhua.kt b/multisrc/overrides/webtoons/dongmanmanhua/src/DongmanManhua.kt similarity index 89% rename from src/all/webtoons/src/eu/kanade/tachiyomi/extension/all/webtoons/DongmanManhua.kt rename to multisrc/overrides/webtoons/dongmanmanhua/src/DongmanManhua.kt index 225de49a9..f76da3101 100644 --- a/src/all/webtoons/src/eu/kanade/tachiyomi/extension/all/webtoons/DongmanManhua.kt +++ b/multisrc/overrides/webtoons/dongmanmanhua/src/DongmanManhua.kt @@ -1,6 +1,7 @@ -package eu.kanade.tachiyomi.extension.all.webtoons +package eu.kanade.tachiyomi.extension.zh.dongmanmanhua import eu.kanade.tachiyomi.network.GET +import eu.kanade.tachiyomi.multisrc.webtoons.Webtoons import eu.kanade.tachiyomi.source.model.FilterList import eu.kanade.tachiyomi.source.model.SChapter import eu.kanade.tachiyomi.source.model.SManga @@ -13,10 +14,7 @@ import org.jsoup.nodes.Element import java.text.SimpleDateFormat import java.util.Locale -class DongmanManhua : WebtoonsDefault("zh", "", dateFormat = SimpleDateFormat("yyyy-M-d", Locale.ENGLISH)) { - override val baseUrl = "https://www.dongmanmanhua.cn" - - override val name = "Dongman Manhua" +class DongmanManhua : Webtoons("Dongman Manhua", "https://www.dongmanmanhua.cn", "zh", "", dateFormat = SimpleDateFormat("yyyy-M-d", Locale.ENGLISH)) { override fun headersBuilder(): Headers.Builder = super.headersBuilder() .removeAll("Referer") diff --git a/multisrc/overrides/webtoons/webtoons/src/WebtoonsFactory.kt b/multisrc/overrides/webtoons/webtoons/src/WebtoonsFactory.kt new file mode 100644 index 000000000..8be433150 --- /dev/null +++ b/multisrc/overrides/webtoons/webtoons/src/WebtoonsFactory.kt @@ -0,0 +1,56 @@ +package eu.kanade.tachiyomi.extension.all.webtoons + +import eu.kanade.tachiyomi.multisrc.webtoons.Webtoons +import eu.kanade.tachiyomi.source.Source +import eu.kanade.tachiyomi.source.SourceFactory +import java.text.SimpleDateFormat +import java.util.GregorianCalendar +import java.util.Locale +import java.util.Calendar + +class WebtoonsFactory : SourceFactory { + override fun createSources(): List = listOf( + WebtoonsEN(), + WebtoonsID(), + WebtoonsTH(), + WebtoonsES(), + WebtoonsFR(), + WebtoonsZH(), + ) + +} +class WebtoonsEN : Webtoons("Webtoons", "https://www.webtoons.com", "en") +class WebtoonsID : Webtoons("Webtoons", "https://www.webtoons.com", "id") { + // Override ID as part of the name was removed to be more consiten with other enteries + override val id: Long = 8749627068478740298 + + // Android seems to be unable to parse Indonesian dates; we'll use a short hard-coded table + // instead. + private val dateMap: Array = arrayOf( + "Jan", "Feb", "Mar", "Apr", "Mei", "Jun", "Jul", "Agu", "Sep", "Okt", "Nov", "Des" + ) + + override fun chapterParseDate(date: String): Long { + val expr = Regex("""(\d{4}) ([A-Z][a-z]{2}) (\d+)""").find(date) ?: return 0 + val (_, year, monthString, day) = expr.groupValues + val monthIndex = dateMap.indexOf(monthString) + return GregorianCalendar(year.toInt(), monthIndex, day.toInt()).time.time + } +} +class WebtoonsTH : Webtoons("Webtoons", "https://www.webtoons.com", "th", dateFormat = SimpleDateFormat("d MMM yyyy", Locale("th"))) +class WebtoonsES : Webtoons("Webtoons", "https://www.webtoons.com", "es") { + // Android seems to be unable to parse es dates like Indonesian; we'll use a short hard-coded table + // instead. + private val dateMap: Array = arrayOf( + "Ene", "Feb", "Mar", "Abr", "May", "Jun", "Jul", "Ago", "Sep", "Oct", "Nov", "Dic" + ) + + override fun chapterParseDate(date: String): Long { + val expr = Regex("""(\d+)-([a-z]{3})-(\d{4})""").find(date) ?: return 0 + val (_, day, monthString, year) = expr.groupValues + val monthIndex = dateMap.indexOf(monthString) + return GregorianCalendar(year.toInt(), monthIndex, day.toInt()).time.time + } +} +class WebtoonsFR : Webtoons("Webtoons", "https://www.webtoons.com", "fr", dateFormat = SimpleDateFormat("d MMM yyyy", Locale.FRENCH)) +class WebtoonsZH : Webtoons("Webtoons", "https://www.webtoons.com", "zh", "zh-hant", "zh_TW", SimpleDateFormat("yyyy/MM/dd", Locale.TRADITIONAL_CHINESE)) diff --git a/multisrc/overrides/webtoons/webtoonstranslate/src/WebtoonsTranslateFactory.kt b/multisrc/overrides/webtoons/webtoonstranslate/src/WebtoonsTranslateFactory.kt new file mode 100644 index 000000000..232ec920c --- /dev/null +++ b/multisrc/overrides/webtoons/webtoonstranslate/src/WebtoonsTranslateFactory.kt @@ -0,0 +1,85 @@ +package eu.kanade.tachiyomi.extension.all.webtoonstranslate + +import eu.kanade.tachiyomi.multisrc.webtoons.WebtoonsTranslate +import eu.kanade.tachiyomi.source.Source +import eu.kanade.tachiyomi.source.SourceFactory + +class WebtoonsTranslateFactory : SourceFactory { + override fun createSources(): List = listOf( + WebtoonsTranslateEN(), + WebtoonsTranslateZH_CMN(), + WebtoonsTranslateZH_CMY(), + WebtoonsTranslateTH(), + WebtoonsTranslateID(), + WebtoonsTranslateFR(), + WebtoonsTranslateVI(), + WebtoonsTranslateRU(), + WebtoonsTranslateAR(), + WebtoonsTranslateFIL(), + WebtoonsTranslateDE(), + WebtoonsTranslateHI(), + WebtoonsTranslateIT(), + WebtoonsTranslateJA(), + WebtoonsTranslatePT_POR(), + WebtoonsTranslateTR(), + WebtoonsTranslateMS(), + WebtoonsTranslatePL(), + WebtoonsTranslatePT_POT(), + WebtoonsTranslateBG(), + WebtoonsTranslateDA(), + WebtoonsTranslateNL(), + WebtoonsTranslateRO(), + WebtoonsTranslateMN(), + WebtoonsTranslateEL(), + WebtoonsTranslateLT(), + WebtoonsTranslateCS(), + WebtoonsTranslateSV(), + WebtoonsTranslateBN(), + WebtoonsTranslateFA(), + WebtoonsTranslateUK(), + WebtoonsTranslateES(), + ) +} +class WebtoonsTranslateEN : WebtoonsTranslate("Webtoons.com Translations", "https://translate.webtoons.com", "en", "ENG") +class WebtoonsTranslateZH_CMN : WebtoonsTranslate("Webtoons.com Translations", "https://translate.webtoons.com", "zh-hans", "CMN"){ + override val id: Long = 5196522547754842244 +} +class WebtoonsTranslateZH_CMY : WebtoonsTranslate("Webtoons.com Translations", "https://translate.webtoons.com", "zh-hant", "CMT"){ + override val id: Long = 1016181401146312893 +} +class WebtoonsTranslateTH : WebtoonsTranslate("Webtoons.com Translations", "https://translate.webtoons.com", "th", "THA") +class WebtoonsTranslateID : WebtoonsTranslate("Webtoons.com Translations", "https://translate.webtoons.com", "id", "IND") +class WebtoonsTranslateFR : WebtoonsTranslate("Webtoons.com Translations", "https://translate.webtoons.com", "fr", "FRA") +class WebtoonsTranslateVI : WebtoonsTranslate("Webtoons.com Translations", "https://translate.webtoons.com", "vi", "VIE") +class WebtoonsTranslateRU : WebtoonsTranslate("Webtoons.com Translations", "https://translate.webtoons.com", "ru", "RUS") +class WebtoonsTranslateAR : WebtoonsTranslate("Webtoons.com Translations", "https://translate.webtoons.com", "ar", "ARA") +class WebtoonsTranslateFIL : WebtoonsTranslate("Webtoons.com Translations", "https://translate.webtoons.com", "fil", "FIL") +class WebtoonsTranslateDE : WebtoonsTranslate("Webtoons.com Translations", "https://translate.webtoons.com", "de", "DEU") +class WebtoonsTranslateHI : WebtoonsTranslate("Webtoons.com Translations", "https://translate.webtoons.com", "hi", "HIN") +class WebtoonsTranslateIT : WebtoonsTranslate("Webtoons.com Translations", "https://translate.webtoons.com", "it", "ITA") +class WebtoonsTranslateJA : WebtoonsTranslate("Webtoons.com Translations", "https://translate.webtoons.com", "ja", "JPN") +class WebtoonsTranslatePT_POR : WebtoonsTranslate("Webtoons.com Translations", "https://translate.webtoons.com", "pt-br", "POR"){ + //Changed languge code from pt to pt-br + override val id: Long = 275670196689829558 +} +class WebtoonsTranslateTR : WebtoonsTranslate("Webtoons.com Translations", "https://translate.webtoons.com", "tr", "TUR") +class WebtoonsTranslateMS : WebtoonsTranslate("Webtoons.com Translations", "https://translate.webtoons.com", "ms", "MAY") +class WebtoonsTranslatePL : WebtoonsTranslate("Webtoons.com Translations", "https://translate.webtoons.com", "pl", "POL") +class WebtoonsTranslatePT_POT : WebtoonsTranslate("Webtoons.com Translations", "https://translate.webtoons.com", "pt", "POT") { + override val id: Long = 9219933036054791613 +} +class WebtoonsTranslateBG : WebtoonsTranslate("Webtoons.com Translations", "https://translate.webtoons.com", "bg", "BUL") +class WebtoonsTranslateDA : WebtoonsTranslate("Webtoons.com Translations", "https://translate.webtoons.com", "da", "DAN") +class WebtoonsTranslateNL : WebtoonsTranslate("Webtoons.com Translations", "https://translate.webtoons.com", "nl", "NLD") +class WebtoonsTranslateRO : WebtoonsTranslate("Webtoons.com Translations", "https://translate.webtoons.com", "ro", "RON") +class WebtoonsTranslateMN : WebtoonsTranslate("Webtoons.com Translations", "https://translate.webtoons.com", "mn", "MON") +class WebtoonsTranslateEL : WebtoonsTranslate("Webtoons.com Translations", "https://translate.webtoons.com", "el", "GRE") +class WebtoonsTranslateLT : WebtoonsTranslate("Webtoons.com Translations", "https://translate.webtoons.com", "lt", "LIT") +class WebtoonsTranslateCS : WebtoonsTranslate("Webtoons.com Translations", "https://translate.webtoons.com", "cs", "CES") +class WebtoonsTranslateSV : WebtoonsTranslate("Webtoons.com Translations", "https://translate.webtoons.com", "sv", "SWE") +class WebtoonsTranslateBN : WebtoonsTranslate("Webtoons.com Translations", "https://translate.webtoons.com", "bn", "BEN") +class WebtoonsTranslateFA : WebtoonsTranslate("Webtoons.com Translations", "https://translate.webtoons.com", "fa", "PER") +class WebtoonsTranslateUK : WebtoonsTranslate("Webtoons.com Translations", "https://translate.webtoons.com", "uk", "UKR") +class WebtoonsTranslateES : WebtoonsTranslate("Webtoons.com Translations", "https://translate.webtoons.com", "es", "SPA") + + diff --git a/src/all/webtoons/src/eu/kanade/tachiyomi/extension/all/webtoons/Webtoons.kt b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/webtoons/Webtoons.kt similarity index 75% rename from src/all/webtoons/src/eu/kanade/tachiyomi/extension/all/webtoons/Webtoons.kt rename to multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/webtoons/Webtoons.kt index d6b9ee6bd..109c81048 100644 --- a/src/all/webtoons/src/eu/kanade/tachiyomi/extension/all/webtoons/Webtoons.kt +++ b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/webtoons/Webtoons.kt @@ -1,12 +1,10 @@ -package eu.kanade.tachiyomi.extension.all.webtoons +package eu.kanade.tachiyomi.multisrc.webtoons import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.source.model.Filter.Header import eu.kanade.tachiyomi.source.model.Filter.Select import eu.kanade.tachiyomi.source.model.Filter.Separator import eu.kanade.tachiyomi.source.model.FilterList -import eu.kanade.tachiyomi.source.model.MangasPage -import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.online.ParsedHttpSource import eu.kanade.tachiyomi.util.asJsoup import okhttp3.Cookie @@ -16,20 +14,26 @@ import okhttp3.HttpUrl import okhttp3.OkHttpClient import okhttp3.Request import okhttp3.Response +import org.json.JSONObject import org.jsoup.nodes.Document import org.jsoup.nodes.Element +import java.text.SimpleDateFormat +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.model.MangasPage +import java.util.Locale import java.util.Calendar -abstract class Webtoons( +open class Webtoons( + override val name: String, + override val baseUrl: String, override val lang: String, open val langCode: String = lang, - open val localeForCookie: String = lang + open val localeForCookie: String = lang, + private val dateFormat: SimpleDateFormat = SimpleDateFormat("MMM d, yyyy", Locale.ENGLISH) ) : ParsedHttpSource() { - override val name = "Webtoons.com" - - override val baseUrl = "https://www.webtoons.com" - override val supportsLatest = true override val client: OkHttpClient = super.client.newBuilder() @@ -178,6 +182,8 @@ abstract class Webtoons( ) } + override fun chapterListSelector() = "ul#_episodeList li[id*=episode]" + private class SearchType(vals: Array>) : UriPartFilter("Official or Challenge", vals) private fun getOfficialList() = arrayOf( @@ -190,4 +196,48 @@ abstract class Webtoons( Select(displayName, vals.map { it.first }.toTypedArray()) { fun toUriPart() = vals[state].second } + + 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 { chapterParseDate(it) } ?: 0 + return chapter + } + + open fun chapterParseDate(date: String): Long { + return dateFormat.parse(date)?.time ?: 0 + } + override fun chapterListRequest(manga: SManga) = GET("https://m.webtoons.com" + manga.url, mobileHeaders) + + override fun pageListParse(document: Document): List { + val pages = document.select("div#_imageList > img").mapIndexed { i, element -> Page(i, "", element.attr("data-url")) } + + if (pages.isNotEmpty()) { return pages } + + val docString = document.toString() + + val docUrlRegex = Regex("documentURL:.*?'(.*?)'") + val motiontoonPathRegex = Regex("jpg:.*?'(.*?)\\{") + + val docUrl = docUrlRegex.find(docString)!!.destructured.toList()[0] + val motiontoonPath = motiontoonPathRegex.find(docString)!!.destructured.toList()[0] + + val motiontoonJson = JSONObject(client.newCall(GET(docUrl, headers)).execute().body()!!.string()).getJSONObject("assets").getJSONObject("image") + + val keys = motiontoonJson.keys().asSequence().toList().filter { it.contains("layer") } + + return keys.mapIndexed { i, key -> + Page(i, "", motiontoonPath + motiontoonJson.getString(key)) + } + } } diff --git a/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/webtoons/WebtoonsGenerator.kt b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/webtoons/WebtoonsGenerator.kt new file mode 100644 index 000000000..07159bf77 --- /dev/null +++ b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/webtoons/WebtoonsGenerator.kt @@ -0,0 +1,26 @@ +package eu.kanade.tachiyomi.multisrc.webtoons + +import generator.ThemeSourceData.SingleLang +import generator.ThemeSourceData.MultiLang +import generator.ThemeSourceGenerator + +class WebtoonsGenerator : ThemeSourceGenerator { + + override val themePkg = "webtoons" + + override val themeClass = "Webtoons" + + override val baseVersionCode: Int = 1 + + override val sources = listOf( + MultiLang("Webtoons.com", "https://www.webtoons.com", listOf("en", "fr", "es", "id", "th", "zh"), className = "WebtoonsFactory", pkgName = "webtoons", overrideVersionCode = 26), + SingleLang("Dongman Manhua", "https://www.dongmanmanhua.cn", "zh") + ) + + companion object { + @JvmStatic + fun main(args: Array) { + WebtoonsGenerator().createAll() + } + } +} diff --git a/src/all/webtoons/src/eu/kanade/tachiyomi/extension/all/webtoons/WebtoonsTranslate.kt b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/webtoons/WebtoonsTranslate.kt similarity index 97% rename from src/all/webtoons/src/eu/kanade/tachiyomi/extension/all/webtoons/WebtoonsTranslate.kt rename to multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/webtoons/WebtoonsTranslate.kt index 5aa474723..dfb7749e5 100644 --- a/src/all/webtoons/src/eu/kanade/tachiyomi/extension/all/webtoons/WebtoonsTranslate.kt +++ b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/webtoons/WebtoonsTranslate.kt @@ -1,4 +1,4 @@ -package eu.kanade.tachiyomi.extension.all.webtoons +package eu.kanade.tachiyomi.multisrc.webtoons import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.asObservableSuccess @@ -17,7 +17,12 @@ import org.jsoup.nodes.Element import rx.Observable import java.util.ArrayList -open class WebtoonsTranslate(override val lang: String, private val translateLangCode: String, languageNameExtra: String = "") : Webtoons(lang) { +open class WebtoonsTranslate ( + override val name: String, + override val baseUrl: String, + override val lang: String, + private val translateLangCode: String + ) : Webtoons(name, baseUrl, lang) { // popularMangaRequest already returns manga sorted by latest update override val supportsLatest = false @@ -29,7 +34,6 @@ open class WebtoonsTranslate(override val lang: String, private val translateLan private val pageSize = 24 - override val name = "Webtoons.com Translations$languageNameExtra" override fun headersBuilder(): Headers.Builder = super.headersBuilder() .removeAll("Referer") diff --git a/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/webtoons/WebtoonsTranslateGenerator.kt b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/webtoons/WebtoonsTranslateGenerator.kt new file mode 100644 index 000000000..0e6ae24de --- /dev/null +++ b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/webtoons/WebtoonsTranslateGenerator.kt @@ -0,0 +1,24 @@ +package eu.kanade.tachiyomi.multisrc.webtoons + +import generator.ThemeSourceData.SingleLang +import generator.ThemeSourceData.MultiLang +import generator.ThemeSourceGenerator + +class WebtoonsTranslateGenerator : ThemeSourceGenerator { + override val themePkg = "webtoons" + + override val themeClass = "WebtoonsTranslation" + + override val baseVersionCode: Int = 1 + + override val sources = listOf( + MultiLang("Webtoons.com Translations", "https://translate.webtoons.com", listOf("en", "zh-hans", "zh-hant", "th", "id", "fr", "vi", "ru", "ar", "fil", "de", "hi", "it", "ja", "pt-br", "tr", "ms", "pl", "pt", "bg", "da", "nl", "ro", "mn", "el", "lt", "cs", "sv", "bn", "fa", "uk", "es"), className = "WebtoonsTranslateFactory", pkgName = "webtoonstranslate"), + ) + + companion object { + @JvmStatic + fun main(args: Array) { + WebtoonsTranslateGenerator().createAll() + } + } +} diff --git a/src/all/webtoons/AndroidManifest.xml b/src/all/webtoons/AndroidManifest.xml deleted file mode 100644 index 30deb7f79..000000000 --- a/src/all/webtoons/AndroidManifest.xml +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/src/all/webtoons/build.gradle b/src/all/webtoons/build.gradle deleted file mode 100644 index 465283baf..000000000 --- a/src/all/webtoons/build.gradle +++ /dev/null @@ -1,12 +0,0 @@ -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' - -ext { - extName = 'Webtoons' - pkgNameSuffix = 'all.webtoons' - extClass = '.WebtoonsFactory' - extVersionCode = 26 - libVersion = '1.2' -} - -apply from: "$rootDir/common.gradle" diff --git a/src/all/webtoons/src/eu/kanade/tachiyomi/extension/all/webtoons/WebtoonsDefault.kt b/src/all/webtoons/src/eu/kanade/tachiyomi/extension/all/webtoons/WebtoonsDefault.kt deleted file mode 100644 index 3811e7d74..000000000 --- a/src/all/webtoons/src/eu/kanade/tachiyomi/extension/all/webtoons/WebtoonsDefault.kt +++ /dev/null @@ -1,66 +0,0 @@ -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.json.JSONObject -import org.jsoup.nodes.Document -import org.jsoup.nodes.Element -import java.text.SimpleDateFormat -import java.util.Locale - -open class WebtoonsDefault( - override val lang: String, - override val langCode: String = lang, - override val localeForCookie: String = lang, - private val dateFormat: SimpleDateFormat = SimpleDateFormat("MMM d, yyyy", Locale.ENGLISH) -) : Webtoons(lang, langCode, 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 { chapterParseDate(it) } ?: 0 - return chapter - } - - open fun chapterParseDate(date: String): Long { - return dateFormat.parse(date)?.time ?: 0 - } - - override fun chapterListRequest(manga: SManga) = GET("https://m.webtoons.com" + manga.url, mobileHeaders) - - override fun pageListParse(document: Document): List { - val pages = document.select("div#_imageList > img").mapIndexed { i, element -> Page(i, "", element.attr("data-url")) } - - if (pages.isNotEmpty()) { return pages } - - val docString = document.toString() - - val docUrlRegex = Regex("documentURL:.*?'(.*?)'") - val motiontoonPathRegex = Regex("jpg:.*?'(.*?)\\{") - - val docUrl = docUrlRegex.find(docString)!!.destructured.toList()[0] - val motiontoonPath = motiontoonPathRegex.find(docString)!!.destructured.toList()[0] - - val motiontoonJson = JSONObject(client.newCall(GET(docUrl, headers)).execute().body()!!.string()).getJSONObject("assets").getJSONObject("image") - - val keys = motiontoonJson.keys().asSequence().toList().filter { it.contains("layer") } - - return keys.mapIndexed { i, key -> - Page(i, "", motiontoonPath + motiontoonJson.getString(key)) - } - } -} diff --git a/src/all/webtoons/src/eu/kanade/tachiyomi/extension/all/webtoons/WebtoonsFactory.kt b/src/all/webtoons/src/eu/kanade/tachiyomi/extension/all/webtoons/WebtoonsFactory.kt deleted file mode 100644 index 6c8a8abf0..000000000 --- a/src/all/webtoons/src/eu/kanade/tachiyomi/extension/all/webtoons/WebtoonsFactory.kt +++ /dev/null @@ -1,93 +0,0 @@ -package eu.kanade.tachiyomi.extension.all.webtoons - -import eu.kanade.tachiyomi.source.Source -import eu.kanade.tachiyomi.source.SourceFactory -import java.text.SimpleDateFormat -import java.util.GregorianCalendar -import java.util.Locale - -class WebtoonsFactory : SourceFactory { - override fun createSources(): List = listOf( - WebtoonsEnglish(), - WebtoonsChineseTraditional(), - WebtoonsIndonesian(), - WebtoonsThai(), - WebtoonsFr(), - WebtoonsEs(), - DongmanManhua(), - - // Fan translations - WebtoonsTranslate("en", "ENG"), - WebtoonsTranslate("zh", "CMN", " (Simplified)"), - WebtoonsTranslate("zh", "CMT", " (Traditional)"), - WebtoonsTranslate("th", "THA"), - WebtoonsTranslate("id", "IND"), - WebtoonsTranslate("fr", "FRA"), - WebtoonsTranslate("vi", "VIE"), - WebtoonsTranslate("ru", "RUS"), - WebtoonsTranslate("ar", "ARA"), - WebtoonsTranslate("fil", "FIL"), - WebtoonsTranslate("de", "DEU"), - WebtoonsTranslate("hi", "HIN"), - WebtoonsTranslate("it", "ITA"), - WebtoonsTranslate("ja", "JPN"), - WebtoonsTranslate("pt", "POR", " (Brazilian)"), - WebtoonsTranslate("tr", "TUR"), - WebtoonsTranslate("ms", "MAY"), - WebtoonsTranslate("pl", "POL"), - WebtoonsTranslate("pt", "POT", " (European)"), - WebtoonsTranslate("bg", "BUL"), - WebtoonsTranslate("da", "DAN"), - WebtoonsTranslate("nl", "NLD"), - WebtoonsTranslate("ro", "RON"), - WebtoonsTranslate("mn", "MON"), - WebtoonsTranslate("el", "GRE"), - WebtoonsTranslate("lt", "LIT"), - WebtoonsTranslate("cs", "CES"), - WebtoonsTranslate("sv", "SWE"), - WebtoonsTranslate("bn", "BEN"), - WebtoonsTranslate("fa", "PER"), - WebtoonsTranslate("uk", "UKR"), - WebtoonsTranslate("es", "SPA") - ) -} - -class WebtoonsEnglish : WebtoonsDefault("en") - -class WebtoonsIndonesian : WebtoonsDefault("id") { - override val name: String = "Webtoons.com (Indonesian)" - - // Android seems to be unable to parse Indonesian dates; we'll use a short hard-coded table - // instead. - private val dateMap: Array = arrayOf( - "Jan", "Feb", "Mar", "Apr", "Mei", "Jun", "Jul", "Agu", "Sep", "Okt", "Nov", "Des" - ) - - override fun chapterParseDate(date: String): Long { - val expr = Regex("""(\d{4}) ([A-Z][a-z]{2}) (\d+)""").find(date) ?: return 0 - val (_, year, monthString, day) = expr.groupValues - val monthIndex = dateMap.indexOf(monthString) - return GregorianCalendar(year.toInt(), monthIndex, day.toInt()).time.time - } -} - -class WebtoonsThai : WebtoonsDefault("th", dateFormat = SimpleDateFormat("d MMM yyyy", Locale("th"))) - -class WebtoonsChineseTraditional : WebtoonsDefault("zh", "zh-hant", "zh_TW", SimpleDateFormat("yyyy/MM/dd", Locale.TRADITIONAL_CHINESE)) - -class WebtoonsFr : WebtoonsDefault("fr", dateFormat = SimpleDateFormat("d MMM yyyy", Locale.FRENCH)) - -class WebtoonsEs : WebtoonsDefault("es") { - // Android seems to be unable to parse es dates like Indonesian; we'll use a short hard-coded table - // instead. - private val dateMap: Array = arrayOf( - "Ene", "Feb", "Mar", "Abr", "May", "Jun", "Jul", "Ago", "Sep", "Oct", "Nov", "Dic" - ) - - override fun chapterParseDate(date: String): Long { - val expr = Regex("""(\d+)-([a-z]{3})-(\d{4})""").find(date) ?: return 0 - val (_, day, monthString, year) = expr.groupValues - val monthIndex = dateMap.indexOf(monthString) - return GregorianCalendar(year.toInt(), monthIndex, day.toInt()).time.time - } -}