diff --git a/src/it/dreamsub/build.gradle b/src/it/dreamsub/build.gradle index 330447125..2020f385e 100644 --- a/src/it/dreamsub/build.gradle +++ b/src/it/dreamsub/build.gradle @@ -5,8 +5,9 @@ ext { extName = 'DreamSub' pkgNameSuffix = 'it.dreamsub' extClass = '.DreamSub' - extVersionCode = 1 + extVersionCode = 2 libVersion = '12' + containsNsfw = true } apply from: "$rootDir/common.gradle" diff --git a/src/it/dreamsub/src/eu/kanade/tachiyomi/animeextension/it/dreamsub/DreamSub.kt b/src/it/dreamsub/src/eu/kanade/tachiyomi/animeextension/it/dreamsub/DreamSub.kt index 80fa3d755..755679a64 100644 --- a/src/it/dreamsub/src/eu/kanade/tachiyomi/animeextension/it/dreamsub/DreamSub.kt +++ b/src/it/dreamsub/src/eu/kanade/tachiyomi/animeextension/it/dreamsub/DreamSub.kt @@ -1,10 +1,12 @@ package eu.kanade.tachiyomi.animeextension.it.dreamsub +import android.annotation.SuppressLint 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 @@ -21,6 +23,7 @@ import org.jsoup.nodes.Element import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.api.get import java.lang.Exception +import java.text.SimpleDateFormat class DreamSub : ConfigurableAnimeSource, ParsedAnimeHttpSource() { @@ -59,12 +62,36 @@ class DreamSub : ConfigurableAnimeSource, ParsedAnimeHttpSource() { return document.select(episodeListSelector()).map { episodeFromElement(it) }.reversed() } + private fun formatDate(scrape_time: String): String = scrape_time.filter { !it.isWhitespace() } + .replace("Gennaio", "-01-") + .replace("Febbraio", "-02-") + .replace("Marzo", "-03-") + .replace("Aprile", "-04-") + .replace("Maggio", "-05-") + .replace("Giugno", "-06-") + .replace("Luglio", "-07-") + .replace("Agosto", "-08-") + .replace("Settembre", "-09-") + .replace("Ottobre", "-10-") + .replace("Novembre", "-11-") + .replace("Dicembre", "-12-") + + @SuppressLint("SimpleDateFormat") + private fun parseDate(scrape_time: String): Long { + return SimpleDateFormat("dd-MM-yyyy").parse(scrape_time).time + } + private fun oneEpisodeParse(document: Document): List { val episode = SEpisode.create() episode.setUrlWithoutDomain(document.location()) episode.episode_number = 1F episode.name = document.selectFirst("ol.breadcrumb li a").text() - episode.date_upload = System.currentTimeMillis() + episode.date_upload = parseDate( + formatDate( + document.select("div.dcis").text() + .substringBefore(", Conclusa").substringAfter("Data:") + ) + ) return listOf(episode) } @@ -76,7 +103,7 @@ class DreamSub : ConfigurableAnimeSource, ParsedAnimeHttpSource() { val epText = element.selectFirst("div.sli-name a").text() episode.episode_number = epText.substringAfter("Episodio ").substringBefore(":").toFloat() episode.name = epText.replace(": TBA", "") - episode.date_upload = System.currentTimeMillis() + episode.date_upload = parseDate(formatDate(element.selectFirst("div.sli-name span").text())) return episode } @@ -128,26 +155,34 @@ class DreamSub : ConfigurableAnimeSource, ParsedAnimeHttpSource() { override fun searchAnimeSelector(): String = "div.goblock-content.go-full div.tvBlock" - override fun searchAnimeRequest(page: Int, query: String, filters: AnimeFilterList): Request = - GET("$baseUrl/search/?q=$query&page=${page - 1}") + override fun searchAnimeRequest(page: Int, query: String, filters: AnimeFilterList): Request { + val parameters = getSearchParameters(filters) + return GET("$baseUrl/search?$parameters&q=$query&page=${page - 1}") + } override fun animeDetailsParse(document: Document): SAnime { val anime = SAnime.create() anime.title = document.select("div.dc-info h1.dc-title a").text() anime.genre = document.select("div.dc-info div.dci-spe div.dcis a").joinToString { it.text() } - anime.description = document.select("div.dc-info div.dci-desc span#tramaLong").firstOrNull()?.ownText() + val descriptiontry = document.select("div.dc-info div.dci-desc span#tramaLong").firstOrNull()?.ownText() + if (descriptiontry.isNullOrEmpty()) anime.description = document.select("div.dc-info div.dci-desc span").firstOrNull()?.ownText() + else anime.description = descriptiontry anime.status = parseStatus(document.select("div.dcis:contains(Data:)").text()) anime.thumbnail_url = "https:" + document.selectFirst("div.dc-thumb img").attr("src") return anime } private fun parseStatus(statusString: String): Int { - return if (statusString.contains("In Corso")) { - SAnime.ONGOING - } else if (statusString.contains("Conclusa")) { - SAnime.COMPLETED - } else { - SAnime.UNKNOWN + return when { + statusString.contains("In Corso") -> { + SAnime.ONGOING + } + statusString.contains("Conclusa") -> { + SAnime.COMPLETED + } + else -> { + SAnime.UNKNOWN + } } } @@ -169,6 +204,239 @@ class DreamSub : ConfigurableAnimeSource, ParsedAnimeHttpSource() { override fun latestUpdatesSelector(): String = "div.vistaGriglia ul.grid-item li" + internal class Type(val id: String) : AnimeFilter.TriState(id) + private class TypeList(types: List) : AnimeFilter.Group("Tipo", types) + private fun getTypes() = listOf( + Type("TV"), + Type("Movie"), + Type("OAV"), + Type("Spinoff"), + Type("Special"), + Type("ONA") + ) + + internal class Genre(val id: String, name: String) : AnimeFilter.TriState(name) + private class GenreList(genres: List) : AnimeFilter.Group("Generi", genres) + private fun getGenres() = listOf( + Genre("2|", "Arti Marziali"), + Genre("4|", "Avventura"), + Genre("5|", "Azione"), + Genre("6|", "Bambini"), + Genre("9|", "Commedia"), + Genre("10|", "Crimine"), + Genre("11|", "Demenziale"), + Genre("12|", "Demoni"), + Genre("14|", "Dramma"), + Genre("15|", "Ecchi"), + Genre("17|", "Fantascienza"), + Genre("18|", "Fantasy"), + Genre("19|", "Giallo"), + Genre("22|", "Harem"), + Genre("23|", "Hentai"), + Genre("24|", "Horror"), + Genre("25|", "Josei"), + Genre("27|", "Magia"), + Genre("28|", "Mecha"), + Genre("20|", "Militare"), + Genre("47|", "Mistero"), + Genre("30|", "Musica"), + Genre("32|", "Parodia"), + Genre("33|", "Poliziesco"), + Genre("35|", "Psicologico"), + Genre("36|", "Samurai"), + Genre("37|", "Scuola"), + Genre("38|", "Seinen"), + Genre("39|", "Sentimentale"), + Genre("40|", "Shojo"), + Genre("41|", "Shonen"), + Genre("56|", "Shounen Ai"), + Genre("52|", "Slice of Life"), + Genre("42|", "Sovrannaturale"), + Genre("21|", "Spazio"), + Genre("43|", "Sport"), + Genre("44|", "Storico"), + Genre("45|", "Superpoteri"), + Genre("48|", "Vampiri"), + Genre("49|", "Videogame"), + Genre("53|", "Yaoi"), + Genre("54|", "Yuri") + ) + + internal class State(val id: String, name: String) : AnimeFilter.TriState(name) + private class StateList(states: List) : AnimeFilter.Group("Stato", states) + private fun getStates() = listOf( + State("inCorso", "In Corso"), + State("future", "Future"), + State("concluse", "Concluse") + ) + + private val sortableList = listOf( + Pair("Popolarità", "ppl-"), + Pair("Alfabetico", "az-"), + Pair("Punteggio", "score-"), + Pair("Ultime Aggiunte", "lat-"), + Pair("Anno di Uscita", "yea-"), + Pair("Numero Episodi", "eps-"), + Pair("Visualizzazioni", "view-") + ) + class SortFilter(sortables: Array) : AnimeFilter.Sort("Ordina Per", sortables, Selection(0, true)) + + private class ScoreFilter : + AnimeFilter.Select( + "Voto Minimo", + arrayOf( + "", + "0", + "0.5", + "1", + "1.5", + "2", + "2.5", + "3", + "3.5", + "4", + "4.5", + "5", + "5.5", + "6", + "6.5", + "7", + "7.5", + "8", + "8.5", + "9", + "9.5", + "10" + ), + 0 + ) + + internal class MinYear(val input: String, name: String) : AnimeFilter.Text(name) + internal class MaxYear(val input: String, name: String) : AnimeFilter.Text(name) + + internal class MinEps(val input: String, name: String) : AnimeFilter.Text(name) + internal class MaxEps(val input: String, name: String) : AnimeFilter.Text(name) + + internal class Length(val input: String, name: String) : AnimeFilter.Text(name) + + override fun getFilterList(): AnimeFilterList = AnimeFilterList( + TypeList(getTypes()), + GenreList(getGenres()), + AnimeFilter.Header("Anno di Uscita"), + MinYear("1968", "Minimo Anno di Uscita(Default: 1968)"), // 1968 default + MaxYear("2022", "Massimo Anno di Uscita(Default: 2022)"), // 2022 default + ScoreFilter(), + AnimeFilter.Header("Numero Episodi"), + MinEps("1", "Minimo Episodi"), // 1 default + MaxEps("1105", "Massimo Episodi(Default: 1105)"), // 1105 default + AnimeFilter.Header("Durata Episodi(minuti)"), + Length("216", "Massima Durata(Default: 216)"), // 216 default + StateList(getStates()), + SortFilter(sortableList.map { it.first }.toTypedArray()), + ) + + private fun getSearchParameters(filters: AnimeFilterList): String { + var finalstring = "" + var includedTypes = "" + var blackListedTypes = "" + + var includedGenres = "" + var blackListedGenres = "" + + var includedStates = "" + var blackListedStates = "" + + var sortString = "" + + var minyear = "" + var maxyear = "" + var mineps = "" + var maxeps = "" + + filters.forEach { filter -> + when (filter) { + is TypeList -> { + filter.state.forEach { type -> + if (type.isIncluded()) { + includedTypes += type.id.toLowerCase() + } else if (type.isExcluded()) { + blackListedTypes += type.id.toLowerCase() + } + } + } + + is GenreList -> { + filter.state.forEach { genre -> + if (genre.isIncluded()) { + includedGenres += genre.id + } else if (genre.isExcluded()) { + blackListedGenres += genre.id + } + } + } + + is StateList -> { + filter.state.forEach { state -> + if (state.isIncluded()) { + includedStates += state.id + } else if (state.isExcluded()) { + blackListedStates += state.id + } + } + } + is ScoreFilter -> { + if (filter.values[filter.state] != "") finalstring += "voto=${filter.values[filter.state]}" + } + is SortFilter -> { + if (filter.state != null) { + when (sortableList[filter.state!!.index].second) { + "az-" -> sortString += "&order=A-Z" + "score-" -> sortString += "&order=rating" + "lat-" -> sortString += "&order=recenti" + "yea-" -> sortString += "&order=anno" + "eps-" -> sortString += "&order=episodi" + "view-" -> sortString += "&order=views" + } + when (filter.state!!.ascending) { + false -> sortString += "¬_order=true" + } + } + } + is MinYear -> { + minyear = if (filter.state.isEmpty()) "1968" // default value + else filter.state + } + is MaxYear -> { + maxyear = if (filter.state.isEmpty()) "2022" // default value + else filter.state + } + is MinEps -> { + mineps = if (filter.state.isEmpty()) "1" // default value + else filter.state + } + is MaxEps -> { + maxeps = if (filter.state.isEmpty()) "1105" // default value + else filter.state + } + is Length -> { + finalstring += if (filter.state.isEmpty()) "&maxEpLenght=216" // default value + else "&maxEpLenght=${filter.state}" + } + else -> {} + } + } + if (includedTypes.isNotEmpty()) finalstring += "&typeY=|$includedTypes" + if (blackListedTypes.isNotEmpty()) finalstring += "&typeN=|$blackListedTypes" + if (includedGenres.isNotEmpty()) finalstring += "&genereY=|$includedGenres" + if (blackListedGenres.isNotEmpty()) finalstring += "&genereN=|$blackListedGenres" + if (includedStates.isNotEmpty()) finalstring += "&statesY=|$includedStates" + if (blackListedStates.isNotEmpty()) finalstring += "&statesN=|$blackListedStates" + finalstring += "&year=$minyear-$maxyear" // year release + finalstring += "&episodes=$mineps-$maxeps" // amount episodes + finalstring += sortString + return finalstring + } + override fun setupPreferenceScreen(screen: PreferenceScreen) { val videoQualityPref = ListPreference(screen.context).apply { key = "preferred_quality"