New Source: LegionAnime (#1014)

This commit is contained in:
Diego Peña Y Lillo
2022-11-11 21:52:03 -03:00
committed by GitHub
parent 67e444b8b4
commit ef007053a5
14 changed files with 921 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,20 @@
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
ext {
extName = 'LegionAnime'
pkgNameSuffix = 'es.legionanime'
extClass = '.LegionAnime'
extVersionCode = 1
libVersion = '13'
}
dependencies {
implementation(project(':lib-fembed-extractor'))
implementation(project(':lib-streamtape-extractor'))
implementation(project(':lib-okru-extractor'))
implementation(project(':lib-streamsb-extractor'))
implementation(project(':lib-dood-extractor'))
}
apply from: "$rootDir/common.gradle"

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

View File

@ -0,0 +1,293 @@
package eu.kanade.tachiyomi.animeextension.es.legionanime
import android.app.Application
import android.content.SharedPreferences
import androidx.preference.PreferenceScreen
import eu.kanade.tachiyomi.animeextension.es.legionanime.extractors.JkanimeExtractor
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.AnimesPage
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.lib.fembedextractor.FembedExtractor
import eu.kanade.tachiyomi.lib.streamsbextractor.StreamSBExtractor
import eu.kanade.tachiyomi.lib.streamtapeextractor.StreamTapeExtractor
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.POST
import eu.kanade.tachiyomi.util.asJsoup
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.json.jsonArray
import kotlinx.serialization.json.jsonObject
import kotlinx.serialization.json.jsonPrimitive
import okhttp3.FormBody
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 uy.kohesive.injekt.injectLazy
class LegionAnime : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
override val name = "LegionAnime"
override val baseUrl = "https://legionanime.club/api"
override val lang = "es"
override val supportsLatest = true
override val client: OkHttpClient = network.cloudflareClient
private val json: Json by injectLazy()
private val preferences: SharedPreferences by lazy {
Injekt.get<Application>().getSharedPreferences("source_$id", 0x0000)
}
private val headers1 = headersBuilder().add("json", jsonString).add("User-Agent", "android l3gi0n4N1mE %E6%9C%AC%E7%89%A9").build()
override fun animeDetailsParse(document: Document): SAnime {
val jsonResponse = json.decodeFromString<JsonObject>(document.body().text())["response"]!!.jsonObject
val anime = jsonResponse["anime"]!!.jsonObject
val studioId = anime["studios"]!!
val studio = studiosMap.filter { it.value == studioId.jsonPrimitive.content.toInt() }.keys.firstOrNull()
return SAnime.create().apply {
title = anime["name"]!!.jsonPrimitive.content
description = anime["synopsis"]!!.jsonPrimitive.content
genre = anime["genres"]!!.jsonPrimitive.content
author = studio
status = when (anime["status"]!!.jsonPrimitive.content) {
"En emisión" -> SAnime.ONGOING
"Finalizado" -> SAnime.COMPLETED
else -> SAnime.UNKNOWN
}
}
}
override fun animeDetailsRequest(anime: SAnime): Request = episodeListRequest(anime)
override fun episodeListParse(response: Response): List<SEpisode> {
val jsonResponse = json.decodeFromString<JsonObject>(response.asJsoup().body().text())
val episodes = jsonResponse["response"]!!.jsonObject["episodes"]!!.jsonArray
return episodes.map {
SEpisode.create().apply {
name = it.jsonObject["name"]!!.jsonPrimitive.content
url = "$baseUrl/v2/episode_links/${it.jsonObject["id"]!!.jsonPrimitive.content}"
}
}
}
override fun episodeListRequest(anime: SAnime): Request = GET(anime.url, headers1)
override fun latestUpdatesRequest(page: Int): Request {
val body = FormBody.Builder().add("apyki", apyki).build()
return POST(
"$baseUrl/v2/directories?studio=0&not_genre=&year=&orderBy=2&language=&type=&duration=&search=&letter=0&limit=24&genre=&season=&page=${(page - 1) * 24}&status=",
headers = headers1, body = body
)
}
override fun latestUpdatesParse(response: Response): AnimesPage = popularAnimeParse(response)
override fun popularAnimeRequest(page: Int): Request {
val body = FormBody.Builder().add("apyki", apyki).build()
return POST(
"$baseUrl/v2/directories?studio=0&not_genre=&year=&orderBy=4&language=&type=&duration=&search=&letter=0&limit=24&genre=&season=&page=${(page - 1) * 24}&status=",
headers = headers1, body = body
)
}
override fun popularAnimeParse(response: Response): AnimesPage {
val responseJson = json.decodeFromString<JsonObject>(response.asJsoup().body().text())
try {
val animeArray = responseJson["response"]!!.jsonArray
return AnimesPage(
animeArray.map {
val animeDetail = it.jsonObject
val animeId = animeDetail["id"]!!.jsonPrimitive.content
SAnime.create().apply {
title = animeDetail["nombre"]!!.jsonPrimitive.content
url = "$baseUrl/v1/episodes/$animeId"
thumbnail_url = aip.random() + animeDetail["img_url"]!!.jsonPrimitive.content
}
},
true
)
} catch (e: Exception) {
return AnimesPage(emptyList(), false)
}
}
override fun searchAnimeRequest(page: Int, query: String, filters: AnimeFilterList): Request {
val body = FormBody.Builder().add("apyki", apyki).build()
val genreFilter = (filters.find { it is TagFilter } as TagFilter).state
val excludeGenreFilter = (filters.find { it is ExcludeTagFilter } as ExcludeTagFilter).state
val studioFilter = (filters.find { it is StudioFilter } as StudioFilter).state
val stateFilter = (filters.find { it is StateFilter } as StateFilter)
val genre = if (genreFilter.isNotEmpty()) {
genreFilter.filter { it.state }.map { genres[it.name] }.joinToString("%2C") { it.toString() }
} else {
""
}
val excludeGenre = if (genreFilter.isNotEmpty()) {
excludeGenreFilter.filter { it.state }.map { genres[it.name] }.joinToString("%2C") { it.toString() }
} else {
""
}
val studio = if (studioFilter.isNotEmpty()) {
studioFilter.filter { it.state }.map { studiosMap[it.name] }.joinToString("%2C") { it.toString() }
} else {
"0"
}
val status = if (stateFilter.state != 0) {
stateFilter.toUriPart()
} else {
""
}
val url = "$baseUrl/v2/directories?studio=$studio&not_genre=$excludeGenre&year=&orderBy=4&language=&type=&duration=&search=$query&letter=0&limit=24&genre=$genre&season=&page=${(page - 1) * 24}&status=$status"
return POST(
url,
headers = headers1, body = body
)
}
override fun searchAnimeParse(response: Response): AnimesPage = popularAnimeParse(response)
override fun videoListParse(response: Response): List<Video> {
val jsonResponse = json.decodeFromString<JsonObject>(response.asJsoup().body().text())
val responseArray = jsonResponse["response"]!!.jsonObject
val players = responseArray["players"]!!.jsonArray
val videoList = mutableListOf<Video>()
players.forEach {
val url = if (it.jsonObject["name"]!!.jsonPrimitive.content.startsWith("F-")) {
it.jsonObject["name"]!!.jsonPrimitive.content.substringAfter("-")
} else {
it.jsonObject["name"]!!.jsonPrimitive.content.substringAfter("-").reversed()
}
val server = it.jsonObject["option"]!!.jsonPrimitive.content
when {
url.contains("streamtape") -> {
val video = StreamTapeExtractor(client).videoFromUrl(url, server)
if (video != null) {
videoList.add(video)
}
}
(url.contains("fembed") || url.contains("vanfem")) -> {
videoList.addAll(FembedExtractor(client).videosFromUrl(url, server))
}
url.contains("sb") -> {
val video = StreamSBExtractor(client).videosFromUrl(url, headers)
videoList.addAll(video)
}
url.contains("jkanime") -> {
videoList.add(JkanimeExtractor(client).getDesuFromUrl(url))
}
url.contains("/stream/amz.php?") -> {
val video = amazonExtractor(url)
if (video.isNotBlank()) {
videoList.add(Video(video, server, video))
}
}
}
}
return videoList
}
private fun amazonExtractor(url: String): String {
val document = client.newCall(GET(url)).execute().asJsoup()
val videoURl = document.selectFirst("script:containsData(sources: [)").data()
.substringAfter("[{\"file\":\"")
.substringBefore("\",").replace("\\", "")
return try {
if (client.newCall(GET(videoURl)).execute().code == 200) videoURl else ""
} catch (_: Exception) {
""
}
}
override fun videoListRequest(episode: SEpisode): Request {
val body = FormBody.Builder().add("apyki", apyki).build()
return POST(
episode.url,
headers1,
body
)
}
/* --FilterStuff-- */
override fun getFilterList(): AnimeFilterList = AnimeFilterList(
TagFilter("Generos", checkboxesFrom(genres)),
TagFilter("Ordernar Por", checkboxesFrom(orderby)),
StateFilter(),
StudioFilter("Estudio", checkboxesFrom(studiosMap)),
ExcludeTagFilter("Excluir Genero", checkboxesFrom(genres)),
)
private class StateFilter : UriPartFilter(
"Estado",
arrayOf(
Pair("<Seleccionar>", ""),
Pair("Emision", "1"),
Pair("Finalizado", "2"),
Pair("Proximamente", "3"),
)
)
class TagCheckBox(tag: String) : AnimeFilter.CheckBox(tag, false)
private fun checkboxesFrom(tagArray: Map<String, Int>): List<TagCheckBox> = tagArray.map { TagCheckBox(it.key) }
class TagFilter(name: String, checkBoxes: List<TagCheckBox>) : AnimeFilter.Group<TagCheckBox>(name, checkBoxes)
class StudioFilter(name: String, checkBoxes: List<TagCheckBox>) : AnimeFilter.Group<TagCheckBox>(name, checkBoxes)
class ExcludeTagFilter(name: String, checkBoxes: List<TagCheckBox>) : AnimeFilter.Group<TagCheckBox>(name, checkBoxes)
private open class UriPartFilter(displayName: String, val vals: Array<Pair<String, String>>) :
AnimeFilter.Select<String>(displayName, vals.map { it.first }.toTypedArray()) {
fun toUriPart() = vals[state].second
}
override fun setupPreferenceScreen(screen: PreferenceScreen) {
TODO("Not yet implemented")
}
/* --Unused stuff-- */
override fun popularAnimeSelector(): String = throw Exception("not used")
override fun popularAnimeFromElement(element: Element): SAnime = throw Exception("not used")
override fun popularAnimeNextPageSelector(): String = throw Exception("not used")
override fun videoFromElement(element: Element): Video = throw Exception("not used")
override fun videoListSelector(): String = throw Exception("not used")
override fun videoUrlParse(document: Document): String = throw Exception("not used")
override fun searchAnimeSelector(): String = throw Exception("not used")
override fun searchAnimeFromElement(element: Element): SAnime = throw Exception("not used")
override fun searchAnimeNextPageSelector(): String? = throw Exception("not used")
override fun episodeFromElement(element: Element): SEpisode = throw Exception("not used")
override fun episodeListSelector(): String = throw Exception("not used")
override fun latestUpdatesFromElement(element: Element): SAnime = throw Exception("not used")
override fun latestUpdatesNextPageSelector(): String? = throw Exception("not used")
override fun latestUpdatesSelector(): String = throw Exception("not used")
}

View File

@ -0,0 +1,41 @@
package eu.kanade.tachiyomi.animeextension.es.legionanime.extractors
import eu.kanade.tachiyomi.animesource.model.Video
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.POST
import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.Headers
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.OkHttpClient
import okhttp3.RequestBody.Companion.toRequestBody
import org.json.JSONObject
class JkanimeExtractor(
private val client: OkHttpClient
) {
fun getNozomiFromUrl(url: String): Video {
val dataKeyHeaders = Headers.Builder().add("Referer", url).build()
val doc = client.newCall(GET(url, dataKeyHeaders)).execute().asJsoup()
val dataKey = doc.select("form input[value]").attr("value")
val gsplayBody = "data=$dataKey".toRequestBody("application/x-www-form-urlencoded".toMediaTypeOrNull())
val location = client.newCall(POST("https://jkanime.net/gsplay/redirect_post.php", dataKeyHeaders, gsplayBody)).execute().request.url.toString()
val postKey = location.substringAfter("player.html#")
val nozomiBody = "v=$postKey".toRequestBody("application/x-www-form-urlencoded".toMediaTypeOrNull())
val nozomiResponse = client.newCall(POST("https://jkanime.net/gsplay/api.php", body = nozomiBody)).execute().body!!.string()
val nozomiUrl = JSONObject(nozomiResponse).getString("file")
return Video(nozomiUrl, "Nozomi", nozomiUrl)
}
fun getDesuFromUrl(url: String): Video {
val document = client.newCall(GET(url)).execute().asJsoup()
val script = document.selectFirst("script:containsData(var parts = {)").data()
val streamUrl = script.substringAfter("url: '").substringBefore("'")
return Video(streamUrl, "Desu", streamUrl)
}
}

View File

@ -0,0 +1,28 @@
package eu.kanade.tachiyomi.animeextension.es.legionanime.extractors
import eu.kanade.tachiyomi.animesource.model.Video
import okhttp3.Headers
import org.jsoup.Connection
import org.jsoup.Jsoup
class Mp4uploadExtractor {
fun getVideoFromUrl(url: String, headers: Headers): Video {
val id = url.substringAfterLast("embed-").substringBeforeLast(".html")
return try {
val videoUrl = Jsoup.connect(url).data(
mutableMapOf(
"op" to "download2",
"id" to id,
"rand" to "",
"referer" to url,
"method_free" to "+",
"method_premiun" to "",
)
).method(Connection.Method.POST).ignoreContentType(true)
.ignoreHttpErrors(true).execute().url().toString()
Video(videoUrl, "Mp4Upload", videoUrl, headers)
} catch (e: Exception) {
Video("", "", "")
}
}
}

View File

@ -0,0 +1,19 @@
package eu.kanade.tachiyomi.animeextension.es.monoschinos.extractors
import eu.kanade.tachiyomi.animesource.model.Video
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.Headers
import okhttp3.OkHttpClient
class UploadExtractor(private val client: OkHttpClient) {
fun videoFromUrl(url: String, headers: Headers): Video? {
return try {
val document = client.newCall(GET(url)).execute().asJsoup()
val basicUrl = document.selectFirst("script:containsData(var player =)").data().substringAfter("sources: [\"").substringBefore("\"],")
return Video(basicUrl, "Uqload", basicUrl, headers = headers)
} catch (e: Exception) {
null
}
}
}

View File

@ -0,0 +1,28 @@
package eu.kanade.tachiyomi.animeextension.es.legionanime.extractors
import eu.kanade.tachiyomi.animesource.model.Video
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.Headers
import okhttp3.OkHttpClient
class YourUploadExtractor(private val client: OkHttpClient) {
fun videoFromUrl(url: String, headers: Headers): List<Video> {
val videoList = mutableListOf<Video>()
return try {
val document = client.newCall(GET(url)).execute()
if (document.isSuccessful) {
val content = document.asJsoup()
val baseData =
content!!.selectFirst("script:containsData(jwplayerOptions)")!!.data()
if (!baseData.isNullOrEmpty()) {
val basicUrl = baseData.substringAfter("file: '").substringBefore("',")
videoList.add(Video(basicUrl, "YourUpload", basicUrl, headers = headers))
}
}
videoList
} catch (e: Exception) {
videoList
}
}
}

View File

@ -0,0 +1,28 @@
package eu.kanade.tachiyomi.animeextension.legionanime.onepace
import app.cash.quickjs.QuickJs
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.json.jsonPrimitive
import org.jsoup.Jsoup
class ZippyExtractor {
fun getVideoUrl(url: String, json: Json): String {
val document = Jsoup.connect(url).get()
val jscript = document.selectFirst("script:containsData(dlbutton)").data()
.replace("document.getElementById('dlbutton').href", "a")
.replace("document.getElementById('fimage').href", "b")
.replace("document.getElementById('fimage')", "false")
val quickjs = QuickJs.create()
val objectA = quickjs.evaluate(objectScript(jscript)).toString()
quickjs.close()
return json.decodeFromString<JsonObject>(objectA)["a"]!!.jsonPrimitive.content
}
private fun objectScript(script: String) = """
$script;
let return_object = {a:a};
JSON.stringify(return_object);
"""
}

View File

@ -0,0 +1,462 @@
package eu.kanade.tachiyomi.animeextension.es.legionanime
val studiosMap = mapOf(
"TMS Entertainment" to 4,
"TNK" to 39,
"Toei Animation" to 1,
"Toho Interactive Animation" to 261,
"Tokyo Kids" to 96,
"Tokyo Movie Shinsha" to 3,
"Tomason" to 329,
"Tomovies" to 164,
"Topcraft" to 293,
"Trans Arts" to 105,
"Tri-Slash" to 270,
"Triangle Staff" to 219,
"TriF Studio" to 239,
"Trigger" to 87,
"Trinet Entertainment" to 283,
"TROYCA" to 120,
"Tsuchida Productions" to 192,
"TV Tokyo" to 19,
"Twilight Studio" to 183,
"TYO Animations" to 166,
"Typhoon Graphics" to 232,
"ufotable" to 47,
"Urban Product" to 186,
"UWAN Pictures" to 187,
"Vega Entertainment" to 274,
"View Works" to 248,
"Visual Flight" to 339,
"Viz Media" to 8,
"W-Toon Studio" to 37,
"WAO World" to 176,
"Wawayu Animation" to 389,
"Welz Animation Studios" to 273,
"White Fox" to 107,
"Wit Studio" to 23,
"Wolfsbane" to 136,
"Xebec" to 25,
"XFLAG" to 313,
"Yamato Works" to 299,
"Yaoyorozu" to 256,
"Yokohama Animation Lab" to 84,
"Yostar Pictures" to 343,
"Yumeta Company" to 173,
"Zero-G" to 132,
"Zero-G Room" to 325,
"Zexcs" to 83,
"Lay-duce" to 56,
"Lerche" to 40,
"Lesprit" to 158,
"LEVELS" to 337,
"LICO" to 378,
"Lide" to 212,
"LIDENFILMS" to 43,
"LIDENFILMS Kyoto Studio" to 361,
"Life Work" to 322,
"Lilix" to 225,
"LMD" to 336,
"M.S.C" to 72,
"Madhouse" to 13,
"Magia Doraglier" to 99,
"Magic Bus" to 14,
"Maho Film" to 182,
"Manglobe" to 85,
"MAPPA" to 67,
"Marine Entertainment" to 236,
"Marvy Jack" to 237,
"Marza Animation Planet" to 80,
"MASTER LIGHTS" to 216,
"Millepensee" to 150,
"Minami Machi Bugyousho" to 318,
"monofilmo" to 54,
"MooGoo" to 234,
"Mushi Production" to 26,
"Nakamura Production" to 311,
"Namu Animation" to 199,
"NAZ" to 82,
"Next Media Animation" to 326,
"Nexus" to 127,
"NHK" to 334,
"Nickelodeon Animation Studio" to 62,
"Nihon Ad Systems" to 207,
"Nippon Animation" to 36,
"Nomad" to 155,
"Nut" to 108,
"Office DCI" to 317,
"Office Nobu" to 324,
"Oh! Production" to 310,
"Okuruto Noboru" to 221,
"OLM" to 65,
"OLM Team Yoshioka" to 368,
"Orange" to 59,
"Ordet" to 250,
"OZ" to 367,
"P.A. Works" to 6,
"P.I.C.S." to 230,
"Palm Studio" to 290,
"Passione" to 113,
"Pastel" to 215,
"Picture Magic" to 279,
"Pie in the sky" to 321,
"Pierrot" to 393,
"Pierrot Plus" to 79,
"Pine Jam" to 81,
"Planet" to 386,
"Planet Cartoon" to 394,
"Platinum Vision" to 91,
"Plum" to 259,
"Polygon Pictures" to 88,
"PRA" to 181,
"Primastea" to 245,
"Production +h." to 373,
"production doA" to 188,
"Production GoodBook" to 227,
"Production I.G" to 64,
"Production IMS" to 116,
"Production Reed" to 18,
"Project No.9" to 30,
"Purple Cow Studio Japan" to 135,
"Quad" to 364,
"Qualia Animation" to 217,
"Qubic Pictures" to 347,
"Quebico" to 350,
"Radix" to 235,
"Red Dog Culture House" to 379,
"Remic" to 304,
"Revoroot" to 209,
"Rising Force" to 291,
"Robot Communications" to 277,
"Saetta" to 205,
"Sanrio" to 333,
"SANZIGEN" to 122,
"Satelight" to 51,
"Science SARU" to 157,
"Scooter Films" to 381,
"Seven" to 133,
"Seven Arcs" to 115,
"Seven Arcs Pictures" to 102,
"Seven Stone Entertainment" to 359,
"Shaft" to 15,
"Shanghai Foch Film and TV Culture Investment" to 352,
"Shanghai Foch Film Culture Investment" to 332,
"Shenying Animation" to 358,
"Shin-Ei Animation" to 57,
"Shinkuukan" to 316,
"Shirogumi" to 92,
"Shogakukan Music & Digital Entertainment" to 231,
"Shuka" to 167,
"Signal.MD" to 61,
"Silver" to 124,
"Silver Link." to 31,
"Sola Digital Arts" to 148,
"Space Neko Company" to 342,
"Sparkly Key Animation Studio" to 123,
"Sparky Animation" to 320,
"Staple Entertainment" to 388,
"Stingray" to 268,
"Studio 3Hz" to 137,
"Studio 4°C" to 241,
"Studio A-CAT" to 146,
"Studio Animal" to 276,
"Studio Bind" to 338,
"Studio Blanc" to 109,
"Studio Chizu" to 251,
"Studio Colorido" to 119,
"Studio Comet" to 144,
"Studio Crocodile" to 68,
"Studio Daisy" to 346,
"Studio Deen" to 93,
"Studio elle" to 142,
"Studio Fantasia" to 233,
"Studio Flad" to 77,
"Studio Flag" to 278,
"Studio Ghibli" to 44,
"Studio Gokumi" to 111,
"Studio Hibari" to 49,
"Studio Junio" to 218,
"Studio Kafka" to 353,
"Studio Kai" to 260,
"Studio Kelmadick" to 309,
"Studio Kyuuma" to 284,
"Studio LAN" to 243,
"Studio Lings" to 197,
"Studio Live" to 178,
"Studio M2" to 327,
"Studio Matrix" to 152,
"Studio Moriken" to 35,
"studio MOTHER" to 369,
"Studio Palette" to 356,
"Studio Pierrot" to 11,
"Studio Ponoc" to 264,
"Studio PuYUKAI" to 117,
"Studio Rikka" to 134,
"Studio Signpost" to 238,
"Studio VOLN" to 94,
"Studio W.Baba" to 229,
"Studio! Cucuri" to 288,
"Sublimation" to 253,
"Sunrise" to 45,
"Sunrise Beyond" to 46,
"Super Normal Studio" to 267,
"Synergy Japan" to 28,
"SynergySP" to 7,
"Tatsunoko Production" to 17,
"Team TillDawn" to 269,
"Team YokkyuFuman" to 240,
"teamKG" to 101,
"Tear Studio" to 118,
"Telecom Animation Film" to 194,
"Tengu Kobo" to 319,
"Tezuka Productions" to 110,
"The Answer Studio" to 331,
"Think Corporation" to 297,
"Thundray" to 154,
"Todos" to 0,
"3xCube" to 41,
"8bit" to 90,
"A-1 Pictures" to 9,
"A-Real" to 201,
"A.C.G.T." to 55,
"Acca effe" to 210,
"Actas" to 163,
"Agent 21" to 383,
"AIC" to 24,
"AIC A.S.T.A." to 97,
"AIC Build" to 121,
"AIC Classic" to 159,
"AIC Frontier" to 305,
"AIC Plus+" to 98,
"AIC Spirits" to 200,
"Ajia-Do" to 76,
"Akatsuki" to 372,
"Albacrow" to 147,
"Amuse" to 315,
"Anima" to 306,
"Anima&Co." to 203,
"Animaruya" to 314,
"Animation Do" to 73,
"Annapuru" to 298,
"Anpro" to 294,
"APPP" to 50,
"AQUA ARIS" to 189,
"ARECT" to 360,
"Arms" to 33,
"Artland" to 12,
"Artmic" to 285,
"Arvo Animation" to 125,
"Asahi Production" to 202,
"Ascension" to 289,
"ASK Animation Studio" to 385,
"asread." to 86,
"AtelierPontdarc" to 357,
"AXsiZ" to 131,
"B.CMAY PICTURES" to 184,
"B&T" to 275,
"Bakken Record" to 161,
"Bandai Namco Pictures" to 126,
"Barnum Studio" to 172,
"Bee Media" to 295,
"Bee Train" to 162,
"Beijing Rocen Digital" to 246,
"BeSTACK" to 106,
"Bibury Animation CG" to 374,
"Bibury Animation Studios" to 196,
"BigFireBird Animation" to 104,
"Blade" to 153,
"Bones" to 22,
"Bouncy" to 249,
"Brain's Base" to 53,
"Bridge" to 29,
"Brio Animation" to 280,
"Buemon" to 226,
"C-Station" to 156,
"C2C" to 145,
"CANDY BOX" to 344,
"CGCG Studio" to 348,
"Chaos Project" to 100,
"Charaction" to 296,
"Children's Playground Entertainment" to 78,
"CLAP" to 371,
"CloverWorks" to 52,
"Colored Pencil Animation" to 351,
"CoMix Wave Films" to 69,
"Connect" to 32,
"Craftar Studios" to 223,
"Creators in Pack" to 138,
"CyberConnect2" to 312,
"Cyclone Graphics" to 391,
"CygamesPictures" to 149,
"DandeLion Animation Studio" to 220,
"Daume" to 143,
"David Production" to 2,
"Dentsu" to 20,
"Digital Frontier" to 160,
"Digital Network Animation" to 363,
"Diomedea" to 10,
"DLE" to 140,
"DMM pictures" to 262,
"DMM.futureworks" to 38,
"Doga Kobo" to 58,
"domerica" to 345,
"Dongwoo A&E" to 206,
"DR Movie" to 376,
"DRAWIZ" to 349,
"Drive" to 66,
"drop" to 307,
"Dwango" to 252,
"dwarf" to 272,
"Dynamo Pictures" to 247,
"E&G Films" to 254,
"Egg Firm" to 128,
"EKACHI EPILKA" to 169,
"Emon" to 175,
"EMT Squared" to 95,
"Encourage Films" to 168,
"ENGI" to 129,
"Ezόla" to 130,
"Fanworks" to 71,
"feel." to 21,
"Felix Film" to 174,
"Fever Creations" to 395,
"Fifth Avenue" to 265,
"Flat Studio" to 382,
"Front Line" to 301,
"Fuji TV" to 287,
"G-angle" to 228,
"G&G Entertainment" to 286,
"Gaina" to 112,
"Gainax" to 16,
"Gainax Kyoto" to 224,
"Gallop" to 60,
"Gambit" to 354,
"Gathering" to 213,
"GEEK TOYS" to 366,
"GEEKTOYS" to 114,
"GEMBA" to 151,
"Genco" to 308,
"Geno Studio" to 171,
"GIFTanimation" to 355,
"Giga Production" to 211,
"Ginga Ya" to 282,
"GoHands" to 89,
"Gonzo" to 34,
"Gosay Studio" to 244,
"Graphinica" to 165,
"GRIZZLY" to 384,
"Group TAC" to 185,
"Grouper Productions" to 302,
"Hal Film Maker" to 195,
"Haoliners Animation League" to 139,
"Hayabusa Film" to 377,
"Hoods Drifters Studio" to 190,
"Hoods Entertainment" to 63,
"HORNETS" to 375,
"Hotline" to 328,
"HOTZIPANG" to 70,
"HS Pictures Studio" to 281,
"Husio Studio" to 242,
"I.Gzwei" to 300,
"iDRAGONS Creative Studio" to 208,
"ILCA" to 27,
"Imagica Lab." to 204,
"Imagin" to 177,
"Imagineer" to 191,
"Indivision" to 362,
"Ishimori Entertainment" to 263,
"Issen" to 222,
"ixtl" to 42,
"Iyasakadou Film" to 330,
"J.C.Staff" to 5,
"Japan Vistec" to 303,
"Jinnan Studio" to 370,
"Jinnis Animation Studios" to 271,
"Jumondo" to 380,
"Jumonji" to 257,
"Kachidoki Studio" to 335,
"Kamikaze Douga" to 170,
"Karaku" to 258,
"Kazami Gakuen Koushiki Douga-bu" to 266,
"Kenji Studio" to 390,
"Khara" to 179,
"Kigumi" to 365,
"Kinema Citrus" to 103,
"Kitty Films" to 214,
"KJJ Animation" to 392,
"Kung Fu Frog Animation" to 387,
"Kyoto Animation" to 48,
"Kyotoma" to 323,
"l-a-unch・BOX" to 141,
"L²Studio" to 180,
"LandQ studios" to 193,
"Lapin Track" to 198,
"Larx Entertainment" to 74,
)
val genres = mapOf(
"Buscar exactamente con géneros seleccionados" to 100,
"Acción" to 1,
"Artes Marciales" to 11,
"Aventuras" to 21,
"Carreras" to 31,
"Ciencia Ficción" to 2,
"Comedia" to 12,
"Demencia" to 22,
"Demonios" to 32,
"Deportes" to 3,
"Donghua" to 45,
"Drama" to 13,
"Ecchi" to 23,
"Escolares" to 33,
"Espacial" to 4,
"Fantasía" to 14,
"Harem" to 24,
"Historico" to 34,
"Infantil" to 5,
"Isekai" to 43,
"Josei" to 15,
"Juegos" to 25,
"Latino y Castellano" to 41,
"Magia" to 35,
"Mecha" to 6,
"Militar" to 16,
"Misterio" to 26,
"Música" to 36,
"Parodia" to 7,
"Policía" to 17,
"Psicológico" to 27,
"Recuentos de la vida" to 37,
"Romance" to 8,
"Samurai" to 18,
"Seinen" to 28,
"Shoujo" to 38,
"Shounen" to 9,
"Sobrenatural" to 19,
"Superpoderes" to 29,
"Suspenso" to 39,
"Terror / Gore" to 10,
"Vampiros" to 20,
"Yaoi" to 30,
"Yuri" to 40,
)
val orderby = mapOf(
"Fecha (Menor a Mayor)" to 0,
"Recientemente vistos por otros" to 1,
"Fecha (Mayor a Menor)" to 2,
"A-Z" to 3,
"Más Visitado" to 4,
"Z-A" to 5,
"Mejor Calificación" to 6,
"Peor Calificación" to 7,
"Últimos Agregados en app" to 8,
"Primeros Agregados en app" to 9,
)
// this is supposed to be information about the device, it is needed to make any api calls, this could probably be randomized
// to clarify, this is generated from an emulator so it's not a real device
val jsonString = "{\"mob3\":\"wj2fea7esGZ44ef\",\"mob\":\"ca-app-pub-8704883736496335~2640452466\",\"mob2\":\"ca-app-pub-8704883736496335/7509635763\",\"laltx\":\"ca-app-pub-7457591504273346/96408526573970637unleinunleba\",\"language\":\"es\",\"isDeb\":false,\"mobx\":\"ca-app-pub-7457591504273346~4714978974\",\"loadLvl\":1,\"code_name\":\"emu64xa\",\"vcode\":\"2.0.2.6\",\"platform\":\"13\",\"lalt\":\"ca-app-pub-8704883736496335/71217888083970637unleinunleba\",\"kind_device\":\"0\",\"manufacturer\":\"Google\",\"som\":\"android\",\"device_name\":\"Sdk_gphone64_x86_64\",\"player_id\":\"50dfea02-9f24-4116-902b-a726146da421\",\"mobf\":\"ca-app-pub-8704883736496335/2195575817\",\"ipv6\":\"FE80::6898:34FF:FE32:E13E\",\"root\":\"0\",\"eth\":\"02:00:00:00:00:00\",\"tel\":\"XXX-XXX-XXX\",\"UUID\":\"00000000-0001-a657-0001-aad30001b11d\",\"yek\":\"bqUgI4l339bqQbnz\",\"moned\":false,\"lvl_sign\":1,\"mobfx\":\"ca-app-pub-7457591504273346/1377852271\",\"device_id\":\"\",\"orp\":false,\"modelo\":\"sdk_gphone64_x86_64\",\"market_name\":\"Sdk_gphone64_x86_64\",\"token\":\"es\",\"isSign\":true,\"malt\":\"ca-app-pub-8704883736496335/7121788808\",\"maltx\":\"ca-app-pub-7457591504273346/9640852657\",\"api_lvl\":\"33\",\"package_version\":\"26\",\"kind_release\":0,\"ipLocal\":\"10.0.2.15\",\"mob2x\":\"ca-app-pub-7457591504273346/9640852657\",\"wlan\":\"02:00:00:00:00:00\",\"inmo\":\"a3c41c881e7f4bc982db32a889eb9e57\",\"inst\":\"\",\"package_name\":\"aplicaciones.paleta.legionanimefull\",\"androidID\":\"b70a95e4fda18f3c\"}"
// this is supposed to be the api key but apparently it is not necessary, anyway I add it to avoid any errors
val apyki = "pM7VYr2bBG2plWQp"
// these are the urls used for the thumbnails, apparently it doesn't matter which one to use but it would be good to check the status of the request before assigning it to the anime
val aip = arrayOf("https://la-space-4.sfo2.digitaloceanspaces.com/", "https://la-space-5.sfo2.digitaloceanspaces.com/", "https://la-space-4.sfo2.digitaloceanspaces.com/", "https://la-space-5.sfo2.digitaloceanspaces.com/", "https://la-space-4.sfo2.cdn.digitaloceanspaces.com/")