diff --git a/multisrc/overrides/comicake/letitgoscans/src/LetItGoScans.kt b/multisrc/overrides/comicake/letitgoscans/src/LetItGoScans.kt deleted file mode 100644 index 169c2684b..000000000 --- a/multisrc/overrides/comicake/letitgoscans/src/LetItGoScans.kt +++ /dev/null @@ -1,5 +0,0 @@ -package eu.kanade.tachiyomi.extension.en.letitgoscans - -import eu.kanade.tachiyomi.multisrc.comicake.ComiCake - -class LetItGoScans : ComiCake("LetItGo Scans", "https://reader.letitgo.scans.today", "en", "/") diff --git a/multisrc/overrides/foolslide/baixarhentai/src/BaixarHentai.kt b/multisrc/overrides/foolslide/baixarhentai/src/BaixarHentai.kt index 38db445fb..5fceba802 100644 --- a/multisrc/overrides/foolslide/baixarhentai/src/BaixarHentai.kt +++ b/multisrc/overrides/foolslide/baixarhentai/src/BaixarHentai.kt @@ -1,30 +1,29 @@ package eu.kanade.tachiyomi.extension.pt.baixarhentai -import eu.kanade.tachiyomi.multisrc.foolslide.FoolSlide +import androidx.preference.PreferenceScreen import eu.kanade.tachiyomi.annotations.Nsfw import eu.kanade.tachiyomi.lib.ratelimit.RateLimitInterceptor +import eu.kanade.tachiyomi.multisrc.foolslide.FoolSlide import eu.kanade.tachiyomi.source.model.SManga -import okhttp3.OkHttpClient import org.jsoup.nodes.Document import java.util.concurrent.TimeUnit @Nsfw -class BaixarHentai : FoolSlide( - "Baixar Hentai", - "https://leitura.baixarhentai.net", - "pt-BR" -) { +class BaixarHentai : FoolSlide("Baixar Hentai", "https://leitura.baixarhentai.net", "pt-BR") { // Hardcode the id because the language wasn't specific. - override val id: Long = 8908032188831949972 + override val id = 8908032188831949972 - override val client: OkHttpClient = super.client.newBuilder() + override val client = super.client.newBuilder() .addInterceptor(RateLimitInterceptor(1, 2, TimeUnit.SECONDS)) .build() - override fun mangaDetailsParse(document: Document): SManga { - return SManga.create().apply { - title = document.select("h1.title").text() - thumbnail_url = getDetailsThumbnail(document, "div.title a") - } + override fun mangaDetailsParse(document: Document) = SManga.create().apply { + title = document.select("h1.title").text() + thumbnail_url = getDetailsThumbnail(document, "div.title a") } + + // Always show adult content + override val allowAdult = true + + override fun setupPreferenceScreen(screen: PreferenceScreen) {} } diff --git a/multisrc/overrides/foolslide/foolslidecustomizable/src/FoolSlideCustomizableFactory.kt b/multisrc/overrides/foolslide/foolslidecustomizable/src/FoolSlideCustomizableFactory.kt index cfaab650c..c7a349599 100644 --- a/multisrc/overrides/foolslide/foolslidecustomizable/src/FoolSlideCustomizableFactory.kt +++ b/multisrc/overrides/foolslide/foolslidecustomizable/src/FoolSlideCustomizableFactory.kt @@ -1,34 +1,28 @@ package eu.kanade.tachiyomi.extension.all.foolslidecustomizable -import eu.kanade.tachiyomi.multisrc.foolslide.FoolSlide -import eu.kanade.tachiyomi.source.Source -import eu.kanade.tachiyomi.source.SourceFactory -import android.app.Application -import android.content.SharedPreferences import android.widget.Toast +import androidx.preference.EditTextPreference +import androidx.preference.PreferenceScreen import eu.kanade.tachiyomi.BuildConfig -import eu.kanade.tachiyomi.source.ConfigurableSource -import uy.kohesive.injekt.Injekt -import uy.kohesive.injekt.api.get +import eu.kanade.tachiyomi.multisrc.foolslide.FoolSlide +import eu.kanade.tachiyomi.source.SourceFactory class FoolSlideCustomizableFactory : SourceFactory { - override fun createSources(): List = listOf( - FoolSlideCustomizable(), - ) + override fun createSources() = listOf(FoolSlideCustomizable()) } -class FoolSlideCustomizable : ConfigurableSource, FoolSlide("FoolSlide Customizable", "", "other") { - override val baseUrl: String by lazy { getPrefBaseUrl() } - private val preferences: SharedPreferences by lazy { - Injekt.get().getSharedPreferences("source_$id", 0x0000) +class FoolSlideCustomizable : FoolSlide("FoolSlide Customizable", "", "other") { + override val baseUrl: String by lazy { + preferences.getString(BASE_URL_PREF, DEFAULT_BASEURL)!!.substringBefore("/directory") } - override fun setupPreferenceScreen(screen: androidx.preference.PreferenceScreen) { - val baseUrlPref = androidx.preference.EditTextPreference(screen.context).apply { + override fun setupPreferenceScreen(screen: PreferenceScreen) { + super.setupPreferenceScreen(screen) + EditTextPreference(screen.context).apply { key = BASE_URL_PREF_TITLE title = BASE_URL_PREF_TITLE summary = BASE_URL_PREF_SUMMARY - this.setDefaultValue(DEFAULT_BASEURL) + setDefaultValue(DEFAULT_BASEURL) dialogTitle = BASE_URL_PREF_TITLE dialogMessage = "Default: $DEFAULT_BASEURL" @@ -42,17 +36,9 @@ class FoolSlideCustomizable : ConfigurableSource, FoolSlide("FoolSlide Customiza false } } - } - - screen.addPreference(baseUrlPref) + }.let(screen::addPreference) } - /** - * Tell the user to include /directory/ in the URL even though we remove it - * To increase the chance they input a usable URL - */ - private fun getPrefBaseUrl() = preferences.getString(BASE_URL_PREF, DEFAULT_BASEURL)!!.substringBefore("/directory") - companion object { private const val DEFAULT_BASEURL = "https://127.0.0.1" private const val BASE_URL_PREF_TITLE = "Example URL: https://domain.com/path_to/directory/" diff --git a/multisrc/overrides/foolslide/hniscantrad/src/HNIScantradFactory.kt b/multisrc/overrides/foolslide/hniscantrad/src/HNIScantradFactory.kt index 88a3e9f17..b83c06f7f 100644 --- a/multisrc/overrides/foolslide/hniscantrad/src/HNIScantradFactory.kt +++ b/multisrc/overrides/foolslide/hniscantrad/src/HNIScantradFactory.kt @@ -1,50 +1,19 @@ package eu.kanade.tachiyomi.extension.all.hniscantrad import eu.kanade.tachiyomi.multisrc.foolslide.FoolSlide -import eu.kanade.tachiyomi.source.Source import eu.kanade.tachiyomi.source.SourceFactory -import eu.kanade.tachiyomi.network.GET -import eu.kanade.tachiyomi.source.model.FilterList -import eu.kanade.tachiyomi.source.model.Page -import eu.kanade.tachiyomi.source.model.SChapter -import eu.kanade.tachiyomi.source.model.SManga -import okhttp3.Request import okhttp3.Response -import org.jsoup.nodes.Element class HNIScantradFactory : SourceFactory { - override fun createSources(): List = listOf( - HNIScantradFR(), - HNIScantradEN(), - ) + override fun createSources() = listOf(HNIScantradFR(), HNIScantradEN()) } -class HNIScantradFR : FoolSlide("HNI-Scantrad", "https://hni-scantrad.com", "fr", "/lel") -class HNIScantradEN : FoolSlide("HNI-Scantrad", "https://hni-scantrad.com", "en", "/eng/lel") { - override val supportsLatest = false - override fun popularMangaRequest(page: Int) = GET(baseUrl + urlModifier, headers) - override fun popularMangaSelector() = "div.listed" - override fun popularMangaFromElement(element: Element): SManga { - return SManga.create().apply { - element.select("a:has(h3)").let { - title = it.text() - setUrlWithoutDomain(it.attr("abs:href")) - } - thumbnail_url = element.select("img").attr("abs:src") - } - } - override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request = GET("$baseUrl$urlModifier/?manga=${query.replace(" ", "+")}") - override fun searchMangaSelector(): String = popularMangaSelector() - override fun searchMangaFromElement(element: Element): SManga = popularMangaFromElement(element) - override fun chapterListSelector() = "div.theList > a" - override fun chapterFromElement(element: Element): SChapter { - return SChapter.create().apply { - name = element.select("div.chapter b").text() - setUrlWithoutDomain(element.attr("abs:href")) - } - } - override fun pageListParse(response: Response): List { - return Regex("""imageArray\[\d+]='(.*)'""").findAll(response.body!!.string()).toList().mapIndexed { i, mr -> - Page(i, "", "$baseUrl$urlModifier/${mr.groupValues[1]}") - } - } + +class HNIScantradFR : FoolSlide("HNI-Scantrad", "https://hni-scantrad.com", "fr", "/lel") { + override fun chapterListParse(response: Response) = + super.chapterListParse(response).filter { "/fr/" in it.url } +} + +class HNIScantradEN : FoolSlide("HNI-Scantrad", "https://hni-scantrad.com", "en", "/lel") { + override fun chapterListParse(response: Response) = + super.chapterListParse(response).filter { "/en-us/" in it.url } } diff --git a/multisrc/overrides/foolslide/hyakuro/src/Hyakuro.kt b/multisrc/overrides/foolslide/hyakuro/src/Hyakuro.kt index fb0c4e945..7366b7de8 100644 --- a/multisrc/overrides/foolslide/hyakuro/src/Hyakuro.kt +++ b/multisrc/overrides/foolslide/hyakuro/src/Hyakuro.kt @@ -4,12 +4,10 @@ import eu.kanade.tachiyomi.multisrc.foolslide.FoolSlide import eu.kanade.tachiyomi.source.model.SManga import org.jsoup.nodes.Document -class Hyakuro : FoolSlide("Hyakuro", "https://hyakuro.com/reader/", "en") { - override fun mangaDetailsParse(document: Document): SManga { - return SManga.create().apply { - description = document.select("$mangaDetailsInfoSelector li:has(b:contains(description))") - .first()?.ownText()?.substringAfter(":") - thumbnail_url = getDetailsThumbnail(document) - } +class Hyakuro : FoolSlide("Hyakuro", "https://hyakuro.com", "en", "/reader") { + override fun mangaDetailsParse(document: Document) = SManga.create().apply { + description = document.select("$mangaDetailsInfoSelector li:has(b:contains(description))") + .first()?.ownText()?.substringAfter(":") + thumbnail_url = getDetailsThumbnail(document) } } diff --git a/multisrc/overrides/foolslide/kireicake/src/KireiCake.kt b/multisrc/overrides/foolslide/kireicake/src/KireiCake.kt index 3ec78715b..84816a3dd 100644 --- a/multisrc/overrides/foolslide/kireicake/src/KireiCake.kt +++ b/multisrc/overrides/foolslide/kireicake/src/KireiCake.kt @@ -5,11 +5,9 @@ import eu.kanade.tachiyomi.source.model.SManga import org.jsoup.nodes.Document class KireiCake : FoolSlide("Kirei Cake", "https://reader.kireicake.com", "en") { - override fun mangaDetailsParse(document: Document): SManga { - return SManga.create().apply { - description = document.select("$mangaDetailsInfoSelector li:has(b:contains(description))") - .first()?.ownText()?.substringAfter(":") - thumbnail_url = getDetailsThumbnail(document) - } + override fun mangaDetailsParse(document: Document) = SManga.create().apply { + description = document.select("$mangaDetailsInfoSelector li:has(b:contains(description))") + .first()?.ownText()?.substringAfter(":") + thumbnail_url = getDetailsThumbnail(document) } } diff --git a/multisrc/overrides/foolslide/lecercleduscan/src/LeCercleDuScan.kt b/multisrc/overrides/foolslide/lecercleduscan/src/LeCercleDuScan.kt index 71d15205e..71326c540 100644 --- a/multisrc/overrides/foolslide/lecercleduscan/src/LeCercleDuScan.kt +++ b/multisrc/overrides/foolslide/lecercleduscan/src/LeCercleDuScan.kt @@ -1,18 +1,15 @@ package eu.kanade.tachiyomi.extension.fr.lecercleduscan import eu.kanade.tachiyomi.multisrc.foolslide.FoolSlide +import java.util.Locale class LeCercleDuScan : FoolSlide("Le Cercle du Scan", "https://lel.lecercleduscan.com", "fr") { - - override fun parseChapterDate(date: String): Long? { - val dateToEnglish = when (val lcDate = date.toLowerCase()) { + override fun parseChapterDate(date: String) = super.parseChapterDate( + when (val lcDate = date.toLowerCase(Locale.FRENCH)) { "hier" -> "yesterday" "aujourd'hui" -> "today" "demain" -> "tomorrow" - else -> lcDate } - - return super.parseChapterDate(dateToEnglish) - } + ) } diff --git a/multisrc/overrides/comicake/letitgoscans/res/mipmap-hdpi/ic_launcher.png b/multisrc/overrides/foolslide/letitgoscans/res/mipmap-hdpi/ic_launcher.png similarity index 100% rename from multisrc/overrides/comicake/letitgoscans/res/mipmap-hdpi/ic_launcher.png rename to multisrc/overrides/foolslide/letitgoscans/res/mipmap-hdpi/ic_launcher.png diff --git a/multisrc/overrides/comicake/letitgoscans/res/mipmap-mdpi/ic_launcher.png b/multisrc/overrides/foolslide/letitgoscans/res/mipmap-mdpi/ic_launcher.png similarity index 100% rename from multisrc/overrides/comicake/letitgoscans/res/mipmap-mdpi/ic_launcher.png rename to multisrc/overrides/foolslide/letitgoscans/res/mipmap-mdpi/ic_launcher.png diff --git a/multisrc/overrides/comicake/letitgoscans/res/mipmap-xhdpi/ic_launcher.png b/multisrc/overrides/foolslide/letitgoscans/res/mipmap-xhdpi/ic_launcher.png similarity index 100% rename from multisrc/overrides/comicake/letitgoscans/res/mipmap-xhdpi/ic_launcher.png rename to multisrc/overrides/foolslide/letitgoscans/res/mipmap-xhdpi/ic_launcher.png diff --git a/multisrc/overrides/comicake/letitgoscans/res/mipmap-xxhdpi/ic_launcher.png b/multisrc/overrides/foolslide/letitgoscans/res/mipmap-xxhdpi/ic_launcher.png similarity index 100% rename from multisrc/overrides/comicake/letitgoscans/res/mipmap-xxhdpi/ic_launcher.png rename to multisrc/overrides/foolslide/letitgoscans/res/mipmap-xxhdpi/ic_launcher.png diff --git a/multisrc/overrides/comicake/letitgoscans/res/mipmap-xxxhdpi/ic_launcher.png b/multisrc/overrides/foolslide/letitgoscans/res/mipmap-xxxhdpi/ic_launcher.png similarity index 100% rename from multisrc/overrides/comicake/letitgoscans/res/mipmap-xxxhdpi/ic_launcher.png rename to multisrc/overrides/foolslide/letitgoscans/res/mipmap-xxxhdpi/ic_launcher.png diff --git a/multisrc/overrides/comicake/letitgoscans/res/web_hi_res_512.png b/multisrc/overrides/foolslide/letitgoscans/res/web_hi_res_512.png similarity index 100% rename from multisrc/overrides/comicake/letitgoscans/res/web_hi_res_512.png rename to multisrc/overrides/foolslide/letitgoscans/res/web_hi_res_512.png diff --git a/multisrc/overrides/foolslide/lupiteam/src/LupiTeam.kt b/multisrc/overrides/foolslide/lupiteam/src/LupiTeam.kt index ed725efc8..560c3298b 100644 --- a/multisrc/overrides/foolslide/lupiteam/src/LupiTeam.kt +++ b/multisrc/overrides/foolslide/lupiteam/src/LupiTeam.kt @@ -5,22 +5,17 @@ import eu.kanade.tachiyomi.source.model.SManga import org.jsoup.nodes.Document class LupiTeam : FoolSlide("LupiTeam", "https://lupiteam.net", "it", "/reader") { - override fun mangaDetailsParse(document: Document): SManga { + override fun mangaDetailsParse(document: Document) = SManga.create().apply { val infoElement = document.select(mangaDetailsInfoSelector).first().text() - - val manga = SManga.create() - manga.author = infoElement.substringAfter("Autore: ").substringBefore("Artista: ") - manga.artist = infoElement.substringAfter("Artista: ").substringBefore("Target: ") - val stato = infoElement.substringAfter("Stato: ").substringBefore("Trama: ").substring(0, 8) - manga.status = when (stato) { + author = infoElement.substringAfter("Autore: ").substringBefore("Artista: ") + artist = infoElement.substringAfter("Artista: ").substringBefore("Target: ") + status = when (infoElement.substringAfter("Stato: ").substringBefore("Trama: ").take(8)) { "In corso" -> SManga.ONGOING "Completa" -> SManga.COMPLETED "Licenzia" -> SManga.LICENSED else -> SManga.UNKNOWN } - manga.description = infoElement.substringAfter("Trama: ") - manga.thumbnail_url = getDetailsThumbnail(document) - - return manga + description = infoElement.substringAfter("Trama: ") + thumbnail_url = getDetailsThumbnail(document) } } diff --git a/multisrc/overrides/foolslide/mangatellers/res/mipmap-hdpi/ic_launcher.png b/multisrc/overrides/foolslide/mangatellers/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 000000000..a31c87697 Binary files /dev/null and b/multisrc/overrides/foolslide/mangatellers/res/mipmap-hdpi/ic_launcher.png differ diff --git a/multisrc/overrides/foolslide/mangatellers/res/mipmap-mdpi/ic_launcher.png b/multisrc/overrides/foolslide/mangatellers/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 000000000..02c8bb187 Binary files /dev/null and b/multisrc/overrides/foolslide/mangatellers/res/mipmap-mdpi/ic_launcher.png differ diff --git a/multisrc/overrides/foolslide/mangatellers/res/mipmap-xhdpi/ic_launcher.png b/multisrc/overrides/foolslide/mangatellers/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 000000000..721c83311 Binary files /dev/null and b/multisrc/overrides/foolslide/mangatellers/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/multisrc/overrides/foolslide/mangatellers/res/mipmap-xxhdpi/ic_launcher.png b/multisrc/overrides/foolslide/mangatellers/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 000000000..becc0e0f8 Binary files /dev/null and b/multisrc/overrides/foolslide/mangatellers/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/multisrc/overrides/foolslide/mangatellers/res/mipmap-xxxhdpi/ic_launcher.png b/multisrc/overrides/foolslide/mangatellers/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 000000000..f5ced5084 Binary files /dev/null and b/multisrc/overrides/foolslide/mangatellers/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/multisrc/overrides/foolslide/mangatellers/res/web_hi_res_512.png b/multisrc/overrides/foolslide/mangatellers/res/web_hi_res_512.png new file mode 100644 index 000000000..e40a6cb99 Binary files /dev/null and b/multisrc/overrides/foolslide/mangatellers/res/web_hi_res_512.png differ diff --git a/multisrc/overrides/foolslide/mangatellers/src/Mangatellers.kt b/multisrc/overrides/foolslide/mangatellers/src/Mangatellers.kt index f19f5d991..e93ac54e6 100644 --- a/multisrc/overrides/foolslide/mangatellers/src/Mangatellers.kt +++ b/multisrc/overrides/foolslide/mangatellers/src/Mangatellers.kt @@ -1,11 +1,5 @@ package eu.kanade.tachiyomi.extension.en.mangatellers import eu.kanade.tachiyomi.multisrc.foolslide.FoolSlide -import eu.kanade.tachiyomi.network.GET -import okhttp3.Request -class Mangatellers : FoolSlide("Mangatellers", "http://www.mangatellers.gr", "en", "/reader/reader") { - override fun popularMangaRequest(page: Int): Request { - return GET("$baseUrl$urlModifier/list/$page/", headers) - } -} +class Mangatellers : FoolSlide("Mangatellers", "https://reader.mangatellers.gr", "en") diff --git a/multisrc/overrides/foolslide/thecatscans/res/mipmap-hdpi/ic_launcher.png b/multisrc/overrides/foolslide/thecatscans/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 000000000..03dbdd273 Binary files /dev/null and b/multisrc/overrides/foolslide/thecatscans/res/mipmap-hdpi/ic_launcher.png differ diff --git a/multisrc/overrides/foolslide/thecatscans/res/mipmap-mdpi/ic_launcher.png b/multisrc/overrides/foolslide/thecatscans/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 000000000..3240c189d Binary files /dev/null and b/multisrc/overrides/foolslide/thecatscans/res/mipmap-mdpi/ic_launcher.png differ diff --git a/multisrc/overrides/foolslide/thecatscans/res/mipmap-xhdpi/ic_launcher.png b/multisrc/overrides/foolslide/thecatscans/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 000000000..7e6cc065f Binary files /dev/null and b/multisrc/overrides/foolslide/thecatscans/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/multisrc/overrides/foolslide/thecatscans/res/mipmap-xxhdpi/ic_launcher.png b/multisrc/overrides/foolslide/thecatscans/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 000000000..6ab024064 Binary files /dev/null and b/multisrc/overrides/foolslide/thecatscans/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/multisrc/overrides/foolslide/thecatscans/res/mipmap-xxxhdpi/ic_launcher.png b/multisrc/overrides/foolslide/thecatscans/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 000000000..7eb409985 Binary files /dev/null and b/multisrc/overrides/foolslide/thecatscans/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/multisrc/overrides/foolslide/thecatscans/res/web_hi_res_512.png b/multisrc/overrides/foolslide/thecatscans/res/web_hi_res_512.png new file mode 100644 index 000000000..54cf3959c Binary files /dev/null and b/multisrc/overrides/foolslide/thecatscans/res/web_hi_res_512.png differ diff --git a/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/comicake/ComiCakeGenerator.kt b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/comicake/ComiCakeGenerator.kt index 7baa3aff5..58bf697ca 100644 --- a/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/comicake/ComiCakeGenerator.kt +++ b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/comicake/ComiCakeGenerator.kt @@ -12,7 +12,6 @@ class ComiCakeGenerator : ThemeSourceGenerator { override val baseVersionCode: Int = 1 override val sources = listOf( - SingleLang("LetItGo Scans", "https://reader.letitgo.scans.today", "en"), SingleLang("WhimSubs", "https://whimsubs.xyz", "en") ) diff --git a/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/foolslide/FoolSlide.kt b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/foolslide/FoolSlide.kt index 83816b13b..f5c230518 100644 --- a/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/foolslide/FoolSlide.kt +++ b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/foolslide/FoolSlide.kt @@ -1,7 +1,13 @@ package eu.kanade.tachiyomi.multisrc.foolslide +import android.app.Application +import android.os.Build +import androidx.preference.CheckBoxPreference +import androidx.preference.PreferenceScreen +import eu.kanade.tachiyomi.BuildConfig import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.POST +import eu.kanade.tachiyomi.source.ConfigurableSource import eu.kanade.tachiyomi.source.model.FilterList import eu.kanade.tachiyomi.source.model.MangasPage import eu.kanade.tachiyomi.source.model.Page @@ -17,26 +23,24 @@ import okhttp3.Request import okhttp3.Response import org.jsoup.nodes.Document import org.jsoup.nodes.Element -import uy.kohesive.injekt.injectLazy +import uy.kohesive.injekt.Injekt +import uy.kohesive.injekt.api.get import java.text.ParseException import java.text.SimpleDateFormat import java.util.Calendar import java.util.Date -import java.util.HashSet import java.util.Locale abstract class FoolSlide( override val name: String, override val baseUrl: String, override val lang: String, - val urlModifier: String = "" -) : ParsedHttpSource() { - - protected open val dedupeLatestUpdates = true + open val urlModifier: String = "" +) : ConfigurableSource, ParsedHttpSource() { override val supportsLatest = true - private val json: Json by injectLazy() + private val json by lazy { Injekt.get() } override fun popularMangaSelector() = "div.group" @@ -44,48 +48,39 @@ abstract class FoolSlide( return GET("$baseUrl$urlModifier/directory/$page/", headers) } - val latestUpdatesUrls = HashSet() + private val latestUpdatesUrls = mutableSetOf() override fun latestUpdatesParse(response: Response): MangasPage { val mp = super.latestUpdatesParse(response) - return if (dedupeLatestUpdates) { - val mangas = mp.mangas.distinctBy { it.url }.filterNot { latestUpdatesUrls.contains(it.url) } - latestUpdatesUrls.addAll(mangas.map { it.url }) - MangasPage(mangas, mp.hasNextPage) - } else mp + return mp.copy( + mp.mangas.distinctBy { it.url }.filter { + latestUpdatesUrls.add(it.url) + } + ) } override fun latestUpdatesSelector() = "div.group" override fun latestUpdatesRequest(page: Int): Request { - if (page == 1) { - latestUpdatesUrls.clear() - } + if (page == 1) latestUpdatesUrls.clear() return GET("$baseUrl$urlModifier/latest/$page/") } - override fun popularMangaFromElement(element: Element): SManga { - val manga = SManga.create() - + override fun popularMangaFromElement(element: Element) = SManga.create().apply { element.select("a[title]").first().let { - manga.setUrlWithoutDomain(it.attr("href")) - manga.title = it.text() + setUrlWithoutDomain(it.attr("href")) + title = it.text() } - element.select("img").first()?.let { - manga.thumbnail_url = it.absUrl("src").replace("/thumb_", "/") + thumbnail_url = it.absUrl("src").replace("/thumb_", "/") } - - return manga } - override fun latestUpdatesFromElement(element: Element): SManga { - val manga = SManga.create() + override fun latestUpdatesFromElement(element: Element) = SManga.create().apply { element.select("a[title]").first().let { - manga.setUrlWithoutDomain(it.attr("href")) - manga.title = it.text() + setUrlWithoutDomain(it.attr("href")) + title = it.text() } - return manga } override fun popularMangaNextPageSelector() = "div.next" @@ -94,11 +89,8 @@ abstract class FoolSlide( override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { val searchHeaders = headersBuilder().add("Content-Type", "application/x-www-form-urlencoded").build() - - val form = FormBody.Builder() - .add("search", query) - - return POST("$baseUrl$urlModifier/search/", searchHeaders, form.build()) + val form = FormBody.Builder().add("search", query).build() + return POST("$baseUrl$urlModifier/search/", searchHeaders, form) } override fun searchMangaSelector() = "div.group" @@ -116,61 +108,52 @@ abstract class FoolSlide( override fun mangaDetailsRequest(manga: SManga) = allowAdult(super.mangaDetailsRequest(manga)) - open val mangaDetailsInfoSelector = "div.info" + protected open val mangaDetailsInfoSelector = "div.info" // if there's no image on the details page, get the first page of the first chapter - fun getDetailsThumbnail(document: Document, urlSelector: String = chapterUrlSelector): String? { + protected fun getDetailsThumbnail(document: Document, urlSelector: String = chapterUrlSelector): String? { return document.select("div.thumbnail img, table.thumb img").firstOrNull()?.attr("abs:src") ?: document.select(chapterListSelector()).last().select(urlSelector).attr("abs:href") - .let { url -> client.newCall(allowAdult(GET(url, headers))).execute() } + .let { url -> client.newCall(allowAdult(GET(url))).execute() } .let { response -> pageListParse(response).first().imageUrl } } - override fun mangaDetailsParse(document: Document): SManga { - return SManga.create().apply { - document.select(mangaDetailsInfoSelector).firstOrNull()?.html()?.let { infoHtml -> - author = Regex("""(?i)(Author|Autore):\s?([^\n<]*)[\n<]""").find(infoHtml)?.groupValues?.get(2) - artist = Regex("""Artist:\s?([^\n<]*)[\n<]""").find(infoHtml)?.groupValues?.get(1) - description = Regex("""(?i)(Synopsis|Description|Trama):\s?([^\n<]*)[\n<]""").find(infoHtml)?.groupValues?.get(2) - } - thumbnail_url = getDetailsThumbnail(document) + override fun mangaDetailsParse(document: Document) = SManga.create().apply { + document.select(mangaDetailsInfoSelector).firstOrNull()?.html()?.let { infoHtml -> + author = Regex("""(?i)(Author|Autore):\s?([^\n<]*)[\n<]""").find(infoHtml)?.groupValues?.get(2) + artist = Regex("""Artist:\s?([^\n<]*)[\n<]""").find(infoHtml)?.groupValues?.get(1) + description = Regex("""(?i)(Synopsis|Description|Trama):\s?([^\n<]*)[\n<]""").find(infoHtml)?.groupValues?.get(2) } + thumbnail_url = getDetailsThumbnail(document) } - /** - * Transform a GET request into a POST request that automatically authorizes all adult content - */ - private fun allowAdult(request: Request) = allowAdult(request.url.toString()) + protected open val allowAdult: Boolean + get() = preferences.getBoolean("adult", true) - private fun allowAdult(url: String): Request { - return POST( - url, - body = FormBody.Builder() - .add("adult", "true") - .build() - ) + private fun allowAdult(request: Request): Request { + val form = FormBody.Builder().add("adult", allowAdult.toString()).build() + return POST(request.url.toString(), headers, form) } override fun chapterListRequest(manga: SManga) = allowAdult(super.chapterListRequest(manga)) override fun chapterListSelector() = "div.group div.element, div.list div.element" - open val chapterDateSelector = "div.meta_r" + protected open val chapterDateSelector = "div.meta_r" - open val chapterUrlSelector = "a[title]" + protected open val chapterUrlSelector = "a[title]" - override fun chapterFromElement(element: Element): SChapter { + override fun chapterFromElement(element: Element) = SChapter.create().apply { val urlElement = element.select(chapterUrlSelector).first() val dateElement = element.select(chapterDateSelector).first() - val chapter = SChapter.create() - chapter.setUrlWithoutDomain(urlElement.attr("href")) - chapter.name = urlElement.text() - chapter.date_upload = dateElement.text()?.let { parseChapterDate(it.substringAfter(", ")) } - ?: 0 - return chapter + setUrlWithoutDomain(urlElement.attr("href")) + name = urlElement.text() + date_upload = dateElement.text()?.let { + parseChapterDate(it.substringAfter(", ")) + } ?: 0 } - open fun parseChapterDate(date: String): Long? { + protected open fun parseChapterDate(date: String): Long? { val lcDate = date.toLowerCase(Locale.ROOT) if (lcDate.endsWith(" ago")) parseRelativeDate(lcDate)?.let { return it } @@ -279,19 +262,33 @@ abstract class FoolSlide( val doc = document.toString() val jsonStr = doc.substringAfter("var pages = ").substringBefore(";") val pages = json.parseToJsonElement(jsonStr).jsonArray - return pages.mapIndexed { i, jsonEl -> // Create dummy element to resolve relative URL val absUrl = document.createElement("a") .attr("href", jsonEl.jsonObject["url"]!!.jsonPrimitive.content) .absUrl("href") - Page(i, "", absUrl) } } override fun imageUrlParse(document: Document) = throw UnsupportedOperationException("Not used") + protected val preferences by lazy { + Injekt.get().getSharedPreferences("source_$id", 0x0000)!! + } + + override fun setupPreferenceScreen(screen: PreferenceScreen) { + CheckBoxPreference(screen.context).apply { + key = "adult" + summary = "Show adult content" + setDefaultValue(true) + + setOnPreferenceChangeListener { _, newValue -> + preferences.edit().putBoolean(key, newValue as Boolean).commit() + } + }.let(screen::addPreference) + } + companion object { private val ORDINAL_SUFFIXES = listOf("st", "nd", "rd", "th") private val DATE_FORMAT_1 = SimpleDateFormat("yyyy.MM.dd", Locale.US) diff --git a/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/foolslide/FoolSlideGenerator.kt b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/foolslide/FoolSlideGenerator.kt index 09d84d9ed..6f75ee656 100644 --- a/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/foolslide/FoolSlideGenerator.kt +++ b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/foolslide/FoolSlideGenerator.kt @@ -10,10 +10,10 @@ class FoolSlideGenerator : ThemeSourceGenerator { override val themeClass = "FoolSlide" - override val baseVersionCode: Int = 2 + override val baseVersionCode: Int = 3 override val sources = listOf( - SingleLang("The Cat Scans", "https://reader2.thecatscans.com/", "en"), + SingleLang("The Cat Scans", "https://reader2.thecatscans.com", "en"), SingleLang("Silent Sky", "https://reader.silentsky-scans.net", "en"), SingleLang("Death Toll Scans", "https://reader.deathtollscans.net", "en"), SingleLang("MangaScouts", "http://onlinereader.mangascouts.org", "de"), @@ -25,7 +25,7 @@ class FoolSlideGenerator : ThemeSourceGenerator { SingleLang("Menudo-Fansub", "https://www.menudo-fansub.com", "es", className = "MenudoFansub", overrideVersionCode = 1), SingleLang("Sense-Scans", "https://sensescans.com", "en", className = "SenseScans", overrideVersionCode = 1), SingleLang("Kirei Cake", "https://reader.kireicake.com", "en"), - SingleLang("Mangatellers", "http://www.mangatellers.gr", "en"), + SingleLang("Mangatellers", "https://reader.mangatellers.gr", "en"), SingleLang("Iskultrip Scans", "https://maryfaye.net", "en"), SingleLang("Anata no Motokare", "https://motokare.xyz", "en", className = "AnataNoMotokare"), SingleLang("Yuri-ism", "https://www.yuri-ism.net", "en", className = "YuriIsm"), @@ -42,10 +42,9 @@ class FoolSlideGenerator : ThemeSourceGenerator { SingleLang("Tortuga Ceviri", "http://tortuga-ceviri.com", "tr"), SingleLang("Rama", "https://www.ramareader.it", "it"), SingleLang("Mabushimajo", "http://mabushimajo.com", "tr"), - SingleLang("Hyakuro", "https://hyakuro.com/reader", "en"), - SingleLang("Le Cercle du Scan", "https://lel.lecercleduscan.com", "fr", className = "LeCercleDuScan", overrideVersionCode = 1) - //Sites that are down - //SingleLang("One Time Scans", "https://reader.otscans.com", "en"), + SingleLang("Hyakuro", "https://hyakuro.com", "en"), + SingleLang("Le Cercle du Scan", "https://lel.lecercleduscan.com", "fr", className = "LeCercleDuScan", overrideVersionCode = 1), + SingleLang("LetItGo Scans", "https://reader.letitgo.scans.today", "en", overrideVersionCode = 1) ) companion object {