Initial commit

This commit is contained in:
FourTOne5
2024-01-09 04:12:39 +06:00
commit 600c345dfe
8593 changed files with 150590 additions and 0 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

View File

@@ -0,0 +1,62 @@
package eu.kanade.tachiyomi.extension.zh.dongmanmanhua
import eu.kanade.tachiyomi.multisrc.webtoons.Webtoons
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.Headers
import okhttp3.Request
import okhttp3.Response
import org.jsoup.nodes.Document
import org.jsoup.nodes.Element
import java.text.SimpleDateFormat
import java.util.Locale
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")
.add("Referer", baseUrl)
override fun popularMangaRequest(page: Int) = GET("$baseUrl/dailySchedule", headers)
override fun latestUpdatesRequest(page: Int) = GET("$baseUrl/dailySchedule?sortOrder=UPDATE&webtoonCompleteType=ONGOING", headers)
override fun parseDetailsThumbnail(document: Document): String? {
return document.select("div.detail_body").attr("style").substringAfter("(").substringBefore(")")
}
override fun chapterListRequest(manga: SManga): Request = GET(baseUrl + manga.url, headers)
override fun chapterListSelector() = "ul#_listUl li"
override fun chapterListParse(response: Response): List<SChapter> {
var document = response.asJsoup()
var continueParsing = true
val chapters = mutableListOf<SChapter>()
while (continueParsing) {
document.select(chapterListSelector()).map { chapters.add(chapterFromElement(it)) }
document.select("div.paginate a[onclick] + a").let { element ->
if (element.isNotEmpty()) {
document = client.newCall(GET(element.attr("abs:href"), headers)).execute().asJsoup()
} else {
continueParsing = false
}
}
}
return chapters
}
override fun chapterFromElement(element: Element): SChapter {
return SChapter.create().apply {
name = element.select("span.subj span").text()
url = element.select("a").attr("href").substringAfter(".cn")
date_upload = chapterParseDate(element.select("span.date").text())
}
}
override fun getFilterList(): FilterList = FilterList()
}

View File

@@ -0,0 +1,43 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application>
<activity
android:name="eu.kanade.tachiyomi.multisrc.webtoons.WebtoonsUrlActivity"
android:excludeFromRecents="true"
android:exported="true"
android:theme="@android:style/Theme.NoDisplay">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="webtoons.com"
android:pathPattern="/.*/.*/.*/..*"
android:scheme="https" />
<data
android:host="www.webtoons.com"
android:pathPattern="/.*/.*/.*/..*"
android:scheme="https" />
<data
android:host="m.webtoons.com"
android:pathPattern="/.*/.*/.*/..*"
android:scheme="https" />
<data
android:host="webtoons.com"
android:pathPattern="/.*/.*/.*/.*/..*"
android:scheme="https" />
<data
android:host="www.webtoons.com"
android:pathPattern="/.*/.*/.*/.*/..*"
android:scheme="https" />
<data
android:host="m.webtoons.com"
android:pathPattern="/.*/.*/.*/.*/..*"
android:scheme="https" />
</intent-filter>
</activity>
</application>
</manifest>

View File

@@ -0,0 +1,3 @@
dependencies {
implementation(project(':lib-textinterceptor'))
}

View File

@@ -0,0 +1,66 @@
package eu.kanade.tachiyomi.extension.all.webtoons
import eu.kanade.tachiyomi.source.Source
import eu.kanade.tachiyomi.source.SourceFactory
import eu.kanade.tachiyomi.source.model.SManga
import java.text.SimpleDateFormat
import java.util.GregorianCalendar
import java.util.Locale
class WebtoonsFactory : SourceFactory {
override fun createSources(): List<Source> = listOf(
WebtoonsEN(),
WebtoonsID(),
WebtoonsTH(),
WebtoonsES(),
WebtoonsFR(),
WebtoonsZH(),
WebtoonsDE(),
)
}
class WebtoonsEN : WebtoonsSrc("Webtoons.com", "https://www.webtoons.com", "en")
class WebtoonsID : WebtoonsSrc("Webtoons.com", "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<String> = 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 : WebtoonsSrc("Webtoons.com", "https://www.webtoons.com", "th", dateFormat = SimpleDateFormat("d MMM yyyy", Locale("th")))
class WebtoonsES : WebtoonsSrc("Webtoons.com", "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<String> = arrayOf(
"ene", "feb", "mar", "abr", "may", "jun", "jul", "ago", "sep", "oct", "nov", "dic",
)
override fun chapterParseDate(date: String): Long {
val expr = Regex("""(\d+)-([A-Za-z]{3})-(\d{4})""").find(date) ?: return 0
val (_, day, monthString, year) = expr.groupValues
val monthIndex = dateMap.indexOf(monthString.lowercase(Locale("es")))
return GregorianCalendar(year.toInt(), monthIndex, day.toInt()).time.time
}
}
class WebtoonsFR : WebtoonsSrc("Webtoons.com", "https://www.webtoons.com", "fr", dateFormat = SimpleDateFormat("d MMM yyyy", Locale.FRENCH)) {
override fun String.toStatus(): Int = when {
contains("NOUVEAU") -> SManga.ONGOING
contains("TERMINÉ") -> SManga.COMPLETED
else -> SManga.UNKNOWN
}
}
class WebtoonsZH : WebtoonsSrc("Webtoons.com", "https://www.webtoons.com", "zh-Hant", "zh-hant", "zh_TW", SimpleDateFormat("yyyy/MM/dd", Locale.TRADITIONAL_CHINESE)) {
// Due to lang code getting more specific
override val id: Long = 2959982438613576472
}
class WebtoonsDE : WebtoonsSrc("Webtoons.com", "https://www.webtoons.com", "de", dateFormat = SimpleDateFormat("dd.MM.yyyy", Locale.GERMAN))

View File

@@ -0,0 +1,97 @@
package eu.kanade.tachiyomi.extension.all.webtoons
import android.app.Application
import android.content.SharedPreferences
import androidx.preference.PreferenceScreen
import androidx.preference.SwitchPreferenceCompat
import eu.kanade.tachiyomi.lib.textinterceptor.TextInterceptor
import eu.kanade.tachiyomi.lib.textinterceptor.TextInterceptorHelper
import eu.kanade.tachiyomi.multisrc.webtoons.Webtoons
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.source.ConfigurableSource
import eu.kanade.tachiyomi.source.model.Page
import kotlinx.serialization.json.jsonObject
import kotlinx.serialization.json.jsonPrimitive
import okhttp3.OkHttpClient
import org.jsoup.nodes.Document
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import java.text.SimpleDateFormat
import java.util.Locale
open class WebtoonsSrc(
override val name: String,
override val baseUrl: String,
override val lang: String,
langCode: String = lang,
override val localeForCookie: String = lang,
dateFormat: SimpleDateFormat = SimpleDateFormat("MMM d, yyyy", Locale.ENGLISH),
) : ConfigurableSource, Webtoons(name, baseUrl, lang, langCode, localeForCookie, dateFormat) {
override val client: OkHttpClient = super.client.newBuilder()
.addInterceptor(TextInterceptor())
.build()
private val preferences: SharedPreferences by lazy {
Injekt.get<Application>().getSharedPreferences("source_$id", 0x0000)
}
override fun setupPreferenceScreen(screen: PreferenceScreen) {
val authorsNotesPref = SwitchPreferenceCompat(screen.context).apply {
key = SHOW_AUTHORS_NOTES_KEY
title = "Show author's notes"
summary = "Enable to see the author's notes at the end of chapters (if they're there)."
setDefaultValue(false)
setOnPreferenceChangeListener { _, newValue ->
val checkValue = newValue as Boolean
preferences.edit().putBoolean(SHOW_AUTHORS_NOTES_KEY, checkValue).commit()
}
}
screen.addPreference(authorsNotesPref)
}
private fun showAuthorsNotesPref() = preferences.getBoolean(SHOW_AUTHORS_NOTES_KEY, false)
override fun pageListParse(document: Document): List<Page> {
var pages = document.select("div#_imageList > img").mapIndexed { i, element -> Page(i, "", element.attr("data-url")) }
if (showAuthorsNotesPref()) {
val note = document.select("div.creator_note p.author_text").text()
if (note.isNotEmpty()) {
val creator = document.select("div.creator_note a.author_name span").text().trim()
pages = pages + Page(
pages.size,
"",
TextInterceptorHelper.createUrl(creator, note),
)
}
}
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 motiontoonResponse = client.newCall(GET(docUrl, headers)).execute()
val motiontoonJson = json.parseToJsonElement(motiontoonResponse.body.string()).jsonObject
val motiontoonImages = motiontoonJson["assets"]!!.jsonObject["image"]!!.jsonObject
return motiontoonImages.entries
.filter { it.key.contains("layer") }
.mapIndexed { i, entry ->
Page(i, "", motiontoonPath + entry.value.jsonPrimitive.content)
}
}
companion object {
private const val SHOW_AUTHORS_NOTES_KEY = "showAuthorsNotes"
}
}

View File

@@ -0,0 +1,83 @@
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<Source> = 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") {
// Hardcode the id because the language code was wrong.
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")