some cleanup and removal of gson dependency

This commit is contained in:
jmir1 2021-12-13 15:10:16 +01:00
parent fffc47b29d
commit bc150ba575
11 changed files with 222 additions and 187 deletions

View File

@ -10,9 +10,8 @@ dependencies {
compileOnly 'com.squareup.okhttp3:okhttp:4.9.1'
compileOnly 'io.reactivex:rxjava:1.3.8'
compileOnly 'org.jsoup:jsoup:1.13.1'
compileOnly 'com.google.code.gson:gson:2.8.6'
compileOnly 'com.github.salomonbrys.kotson:kotson:2.5.0'
compileOnly 'org.jetbrains.kotlinx:kotlinx-serialization-json:1.2.2'
compileOnly 'org.jetbrains.kotlinx:kotlinx-serialization-protobuf:1.2.0'
compileOnly 'org.jetbrains.kotlinx:kotlinx-serialization-json:1.2.0'
implementation project(":annotations")
compileOnly project(':duktape-stub')

View File

@ -5,7 +5,7 @@ ext {
extName = 'AnimePahe'
pkgNameSuffix = 'en.animepahe'
extClass = '.AnimePahe'
extVersionCode = 9
extVersionCode = 10
libVersion = '12'
}

View File

@ -5,10 +5,6 @@ import android.content.SharedPreferences
import androidx.preference.ListPreference
import androidx.preference.PreferenceScreen
import androidx.preference.SwitchPreferenceCompat
import com.google.gson.JsonElement
import com.google.gson.JsonNull
import com.google.gson.JsonObject
import com.google.gson.JsonParser
import eu.kanade.tachiyomi.animesource.ConfigurableAnimeSource
import eu.kanade.tachiyomi.animesource.model.AnimeFilterList
import eu.kanade.tachiyomi.animesource.model.AnimesPage
@ -21,12 +17,21 @@ import eu.kanade.tachiyomi.util.asJsoup
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonNull
import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.json.int
import kotlinx.serialization.json.jsonArray
import kotlinx.serialization.json.jsonObject
import kotlinx.serialization.json.jsonPrimitive
import okhttp3.Headers
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import uy.kohesive.injekt.injectLazy
import java.lang.Exception
import java.text.SimpleDateFormat
import java.util.Locale
@ -48,6 +53,8 @@ class AnimePahe : ConfigurableAnimeSource, AnimeHttpSource() {
override val supportsLatest = false
private val json: Json by injectLazy()
override fun headersBuilder(): Headers.Builder {
try {
// Bypass...
@ -111,15 +118,15 @@ class AnimePahe : ConfigurableAnimeSource, AnimeHttpSource() {
}
private fun parseSearchJson(jsonLine: String?): AnimesPage {
val jElement: JsonElement = JsonParser.parseString(jsonLine)
val jObject: JsonObject = jElement.asJsonObject
val data = jObject.get("data") ?: return AnimesPage(emptyList(), false)
val array = data.asJsonArray
val jsonData = jsonLine ?: return AnimesPage(emptyList(), false)
val jObject = json.decodeFromString<JsonObject>(jsonData)
val data = jObject["data"] ?: return AnimesPage(emptyList(), false)
val array = data.jsonArray
val animeList = mutableListOf<SAnime>()
for (item in array) {
val anime = SAnime.create()
anime.title = item.asJsonObject.get("title").asString
val animeId = item.asJsonObject.get("id").asInt
anime.title = item.jsonObject["title"]!!.jsonPrimitive.content
val animeId = item.jsonObject["id"]!!.jsonPrimitive.int
anime.setUrlWithoutDomain("$baseUrl/anime/?anime_id=$animeId")
animeList.add(anime)
}
@ -134,19 +141,19 @@ class AnimePahe : ConfigurableAnimeSource, AnimeHttpSource() {
}
private fun parsePopularAnimeJson(jsonLine: String?): AnimesPage {
val jElement: JsonElement = JsonParser.parseString(jsonLine)
val jObject: JsonObject = jElement.asJsonObject
val lastPage = jObject.get("last_page").asInt
val page = jObject.get("current_page").asInt
val jsonData = jsonLine ?: return AnimesPage(emptyList(), false)
val jObject = json.decodeFromString<JsonObject>(jsonData)
val lastPage = jObject["last_page"]!!.jsonPrimitive.int
val page = jObject["current_page"]!!.jsonPrimitive.int
val hasNextPage = page < lastPage
val array = jObject.get("data").asJsonArray
val array = jObject["data"]!!.jsonArray
val animeList = mutableListOf<SAnime>()
for (item in array) {
val anime = SAnime.create()
anime.title = item.asJsonObject.get("anime_title").asString
val animeId = item.asJsonObject.get("anime_id").asInt
anime.title = item.jsonObject["anime_title"]!!.jsonPrimitive.content
val animeId = item.jsonObject["anime_id"]!!.jsonPrimitive.int
anime.setUrlWithoutDomain("$baseUrl/anime/?anime_id=$animeId")
anime.artist = item.asJsonObject.get("fansub").asString
anime.artist = item.jsonObject["fansub"]!!.jsonPrimitive.content
animeList.add(anime)
}
return AnimesPage(animeList, hasNextPage)
@ -170,19 +177,19 @@ class AnimePahe : ConfigurableAnimeSource, AnimeHttpSource() {
}
private fun parseEpisodePage(jsonLine: String?): MutableList<SEpisode> {
val jElement: JsonElement = JsonParser.parseString(jsonLine)
val jObject: JsonObject = jElement.asJsonObject
val array = jObject.get("data").asJsonArray
val jsonData = jsonLine ?: return mutableListOf()
val jObject = json.decodeFromString<JsonObject>(jsonData)
val array = jObject["data"]!!.jsonArray
val episodeList = mutableListOf<SEpisode>()
for (item in array) {
val itemO = item.asJsonObject
val itemO = item.jsonObject
val episode = SEpisode.create()
episode.date_upload = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.US)
.parse(itemO.get("created_at").asString)!!.time
val animeId = itemO.get("anime_id").asInt
val session = itemO.get("session").asString
.parse(itemO["created_at"]!!.jsonPrimitive.content)!!.time
val animeId = itemO["anime_id"]!!.jsonPrimitive.int
val session = itemO["session"]!!.jsonPrimitive.content
episode.setUrlWithoutDomain("$baseUrl/api?m=links&id=$animeId&session=$session&p=kwik")
val epNum = itemO.get("episode").asInt
val epNum = itemO["episode"]!!.jsonPrimitive.int
episode.episode_number = epNum.toFloat()
episode.name = "Episode $epNum"
episodeList.add(episode)
@ -192,10 +199,9 @@ class AnimePahe : ConfigurableAnimeSource, AnimeHttpSource() {
private fun recursivePages(response: Response): List<SEpisode> {
val responseString = response.body!!.string()
val jElement: JsonElement = JsonParser.parseString(responseString)
val jObject: JsonObject = jElement.asJsonObject
val lastPage = jObject.get("last_page").asInt
val page = jObject.get("current_page").asInt
val jObject = json.decodeFromString<JsonObject>(responseString)
val lastPage = jObject["last_page"]!!.jsonPrimitive.int
val page = jObject["current_page"]!!.jsonPrimitive.int
val hasNextPage = page < lastPage
val returnList = parseEpisodePage(responseString)
if (hasNextPage) {
@ -211,17 +217,15 @@ class AnimePahe : ConfigurableAnimeSource, AnimeHttpSource() {
}
override fun videoListParse(response: Response): List<Video> {
val array = JsonParser.parseString(response.body!!.string())
.asJsonObject.get("data").asJsonArray
val array = json.decodeFromString<JsonObject>(response.body!!.string())
.jsonObject["data"]!!.jsonArray
val videos = mutableListOf<Video>()
for (item in array) {
val quality = item.asJsonObject.keySet().first()
val adflyLink = item.asJsonObject.get(quality)
.asJsonObject.get("kwik_adfly").asString
val kwikLink = item.asJsonObject.get(quality)
.asJsonObject.get("kwik").asString
val audio = item.asJsonObject.get(quality).asJsonObject.get("audio")
val qualityString = if (audio is JsonNull) "${quality}p" else "${quality}p (" + audio.asString + " audio)"
val quality = item.jsonObject.keys.first()
val adflyLink = item.jsonObject[quality]!!.jsonObject["kwik_adfly"]!!.jsonPrimitive.content
val kwikLink = item.jsonObject[quality]!!.jsonObject["kwik"]!!.jsonPrimitive.content
val audio = item.jsonObject[quality]!!.jsonObject["audio"]!!
val qualityString = if (audio is JsonNull) "${quality}p" else "${quality}p (" + audio.jsonPrimitive.content + " audio)"
videos.add(getVideo(adflyLink, kwikLink, qualityString))
}
return videos

View File

@ -5,7 +5,7 @@ ext {
extName = 'hanime.tv'
pkgNameSuffix = 'en.hanime'
extClass = '.Hanime'
extVersionCode = 13
extVersionCode = 14
libVersion = '12'
containsNsfw = true
}

View File

@ -4,10 +4,6 @@ import android.app.Application
import android.content.SharedPreferences
import androidx.preference.ListPreference
import androidx.preference.PreferenceScreen
import com.google.gson.JsonArray
import com.google.gson.JsonElement
import com.google.gson.JsonObject
import com.google.gson.JsonParser
import eu.kanade.tachiyomi.animesource.ConfigurableAnimeSource
import eu.kanade.tachiyomi.animesource.model.AnimeFilter
import eu.kanade.tachiyomi.animesource.model.AnimeFilterList
@ -19,6 +15,15 @@ import eu.kanade.tachiyomi.animesource.online.AnimeHttpSource
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.JsonArray
import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.json.int
import kotlinx.serialization.json.jsonArray
import kotlinx.serialization.json.jsonObject
import kotlinx.serialization.json.jsonPrimitive
import kotlinx.serialization.json.long
import okhttp3.Headers
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.Request
@ -27,6 +32,7 @@ import okhttp3.RequestBody.Companion.toRequestBody
import okhttp3.Response
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import uy.kohesive.injekt.injectLazy
import java.util.Locale
class Hanime : ConfigurableAnimeSource, AnimeHttpSource() {
@ -39,6 +45,8 @@ class Hanime : ConfigurableAnimeSource, AnimeHttpSource() {
override val supportsLatest = true
private val json: Json by injectLazy()
private val preferences: SharedPreferences by lazy {
Injekt.get<Application>().getSharedPreferences("source_$id", 0x0000)
}
@ -69,25 +77,24 @@ class Hanime : ConfigurableAnimeSource, AnimeHttpSource() {
return parseSearchJson(responseString)
}
private fun parseSearchJson(jsonLine: String?): AnimesPage {
val jElement: JsonElement = JsonParser.parseString(jsonLine)
val jObject: JsonObject = jElement.asJsonObject
val nbPages = jObject.get("nbPages").asInt
val page = jObject.get("page").asInt
val jsonData = jsonLine ?: return AnimesPage(emptyList(), false)
val jObject = json.decodeFromString<JsonObject>(jsonData)
val nbPages = jObject["nbPages"]!!.jsonPrimitive.int
val page = jObject["page"]!!.jsonPrimitive.int
val hasNextPage = page < nbPages - 1
val arrayString = jObject.get("hits").asString
val array = JsonParser.parseString(arrayString)
val jObjectb: JsonArray = array.asJsonArray
val arrayString = jObject["hits"]!!.jsonPrimitive.content
val array = json.decodeFromString<JsonArray>(arrayString)
val animeList = mutableListOf<SAnime>()
for (item in jObjectb) {
for (item in array) {
val anime = SAnime.create()
anime.title = item.asJsonObject.get("name").asString
anime.thumbnail_url = item.asJsonObject.get("cover_url").asString
anime.setUrlWithoutDomain("https://hanime.tv/videos/hentai/" + item.asJsonObject.get("slug").asString)
anime.author = item.asJsonObject.get("brand").asString
anime.description = item.asJsonObject.get("description").asString.replace("<p>", "").replace("</p>", "")
anime.title = item.jsonObject["name"]!!.jsonPrimitive.content
anime.thumbnail_url = item.jsonObject["cover_url"]!!.jsonPrimitive.content
anime.setUrlWithoutDomain("https://hanime.tv/videos/hentai/" + item.jsonObject["slug"]!!.jsonPrimitive.content)
anime.author = item.jsonObject["brand"]!!.jsonPrimitive.content
anime.description = item.jsonObject["description"]!!.jsonPrimitive.content.replace("<p>", "").replace("</p>", "")
anime.status = SAnime.COMPLETED
val tags = item.asJsonObject.get("tags").asJsonArray
anime.genre = tags.joinToString(", ") { it.asString }
val tags = item.jsonObject["tags"]!!.jsonArray
anime.genre = tags.joinToString(", ") { it.jsonPrimitive.content }
anime.initialized = true
animeList.add(anime)
}
@ -122,14 +129,21 @@ class Hanime : ConfigurableAnimeSource, AnimeHttpSource() {
override fun videoListParse(response: Response): List<Video> {
val responseString = response.body!!.string()
val jElement: JsonElement = JsonParser.parseString(responseString)
val jObject: JsonObject = jElement.asJsonObject
val server = jObject.get("videos_manifest").asJsonObject.get("servers").asJsonArray[0].asJsonObject
val streams = server.get("streams").asJsonArray
val jObject = json.decodeFromString<JsonObject>(responseString)
val server = jObject["videos_manifest"]!!.jsonObject["servers"]!!.jsonArray[0].jsonObject
val streams = server["streams"]!!.jsonArray
val linkList = mutableListOf<Video>()
for (stream in streams) {
if (stream.asJsonObject.get("kind").asString != "premium_alert") {
linkList.add(Video(stream.asJsonObject.get("url").asString, stream.asJsonObject.get("height").asString + "p", stream.asJsonObject.get("url").asString, null))
val streamObject = stream.jsonObject
if (streamObject["kind"]!!.jsonPrimitive.content != "premium_alert") {
linkList.add(
Video(
url = streamObject["url"]!!.jsonPrimitive.content,
quality = streamObject["height"]!!.jsonPrimitive.content + "p",
videoUrl = streamObject["url"]!!.jsonPrimitive.content,
uri = null
)
)
}
}
return linkList
@ -160,11 +174,10 @@ class Hanime : ConfigurableAnimeSource, AnimeHttpSource() {
override fun episodeListParse(response: Response): List<SEpisode> {
val responseString = response.body!!.string()
val jElement: JsonElement = JsonParser.parseString(responseString)
val jObject: JsonObject = jElement.asJsonObject
val jObject = json.decodeFromString<JsonObject>(responseString)
val episode = SEpisode.create()
episode.date_upload = jObject.asJsonObject.get("hentai_video").asJsonObject.get("released_at_unix").asLong * 1000
episode.name = jObject.asJsonObject.get("hentai_video").asJsonObject.get("name").asString
episode.date_upload = jObject.jsonObject["hentai_video"]!!.jsonObject["released_at_unix"]!!.jsonPrimitive.long * 1000
episode.name = jObject.jsonObject["hentai_video"]!!.jsonObject["name"]!!.jsonPrimitive.content
episode.url = response.request.url.toString()
episode.episode_number = 1F
return listOf(episode)

View File

@ -5,7 +5,7 @@ ext {
extName = 'twist.moe'
pkgNameSuffix = 'en.twistmoe'
extClass = '.TwistMoe'
extVersionCode = 7
extVersionCode = 8
libVersion = '12'
}

View File

@ -1,10 +1,6 @@
package eu.kanade.tachiyomi.animeextension.en.twistmoe
import android.annotation.SuppressLint
import com.google.gson.JsonArray
import com.google.gson.JsonElement
import com.google.gson.JsonObject
import com.google.gson.JsonParser
import eu.kanade.tachiyomi.animesource.model.AnimeFilterList
import eu.kanade.tachiyomi.animesource.model.AnimesPage
import eu.kanade.tachiyomi.animesource.model.SAnime
@ -13,11 +9,22 @@ import eu.kanade.tachiyomi.animesource.model.Video
import eu.kanade.tachiyomi.animesource.online.AnimeHttpSource
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.POST
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonArray
import kotlinx.serialization.json.JsonElement
import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.json.contentOrNull
import kotlinx.serialization.json.float
import kotlinx.serialization.json.int
import kotlinx.serialization.json.jsonObject
import kotlinx.serialization.json.jsonPrimitive
import okhttp3.Headers
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.Request
import okhttp3.RequestBody.Companion.toRequestBody
import okhttp3.Response
import uy.kohesive.injekt.injectLazy
import java.lang.Exception
import java.text.SimpleDateFormat
import java.util.Locale
@ -33,6 +40,8 @@ class TwistMoe : AnimeHttpSource() {
override val supportsLatest = false
private val json: Json by injectLazy()
override fun headersBuilder() = Headers.Builder().apply {
add("User-Agent", "Aniyomi")
add("Referer", "https://twist.moe/")
@ -46,8 +55,7 @@ class TwistMoe : AnimeHttpSource() {
override fun popularAnimeParse(response: Response): AnimesPage {
val responseString = response.body!!.string()
val jElement: JsonElement = JsonParser.parseString(responseString)
val array: JsonArray = jElement.asJsonArray
val array = json.decodeFromString<JsonArray>(responseString)
val list = mutableListOf<JsonElement>()
array.toCollection(list)
val page = response.request.url.fragment!!.toInt() - 1
@ -61,9 +69,9 @@ class TwistMoe : AnimeHttpSource() {
val animeList = mutableListOf<SAnime>()
for (item in array) {
val anime = SAnime.create()
anime.title = item.asJsonObject.get("title").asString
anime.setUrlWithoutDomain("$baseUrl/a/" + item.asJsonObject.get("slug").asJsonObject.get("slug").asString)
anime.status = when (item.asJsonObject.get("ongoing").asInt) {
anime.title = item.jsonObject["title"]!!.jsonPrimitive.content
anime.setUrlWithoutDomain("$baseUrl/a/" + item.jsonObject["slug"]!!.jsonObject["slug"]!!.jsonPrimitive.content)
anime.status = when (item.jsonObject["ongoing"]!!.jsonPrimitive.int) {
0 -> SAnime.COMPLETED
1 -> SAnime.ONGOING
else -> SAnime.UNKNOWN
@ -78,8 +86,7 @@ class TwistMoe : AnimeHttpSource() {
override fun searchAnimeParse(response: Response): AnimesPage {
val responseString = response.body!!.string()
val jElement: JsonElement = JsonParser.parseString(responseString)
val array: JsonArray = jElement.asJsonArray
val array = json.decodeFromString<JsonArray>(responseString)
val list = mutableListOf<JsonElement>()
array.toCollection(list)
val query = response.request.url.fragment!!
@ -88,9 +95,9 @@ class TwistMoe : AnimeHttpSource() {
.toLowerCase(Locale.ROOT)
val toRemove = mutableListOf<JsonElement>()
for (entry in list) {
val title = entry.asJsonObject.get("title").asString.toLowerCase(Locale.ROOT)
val title = entry.jsonObject["title"]!!.jsonPrimitive.content.toLowerCase(Locale.ROOT)
val altTitle = try {
entry.asJsonObject.get("alt_title").asString.toLowerCase(Locale.ROOT)
entry.jsonObject["alt_title"]!!.jsonPrimitive.content.toLowerCase(Locale.ROOT)
} catch (e: Exception) { "" }
if (!(title.contains(query) || altTitle.contains(query))) toRemove.add(entry)
}
@ -109,13 +116,12 @@ class TwistMoe : AnimeHttpSource() {
override fun animeDetailsParse(response: Response): SAnime {
val responseString = response.body!!.string()
val jElement: JsonElement = JsonParser.parseString(responseString)
val jObject: JsonObject = jElement.asJsonObject
val jObject = json.decodeFromString<JsonObject>(responseString)
val anime = SAnime.create()
anime.title = jObject.get("title").asString
anime.setUrlWithoutDomain("$baseUrl/a/" + jObject.get("slug").asJsonObject.get("slug").asString)
anime.description = jObject.get("description").asString
anime.status = when (jObject.get("ongoing").asInt) {
anime.title = jObject["title"]!!.jsonPrimitive.content
anime.setUrlWithoutDomain("$baseUrl/a/" + jObject["slug"]!!.jsonObject["slug"]!!.jsonPrimitive.content)
anime.description = jObject["description"]!!.jsonPrimitive.content
anime.status = when (jObject["ongoing"]!!.jsonPrimitive.int) {
0 -> SAnime.COMPLETED
1 -> SAnime.ONGOING
else -> SAnime.UNKNOWN
@ -127,11 +133,11 @@ class TwistMoe : AnimeHttpSource() {
private fun getCover(jObject: JsonObject, anime: SAnime) {
try {
val malID = try {
jObject.get("mal_id").asNumber.toString()
jObject["mal_id"]!!.jsonPrimitive.contentOrNull
} catch (e: Exception) {
""
}
if (malID.isNotEmpty()) {
if (malID != null) {
val headers = Headers.Builder().apply {
add("Content-Type", "application/json")
add("Accept", "application/json")
@ -139,11 +145,10 @@ class TwistMoe : AnimeHttpSource() {
val bodyString = "{\"query\":\"query(\$id: Int){Media(type:ANIME,idMal:\$id){coverImage{large}}}\",\"variables\":{\"id\":$malID}}"
val body = bodyString.toRequestBody("application/json".toMediaType())
val coverResponse = client.newCall(POST("https://graphql.anilist.co", headers, body)).execute()
val imageUrl = JsonParser.parseString(coverResponse.body!!.string())
.asJsonObject.get("data")
.asJsonObject.get("Media")
.asJsonObject.get("coverImage")
.asJsonObject.get("large").asString
val imageUrl = json.decodeFromString<JsonObject>(coverResponse.body!!.string())["data"]!!
.jsonObject["Media"]!!
.jsonObject["coverImage"]!!
.jsonObject["large"]!!.jsonPrimitive.content
if (imageUrl.isNotEmpty()) anime.thumbnail_url = imageUrl
} else {
val query = anime.title
@ -154,11 +159,10 @@ class TwistMoe : AnimeHttpSource() {
val bodyString = "{\"query\":\"query(\$query: String){Media(type:ANIME,search:\$query){coverImage{large}}}\",\"variables\":{\"query\":\"$query\"}}"
val body = bodyString.toRequestBody("application/json".toMediaType())
val coverResponse = client.newCall(POST("https://graphql.anilist.co", headers, body)).execute()
val imageUrl = JsonParser.parseString(coverResponse.body!!.string())
.asJsonObject.get("data")
.asJsonObject.get("Media")
.asJsonObject.get("coverImage")
.asJsonObject.get("large").asString
val imageUrl = json.decodeFromString<JsonObject>(coverResponse.body!!.string())["data"]!!
.jsonObject["Media"]!!
.jsonObject["coverImage"]!!
.jsonObject["large"]!!.jsonPrimitive.content
if (imageUrl.isNotEmpty()) anime.thumbnail_url = imageUrl
}
} catch (e: Exception) {
@ -171,15 +175,15 @@ class TwistMoe : AnimeHttpSource() {
override fun videoListParse(response: Response): List<Video> {
val responseString = response.body!!.string()
val array = JsonParser.parseString(responseString).asJsonArray
val array = json.decodeFromString<JsonArray>(responseString)
val list = mutableListOf<JsonElement>()
array.toCollection(list)
val episodeNumber = response.request.url.fragment!!.toFloat()
val videoList = mutableListOf<Video>()
val aes = AESDecrypt()
for (entry in list) {
if (entry.asJsonObject.get("number").asNumber.toFloat() == episodeNumber) {
val source = entry.asJsonObject.get("source").asString
if (entry.jsonObject["number"]!!.jsonPrimitive.float == episodeNumber) {
val source = entry.jsonObject["source"]!!.jsonPrimitive.content
val ivAndKey = aes.getIvAndKey(source)
val toDecode = aes.getToDecode(source)
val url = "https://air-cdn.twist.moe" +
@ -198,16 +202,16 @@ class TwistMoe : AnimeHttpSource() {
override fun episodeListParse(response: Response): List<SEpisode> {
val responseString = response.body!!.string()
val array = JsonParser.parseString(responseString).asJsonArray
val array = json.decodeFromString<JsonArray>(responseString)
val list = mutableListOf<JsonElement>()
array.toCollection(list)
val episodeList = mutableListOf<SEpisode>()
for (entry in list) {
try {
val episode = SEpisode.create()
episode.date_upload = parseDate(entry.asJsonObject.get("updated_at").asString)
episode.name = "Episode " + entry.asJsonObject.get("number").asNumber.toString()
episode.episode_number = entry.asJsonObject.get("number").asNumber.toFloat()
episode.date_upload = parseDate(entry.jsonObject["updated_at"]!!.jsonPrimitive.content)
episode.name = "Episode " + entry.jsonObject["number"]!!.jsonPrimitive.content
episode.episode_number = entry.jsonObject["number"]!!.jsonPrimitive.float
episode.url = response.request.url.toString() + "#${episode.episode_number}"
episodeList.add(episode)
} catch (e: Exception) {

View File

@ -5,7 +5,7 @@ ext {
extName = 'AnimeFLV'
pkgNameSuffix = 'es.animeflv'
extClass = '.AnimeFlv'
extVersionCode = 4
extVersionCode = 5
libVersion = '12'
}

View File

@ -2,11 +2,10 @@ package eu.kanade.tachiyomi.animeextension.es.animeflv
import android.app.Application
import android.content.SharedPreferences
import android.util.Log
import androidx.preference.ListPreference
import androidx.preference.PreferenceScreen
import com.github.salomonbrys.kotson.get
import com.google.gson.JsonParser
import eu.kanade.tachiyomi.animeextension.es.animeflv.extractors.OkruExtractor
import eu.kanade.tachiyomi.animeextension.es.animeflv.extractors.StreamTapeExtractor
import eu.kanade.tachiyomi.animesource.ConfigurableAnimeSource
import eu.kanade.tachiyomi.animesource.model.AnimeFilterList
import eu.kanade.tachiyomi.animesource.model.SAnime
@ -15,6 +14,13 @@ 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 kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonNull
import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.json.jsonArray
import kotlinx.serialization.json.jsonObject
import kotlinx.serialization.json.jsonPrimitive
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
@ -22,8 +28,8 @@ 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
import java.lang.Exception
import java.net.URL
class AnimeFlv : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
@ -37,6 +43,8 @@ class AnimeFlv : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
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)
}
@ -96,19 +104,23 @@ class AnimeFlv : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
document.select("script").forEach { script ->
if (script.data().contains("var videos = {")) {
val data = script.data().substringAfter("var videos = ").substringBefore(";")
val json = JsonParser.parseString(data).asJsonObject
val sub = json.get("SUB")
if (!sub.isJsonNull) {
for (server in sub.asJsonArray) {
val url = server.asJsonObject.get("code").asString.replace("\\/", "/")
val quality = server.asJsonObject.get("title").asString
val jsonObject = json.decodeFromString<JsonObject>(data)
val sub = jsonObject["SUB"]!!
if (sub !is JsonNull) {
for (server in sub.jsonArray) {
val url = server.jsonObject["code"]!!.jsonPrimitive.content.replace("\\/", "/")
val quality = server.jsonObject["title"]!!.jsonPrimitive.content
if (quality == "Stape") {
val videos = getStapeVideos(url)
videoList += videos
val video = StreamTapeExtractor(client).videoFromUrl(url, quality)
if (video != null) {
videoList.add(video)
}
}
if (quality == "Okru") {
val videos = getOkruVideos(url)
videoList += videos
val videos = OkruExtractor(client).videosFromUrl(url, quality)
if (videos != null) {
videoList.addAll(videos)
}
}
}
}
@ -123,64 +135,8 @@ class AnimeFlv : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
override fun videoFromElement(element: Element) = throw Exception("not used")
// this code is trash but work
private fun getStapeVideos(url: String): List<Video> {
val videoList = mutableListOf<Video>()
val url5 = url.replace("https://streamtape.com/e/", "")
val url6 = url5.replace("/", "")
val document = client.newCall(GET("https://api.streamtape.com/file/dlticket?file=$url6&login=ef23317a52e4442dbdd3&key=mydvdBk717tb08Y")).execute().asJsoup()
val test22 = document.body().text()
val test23 = JsonParser.parseString(test22).asJsonObject
val test24 = test23.get("result").get("ticket").toString().replace("\"", "")
val test80 = test24
val url80 = "https://api.streamtape.com/file/dl?file=$url6&ticket=$test24&captcha_response={captcha_response}".replace("={captcha_response}", "={captcha_response}")
Log.i("stapeee", url80)
val document2 = client.newCall(GET(url80)).execute().asJsoup()
//I don't know how to make it wait 5 seconds, but this worked for some reason
val jsjs = URL(url80).readText()
val jsjs1 = URL(url80).readText()
val jsjs2 = URL(url80).readText()
val jsjs3 = URL(url80).readText()
URL(url80).readText()
URL(url80).readText()
URL(url80).readText()
URL(url80).readText()
URL(url80).readText()
URL(url80).readText()
URL(url80).readText()
URL(url80).readText()
URL(url80).readText()
val jsjs4 = URL(url80).readText()
val test29 = document2.body().text()
Log.i("stapeee", jsjs4)
val test30 = JsonParser.parseString(jsjs4).asJsonObject
val test31 = test30.get("result").get("url").toString().replace("\"", "")
Log.i("stapeee", test31)
videoList.add(Video(test31, "Stape", test31, null))
return videoList
}
private fun getOkruVideos(url: String): List<Video> {
val document = client.newCall(GET(url)).execute().asJsoup()
Log.i("bruuh", document.select("div[data-options]").attr("data-options"))
val videoList = mutableListOf<Video>()
val videosString = document.select("div[data-options]").attr("data-options")
.substringAfter("\\\"videos\\\":[{\\\"name\\\":\\\"")
.substringBefore("]")
videosString.split("{\\\"name\\\":\\\"").reversed().forEach {
val videoUrl = it.substringAfter("url\\\":\\\"")
.substringBefore("\\\"")
.replace("\\\\u0026", "&")
val quality = it.substringBefore("\\\"")
if (videoUrl.startsWith("https://")) {
videoList.add(Video(videoUrl, quality, videoUrl, null))
}
}
return videoList
}
override fun List<Video>.sort(): List<Video> {
val quality = preferences.getString("preferred_quality", "hd")
val quality = preferences.getString("preferred_quality", "Stape")
if (quality != null) {
val newList = mutableListOf<Video>()
var preferred = 0
@ -237,9 +193,9 @@ class AnimeFlv : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
val videoQualityPref = ListPreference(screen.context).apply {
key = "preferred_quality"
title = "Preferred quality"
entries = arrayOf("hd", "sd", "low", "lowest", "mobile")
entryValues = arrayOf("hd", "sd", "low", "lowest", "mobile")
setDefaultValue("hd")
entries = arrayOf("Stape", "hd", "sd", "low", "lowest", "mobile")
entryValues = arrayOf("Stape", "hd", "sd", "low", "lowest", "mobile")
setDefaultValue("Stape")
summary = "%s"
setOnPreferenceChangeListener { _, newValue ->

View File

@ -0,0 +1,41 @@
package eu.kanade.tachiyomi.animeextension.es.animeflv.extractors
import android.util.Log
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 OkruExtractor(private val client: OkHttpClient) {
fun videosFromUrl(url: String, quality: String): List<Video>? {
val document = client.newCall(GET(url)).execute().asJsoup()
Log.i("bruuh", document.select("div[data-options]").attr("data-options"))
val videoList = mutableListOf<Video>()
val videosString = document.select("div[data-options]").attr("data-options")
.substringAfter("\\\"videos\\\":[{\\\"name\\\":\\\"")
.substringBefore("]")
videosString.split("{\\\"name\\\":\\\"").reversed().forEach {
val videoUrl = it.substringAfter("url\\\":\\\"")
.substringBefore("\\\"")
.replace("\\\\u0026", "&")
val videoQuality = "Okru: " + it.substringBefore("\\\"")
if (videoUrl.startsWith("https://")) {
videoList.add(Video(videoUrl, videoQuality, videoUrl, null))
}
}
return videoList
}
private fun getRandomString(length: Int = 10): String {
val allowedChars = ('A'..'Z') + ('a'..'z') + ('0'..'9')
return (1..length)
.map { allowedChars.random() }
.joinToString("")
}
private fun doodHeaders(tld: String) = Headers.Builder().apply {
add("User-Agent", "Aniyomi")
add("Referer", "https://dood.$tld/")
}.build()
}

View File

@ -0,0 +1,18 @@
package eu.kanade.tachiyomi.animeextension.es.animeflv.extractors
import eu.kanade.tachiyomi.animesource.model.Video
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.OkHttpClient
class StreamTapeExtractor(private val client: OkHttpClient) {
fun videoFromUrl(url: String, quality: String): Video? {
val document = client.newCall(GET(url)).execute().asJsoup()
val script = document.select("script:containsData(document.getElementById('robotlink'))")
.firstOrNull()?.data()?.substringAfter("document.getElementById('robotlink').innerHTML = '")
?: return null
val videoUrl = "https:" + script.substringBefore("'") +
script.substringAfter("+ ('xcd").substringBefore("'")
return Video(url, quality, videoUrl, null)
}
}