Split FoolSlide Extension (#5840)
* Split FoolSlide Extension * remove FoolSlide * add className * change default_res #5845 * add nsfw * nsfw2
@ -0,0 +1,5 @@
|
|||||||
|
package eu.kanade.tachiyomi.extension.fr.ajianoscantrad
|
||||||
|
|
||||||
|
import eu.kanade.tachiyomi.multisrc.foolslide.FoolSlide
|
||||||
|
|
||||||
|
class AjiaNoScantrad : FoolSlide("Ajia no Scantrad", "https://www.ajianoscantrad.fr", "fr", "/reader")
|
@ -0,0 +1,5 @@
|
|||||||
|
package eu.kanade.tachiyomi.extension.en.anatanomotokare
|
||||||
|
|
||||||
|
import eu.kanade.tachiyomi.multisrc.foolslide.FoolSlide
|
||||||
|
|
||||||
|
class AnataNoMotokare : FoolSlide("Anata no Motokare", "https://motokare.xyz", "en", "/reader")
|
@ -0,0 +1,19 @@
|
|||||||
|
package eu.kanade.tachiyomi.extension.pt.baixarhentai
|
||||||
|
|
||||||
|
import eu.kanade.tachiyomi.multisrc.foolslide.FoolSlide
|
||||||
|
import eu.kanade.tachiyomi.annotations.Nsfw
|
||||||
|
import eu.kanade.tachiyomi.source.model.SManga
|
||||||
|
import org.jsoup.nodes.Document
|
||||||
|
|
||||||
|
@Nsfw
|
||||||
|
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 fun mangaDetailsParse(document: Document): SManga {
|
||||||
|
return SManga.create().apply {
|
||||||
|
title = document.select("h1.title").text()
|
||||||
|
thumbnail_url = getDetailsThumbnail(document, "div.title a")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 2.7 KiB |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.7 KiB |
Before Width: | Height: | Size: 6.3 KiB After Width: | Height: | Size: 6.3 KiB |
Before Width: | Height: | Size: 9.6 KiB After Width: | Height: | Size: 9.6 KiB |
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 38 KiB |
@ -0,0 +1,5 @@
|
|||||||
|
package eu.kanade.tachiyomi.extension.it.fallenworldorder
|
||||||
|
|
||||||
|
import eu.kanade.tachiyomi.multisrc.foolslide.FoolSlide
|
||||||
|
|
||||||
|
class FallenWorldOrder : FoolSlide("Fall World Reader", "https://faworeader.altervista.org", "it", "/slide")
|
@ -0,0 +1,89 @@
|
|||||||
|
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.support.v7.preference.EditTextPreference
|
||||||
|
import android.support.v7.preference.PreferenceScreen
|
||||||
|
import android.widget.Toast
|
||||||
|
import eu.kanade.tachiyomi.extension.BuildConfig
|
||||||
|
import eu.kanade.tachiyomi.source.ConfigurableSource
|
||||||
|
import uy.kohesive.injekt.Injekt
|
||||||
|
import uy.kohesive.injekt.api.get
|
||||||
|
|
||||||
|
class FoolSlideCustomizableFactory : SourceFactory {
|
||||||
|
override fun createSources(): List<Source> = listOf(
|
||||||
|
FoolSlideCustomizable(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
class FoolSlideCustomizable : ConfigurableSource, FoolSlide("FoolSlide Customizable", "", "other") {
|
||||||
|
override val baseUrl: String by lazy { getPrefBaseUrl() }
|
||||||
|
|
||||||
|
private val preferences: SharedPreferences by lazy {
|
||||||
|
Injekt.get<Application>().getSharedPreferences("source_$id", 0x0000)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setupPreferenceScreen(screen: androidx.preference.PreferenceScreen) {
|
||||||
|
val baseUrlPref = androidx.preference.EditTextPreference(screen.context).apply {
|
||||||
|
key = BASE_URL_PREF_TITLE
|
||||||
|
title = BASE_URL_PREF_TITLE
|
||||||
|
summary = BASE_URL_PREF_SUMMARY
|
||||||
|
this.setDefaultValue(DEFAULT_BASEURL)
|
||||||
|
dialogTitle = BASE_URL_PREF_TITLE
|
||||||
|
dialogMessage = "Default: $DEFAULT_BASEURL"
|
||||||
|
|
||||||
|
setOnPreferenceChangeListener { _, newValue ->
|
||||||
|
try {
|
||||||
|
val res = preferences.edit().putString(BASE_URL_PREF, newValue as String).commit()
|
||||||
|
Toast.makeText(screen.context, RESTART_TACHIYOMI, Toast.LENGTH_LONG).show()
|
||||||
|
res
|
||||||
|
} catch (e: Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
screen.addPreference(baseUrlPref)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setupPreferenceScreen(screen: PreferenceScreen) {
|
||||||
|
val baseUrlPref = EditTextPreference(screen.context).apply {
|
||||||
|
key = BASE_URL_PREF_TITLE
|
||||||
|
title = BASE_URL_PREF_TITLE
|
||||||
|
summary = BASE_URL_PREF_SUMMARY
|
||||||
|
this.setDefaultValue(DEFAULT_BASEURL)
|
||||||
|
dialogTitle = BASE_URL_PREF_TITLE
|
||||||
|
dialogMessage = "Default: $DEFAULT_BASEURL"
|
||||||
|
|
||||||
|
setOnPreferenceChangeListener { _, newValue ->
|
||||||
|
try {
|
||||||
|
val res = preferences.edit().putString(BASE_URL_PREF, newValue as String).commit()
|
||||||
|
Toast.makeText(screen.context, RESTART_TACHIYOMI, Toast.LENGTH_LONG).show()
|
||||||
|
res
|
||||||
|
} catch (e: Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
screen.addPreference(baseUrlPref)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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/"
|
||||||
|
private const val BASE_URL_PREF = "overrideBaseUrl_v${BuildConfig.VERSION_NAME}"
|
||||||
|
private const val BASE_URL_PREF_SUMMARY = "Connect to a designated FoolSlide server"
|
||||||
|
private const val RESTART_TACHIYOMI = "Restart Tachiyomi to apply new setting."
|
||||||
|
}
|
||||||
|
}
|
5
multisrc/overrides/foolslide/gto/src/GTO.kt
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
package eu.kanade.tachiyomi.extension.it.gto
|
||||||
|
|
||||||
|
import eu.kanade.tachiyomi.multisrc.foolslide.FoolSlide
|
||||||
|
|
||||||
|
class GTO : FoolSlide("GTO The Great Site", "https://www.gtothegreatsite.net", "it", "/reader")
|
@ -0,0 +1,5 @@
|
|||||||
|
package eu.kanade.tachiyomi.extension.en.helveticascans
|
||||||
|
|
||||||
|
import eu.kanade.tachiyomi.multisrc.foolslide.FoolSlide
|
||||||
|
|
||||||
|
class HelveticaScans : FoolSlide("Helvetica Scans", "https://helveticascans.com", "en", "/r")
|
@ -1,18 +1,19 @@
|
|||||||
package eu.kanade.tachiyomi.extension.all.foolslide
|
package eu.kanade.tachiyomi.extension.en.hentaicafe
|
||||||
|
|
||||||
|
import eu.kanade.tachiyomi.multisrc.foolslide.FoolSlide
|
||||||
import eu.kanade.tachiyomi.annotations.Nsfw
|
import eu.kanade.tachiyomi.annotations.Nsfw
|
||||||
import eu.kanade.tachiyomi.network.GET
|
import eu.kanade.tachiyomi.network.GET
|
||||||
import eu.kanade.tachiyomi.network.asObservable
|
|
||||||
import eu.kanade.tachiyomi.source.model.Filter
|
|
||||||
import eu.kanade.tachiyomi.source.model.FilterList
|
import eu.kanade.tachiyomi.source.model.FilterList
|
||||||
import eu.kanade.tachiyomi.source.model.MangasPage
|
|
||||||
import eu.kanade.tachiyomi.source.model.SChapter
|
import eu.kanade.tachiyomi.source.model.SChapter
|
||||||
import eu.kanade.tachiyomi.source.model.SManga
|
import eu.kanade.tachiyomi.source.model.SManga
|
||||||
import eu.kanade.tachiyomi.util.asJsoup
|
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
import okhttp3.Response
|
import okhttp3.Response
|
||||||
import org.jsoup.nodes.Document
|
import org.jsoup.nodes.Document
|
||||||
import org.jsoup.nodes.Element
|
import org.jsoup.nodes.Element
|
||||||
|
import eu.kanade.tachiyomi.network.asObservable
|
||||||
|
import eu.kanade.tachiyomi.source.model.Filter
|
||||||
|
import eu.kanade.tachiyomi.source.model.MangasPage
|
||||||
|
import eu.kanade.tachiyomi.util.asJsoup
|
||||||
import rx.Observable
|
import rx.Observable
|
||||||
import java.net.URLEncoder
|
import java.net.URLEncoder
|
||||||
|
|
@ -0,0 +1,5 @@
|
|||||||
|
package eu.kanade.tachiyomi.extension.fr.hniscantrad
|
||||||
|
|
||||||
|
import eu.kanade.tachiyomi.multisrc.foolslide.FoolSlide
|
||||||
|
|
||||||
|
class HNIScantrad : FoolSlide("HNI-Scantrad", "https://hni-scantrad.com", "fr", "/lel")
|
@ -0,0 +1,41 @@
|
|||||||
|
package eu.kanade.tachiyomi.extension.en.hniscantraden
|
||||||
|
|
||||||
|
import eu.kanade.tachiyomi.multisrc.foolslide.FoolSlide
|
||||||
|
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 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<Page> {
|
||||||
|
return Regex("""imageArray\[\d+]='(.*)'""").findAll(response.body()!!.string()).toList().mapIndexed { i, mr ->
|
||||||
|
Page(i, "", "$baseUrl$urlModifier/${mr.groupValues[1]}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,5 @@
|
|||||||
|
package eu.kanade.tachiyomi.extension.en.iskultripscans
|
||||||
|
|
||||||
|
import eu.kanade.tachiyomi.multisrc.foolslide.FoolSlide
|
||||||
|
|
||||||
|
class IskultripScans : FoolSlide("Iskultrip Scans", "https://maryfaye.net", "en", "/reader")
|
After Width: | Height: | Size: 5.1 KiB |
After Width: | Height: | Size: 2.7 KiB |
After Width: | Height: | Size: 7.4 KiB |
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 23 KiB |
BIN
multisrc/overrides/foolslide/kireicake/res/web_hi_res_512.png
Normal file
After Width: | Height: | Size: 115 KiB |
15
multisrc/overrides/foolslide/kireicake/src/KireiCake.kt
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
package eu.kanade.tachiyomi.extension.en.kireicake
|
||||||
|
|
||||||
|
import eu.kanade.tachiyomi.multisrc.foolslide.FoolSlide
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,5 @@
|
|||||||
|
package eu.kanade.tachiyomi.extension.es.kirishimafansub
|
||||||
|
|
||||||
|
import eu.kanade.tachiyomi.multisrc.foolslide.FoolSlide
|
||||||
|
|
||||||
|
class KirishimaFansub : FoolSlide("Kirishima Fansub", "https://www.kirishimafansub.net", "es", "/lector")
|
26
multisrc/overrides/foolslide/lupiteam/src/LupiTeam.kt
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
package eu.kanade.tachiyomi.extension.it.lupiteam
|
||||||
|
|
||||||
|
import eu.kanade.tachiyomi.multisrc.foolslide.FoolSlide
|
||||||
|
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 {
|
||||||
|
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) {
|
||||||
|
"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
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,5 @@
|
|||||||
|
package eu.kanade.tachiyomi.extension.tr.mabushimajo
|
||||||
|
|
||||||
|
import eu.kanade.tachiyomi.multisrc.foolslide.FoolSlide
|
||||||
|
|
||||||
|
class Mabushimajo : FoolSlide("Mabushimajo", "http://mabushimajo.com", "tr", "/onlineokuma")
|
@ -0,0 +1,11 @@
|
|||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,5 @@
|
|||||||
|
package eu.kanade.tachiyomi.extension.es.menudofansub
|
||||||
|
|
||||||
|
import eu.kanade.tachiyomi.multisrc.foolslide.FoolSlide
|
||||||
|
|
||||||
|
class MenudoFansub : FoolSlide("Menudo-Fansub", "http://www.menudo-fansub.com", "es", "/slide")
|
5
multisrc/overrides/foolslide/nifteam/src/NIFTeam.kt
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
package eu.kanade.tachiyomi.extension.it.nifteam
|
||||||
|
|
||||||
|
import eu.kanade.tachiyomi.multisrc.foolslide.FoolSlide
|
||||||
|
|
||||||
|
class NIFTeam : FoolSlide("NIFTeam", "http://read-nifteam.info", "it", "/slide")
|
@ -0,0 +1,5 @@
|
|||||||
|
package eu.kanade.tachiyomi.extension.it.phoenixscans
|
||||||
|
|
||||||
|
import eu.kanade.tachiyomi.multisrc.foolslide.FoolSlide
|
||||||
|
|
||||||
|
class PhoenixScans : FoolSlide("The Phoenix Scans", "https://www.phoenixscans.com", "it", "/reader")
|
5
multisrc/overrides/foolslide/rama/src/Rama.kt
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
package eu.kanade.tachiyomi.extension.it.rama
|
||||||
|
|
||||||
|
import eu.kanade.tachiyomi.multisrc.foolslide.FoolSlide
|
||||||
|
|
||||||
|
class Rama : FoolSlide("Rama", "https://www.ramareader.it", "it", "/read")
|
@ -0,0 +1,5 @@
|
|||||||
|
package eu.kanade.tachiyomi.extension.en.sensescans
|
||||||
|
|
||||||
|
import eu.kanade.tachiyomi.multisrc.foolslide.FoolSlide
|
||||||
|
|
||||||
|
class SenseScans : FoolSlide("Sense-Scans", "http://sensescans.com", "en", "/reader")
|
@ -0,0 +1,5 @@
|
|||||||
|
package eu.kanade.tachiyomi.extension.it.storminheaven
|
||||||
|
|
||||||
|
import eu.kanade.tachiyomi.multisrc.foolslide.FoolSlide
|
||||||
|
|
||||||
|
class StormInHeaven : FoolSlide("Storm in Heaven", "https://www.storm-in-heaven.net", "it", "/reader-sih")
|
@ -0,0 +1,5 @@
|
|||||||
|
package eu.kanade.tachiyomi.extension.tr.tortugaceviri
|
||||||
|
|
||||||
|
import eu.kanade.tachiyomi.multisrc.foolslide.FoolSlide
|
||||||
|
|
||||||
|
class TortugaCeviri : FoolSlide("Tortuga Ceviri", "http://tortuga-ceviri.com", "tr", "/okuma")
|
@ -0,0 +1,5 @@
|
|||||||
|
package eu.kanade.tachiyomi.extension.it.tuttoanimemanga
|
||||||
|
|
||||||
|
import eu.kanade.tachiyomi.multisrc.foolslide.FoolSlide
|
||||||
|
|
||||||
|
class TuttoAnimeManga : FoolSlide("TuttoAnimeManga", "https://tuttoanimemanga.net", "it", "/slide")
|
5
multisrc/overrides/foolslide/yuriism/src/YuriIsm.kt
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
package eu.kanade.tachiyomi.extension.en.yuriism
|
||||||
|
|
||||||
|
import eu.kanade.tachiyomi.multisrc.foolslide.FoolSlide
|
||||||
|
|
||||||
|
class YuriIsm : FoolSlide("Yuri-ism", "https://www.yuri-ism.net", "en", "/slide")
|
@ -0,0 +1,5 @@
|
|||||||
|
package eu.kanade.tachiyomi.extension.en.zandynofansub
|
||||||
|
|
||||||
|
import eu.kanade.tachiyomi.multisrc.foolslide.FoolSlide
|
||||||
|
|
||||||
|
class ZandynoFansub : FoolSlide("Zandy no Fansub", "https://zandynofansub.aishiteru.org", "en", "/reader")
|
@ -1,4 +1,4 @@
|
|||||||
package eu.kanade.tachiyomi.extension.all.foolslide
|
package eu.kanade.tachiyomi.multisrc.foolslide
|
||||||
|
|
||||||
import com.github.salomonbrys.kotson.get
|
import com.github.salomonbrys.kotson.get
|
||||||
import com.google.gson.JsonParser
|
import com.google.gson.JsonParser
|
@ -0,0 +1,59 @@
|
|||||||
|
package eu.kanade.tachiyomi.multisrc.foolslide
|
||||||
|
|
||||||
|
import eu.kanade.tachiyomi.multisrc.ThemeSourceData.SingleLang
|
||||||
|
import eu.kanade.tachiyomi.multisrc.ThemeSourceData.MultiLang
|
||||||
|
import eu.kanade.tachiyomi.multisrc.ThemeSourceGenerator
|
||||||
|
|
||||||
|
class FoolSlideGenerator : ThemeSourceGenerator {
|
||||||
|
|
||||||
|
override val themePkg = "foolslide"
|
||||||
|
|
||||||
|
override val themeClass = "FoolSlide"
|
||||||
|
|
||||||
|
override val baseVersionCode: Int = 1
|
||||||
|
|
||||||
|
override val sources = listOf(
|
||||||
|
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("One Time Scans", "https://reader.otscans.com", "en"),
|
||||||
|
SingleLang("MangaScouts", "http://onlinereader.mangascouts.org", "de"),
|
||||||
|
SingleLang("Lilyreader", "https://manga.smuglo.li", "en"),
|
||||||
|
SingleLang("Evil Flowers", "https://reader.evilflowers.com", "en"),
|
||||||
|
SingleLang("Русификация", "https://rusmanga.ru", "ru", className = "Russification"),
|
||||||
|
SingleLang("PowerManga", "https://reader.powermanga.org", "it", className = "PowerMangaIT"),
|
||||||
|
MultiLang("FoolSlide Customizable", "", listOf("other")),
|
||||||
|
SingleLang("Menudo-Fansub", "http://www.menudo-fansub.com", "es", className = "MenudoFansub"),
|
||||||
|
SingleLang("Sense-Scans", "http://sensescans.com", "en", className = "SenseScans"),
|
||||||
|
SingleLang("Kirei Cake", "https://reader.kireicake.com", "en"),
|
||||||
|
SingleLang("Mangatellers", "http://www.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"),
|
||||||
|
SingleLang("Ajia no Scantrad", "https://www.ajianoscantrad.fr", "fr", className = "AjiaNoScantrad"),
|
||||||
|
SingleLang("Storm in Heaven", "https://www.storm-in-heaven.net", "it", className = "StormInHeaven"),
|
||||||
|
SingleLang("LupiTeam", "https://lupiteam.net", "it"),
|
||||||
|
SingleLang("Zandy no Fansub", "https://zandynofansub.aishiteru.org", "en"),
|
||||||
|
SingleLang("Helvetica Scans", "https://helveticascans.com", "en"),
|
||||||
|
SingleLang("Kirishima Fansub", "https://www.kirishimafansub.net", "es"),
|
||||||
|
SingleLang("Baixar Hentai", "https://leitura.baixarhentai.net", "pt-BR", isNsfw = true),
|
||||||
|
SingleLang("HNI-Scantrad", "https://hni-scantrad.com", "fr", className = "HNIScantrad"),
|
||||||
|
SingleLang("HNI-Scantrad", "https://hni-scantrad.com", "en", className = "HNIScantradEN"),
|
||||||
|
SingleLang("The Phoenix Scans", "https://www.phoenixscans.com", "it", className = "PhoenixScans"),
|
||||||
|
SingleLang("GTO The Great Site", "https://www.gtothegreatsite.net", "it", className = "GTO"),
|
||||||
|
SingleLang("Fall World Reader", "https://faworeader.altervista.org", "it", className = "FallenWorldOrder"),
|
||||||
|
SingleLang("NIFTeam", "http://read-nifteam.info", "it"),
|
||||||
|
SingleLang("TuttoAnimeManga", "https://tuttoanimemanga.net", "it"),
|
||||||
|
SingleLang("Tortuga Ceviri", "http://tortuga-ceviri.com", "tr"),
|
||||||
|
SingleLang("Rama", "https://www.ramareader.it", "it"),
|
||||||
|
SingleLang("Mabushimajo", "http://mabushimajo.com", "tr"),
|
||||||
|
SingleLang("Hentai Cafe", "https://hentai.cafe", "en", isNsfw = true),
|
||||||
|
)
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
@JvmStatic
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
FoolSlideGenerator().createAll()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,2 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<manifest package="eu.kanade.tachiyomi.extension" />
|
|
@ -1,13 +0,0 @@
|
|||||||
apply plugin: 'com.android.application'
|
|
||||||
apply plugin: 'kotlin-android'
|
|
||||||
|
|
||||||
ext {
|
|
||||||
extName = 'FoolSlide (multiple sources)'
|
|
||||||
pkgNameSuffix = 'all.foolslide'
|
|
||||||
extClass = '.FoolSlideFactory'
|
|
||||||
extVersionCode = 59
|
|
||||||
libVersion = '1.2'
|
|
||||||
containsNsfw = true
|
|
||||||
}
|
|
||||||
|
|
||||||
apply from: "$rootDir/common.gradle"
|
|
@ -1,270 +0,0 @@
|
|||||||
package eu.kanade.tachiyomi.extension.all.foolslide
|
|
||||||
|
|
||||||
import android.app.Application
|
|
||||||
import android.content.SharedPreferences
|
|
||||||
import android.support.v7.preference.EditTextPreference
|
|
||||||
import android.support.v7.preference.PreferenceScreen
|
|
||||||
import android.widget.Toast
|
|
||||||
import com.github.salomonbrys.kotson.get
|
|
||||||
import eu.kanade.tachiyomi.annotations.Nsfw
|
|
||||||
import eu.kanade.tachiyomi.extension.BuildConfig
|
|
||||||
import eu.kanade.tachiyomi.network.GET
|
|
||||||
import eu.kanade.tachiyomi.source.ConfigurableSource
|
|
||||||
import eu.kanade.tachiyomi.source.Source
|
|
||||||
import eu.kanade.tachiyomi.source.SourceFactory
|
|
||||||
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.Document
|
|
||||||
import org.jsoup.nodes.Element
|
|
||||||
import uy.kohesive.injekt.Injekt
|
|
||||||
import uy.kohesive.injekt.api.get
|
|
||||||
|
|
||||||
class FoolSlideFactory : SourceFactory {
|
|
||||||
override fun createSources(): List<Source> = listOf(
|
|
||||||
SenseScans(),
|
|
||||||
KireiCake(),
|
|
||||||
SilentSky(),
|
|
||||||
Mangatellers(),
|
|
||||||
IskultripScans(),
|
|
||||||
AnataNoMotokare(),
|
|
||||||
DeathTollScans(),
|
|
||||||
YuriIsm(),
|
|
||||||
AjiaNoScantrad(),
|
|
||||||
OneTimeScans(),
|
|
||||||
MangaScouts(),
|
|
||||||
StormInHeaven(),
|
|
||||||
Lilyreader(),
|
|
||||||
Russification(),
|
|
||||||
EvilFlowers(),
|
|
||||||
LupiTeam(),
|
|
||||||
HentaiCafe(),
|
|
||||||
TheCatScans(),
|
|
||||||
ZandynoFansub(),
|
|
||||||
HelveticaScans(),
|
|
||||||
KirishimaFansub(),
|
|
||||||
PowerMangaIT(),
|
|
||||||
BaixarHentai(),
|
|
||||||
HNIScantrad(),
|
|
||||||
HNIScantradEN(),
|
|
||||||
PhoenixScans(),
|
|
||||||
GTO(),
|
|
||||||
FallenWorldOrder(),
|
|
||||||
NIFTeam(),
|
|
||||||
TuttoAnimeManga(),
|
|
||||||
Customizable(),
|
|
||||||
TortugaCeviri(),
|
|
||||||
Rama(),
|
|
||||||
Mabushimajo(),
|
|
||||||
MenudoFansub()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
class MenudoFansub : FoolSlide("Menudo-Fansub", "http://www.menudo-fansub.com", "es", "/slide")
|
|
||||||
|
|
||||||
class TheCatScans : FoolSlide("The Cat Scans", "https://reader2.thecatscans.com/", "en")
|
|
||||||
|
|
||||||
class SenseScans : FoolSlide("Sense-Scans", "http://sensescans.com", "en", "/reader")
|
|
||||||
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class SilentSky : FoolSlide("Silent Sky", "https://reader.silentsky-scans.net", "en")
|
|
||||||
|
|
||||||
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 IskultripScans : FoolSlide("Iskultrip Scans", "https://maryfaye.net", "en", "/reader")
|
|
||||||
|
|
||||||
class AnataNoMotokare : FoolSlide("Anata no Motokare", "https://motokare.xyz", "en", "/reader")
|
|
||||||
|
|
||||||
class DeathTollScans : FoolSlide("Death Toll Scans", "https://reader.deathtollscans.net", "en")
|
|
||||||
|
|
||||||
class YuriIsm : FoolSlide("Yuri-ism", "https://www.yuri-ism.net", "en", "/slide")
|
|
||||||
|
|
||||||
class AjiaNoScantrad : FoolSlide("Ajia no Scantrad", "https://www.ajianoscantrad.fr", "fr", "/reader")
|
|
||||||
|
|
||||||
class OneTimeScans : FoolSlide("One Time Scans", "https://reader.otscans.com", "en")
|
|
||||||
|
|
||||||
class MangaScouts : FoolSlide("MangaScouts", "http://onlinereader.mangascouts.org", "de")
|
|
||||||
|
|
||||||
class StormInHeaven : FoolSlide("Storm in Heaven", "https://www.storm-in-heaven.net", "it", "/reader-sih")
|
|
||||||
|
|
||||||
class Lilyreader : FoolSlide("Lilyreader", "https://manga.smuglo.li", "en")
|
|
||||||
|
|
||||||
class Russification : FoolSlide("Русификация", "https://rusmanga.ru", "ru")
|
|
||||||
|
|
||||||
class EvilFlowers : FoolSlide("Evil Flowers", "https://reader.evilflowers.com", "en")
|
|
||||||
|
|
||||||
class LupiTeam : FoolSlide("LupiTeam", "https://lupiteam.net", "it", "/reader") {
|
|
||||||
override fun mangaDetailsParse(document: Document): SManga {
|
|
||||||
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) {
|
|
||||||
"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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class ZandynoFansub : FoolSlide("Zandy no Fansub", "https://zandynofansub.aishiteru.org", "en", "/reader")
|
|
||||||
|
|
||||||
class HelveticaScans : FoolSlide("Helvetica Scans", "https://helveticascans.com", "en", "/r")
|
|
||||||
|
|
||||||
class KirishimaFansub : FoolSlide("Kirishima Fansub", "https://www.kirishimafansub.net", "es", "/lector")
|
|
||||||
|
|
||||||
class PowerMangaIT : FoolSlide("PowerManga", "https://reader.powermanga.org", "it", "")
|
|
||||||
|
|
||||||
@Nsfw
|
|
||||||
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 fun mangaDetailsParse(document: Document): SManga {
|
|
||||||
return SManga.create().apply {
|
|
||||||
title = document.select("h1.title").text()
|
|
||||||
thumbnail_url = getDetailsThumbnail(document, "div.title a")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class HNIScantrad : 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<Page> {
|
|
||||||
return Regex("""imageArray\[\d+]='(.*)'""").findAll(response.body()!!.string()).toList().mapIndexed { i, mr ->
|
|
||||||
Page(i, "", "$baseUrl$urlModifier/${mr.groupValues[1]}")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class PhoenixScans : FoolSlide("The Phoenix Scans", "https://www.phoenixscans.com", "it", "/reader")
|
|
||||||
|
|
||||||
class GTO : FoolSlide("GTO The Great Site", "https://www.gtothegreatsite.net", "it", "/reader")
|
|
||||||
|
|
||||||
class FallenWorldOrder : FoolSlide("Fall World Reader", "https://faworeader.altervista.org", "it", "/slide")
|
|
||||||
|
|
||||||
class NIFTeam : FoolSlide("NIFTeam", "http://read-nifteam.info", "it", "/slide")
|
|
||||||
|
|
||||||
class TuttoAnimeManga : FoolSlide("TuttoAnimeManga", "https://tuttoanimemanga.net", "it", "/slide")
|
|
||||||
|
|
||||||
class Customizable : ConfigurableSource, FoolSlide("Customizable", "", "other") {
|
|
||||||
override val baseUrl: String by lazy { getPrefBaseUrl() }
|
|
||||||
|
|
||||||
private val preferences: SharedPreferences by lazy {
|
|
||||||
Injekt.get<Application>().getSharedPreferences("source_$id", 0x0000)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun setupPreferenceScreen(screen: androidx.preference.PreferenceScreen) {
|
|
||||||
val baseUrlPref = androidx.preference.EditTextPreference(screen.context).apply {
|
|
||||||
key = BASE_URL_PREF_TITLE
|
|
||||||
title = BASE_URL_PREF_TITLE
|
|
||||||
summary = BASE_URL_PREF_SUMMARY
|
|
||||||
this.setDefaultValue(DEFAULT_BASEURL)
|
|
||||||
dialogTitle = BASE_URL_PREF_TITLE
|
|
||||||
dialogMessage = "Default: $DEFAULT_BASEURL"
|
|
||||||
|
|
||||||
setOnPreferenceChangeListener { _, newValue ->
|
|
||||||
try {
|
|
||||||
val res = preferences.edit().putString(BASE_URL_PREF, newValue as String).commit()
|
|
||||||
Toast.makeText(screen.context, RESTART_TACHIYOMI, Toast.LENGTH_LONG).show()
|
|
||||||
res
|
|
||||||
} catch (e: Exception) {
|
|
||||||
e.printStackTrace()
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
screen.addPreference(baseUrlPref)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun setupPreferenceScreen(screen: PreferenceScreen) {
|
|
||||||
val baseUrlPref = EditTextPreference(screen.context).apply {
|
|
||||||
key = BASE_URL_PREF_TITLE
|
|
||||||
title = BASE_URL_PREF_TITLE
|
|
||||||
summary = BASE_URL_PREF_SUMMARY
|
|
||||||
this.setDefaultValue(DEFAULT_BASEURL)
|
|
||||||
dialogTitle = BASE_URL_PREF_TITLE
|
|
||||||
dialogMessage = "Default: $DEFAULT_BASEURL"
|
|
||||||
|
|
||||||
setOnPreferenceChangeListener { _, newValue ->
|
|
||||||
try {
|
|
||||||
val res = preferences.edit().putString(BASE_URL_PREF, newValue as String).commit()
|
|
||||||
Toast.makeText(screen.context, RESTART_TACHIYOMI, Toast.LENGTH_LONG).show()
|
|
||||||
res
|
|
||||||
} catch (e: Exception) {
|
|
||||||
e.printStackTrace()
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
screen.addPreference(baseUrlPref)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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/"
|
|
||||||
private const val BASE_URL_PREF = "overrideBaseUrl_v${BuildConfig.VERSION_NAME}"
|
|
||||||
private const val BASE_URL_PREF_SUMMARY = "Connect to a designated FoolSlide server"
|
|
||||||
private const val RESTART_TACHIYOMI = "Restart Tachiyomi to apply new setting."
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class TortugaCeviri : FoolSlide("Tortuga Ceviri", "http://tortuga-ceviri.com", "tr", "/okuma")
|
|
||||||
|
|
||||||
class Rama : FoolSlide("Rama", "https://www.ramareader.it", "it", "/read")
|
|
||||||
|
|
||||||
class Mabushimajo : FoolSlide("Mabushimajo", "http://mabushimajo.com", "tr", "/onlineokuma")
|
|