refactor(it): refactoring of some italian extensions (#1776)
This commit is contained in:
@ -15,7 +15,6 @@ import eu.kanade.tachiyomi.animesource.online.ParsedAnimeHttpSource
|
|||||||
import eu.kanade.tachiyomi.lib.streamtapeextractor.StreamTapeExtractor
|
import eu.kanade.tachiyomi.lib.streamtapeextractor.StreamTapeExtractor
|
||||||
import eu.kanade.tachiyomi.network.GET
|
import eu.kanade.tachiyomi.network.GET
|
||||||
import eu.kanade.tachiyomi.util.asJsoup
|
import eu.kanade.tachiyomi.util.asJsoup
|
||||||
import okhttp3.HttpUrl.Companion.toHttpUrl
|
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
import okhttp3.Response
|
import okhttp3.Response
|
||||||
@ -46,15 +45,13 @@ class AnimeLove : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
|||||||
|
|
||||||
override fun popularAnimeSelector(): String = "div.containerlista > div.row > div.col-6"
|
override fun popularAnimeSelector(): String = "div.containerlista > div.row > div.col-6"
|
||||||
|
|
||||||
override fun popularAnimeNextPageSelector(): String = "div > ul.page-nav > li:last-child:not(:has(a.disabled))"
|
override fun popularAnimeFromElement(element: Element): SAnime = SAnime.create().apply {
|
||||||
|
setUrlWithoutDomain(element.selectFirst("a")!!.attr("href"))
|
||||||
override fun popularAnimeFromElement(element: Element): SAnime {
|
|
||||||
return SAnime.create().apply {
|
|
||||||
setUrlWithoutDomain(element.selectFirst("a")!!.attr("href").toHttpUrl().encodedPath)
|
|
||||||
thumbnail_url = element.selectFirst("img")?.attr("src")
|
thumbnail_url = element.selectFirst("img")?.attr("src")
|
||||||
title = element.selectFirst("div.default-text")!!.text()
|
title = element.selectFirst("div.default-text")!!.text()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
override fun popularAnimeNextPageSelector(): String = "div > ul.page-nav > li:last-child:not(:has(a.disabled))"
|
||||||
|
|
||||||
// =============================== Latest ===============================
|
// =============================== Latest ===============================
|
||||||
|
|
||||||
@ -62,10 +59,10 @@ class AnimeLove : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
|||||||
|
|
||||||
override fun latestUpdatesSelector(): String = popularAnimeSelector()
|
override fun latestUpdatesSelector(): String = popularAnimeSelector()
|
||||||
|
|
||||||
override fun latestUpdatesNextPageSelector(): String = popularAnimeNextPageSelector()
|
|
||||||
|
|
||||||
override fun latestUpdatesFromElement(element: Element): SAnime = popularAnimeFromElement(element)
|
override fun latestUpdatesFromElement(element: Element): SAnime = popularAnimeFromElement(element)
|
||||||
|
|
||||||
|
override fun latestUpdatesNextPageSelector(): String = popularAnimeNextPageSelector()
|
||||||
|
|
||||||
// =============================== Search ===============================
|
// =============================== Search ===============================
|
||||||
|
|
||||||
override fun searchAnimeRequest(page: Int, query: String, filters: AnimeFilterList): Request {
|
override fun searchAnimeRequest(page: Int, query: String, filters: AnimeFilterList): Request {
|
||||||
@ -89,30 +86,26 @@ class AnimeLove : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
|||||||
return super.searchAnimeParse(response)
|
return super.searchAnimeParse(response)
|
||||||
}
|
}
|
||||||
|
|
||||||
val document = response.asJsoup()
|
val animeList = response.asJsoup()
|
||||||
|
.select(searchAnimeSelectorSearch())
|
||||||
|
.map(::searchAnimeFromElementSearch)
|
||||||
|
|
||||||
val animes = document.select(searchAnimeSelectorSearch()).map { element ->
|
return AnimesPage(animeList, false)
|
||||||
searchAnimeFromElementSearch(element)
|
|
||||||
}
|
|
||||||
|
|
||||||
return AnimesPage(animes, false)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun searchAnimeSelector(): String = popularAnimeSelector()
|
override fun searchAnimeSelector(): String = popularAnimeSelector()
|
||||||
|
|
||||||
private fun searchAnimeSelectorSearch(): String = "div.col-md-8 > div.card > div.card-body > div.row > div.col-6"
|
private fun searchAnimeSelectorSearch(): String = "div.col-md-8 > div.card > div.card-body > div.row > div.col-6"
|
||||||
|
|
||||||
override fun searchAnimeNextPageSelector(): String = popularAnimeNextPageSelector()
|
override fun searchAnimeFromElement(element: Element): SAnime = popularAnimeFromElement(element)
|
||||||
|
|
||||||
private fun searchAnimeFromElementSearch(element: Element): SAnime {
|
private fun searchAnimeFromElementSearch(element: Element): SAnime = SAnime.create().apply {
|
||||||
return SAnime.create().apply {
|
setUrlWithoutDomain(element.selectFirst("a")!!.attr("href"))
|
||||||
setUrlWithoutDomain(element.selectFirst("a")!!.attr("href").toHttpUrl().encodedPath)
|
|
||||||
thumbnail_url = element.selectFirst("img")?.attr("src")
|
thumbnail_url = element.selectFirst("img")?.attr("src")
|
||||||
title = element.selectFirst("p.card-text")!!.text()
|
title = element.selectFirst("p.card-text")!!.text()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
override fun searchAnimeFromElement(element: Element): SAnime = popularAnimeFromElement(element)
|
override fun searchAnimeNextPageSelector(): String = popularAnimeNextPageSelector()
|
||||||
|
|
||||||
// ============================== Filters ===============================
|
// ============================== Filters ===============================
|
||||||
|
|
||||||
@ -238,37 +231,33 @@ class AnimeLove : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
|||||||
|
|
||||||
// =========================== Anime Details ============================
|
// =========================== Anime Details ============================
|
||||||
|
|
||||||
override fun animeDetailsParse(document: Document): SAnime {
|
override fun animeDetailsParse(document: Document): SAnime = SAnime.create().apply {
|
||||||
val moreInfo = (document.selectFirst("div.card-body > p:contains(TIPO:)")?.text() ?: "") +
|
|
||||||
"\n" +
|
|
||||||
(document.selectFirst("div.card-body > p:contains(ANNO)")?.text() ?: "")
|
|
||||||
|
|
||||||
return SAnime.create().apply {
|
|
||||||
title = document.selectFirst("div.card-body > p:contains(TITOLO:)")?.ownText() ?: ""
|
title = document.selectFirst("div.card-body > p:contains(TITOLO:)")?.ownText() ?: ""
|
||||||
thumbnail_url = document.selectFirst("div.card-body > div > img")?.attr("src") ?: ""
|
thumbnail_url = document.selectFirst("div.card-body > div > img")?.attr("src") ?: ""
|
||||||
author = document.selectFirst("div.card-body > p:contains(STUDIO:)")?.ownText() ?: ""
|
author = document.selectFirst("div.card-body > p:contains(STUDIO:)")?.ownText() ?: ""
|
||||||
status = document.selectFirst("div.card-body > p:contains(STATO:)")?.let {
|
status = document.selectFirst("div.card-body > p:contains(STATO:)")?.let {
|
||||||
parseStatus(it.ownText())
|
parseStatus(it.ownText())
|
||||||
} ?: SAnime.UNKNOWN
|
} ?: SAnime.UNKNOWN
|
||||||
description = (document.selectFirst("div.card-body > p:contains(TRAMA:) ~ p")?.text() ?: "") + "\n\n$moreInfo"
|
|
||||||
genre = document.selectFirst("div.card-body > p:contains(GENERI:)")?.ownText() ?: ""
|
genre = document.selectFirst("div.card-body > p:contains(GENERI:)")?.ownText() ?: ""
|
||||||
|
description = buildString {
|
||||||
|
append(document.selectFirst("div.card-body > p:contains(TRAMA:) ~ p")?.text() ?: "")
|
||||||
|
append("\n\n")
|
||||||
|
append(document.selectFirst("div.card-body > p:contains(TIPO:)")?.text() ?: "")
|
||||||
|
append("\n")
|
||||||
|
append(document.selectFirst("div.card-body > p:contains(ANNO)")?.text() ?: "")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============================== Episodes ==============================
|
// ============================== Episodes ==============================
|
||||||
|
|
||||||
override fun episodeListParse(response: Response): List<SEpisode> {
|
override fun episodeListParse(response: Response): List<SEpisode> = super.episodeListParse(response).reversed()
|
||||||
return super.episodeListParse(response).reversed()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun episodeListSelector(): String = "div.card ul.page-nav-list-episodi > li"
|
override fun episodeListSelector(): String = "div.card ul.page-nav-list-episodi > li"
|
||||||
|
|
||||||
override fun episodeFromElement(element: Element): SEpisode {
|
override fun episodeFromElement(element: Element): SEpisode = SEpisode.create().apply {
|
||||||
return SEpisode.create().apply {
|
|
||||||
name = "Episodi ${element.text()}"
|
name = "Episodi ${element.text()}"
|
||||||
episode_number = element.selectFirst("span")?.text()?.toFloatOrNull() ?: 0F
|
episode_number = element.selectFirst("span")?.text()?.toFloatOrNull() ?: 0F
|
||||||
setUrlWithoutDomain(element.selectFirst("a[href]")!!.attr("href").toHttpUrl().encodedPath)
|
setUrlWithoutDomain(element.selectFirst("a[href]")!!.attr("href"))
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============================ Video Links =============================
|
// ============================ Video Links =============================
|
||||||
@ -301,13 +290,15 @@ class AnimeLove : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
require(videoList.isNotEmpty()) { "Failed to fetch videos" }
|
||||||
|
|
||||||
return videoList
|
return videoList
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun videoFromElement(element: Element): Video = throw Exception("Not Used")
|
|
||||||
|
|
||||||
override fun videoListSelector(): String = throw Exception("Not Used")
|
override fun videoListSelector(): String = throw Exception("Not Used")
|
||||||
|
|
||||||
|
override fun videoFromElement(element: Element): Video = throw Exception("Not Used")
|
||||||
|
|
||||||
override fun videoUrlParse(document: Document): String = throw Exception("Not Used")
|
override fun videoUrlParse(document: Document): String = throw Exception("Not Used")
|
||||||
|
|
||||||
// ============================= Utilities ==============================
|
// ============================= Utilities ==============================
|
||||||
@ -328,7 +319,7 @@ class AnimeLove : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun List<Video>.sort(): List<Video> {
|
override fun List<Video>.sort(): List<Video> {
|
||||||
val server = preferences.getString("preferred_server", "AnimeLove")!!
|
val server = preferences.getString(PREF_SERVER_KEY, PREF_SERVER_DEFAULT)!!
|
||||||
|
|
||||||
return this.sortedWith(
|
return this.sortedWith(
|
||||||
compareBy { it.quality.contains(server, true) },
|
compareBy { it.quality.contains(server, true) },
|
||||||
@ -343,13 +334,20 @@ class AnimeLove : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val PREF_SERVER_KEY = "preferred_server"
|
||||||
|
private const val PREF_SERVER_DEFAULT = "AnimeLove"
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================== Settings ==============================
|
||||||
|
|
||||||
override fun setupPreferenceScreen(screen: PreferenceScreen) {
|
override fun setupPreferenceScreen(screen: PreferenceScreen) {
|
||||||
val videoServerPref = ListPreference(screen.context).apply {
|
ListPreference(screen.context).apply {
|
||||||
key = "preferred_server"
|
key = PREF_SERVER_KEY
|
||||||
title = "Preferred server"
|
title = "Preferred server"
|
||||||
entries = arrayOf("AnimeLove", "StreamTape")
|
entries = arrayOf("AnimeLove", "StreamTape")
|
||||||
entryValues = arrayOf("AnimeLove", "StreamTape")
|
entryValues = arrayOf("AnimeLove", "StreamTape")
|
||||||
setDefaultValue("AnimeLove")
|
setDefaultValue(PREF_SERVER_DEFAULT)
|
||||||
summary = "%s"
|
summary = "%s"
|
||||||
|
|
||||||
setOnPreferenceChangeListener { _, newValue ->
|
setOnPreferenceChangeListener { _, newValue ->
|
||||||
@ -358,7 +356,6 @@ class AnimeLove : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
|||||||
val entry = entryValues[index] as String
|
val entry = entryValues[index] as String
|
||||||
preferences.edit().putString(key, entry).commit()
|
preferences.edit().putString(key, entry).commit()
|
||||||
}
|
}
|
||||||
}
|
}.also(screen::addPreference)
|
||||||
screen.addPreference(videoServerPref)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,8 @@ package eu.kanade.tachiyomi.animeextension.it.animeunity
|
|||||||
|
|
||||||
import eu.kanade.tachiyomi.animesource.model.AnimeFilter
|
import eu.kanade.tachiyomi.animesource.model.AnimeFilter
|
||||||
import eu.kanade.tachiyomi.animesource.model.AnimeFilterList
|
import eu.kanade.tachiyomi.animesource.model.AnimeFilterList
|
||||||
|
import kotlinx.serialization.json.buildJsonObject
|
||||||
|
import kotlinx.serialization.json.put
|
||||||
|
|
||||||
object AnimeUnityFilters {
|
object AnimeUnityFilters {
|
||||||
|
|
||||||
@ -28,7 +30,7 @@ object AnimeUnityFilters {
|
|||||||
|
|
||||||
class GenreFilter : CheckBoxFilterList(
|
class GenreFilter : CheckBoxFilterList(
|
||||||
"Genere",
|
"Genere",
|
||||||
AnimeUnityFiltersData.GENERE.map { CheckBoxVal(it.first, false) },
|
AnimeUnityFiltersData.GENRE.map { CheckBoxVal(it.first, false) },
|
||||||
)
|
)
|
||||||
|
|
||||||
class YearFilter : QueryPartFilter("Anno", AnimeUnityFiltersData.YEAR)
|
class YearFilter : QueryPartFilter("Anno", AnimeUnityFiltersData.YEAR)
|
||||||
@ -73,15 +75,12 @@ object AnimeUnityFilters {
|
|||||||
|
|
||||||
val genre: String = filters.filterIsInstance<GenreFilter>()
|
val genre: String = filters.filterIsInstance<GenreFilter>()
|
||||||
.first()
|
.first()
|
||||||
.state.mapNotNull { format ->
|
.state.filter { it.state }.joinToString(",") { format ->
|
||||||
if (format.state) {
|
buildJsonObject {
|
||||||
"{\"id\":" +
|
put("id", AnimeUnityFiltersData.GENRE.find { it.first == format.name }!!.second.toInt())
|
||||||
AnimeUnityFiltersData.GENERE.find { it.first == format.name }!!.second +
|
put("name", AnimeUnityFiltersData.GENRE.find { it.first == format.name }!!.first)
|
||||||
",\"name\":\"" +
|
}.toString()
|
||||||
AnimeUnityFiltersData.GENERE.find { it.first == format.name }!!.first +
|
}
|
||||||
"\"}"
|
|
||||||
} else { null }
|
|
||||||
}.joinToString(",")
|
|
||||||
|
|
||||||
return FilterSearchParams(
|
return FilterSearchParams(
|
||||||
filters.asQueryPart<TopFilter>(),
|
filters.asQueryPart<TopFilter>(),
|
||||||
@ -113,7 +112,7 @@ object AnimeUnityFilters {
|
|||||||
Pair("Più visti", "top-anime?order=most_viewed"),
|
Pair("Più visti", "top-anime?order=most_viewed"),
|
||||||
)
|
)
|
||||||
|
|
||||||
val GENERE = arrayOf(
|
val GENRE = arrayOf(
|
||||||
Pair("Action", "51"),
|
Pair("Action", "51"),
|
||||||
Pair("Adventure", "21"),
|
Pair("Adventure", "21"),
|
||||||
Pair("Cars", "29"),
|
Pair("Cars", "29"),
|
||||||
|
@ -76,33 +76,33 @@ class AniPlay : ConfigurableAnimeSource, AnimeHttpSource() {
|
|||||||
override fun searchAnimeRequest(page: Int, query: String, filters: AnimeFilterList): Request = throw Exception("Not used")
|
override fun searchAnimeRequest(page: Int, query: String, filters: AnimeFilterList): Request = throw Exception("Not used")
|
||||||
|
|
||||||
private fun searchAnimeRequest(page: Int, query: String, filters: AniPlayFilters.FilterSearchParams): Request {
|
private fun searchAnimeRequest(page: Int, query: String, filters: AniPlayFilters.FilterSearchParams): Request {
|
||||||
if ((filters.anni.isNotEmpty() && filters.stagione.isEmpty()) ||
|
if ((filters.year.isNotEmpty() && filters.season.isEmpty()) ||
|
||||||
(filters.anni.isEmpty() && filters.stagione.isNotEmpty())
|
(filters.year.isEmpty() && filters.season.isNotEmpty())
|
||||||
) {
|
) {
|
||||||
throw Exception("Per gli anime stagionali, seleziona sia l'anno che la stagione")
|
error("Per gli anime stagionali, seleziona sia l'anno che la stagione")
|
||||||
}
|
}
|
||||||
|
|
||||||
val url = if (filters.anni.isNotEmpty()) {
|
val url = if (filters.year.isNotEmpty()) {
|
||||||
"$baseUrl/api/seasonal-view".toHttpUrlOrNull()!!.newBuilder()
|
"$baseUrl/api/seasonal-view".toHttpUrlOrNull()!!.newBuilder()
|
||||||
.addPathSegment("${filters.stagione}-${filters.anni}")
|
.addPathSegment("${filters.season}-${filters.year}")
|
||||||
.addQueryParameter("page", (page - 1).toString())
|
.addQueryParameter("page", (page - 1).toString())
|
||||||
.addQueryParameter("size", "36")
|
.addQueryParameter("size", "36")
|
||||||
.addQueryParameter("sort", filters.ordina)
|
.addQueryParameter("sort", filters.order)
|
||||||
.addQueryParameter("sort", "id")
|
.addQueryParameter("sort", "id")
|
||||||
} else {
|
} else {
|
||||||
"$baseUrl/api/anime/advanced-similar-search".toHttpUrlOrNull()!!.newBuilder()
|
"$baseUrl/api/anime/advanced-similar-search".toHttpUrlOrNull()!!.newBuilder()
|
||||||
.addQueryParameter("page", (page - 1).toString())
|
.addQueryParameter("page", (page - 1).toString())
|
||||||
.addQueryParameter("size", "36")
|
.addQueryParameter("size", "36")
|
||||||
.addQueryParameter("sort", filters.ordina)
|
.addQueryParameter("sort", filters.order)
|
||||||
.addQueryParameter("sort", "id")
|
.addQueryParameter("sort", "id")
|
||||||
.addIfNotBlank("query", query)
|
.addIfNotBlank("query", query)
|
||||||
.addIfNotBlank("genreIds", filters.genere)
|
.addIfNotBlank("genreIds", filters.genre)
|
||||||
.addIfNotBlank("typeIds", filters.tipologia)
|
.addIfNotBlank("typeIds", filters.type)
|
||||||
.addIfNotBlank("statusIds", filters.stato)
|
.addIfNotBlank("statusIds", filters.status)
|
||||||
.addIfNotBlank("originIds", filters.origine)
|
.addIfNotBlank("originIds", filters.origin)
|
||||||
.addIfNotBlank("studioIds", filters.studio)
|
.addIfNotBlank("studioIds", filters.studio)
|
||||||
.addIfNotBlank("startYear", filters.inizio)
|
.addIfNotBlank("startYear", filters.start)
|
||||||
.addIfNotBlank("endYear", filters.fine)
|
.addIfNotBlank("endYear", filters.end)
|
||||||
}
|
}
|
||||||
|
|
||||||
return GET(url.build().toString())
|
return GET(url.build().toString())
|
||||||
|
@ -24,24 +24,24 @@ object AniPlayFilters {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class GenereFilter : CheckBoxFilterList(
|
class GenreFilter : CheckBoxFilterList(
|
||||||
"Genere",
|
"Genere",
|
||||||
AniPlayFiltersData.GENERE.map { CheckBoxVal(it.first, false) },
|
AniPlayFiltersData.GENRE.map { CheckBoxVal(it.first, false) },
|
||||||
)
|
)
|
||||||
|
|
||||||
class TipologiaFilter : CheckBoxFilterList(
|
class TypeFilter : CheckBoxFilterList(
|
||||||
"Tipologia anime",
|
"Tipologia anime",
|
||||||
AniPlayFiltersData.TIPOLOGIA.map { CheckBoxVal(it.first, false) },
|
AniPlayFiltersData.TYPE.map { CheckBoxVal(it.first, false) },
|
||||||
)
|
)
|
||||||
|
|
||||||
class StatoFilter : CheckBoxFilterList(
|
class StatusFilter : CheckBoxFilterList(
|
||||||
"Stato",
|
"Stato",
|
||||||
AniPlayFiltersData.STATO.map { CheckBoxVal(it.first, false) },
|
AniPlayFiltersData.STATUS.map { CheckBoxVal(it.first, false) },
|
||||||
)
|
)
|
||||||
|
|
||||||
class OrigineFilter : CheckBoxFilterList(
|
class OriginFilter : CheckBoxFilterList(
|
||||||
"Origine",
|
"Origine",
|
||||||
AniPlayFiltersData.ORIGINE.map { CheckBoxVal(it.first, false) },
|
AniPlayFiltersData.ORIGIN.map { CheckBoxVal(it.first, false) },
|
||||||
)
|
)
|
||||||
|
|
||||||
class StudioFilter : CheckBoxFilterList(
|
class StudioFilter : CheckBoxFilterList(
|
||||||
@ -49,110 +49,105 @@ object AniPlayFilters {
|
|||||||
AniPlayFiltersData.STUDIO.map { CheckBoxVal(it.first, false) },
|
AniPlayFiltersData.STUDIO.map { CheckBoxVal(it.first, false) },
|
||||||
)
|
)
|
||||||
|
|
||||||
class InizioFilter : QueryPartFilter("Inizio", AniPlayFiltersData.ANNI)
|
class StartFilter : QueryPartFilter("Inizio", AniPlayFiltersData.YEAR)
|
||||||
class FineFilter : QueryPartFilter("Fine", AniPlayFiltersData.ANNI)
|
class EndFilter : QueryPartFilter("Fine", AniPlayFiltersData.YEAR)
|
||||||
class OrdinaFilter : QueryPartFilter("Ordina per", AniPlayFiltersData.ORDINA)
|
class OrderFilter : QueryPartFilter("Ordina per", AniPlayFiltersData.ORDER)
|
||||||
|
|
||||||
class AnniFilter : QueryPartFilter("Anni", AniPlayFiltersData.ANNI)
|
class YearFilter : QueryPartFilter("Anni", AniPlayFiltersData.YEAR)
|
||||||
class StagioneFilter : QueryPartFilter("Stagione", AniPlayFiltersData.STAGIONE)
|
class SeasonFilter : QueryPartFilter("Stagione", AniPlayFiltersData.SEASON)
|
||||||
|
|
||||||
val FILTER_LIST get() = AnimeFilterList(
|
val FILTER_LIST get() = AnimeFilterList(
|
||||||
OrdinaFilter(),
|
OrderFilter(),
|
||||||
AnimeFilter.Separator(),
|
AnimeFilter.Separator(),
|
||||||
|
|
||||||
GenereFilter(),
|
GenreFilter(),
|
||||||
TipologiaFilter(),
|
TypeFilter(),
|
||||||
StatoFilter(),
|
StatusFilter(),
|
||||||
OrigineFilter(),
|
OriginFilter(),
|
||||||
StudioFilter(),
|
StudioFilter(),
|
||||||
|
|
||||||
AnimeFilter.Separator(),
|
AnimeFilter.Separator(),
|
||||||
AnimeFilter.Header("Anni"),
|
AnimeFilter.Header("Anni"),
|
||||||
InizioFilter(),
|
StartFilter(),
|
||||||
FineFilter(),
|
EndFilter(),
|
||||||
|
|
||||||
AnimeFilter.Separator(),
|
AnimeFilter.Separator(),
|
||||||
AnimeFilter.Header("Anime stagionali"),
|
AnimeFilter.Header("Anime stagionali"),
|
||||||
AnimeFilter.Header("(ignora altri filtri tranne l'ordinamento per)"),
|
AnimeFilter.Header("(ignora altri filtri tranne l'ordinamento per)"),
|
||||||
AnniFilter(),
|
YearFilter(),
|
||||||
StagioneFilter(),
|
SeasonFilter(),
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
data class FilterSearchParams(
|
data class FilterSearchParams(
|
||||||
val ordina: String = "views,desc",
|
val order: String = "views,desc",
|
||||||
val genere: String = "",
|
val genre: String = "",
|
||||||
val tipologia: String = "",
|
val type: String = "",
|
||||||
val stato: String = "",
|
val status: String = "",
|
||||||
val origine: String = "",
|
val origin: String = "",
|
||||||
val studio: String = "",
|
val studio: String = "",
|
||||||
val inizio: String = "",
|
val start: String = "",
|
||||||
val fine: String = "",
|
val end: String = "",
|
||||||
val anni: String = "",
|
val year: String = "",
|
||||||
val stagione: String = "",
|
val season: String = "",
|
||||||
)
|
)
|
||||||
|
|
||||||
internal fun getSearchParameters(filters: AnimeFilterList): FilterSearchParams {
|
internal fun getSearchParameters(filters: AnimeFilterList): FilterSearchParams {
|
||||||
if (filters.isEmpty()) return FilterSearchParams()
|
if (filters.isEmpty()) return FilterSearchParams()
|
||||||
|
|
||||||
val genere: String = filters.filterIsInstance<GenereFilter>()
|
val genre: String = filters.filterIsInstance<GenreFilter>()
|
||||||
.first()
|
.first()
|
||||||
.state.mapNotNull { format ->
|
.state.filter { it.state }
|
||||||
if (format.state) {
|
.joinToString(",") { format ->
|
||||||
AniPlayFiltersData.GENERE.find { it.first == format.name }!!.second
|
AniPlayFiltersData.GENRE.find { it.first == format.name }!!.second
|
||||||
} else { null }
|
}
|
||||||
}.joinToString(",")
|
|
||||||
|
|
||||||
val tipologia: String = filters.filterIsInstance<TipologiaFilter>()
|
val type: String = filters.filterIsInstance<TypeFilter>()
|
||||||
.first()
|
.first()
|
||||||
.state.mapNotNull { format ->
|
.state.filter { it.state }
|
||||||
if (format.state) {
|
.joinToString(",") { format ->
|
||||||
AniPlayFiltersData.TIPOLOGIA.find { it.first == format.name }!!.second
|
AniPlayFiltersData.TYPE.find { it.first == format.name }!!.second
|
||||||
} else { null }
|
}
|
||||||
}.joinToString(",")
|
|
||||||
|
|
||||||
val stato: String = filters.filterIsInstance<StatoFilter>()
|
val status: String = filters.filterIsInstance<StatusFilter>()
|
||||||
.first()
|
.first()
|
||||||
.state.mapNotNull { format ->
|
.state.filter { it.state }
|
||||||
if (format.state) {
|
.joinToString(",") { format ->
|
||||||
AniPlayFiltersData.STATO.find { it.first == format.name }!!.second
|
AniPlayFiltersData.STATUS.find { it.first == format.name }!!.second
|
||||||
} else { null }
|
}
|
||||||
}.joinToString(",")
|
|
||||||
|
|
||||||
val origine: String = filters.filterIsInstance<OrigineFilter>()
|
val origin: String = filters.filterIsInstance<OriginFilter>()
|
||||||
.first()
|
.first()
|
||||||
.state.mapNotNull { format ->
|
.state.filter { it.state }
|
||||||
if (format.state) {
|
.joinToString(",") { format ->
|
||||||
AniPlayFiltersData.ORIGINE.find { it.first == format.name }!!.second
|
AniPlayFiltersData.ORIGIN.find { it.first == format.name }!!.second
|
||||||
} else { null }
|
}
|
||||||
}.joinToString(",")
|
|
||||||
|
|
||||||
val studio: String = filters.filterIsInstance<StudioFilter>()
|
val studio: String = filters.filterIsInstance<StudioFilter>()
|
||||||
.first()
|
.first()
|
||||||
.state.mapNotNull { format ->
|
.state.filter { it.state }
|
||||||
if (format.state) {
|
.joinToString(",") { format ->
|
||||||
AniPlayFiltersData.STUDIO.find { it.first == format.name }!!.second
|
AniPlayFiltersData.STUDIO.find { it.first == format.name }!!.second
|
||||||
} else { null }
|
}
|
||||||
}.joinToString(",")
|
|
||||||
|
|
||||||
return FilterSearchParams(
|
return FilterSearchParams(
|
||||||
filters.asQueryPart<OrdinaFilter>(),
|
filters.asQueryPart<OrderFilter>(),
|
||||||
genere,
|
genre,
|
||||||
tipologia,
|
type,
|
||||||
stato,
|
status,
|
||||||
origine,
|
origin,
|
||||||
studio,
|
studio,
|
||||||
filters.asQueryPart<InizioFilter>(),
|
filters.asQueryPart<StartFilter>(),
|
||||||
filters.asQueryPart<FineFilter>(),
|
filters.asQueryPart<EndFilter>(),
|
||||||
filters.asQueryPart<AnniFilter>(),
|
filters.asQueryPart<YearFilter>(),
|
||||||
filters.asQueryPart<StagioneFilter>(),
|
filters.asQueryPart<SeasonFilter>(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private object AniPlayFiltersData {
|
private object AniPlayFiltersData {
|
||||||
val ALL = Pair("All", "")
|
val ALL = Pair("All", "")
|
||||||
|
|
||||||
val ORDINA = arrayOf(
|
val ORDER = arrayOf(
|
||||||
Pair("Popolarità decrescente", "views,desc"),
|
Pair("Popolarità decrescente", "views,desc"),
|
||||||
Pair("Popolarità crescente", "views,asc"),
|
Pair("Popolarità crescente", "views,asc"),
|
||||||
Pair("Titolo decrescente", "title,desc"),
|
Pair("Titolo decrescente", "title,desc"),
|
||||||
@ -167,7 +162,7 @@ object AniPlayFilters {
|
|||||||
Pair("Data di fine aggiunta", "createdDate,asc"),
|
Pair("Data di fine aggiunta", "createdDate,asc"),
|
||||||
)
|
)
|
||||||
|
|
||||||
val GENERE = arrayOf(
|
val GENRE = arrayOf(
|
||||||
Pair("Arti marziali", "68"),
|
Pair("Arti marziali", "68"),
|
||||||
Pair("Automobilismo", "90"),
|
Pair("Automobilismo", "90"),
|
||||||
Pair("Avventura", "25"),
|
Pair("Avventura", "25"),
|
||||||
@ -222,7 +217,7 @@ object AniPlayFilters {
|
|||||||
Pair("Yuri", "50"),
|
Pair("Yuri", "50"),
|
||||||
)
|
)
|
||||||
|
|
||||||
val TIPOLOGIA = arrayOf(
|
val TYPE = arrayOf(
|
||||||
Pair("Movie", "2"),
|
Pair("Movie", "2"),
|
||||||
Pair("ONA", "4"),
|
Pair("ONA", "4"),
|
||||||
Pair("OVA", "3"),
|
Pair("OVA", "3"),
|
||||||
@ -230,7 +225,7 @@ object AniPlayFilters {
|
|||||||
Pair("Special", "5"),
|
Pair("Special", "5"),
|
||||||
)
|
)
|
||||||
|
|
||||||
val STATO = arrayOf(
|
val STATUS = arrayOf(
|
||||||
Pair("Annunciato", "4"),
|
Pair("Annunciato", "4"),
|
||||||
Pair("Completato", "1"),
|
Pair("Completato", "1"),
|
||||||
Pair("In corso", "2"),
|
Pair("In corso", "2"),
|
||||||
@ -238,7 +233,7 @@ object AniPlayFilters {
|
|||||||
Pair("Sospeso", "3"),
|
Pair("Sospeso", "3"),
|
||||||
)
|
)
|
||||||
|
|
||||||
val ORIGINE = arrayOf(
|
val ORIGIN = arrayOf(
|
||||||
Pair("Gioco di carte", "1"),
|
Pair("Gioco di carte", "1"),
|
||||||
Pair("Light novel", "2"),
|
Pair("Light novel", "2"),
|
||||||
Pair("Mange", "3"),
|
Pair("Mange", "3"),
|
||||||
@ -568,7 +563,7 @@ object AniPlayFilters {
|
|||||||
Pair("Zexcs", "259"),
|
Pair("Zexcs", "259"),
|
||||||
)
|
)
|
||||||
|
|
||||||
val STAGIONE = arrayOf(
|
val SEASON = arrayOf(
|
||||||
ALL,
|
ALL,
|
||||||
Pair("Inverno", "winter"),
|
Pair("Inverno", "winter"),
|
||||||
Pair("Primavera", "spring"),
|
Pair("Primavera", "spring"),
|
||||||
@ -576,7 +571,7 @@ object AniPlayFilters {
|
|||||||
Pair("Autunno", "fall"),
|
Pair("Autunno", "fall"),
|
||||||
)
|
)
|
||||||
|
|
||||||
val ANNI = arrayOf(ALL) + (1984..2023).map {
|
val YEAR = arrayOf(ALL) + (1984..2023).map {
|
||||||
Pair(it.toString(), it.toString())
|
Pair(it.toString(), it.toString())
|
||||||
}.reversed().toTypedArray()
|
}.reversed().toTypedArray()
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,6 @@ import eu.kanade.tachiyomi.network.asObservableSuccess
|
|||||||
import kotlinx.serialization.decodeFromString
|
import kotlinx.serialization.decodeFromString
|
||||||
import kotlinx.serialization.encodeToString
|
import kotlinx.serialization.encodeToString
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import okhttp3.Headers
|
|
||||||
import okhttp3.HttpUrl.Companion.toHttpUrl
|
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||||
import okhttp3.MediaType.Companion.toMediaType
|
import okhttp3.MediaType.Companion.toMediaType
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
@ -58,15 +57,14 @@ class VVVVID : ConfigurableAnimeSource, AnimeHttpSource() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun getConnId() {
|
private fun getConnId() {
|
||||||
val headers = Headers.headersOf(
|
val headers = headers.newBuilder()
|
||||||
"User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/109.0",
|
.add("Accept", "application/json, text/javascript, */*; q=0.01")
|
||||||
"Accept", "application/json, text/javascript, */*; q=0.01",
|
.add("Accept-Language", "en-US,en;q=0.5")
|
||||||
"Accept-Language", "en-US,en;q=0.5",
|
.add("Content-Type", "application/json")
|
||||||
"Content-Type", "application/json",
|
.add("Origin", baseUrl)
|
||||||
"Origin", "https://www.vvvvid.it",
|
.add("Referer", "$baseUrl/channel/0/you")
|
||||||
"Referer", "https://www.vvvvid.it/channel/0/you",
|
.add("X-Requested-With", "XMLHttpRequest")
|
||||||
"X-Requested-With", "XMLHttpRequest",
|
.build()
|
||||||
)
|
|
||||||
|
|
||||||
val body = """
|
val body = """
|
||||||
{
|
{
|
||||||
@ -92,7 +90,7 @@ class VVVVID : ConfigurableAnimeSource, AnimeHttpSource() {
|
|||||||
val response = client.newCall(
|
val response = client.newCall(
|
||||||
POST("$baseUrl/user/login", body = body, headers = headers),
|
POST("$baseUrl/user/login", body = body, headers = headers),
|
||||||
).execute()
|
).execute()
|
||||||
if (response.code != 200) throw Exception("Failed to log in")
|
if (response.code != 200) error("Failed to log in")
|
||||||
val parsed = json.decodeFromString<LoginResponse>(response.body.string())
|
val parsed = json.decodeFromString<LoginResponse>(response.body.string())
|
||||||
|
|
||||||
connId = parsed.data.conn_id
|
connId = parsed.data.conn_id
|
||||||
@ -106,14 +104,13 @@ class VVVVID : ConfigurableAnimeSource, AnimeHttpSource() {
|
|||||||
getConnId()
|
getConnId()
|
||||||
}
|
}
|
||||||
|
|
||||||
val headers = Headers.headersOf(
|
val headers = headers.newBuilder()
|
||||||
"User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/109.0",
|
.add("Accept", "application/json, text/javascript, */*; q=0.01")
|
||||||
"Accept", "application/json, text/javascript, */*; q=0.01",
|
.add("Accept-Language", "en-US,en;q=0.5")
|
||||||
"Accept-Language", "en-US,en;q=0.5",
|
.add("Cookie", "JSESSIONID=$sessionId")
|
||||||
"Cookie", "JSESSIONID=$sessionId",
|
.add("Referer", "$baseUrl/")
|
||||||
"Referer", "https://www.vvvvid.it/",
|
.add("X-Requested-With", "XMLHttpRequest")
|
||||||
"X-Requested-With", "XMLHttpRequest",
|
.build()
|
||||||
)
|
|
||||||
|
|
||||||
if (page == 1) {
|
if (page == 1) {
|
||||||
updateFilters("anime", "Popolari")
|
updateFilters("anime", "Popolari")
|
||||||
@ -143,14 +140,13 @@ class VVVVID : ConfigurableAnimeSource, AnimeHttpSource() {
|
|||||||
getConnId()
|
getConnId()
|
||||||
}
|
}
|
||||||
|
|
||||||
val headers = Headers.headersOf(
|
val headers = headers.newBuilder()
|
||||||
"User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/109.0",
|
.add("Accept", "application/json, text/javascript, */*; q=0.01")
|
||||||
"Accept", "application/json, text/javascript, */*; q=0.01",
|
.add("Accept-Language", "en-US,en;q=0.5")
|
||||||
"Accept-Language", "en-US,en;q=0.5",
|
.add("Cookie", "JSESSIONID=$sessionId")
|
||||||
"Cookie", "JSESSIONID=$sessionId",
|
.add("Referer", "$baseUrl/")
|
||||||
"Referer", "https://www.vvvvid.it/",
|
.add("X-Requested-With", "XMLHttpRequest")
|
||||||
"X-Requested-With", "XMLHttpRequest",
|
.build()
|
||||||
)
|
|
||||||
|
|
||||||
if (page == 1) {
|
if (page == 1) {
|
||||||
updateFilters("anime", "Nuove")
|
updateFilters("anime", "Nuove")
|
||||||
@ -169,17 +165,16 @@ class VVVVID : ConfigurableAnimeSource, AnimeHttpSource() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (query.isNotEmpty()) {
|
if (query.isNotEmpty()) {
|
||||||
throw Exception("Ricerca non disponibile")
|
error("Ricerca non disponibile")
|
||||||
}
|
}
|
||||||
|
|
||||||
val headers = Headers.headersOf(
|
val headers = headers.newBuilder()
|
||||||
"User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/109.0",
|
.add("Accept", "application/json, text/javascript, */*; q=0.01")
|
||||||
"Accept", "application/json, text/javascript, */*; q=0.01",
|
.add("Accept-Language", "en-US,en;q=0.5")
|
||||||
"Accept-Language", "en-US,en;q=0.5",
|
.add("Cookie", "JSESSIONID=$sessionId")
|
||||||
"Cookie", "JSESSIONID=$sessionId",
|
.add("Referer", "$baseUrl/")
|
||||||
"Referer", "https://www.vvvvid.it/",
|
.add("X-Requested-With", "XMLHttpRequest")
|
||||||
"X-Requested-With", "XMLHttpRequest",
|
.build()
|
||||||
)
|
|
||||||
|
|
||||||
var filterStringFinal = ""
|
var filterStringFinal = ""
|
||||||
var filterCounter = 0
|
var filterCounter = 0
|
||||||
@ -329,33 +324,30 @@ class VVVVID : ConfigurableAnimeSource, AnimeHttpSource() {
|
|||||||
getConnId()
|
getConnId()
|
||||||
}
|
}
|
||||||
|
|
||||||
val headers = Headers.headersOf(
|
val headers = headers.newBuilder()
|
||||||
"User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/109.0",
|
.add("Accept", "application/json, text/javascript, */*; q=0.01")
|
||||||
"Accept", "application/json, text/javascript, */*; q=0.01",
|
.add("Accept-Language", "en-US,en;q=0.5")
|
||||||
"Accept-Language", "en-US,en;q=0.5",
|
.add("Cookie", "JSESSIONID=$sessionId")
|
||||||
"Cookie", "JSESSIONID=$sessionId",
|
.add("Referer", "$baseUrl/")
|
||||||
"Referer", "https://www.vvvvid.it/",
|
.add("X-Requested-With", "XMLHttpRequest")
|
||||||
"X-Requested-With", "XMLHttpRequest",
|
.build()
|
||||||
)
|
|
||||||
|
|
||||||
return GET("$baseUrl/vvvvid/ondemand/${anime.url}/info/?conn_id=$connId", headers = headers)
|
return GET("$baseUrl/vvvvid/ondemand/${anime.url}/info/?conn_id=$connId", headers = headers)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun animeDetailsParse(response: Response): SAnime {
|
override fun animeDetailsParse(response: Response): SAnime {
|
||||||
val detailsJson = json.decodeFromString<InfoResponse>(response.body.string()).data
|
val detailsJson = json.decodeFromString<InfoResponse>(response.body.string()).data
|
||||||
val anime = SAnime.create()
|
|
||||||
|
|
||||||
anime.title = detailsJson.title
|
return SAnime.create().apply {
|
||||||
anime.status = SAnime.UNKNOWN
|
title = detailsJson.title
|
||||||
|
status = SAnime.UNKNOWN
|
||||||
var description = detailsJson.description + "\n"
|
genre = detailsJson.show_genres?.joinToString(", ") ?: ""
|
||||||
description += "\nAnno pubblicato: ${detailsJson.date_published}"
|
description = buildString {
|
||||||
description += "\n${detailsJson.additional_info.split(" | ").joinToString("\n")}"
|
append(detailsJson.description)
|
||||||
anime.description = description
|
append("\n\nAnno pubblicato: ${detailsJson.date_published}")
|
||||||
|
append("\n${detailsJson.additional_info.split(" | ").joinToString("\n")}")
|
||||||
anime.genre = detailsJson.show_genres?.let { it.joinToString(", ") } ?: ""
|
}
|
||||||
|
}
|
||||||
return anime
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============================== Episodes ==============================
|
// ============================== Episodes ==============================
|
||||||
@ -365,14 +357,13 @@ class VVVVID : ConfigurableAnimeSource, AnimeHttpSource() {
|
|||||||
getConnId()
|
getConnId()
|
||||||
}
|
}
|
||||||
|
|
||||||
val headers = Headers.headersOf(
|
val headers = headers.newBuilder()
|
||||||
"User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/109.0",
|
.add("Accept", "application/json, text/javascript, */*; q=0.01")
|
||||||
"Accept", "application/json, text/javascript, */*; q=0.01",
|
.add("Accept-Language", "en-US,en;q=0.5")
|
||||||
"Accept-Language", "en-US,en;q=0.5",
|
.add("Cookie", "JSESSIONID=$sessionId")
|
||||||
"Cookie", "JSESSIONID=$sessionId",
|
.add("Referer", "$baseUrl/")
|
||||||
"Referer", "https://www.vvvvid.it/",
|
.add("X-Requested-With", "XMLHttpRequest")
|
||||||
"X-Requested-With", "XMLHttpRequest",
|
.build()
|
||||||
)
|
|
||||||
|
|
||||||
return GET("$baseUrl/vvvvid/ondemand/${anime.url}/seasons/?conn_id=$connId", headers = headers)
|
return GET("$baseUrl/vvvvid/ondemand/${anime.url}/seasons/?conn_id=$connId", headers = headers)
|
||||||
}
|
}
|
||||||
@ -380,7 +371,7 @@ class VVVVID : ConfigurableAnimeSource, AnimeHttpSource() {
|
|||||||
override fun episodeListParse(response: Response): List<SEpisode> {
|
override fun episodeListParse(response: Response): List<SEpisode> {
|
||||||
val animeJson = json.decodeFromString<SeasonsResponse>(response.body.string())
|
val animeJson = json.decodeFromString<SeasonsResponse>(response.body.string())
|
||||||
val episodeList = mutableListOf<SEpisode>()
|
val episodeList = mutableListOf<SEpisode>()
|
||||||
val subDub = preferences.getString("preferred_sub", "none")!!
|
val subDub = preferences.getString(PREF_SUB_KEY, PREF_SUB_DEFAULT)!!
|
||||||
|
|
||||||
var counter = 1
|
var counter = 1
|
||||||
animeJson.data.forEach {
|
animeJson.data.forEach {
|
||||||
@ -395,11 +386,13 @@ class VVVVID : ConfigurableAnimeSource, AnimeHttpSource() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
it.episodes.forEach { ep ->
|
it.episodes.forEach { ep ->
|
||||||
val episode = SEpisode.create()
|
episodeList.add(
|
||||||
episode.name = "$prefix${ep.number} ${ep.title}"
|
SEpisode.create().apply {
|
||||||
episode.episode_number = counter.toFloat()
|
name = "$prefix${ep.number} ${ep.title}"
|
||||||
episode.url = LinkData(it.show_id, ep.season_id, ep.video_id).toJsonString()
|
episode_number = counter.toFloat()
|
||||||
episodeList.add(episode)
|
url = LinkData(it.show_id, ep.season_id, ep.video_id).toJsonString()
|
||||||
|
},
|
||||||
|
)
|
||||||
counter++
|
counter++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -429,14 +422,13 @@ class VVVVID : ConfigurableAnimeSource, AnimeHttpSource() {
|
|||||||
|
|
||||||
val mediaId = json.decodeFromString<LinkData>(episode.url)
|
val mediaId = json.decodeFromString<LinkData>(episode.url)
|
||||||
|
|
||||||
val headers = Headers.headersOf(
|
val headers = headers.newBuilder()
|
||||||
"User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/109.0",
|
.add("Accept", "application/json, text/javascript, */*; q=0.01")
|
||||||
"Accept", "application/json, text/javascript, */*; q=0.01",
|
.add("Accept-Language", "en-US,en;q=0.5")
|
||||||
"Accept-Language", "en-US,en;q=0.5",
|
.add("Cookie", "JSESSIONID=$sessionId")
|
||||||
"Cookie", "JSESSIONID=$sessionId",
|
.add("Referer", "$baseUrl/")
|
||||||
"Referer", "https://www.vvvvid.it/",
|
.add("X-Requested-With", "XMLHttpRequest")
|
||||||
"X-Requested-With", "XMLHttpRequest",
|
.build()
|
||||||
)
|
|
||||||
|
|
||||||
return Pair(
|
return Pair(
|
||||||
GET(
|
GET(
|
||||||
@ -528,13 +520,12 @@ class VVVVID : ConfigurableAnimeSource, AnimeHttpSource() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun videoFromDash(url: String, name: String): Video {
|
private fun videoFromDash(url: String, name: String): Video {
|
||||||
val dashHeaders = Headers.headersOf(
|
val dashHeaders = headers.newBuilder()
|
||||||
"User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/109.0",
|
.add("Accept", "*/*")
|
||||||
"Accept", "*/*",
|
.add("Accept-Language", "en-US,en;q=0.5")
|
||||||
"Accept-Language", "en-US,en;q=0.5",
|
.add("Origin", baseUrl)
|
||||||
"Origin", "https://www.vvvvid.it",
|
.add("Referer", "$baseUrl/")
|
||||||
"Referer", "https://www.vvvvid.it/",
|
.build()
|
||||||
)
|
|
||||||
|
|
||||||
val dashContents = client.newCall(
|
val dashContents = client.newCall(
|
||||||
GET(url, headers = dashHeaders),
|
GET(url, headers = dashHeaders),
|
||||||
@ -545,24 +536,14 @@ class VVVVID : ConfigurableAnimeSource, AnimeHttpSource() {
|
|||||||
val audioUrl = dashContents.substringAfter("mimeType=\"audio").substringBefore("</BaseURL>").substringAfter("<BaseURL>")
|
val audioUrl = dashContents.substringAfter("mimeType=\"audio").substringBefore("</BaseURL>").substringAfter("<BaseURL>")
|
||||||
|
|
||||||
val audioTracks = mutableListOf<Track>()
|
val audioTracks = mutableListOf<Track>()
|
||||||
try {
|
|
||||||
audioTracks.add(Track("$baseVideoUrl/$audioUrl", "Audio"))
|
audioTracks.add(Track("$baseVideoUrl/$audioUrl", "Audio"))
|
||||||
} catch (_: Error) { }
|
|
||||||
|
|
||||||
return try {
|
return Video(
|
||||||
Video(
|
|
||||||
baseVideoUrl,
|
baseVideoUrl,
|
||||||
name,
|
name,
|
||||||
"$baseVideoUrl/$videoUrl",
|
"$baseVideoUrl/$videoUrl",
|
||||||
audioTracks = audioTracks,
|
audioTracks = audioTracks,
|
||||||
)
|
)
|
||||||
} catch (_: Error) {
|
|
||||||
Video(
|
|
||||||
baseVideoUrl,
|
|
||||||
name,
|
|
||||||
"$baseVideoUrl/$videoUrl",
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getRandomIntString(): String {
|
private fun getRandomIntString(): String {
|
||||||
@ -577,7 +558,7 @@ class VVVVID : ConfigurableAnimeSource, AnimeHttpSource() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun List<Video>.sort(): List<Video> {
|
override fun List<Video>.sort(): List<Video> {
|
||||||
val quality = preferences.getString("preferred_quality", "HD")!!
|
val quality = preferences.getString(PREF_QUALITY_KEY, PREF_QUALITY_DEFAULT)!!
|
||||||
|
|
||||||
return this.sortedWith(
|
return this.sortedWith(
|
||||||
compareBy { it.quality.contains(quality) },
|
compareBy { it.quality.contains(quality) },
|
||||||
@ -656,13 +637,23 @@ class VVVVID : ConfigurableAnimeSource, AnimeHttpSource() {
|
|||||||
return d
|
return d
|
||||||
}
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val PREF_SUB_KEY = "preferred_sub"
|
||||||
|
private const val PREF_SUB_DEFAULT = "none"
|
||||||
|
|
||||||
|
private const val PREF_QUALITY_KEY = "preferred_quality"
|
||||||
|
private const val PREF_QUALITY_DEFAULT = "HD"
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================== Settings ==============================
|
||||||
|
|
||||||
override fun setupPreferenceScreen(screen: PreferenceScreen) {
|
override fun setupPreferenceScreen(screen: PreferenceScreen) {
|
||||||
val subDubPref = ListPreference(screen.context).apply {
|
ListPreference(screen.context).apply {
|
||||||
key = "preferred_sub"
|
key = PREF_SUB_KEY
|
||||||
title = "Preferenza sub/dub"
|
title = "Preferenza sub/dub"
|
||||||
entries = arrayOf("Nessuno", "Sub", "Dub")
|
entries = arrayOf("Nessuno", "Sub", "Dub")
|
||||||
entryValues = arrayOf("none", "sub", "dub")
|
entryValues = arrayOf("none", "sub", "dub")
|
||||||
setDefaultValue("none")
|
setDefaultValue(PREF_SUB_DEFAULT)
|
||||||
summary = "%s"
|
summary = "%s"
|
||||||
|
|
||||||
setOnPreferenceChangeListener { _, newValue ->
|
setOnPreferenceChangeListener { _, newValue ->
|
||||||
@ -671,14 +662,14 @@ class VVVVID : ConfigurableAnimeSource, AnimeHttpSource() {
|
|||||||
val entry = entryValues[index] as String
|
val entry = entryValues[index] as String
|
||||||
preferences.edit().putString(key, entry).commit()
|
preferences.edit().putString(key, entry).commit()
|
||||||
}
|
}
|
||||||
}
|
}.also(screen::addPreference)
|
||||||
|
|
||||||
val videoQualityPref = ListPreference(screen.context).apply {
|
ListPreference(screen.context).apply {
|
||||||
key = "preferred_quality"
|
key = PREF_QUALITY_KEY
|
||||||
title = "Qualità preferita"
|
title = "Qualità preferita"
|
||||||
entries = arrayOf("HD", "SD")
|
entries = arrayOf("HD", "SD")
|
||||||
entryValues = arrayOf("HD", "SD")
|
entryValues = arrayOf("HD", "SD")
|
||||||
setDefaultValue("HD")
|
setDefaultValue(PREF_QUALITY_DEFAULT)
|
||||||
summary = "%s"
|
summary = "%s"
|
||||||
|
|
||||||
setOnPreferenceChangeListener { _, newValue ->
|
setOnPreferenceChangeListener { _, newValue ->
|
||||||
@ -687,9 +678,6 @@ class VVVVID : ConfigurableAnimeSource, AnimeHttpSource() {
|
|||||||
val entry = entryValues[index] as String
|
val entry = entryValues[index] as String
|
||||||
preferences.edit().putString(key, entry).commit()
|
preferences.edit().putString(key, entry).commit()
|
||||||
}
|
}
|
||||||
}
|
}.also(screen::addPreference)
|
||||||
|
|
||||||
screen.addPreference(subDubPref)
|
|
||||||
screen.addPreference(videoQualityPref)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user