Compare commits

...

23 Commits

Author SHA1 Message Date
Draff d61cbfc0c1 Add missing changes from keiyoushi
CI / Prepare job (push) Successful in 10s Details
CI / Build multisrc modules (push) Successful in 11m19s Details
CI / Build individual modules (push) Successful in 2m2s Details
CI / Publish repo (push) Successful in 2m41s Details
2024-01-16 02:56:21 +00:00
AwkwardPeak7 c5f82e6aeb Move plugin section to common.gradle (#281)
* move apply plugins to common.gradle

* update CONTRIBUTING.md

* remove whitespace

* move common.gradle apply above in multisrc

* move kotlinter

* newlines
2024-01-16 02:49:40 +00:00
stevenyomi 4c8c21596b Remove message in UnsupportedOperationException (#277) 2024-01-16 02:47:22 +00:00
stevenyomi 3ceea4ab95 Update docs and checklist on web_hi_res icons (#275) 2024-01-16 02:45:33 +00:00
Claudemirovsky 35673b2199 New source: Bakai (#270)
* chore: Add Bakai base

* feat: Implement popular manga page

* feat: Implement (basic) search

* fix: Prevent http 429 - Use stricter rate limit

* feat: Implement manga details page

* feat: Add single-entry chapter "list"

* feat: Parse page list

* chore: Add source icon
2024-01-16 02:44:58 +00:00
stevenyomi 029932e3d8 [RU]GroupLe rollback variety for allhentai (#273)
* [RU]GroupLe rollback variety for allhentai

* clean

---------

Co-authored-by: Eshlender <e.shlyapkin99@gmail.com>
2024-01-16 02:44:56 +00:00
stevenyomi 5023bde8ef Add Norte Rose Scan (#272)
* Adds Norte Rose Scan

* Delete multisrc/overrides/madara/norterosescan/src/NorteRoseScan.kt

* Remove web_hi_res_512.png

---------

Co-authored-by: NotBlankyu <66680364+NotBlankyu@users.noreply.github.com>
2024-01-16 02:44:50 +00:00
Claudemirovsky fb2d7cfd23 feat(multisrc/id): New source: Shirakami (#264)
* feat(multisrc/id): New source: Shirakami

* chore: Add source icon
2024-01-16 02:44:48 +00:00
uy/sun f8e98da8a6 COLAMANGA: fix unencrypted image error (#269) 2024-01-16 02:44:44 +00:00
stevenyomi 3e22055a7a Switch Java distribution to Temurin (#267) 2024-01-16 02:44:36 +00:00
Claudemirovsky d3da494cba Address some gradle warnings (#259)
* chore: Address AGP 8.X warning
* chore(core): Address conflicting-namespace warning
2024-01-16 02:43:08 +00:00
beerpsi 172d11d9ea Nexo Scans: Fix chapter parsing (#262)
* Nexo Scans: Fix chapter parsing

* bump overrideVersionCode
2024-01-16 02:42:56 +00:00
AwkwardPeak7 205e138dd2 upgrade AGP to 8.2.1 (#255)
* upgrade AGP

* bump to java 17 in ci
2024-01-16 02:42:39 +00:00
Ruliam dos Santos de Oliveira 4b155000b4 Add Nexo Scans (#224)
* Adding requested source

* Removing extra slash on link

Co-authored-by: Vetle Ledaal <vetle.ledaal@gmail.com>

* Fix language from pt to pt-BR

* Removing unnecessary override method

* Fixing all requested changes

---------

Co-authored-by: Vetle Ledaal <vetle.ledaal@gmail.com>
2024-01-16 02:40:52 +00:00
uy/sun f5f90f7a0e ColaManhua (OhManhua): add Category and Char filters (#248)
* ColaManhua (OhManhua): add Category and Char filters

* Use UriPartFilter

* Change source name

* Refactor StatusFilter
2024-01-16 02:40:49 +00:00
Vetle Ledaal 4feb5e77a5 Update domain for LuxManga (#251)
Also marking it as NSFW because of "Prince Snow White is Taken by the Queen".
2024-01-16 02:40:43 +00:00
Claudemirovsky ef9312261e fix(tr/mangatr): Fix popular/latest pages + fix http 403 (#244)
* fix: Update requestPath - Fixes popular/latest tabs

* fix: Fix HTTP 403 - Steal DDoSGuardInterceptor from all/akuma

* chore: Bump version
2024-01-16 02:40:40 +00:00
beerpsi 04ca6e2fb7 Add ColaManga/ColaManhua (#243)
* Add ColaManhua

* Remove unneeded preference change listener

Co-authored-by: stevenyomi <95685115+stevenyomi@users.noreply.github.com>

---------

Co-authored-by: stevenyomi <95685115+stevenyomi@users.noreply.github.com>
2024-01-16 02:40:32 +00:00
rtlow 3045c7be96 Load all chapters for Dynasty Doujins (#139)
* Added next page to all

Copied implementation from `Chapters` to all other extensions. New pages load when scrolling now

* Update DynastyDoujins.kt

Circumvent `IndexOutOfBoundsException` when section has no chapters

* Update build.gradle

* Moved functionality to base class

* Update DynastyDoujins.kt

Lazy implementation to load all chapters for `Dynasty Doujins`

* Update build.gradle

* Update src/en/dynasty/src/eu/kanade/tachiyomi/extension/en/dynasty/DynastyDoujins.kt

Co-authored-by: stevenyomi <95685115+stevenyomi@users.noreply.github.com>

* Fix exceeding max retry behavior

* Remove retry logic

* Update DynastyDoujins.kt

---------

Co-authored-by: stevenyomi <95685115+stevenyomi@users.noreply.github.com>
2024-01-16 02:40:29 +00:00
bapeey e6dba52ab9 Manhwas.net: Tweak Sucuri Interceptor (#238)
Fix possible issues in SucuriInterceptor
2024-01-16 02:40:25 +00:00
bapeey c8df4afffd Cartel de Manhwas: Fix thumbnails (#239)
* Fix thumbnails

* Remove all other sources for test

* Revert "Remove all other sources for test"

This reverts commit 36758ba22b4ae4b761610d4fbd09abf1359c1ccc.

* Bump

* Add line space
2024-01-16 02:40:18 +00:00
Draff c82ebd9e0f Tenkai Scan: Move to Madara (#237)
* Move to Madara

* Remove Madara sources

* I'm idiot

* Revert "Remove Madara sources"

This reverts commit 210ef90eb2774c4011f7868feff68f7966cffb13.
2024-01-16 02:40:06 +00:00
bapeey 6f0d4d21b8 MNS: Fix HTTP 500 and order filter (#235)
* Remove Madara sources

* Fix MangasNoSekai

* Revert "Remove Madara sources"

This reverts commit 915cf5020a8055ab357075f8bb3377afa6c726b2.

* Bump
2024-01-16 02:37:45 +00:00
683 changed files with 2944 additions and 2333 deletions

View File

@ -7,3 +7,4 @@ Checklist:
- [ ] Have not changed source names
- [ ] 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 removed `web_hi_res_512.png` when adding a new extension

View File

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

View File

@ -6,31 +6,54 @@ This guide is not definitive and it's being updated over time. If you find any i
## Table of Contents
1. [Prerequisites](#prerequisites)
1. [Tools](#tools)
2. [Cloning the repository](#cloning-the-repository)
2. [Getting help](#getting-help)
3. [Writing an extension](#writing-an-extension)
1. [Setting up a new Gradle module](#setting-up-a-new-gradle-module)
2. [Core dependencies](#core-dependencies)
3. [Extension main class](#extension-main-class)
4. [Extension call flow](#extension-call-flow)
5. [Misc notes](#misc-notes)
6. [Advanced extension features](#advanced-extension-features)
4. [Multi-source themes](#multi-source-themes)
1. [The directory structure](#the-directory-structure)
2. [Development workflow](#development-workflow)
3. [Scaffolding overrides](#scaffolding-overrides)
4. [Additional Notes](#additional-notes)
5. [Running](#running)
6. [Debugging](#debugging)
1. [Android Debugger](#android-debugger)
2. [Logs](#logs)
3. [Inspecting network calls](#inspecting-network-calls)
4. [Using external network inspecting tools](#using-external-network-inspecting-tools)
7. [Building](#building)
8. [Submitting the changes](#submitting-the-changes)
1. [Pull Request checklist](#pull-request-checklist)
- [Contributing](#contributing)
- [Table of Contents](#table-of-contents)
- [Prerequisites](#prerequisites)
- [Tools](#tools)
- [Cloning the repository](#cloning-the-repository)
- [Getting help](#getting-help)
- [Writing an extension](#writing-an-extension)
- [Setting up a new Gradle module](#setting-up-a-new-gradle-module)
- [Loading a subset of Gradle modules](#loading-a-subset-of-gradle-modules)
- [Extension file structure](#extension-file-structure)
- [AndroidManifest.xml](#androidmanifestxml)
- [build.gradle](#buildgradle)
- [Core dependencies](#core-dependencies)
- [Extension API](#extension-api)
- [DataImage library](#dataimage-library)
- [i18n library](#i18n-library)
- [Additional dependencies](#additional-dependencies)
- [Extension main class](#extension-main-class)
- [Main class key variables](#main-class-key-variables)
- [Extension call flow](#extension-call-flow)
- [Popular Manga](#popular-manga)
- [Latest Manga](#latest-manga)
- [Manga Search](#manga-search)
- [Filters](#filters)
- [Manga Details](#manga-details)
- [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
@ -201,9 +224,8 @@ src/<lang>/<mysourcename>/
│   │   └── ic_launcher.png
│   ├── mipmap-xxhdpi
│   │   └── ic_launcher.png
│   ├── mipmap-xxxhdpi
│   │   └── ic_launcher.png
│   └── web_hi_res_512.png
│   └── mipmap-xxxhdpi
│      └── ic_launcher.png
└── src
└── eu
└── kanade
@ -223,9 +245,6 @@ 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:
```gradle
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
ext {
extName = '<My source name>'
pkgNameSuffix = '<lang>.<mysourcename>'
@ -415,10 +434,15 @@ open class UriPartFilter(displayName: String, private val vals: Array<Pair<Strin
### Misc notes
- Sometimes you may find no use for some inherited methods. If so just override them and throw exceptions: `throw UnsupportedOperationException("Not used.")`
- 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`).
- 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).
- Sometimes you may find no use for some inherited methods. If so just override them and throw
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`).
- 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
@ -495,9 +519,8 @@ multisrc
│   │   │   └── ic_launcher.png
│   │   ├── mipmap-xxhdpi
│   │   │   └── ic_launcher.png
│   │   ├── mipmap-xxxhdpi
│   │   │   └── ic_launcher.png
│   │   └── web_hi_res_512.png
│   │   └── mipmap-xxxhdpi
│   │      └── ic_launcher.png
│   └── <sourcepkg>
│   ├── additional.gradle
│   ├── AndroidManifest.xml
@ -510,9 +533,8 @@ multisrc
│   │   │   └── ic_launcher.png
│   │   ├── mipmap-xxhdpi
│   │   │   └── ic_launcher.png
│   │   ├── mipmap-xxxhdpi
│   │   │   └── ic_launcher.png
│   │   └── web_hi_res_512.png
│   │   └── mipmap-xxxhdpi
│   │      └── ic_launcher.png
│   └── src
│   └── <SourceName>.kt
└── src
@ -739,7 +761,9 @@ 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.
> [!IMPORTANT]
> 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.
> 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. 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.

View File

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

View File

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

View File

@ -21,3 +21,5 @@ org.gradle.caching=true
# Enable AndroidX dependencies
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"
[libraries]
gradle-agp = { module = "com.android.tools.build:gradle", version = "7.4.2" }
gradle-agp = { module = "com.android.tools.build:gradle", version = "8.2.1" }
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-kotlinter = { module = "org.jmailen.gradle:kotlinter-gradle", version = "3.13.0" }

View File

@ -0,0 +1,68 @@
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,6 +19,15 @@ class MangaTR : FMReader("Manga-TR", "https://manga-tr.com", "tr") {
override fun headersBuilder() = super.headersBuilder()
.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"
// =============================== 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

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

View File

@ -0,0 +1,24 @@
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.

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

View File

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

View File

@ -1,11 +1,28 @@
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.network.interceptor.rateLimit
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter
import kotlinx.serialization.Serializable
import kotlinx.serialization.decodeFromString
import okhttp3.Headers
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.Response
import org.jsoup.nodes.Document
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
class Shinigami : Madara("Shinigami", "https://shinigamitoon.com", "id") {
@ -16,15 +33,91 @@ class Shinigami : Madara("Shinigami", "https://shinigamitoon.com", "id") {
override fun searchPage(page: Int): String = if (page == 1) "" else "page/$page/"
override val client: OkHttpClient = super.client.newBuilder()
.rateLimit(4, 1, TimeUnit.SECONDS)
private val preferences: SharedPreferences by lazy {
Injekt.get<Application>().getSharedPreferences("source_$id", 0x0000)
}
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()
override fun headersBuilder(): Headers.Builder = super.headersBuilder()
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()
override fun headersBuilder(): Headers.Builder {
val builder = super.headersBuilder()
.add("Sec-Fetch-Dest", "document")
.add("Sec-Fetch-Mode", "navigate")
.add("Sec-Fetch-Site", "same-origin")
.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"
@ -43,4 +136,76 @@ class Shinigami : Madara("Shinigami", "https://shinigamitoon.com", "id") {
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

@ -0,0 +1,15 @@
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,6 +1,7 @@
package eu.kanade.tachiyomi.extension.es.carteldemanhwas
import eu.kanade.tachiyomi.multisrc.mangathemesia.MangaThemesia
import org.jsoup.nodes.Element
import java.text.SimpleDateFormat
import java.util.Locale
@ -14,6 +15,13 @@ class CarteldeManhwas : MangaThemesia(
override val hasProjectPage = true
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)), " +
".listupd .bs .bsx:not(:has(span.novelabel)), " +
".listo .bs .bsx:not(:has(span.novelabel))"

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

View File

@ -0,0 +1,12 @@
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.

Before

Width:  |  Height:  |  Size: 60 KiB

View File

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

View File

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

View File

@ -40,19 +40,19 @@ open class ComicGamma(
thumbnail_url = element.selectFirst(Evaluator.Tag("img"))!!.absUrl("src")
}
override fun latestUpdatesRequest(page: Int) = throw UnsupportedOperationException("Not used.")
override fun latestUpdatesNextPageSelector() = throw UnsupportedOperationException("Not used.")
override fun latestUpdatesSelector() = throw UnsupportedOperationException("Not used.")
override fun latestUpdatesFromElement(element: Element) = throw UnsupportedOperationException("Not used.")
override fun latestUpdatesRequest(page: Int) = throw UnsupportedOperationException()
override fun latestUpdatesNextPageSelector() = throw UnsupportedOperationException()
override fun latestUpdatesSelector() = throw UnsupportedOperationException()
override fun latestUpdatesFromElement(element: Element) = throw UnsupportedOperationException()
override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable<MangasPage> =
fetchPopularManga(page).map { p -> MangasPage(p.mangas.filter { it.title.contains(query) }, false) }
override fun searchMangaNextPageSelector() = throw UnsupportedOperationException("Not used.")
override fun searchMangaSelector() = throw UnsupportedOperationException("Not used.")
override fun searchMangaFromElement(element: Element) = throw UnsupportedOperationException("Not used.")
override fun searchMangaNextPageSelector() = throw UnsupportedOperationException()
override fun searchMangaSelector() = throw UnsupportedOperationException()
override fun searchMangaFromElement(element: Element) = throw UnsupportedOperationException()
override fun searchMangaRequest(page: Int, query: String, filters: FilterList) =
throw UnsupportedOperationException("Not used.")
throw UnsupportedOperationException()
override fun pageListParse(document: Document) =
document.select("#content > div[data-ptimg]").mapIndexed { i, e ->
@ -91,7 +91,7 @@ open class ComicGamma(
override fun pageListRequest(chapter: SChapter) =
GET(baseUrl + chapter.url.toNewChapterUrl(), headers)
override fun imageUrlParse(document: Document) = throw UnsupportedOperationException("Not used.")
override fun imageUrlParse(document: Document) = throw UnsupportedOperationException()
companion object {
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 popularMangaRequest(page: Int): Request = throw UnsupportedOperationException("Not used")
override fun popularMangaParse(response: Response): MangasPage = throw UnsupportedOperationException("Not used")
override fun popularMangaRequest(page: Int): Request = throw UnsupportedOperationException()
override fun popularMangaParse(response: Response): MangasPage = throw UnsupportedOperationException()
// Latest
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("Not used")
override fun latestUpdatesParse(response: Response): MangasPage = throw UnsupportedOperationException("Not used")
override fun latestUpdatesRequest(page: Int): Request = throw UnsupportedOperationException()
override fun latestUpdatesParse(response: Response): MangasPage = throw UnsupportedOperationException()
// Search
@ -228,8 +228,8 @@ open class EroMuse(override val name: String, override val baseUrl: String) : Ht
.map { response -> parseManga(response.asJsoup()) }
}
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request = throw UnsupportedOperationException("Not used")
override fun searchMangaParse(response: Response): MangasPage = throw UnsupportedOperationException("Not used")
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request = throw UnsupportedOperationException()
override fun searchMangaParse(response: Response): MangasPage = throw UnsupportedOperationException()
// Details
@ -332,7 +332,7 @@ open class EroMuse(override val name: String, override val baseUrl: String) : Ht
return parsePages(response.asJsoup())
}
override fun imageUrlParse(response: Response): String = throw UnsupportedOperationException("Not used")
override fun imageUrlParse(response: Response): String = throw UnsupportedOperationException()
// Filters

View File

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

View File

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

View File

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

View File

@ -14,7 +14,7 @@ class FMReaderGenerator : ThemeSourceGenerator {
override val sources = listOf(
SingleLang("Epik Manga", "https://www.epikmanga.com", "tr"),
SingleLang("KissLove", "https://klz9.com", "ja", isNsfw = true, overrideVersionCode = 4),
SingleLang("Manga-TR", "https://manga-tr.com", "tr", className = "MangaTR", overrideVersionCode = 2),
SingleLang("Manga-TR", "https://manga-tr.com", "tr", className = "MangaTR", overrideVersionCode = 3),
SingleLang("ManhuaRock", "https://manhuarock.net", "vi", overrideVersionCode = 1),
SingleLang("Say Truyen", "https://saytruyenvip.com", "vi", overrideVersionCode = 3),
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("Not used")
override fun imageUrlParse(document: Document) = throw UnsupportedOperationException()
protected val preferences by lazy {
Injekt.get<Application>().getSharedPreferences("source_$id", 0x0000)!!

View File

@ -255,7 +255,7 @@ abstract class GroupLe(
}
override fun chapterFromElement(element: Element): SChapter {
throw Exception("Not used")
throw UnsupportedOperationException()
}
override fun prepareNewChapter(chapter: SChapter, manga: SManga) {
@ -288,6 +288,11 @@ abstract class GroupLe(
var readerMark = "rm_h.readerDoInit(["
// allhentai necessary
if (!html.contains(readerMark)) {
readerMark = "rm_h.readerInit( 0,["
}
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)) {
throw Exception("Для просмотра контента необходима авторизация через WebView\uD83C\uDF0E")

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -65,7 +65,6 @@ class MadaraGenerator : ThemeSourceGenerator {
SingleLang("Cat300", "https://cat300.com", "th", isNsfw = true, className = "Cat300", overrideVersionCode = 1),
SingleLang("CatOnHeadTranslations", "https://catonhead.com", "en", overrideVersionCode = 2),
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("Coco Rip", "https://cocorip.net", "es"),
SingleLang("Coffee Manga", "https://coffeemanga.io", "en", isNsfw = false, overrideVersionCode = 2),
@ -193,7 +192,7 @@ class MadaraGenerator : ThemeSourceGenerator {
SingleLang("Lolicon", "https://lolicon.mobi", "en", isNsfw = true, overrideVersionCode = 2),
SingleLang("Lord Manga", "https://lordmanga.com", "en"),
SingleLang("Luffy Manga", "https://luffymanga.com", "en", isNsfw = false),
SingleLang("LuxManga", "https://luxmanga.com", "en"),
SingleLang("LuxManga", "https://luxmanga.net", "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("Manga 18h", "https://manga18h.com", "en", isNsfw = true),
@ -214,23 +213,22 @@ class MadaraGenerator : ThemeSourceGenerator {
SingleLang("Manga Lord", "https://mangalord.com", "en", overrideVersionCode = 1),
SingleLang("Manga Mammy", "https://mangamammy.ru", "ru", isNsfw = true),
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 One Love", "https://mangaonelove.site/", "ru", isNsfw = true),
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.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 Rock Team", "https://mangarockteam.com", "en", overrideVersionCode = 1),
SingleLang("Manga Rock.team (unoriginal)", "https://mangarock.team", "en", isNsfw = false, className = "MangaRockTeamUnoriginal"),
SingleLang("Manga Rocky", "https://mangarocky.com", "en", overrideVersionCode = 1),
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 Too", "https://mangatoo.com", "en", overrideVersionCode = 1),
SingleLang("Manga Tx.gg (unoriginal)", "https://mangatx.gg", "en", isNsfw = false, className = "MangaTxGg"),
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-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"),
@ -244,8 +242,8 @@ class MadaraGenerator : ThemeSourceGenerator {
SingleLang("MangaBaz", "https://mangabaz.net", "en"),
SingleLang("MangaBob", "https://mangabob.com", "en", overrideVersionCode = 1),
SingleLang("MangaCC", "https://mangacc.com", "en"),
SingleLang("MangaClash.tv (unoriginal)", "https://mangaclash.tv", "en", isNsfw = true, className = "MangaClashTv"),
SingleLang("MangaClash", "https://mangaclash.com", "en", overrideVersionCode = 3),
SingleLang("MangaClash.tv (unoriginal)", "https://mangaclash.tv", "en", isNsfw = true, className = "MangaClashTv"),
SingleLang("MangaCrazy", "https://mangacrazy.net", "all", isNsfw = true),
SingleLang("MangaCultivator", "https://mangacultivator.com", "en", overrideVersionCode = 2),
SingleLang("MangaCV", "https://mangacv.com", "en", isNsfw = true),
@ -287,7 +285,7 @@ class MadaraGenerator : ThemeSourceGenerator {
SingleLang("MangaRosie", "https://mangarosie.in", "en", isNsfw = true),
SingleLang("MangaRuby.com", "https://mangaruby.com", "en", isNsfw = true, className = "MangaRubyCom"),
SingleLang("Mangaryu", "https://mangaryu.com", "en", isNsfw = true),
SingleLang("Mangas No Sekai", "https://mangasnosekai.com", "es", overrideVersionCode = 1),
SingleLang("Mangas No Sekai", "https://mangasnosekai.com", "es", overrideVersionCode = 2),
SingleLang("Mangas Origines", "https://mangas-origines.xyz", "fr", isNsfw = true, overrideVersionCode = 4),
SingleLang("Mangas-Origines.fr", "https://mangas-origines.fr", "fr", className = "MangasOriginesFr"),
SingleLang("MangaSco", "https://manhwasco.net", "en", overrideVersionCode = 2),
@ -307,6 +305,7 @@ class MadaraGenerator : ThemeSourceGenerator {
SingleLang("Mangaxico", "https://mangaxico.com", "es", isNsfw = true),
SingleLang("MangaXP", "https://mangaxp.com", "en", overrideVersionCode = 1),
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("Manhatic", "https://manhatic.com", "ar", isNsfw = true),
SingleLang("Manhua ES", "https://manhuaes.com", "en", overrideVersionCode = 6),
@ -319,12 +318,12 @@ class MadaraGenerator : ThemeSourceGenerator {
SingleLang("ManhuaBox", "https://manhuabox.net", "en", overrideVersionCode = 2),
SingleLang("ManhuaChill", "https://manhuachill.com", "en"),
SingleLang("ManhuaDex", "https://manhuadex.com", "en", isNsfw = false),
SingleLang("ManhuaFast.net (unoriginal)", "https://manhuafast.net", "en", isNsfw = false, className = "ManhuaFastNet"),
SingleLang("ManhuaFast", "https://manhuafast.com", "en", overrideVersionCode = 3),
SingleLang("ManhuaFast.net (unoriginal)", "https://manhuafast.net", "en", isNsfw = false, className = "ManhuaFastNet"),
SingleLang("Manhuaga", "https://manhuaga.com", "en", overrideVersionCode = 2),
SingleLang("ManhuaHot", "https://manhuahot.com", "en"),
SingleLang("ManhuaManhwa.online", "https://manhuamanhwa.online", "en", isNsfw = false, className = "ManhuaManhwaOnline"),
SingleLang("ManhuaManhwa", "https://manhuamanhwa.com", "en", isNsfw = true),
SingleLang("ManhuaManhwa.online", "https://manhuamanhwa.online", "en", isNsfw = false, className = "ManhuaManhwaOnline"),
SingleLang("ManhuaScan.info (unoriginal)", "https://manhuascan.info", "en", isNsfw = true, className = "ManhuaScanInfo"),
SingleLang("ManhuaUS", "https://manhuaus.com", "en", overrideVersionCode = 5),
SingleLang("ManhuaZone", "https://manhuazone.org", "en", overrideVersionCode = 1),
@ -349,8 +348,8 @@ class MadaraGenerator : ThemeSourceGenerator {
SingleLang("Mantraz Scan", "https://mantrazscan.com", "es"),
SingleLang("ManWe", "https://manwe.pro", "tr", className = "EvaScans", overrideVersionCode = 1),
SingleLang("ManyComic", "https://manycomic.com", "en", isNsfw = true, overrideVersionCode = 1),
SingleLang("ManyToon.me", "https://manytoon.me", "en", isNsfw = true, className = "ManyToonMe", overrideVersionCode = 5),
SingleLang("ManyToon", "https://manytoon.com", "en", isNsfw = true, overrideVersionCode = 5),
SingleLang("ManyToon.me", "https://manytoon.me", "en", isNsfw = true, className = "ManyToonMe", overrideVersionCode = 5),
SingleLang("ManyToonClub", "https://manytoon.club", "ko", isNsfw = true, overrideVersionCode = 2),
SingleLang("MG Komik", "https://mgkomik.id", "id", overrideVersionCode = 11),
SingleLang("Midnight Mess Scans", "https://midnightmess.org", "en", isNsfw = true, overrideVersionCode = 6),
@ -372,9 +371,11 @@ class MadaraGenerator : ThemeSourceGenerator {
SingleLang("NekoPost.co (unoriginal)", "https://www.nekopost.co", "th", isNsfw = false, className = "NekoPostCo"),
SingleLang("NekoScan", "https://nekoscan.com", "en", overrideVersionCode = 2),
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("Niji Translations", "https://niji-translations.com", "ar", 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("Noblesse Translations", "https://www.noblessev1.com", "es", overrideVersionCode = 2),
SingleLang("Nocturne Summer", "https://nocsummer.com.br", "pt-BR", isNsfw = true),
@ -453,6 +454,7 @@ class MadaraGenerator : ThemeSourceGenerator {
SingleLang("Tatakae Scan", "https://tatakaescan.com", "pt-BR", isNsfw = true, overrideVersionCode = 2),
SingleLang("Taurus Fansub", "https://taurusmanga.com", "es", 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 Blank Scanlation", "https://theblank.net", "en", className = "TheBlank", isNsfw = true),
SingleLang("The Guild", "https://theguildscans.com", "en"),
@ -502,18 +504,19 @@ class MadaraGenerator : ThemeSourceGenerator {
SingleLang("Yuri Verso", "https://yuri.live", "pt-BR", overrideVersionCode = 3),
SingleLang("Zandy no Fansub", "https://zandynofansub.aishiteru.org", "en"),
SingleLang("ZinChanManga", "https://zinchanmanga.com", "en", isNsfw = true),
SingleLang("ZinManga.top (unoriginal)", "https://zinmanga.top", "en", isNsfw = false, className = "ZinMangaTop"),
SingleLang("Zinmanga", "https://zinmanga.com", "en", overrideVersionCode = 1),
SingleLang("ZinManga.top (unoriginal)", "https://zinmanga.top", "en", isNsfw = false, className = "ZinMangaTop"),
SingleLang("Zinmanhwa", "https://zinmanhwa.com", "en"),
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://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://manga-lek.net", "ar", className = "Mangalek", overrideVersionCode = 4),
SingleLang("مانجا ليكس", "https://mangaleks.com", "ar", className = "MangaLeks"),
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"),
)

View File

@ -277,7 +277,7 @@ abstract class MadTheme(
}
override fun imageUrlParse(document: Document): String =
throw UnsupportedOperationException("Not used.")
throw UnsupportedOperationException()
// Date logic lifted from Madara
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())
}
override fun imageUrlParse(document: Document): String = throw UnsupportedOperationException("Not used")
override fun imageUrlParse(document: Document): String = throw UnsupportedOperationException()
// Based on change_alias JS function from Mangakakalot's website
@SuppressLint("DefaultLocale")

View File

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

View File

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

View File

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

View File

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

View File

@ -30,7 +30,7 @@ class MangaThemesiaGenerator : ThemeSourceGenerator {
SingleLang("Berserker Scan", "https://ragnascan.com", "es"),
SingleLang("BirdManga", "https://birdmanga.com", "en"),
SingleLang("Boosei", "https://boosei.net", "id", overrideVersionCode = 2),
SingleLang("Cartel de Manhwas", "https://carteldemanhwas.com", "es", overrideVersionCode = 5),
SingleLang("Cartel de Manhwas", "https://carteldemanhwas.com", "es", overrideVersionCode = 6),
SingleLang("Constellar Scans", "https://constellarcomic.com", "en", isNsfw = true, overrideVersionCode = 16),
SingleLang("Cosmic Scans", "https://cosmic-scans.com", "en", overrideVersionCode = 2),
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("KomikMama", "https://komikmama.co", "id", overrideVersionCode = 1),
SingleLang("KomikManhwa", "https://komikmanhwa.me", "id", isNsfw = true),
SingleLang("Komiktap", "https://komiktap.me", "id", isNsfw = true),
SingleLang("Komiksan", "https://komiksan.link", "id", overrideVersionCode = 2),
SingleLang("Komiktap", "https://komiktap.me", "id", isNsfw = true),
SingleLang("Komiku.com", "https://komiku.com", "id", className = "KomikuCom"),
SingleLang("Kuma Scans (Kuma Translation)", "https://kumascans.com", "en", className = "KumaScans", overrideVersionCode = 1),
SingleLang("KumaPoi", "https://kumapoi.info", "id", isNsfw = true, overrideVersionCode = 3),
@ -86,7 +86,6 @@ class MangaThemesiaGenerator : ThemeSourceGenerator {
SingleLang("Mangacim", "https://www.mangacim.com", "tr", overrideVersionCode = 1),
SingleLang("MangaKita", "https://mangakita.id", "id", overrideVersionCode = 2),
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("MangaShiro", "https://mangashiro.me", "id"),
SingleLang("Mangasusu", "https://mangasusuku.xyz", "id", isNsfw = true, overrideVersionCode = 3),
@ -94,6 +93,7 @@ class MangaThemesiaGenerator : ThemeSourceGenerator {
SingleLang("MangaTale", "https://mangatale.co", "id", overrideVersionCode = 1),
SingleLang("MangaWT", "https://mangawt.com", "tr", overrideVersionCode = 5),
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("Manhwa Freak", "https://manhwa-freak.com", "en", overrideVersionCode = 3),
SingleLang("Manhwa Lover", "https://manhwalover.com", "en", isNsfw = true, overrideVersionCode = 1),
@ -137,6 +137,7 @@ class MangaThemesiaGenerator : ThemeSourceGenerator {
SingleLang("Senpai Ediciones", "http://senpaiediciones.com", "es", overrideVersionCode = 1),
SingleLang("Shadow Mangas", "https://shadowmangas.com", "es", overrideVersionCode = 1),
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("Siren Komik", "https://sirenkomik.my.id", "id", className = "MangKomik", overrideVersionCode = 2),
SingleLang("SkyMangas", "https://skymangas.com", "es", overrideVersionCode = 1),
@ -152,7 +153,6 @@ class MangaThemesiaGenerator : ThemeSourceGenerator {
SingleLang("Sushiscan.fr", "https://anime-sama.me", "fr", className = "SushiScanFR", overrideVersionCode = 1),
SingleLang("Tarot Scans", "https://www.tarotscans.com", "tr"),
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("The Apollo Team", "https://theapollo.team", "en"),
SingleLang("Tres Daos Scan", "https://tresdaos.com", "es"),

View File

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

View File

@ -96,7 +96,7 @@ open class MCCMS(
}
}
override fun mangaDetailsParse(response: Response): SManga = throw UnsupportedOperationException("Not used.")
override fun mangaDetailsParse(response: Response): SManga = throw UnsupportedOperationException()
override fun fetchChapterList(manga: SManga): Observable<List<SChapter>> = Observable.fromCallable {
val id = getMangaId(manga.url)
@ -112,7 +112,7 @@ open class MCCMS(
protected open fun getMangaId(url: String) = url.substringAfterLast('/')
override fun chapterListParse(response: Response): List<SChapter> = throw UnsupportedOperationException("Not used.")
override fun chapterListParse(response: Response): List<SChapter> = throw UnsupportedOperationException()
override fun pageListRequest(chapter: SChapter): Request =
GET(baseUrl + chapter.url, pcHeaders)
@ -126,7 +126,7 @@ open class MCCMS(
}
}
override fun imageUrlParse(response: Response) = throw UnsupportedOperationException("Not used.")
override fun imageUrlParse(response: Response) = throw UnsupportedOperationException()
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)
}
override fun imageUrlParse(response: Response) = throw UnsupportedOperationException("Unused method called!")
override fun imageUrlParse(response: Response) = throw UnsupportedOperationException()
private fun getInitialFilterList() = listOf<Filter<*>>(
Filter.Header("NOTE: Ignored if using text search!"),

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -31,7 +31,7 @@ class ComicFury(
private val extraName: String = "",
) : HttpSource(), ConfigurableSource {
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
private val dateFormat = SimpleDateFormat("dd MMM yyyy hh:mm aa", 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 imageUrlParse(response: Response): String =
throw UnsupportedOperationException("Not Used")
throw UnsupportedOperationException()
private fun String.toDate(): Long {
val ret = this.replace("st", "")

View File

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

View File

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

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