Compare commits

..

No commits in common. "d61cbfc0c18a50f7b9805c3dfc01d102f69e353d" and "c353c9a78007329827ba41b637cb160005e0fcf7" have entirely different histories.

683 changed files with 2333 additions and 2944 deletions

View File

@ -7,4 +7,3 @@ Checklist:
- [ ] Have not changed source names - [ ] Have not changed source names
- [ ] Have explicitly kept the `id` if a source's name or language were changed - [ ] Have explicitly kept the `id` if a source's name or language were changed
- [ ] Have tested the modifications by compiling and running the extension through Android Studio - [ ] Have tested the modifications by compiling and running the extension through Android Studio
- [ ] Have removed `web_hi_res_512.png` when adding a new extension

View File

@ -37,8 +37,8 @@ jobs:
- name: Set up JDK - name: Set up JDK
uses: actions/setup-java@v3 uses: actions/setup-java@v3
with: with:
java-version: 17 java-version: 11
distribution: temurin distribution: adopt
- name: Prepare signing key - name: Prepare signing key
run: | run: |
@ -82,8 +82,8 @@ jobs:
- name: Set up JDK - name: Set up JDK
uses: actions/setup-java@v3 uses: actions/setup-java@v3
with: with:
java-version: 17 java-version: 11
distribution: temurin distribution: adopt
- name: Prepare signing key - name: Prepare signing key
run: | run: |
@ -125,7 +125,7 @@ jobs:
uses: actions/setup-java@v3 uses: actions/setup-java@v3
with: with:
java-version: 17 java-version: 17
distribution: temurin distribution: adopt
- name: Checkout master branch - name: Checkout master branch
uses: actions/checkout@v4 uses: actions/checkout@v4

View File

@ -6,54 +6,31 @@ This guide is not definitive and it's being updated over time. If you find any i
## Table of Contents ## Table of Contents
- [Contributing](#contributing) 1. [Prerequisites](#prerequisites)
- [Table of Contents](#table-of-contents) 1. [Tools](#tools)
- [Prerequisites](#prerequisites) 2. [Cloning the repository](#cloning-the-repository)
- [Tools](#tools) 2. [Getting help](#getting-help)
- [Cloning the repository](#cloning-the-repository) 3. [Writing an extension](#writing-an-extension)
- [Getting help](#getting-help) 1. [Setting up a new Gradle module](#setting-up-a-new-gradle-module)
- [Writing an extension](#writing-an-extension) 2. [Core dependencies](#core-dependencies)
- [Setting up a new Gradle module](#setting-up-a-new-gradle-module) 3. [Extension main class](#extension-main-class)
- [Loading a subset of Gradle modules](#loading-a-subset-of-gradle-modules) 4. [Extension call flow](#extension-call-flow)
- [Extension file structure](#extension-file-structure) 5. [Misc notes](#misc-notes)
- [AndroidManifest.xml](#androidmanifestxml) 6. [Advanced extension features](#advanced-extension-features)
- [build.gradle](#buildgradle) 4. [Multi-source themes](#multi-source-themes)
- [Core dependencies](#core-dependencies) 1. [The directory structure](#the-directory-structure)
- [Extension API](#extension-api) 2. [Development workflow](#development-workflow)
- [DataImage library](#dataimage-library) 3. [Scaffolding overrides](#scaffolding-overrides)
- [i18n library](#i18n-library) 4. [Additional Notes](#additional-notes)
- [Additional dependencies](#additional-dependencies) 5. [Running](#running)
- [Extension main class](#extension-main-class) 6. [Debugging](#debugging)
- [Main class key variables](#main-class-key-variables) 1. [Android Debugger](#android-debugger)
- [Extension call flow](#extension-call-flow) 2. [Logs](#logs)
- [Popular Manga](#popular-manga) 3. [Inspecting network calls](#inspecting-network-calls)
- [Latest Manga](#latest-manga) 4. [Using external network inspecting tools](#using-external-network-inspecting-tools)
- [Manga Search](#manga-search) 7. [Building](#building)
- [Filters](#filters) 8. [Submitting the changes](#submitting-the-changes)
- [Manga Details](#manga-details) 1. [Pull Request checklist](#pull-request-checklist)
- [Chapter](#chapter)
- [Chapter Pages](#chapter-pages)
- [Misc notes](#misc-notes)
- [Advanced Extension features](#advanced-extension-features)
- [URL intent filter](#url-intent-filter)
- [Update strategy](#update-strategy)
- [Renaming existing sources](#renaming-existing-sources)
- [Multi-source themes](#multi-source-themes)
- [The directory structure](#the-directory-structure)
- [Development workflow](#development-workflow)
- [Scaffolding overrides](#scaffolding-overrides)
- [Additional Notes](#additional-notes)
- [Running](#running)
- [Debugging](#debugging)
- [Android Debugger](#android-debugger)
- [Logs](#logs)
- [Inspecting network calls](#inspecting-network-calls)
- [Using external network inspecting tools](#using-external-network-inspecting-tools)
- [Setup your proxy server](#setup-your-proxy-server)
- [OkHttp proxy setup](#okhttp-proxy-setup)
- [Building](#building)
- [Submitting the changes](#submitting-the-changes)
- [Pull Request checklist](#pull-request-checklist)
## Prerequisites ## Prerequisites
@ -224,8 +201,9 @@ src/<lang>/<mysourcename>/
│   │   └── ic_launcher.png │   │   └── ic_launcher.png
│   ├── mipmap-xxhdpi │   ├── mipmap-xxhdpi
│   │   └── ic_launcher.png │   │   └── ic_launcher.png
│   └── mipmap-xxxhdpi │   ├── mipmap-xxxhdpi
│      └── ic_launcher.png │   │   └── ic_launcher.png
│   └── web_hi_res_512.png
└── src └── src
└── eu └── eu
└── kanade └── kanade
@ -245,6 +223,9 @@ A minimal [Android manifest file](https://developer.android.com/guide/topics/man
Make sure that your new extension's `build.gradle` file follows the following structure: Make sure that your new extension's `build.gradle` file follows the following structure:
```gradle ```gradle
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
ext { ext {
extName = '<My source name>' extName = '<My source name>'
pkgNameSuffix = '<lang>.<mysourcename>' pkgNameSuffix = '<lang>.<mysourcename>'
@ -434,15 +415,10 @@ open class UriPartFilter(displayName: String, private val vals: Array<Pair<Strin
### Misc notes ### Misc notes
- Sometimes you may find no use for some inherited methods. If so just override them and throw - Sometimes you may find no use for some inherited methods. If so just override them and throw exceptions: `throw UnsupportedOperationException("Not used.")`
exceptions: `throw UnsupportedOperationException()` - You probably will find `getUrlWithoutDomain` useful when parsing the target source URLs. Keep in mind there's a current issue with spaces in the URL though, so if you use it, replace all spaces with URL encoded characters (like `%20`).
- You probably will find `getUrlWithoutDomain` useful when parsing the target source URLs. Keep in - If possible try to stick to the general workflow from `HttpSource`/`ParsedHttpSource`; breaking them may cause you more headache than necessary.
mind there's a current issue with spaces in the URL though, so if you use it, replace all spaces with - By implementing `ConfigurableSource` you can add settings to your source, which is backed by [`SharedPreferences`](https://developer.android.com/reference/android/content/SharedPreferences).
URL encoded characters (like `%20`).
- If possible try to stick to the general workflow from `HttpSource`/`ParsedHttpSource`; breaking
them may cause you more headache than necessary.
- By implementing `ConfigurableSource` you can add settings to your source, which is backed by
[`SharedPreferences`](https://developer.android.com/reference/android/content/SharedPreferences).
### Advanced Extension features ### Advanced Extension features
@ -519,8 +495,9 @@ multisrc
│   │   │   └── ic_launcher.png │   │   │   └── ic_launcher.png
│   │   ├── mipmap-xxhdpi │   │   ├── mipmap-xxhdpi
│   │   │   └── ic_launcher.png │   │   │   └── ic_launcher.png
│   │   └── mipmap-xxxhdpi │   │   ├── mipmap-xxxhdpi
│   │      └── ic_launcher.png │   │   │   └── ic_launcher.png
│   │   └── web_hi_res_512.png
│   └── <sourcepkg> │   └── <sourcepkg>
│   ├── additional.gradle │   ├── additional.gradle
│   ├── AndroidManifest.xml │   ├── AndroidManifest.xml
@ -533,8 +510,9 @@ multisrc
│   │   │   └── ic_launcher.png │   │   │   └── ic_launcher.png
│   │   ├── mipmap-xxhdpi │   │   ├── mipmap-xxhdpi
│   │   │   └── ic_launcher.png │   │   │   └── ic_launcher.png
│   │   └── mipmap-xxxhdpi │   │   ├── mipmap-xxxhdpi
│   │      └── ic_launcher.png │   │   │   └── ic_launcher.png
│   │   └── web_hi_res_512.png
│   └── src │   └── src
│   └── <SourceName>.kt │   └── <SourceName>.kt
└── src └── src
@ -761,9 +739,7 @@ When you feel confident about your changes, submit a new Pull Request so your co
If you are more comfortable about using Git GUI-based tools, you can refer to [this guide](https://learntodroid.com/how-to-use-git-and-github-in-android-studio/) about the Git integration inside Android Studio, specifically the "How to Contribute to an to Existing Git Repository in Android Studio" section of the guide. If you are more comfortable about using Git GUI-based tools, you can refer to [this guide](https://learntodroid.com/how-to-use-git-and-github-in-android-studio/) about the Git integration inside Android Studio, specifically the "How to Contribute to an to Existing Git Repository in Android Studio" section of the guide.
> [!IMPORTANT] > [!IMPORTANT]
> Make sure you have generated the extension icon using the linked Icon Generator tool in the [Tools](#tools) > Make sure you have generated the extension icon using the linked Icon Generator tool in the [Tools](#tools) section. The icon **must follow the pattern** adopted by all other extensions: a square with rounded corners.
> section. The icon **must follow the pattern** adopted by all other extensions: a square with rounded
> corners. Make sure to remove the generated `web_hi_res_512.png`.
Please **do test your changes by compiling it through Android Studio** before submitting it. Obvious untested PRs will not be merged, such as ones created with the GitHub web interface. Also make sure to follow the PR checklist available in the PR body field when creating a new PR. As a reference, you can find it below. Please **do test your changes by compiling it through Android Studio** before submitting it. Obvious untested PRs will not be merged, such as ones created with the GitHub web interface. Also make sure to follow the PR checklist available in the PR body field when creating a new PR. As a reference, you can find it below.

View File

@ -1,6 +1,3 @@
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlinx-serialization'
apply plugin: 'org.jmailen.kotlinter' apply plugin: 'org.jmailen.kotlinter'
android { android {
@ -28,9 +25,7 @@ android {
applicationIdSuffix pkgNameSuffix applicationIdSuffix pkgNameSuffix
versionCode extVersionCode versionCode extVersionCode
versionName project.ext.properties.getOrDefault("libVersion", "1.4") + ".$extVersionCode" versionName project.ext.properties.getOrDefault("libVersion", "1.4") + ".$extVersionCode"
base { setProperty("archivesBaseName", "tachiyomi-$pkgNameSuffix-v$versionName")
archivesName = "tachiyomi-$pkgNameSuffix-v$versionName"
}
def readmes = project.projectDir.listFiles({ File file -> def readmes = project.projectDir.listFiles({ File file ->
file.name == "README.md" || file.name == "CHANGELOG.md" file.name == "README.md" || file.name == "CHANGELOG.md"
} as FileFilter) } as FileFilter)
@ -76,7 +71,6 @@ android {
renderScript false renderScript false
resValues false resValues false
shaders false shaders false
buildConfig true
} }
compileOptions { compileOptions {

View File

@ -9,7 +9,7 @@ android {
minSdk = AndroidConfig.minSdk minSdk = AndroidConfig.minSdk
} }
namespace = "eu.kanade.tachiyomi.extension.core" namespace = "eu.kanade.tachiyomi.extension"
@Suppress("UnstableApiUsage") @Suppress("UnstableApiUsage")
sourceSets { sourceSets {

View File

@ -21,5 +21,3 @@ org.gradle.caching=true
# Enable AndroidX dependencies # Enable AndroidX dependencies
android.useAndroidX=true android.useAndroidX=true
android.nonTransitiveRClass=false
android.nonFinalResIds=false

View File

@ -4,7 +4,7 @@ coroutines_version = "1.6.4"
serialization_version = "1.4.0" serialization_version = "1.4.0"
[libraries] [libraries]
gradle-agp = { module = "com.android.tools.build:gradle", version = "8.2.1" } gradle-agp = { module = "com.android.tools.build:gradle", version = "7.4.2" }
gradle-kotlin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin_version" } gradle-kotlin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin_version" }
gradle-serialization = { module = "org.jetbrains.kotlin:kotlin-serialization", version.ref = "kotlin_version" } gradle-serialization = { module = "org.jetbrains.kotlin:kotlin-serialization", version.ref = "kotlin_version" }
gradle-kotlinter = { module = "org.jmailen.gradle:kotlinter-gradle", version = "3.13.0" } gradle-kotlinter = { module = "org.jmailen.gradle:kotlinter-gradle", version = "3.13.0" }

View File

@ -1,68 +0,0 @@
package eu.kanade.tachiyomi.extension.tr.mangatr
import android.webkit.CookieManager
import eu.kanade.tachiyomi.network.GET
import okhttp3.Cookie
import okhttp3.HttpUrl
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.Response
// Taken from src/all/akuma.
class DDoSGuardInterceptor(private val client: OkHttpClient) : Interceptor {
private val cookieManager by lazy { CookieManager.getInstance() }
override fun intercept(chain: Interceptor.Chain): Response {
val originalRequest = chain.request()
val response = chain.proceed(originalRequest)
// Check if DDos-GUARD is on
if (response.code !in ERROR_CODES || response.header("Server") !in SERVER_CHECK) {
return response
}
val cookies = cookieManager.getCookie(originalRequest.url.toString())
val oldCookie = if (cookies != null && cookies.isNotEmpty()) {
cookies.split(";").mapNotNull { Cookie.parse(originalRequest.url, it) }
} else {
emptyList()
}
val ddg2Cookie = oldCookie.firstOrNull { it.name == "__ddg2_" }
if (!ddg2Cookie?.value.isNullOrEmpty()) {
return response
}
response.close()
val newCookie = getNewCookie(originalRequest.url)
?: return chain.proceed(originalRequest)
val newCookieHeader = (oldCookie + newCookie)
.joinToString("; ") { "${it.name}=${it.value}" }
val modifiedRequest = originalRequest.newBuilder()
.header("cookie", newCookieHeader)
.build()
return chain.proceed(modifiedRequest)
}
private fun getNewCookie(url: HttpUrl): Cookie? {
val wellKnown = client.newCall(GET(wellKnownUrl))
.execute().body.string()
.substringAfter("'", "")
.substringBefore("'", "")
val checkUrl = "${url.scheme}://${url.host + wellKnown}"
val response = client.newCall(GET(checkUrl)).execute()
return response.header("set-cookie")?.let {
Cookie.parse(url, it)
}
}
companion object {
private const val wellKnownUrl = "https://check.ddos-guard.net/check.js"
private val ERROR_CODES = listOf(403)
private val SERVER_CHECK = listOf("ddos-guard")
}
}

View File

@ -19,15 +19,6 @@ class MangaTR : FMReader("Manga-TR", "https://manga-tr.com", "tr") {
override fun headersBuilder() = super.headersBuilder() override fun headersBuilder() = super.headersBuilder()
.add("Accept-Language", "en-US,en;q=0.5") .add("Accept-Language", "en-US,en;q=0.5")
override val client by lazy {
super.client.newBuilder()
.addInterceptor(DDoSGuardInterceptor(super.client))
.build()
}
override val requestPath = "manga-list-sayfala.html"
// ============================== Popular ===============================
override fun popularMangaNextPageSelector() = "div.btn-group:not(div.btn-block) button.btn-info" override fun popularMangaNextPageSelector() = "div.btn-group:not(div.btn-block) button.btn-info"
// =============================== Search =============================== // =============================== Search ===============================

View File

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

Before

Width:  |  Height:  |  Size: 8.6 KiB

After

Width:  |  Height:  |  Size: 8.6 KiB

View File

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View File

@ -1,9 +0,0 @@
package eu.kanade.tachiyomi.extension.en.luxmanga
import eu.kanade.tachiyomi.multisrc.madara.Madara
class LuxManga : Madara("LuxManga", "https://luxmanga.net", "en") {
override val useNewChapterEndpoint = false
override fun searchPage(page: Int): String = if (page == 1) "" else "page/$page/"
}

View File

@ -4,7 +4,6 @@ import eu.kanade.tachiyomi.multisrc.madara.Madara
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.interceptor.rateLimitHost import eu.kanade.tachiyomi.network.interceptor.rateLimitHost
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import okhttp3.CacheControl
import okhttp3.HttpUrl.Companion.toHttpUrl import okhttp3.HttpUrl.Companion.toHttpUrl
import okhttp3.Request import okhttp3.Request
import org.jsoup.nodes.Document import org.jsoup.nodes.Document
@ -24,47 +23,17 @@ class MangasNoSekai : Madara(
override val useNewChapterEndpoint = true override val useNewChapterEndpoint = true
override val mangaSubString = "manganews" override fun popularMangaRequest(page: Int): Request = GET("$baseUrl/${searchPage(page)}?s=&post_type=wp-manga&m_orderby=views", headers)
override fun popularMangaRequest(page: Int): Request { override fun popularMangaSelector() = searchMangaSelector()
return GET(
url = "$baseUrl/$mangaSubString/${searchPage(page)}?m_orderby=views",
headers = headers,
cache = CacheControl.FORCE_NETWORK,
)
}
override fun popularMangaSelector() = "div.page-listing-item > div.row > div" override fun popularMangaFromElement(element: Element) = searchMangaFromElement(element)
override val popularMangaUrlSelector = "a[href]" override fun latestUpdatesRequest(page: Int): Request = GET("$baseUrl/${searchPage(page)}?s=&post_type=wp-manga&m_orderby=latest", headers)
override fun popularMangaFromElement(element: Element): SManga { override fun latestUpdatesSelector() = searchMangaSelector()
val manga = SManga.create()
with(element) { override fun latestUpdatesFromElement(element: Element) = searchMangaFromElement(element)
select(popularMangaUrlSelector).first()?.let {
manga.setUrlWithoutDomain(it.attr("abs:href"))
}
select("figcaption").first()?.let {
manga.title = it.text()
}
select("img").first()?.let {
manga.thumbnail_url = imageFromElement(it)
}
}
return manga
}
override fun latestUpdatesRequest(page: Int): Request {
return GET(
url = "$baseUrl/$mangaSubString/${searchPage(page)}?m_orderby=latest",
headers = headers,
cache = CacheControl.FORCE_NETWORK,
)
}
override fun searchPage(page: Int): String { override fun searchPage(page: Int): String {
return if (page > 1) "page/$page/" else "" return if (page > 1) "page/$page/" else ""
@ -143,14 +112,4 @@ class MangasNoSekai : Madara(
return manga return manga
} }
override val orderByFilterOptionsValues: Array<String> = arrayOf(
"",
"latest2",
"alphabet",
"rating",
"trending",
"views2",
"new-manga",
)
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

View File

@ -1,24 +0,0 @@
package eu.kanade.tachiyomi.extension.pt.nexoscans
import eu.kanade.tachiyomi.multisrc.madara.Madara
import eu.kanade.tachiyomi.network.interceptor.rateLimit
import okhttp3.OkHttpClient
import java.text.SimpleDateFormat
import java.util.Locale
import java.util.concurrent.TimeUnit
class NexoScans : Madara(
"Nexo Scans",
"https://nexoscans.com",
"pt-BR",
SimpleDateFormat("dd/MM/yyyy", Locale.US),
) {
override val client: OkHttpClient = super.client.newBuilder()
.rateLimit(1, 2, TimeUnit.SECONDS)
.build()
override val useNewChapterEndpoint = true
override val chapterUrlSelector = "a:not(div.chapter-thumbnail a)"
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

View File

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

View File

@ -1,28 +1,11 @@
package eu.kanade.tachiyomi.extension.id.shinigami package eu.kanade.tachiyomi.extension.id.shinigami
import android.app.Application
import android.content.SharedPreferences
import android.util.Base64
import android.widget.Toast
import androidx.preference.EditTextPreference
import androidx.preference.PreferenceScreen
import eu.kanade.tachiyomi.lib.cryptoaes.CryptoAES
import eu.kanade.tachiyomi.lib.synchrony.Deobfuscator
import eu.kanade.tachiyomi.multisrc.madara.Madara import eu.kanade.tachiyomi.multisrc.madara.Madara
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.interceptor.rateLimit
import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter import eu.kanade.tachiyomi.source.model.SChapter
import kotlinx.serialization.Serializable
import kotlinx.serialization.decodeFromString
import okhttp3.Headers import okhttp3.Headers
import okhttp3.Interceptor
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Response
import org.jsoup.nodes.Document
import org.jsoup.nodes.Element import org.jsoup.nodes.Element
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import java.io.IOException
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
class Shinigami : Madara("Shinigami", "https://shinigamitoon.com", "id") { class Shinigami : Madara("Shinigami", "https://shinigamitoon.com", "id") {
@ -33,91 +16,15 @@ class Shinigami : Madara("Shinigami", "https://shinigamitoon.com", "id") {
override fun searchPage(page: Int): String = if (page == 1) "" else "page/$page/" override fun searchPage(page: Int): String = if (page == 1) "" else "page/$page/"
private val preferences: SharedPreferences by lazy { override val client: OkHttpClient = super.client.newBuilder()
Injekt.get<Application>().getSharedPreferences("source_$id", 0x0000) .rateLimit(4, 1, TimeUnit.SECONDS)
}
private val encodedString = "AAA AaAAAAH QAAAB0 AAAAcA AAAHMAA AA6AAA ALwAAAC8AA " + "AB0AAAAYQA AAGM AAADoAAAAaQAAAH kAAABvAA AAbQAAA GkAAABvAAAA cgAAAGcAAAAuAAA AZwAAAGk " + "AAAB0AAAA aAAAAHUAA ABiAAAALgAAAGkAA ABvAAAAL wAAAHUAAABzA AAAZQAAAHIAAAAtA AAAYQAAAGcA " + "AABlyAtAAAbgA AAHQAAAB6AAAA LwAAAHUAAA BcAAAAZQ AAAHIAAAAtAAA AYQAAAGcAAABl AAAAbgAA AHQAAAB6AAAALgAAAG" + " oAhAntUAABzAA AAbwAAAG4="
private val tachiUaUrl = Base64.decode(encodedString.replace("\\s".toRegex(), "").replace("DoA", "BoA").replace("GoAhAntU", "GoA").replace("BlyAt", "BlA").replace("BcA", "BzA"), Base64.DEFAULT).toString(Charsets.UTF_32).replace("z", "s")
private var secChUaMP: List<String>? = null
private var userAgent: String? = null
private var checkedUa = false
private val uaIntercept = object : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
val customUa = preferences.getString(PREF_KEY_CUSTOM_UA, "")
try {
if (customUa!!.isNotBlank()) userAgent = customUa
if (userAgent.isNullOrBlank() && checkedUa.not()) {
val uaResponse = chain.proceed(GET(tachiUaUrl))
if (uaResponse.isSuccessful) {
val parseTachiUa = uaResponse.use { json.decodeFromString<TachiUaResponse>(it.body.string()) }
var listUserAgentString = parseTachiUa.desktop + parseTachiUa.mobile
listUserAgentString = listUserAgentString!!.filter {
listOf("windows", "android").any { filter ->
it.contains(filter, ignoreCase = true)
}
}
userAgent = listUserAgentString!!.random()
checkedUa = true
}
uaResponse.close()
}
if (userAgent.isNullOrBlank().not()) {
secChUaMP = if (userAgent!!.contains("Windows")) {
listOf("?0", "Windows")
} else {
listOf("?1", "Android")
}
val newRequest = chain.request().newBuilder()
.header("User-Agent", userAgent!!.trim())
.header("Sec-CH-UA-Mobile", secChUaMP!![0])
.header("Sec-CH-UA-Platform", secChUaMP!![1])
.removeHeader("X-Requested-With")
.build()
return chain.proceed(newRequest)
}
return chain.proceed(chain.request())
} catch (e: Exception) {
throw IOException(e.message)
}
}
}
@Serializable
data class TachiUaResponse(
val desktop: List<String> = emptyList(),
val mobile: List<String> = emptyList(),
)
// disable random ua in ext setting from multisrc (.setRandomUserAgent)
override val client: OkHttpClient = network.cloudflareClient.newBuilder()
.addInterceptor(uaIntercept)
.connectTimeout(10, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.build() .build()
override fun headersBuilder(): Headers.Builder { override fun headersBuilder(): Headers.Builder = super.headersBuilder()
val builder = super.headersBuilder() .add("Sec-Fetch-Dest", "document")
.add("Sec-Fetch-Dest", "document") .add("Sec-Fetch-Mode", "navigate")
.add("Sec-Fetch-Mode", "navigate") .add("Sec-Fetch-Site", "same-origin")
.add("Sec-Fetch-Site", "same-origin") .add("Upgrade-Insecure-Requests", "1")
.add("Upgrade-Insecure-Requests", "1")
.add("X-Requested-With", "") // added for webview, and removed in interceptor for normal use
// used to flush tachi custom ua in webview and use system ua instead
if (userAgent.isNullOrBlank()) builder.removeAll("User-Agent")
return builder
}
override val mangaSubString = "semua-series" override val mangaSubString = "semua-series"
@ -136,76 +43,4 @@ class Shinigami : Madara("Shinigami", "https://shinigamitoon.com", "id") {
setUrlWithoutDomain(fixedUrl) setUrlWithoutDomain(fixedUrl)
} }
// Page list
@Serializable
data class CDT(val ct: String, val s: String)
override fun pageListParse(document: Document): List<Page> {
val script = document.selectFirst("script:containsData(chapter_data)")?.data()
?: throw Exception("chapter_data script not found")
val deobfuscated = Deobfuscator.deobfuscateScript(script)
?: throw Exception("Unable to deobfuscate chapter_data script")
val postId = script.substringAfter("var post_id = '").substringBefore("'")
val chapterData = json.decodeFromString<CDT>(
script.substringAfter("var chapter_data = '").substringBefore("'"),
)
val keyMatch = KEY_REGEX.find(deobfuscated)!!.groupValues
val key = postId + keyMatch[1] + postId + keyMatch[2] + postId
val salt = chapterData.s.decodeHex()
val unsaltedCiphertext = Base64.decode(chapterData.ct, Base64.DEFAULT)
val ciphertext = SALTED + salt + unsaltedCiphertext
val decrypted = CryptoAES.decrypt(Base64.encodeToString(ciphertext, Base64.DEFAULT), key)
val data = json.decodeFromString<List<String>>(decrypted)
return data.mapIndexed { idx, it ->
Page(idx, document.location(), it)
}
}
// https://stackoverflow.com/a/66614516
private fun String.decodeHex(): ByteArray {
check(length % 2 == 0) { "Must have an even length" }
return chunked(2)
.map { it.toInt(16).toByte() }
.toByteArray()
}
// remove random ua in setting ext from multisrc and use custom one
override fun setupPreferenceScreen(screen: PreferenceScreen) {
val prefCustomUserAgent = EditTextPreference(screen.context).apply {
key = PREF_KEY_CUSTOM_UA
title = TITLE_CUSTOM_UA
summary = (preferences.getString(PREF_KEY_CUSTOM_UA, "")!!.trim() + SUMMARY_STRING_CUSTOM_UA).trim()
setOnPreferenceChangeListener { _, newValue ->
val customUa = newValue as String
preferences.edit().putString(PREF_KEY_CUSTOM_UA, customUa).apply()
if (customUa.isNullOrBlank()) {
Toast.makeText(screen.context, RESTART_APP_STRING, Toast.LENGTH_LONG).show()
} else {
userAgent = null
}
summary = (customUa.trim() + SUMMARY_STRING2_CUSTOM_UA).trim()
true
}
}
screen.addPreference(prefCustomUserAgent)
}
companion object {
const val TITLE_CUSTOM_UA = "Custom User-Agent"
const val PREF_KEY_CUSTOM_UA = "pref_key_custom_ua"
const val SUMMARY_STRING_CUSTOM_UA = "\n\nBiarkan kosong untuk menggunakan User-Agent secara random"
const val SUMMARY_STRING2_CUSTOM_UA = "\n\nKosongkan untuk menggunakan User-Agent secara random"
const val RESTART_APP_STRING = "Restart Tachiyomi untuk menggunakan pengaturan baru."
private val KEY_REGEX by lazy { Regex("""post_id\s+\+\s+'(.*?)'\s+\+\s+post_id\s+\+\s+'(.*?)'\s+\+\s+post_id""") }
}
} }

View File

@ -1,15 +0,0 @@
package eu.kanade.tachiyomi.extension.es.tenkaiscan
import eu.kanade.tachiyomi.multisrc.madara.Madara
import java.text.SimpleDateFormat
import java.util.Locale
class TenkaiScan : Madara(
"TenkaiScan",
"https://tenkaiscan.net",
"es",
dateFormat = SimpleDateFormat("dd 'de' MMMM 'de' yyyy", Locale("es")),
) {
override val versionId = 2
override val useNewChapterEndpoint = true
override val mangaDetailsSelectorStatus = "div.post-content_item:contains(Status) > div.summary-content"
}

View File

@ -1,7 +1,6 @@
package eu.kanade.tachiyomi.extension.es.carteldemanhwas package eu.kanade.tachiyomi.extension.es.carteldemanhwas
import eu.kanade.tachiyomi.multisrc.mangathemesia.MangaThemesia import eu.kanade.tachiyomi.multisrc.mangathemesia.MangaThemesia
import org.jsoup.nodes.Element
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Locale import java.util.Locale
@ -15,13 +14,6 @@ class CarteldeManhwas : MangaThemesia(
override val hasProjectPage = true override val hasProjectPage = true
override val projectPageString = "/proyectos" override val projectPageString = "/proyectos"
override fun Element.imgAttr(): String = when {
hasAttr("data-lazy-src") -> attr("abs:data-lazy-src")
hasAttr("data-cfsrc") -> attr("abs:data-cfsrc")
hasAttr("data-src") -> attr("abs:data-src")
else -> attr("abs:src")
}
override fun searchMangaSelector() = ".utao .uta .imgu:not(:has(span.novelabel)), " + override fun searchMangaSelector() = ".utao .uta .imgu:not(:has(span.novelabel)), " +
".listupd .bs .bsx:not(:has(span.novelabel)), " + ".listupd .bs .bsx:not(:has(span.novelabel)), " +
".listo .bs .bsx:not(:has(span.novelabel))" ".listo .bs .bsx:not(:has(span.novelabel))"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

View File

@ -1,12 +0,0 @@
package eu.kanade.tachiyomi.extension.id.shirakami
import eu.kanade.tachiyomi.multisrc.mangathemesia.MangaThemesia
import java.text.SimpleDateFormat
import java.util.Locale
class Shirakami : MangaThemesia(
"Shirakami",
"https://shirakami.xyz",
"id",
dateFormat = SimpleDateFormat("MMMM dd, yyyy", Locale("id")),
)

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

View File

@ -0,0 +1,12 @@
package eu.kanade.tachiyomi.extension.es.tenkaiscan
import eu.kanade.tachiyomi.multisrc.mangathemesia.MangaThemesia
import java.text.SimpleDateFormat
import java.util.Locale
class TenkaiScan : MangaThemesia(
"TenkaiScan",
"https://tenkaiscan.net",
"es",
dateFormat = SimpleDateFormat("MMMM dd, yyyy", Locale("en")),
)

View File

@ -56,13 +56,13 @@ open class A3Manga(
override fun popularMangaNextPageSelector() = "li.next:not(.disabled)" override fun popularMangaNextPageSelector() = "li.next:not(.disabled)"
override fun latestUpdatesRequest(page: Int) = throw UnsupportedOperationException() override fun latestUpdatesRequest(page: Int) = throw UnsupportedOperationException("Not used")
override fun latestUpdatesSelector() = throw UnsupportedOperationException() override fun latestUpdatesSelector() = throw UnsupportedOperationException("Not used")
override fun latestUpdatesFromElement(element: Element) = throw UnsupportedOperationException() override fun latestUpdatesFromElement(element: Element) = throw UnsupportedOperationException("Not used")
override fun latestUpdatesNextPageSelector() = throw UnsupportedOperationException() override fun latestUpdatesNextPageSelector() = throw UnsupportedOperationException("Not used")
override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable<MangasPage> { override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable<MangasPage> {
return when { return when {
@ -92,11 +92,11 @@ open class A3Manga(
.build(), .build(),
) )
override fun searchMangaSelector(): String = throw UnsupportedOperationException() override fun searchMangaSelector(): String = throw UnsupportedOperationException("Not used")
override fun searchMangaFromElement(element: Element): SManga = throw UnsupportedOperationException() override fun searchMangaFromElement(element: Element): SManga = throw UnsupportedOperationException("Not used")
override fun searchMangaNextPageSelector() = throw UnsupportedOperationException() override fun searchMangaNextPageSelector() = throw UnsupportedOperationException("Not used")
override fun searchMangaParse(response: Response): MangasPage { override fun searchMangaParse(response: Response): MangasPage {
val dto = response.parseAs<SearchResponseDto>() val dto = response.parseAs<SearchResponseDto>()
@ -213,7 +213,7 @@ open class A3Manga(
} }
} }
override fun imageUrlParse(document: Document) = throw UnsupportedOperationException() override fun imageUrlParse(document: Document) = throw UnsupportedOperationException("Not used")
private inline fun <reified T> Response.parseAs(): T { private inline fun <reified T> Response.parseAs(): T {
return json.decodeFromString(body.string()) return json.decodeFromString(body.string())

View File

@ -134,35 +134,35 @@ abstract class BakkinReaderX(
} }
override fun searchMangaRequest(page: Int, query: String, filters: FilterList) = override fun searchMangaRequest(page: Int, query: String, filters: FilterList) =
throw UnsupportedOperationException() throw UnsupportedOperationException("Not used!")
override fun popularMangaRequest(page: Int) = override fun popularMangaRequest(page: Int) =
throw UnsupportedOperationException() throw UnsupportedOperationException("Not used!")
override fun latestUpdatesRequest(page: Int) = override fun latestUpdatesRequest(page: Int) =
throw UnsupportedOperationException() throw UnsupportedOperationException("Not used!")
override fun mangaDetailsRequest(manga: SManga) = override fun mangaDetailsRequest(manga: SManga) =
throw UnsupportedOperationException() throw UnsupportedOperationException("Not used!")
override fun searchMangaParse(response: Response) = override fun searchMangaParse(response: Response) =
throw UnsupportedOperationException() throw UnsupportedOperationException("Not used!")
override fun popularMangaParse(response: Response) = override fun popularMangaParse(response: Response) =
throw UnsupportedOperationException() throw UnsupportedOperationException("Not used!")
override fun latestUpdatesParse(response: Response) = override fun latestUpdatesParse(response: Response) =
throw UnsupportedOperationException() throw UnsupportedOperationException("Not used!")
override fun mangaDetailsParse(response: Response) = override fun mangaDetailsParse(response: Response) =
throw UnsupportedOperationException() throw UnsupportedOperationException("Not used!")
override fun chapterListParse(response: Response) = override fun chapterListParse(response: Response) =
throw UnsupportedOperationException() throw UnsupportedOperationException("Not used!")
override fun pageListParse(response: Response) = override fun pageListParse(response: Response) =
throw UnsupportedOperationException() throw UnsupportedOperationException("Not used!")
override fun imageUrlParse(response: Response) = override fun imageUrlParse(response: Response) =
throw UnsupportedOperationException() throw UnsupportedOperationException("Not used!")
} }

View File

@ -40,19 +40,19 @@ open class ComicGamma(
thumbnail_url = element.selectFirst(Evaluator.Tag("img"))!!.absUrl("src") thumbnail_url = element.selectFirst(Evaluator.Tag("img"))!!.absUrl("src")
} }
override fun latestUpdatesRequest(page: Int) = throw UnsupportedOperationException() override fun latestUpdatesRequest(page: Int) = throw UnsupportedOperationException("Not used.")
override fun latestUpdatesNextPageSelector() = throw UnsupportedOperationException() override fun latestUpdatesNextPageSelector() = throw UnsupportedOperationException("Not used.")
override fun latestUpdatesSelector() = throw UnsupportedOperationException() override fun latestUpdatesSelector() = throw UnsupportedOperationException("Not used.")
override fun latestUpdatesFromElement(element: Element) = throw UnsupportedOperationException() override fun latestUpdatesFromElement(element: Element) = throw UnsupportedOperationException("Not used.")
override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable<MangasPage> = override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable<MangasPage> =
fetchPopularManga(page).map { p -> MangasPage(p.mangas.filter { it.title.contains(query) }, false) } fetchPopularManga(page).map { p -> MangasPage(p.mangas.filter { it.title.contains(query) }, false) }
override fun searchMangaNextPageSelector() = throw UnsupportedOperationException() override fun searchMangaNextPageSelector() = throw UnsupportedOperationException("Not used.")
override fun searchMangaSelector() = throw UnsupportedOperationException() override fun searchMangaSelector() = throw UnsupportedOperationException("Not used.")
override fun searchMangaFromElement(element: Element) = throw UnsupportedOperationException() override fun searchMangaFromElement(element: Element) = throw UnsupportedOperationException("Not used.")
override fun searchMangaRequest(page: Int, query: String, filters: FilterList) = override fun searchMangaRequest(page: Int, query: String, filters: FilterList) =
throw UnsupportedOperationException() throw UnsupportedOperationException("Not used.")
override fun pageListParse(document: Document) = override fun pageListParse(document: Document) =
document.select("#content > div[data-ptimg]").mapIndexed { i, e -> document.select("#content > div[data-ptimg]").mapIndexed { i, e ->
@ -91,7 +91,7 @@ open class ComicGamma(
override fun pageListRequest(chapter: SChapter) = override fun pageListRequest(chapter: SChapter) =
GET(baseUrl + chapter.url.toNewChapterUrl(), headers) GET(baseUrl + chapter.url.toNewChapterUrl(), headers)
override fun imageUrlParse(document: Document) = throw UnsupportedOperationException() override fun imageUrlParse(document: Document) = throw UnsupportedOperationException("Not used.")
companion object { companion object {
internal fun SimpleDateFormat.parseJST(date: String) = parse(date)?.apply { internal fun SimpleDateFormat.parseJST(date: String) = parse(date)?.apply {

View File

@ -188,15 +188,15 @@ open class EroMuse(override val name: String, override val baseUrl: String) : Ht
override fun fetchPopularManga(page: Int): Observable<MangasPage> = fetchManga("$baseUrl/comics/album/Various-Authors", page, "") override fun fetchPopularManga(page: Int): Observable<MangasPage> = fetchManga("$baseUrl/comics/album/Various-Authors", page, "")
override fun popularMangaRequest(page: Int): Request = throw UnsupportedOperationException() override fun popularMangaRequest(page: Int): Request = throw UnsupportedOperationException("Not used")
override fun popularMangaParse(response: Response): MangasPage = throw UnsupportedOperationException() override fun popularMangaParse(response: Response): MangasPage = throw UnsupportedOperationException("Not used")
// Latest // Latest
override fun fetchLatestUpdates(page: Int): Observable<MangasPage> = fetchManga("$baseUrl/comics/album/Various-Authors?sort=date", page, "date") override fun fetchLatestUpdates(page: Int): Observable<MangasPage> = fetchManga("$baseUrl/comics/album/Various-Authors?sort=date", page, "date")
override fun latestUpdatesRequest(page: Int): Request = throw UnsupportedOperationException() override fun latestUpdatesRequest(page: Int): Request = throw UnsupportedOperationException("Not used")
override fun latestUpdatesParse(response: Response): MangasPage = throw UnsupportedOperationException() override fun latestUpdatesParse(response: Response): MangasPage = throw UnsupportedOperationException("Not used")
// Search // Search
@ -228,8 +228,8 @@ open class EroMuse(override val name: String, override val baseUrl: String) : Ht
.map { response -> parseManga(response.asJsoup()) } .map { response -> parseManga(response.asJsoup()) }
} }
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request = throw UnsupportedOperationException() override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request = throw UnsupportedOperationException("Not used")
override fun searchMangaParse(response: Response): MangasPage = throw UnsupportedOperationException() override fun searchMangaParse(response: Response): MangasPage = throw UnsupportedOperationException("Not used")
// Details // Details
@ -332,7 +332,7 @@ open class EroMuse(override val name: String, override val baseUrl: String) : Ht
return parsePages(response.asJsoup()) return parsePages(response.asJsoup())
} }
override fun imageUrlParse(response: Response): String = throw UnsupportedOperationException() override fun imageUrlParse(response: Response): String = throw UnsupportedOperationException("Not used")
// Filters // Filters

View File

@ -190,7 +190,7 @@ abstract class FansubsCat(
override fun pageListParse(response: Response): List<Page> = parsePageListFromJson(response) override fun pageListParse(response: Response): List<Page> = parsePageListFromJson(response)
override fun imageUrlParse(response: Response): String = override fun imageUrlParse(response: Response): String =
throw UnsupportedOperationException() throw UnsupportedOperationException("Not used")
// Filter // Filter
override fun getFilterList() = FilterList( override fun getFilterList() = FilterList(

View File

@ -263,7 +263,7 @@ abstract class FlixScans(
} }
} }
override fun imageUrlParse(response: Response) = throw UnsupportedOperationException() override fun imageUrlParse(response: Response) = throw UnsupportedOperationException("Not Used")
protected inline fun <reified T> Response.parseAs(): T = protected inline fun <reified T> Response.parseAs(): T =
use { body.string() }.let(json::decodeFromString) use { body.string() }.let(json::decodeFromString)

View File

@ -333,7 +333,7 @@ abstract class FMReader(
} }
} }
override fun imageUrlParse(document: Document): String = throw UnsupportedOperationException() override fun imageUrlParse(document: Document): String = throw UnsupportedOperationException("Not used")
private class TextField(name: String, val key: String) : Filter.Text(name) private class TextField(name: String, val key: String) : Filter.Text(name)
private class Status : Filter.Select<String>("Status", arrayOf("Any", "Completed", "Ongoing")) private class Status : Filter.Select<String>("Status", arrayOf("Any", "Completed", "Ongoing"))

View File

@ -14,7 +14,7 @@ class FMReaderGenerator : ThemeSourceGenerator {
override val sources = listOf( override val sources = listOf(
SingleLang("Epik Manga", "https://www.epikmanga.com", "tr"), SingleLang("Epik Manga", "https://www.epikmanga.com", "tr"),
SingleLang("KissLove", "https://klz9.com", "ja", isNsfw = true, overrideVersionCode = 4), SingleLang("KissLove", "https://klz9.com", "ja", isNsfw = true, overrideVersionCode = 4),
SingleLang("Manga-TR", "https://manga-tr.com", "tr", className = "MangaTR", overrideVersionCode = 3), SingleLang("Manga-TR", "https://manga-tr.com", "tr", className = "MangaTR", overrideVersionCode = 2),
SingleLang("ManhuaRock", "https://manhuarock.net", "vi", overrideVersionCode = 1), SingleLang("ManhuaRock", "https://manhuarock.net", "vi", overrideVersionCode = 1),
SingleLang("Say Truyen", "https://saytruyenvip.com", "vi", overrideVersionCode = 3), SingleLang("Say Truyen", "https://saytruyenvip.com", "vi", overrideVersionCode = 3),
SingleLang("WeLoveManga", "https://weloma.art", "ja", pkgName = "rawlh", isNsfw = true, overrideVersionCode = 5), SingleLang("WeLoveManga", "https://weloma.art", "ja", pkgName = "rawlh", isNsfw = true, overrideVersionCode = 5),

View File

@ -271,7 +271,7 @@ abstract class FoolSlide(
} }
} }
override fun imageUrlParse(document: Document) = throw UnsupportedOperationException() override fun imageUrlParse(document: Document) = throw UnsupportedOperationException("Not used")
protected val preferences by lazy { protected val preferences by lazy {
Injekt.get<Application>().getSharedPreferences("source_$id", 0x0000)!! Injekt.get<Application>().getSharedPreferences("source_$id", 0x0000)!!

View File

@ -255,7 +255,7 @@ abstract class GroupLe(
} }
override fun chapterFromElement(element: Element): SChapter { override fun chapterFromElement(element: Element): SChapter {
throw UnsupportedOperationException() throw Exception("Not used")
} }
override fun prepareNewChapter(chapter: SChapter, manga: SManga) { override fun prepareNewChapter(chapter: SChapter, manga: SManga) {
@ -288,11 +288,6 @@ abstract class GroupLe(
var readerMark = "rm_h.readerDoInit([" var readerMark = "rm_h.readerDoInit(["
// allhentai necessary
if (!html.contains(readerMark)) {
readerMark = "rm_h.readerInit( 0,["
}
if (!html.contains(readerMark)) { if (!html.contains(readerMark)) {
if (document.select(".input-lg").isNotEmpty() || (document.select(".user-avatar").isNullOrEmpty() && document.select("img.logo").first()?.attr("title")?.contains("Allhentai") == true)) { if (document.select(".input-lg").isNotEmpty() || (document.select(".user-avatar").isNullOrEmpty() && document.select("img.logo").first()?.attr("title")?.contains("Allhentai") == true)) {
throw Exception("Для просмотра контента необходима авторизация через WebView\uD83C\uDF0E") throw Exception("Для просмотра контента необходима авторизация через WebView\uD83C\uDF0E")

View File

@ -9,7 +9,7 @@ class GroupLeGenerator : ThemeSourceGenerator {
override val themeClass = "GroupLe" override val themeClass = "GroupLe"
override val baseVersionCode = 22 override val baseVersionCode = 21
override val sources = listOf( override val sources = listOf(
SingleLang("ReadManga", "https://readmanga.live", "ru", overrideVersionCode = 46), SingleLang("ReadManga", "https://readmanga.live", "ru", overrideVersionCode = 46),

View File

@ -455,7 +455,7 @@ abstract class Guya(
// ----------------- Things we aren't supporting ----------------- // ----------------- Things we aren't supporting -----------------
override fun mangaDetailsParse(response: Response): SManga { override fun mangaDetailsParse(response: Response): SManga {
throw UnsupportedOperationException() throw UnsupportedOperationException("Unused")
} }
override fun chapterListParse(response: Response): List<SChapter> { override fun chapterListParse(response: Response): List<SChapter> {
@ -467,11 +467,11 @@ abstract class Guya(
} }
override fun searchMangaParse(response: Response): MangasPage { override fun searchMangaParse(response: Response): MangasPage {
throw UnsupportedOperationException() throw UnsupportedOperationException("Unused.")
} }
override fun imageUrlParse(response: Response): String { override fun imageUrlParse(response: Response): String {
throw UnsupportedOperationException() throw UnsupportedOperationException("Unused.")
} }
companion object { companion object {

View File

@ -274,7 +274,7 @@ abstract class HentaiHand(
Page(index, "", imgUrl) Page(index, "", imgUrl)
} }
override fun imageUrlParse(response: Response): String = throw UnsupportedOperationException() override fun imageUrlParse(response: Response): String = throw UnsupportedOperationException("Not used")
// Authorization // Authorization

View File

@ -123,7 +123,7 @@ abstract class LibGroup(
.build() .build()
// Latest // Latest
override fun latestUpdatesRequest(page: Int) = throw UnsupportedOperationException() // popularMangaRequest() override fun latestUpdatesRequest(page: Int) = throw UnsupportedOperationException("Not used") // popularMangaRequest()
override fun fetchLatestUpdates(page: Int): Observable<MangasPage> { override fun fetchLatestUpdates(page: Int): Observable<MangasPage> {
if (csrfToken.isEmpty()) { if (csrfToken.isEmpty()) {
return client.newCall(popularMangaRequest(page)) return client.newCall(popularMangaRequest(page))

View File

@ -285,7 +285,7 @@ abstract class Madara(
else -> arrayOf("Completed", "Ongoing", "Canceled", "On Hold") else -> arrayOf("Completed", "Ongoing", "Canceled", "On Hold")
} }
protected open val statusFilterOptionsValues: Array<String> = arrayOf( protected val statusFilterOptionsValues: Array<String> = arrayOf(
"end", "end",
"on-going", "on-going",
"canceled", "canceled",
@ -318,7 +318,7 @@ abstract class Madara(
) )
} }
protected open val orderByFilterOptionsValues: Array<String> = arrayOf( protected val orderByFilterOptionsValues: Array<String> = arrayOf(
"", "",
"latest", "latest",
"alphabet", "alphabet",

View File

@ -65,6 +65,7 @@ class MadaraGenerator : ThemeSourceGenerator {
SingleLang("Cat300", "https://cat300.com", "th", isNsfw = true, className = "Cat300", overrideVersionCode = 1), SingleLang("Cat300", "https://cat300.com", "th", isNsfw = true, className = "Cat300", overrideVersionCode = 1),
SingleLang("CatOnHeadTranslations", "https://catonhead.com", "en", overrideVersionCode = 2), SingleLang("CatOnHeadTranslations", "https://catonhead.com", "en", overrideVersionCode = 2),
SingleLang("Cerise Scan", "https://cerisescan.com", "pt-BR", pkgName = "cerisescans", isNsfw = true, overrideVersionCode = 7), SingleLang("Cerise Scan", "https://cerisescan.com", "pt-BR", pkgName = "cerisescans", isNsfw = true, overrideVersionCode = 7),
SingleLang("Çizgi Roman Arşivi", "https://cizgiromanarsivi.com", "tr", className = "CizgiRomanArsivi"),
SingleLang("Clover Manga", "https://clover-manga.com", "tr", overrideVersionCode = 2), SingleLang("Clover Manga", "https://clover-manga.com", "tr", overrideVersionCode = 2),
SingleLang("Coco Rip", "https://cocorip.net", "es"), SingleLang("Coco Rip", "https://cocorip.net", "es"),
SingleLang("Coffee Manga", "https://coffeemanga.io", "en", isNsfw = false, overrideVersionCode = 2), SingleLang("Coffee Manga", "https://coffeemanga.io", "en", isNsfw = false, overrideVersionCode = 2),
@ -192,7 +193,7 @@ class MadaraGenerator : ThemeSourceGenerator {
SingleLang("Lolicon", "https://lolicon.mobi", "en", isNsfw = true, overrideVersionCode = 2), SingleLang("Lolicon", "https://lolicon.mobi", "en", isNsfw = true, overrideVersionCode = 2),
SingleLang("Lord Manga", "https://lordmanga.com", "en"), SingleLang("Lord Manga", "https://lordmanga.com", "en"),
SingleLang("Luffy Manga", "https://luffymanga.com", "en", isNsfw = false), SingleLang("Luffy Manga", "https://luffymanga.com", "en", isNsfw = false),
SingleLang("LuxManga", "https://luxmanga.net", "en", isNsfw = true, overrideVersionCode = 1), SingleLang("LuxManga", "https://luxmanga.com", "en"),
SingleLang("MadaraDex", "https://madaradex.org", "en", isNsfw = true, overrideVersionCode = 1), SingleLang("MadaraDex", "https://madaradex.org", "en", isNsfw = true, overrideVersionCode = 1),
SingleLang("Maid Scan", "https://maidscan.com.br", "pt-BR"), SingleLang("Maid Scan", "https://maidscan.com.br", "pt-BR"),
SingleLang("Manga 18h", "https://manga18h.com", "en", isNsfw = true), SingleLang("Manga 18h", "https://manga18h.com", "en", isNsfw = true),
@ -213,22 +214,23 @@ class MadaraGenerator : ThemeSourceGenerator {
SingleLang("Manga Lord", "https://mangalord.com", "en", overrideVersionCode = 1), SingleLang("Manga Lord", "https://mangalord.com", "en", overrideVersionCode = 1),
SingleLang("Manga Mammy", "https://mangamammy.ru", "ru", isNsfw = true), SingleLang("Manga Mammy", "https://mangamammy.ru", "ru", isNsfw = true),
SingleLang("Manga Mitsu", "https://mangamitsu.com", "en", isNsfw = true, overrideVersionCode = 2), SingleLang("Manga Mitsu", "https://mangamitsu.com", "en", isNsfw = true, overrideVersionCode = 2),
SingleLang("Mangá Nanquim", "https://mangananquim.com", "pt-BR", className = "MangaNanquim"),
SingleLang("Manga Nerds", "https://manganerds.com", "en", isNsfw = false), SingleLang("Manga Nerds", "https://manganerds.com", "en", isNsfw = false),
SingleLang("Manga One Love", "https://mangaonelove.site/", "ru", isNsfw = true), SingleLang("Manga One Love", "https://mangaonelove.site/", "ru", isNsfw = true),
SingleLang("Manga Online Team", "https://mangaonlineteam.com", "en"), SingleLang("Manga Online Team", "https://mangaonlineteam.com", "en"),
SingleLang("Manga Queen", "https://mangaqueen.net", "en"),
SingleLang("Manga Queen.com", "https://mangaqueen.com", "en", isNsfw = true, className = "MangaQueenCom"), SingleLang("Manga Queen.com", "https://mangaqueen.com", "en", isNsfw = true, className = "MangaQueenCom"),
SingleLang("Manga Queen.online (unoriginal)", "https://mangaqueen.online", "en", isNsfw = true, className = "MangaQueenOnline"), SingleLang("Manga Queen.online (unoriginal)", "https://mangaqueen.online", "en", isNsfw = true, className = "MangaQueenOnline"),
SingleLang("Manga Queen", "https://mangaqueen.net", "en"),
SingleLang("Manga Read", "https://mangaread.co", "en", overrideVersionCode = 1), SingleLang("Manga Read", "https://mangaread.co", "en", overrideVersionCode = 1),
SingleLang("Manga Rock Team", "https://mangarockteam.com", "en", overrideVersionCode = 1), SingleLang("Manga Rock Team", "https://mangarockteam.com", "en", overrideVersionCode = 1),
SingleLang("Manga Rock.team (unoriginal)", "https://mangarock.team", "en", isNsfw = false, className = "MangaRockTeamUnoriginal"), SingleLang("Manga Rock.team (unoriginal)", "https://mangarock.team", "en", isNsfw = false, className = "MangaRockTeamUnoriginal"),
SingleLang("Manga Rocky", "https://mangarocky.com", "en", overrideVersionCode = 1), SingleLang("Manga Rocky", "https://mangarocky.com", "en", overrideVersionCode = 1),
SingleLang("Manga Rose", "https://mangarose.net", "ar"), SingleLang("Manga Rose", "https://mangarose.net", "ar"),
SingleLang("Manga Şehri", "https://manga-sehri.com", "tr", className = "MangaSehri", isNsfw = true, overrideVersionCode = 1),
SingleLang("Manga Starz", "https://mangastarz.org", "ar", overrideVersionCode = 5), SingleLang("Manga Starz", "https://mangastarz.org", "ar", overrideVersionCode = 5),
SingleLang("Manga Too", "https://mangatoo.com", "en", overrideVersionCode = 1), SingleLang("Manga Too", "https://mangatoo.com", "en", overrideVersionCode = 1),
SingleLang("Manga Tx.gg (unoriginal)", "https://mangatx.gg", "en", isNsfw = false, className = "MangaTxGg"), SingleLang("Manga Tx.gg (unoriginal)", "https://mangatx.gg", "en", isNsfw = false, className = "MangaTxGg"),
SingleLang("Manga Weebs", "https://mangaweebs.in", "en", overrideVersionCode = 8), SingleLang("Manga Weebs", "https://mangaweebs.in", "en", overrideVersionCode = 8),
SingleLang("Manga Şehri", "https://manga-sehri.com", "tr", className = "MangaSehri", isNsfw = true, overrideVersionCode = 1),
SingleLang("Manga-1001.com", "https://manga-1001.com", "en", isNsfw = false, className = "MangaDash1001Com"), SingleLang("Manga-1001.com", "https://manga-1001.com", "en", isNsfw = false, className = "MangaDash1001Com"),
SingleLang("Manga-fast.com", "https://manga-fast.com", "en", className = "Mangafastcom", overrideVersionCode = 3), SingleLang("Manga-fast.com", "https://manga-fast.com", "en", className = "Mangafastcom", overrideVersionCode = 3),
SingleLang("Manga-Raw.info (unoriginal)", "https://manga-raw.info", "en", isNsfw = true, className = "MangaRawInfo"), SingleLang("Manga-Raw.info (unoriginal)", "https://manga-raw.info", "en", isNsfw = true, className = "MangaRawInfo"),
@ -242,8 +244,8 @@ class MadaraGenerator : ThemeSourceGenerator {
SingleLang("MangaBaz", "https://mangabaz.net", "en"), SingleLang("MangaBaz", "https://mangabaz.net", "en"),
SingleLang("MangaBob", "https://mangabob.com", "en", overrideVersionCode = 1), SingleLang("MangaBob", "https://mangabob.com", "en", overrideVersionCode = 1),
SingleLang("MangaCC", "https://mangacc.com", "en"), SingleLang("MangaCC", "https://mangacc.com", "en"),
SingleLang("MangaClash", "https://mangaclash.com", "en", overrideVersionCode = 3),
SingleLang("MangaClash.tv (unoriginal)", "https://mangaclash.tv", "en", isNsfw = true, className = "MangaClashTv"), SingleLang("MangaClash.tv (unoriginal)", "https://mangaclash.tv", "en", isNsfw = true, className = "MangaClashTv"),
SingleLang("MangaClash", "https://mangaclash.com", "en", overrideVersionCode = 3),
SingleLang("MangaCrazy", "https://mangacrazy.net", "all", isNsfw = true), SingleLang("MangaCrazy", "https://mangacrazy.net", "all", isNsfw = true),
SingleLang("MangaCultivator", "https://mangacultivator.com", "en", overrideVersionCode = 2), SingleLang("MangaCultivator", "https://mangacultivator.com", "en", overrideVersionCode = 2),
SingleLang("MangaCV", "https://mangacv.com", "en", isNsfw = true), SingleLang("MangaCV", "https://mangacv.com", "en", isNsfw = true),
@ -285,7 +287,7 @@ class MadaraGenerator : ThemeSourceGenerator {
SingleLang("MangaRosie", "https://mangarosie.in", "en", isNsfw = true), SingleLang("MangaRosie", "https://mangarosie.in", "en", isNsfw = true),
SingleLang("MangaRuby.com", "https://mangaruby.com", "en", isNsfw = true, className = "MangaRubyCom"), SingleLang("MangaRuby.com", "https://mangaruby.com", "en", isNsfw = true, className = "MangaRubyCom"),
SingleLang("Mangaryu", "https://mangaryu.com", "en", isNsfw = true), SingleLang("Mangaryu", "https://mangaryu.com", "en", isNsfw = true),
SingleLang("Mangas No Sekai", "https://mangasnosekai.com", "es", overrideVersionCode = 2), SingleLang("Mangas No Sekai", "https://mangasnosekai.com", "es", overrideVersionCode = 1),
SingleLang("Mangas Origines", "https://mangas-origines.xyz", "fr", isNsfw = true, overrideVersionCode = 4), SingleLang("Mangas Origines", "https://mangas-origines.xyz", "fr", isNsfw = true, overrideVersionCode = 4),
SingleLang("Mangas-Origines.fr", "https://mangas-origines.fr", "fr", className = "MangasOriginesFr"), SingleLang("Mangas-Origines.fr", "https://mangas-origines.fr", "fr", className = "MangasOriginesFr"),
SingleLang("MangaSco", "https://manhwasco.net", "en", overrideVersionCode = 2), SingleLang("MangaSco", "https://manhwasco.net", "en", overrideVersionCode = 2),
@ -305,7 +307,6 @@ class MadaraGenerator : ThemeSourceGenerator {
SingleLang("Mangaxico", "https://mangaxico.com", "es", isNsfw = true), SingleLang("Mangaxico", "https://mangaxico.com", "es", isNsfw = true),
SingleLang("MangaXP", "https://mangaxp.com", "en", overrideVersionCode = 1), SingleLang("MangaXP", "https://mangaxp.com", "en", overrideVersionCode = 1),
SingleLang("MangaYami", "https://www.mangayami.club", "en", overrideVersionCode = 2), SingleLang("MangaYami", "https://www.mangayami.club", "en", overrideVersionCode = 2),
SingleLang("Mangá Nanquim", "https://mangananquim.com", "pt-BR", className = "MangaNanquim"),
SingleLang("Manhastro", "https://manhastro.com", "pt-BR"), SingleLang("Manhastro", "https://manhastro.com", "pt-BR"),
SingleLang("Manhatic", "https://manhatic.com", "ar", isNsfw = true), SingleLang("Manhatic", "https://manhatic.com", "ar", isNsfw = true),
SingleLang("Manhua ES", "https://manhuaes.com", "en", overrideVersionCode = 6), SingleLang("Manhua ES", "https://manhuaes.com", "en", overrideVersionCode = 6),
@ -318,12 +319,12 @@ class MadaraGenerator : ThemeSourceGenerator {
SingleLang("ManhuaBox", "https://manhuabox.net", "en", overrideVersionCode = 2), SingleLang("ManhuaBox", "https://manhuabox.net", "en", overrideVersionCode = 2),
SingleLang("ManhuaChill", "https://manhuachill.com", "en"), SingleLang("ManhuaChill", "https://manhuachill.com", "en"),
SingleLang("ManhuaDex", "https://manhuadex.com", "en", isNsfw = false), SingleLang("ManhuaDex", "https://manhuadex.com", "en", isNsfw = false),
SingleLang("ManhuaFast", "https://manhuafast.com", "en", overrideVersionCode = 3),
SingleLang("ManhuaFast.net (unoriginal)", "https://manhuafast.net", "en", isNsfw = false, className = "ManhuaFastNet"), SingleLang("ManhuaFast.net (unoriginal)", "https://manhuafast.net", "en", isNsfw = false, className = "ManhuaFastNet"),
SingleLang("ManhuaFast", "https://manhuafast.com", "en", overrideVersionCode = 3),
SingleLang("Manhuaga", "https://manhuaga.com", "en", overrideVersionCode = 2), SingleLang("Manhuaga", "https://manhuaga.com", "en", overrideVersionCode = 2),
SingleLang("ManhuaHot", "https://manhuahot.com", "en"), SingleLang("ManhuaHot", "https://manhuahot.com", "en"),
SingleLang("ManhuaManhwa", "https://manhuamanhwa.com", "en", isNsfw = true),
SingleLang("ManhuaManhwa.online", "https://manhuamanhwa.online", "en", isNsfw = false, className = "ManhuaManhwaOnline"), SingleLang("ManhuaManhwa.online", "https://manhuamanhwa.online", "en", isNsfw = false, className = "ManhuaManhwaOnline"),
SingleLang("ManhuaManhwa", "https://manhuamanhwa.com", "en", isNsfw = true),
SingleLang("ManhuaScan.info (unoriginal)", "https://manhuascan.info", "en", isNsfw = true, className = "ManhuaScanInfo"), SingleLang("ManhuaScan.info (unoriginal)", "https://manhuascan.info", "en", isNsfw = true, className = "ManhuaScanInfo"),
SingleLang("ManhuaUS", "https://manhuaus.com", "en", overrideVersionCode = 5), SingleLang("ManhuaUS", "https://manhuaus.com", "en", overrideVersionCode = 5),
SingleLang("ManhuaZone", "https://manhuazone.org", "en", overrideVersionCode = 1), SingleLang("ManhuaZone", "https://manhuazone.org", "en", overrideVersionCode = 1),
@ -348,8 +349,8 @@ class MadaraGenerator : ThemeSourceGenerator {
SingleLang("Mantraz Scan", "https://mantrazscan.com", "es"), SingleLang("Mantraz Scan", "https://mantrazscan.com", "es"),
SingleLang("ManWe", "https://manwe.pro", "tr", className = "EvaScans", overrideVersionCode = 1), SingleLang("ManWe", "https://manwe.pro", "tr", className = "EvaScans", overrideVersionCode = 1),
SingleLang("ManyComic", "https://manycomic.com", "en", isNsfw = true, overrideVersionCode = 1), SingleLang("ManyComic", "https://manycomic.com", "en", isNsfw = true, overrideVersionCode = 1),
SingleLang("ManyToon", "https://manytoon.com", "en", isNsfw = true, overrideVersionCode = 5),
SingleLang("ManyToon.me", "https://manytoon.me", "en", isNsfw = true, className = "ManyToonMe", overrideVersionCode = 5), SingleLang("ManyToon.me", "https://manytoon.me", "en", isNsfw = true, className = "ManyToonMe", overrideVersionCode = 5),
SingleLang("ManyToon", "https://manytoon.com", "en", isNsfw = true, overrideVersionCode = 5),
SingleLang("ManyToonClub", "https://manytoon.club", "ko", isNsfw = true, overrideVersionCode = 2), SingleLang("ManyToonClub", "https://manytoon.club", "ko", isNsfw = true, overrideVersionCode = 2),
SingleLang("MG Komik", "https://mgkomik.id", "id", overrideVersionCode = 11), SingleLang("MG Komik", "https://mgkomik.id", "id", overrideVersionCode = 11),
SingleLang("Midnight Mess Scans", "https://midnightmess.org", "en", isNsfw = true, overrideVersionCode = 6), SingleLang("Midnight Mess Scans", "https://midnightmess.org", "en", isNsfw = true, overrideVersionCode = 6),
@ -371,11 +372,9 @@ class MadaraGenerator : ThemeSourceGenerator {
SingleLang("NekoPost.co (unoriginal)", "https://www.nekopost.co", "th", isNsfw = false, className = "NekoPostCo"), SingleLang("NekoPost.co (unoriginal)", "https://www.nekopost.co", "th", isNsfw = false, className = "NekoPostCo"),
SingleLang("NekoScan", "https://nekoscan.com", "en", overrideVersionCode = 2), SingleLang("NekoScan", "https://nekoscan.com", "en", overrideVersionCode = 2),
SingleLang("NewManhua", "https://newmanhua.com", "en", isNsfw = true), SingleLang("NewManhua", "https://newmanhua.com", "en", isNsfw = true),
SingleLang("Nexo Scans", "https://nexoscans.com", "pt-BR", overrideVersionCode = 1),
SingleLang("Night Comic", "https://www.nightcomic.com", "en", overrideVersionCode = 1), SingleLang("Night Comic", "https://www.nightcomic.com", "en", overrideVersionCode = 1),
SingleLang("Niji Translations", "https://niji-translations.com", "ar", overrideVersionCode = 1), SingleLang("Niji Translations", "https://niji-translations.com", "ar", overrideVersionCode = 1),
SingleLang("Nitro Manga", "https://nitromanga.com", "en", className = "NitroScans", overrideVersionCode = 1), SingleLang("Nitro Manga", "https://nitromanga.com", "en", className = "NitroScans", overrideVersionCode = 1),
SingleLang("Norte Rose Scan", "https://norterose.com.br", "pt-BR", isNsfw = true),
SingleLang("No Index Scan", "https://noindexscan.com", "pt-BR", isNsfw = true), SingleLang("No Index Scan", "https://noindexscan.com", "pt-BR", isNsfw = true),
SingleLang("Noblesse Translations", "https://www.noblessev1.com", "es", overrideVersionCode = 2), SingleLang("Noblesse Translations", "https://www.noblessev1.com", "es", overrideVersionCode = 2),
SingleLang("Nocturne Summer", "https://nocsummer.com.br", "pt-BR", isNsfw = true), SingleLang("Nocturne Summer", "https://nocsummer.com.br", "pt-BR", isNsfw = true),
@ -454,7 +453,6 @@ class MadaraGenerator : ThemeSourceGenerator {
SingleLang("Tatakae Scan", "https://tatakaescan.com", "pt-BR", isNsfw = true, overrideVersionCode = 2), SingleLang("Tatakae Scan", "https://tatakaescan.com", "pt-BR", isNsfw = true, overrideVersionCode = 2),
SingleLang("Taurus Fansub", "https://taurusmanga.com", "es", overrideVersionCode = 1), SingleLang("Taurus Fansub", "https://taurusmanga.com", "es", overrideVersionCode = 1),
SingleLang("TeenManhua", "https://teenmanhua.com", "en", overrideVersionCode = 1), SingleLang("TeenManhua", "https://teenmanhua.com", "en", overrideVersionCode = 1),
SingleLang("TenkaiScan", "https://tenkaiscan.net", "es", isNsfw = true),
SingleLang("The Beginning After The End", "https://www.thebeginningaftertheend.fr", "fr", overrideVersionCode = 1), SingleLang("The Beginning After The End", "https://www.thebeginningaftertheend.fr", "fr", overrideVersionCode = 1),
SingleLang("The Blank Scanlation", "https://theblank.net", "en", className = "TheBlank", isNsfw = true), SingleLang("The Blank Scanlation", "https://theblank.net", "en", className = "TheBlank", isNsfw = true),
SingleLang("The Guild", "https://theguildscans.com", "en"), SingleLang("The Guild", "https://theguildscans.com", "en"),
@ -504,19 +502,18 @@ class MadaraGenerator : ThemeSourceGenerator {
SingleLang("Yuri Verso", "https://yuri.live", "pt-BR", overrideVersionCode = 3), SingleLang("Yuri Verso", "https://yuri.live", "pt-BR", overrideVersionCode = 3),
SingleLang("Zandy no Fansub", "https://zandynofansub.aishiteru.org", "en"), SingleLang("Zandy no Fansub", "https://zandynofansub.aishiteru.org", "en"),
SingleLang("ZinChanManga", "https://zinchanmanga.com", "en", isNsfw = true), SingleLang("ZinChanManga", "https://zinchanmanga.com", "en", isNsfw = true),
SingleLang("Zinmanga", "https://zinmanga.com", "en", overrideVersionCode = 1),
SingleLang("ZinManga.top (unoriginal)", "https://zinmanga.top", "en", isNsfw = false, className = "ZinMangaTop"), SingleLang("ZinManga.top (unoriginal)", "https://zinmanga.top", "en", isNsfw = false, className = "ZinMangaTop"),
SingleLang("Zinmanga", "https://zinmanga.com", "en", overrideVersionCode = 1),
SingleLang("Zinmanhwa", "https://zinmanhwa.com", "en"), SingleLang("Zinmanhwa", "https://zinmanhwa.com", "en"),
SingleLang("ZuttoManga", "https://zuttomanga.com", "en", overrideVersionCode = 1), SingleLang("ZuttoManga", "https://zuttomanga.com", "en", overrideVersionCode = 1),
SingleLang("Çizgi Roman Arşivi", "https://cizgiromanarsivi.com", "tr", className = "CizgiRomanArsivi"),
SingleLang("شبكة كونان العربية", "https://manga.detectiveconanar.com", "ar", className = "DetectiveConanAr", overrideVersionCode = 2), SingleLang("شبكة كونان العربية", "https://manga.detectiveconanar.com", "ar", className = "DetectiveConanAr", overrideVersionCode = 2),
SingleLang("عرب تونز", "https://arabtoons.net", "ar", isNsfw = true, className = "ArabToons"), SingleLang("عرب تونز", "https://arabtoons.net", "ar", isNsfw = true, className = "ArabToons"),
SingleLang("فالكون مانجا", "https://falconmanga.com", "ar", className = "FalconManga"),
SingleLang("كوميك العرب", "https://comicarab.com", "ar", isNsfw = true, className = "ComicArab"),
SingleLang("مانجا العاشق", "https://3asq.org", "ar", className = "Manga3asq", overrideVersionCode = 2), SingleLang("مانجا العاشق", "https://3asq.org", "ar", className = "Manga3asq", overrideVersionCode = 2),
SingleLang("مانجا ليك", "https://manga-lek.net", "ar", className = "Mangalek", overrideVersionCode = 4), SingleLang("مانجا ليك", "https://manga-lek.net", "ar", className = "Mangalek", overrideVersionCode = 4),
SingleLang("مانجا ليكس", "https://mangaleks.com", "ar", className = "MangaLeks"), SingleLang("مانجا ليكس", "https://mangaleks.com", "ar", className = "MangaLeks"),
SingleLang("مانجا لينك", "https://mangalink.io", "ar", className = "MangaLinkio", overrideVersionCode = 3), SingleLang("مانجا لينك", "https://mangalink.io", "ar", className = "MangaLinkio", overrideVersionCode = 3),
SingleLang("كوميك العرب", "https://comicarab.com", "ar", isNsfw = true, className = "ComicArab"),
SingleLang("فالكون مانجا", "https://falconmanga.com", "ar", className = "FalconManga"),
SingleLang("巴卡漫画", "https://bakamh.com", "zh", isNsfw = true, className = "Bakamh"), SingleLang("巴卡漫画", "https://bakamh.com", "zh", isNsfw = true, className = "Bakamh"),
) )

View File

@ -277,7 +277,7 @@ abstract class MadTheme(
} }
override fun imageUrlParse(document: Document): String = override fun imageUrlParse(document: Document): String =
throw UnsupportedOperationException() throw UnsupportedOperationException("Not used.")
// Date logic lifted from Madara // Date logic lifted from Madara
private fun parseChapterDate(date: String?): Long { private fun parseChapterDate(date: String?): Long {

View File

@ -269,7 +269,7 @@ abstract class MangaBox(
return GET(page.imageUrl!!, headersBuilder().set("Referer", page.url).build()) return GET(page.imageUrl!!, headersBuilder().set("Referer", page.url).build())
} }
override fun imageUrlParse(document: Document): String = throw UnsupportedOperationException() override fun imageUrlParse(document: Document): String = throw UnsupportedOperationException("Not used")
// Based on change_alias JS function from Mangakakalot's website // Based on change_alias JS function from Mangakakalot's website
@SuppressLint("DefaultLocale") @SuppressLint("DefaultLocale")

View File

@ -36,16 +36,16 @@ abstract class MangaCatalog(
title = name title = name
url = sourceurl url = sourceurl
} }
override fun popularMangaRequest(page: Int): Request = throw UnsupportedOperationException() override fun popularMangaRequest(page: Int): Request = throw Exception("Not used")
override fun popularMangaNextPageSelector(): String? = throw UnsupportedOperationException() override fun popularMangaNextPageSelector(): String? = throw Exception("Not used")
override fun popularMangaSelector(): String = throw UnsupportedOperationException() override fun popularMangaSelector(): String = throw Exception("Not used")
override fun popularMangaFromElement(element: Element) = throw UnsupportedOperationException() override fun popularMangaFromElement(element: Element) = throw Exception("Not used")
// Latest // Latest
override fun latestUpdatesRequest(page: Int): Request = throw UnsupportedOperationException() override fun latestUpdatesRequest(page: Int): Request = throw Exception("Not used")
override fun latestUpdatesNextPageSelector(): String? = throw UnsupportedOperationException() override fun latestUpdatesNextPageSelector(): String? = throw Exception("Not used")
override fun latestUpdatesSelector(): String = throw UnsupportedOperationException() override fun latestUpdatesSelector(): String = throw Exception("Not used")
override fun latestUpdatesFromElement(element: Element): SManga = throw UnsupportedOperationException() override fun latestUpdatesFromElement(element: Element): SManga = throw Exception("Not used")
// Search // Search
@ -59,10 +59,10 @@ abstract class MangaCatalog(
return Observable.just(MangasPage(mangas, false)) return Observable.just(MangasPage(mangas, false))
} }
override fun searchMangaRequest(page: Int, query: String, filters: FilterList) = throw UnsupportedOperationException() override fun searchMangaRequest(page: Int, query: String, filters: FilterList) = throw Exception("Not used")
override fun searchMangaNextPageSelector() = throw UnsupportedOperationException() override fun searchMangaNextPageSelector() = throw Exception("Not used")
override fun searchMangaSelector() = throw UnsupportedOperationException() override fun searchMangaSelector() = throw Exception("Not used")
override fun searchMangaFromElement(element: Element) = throw UnsupportedOperationException() override fun searchMangaFromElement(element: Element) = throw Exception("Not used")
// Get Override // Get Override
@ -106,5 +106,5 @@ abstract class MangaCatalog(
Page(index, "", img.attr("src")) Page(index, "", img.attr("src"))
} }
override fun imageUrlParse(document: Document): String = throw UnsupportedOperationException() override fun imageUrlParse(document: Document): String = throw Exception("Not Used")
} }

View File

@ -116,7 +116,7 @@ abstract class MangAdventure(
} }
override fun imageUrlParse(response: Response) = override fun imageUrlParse(response: Response) =
throw UnsupportedOperationException() throw UnsupportedOperationException("Not used!")
override fun getMangaUrl(manga: SManga) = "$baseUrl/reader/${manga.url}" override fun getMangaUrl(manga: SManga) = "$baseUrl/reader/${manga.url}"

View File

@ -279,7 +279,7 @@ abstract class MangaHub(
} }
override fun chapterFromElement(element: Element): SChapter { override fun chapterFromElement(element: Element): SChapter {
throw UnsupportedOperationException() throw UnsupportedOperationException("Not Used")
} }
private fun parseChapterDate(date: String): Long { private fun parseChapterDate(date: String): Long {
@ -361,7 +361,7 @@ abstract class MangaHub(
.doOnError { refreshApiKey(chapter) } .doOnError { refreshApiKey(chapter) }
.retry(1) .retry(1)
override fun pageListParse(document: Document): List<Page> = throw UnsupportedOperationException() override fun pageListParse(document: Document): List<Page> = throw UnsupportedOperationException("Not used")
override fun pageListParse(response: Response): List<Page> { override fun pageListParse(response: Response): List<Page> {
val chapterObject = json.decodeFromString<ApiChapterPagesResponse>(response.body.string()) val chapterObject = json.decodeFromString<ApiChapterPagesResponse>(response.body.string())
@ -393,7 +393,7 @@ abstract class MangaHub(
return GET(page.url, newHeaders) return GET(page.url, newHeaders)
} }
override fun imageUrlParse(document: Document): String = throw UnsupportedOperationException() override fun imageUrlParse(document: Document): String = throw UnsupportedOperationException("Not used")
// filters // filters
private class Genre(title: String, val key: String) : Filter.TriState(title) { private class Genre(title: String, val key: String) : Filter.TriState(title) {

View File

@ -78,5 +78,5 @@ abstract class MangaRawTheme(
} }
} }
override fun imageUrlParse(document: Document) = throw UnsupportedOperationException() override fun imageUrlParse(document: Document) = throw UnsupportedOperationException("Not used.")
} }

View File

@ -503,15 +503,15 @@ abstract class MangaThemesia(
protected open fun Elements.imgAttr(): String = this.first()!!.imgAttr() protected open fun Elements.imgAttr(): String = this.first()!!.imgAttr()
// Unused // Unused
override fun popularMangaSelector(): String = throw UnsupportedOperationException() override fun popularMangaSelector(): String = throw UnsupportedOperationException("Not used")
override fun popularMangaFromElement(element: Element): SManga = throw UnsupportedOperationException() override fun popularMangaFromElement(element: Element): SManga = throw UnsupportedOperationException("Not used")
override fun popularMangaNextPageSelector(): String? = throw UnsupportedOperationException() override fun popularMangaNextPageSelector(): String? = throw UnsupportedOperationException("Not used")
override fun latestUpdatesSelector(): String = throw UnsupportedOperationException() override fun latestUpdatesSelector(): String = throw UnsupportedOperationException("Not used")
override fun latestUpdatesFromElement(element: Element): SManga = throw UnsupportedOperationException() override fun latestUpdatesFromElement(element: Element): SManga = throw UnsupportedOperationException("Not used")
override fun latestUpdatesNextPageSelector(): String? = throw UnsupportedOperationException() override fun latestUpdatesNextPageSelector(): String? = throw UnsupportedOperationException("Not used")
override fun imageUrlParse(document: Document): String = throw UnsupportedOperationException() override fun imageUrlParse(document: Document): String = throw UnsupportedOperationException("Not Used")
override fun setupPreferenceScreen(screen: PreferenceScreen) { override fun setupPreferenceScreen(screen: PreferenceScreen) {
addRandomUAPreferenceToScreen(screen) addRandomUAPreferenceToScreen(screen)

View File

@ -30,7 +30,7 @@ class MangaThemesiaGenerator : ThemeSourceGenerator {
SingleLang("Berserker Scan", "https://ragnascan.com", "es"), SingleLang("Berserker Scan", "https://ragnascan.com", "es"),
SingleLang("BirdManga", "https://birdmanga.com", "en"), SingleLang("BirdManga", "https://birdmanga.com", "en"),
SingleLang("Boosei", "https://boosei.net", "id", overrideVersionCode = 2), SingleLang("Boosei", "https://boosei.net", "id", overrideVersionCode = 2),
SingleLang("Cartel de Manhwas", "https://carteldemanhwas.com", "es", overrideVersionCode = 6), SingleLang("Cartel de Manhwas", "https://carteldemanhwas.com", "es", overrideVersionCode = 5),
SingleLang("Constellar Scans", "https://constellarcomic.com", "en", isNsfw = true, overrideVersionCode = 16), SingleLang("Constellar Scans", "https://constellarcomic.com", "en", isNsfw = true, overrideVersionCode = 16),
SingleLang("Cosmic Scans", "https://cosmic-scans.com", "en", overrideVersionCode = 2), SingleLang("Cosmic Scans", "https://cosmic-scans.com", "en", overrideVersionCode = 2),
SingleLang("CosmicScans.id", "https://cosmicscans.id", "id", overrideVersionCode = 3, className = "CosmicScansID"), SingleLang("CosmicScans.id", "https://cosmicscans.id", "id", overrideVersionCode = 3, className = "CosmicScansID"),
@ -68,8 +68,8 @@ class MangaThemesiaGenerator : ThemeSourceGenerator {
SingleLang("KomikIndo.co", "https://komikindo.co", "id", className = "KomikindoCo", overrideVersionCode = 3), SingleLang("KomikIndo.co", "https://komikindo.co", "id", className = "KomikindoCo", overrideVersionCode = 3),
SingleLang("KomikMama", "https://komikmama.co", "id", overrideVersionCode = 1), SingleLang("KomikMama", "https://komikmama.co", "id", overrideVersionCode = 1),
SingleLang("KomikManhwa", "https://komikmanhwa.me", "id", isNsfw = true), SingleLang("KomikManhwa", "https://komikmanhwa.me", "id", isNsfw = true),
SingleLang("Komiksan", "https://komiksan.link", "id", overrideVersionCode = 2),
SingleLang("Komiktap", "https://komiktap.me", "id", isNsfw = true), SingleLang("Komiktap", "https://komiktap.me", "id", isNsfw = true),
SingleLang("Komiksan", "https://komiksan.link", "id", overrideVersionCode = 2),
SingleLang("Komiku.com", "https://komiku.com", "id", className = "KomikuCom"), SingleLang("Komiku.com", "https://komiku.com", "id", className = "KomikuCom"),
SingleLang("Kuma Scans (Kuma Translation)", "https://kumascans.com", "en", className = "KumaScans", overrideVersionCode = 1), SingleLang("Kuma Scans (Kuma Translation)", "https://kumascans.com", "en", className = "KumaScans", overrideVersionCode = 1),
SingleLang("KumaPoi", "https://kumapoi.info", "id", isNsfw = true, overrideVersionCode = 3), SingleLang("KumaPoi", "https://kumapoi.info", "id", isNsfw = true, overrideVersionCode = 3),
@ -86,6 +86,7 @@ class MangaThemesiaGenerator : ThemeSourceGenerator {
SingleLang("Mangacim", "https://www.mangacim.com", "tr", overrideVersionCode = 1), SingleLang("Mangacim", "https://www.mangacim.com", "tr", overrideVersionCode = 1),
SingleLang("MangaKita", "https://mangakita.id", "id", overrideVersionCode = 2), SingleLang("MangaKita", "https://mangakita.id", "id", overrideVersionCode = 2),
SingleLang("Mangakyo", "https://mangakyo.org", "id", overrideVersionCode = 3), SingleLang("Mangakyo", "https://mangakyo.org", "id", overrideVersionCode = 3),
SingleLang("Mangás Chan", "https://mangaschan.net", "pt-BR", className = "MangasChan", overrideVersionCode = 1),
SingleLang("MangaShiina", "https://mangashiina.com", "es"), SingleLang("MangaShiina", "https://mangashiina.com", "es"),
SingleLang("MangaShiro", "https://mangashiro.me", "id"), SingleLang("MangaShiro", "https://mangashiro.me", "id"),
SingleLang("Mangasusu", "https://mangasusuku.xyz", "id", isNsfw = true, overrideVersionCode = 3), SingleLang("Mangasusu", "https://mangasusuku.xyz", "id", isNsfw = true, overrideVersionCode = 3),
@ -93,7 +94,6 @@ class MangaThemesiaGenerator : ThemeSourceGenerator {
SingleLang("MangaTale", "https://mangatale.co", "id", overrideVersionCode = 1), SingleLang("MangaTale", "https://mangatale.co", "id", overrideVersionCode = 1),
SingleLang("MangaWT", "https://mangawt.com", "tr", overrideVersionCode = 5), SingleLang("MangaWT", "https://mangawt.com", "tr", overrideVersionCode = 5),
SingleLang("Mangayaro", "https://www.mangayaro.id", "id", overrideVersionCode = 1), SingleLang("Mangayaro", "https://www.mangayaro.id", "id", overrideVersionCode = 1),
SingleLang("Mangás Chan", "https://mangaschan.net", "pt-BR", className = "MangasChan", overrideVersionCode = 1),
SingleLang("Mangás Online", "https://mangasonline.cc", "pt-BR", className = "MangasOnline"), SingleLang("Mangás Online", "https://mangasonline.cc", "pt-BR", className = "MangasOnline"),
SingleLang("Manhwa Freak", "https://manhwa-freak.com", "en", overrideVersionCode = 3), SingleLang("Manhwa Freak", "https://manhwa-freak.com", "en", overrideVersionCode = 3),
SingleLang("Manhwa Lover", "https://manhwalover.com", "en", isNsfw = true, overrideVersionCode = 1), SingleLang("Manhwa Lover", "https://manhwalover.com", "en", isNsfw = true, overrideVersionCode = 1),
@ -137,7 +137,6 @@ class MangaThemesiaGenerator : ThemeSourceGenerator {
SingleLang("Senpai Ediciones", "http://senpaiediciones.com", "es", overrideVersionCode = 1), SingleLang("Senpai Ediciones", "http://senpaiediciones.com", "es", overrideVersionCode = 1),
SingleLang("Shadow Mangas", "https://shadowmangas.com", "es", overrideVersionCode = 1), SingleLang("Shadow Mangas", "https://shadowmangas.com", "es", overrideVersionCode = 1),
SingleLang("Shea Manga", "https://sheakomik.com", "id", overrideVersionCode = 4), SingleLang("Shea Manga", "https://sheakomik.com", "id", overrideVersionCode = 4),
SingleLang("Shirakami", "https://shirakami.xyz", "id"),
SingleLang("Silence Scan", "https://silencescan.com.br", "pt-BR", isNsfw = true, overrideVersionCode = 5), SingleLang("Silence Scan", "https://silencescan.com.br", "pt-BR", isNsfw = true, overrideVersionCode = 5),
SingleLang("Siren Komik", "https://sirenkomik.my.id", "id", className = "MangKomik", overrideVersionCode = 2), SingleLang("Siren Komik", "https://sirenkomik.my.id", "id", className = "MangKomik", overrideVersionCode = 2),
SingleLang("SkyMangas", "https://skymangas.com", "es", overrideVersionCode = 1), SingleLang("SkyMangas", "https://skymangas.com", "es", overrideVersionCode = 1),
@ -153,6 +152,7 @@ class MangaThemesiaGenerator : ThemeSourceGenerator {
SingleLang("Sushiscan.fr", "https://anime-sama.me", "fr", className = "SushiScanFR", overrideVersionCode = 1), SingleLang("Sushiscan.fr", "https://anime-sama.me", "fr", className = "SushiScanFR", overrideVersionCode = 1),
SingleLang("Tarot Scans", "https://www.tarotscans.com", "tr"), SingleLang("Tarot Scans", "https://www.tarotscans.com", "tr"),
SingleLang("Tecno Scan", "https://tecnoscann.com", "es", isNsfw = true, overrideVersionCode = 6), SingleLang("Tecno Scan", "https://tecnoscann.com", "es", isNsfw = true, overrideVersionCode = 6),
SingleLang("TenkaiScan", "https://tenkaiscan.net", "es", isNsfw = true),
SingleLang("Tenshi.id", "https://tenshi.id", "id", className = "TenshiId", pkgName = "masterkomik", overrideVersionCode = 4), SingleLang("Tenshi.id", "https://tenshi.id", "id", className = "TenshiId", pkgName = "masterkomik", overrideVersionCode = 4),
SingleLang("The Apollo Team", "https://theapollo.team", "en"), SingleLang("The Apollo Team", "https://theapollo.team", "en"),
SingleLang("Tres Daos Scan", "https://tresdaos.com", "es"), SingleLang("Tres Daos Scan", "https://tresdaos.com", "es"),

View File

@ -201,7 +201,7 @@ abstract class MangaWorld(
} }
} }
override fun imageUrlParse(document: Document) = throw UnsupportedOperationException() override fun imageUrlParse(document: Document) = throw UnsupportedOperationException("Not used.")
override fun imageRequest(page: Page): Request { override fun imageRequest(page: Page): Request {
val imgHeader = Headers.Builder().apply { val imgHeader = Headers.Builder().apply {

View File

@ -96,7 +96,7 @@ open class MCCMS(
} }
} }
override fun mangaDetailsParse(response: Response): SManga = throw UnsupportedOperationException() override fun mangaDetailsParse(response: Response): SManga = throw UnsupportedOperationException("Not used.")
override fun fetchChapterList(manga: SManga): Observable<List<SChapter>> = Observable.fromCallable { override fun fetchChapterList(manga: SManga): Observable<List<SChapter>> = Observable.fromCallable {
val id = getMangaId(manga.url) val id = getMangaId(manga.url)
@ -112,7 +112,7 @@ open class MCCMS(
protected open fun getMangaId(url: String) = url.substringAfterLast('/') protected open fun getMangaId(url: String) = url.substringAfterLast('/')
override fun chapterListParse(response: Response): List<SChapter> = throw UnsupportedOperationException() override fun chapterListParse(response: Response): List<SChapter> = throw UnsupportedOperationException("Not used.")
override fun pageListRequest(chapter: SChapter): Request = override fun pageListRequest(chapter: SChapter): Request =
GET(baseUrl + chapter.url, pcHeaders) GET(baseUrl + chapter.url, pcHeaders)
@ -126,7 +126,7 @@ open class MCCMS(
} }
} }
override fun imageUrlParse(response: Response) = throw UnsupportedOperationException() override fun imageUrlParse(response: Response) = throw UnsupportedOperationException("Not used.")
override fun imageRequest(page: Page) = GET(page.imageUrl!!, pcHeaders) override fun imageRequest(page: Page) = GET(page.imageUrl!!, pcHeaders)

View File

@ -420,7 +420,7 @@ abstract class MMRCMS(
Page(i, response.request.url.toString(), url) Page(i, response.request.url.toString(), url)
} }
override fun imageUrlParse(response: Response) = throw UnsupportedOperationException() override fun imageUrlParse(response: Response) = throw UnsupportedOperationException("Unused method called!")
private fun getInitialFilterList() = listOf<Filter<*>>( private fun getInitialFilterList() = listOf<Filter<*>>(
Filter.Header("NOTE: Ignored if using text search!"), Filter.Header("NOTE: Ignored if using text search!"),

View File

@ -107,32 +107,32 @@ open class MonochromeCMS(
json.decodeFromString<T>(body.string()) json.decodeFromString<T>(body.string())
override fun popularMangaRequest(page: Int) = override fun popularMangaRequest(page: Int) =
throw UnsupportedOperationException() throw UnsupportedOperationException("Not used!")
override fun latestUpdatesRequest(page: Int) = override fun latestUpdatesRequest(page: Int) =
throw UnsupportedOperationException() throw UnsupportedOperationException("Not used!")
override fun mangaDetailsRequest(manga: SManga) = override fun mangaDetailsRequest(manga: SManga) =
throw UnsupportedOperationException() throw UnsupportedOperationException("Not used!")
override fun popularMangaParse(response: Response) = override fun popularMangaParse(response: Response) =
throw UnsupportedOperationException() throw UnsupportedOperationException("Not used!")
override fun latestUpdatesParse(response: Response) = override fun latestUpdatesParse(response: Response) =
throw UnsupportedOperationException() throw UnsupportedOperationException("Not used!")
override fun mangaDetailsParse(response: Response) = override fun mangaDetailsParse(response: Response) =
throw UnsupportedOperationException() throw UnsupportedOperationException("Not used!")
override fun chapterListParse(response: Response) = override fun chapterListParse(response: Response) =
throw UnsupportedOperationException() throw UnsupportedOperationException("Not used!")
override fun pageListRequest(chapter: SChapter) = override fun pageListRequest(chapter: SChapter) =
throw UnsupportedOperationException() throw UnsupportedOperationException("Not used!")
override fun pageListParse(response: Response) = override fun pageListParse(response: Response) =
throw UnsupportedOperationException() throw UnsupportedOperationException("Not used!")
override fun imageUrlParse(response: Response) = override fun imageUrlParse(response: Response) =
throw UnsupportedOperationException() throw UnsupportedOperationException("Not used!")
} }

View File

@ -262,7 +262,7 @@ abstract class MyMangaCMS(
override fun chapterListSelector(): String = "ul.list-chapters > a" override fun chapterListSelector(): String = "ul.list-chapters > a"
override fun chapterFromElement(element: Element): SChapter = throw UnsupportedOperationException() override fun chapterFromElement(element: Element): SChapter = throw Exception("Not used")
private fun chapterFromElement(element: Element, scanlator: String?): SChapter = private fun chapterFromElement(element: Element, scanlator: String?): SChapter =
SChapter.create().apply { SChapter.create().apply {
@ -307,7 +307,7 @@ abstract class MyMangaCMS(
.filterNot { it.attr("abs:data-src").isNullOrEmpty() } .filterNot { it.attr("abs:data-src").isNullOrEmpty() }
.mapIndexed { index, elem -> Page(index, "", elem.attr("abs:data-src")) } .mapIndexed { index, elem -> Page(index, "", elem.attr("abs:data-src")) }
override fun imageUrlParse(document: Document): String = throw UnsupportedOperationException() override fun imageUrlParse(document: Document): String = throw Exception("Not used")
//endregion //endregion
//region Filters //region Filters

View File

@ -227,7 +227,7 @@ abstract class NepNep(
return parseDirectory(1) return parseDirectory(1)
} }
override fun searchMangaParse(response: Response): MangasPage = throw UnsupportedOperationException() override fun searchMangaParse(response: Response): MangasPage = throw UnsupportedOperationException("Not used")
// Details // Details
@ -357,7 +357,7 @@ abstract class NepNep(
} }
} }
override fun imageUrlParse(response: Response): String = throw UnsupportedOperationException() override fun imageUrlParse(response: Response): String = throw UnsupportedOperationException("Not used")
// Filters // Filters

View File

@ -95,9 +95,9 @@ open class OtakuSanctuary(
return MangasPage(parseMangaCollection(collection), hasNextPage) return MangasPage(parseMangaCollection(collection), hasNextPage)
} }
override fun latestUpdatesRequest(page: Int) = throw UnsupportedOperationException() override fun latestUpdatesRequest(page: Int) = throw UnsupportedOperationException("Not used")
override fun latestUpdatesParse(response: Response) = throw UnsupportedOperationException() override fun latestUpdatesParse(response: Response) = throw UnsupportedOperationException("Not used")
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request = override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request =
GET( GET(
@ -176,7 +176,7 @@ open class OtakuSanctuary(
} }
} }
override fun imageUrlParse(response: Response) = throw UnsupportedOperationException() override fun imageUrlParse(response: Response) = throw UnsupportedOperationException("Not used")
override fun pageListParse(response: Response): List<Page> { override fun pageListParse(response: Response): List<Page> {
val document = response.asJsoup() val document = response.asJsoup()

View File

@ -130,7 +130,7 @@ abstract class Paprika(
// never called // never called
override fun chapterFromElement(element: Element): SChapter { override fun chapterFromElement(element: Element): SChapter {
throw UnsupportedOperationException() throw Exception("unreachable code was reached!")
} }
open fun chapterFromElement(element: Element, mangaTitle: String): SChapter { open fun chapterFromElement(element: Element, mangaTitle: String): SChapter {
@ -179,7 +179,7 @@ abstract class Paprika(
} }
} }
override fun imageUrlParse(document: Document): String = throw UnsupportedOperationException() override fun imageUrlParse(document: Document): String = throw UnsupportedOperationException("Not used")
// Filters // Filters

View File

@ -174,15 +174,15 @@ abstract class ReadAllComics(
} }
override fun imageUrlParse(document: Document) = override fun imageUrlParse(document: Document) =
throw UnsupportedOperationException() throw UnsupportedOperationException("Not Implemented")
override fun latestUpdatesRequest(page: Int) = override fun latestUpdatesRequest(page: Int) =
throw UnsupportedOperationException() throw UnsupportedOperationException("Not Implemented")
override fun latestUpdatesFromElement(element: Element) = override fun latestUpdatesFromElement(element: Element) =
throw UnsupportedOperationException() throw UnsupportedOperationException("Not Implemented")
override fun latestUpdatesSelector() = override fun latestUpdatesSelector() =
throw UnsupportedOperationException() throw UnsupportedOperationException("Not Implemented")
override fun latestUpdatesNextPageSelector() = override fun latestUpdatesNextPageSelector() =
throw UnsupportedOperationException() throw UnsupportedOperationException("Not Implemented")
override fun popularMangaFromElement(element: Element) = override fun popularMangaFromElement(element: Element) =
throw UnsupportedOperationException() throw UnsupportedOperationException("Not Implemented")
} }

View File

@ -165,11 +165,11 @@ abstract class ReaderFront(
private inline val JsonElement.content get() = jsonPrimitive.content private inline val JsonElement.content get() = jsonPrimitive.content
override fun searchMangaRequest(page: Int, query: String, filters: FilterList) = override fun searchMangaRequest(page: Int, query: String, filters: FilterList) =
throw UnsupportedOperationException() throw UnsupportedOperationException("Not used!")
override fun searchMangaParse(response: Response) = override fun searchMangaParse(response: Response) =
throw UnsupportedOperationException() throw UnsupportedOperationException("Not used!")
override fun imageUrlParse(response: Response) = override fun imageUrlParse(response: Response) =
throw UnsupportedOperationException() throw UnsupportedOperationException("Not used!")
} }

View File

@ -261,7 +261,7 @@ abstract class Senkuro(
chapterListParse(response, manga) chapterListParse(response, manga)
} }
} }
override fun chapterListParse(response: Response) = throw UnsupportedOperationException() override fun chapterListParse(response: Response) = throw UnsupportedOperationException("chapterListParse(response: Response, manga: SManga)")
private fun chapterListParse(response: Response, manga: SManga): List<SChapter> { private fun chapterListParse(response: Response, manga: SManga): List<SChapter> {
val chaptersList = json.decodeFromString<PageWrapperDto<MangaTachiyomiChaptersDto>>(response.body.string()) val chaptersList = json.decodeFromString<PageWrapperDto<MangaTachiyomiChaptersDto>>(response.body.string())
val teamsList = chaptersList.data.mangaTachiyomiChapters.teams val teamsList = chaptersList.data.mangaTachiyomiChapters.teams

View File

@ -215,7 +215,7 @@ abstract class SinMH(
emptyList() // [] emptyList() // []
} }
override fun imageUrlParse(document: Document): String = throw UnsupportedOperationException() override fun imageUrlParse(document: Document): String = throw UnsupportedOperationException("Not Used.")
protected class UriPartFilter(displayName: String, values: Array<String>, private val uriParts: Array<String>) : protected class UriPartFilter(displayName: String, values: Array<String>, private val uriParts: Array<String>) :
Filter.Select<String>(displayName, values) { Filter.Select<String>(displayName, values) {

View File

@ -154,11 +154,11 @@ open class WebtoonsTranslate(
} }
} }
override fun chapterListSelector(): String = throw UnsupportedOperationException() override fun chapterListSelector(): String = throw Exception("Not used")
override fun chapterFromElement(element: Element): SChapter = throw UnsupportedOperationException() override fun chapterFromElement(element: Element): SChapter = throw Exception("Not used")
override fun pageListParse(document: Document): List<Page> = throw UnsupportedOperationException() override fun pageListParse(document: Document): List<Page> = throw Exception("Not used")
override fun chapterListRequest(manga: SManga): Request { override fun chapterListRequest(manga: SManga): Request {
val mangaUrl = manga.url.toHttpUrl() val mangaUrl = manga.url.toHttpUrl()

View File

@ -220,7 +220,7 @@ abstract class WPComics(
.mapIndexed { i, image -> Page(i, "", image) } .mapIndexed { i, image -> Page(i, "", image) }
} }
override fun imageUrlParse(document: Document): String = throw UnsupportedOperationException() override fun imageUrlParse(document: Document): String = throw UnsupportedOperationException("Not used")
// Filters // Filters

View File

@ -193,7 +193,7 @@ abstract class Zbulu(
} }
} }
override fun imageUrlParse(document: Document): String = throw UnsupportedOperationException() override fun imageUrlParse(document: Document): String = throw UnsupportedOperationException("Not used")
// Filters // Filters

View File

@ -272,7 +272,7 @@ abstract class ZeistManga(
} }
} }
override fun imageUrlParse(response: Response) = throw UnsupportedOperationException() override fun imageUrlParse(response: Response) = throw UnsupportedOperationException("Not used.")
protected open val mangaCategory: String = "Series" protected open val mangaCategory: String = "Series"

View File

@ -174,7 +174,7 @@ abstract class ZManga(
} }
} }
override fun imageUrlParse(document: Document): String = throw UnsupportedOperationException() override fun imageUrlParse(document: Document): String = throw UnsupportedOperationException("Not used")
open val hasProjectPage = false open val hasProjectPage = false

View File

@ -69,6 +69,10 @@ interface ThemeSourceGenerator {
gradle.writeText( gradle.writeText(
""" """
|// THIS FILE IS AUTO-GENERATED; DO NOT EDIT |// THIS FILE IS AUTO-GENERATED; DO NOT EDIT
|apply plugin: 'com.android.application'
|apply plugin: 'kotlin-android'
|apply plugin: 'kotlinx-serialization'
|
|ext { |ext {
| extName = '${source.name}' | extName = '${source.name}'
| pkgNameSuffix = '${pkgNameSuffix(source, ".")}' | pkgNameSuffix = '${pkgNameSuffix(source, ".")}'
@ -77,11 +81,9 @@ interface ThemeSourceGenerator {
| extVersionCode = ${baseVersionCode + source.overrideVersionCode + multisrcLibraryVersion} | extVersionCode = ${baseVersionCode + source.overrideVersionCode + multisrcLibraryVersion}
| ${if (source.isNsfw) "isNsfw = true\n" else ""} | ${if (source.isNsfw) "isNsfw = true\n" else ""}
|} |}
|
|apply from: "${'$'}rootDir/common.gradle"
|
|$defaultAdditionalGradleText |$defaultAdditionalGradleText
|$additionalGradleOverrideText |$additionalGradleOverrideText
|apply from: "${'$'}rootDir/common.gradle"
| |
|android { |android {
| defaultConfig { | defaultConfig {
@ -90,7 +92,6 @@ interface ThemeSourceGenerator {
| ] | ]
| } | }
|} |}
|
""".trimMargin(), """.trimMargin(),
) )
} }
@ -108,7 +109,6 @@ interface ThemeSourceGenerator {
|<?xml version="1.0" encoding="utf-8"?> |<?xml version="1.0" encoding="utf-8"?>
|<!-- THIS FILE IS AUTO-GENERATED; DO NOT EDIT --> |<!-- THIS FILE IS AUTO-GENERATED; DO NOT EDIT -->
|<manifest /> |<manifest />
|
""".trimMargin(), """.trimMargin(),
) )
} }

View File

@ -1,3 +1,6 @@
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
ext { ext {
extName = 'Akuma' extName = 'Akuma'
pkgNameSuffix = 'all.akuma' pkgNameSuffix = 'all.akuma'

View File

@ -1,3 +1,7 @@
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlinx-serialization'
ext { ext {
extName = 'Bato.to' extName = 'Bato.to'
pkgNameSuffix = 'all.batoto' pkgNameSuffix = 'all.batoto'

View File

@ -298,10 +298,10 @@ open class BatoTo(
add("prevPos", "null") add("prevPos", "null")
} }
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request = throw UnsupportedOperationException() override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request = throw UnsupportedOperationException("Not used")
override fun searchMangaSelector() = throw UnsupportedOperationException() override fun searchMangaSelector() = throw UnsupportedOperationException("Not used")
override fun searchMangaFromElement(element: Element) = throw UnsupportedOperationException() override fun searchMangaFromElement(element: Element) = throw UnsupportedOperationException("Not used")
override fun searchMangaNextPageSelector() = throw UnsupportedOperationException() override fun searchMangaNextPageSelector() = throw UnsupportedOperationException("Not used")
override fun mangaDetailsRequest(manga: SManga): Request { override fun mangaDetailsRequest(manga: SManga): Request {
if (manga.url.startsWith("http")) { if (manga.url.startsWith("http")) {
@ -456,7 +456,7 @@ open class BatoTo(
} }
override fun pageListParse(document: Document): List<Page> { override fun pageListParse(document: Document): List<Page> {
val script = document.selectFirst("script:containsData(imgHttps):containsData(batoWord):containsData(batoPass)")?.html() val script = document.selectFirst("script:containsData(imgHttpLis):containsData(batoWord):containsData(batoPass)")?.html()
?: throw RuntimeException("Couldn't find script with image data.") ?: throw RuntimeException("Couldn't find script with image data.")
val imgHttpsString = script.substringAfter("const imgHttps =").substringBefore(";").trim() val imgHttpsString = script.substringAfter("const imgHttps =").substringBefore(";").trim()
@ -473,7 +473,7 @@ open class BatoTo(
} }
} }
override fun imageUrlParse(document: Document): String = throw UnsupportedOperationException() override fun imageUrlParse(document: Document): String = throw UnsupportedOperationException("Not used")
private fun String.removeEntities(): String = Parser.unescapeEntities(this, true) private fun String.removeEntities(): String = Parser.unescapeEntities(this, true)

View File

@ -1,3 +1,6 @@
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
ext { ext {
extName = 'Buon Dua' extName = 'Buon Dua'
pkgNameSuffix = 'all.buondua' pkgNameSuffix = 'all.buondua'

View File

@ -102,7 +102,7 @@ class BuonDua() : ParsedHttpSource() {
return pages return pages
} }
override fun imageUrlParse(document: Document): String = throw UnsupportedOperationException() override fun imageUrlParse(document: Document): String = throw UnsupportedOperationException("Not used")
// Filters // Filters
override fun getFilterList(): FilterList = FilterList( override fun getFilterList(): FilterList = FilterList(

View File

@ -1,3 +1,7 @@
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlinx-serialization'
ext { ext {
extName = 'Comic Fury' extName = 'Comic Fury'
pkgNameSuffix = 'all.comicfury' pkgNameSuffix = 'all.comicfury'
@ -6,8 +10,8 @@ ext {
isNsfw = true isNsfw = true
} }
apply from: "$rootDir/common.gradle"
dependencies { dependencies {
implementation(project(':lib-textinterceptor')) implementation(project(':lib-textinterceptor'))
} }
apply from: "$rootDir/common.gradle"

View File

@ -31,7 +31,7 @@ class ComicFury(
private val extraName: String = "", private val extraName: String = "",
) : HttpSource(), ConfigurableSource { ) : HttpSource(), ConfigurableSource {
override val baseUrl: String = "https://comicfury.com" override val baseUrl: String = "https://comicfury.com"
override val name: String = "Comic Fury$extraName" // Used for No Text override val name: String = "Comic Fury$extraName" //Used for No Text
override val supportsLatest: Boolean = true override val supportsLatest: Boolean = true
private val dateFormat = SimpleDateFormat("dd MMM yyyy hh:mm aa", Locale.US) private val dateFormat = SimpleDateFormat("dd MMM yyyy hh:mm aa", Locale.US)
private val dateFormatSlim = SimpleDateFormat("dd MMM yyyy", Locale.US) private val dateFormatSlim = SimpleDateFormat("dd MMM yyyy", Locale.US)
@ -276,7 +276,7 @@ class ComicFury(
override fun latestUpdatesParse(response: Response): MangasPage = searchMangaParse(response) override fun latestUpdatesParse(response: Response): MangasPage = searchMangaParse(response)
override fun imageUrlParse(response: Response): String = override fun imageUrlParse(response: Response): String =
throw UnsupportedOperationException() throw UnsupportedOperationException("Not Used")
private fun String.toDate(): Long { private fun String.toDate(): Long {
val ret = this.replace("st", "") val ret = this.replace("st", "")

View File

@ -1,3 +1,7 @@
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlinx-serialization'
ext { ext {
extName = 'Comick' extName = 'Comick'
pkgNameSuffix = 'all.comickfun' pkgNameSuffix = 'all.comickfun'
@ -6,8 +10,8 @@ ext {
isNsfw = true isNsfw = true
} }
apply from: "$rootDir/common.gradle"
dependencies { dependencies {
implementation(project(":lib-i18n")) implementation(project(":lib-i18n"))
} }
apply from: "$rootDir/common.gradle"

View File

@ -452,7 +452,7 @@ abstract class ComickFun(
} }
override fun imageUrlParse(response: Response): String { override fun imageUrlParse(response: Response): String {
throw UnsupportedOperationException() throw UnsupportedOperationException("Not used")
} }
override fun getFilterList() = getFilters() override fun getFilterList() = getFilters()

Some files were not shown because too many files have changed in this diff Show More