new sources: anime saturn (#256)

Co-authored-by: jmir1 <jhmiramon@gmail.com>
Co-authored-by: The007who <The007who@users.noreply.github.com>
This commit is contained in:
jmir1
2022-01-24 22:37:08 +01:00
committed by GitHub
parent 07fae038ed
commit 5336fe9245
16 changed files with 843 additions and 0 deletions

View File

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest package="eu.kanade.tachiyomi.animeextension" />

View File

@ -0,0 +1,12 @@
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
ext {
extName = 'Anime Saturn'
pkgNameSuffix = 'it.animesaturn'
extClass = '.AnimeSaturn'
extVersionCode = 1
libVersion = '12'
}
apply from: "$rootDir/common.gradle"

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

View File

@ -0,0 +1,417 @@
package eu.kanade.tachiyomi.animeextension.it.animesaturn
import android.app.Application
import android.content.SharedPreferences
import androidx.preference.ListPreference
import androidx.preference.PreferenceScreen
import eu.kanade.tachiyomi.animesource.ConfigurableAnimeSource
import eu.kanade.tachiyomi.animesource.model.AnimeFilter
import eu.kanade.tachiyomi.animesource.model.AnimeFilterList
import eu.kanade.tachiyomi.animesource.model.SAnime
import eu.kanade.tachiyomi.animesource.model.SEpisode
import eu.kanade.tachiyomi.animesource.model.Video
import eu.kanade.tachiyomi.animesource.online.ParsedAnimeHttpSource
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.Headers
import okhttp3.OkHttpClient
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
import java.lang.Exception
class AnimeSaturn : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
override val name = "AnimeSaturn"
override val baseUrl by lazy { preferences.getString("preferred_domain", "https://animesaturn.it")!! }
override val lang = "it"
override val supportsLatest = true
override val client: OkHttpClient = network.cloudflareClient
private val preferences: SharedPreferences by lazy {
Injekt.get<Application>().getSharedPreferences("source_$id", 0x0000)
}
override fun popularAnimeSelector(): String = "div.sebox"
override fun popularAnimeRequest(page: Int): Request = GET("$baseUrl/animeincorso?page=$page")
private fun formatTitle(titlestring: String): String = titlestring.replace("(ITA) ITA", "Dub ITA").replace("(ITA)", "Dub ITA").replace("Sub ITA", "")
override fun popularAnimeFromElement(element: Element): SAnime {
val anime = SAnime.create()
anime.setUrlWithoutDomain(element.selectFirst("div.msebox div.headsebox div.tisebox h2 a").attr("href"))
anime.title = formatTitle(element.selectFirst("div.msebox div.headsebox div.tisebox h2 a").text())
anime.thumbnail_url = element.selectFirst("div.msebox div.bigsebox div.l img.attachment-post-thumbnail.size-post-thumbnail.wp-post-image").attr("src")
return anime
}
override fun popularAnimeNextPageSelector(): String = "li.page-item.active:not(li:last-child)"
override fun episodeListParse(response: Response): List<SEpisode> {
val document = response.asJsoup()
return document.select(episodeListSelector()).map { episodeFromElement(it) }.reversed()
}
override fun episodeListSelector() = "div.btn-group.episodes-button.episodi-link-button"
override fun episodeFromElement(element: Element): SEpisode {
val episode = SEpisode.create()
episode.setUrlWithoutDomain(element.selectFirst("a.btn.btn-dark.mb-1.bottone-ep").attr("href"))
val epText = element.selectFirst("a.btn.btn-dark.mb-1.bottone-ep").text()
val epNumber = epText.substringAfter("Episodio ")
if (epNumber.contains("-", true)) {
episode.episode_number = epNumber.substringBefore("-").toFloat()
} else {
episode.episode_number = epNumber.toFloat()
}
episode.name = epText
episode.date_upload = System.currentTimeMillis()
return episode
}
override fun videoListRequest(episode: SEpisode): Request {
val episodePage = client.newCall(GET(baseUrl + episode.url)).execute().asJsoup()
val watchUrl = episodePage.select("a[href*=/watch]").attr("href")
return GET(watchUrl)
}
override fun videoListSelector() = "source"
override fun videoFromElement(element: Element): Video {
val referer = element.ownerDocument().location()
val url = element.attr("src")
return Video(url, "Qualità predefinita", url, null, Headers.headersOf("Referer", referer))
}
// override fun List<Video>.sort(): List<Video> {
// val quality = preferences.getString("preferred_quality", "1080")!!
// val qualityList = mutableListOf<Video>()
// val newList = mutableListOf<Video>()
// var preferred = 0
// for (video in this) {
// if (video.quality.contains(quality)) {
// qualityList.add(preferred, video)
// preferred++
// } else {
// qualityList.add(video)
// }
// }
// return newList
// }
override fun videoUrlParse(document: Document) = throw Exception("not used")
override fun searchAnimeFromElement(element: Element): SAnime {
val anime = SAnime.create()
if (filterSearch) {
// filter search
anime.setUrlWithoutDomain(element.selectFirst("div.card.mb-4.shadow-sm a").attr("href"))
anime.title = formatTitle(element.selectFirst("div.card.mb-4.shadow-sm a").attr("title"))
anime.thumbnail_url = element.selectFirst("div.card.mb-4.shadow-sm a img.new-anime").attr("src")
} else {
// word search
anime.setUrlWithoutDomain(element.selectFirst("li.list-group-item.bg-dark-as-box-shadow div.item-archivio div.info-archivio h3 a.badge.badge-archivio.badge-light").attr("href"))
anime.title = formatTitle(element.selectFirst("li.list-group-item.bg-dark-as-box-shadow div.item-archivio div.info-archivio h3 a.badge.badge-archivio.badge-light").text())
anime.thumbnail_url = element.select("li.list-group-item.bg-dark-as-box-shadow div.item-archivio a.thumb.image-wrapper img.rounded.locandina-archivio").attr("src")
}
return anime
}
override fun searchAnimeNextPageSelector(): String = "li.page-item.active:not(li:last-child)"
private var filterSearch = false
override fun searchAnimeSelector(): String {
return if (filterSearch) "div.anime-card-newanime.main-anime-card" // filter search
else "ul.list-group" // regular search
}
override fun searchAnimeRequest(page: Int, query: String, filters: AnimeFilterList): Request {
val parameters = getSearchParameters(filters)
return if (parameters.isEmpty()) {
filterSearch = false
GET("$baseUrl/animelist?search=$query") // regular search
} else {
filterSearch = true
GET("$baseUrl/filter?$parameters&page=$page") // with filters
}
}
override fun animeDetailsParse(document: Document): SAnime {
val anime = SAnime.create()
anime.title =
formatTitle(document.select("div.container.anime-title-as.mb-3.w-100 b").text())
val tempDetails =
document.select("div.container.shadow.rounded.bg-dark-as-box.mb-3.p-3.w-100.text-white")
.text()
val indexA = tempDetails.indexOf("Stato:")
anime.author = tempDetails.substring(7, indexA).trim()
val indexS1 = tempDetails.indexOf("Stato:") + 6
val indexS2 = tempDetails.indexOf("Data di uscita:")
anime.status = parseStatus(tempDetails.substring(indexS1, indexS2).trim())
anime.genre =
document.select("div.container.shadow.rounded.bg-dark-as-box.mb-3.p-3.w-100 a.badge.badge-dark.generi-as.mb-1")
.joinToString { it.text() }
anime.thumbnail_url = document.selectFirst("img.img-fluid.cover-anime.rounded").attr("src")
val alterTitle = formatTitle(
document.selectFirst("div.box-trasparente-alternativo.rounded").text()
).replace("Dub ITA", "").trim()
val description1 = document.select("div#trama div#shown-trama").firstOrNull()?.ownText()
val description2 = document.select("div#full-trama.d-none").firstOrNull()?.ownText()
when {
description1 == null -> {
anime.description = description2
}
description2 == null -> {
anime.description = description1
} description1.length > description2.length -> {
anime.description = description1
} else -> {
anime.description = description2
}
}
if (!anime.title.contains(alterTitle, true)) anime.description = anime.description + "\n\nTitolo Alternativo: " + alterTitle
return anime
}
private fun parseStatus(statusString: String): Int {
return when {
statusString.contains("In corso") -> {
SAnime.ONGOING
}
statusString.contains("Finito") -> {
SAnime.COMPLETED
}
else -> {
SAnime.UNKNOWN
}
}
}
override fun latestUpdatesSelector(): String = "div.card.mb-4.shadow-sm"
override fun latestUpdatesFromElement(element: Element): SAnime {
val anime = SAnime.create()
anime.setUrlWithoutDomain(element.selectFirst("a").attr("href"))
anime.title = formatTitle(element.selectFirst("a").attr("title"))
anime.thumbnail_url = element.selectFirst("a img.new-anime").attr("src")
return anime
}
override fun latestUpdatesRequest(page: Int): Request = GET("$baseUrl/newest?page=$page")
override fun latestUpdatesNextPageSelector(): String = "li.page-item.active:not(li:last-child)"
// Filters
internal class Genre(val id: String) : AnimeFilter.CheckBox(id)
private class GenreList(genres: List<Genre>) : AnimeFilter.Group<Genre>("Generi", genres)
private fun getGenres() = listOf(
Genre("Arti Marziali"),
Genre("Avventura"),
Genre("Azione"),
Genre("Bambini"),
Genre("Commedia"),
Genre("Demenziale"),
Genre("Demoni"),
Genre("Drammatico"),
Genre("Ecchi"),
Genre("Fantasy"),
Genre("Gioco"),
Genre("Harem"),
Genre("Hentai"),
Genre("Horror"),
Genre("Josei"),
Genre("Magia"),
Genre("Mecha"),
Genre("Militari"),
Genre("Mistero"),
Genre("Musicale"),
Genre("Parodia"),
Genre("Polizia"),
Genre("Psicologico"),
Genre("Romantico"),
Genre("Samurai"),
Genre("Sci-Fi"),
Genre("Scolastico"),
Genre("Seinen"),
Genre("Sentimentale"),
Genre("Shoujo Ai"),
Genre("Shoujo"),
Genre("Shounen Ai"),
Genre("Shounen"),
Genre("Slice of Life"),
Genre("Soprannaturale"),
Genre("Spazio"),
Genre("Sport"),
Genre("Storico"),
Genre("Superpoteri"),
Genre("Thriller"),
Genre("Vampiri"),
Genre("Veicoli"),
Genre("Yaoi"),
Genre("Yuri")
)
internal class Year(val id: String) : AnimeFilter.CheckBox(id)
private class YearList(years: List<Year>) : AnimeFilter.Group<Year>("Anno di Uscita", years)
private fun getYears() = listOf(
Year("1969"),
Year("1970"),
Year("1975"),
Year("1978"),
Year("1979"),
Year("1981"),
Year("1983"),
Year("1984"),
Year("1986"),
Year("1987"),
Year("1988"),
Year("1989"),
Year("1990"),
Year("1991"),
Year("1992"),
Year("1993"),
Year("1994"),
Year("1995"),
Year("1996"),
Year("1997"),
Year("1998"),
Year("1999"),
Year("2000"),
Year("2001"),
Year("2002"),
Year("2003"),
Year("2004"),
Year("2005"),
Year("2006"),
Year("2007"),
Year("2008"),
Year("2009"),
Year("2010"),
Year("2011"),
Year("2012"),
Year("2013"),
Year("2014"),
Year("2015"),
Year("2016"),
Year("2017"),
Year("2018"),
Year("2019"),
Year("2020"),
Year("2021"),
Year("2022")
)
internal class State(val id: String, name: String) : AnimeFilter.CheckBox(name)
private class StateList(states: List<State>) : AnimeFilter.Group<State>("Stato", states)
private fun getStates() = listOf(
State("0", "In corso"),
State("1", "Finito"),
State("2", "Non rilasciato"),
State("3", "Droppato")
)
internal class Lang(val id: String, name: String) : AnimeFilter.CheckBox(name)
private class LangList(langs: List<Lang>) : AnimeFilter.Group<Lang>("Lingua", langs)
private fun getLangs() = listOf(
Lang("0", "Subbato"),
Lang("1", "Doppiato")
)
override fun getFilterList(): AnimeFilterList = AnimeFilterList(
AnimeFilter.Header("Ricerca per titolo ignora i filtri e viceversa"),
GenreList(getGenres()),
YearList(getYears()),
StateList(getStates()),
LangList(getLangs())
)
private fun getSearchParameters(filters: AnimeFilterList): String {
var totalstring = ""
var variantgenre = 0
var variantstate = 0
var variantyear = 0
filters.forEach { filter ->
when (filter) {
is GenreList -> { // ---Genre
filter.state.forEach { Genre ->
if (Genre.state) {
totalstring = totalstring + "&categories%5B" + variantgenre.toString() + "%5D=" + Genre.id
variantgenre++
}
}
}
is YearList -> { // ---Year
filter.state.forEach { Year ->
if (Year.state) {
totalstring = totalstring + "&years%5B" + variantyear.toString() + "%5D=" + Year.id
variantyear++
}
}
}
is StateList -> { // ---State
filter.state.forEach { State ->
if (State.state) {
totalstring = totalstring + "&states%5B" + variantstate.toString() + "%5D=" + State.id
variantstate++
}
}
}
is LangList -> { // ---Lang
filter.state.forEach { Lang ->
if (Lang.state) {
totalstring = totalstring + "&language%5B0%5D=" + Lang.id
}
}
}
else -> {}
}
}
return totalstring
}
override fun setupPreferenceScreen(screen: PreferenceScreen) {
// val videoQualityPref = ListPreference(screen.context).apply {
// key = "preferred_quality"
// title = "Qualità preferita"
// entries = arrayOf("1080p", "720p", "480p", "360p")
// entryValues = arrayOf("1080", "720", "480", "360")
// setDefaultValue("1080")
// summary = "%s"
// setOnPreferenceChangeListener { _, newValue ->
// val selected = newValue as String
// val index = findIndexOfValue(selected)
// val entry = entryValues[index] as String
// preferences.edit().putString(key, entry).commit()
// }
// }
val domainPref = ListPreference(screen.context).apply {
key = "preferred_domain"
title = "Domain in uso (riavvio dell'app richiesto)"
entries = arrayOf("animesaturn.it", "animesaturn.tv")
entryValues = arrayOf("https://animesaturn.it", "https://animesaturn.tv")
setDefaultValue("https://animesaturn.it")
summary = "%s"
setOnPreferenceChangeListener { _, newValue ->
val selected = newValue as String
val index = findIndexOfValue(selected)
val entry = entryValues[index] as String
preferences.edit().putString(key, entry).commit()
}
}
// screen.addPreference(videoQualityPref)
screen.addPreference(domainPref)
}
}

View File

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest package="eu.kanade.tachiyomi.animeextension" />

View File

@ -0,0 +1,12 @@
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
ext {
extName = 'Hentai Saturn'
pkgNameSuffix = 'it.hentaisaturn'
extClass = '.HentaiSaturn'
extVersionCode = 1
libVersion = '12'
}
apply from: "$rootDir/common.gradle"

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

View File

@ -0,0 +1,398 @@
package eu.kanade.tachiyomi.animeextension.it.hentaisaturn
import android.app.Application
import android.content.SharedPreferences
import androidx.preference.ListPreference
import androidx.preference.PreferenceScreen
import eu.kanade.tachiyomi.animesource.ConfigurableAnimeSource
import eu.kanade.tachiyomi.animesource.model.AnimeFilter
import eu.kanade.tachiyomi.animesource.model.AnimeFilterList
import eu.kanade.tachiyomi.animesource.model.SAnime
import eu.kanade.tachiyomi.animesource.model.SEpisode
import eu.kanade.tachiyomi.animesource.model.Video
import eu.kanade.tachiyomi.animesource.online.ParsedAnimeHttpSource
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.Headers
import okhttp3.OkHttpClient
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
import java.lang.Exception
class HentaiSaturn : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
override val name = "HentaiSaturn"
override val baseUrl = "https://www.hentaisaturn.com"
override val lang = "it"
override val supportsLatest = true
override val client: OkHttpClient = network.cloudflareClient
private val preferences: SharedPreferences by lazy {
Injekt.get<Application>().getSharedPreferences("source_$id", 0x0000)
}
override fun popularAnimeSelector(): String = "div.col-md-2.float-left.hentai-img-box-col.hentai-padding-top"
override fun popularAnimeRequest(page: Int): Request = GET("$baseUrl/toplist")
private fun formatTitle(titlestring: String): String = titlestring.replace("(ITA) ITA", "Dub ITA").replace("(ITA)", "Dub ITA").replace("Sub ITA", "")
override fun popularAnimeFromElement(element: Element): SAnime {
val anime = SAnime.create()
anime.setUrlWithoutDomain(element.selectFirst("a").attr("href"))
anime.title = formatTitle(element.selectFirst("a img.img-fluid.w-100.rounded.hentai-img").attr("title"))
anime.thumbnail_url = element.selectFirst("a img.img-fluid.w-100.rounded.hentai-img").attr("src")
return anime
}
override fun popularAnimeNextPageSelector(): String = "li.page-item.active:not(li:last-child)"
override fun episodeListParse(response: Response): List<SEpisode> {
val document = response.asJsoup()
return document.select(episodeListSelector()).map { episodeFromElement(it) }.reversed()
}
override fun episodeListSelector() = "div.btn-group.episodes-button.episodi-link-button"
override fun episodeFromElement(element: Element): SEpisode {
val episode = SEpisode.create()
episode.setUrlWithoutDomain(element.selectFirst("a.btn.btn-dark.mb-1.bottone-ep").attr("href"))
val epText = element.selectFirst("a.btn.btn-dark.mb-1.bottone-ep").text()
val epNumber = epText.substringAfter("Episodio ")
if (epNumber.contains("-", true)) {
episode.episode_number = epNumber.substringBefore("-").toFloat()
} else {
episode.episode_number = epNumber.toFloat()
}
episode.name = epText
episode.date_upload = System.currentTimeMillis()
return episode
}
override fun videoListRequest(episode: SEpisode): Request {
val episodePage = client.newCall(GET(baseUrl + episode.url)).execute().asJsoup()
val watchUrl = episodePage.select("a[href*=/watch]").attr("href")
return GET(watchUrl)
}
override fun videoListSelector() = "source"
override fun videoFromElement(element: Element): Video {
val referer = element.ownerDocument().location()
val url = element.attr("src")
return Video(url, "Qualità predefinita", url, null, Headers.headersOf("Referer", referer))
}
// override fun List<Video>.sort(): List<Video> {
// val quality = preferences.getString("preferred_quality", "1080")!!
// val qualityList = mutableListOf<Video>()
// val newList = mutableListOf<Video>()
// var preferred = 0
// for (video in this) {
// if (video.quality.contains(quality)) {
// qualityList.add(preferred, video)
// preferred++
// } else {
// qualityList.add(video)
// }
// }
// return newList
// }
override fun videoUrlParse(document: Document) = throw Exception("not used")
override fun searchAnimeFromElement(element: Element): SAnime {
val anime = SAnime.create()
if (filterSearch) {
// filter search
anime.setUrlWithoutDomain(element.selectFirst("div.card.mb-4.shadow-sm a").attr("href"))
anime.title = formatTitle(element.selectFirst("div.card.mb-4.shadow-sm a").attr("title"))
anime.thumbnail_url = element.selectFirst("div.card.mb-4.shadow-sm a img.new-hentai").attr("src")
} else {
// word search
anime.setUrlWithoutDomain(element.selectFirst("a.thumb.image-wrapper").attr("href"))
anime.title = formatTitle(element.selectFirst("a.thumb.image-wrapper img.rounded.copertina-archivio").attr("alt"))
anime.thumbnail_url = element.select("a.thumb.image-wrapper img.rounded.copertina-archivio").attr("src")
}
return anime
}
override fun searchAnimeNextPageSelector(): String = "li.page-item.active:not(li:last-child)"
private var filterSearch = false
override fun searchAnimeSelector(): String {
return if (filterSearch) "div.hentai-card-newhentai.main-hentai-card" // filter search
else "div.item-archivio" // regular search
}
override fun searchAnimeRequest(page: Int, query: String, filters: AnimeFilterList): Request {
val parameters = getSearchParameters(filters)
return if (parameters.isEmpty()) {
filterSearch = false
GET("$baseUrl/hentailist?search=$query") // regular search
} else {
filterSearch = true
GET("$baseUrl/filter?$parameters&page=$page") // with filters
}
}
override fun animeDetailsParse(document: Document): SAnime {
val anime = SAnime.create()
anime.title = formatTitle(document.select("div.container.hentai-title-as.mb-3.w-100 b").text())
val tempDetails = document.select("div.container.shadow.rounded.bg-dark-as-box.mb-3.p-3.w-100.text-white").text()
val indexA = tempDetails.indexOf("Stato:")
anime.author = tempDetails.substring(7, indexA).trim()
val indexS1 = tempDetails.indexOf("Stato:") + 6
val indexS2 = tempDetails.indexOf("Data di uscita:")
anime.status = parseStatus(tempDetails.substring(indexS1, indexS2).trim())
anime.genre = document.select("div.container.shadow.rounded.bg-dark-as-box.mb-3.p-3.w-100 a.badge.badge-dark.generi-as.mb-1").joinToString { it.text() }
anime.thumbnail_url = document.selectFirst("img.img-fluid.cover-anime.rounded").attr("src")
val alterTitle = formatTitle(document.selectFirst("div.box-trasparente-alternativo.rounded").text()).replace("Dub ITA", "").trim()
val description1 = document.select("div#trama div#shown-trama").firstOrNull()?.ownText()
val description2 = document.select("div#full-trama.d-none").firstOrNull()?.ownText()
when {
description1 == null -> {
anime.description = description2
}
description2 == null -> {
anime.description = description1
}
description1.length > description2.length -> {
anime.description = description1
}
else -> {
anime.description = description2
}
}
if (!anime.title.contains(alterTitle, true)) {
anime.description = anime.description + "\n\nTitolo Alternativo: " + alterTitle
}
return anime
}
private fun parseStatus(statusString: String): Int {
return when {
statusString.contains("In corso") -> {
SAnime.ONGOING
}
statusString.contains("Finito") -> {
SAnime.COMPLETED
}
else -> {
SAnime.UNKNOWN
}
}
}
override fun latestUpdatesSelector(): String = "div.card.mb-4.shadow-sm"
override fun latestUpdatesFromElement(element: Element): SAnime {
val anime = SAnime.create()
anime.setUrlWithoutDomain(element.selectFirst("a").attr("href"))
anime.title = formatTitle(element.selectFirst("a").attr("title"))
anime.thumbnail_url = element.selectFirst("a img.new-hentai").attr("src")
return anime
}
override fun latestUpdatesRequest(page: Int): Request = GET("$baseUrl/newest?page=$page")
override fun latestUpdatesNextPageSelector(): String = "li.page-item.active:not(li:last-child)"
// Filters
internal class Genre(val id: String) : AnimeFilter.CheckBox(id)
private class GenreList(genres: List<Genre>) : AnimeFilter.Group<Genre>("Generi", genres)
private fun getGenres() = listOf(
Genre("3D"),
Genre("Ahegao"),
Genre("Anal"),
Genre("BDSM"),
Genre("Big Boobs"),
Genre("Blow Job"),
Genre("Bondage"),
Genre("Boob Job"),
Genre("Censored"),
Genre("Comedy"),
Genre("Cosplay"),
Genre("Creampie"),
Genre("Dark Skin"),
Genre("Erotic Game"),
Genre("Facial"),
Genre("Fantasy"),
Genre("Filmed"),
Genre("Foot Job"),
Genre("Futanari"),
Genre("Gangbang"),
Genre("Glasses"),
Genre("Hand Job"),
Genre("Harem"),
Genre("HD"),
Genre("Horror"),
Genre("Incest"),
Genre("Inflation"),
Genre("Lactation"),
Genre("Loli"),
Genre("Maid"),
Genre("Masturbation"),
Genre("Milf"),
Genre("Mind Break"),
Genre("Mind Control"),
Genre("Monster"),
Genre("NTR"),
Genre("Nurse"),
Genre("Orgy"),
Genre("Plot"),
Genre("POV"),
Genre("Pregnant"),
Genre("Public Sex"),
Genre("Rape"),
Genre("Reverse Rape"),
Genre("Rimjob"),
Genre("Scat"),
Genre("School Girl"),
Genre("Shota"),
Genre("Softcore"),
Genre("Swimsuit"),
Genre("Teacher"),
Genre("Tentacle"),
Genre("Threesome"),
Genre("Toys"),
Genre("Trap"),
Genre("Tsundere"),
Genre("Ugly Bastard"),
Genre("Uncensored"),
Genre("Vanilla"),
Genre("Virgin"),
Genre("Watersports"),
Genre("X-Ray"),
Genre("Yaoi"),
Genre("Yuri")
)
internal class Year(val id: String) : AnimeFilter.CheckBox(id)
private class YearList(years: List<Year>) : AnimeFilter.Group<Year>("Anno di Uscita", years)
private fun getYears() = listOf(
Year("1996"),
Year("1997"),
Year("1999"),
Year("2000"),
Year("2001"),
Year("2002"),
Year("2003"),
Year("2004"),
Year("2005"),
Year("2006"),
Year("2007"),
Year("2008"),
Year("2009"),
Year("2010"),
Year("2011"),
Year("2012"),
Year("2013"),
Year("2014"),
Year("2015"),
Year("2016"),
Year("2017"),
Year("2018"),
Year("2019"),
Year("2020"),
Year("2021")
)
internal class State(val id: String, name: String) : AnimeFilter.CheckBox(name)
private class StateList(states: List<State>) : AnimeFilter.Group<State>("Stato", states)
private fun getStates() = listOf(
State("0", "In corso"),
State("1", "Finito"),
State("2", "Non rilasciato"),
State("3", "Droppato")
)
internal class Lang(val id: String, name: String) : AnimeFilter.CheckBox(name)
private class LangList(langs: List<Lang>) : AnimeFilter.Group<Lang>("Lingua", langs)
private fun getLangs() = listOf(
Lang("0", "Subbato"),
Lang("1", "Doppiato")
)
override fun getFilterList(): AnimeFilterList = AnimeFilterList(
AnimeFilter.Header("Ricerca per titolo ignora i filtri e viceversa"),
GenreList(getGenres()),
YearList(getYears()),
StateList(getStates()),
LangList(getLangs())
)
private fun getSearchParameters(filters: AnimeFilterList): String {
var totalstring = ""
var variantgenre = 0
var variantstate = 0
var variantyear = 0
filters.forEach { filter ->
when (filter) {
is GenreList -> { // ---Genre
filter.state.forEach { Genre ->
if (Genre.state) {
totalstring = totalstring + "&categories%5B" + variantgenre.toString() + "%5D=" + Genre.id
variantgenre++
}
}
}
is YearList -> { // ---Year
filter.state.forEach { Year ->
if (Year.state) {
totalstring = totalstring + "&years%5B" + variantyear.toString() + "%5D=" + Year.id
variantyear++
}
}
}
is StateList -> { // ---State
filter.state.forEach { State ->
if (State.state) {
totalstring = totalstring + "&states%5B" + variantstate.toString() + "%5D=" + State.id
variantstate++
}
}
}
is LangList -> { // ---Lang
filter.state.forEach { Lang ->
if (Lang.state) {
totalstring = totalstring + "&language%5B0%5D=" + Lang.id
}
}
}
else -> {}
}
}
return totalstring
}
override fun setupPreferenceScreen(screen: PreferenceScreen) {
val videoQualityPref = ListPreference(screen.context).apply {
key = "preferred_quality"
title = "Qualità preferita"
entries = arrayOf("1080p", "720p", "480p", "360p")
entryValues = arrayOf("1080", "720", "480", "360")
setDefaultValue("1080")
summary = "%s"
setOnPreferenceChangeListener { _, newValue ->
val selected = newValue as String
val index = findIndexOfValue(selected)
val entry = entryValues[index] as String
preferences.edit().putString(key, entry).commit()
}
}
screen.addPreference(videoQualityPref)
}
}