refactor(global): Adapt to extlib v14 (#2759)
This commit is contained in:
@ -21,11 +21,10 @@ import eu.kanade.tachiyomi.multisrc.animestream.AnimeStreamFilters.StudioFilter
|
||||
import eu.kanade.tachiyomi.multisrc.animestream.AnimeStreamFilters.SubFilter
|
||||
import eu.kanade.tachiyomi.multisrc.animestream.AnimeStreamFilters.TypeFilter
|
||||
import eu.kanade.tachiyomi.network.GET
|
||||
import eu.kanade.tachiyomi.network.asObservableSuccess
|
||||
import eu.kanade.tachiyomi.network.awaitSuccess
|
||||
import eu.kanade.tachiyomi.util.asJsoup
|
||||
import eu.kanade.tachiyomi.util.parallelCatchingFlatMapBlocking
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.awaitAll
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.withContext
|
||||
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
|
||||
@ -34,7 +33,6 @@ import okhttp3.Response
|
||||
import org.jsoup.Jsoup
|
||||
import org.jsoup.nodes.Document
|
||||
import org.jsoup.nodes.Element
|
||||
import rx.Observable
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
import java.text.SimpleDateFormat
|
||||
@ -48,8 +46,6 @@ abstract class AnimeStream(
|
||||
|
||||
override val supportsLatest = true
|
||||
|
||||
override val client = network.cloudflareClient
|
||||
|
||||
protected open val preferences by lazy {
|
||||
Injekt.get<Application>().getSharedPreferences("source_$id", 0x0000)
|
||||
}
|
||||
@ -81,9 +77,9 @@ abstract class AnimeStream(
|
||||
protected open val animeListUrl = "$baseUrl/anime"
|
||||
|
||||
// ============================== Popular ===============================
|
||||
override fun fetchPopularAnime(page: Int): Observable<AnimesPage> {
|
||||
override suspend fun getPopularAnime(page: Int): AnimesPage {
|
||||
fetchFilterList()
|
||||
return super.fetchPopularAnime(page)
|
||||
return super.getPopularAnime(page)
|
||||
}
|
||||
|
||||
override fun popularAnimeRequest(page: Int) = GET("$animeListUrl/?page=$page&order=popular")
|
||||
@ -95,9 +91,9 @@ abstract class AnimeStream(
|
||||
override fun popularAnimeNextPageSelector(): String? = searchAnimeNextPageSelector()
|
||||
|
||||
// =============================== Latest ===============================
|
||||
override fun fetchLatestUpdates(page: Int): Observable<AnimesPage> {
|
||||
override suspend fun getLatestUpdates(page: Int): AnimesPage {
|
||||
fetchFilterList()
|
||||
return super.fetchLatestUpdates(page)
|
||||
return super.getLatestUpdates(page)
|
||||
}
|
||||
|
||||
override fun latestUpdatesRequest(page: Int) = GET("$animeListUrl/?page=$page&order=update")
|
||||
@ -109,14 +105,14 @@ abstract class AnimeStream(
|
||||
override fun latestUpdatesNextPageSelector(): String? = searchAnimeNextPageSelector()
|
||||
|
||||
// =============================== Search ===============================
|
||||
override fun fetchSearchAnime(page: Int, query: String, filters: AnimeFilterList): Observable<AnimesPage> {
|
||||
override suspend fun getSearchAnime(page: Int, query: String, filters: AnimeFilterList): AnimesPage {
|
||||
return if (query.startsWith(PREFIX_SEARCH)) { // URL intent handler
|
||||
val path = query.removePrefix(PREFIX_SEARCH)
|
||||
client.newCall(GET("$baseUrl/$path"))
|
||||
.asObservableSuccess()
|
||||
.map(::searchAnimeByPathParse)
|
||||
.awaitSuccess()
|
||||
.use(::searchAnimeByPathParse)
|
||||
} else {
|
||||
super.fetchSearchAnime(page, query, filters)
|
||||
super.getSearchAnime(page, query, filters)
|
||||
}
|
||||
}
|
||||
|
||||
@ -320,13 +316,11 @@ abstract class AnimeStream(
|
||||
|
||||
override fun videoListParse(response: Response): List<Video> {
|
||||
val items = response.use { it.asJsoup() }.select(videoListSelector())
|
||||
return items.parallelMap { element ->
|
||||
runCatching {
|
||||
val name = element.text()
|
||||
val url = getHosterUrl(element)
|
||||
getVideoList(url, name)
|
||||
}.onFailure { it.printStackTrace() }.getOrElse { emptyList() }
|
||||
}.flatten()
|
||||
return items.parallelCatchingFlatMapBlocking { element ->
|
||||
val name = element.text()
|
||||
val url = getHosterUrl(element)
|
||||
getVideoList(url, name)
|
||||
}
|
||||
}
|
||||
|
||||
protected open fun getHosterUrl(element: Element): String {
|
||||
@ -422,11 +416,6 @@ abstract class AnimeStream(
|
||||
} ?: 0L
|
||||
}
|
||||
|
||||
protected inline fun <A, B> Iterable<A>.parallelMap(crossinline f: suspend (A) -> B): List<B> =
|
||||
runBlocking {
|
||||
map { async(Dispatchers.Default) { f(it) } }.awaitAll()
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to get the image url via various possible attributes.
|
||||
* Taken from Tachiyomi's Madara multisrc.
|
||||
|
@ -12,21 +12,15 @@ import eu.kanade.tachiyomi.animesource.model.Video
|
||||
import eu.kanade.tachiyomi.animesource.online.ParsedAnimeHttpSource
|
||||
import eu.kanade.tachiyomi.network.GET
|
||||
import eu.kanade.tachiyomi.network.POST
|
||||
import eu.kanade.tachiyomi.network.asObservableSuccess
|
||||
import eu.kanade.tachiyomi.network.awaitSuccess
|
||||
import eu.kanade.tachiyomi.util.asJsoup
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.awaitAll
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||
import okhttp3.MediaType.Companion.toMediaType
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.Request
|
||||
import okhttp3.RequestBody.Companion.toRequestBody
|
||||
import okhttp3.Response
|
||||
import org.jsoup.nodes.Document
|
||||
import org.jsoup.nodes.Element
|
||||
import rx.Observable
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
|
||||
@ -38,8 +32,6 @@ abstract class DataLifeEngine(
|
||||
|
||||
override val supportsLatest = false
|
||||
|
||||
override val client: OkHttpClient = network.cloudflareClient
|
||||
|
||||
private val preferences by lazy { Injekt.get<Application>().getSharedPreferences("source_$id", 0x0000) }
|
||||
|
||||
// ============================== Popular ===============================
|
||||
@ -139,10 +131,10 @@ abstract class DataLifeEngine(
|
||||
}
|
||||
// =========================== Anime Details ============================
|
||||
|
||||
override fun fetchAnimeDetails(anime: SAnime): Observable<SAnime> {
|
||||
override suspend fun getAnimeDetails(anime: SAnime): SAnime {
|
||||
return client.newCall(animeDetailsRequest(anime))
|
||||
.asObservableSuccess()
|
||||
.map { response ->
|
||||
.awaitSuccess()
|
||||
.use { response ->
|
||||
animeDetailsParse(response, anime).apply { initialized = true }
|
||||
}
|
||||
}
|
||||
@ -183,11 +175,6 @@ abstract class DataLifeEngine(
|
||||
).reversed()
|
||||
}
|
||||
|
||||
inline fun <A, B> Iterable<A>.parallelCatchingFlatMap(crossinline f: suspend (A) -> Iterable<B>): List<B> =
|
||||
runBlocking {
|
||||
map { async(Dispatchers.Default) { runCatching { f(it) }.getOrElse { emptyList() } } }.awaitAll().flatten()
|
||||
}
|
||||
|
||||
override fun setupPreferenceScreen(screen: PreferenceScreen) {
|
||||
val videoQualityPref = ListPreference(screen.context).apply {
|
||||
key = "preferred_quality"
|
||||
|
@ -13,14 +13,12 @@ import eu.kanade.tachiyomi.animesource.model.SEpisode
|
||||
import eu.kanade.tachiyomi.animesource.model.Video
|
||||
import eu.kanade.tachiyomi.animesource.online.ParsedAnimeHttpSource
|
||||
import eu.kanade.tachiyomi.network.GET
|
||||
import eu.kanade.tachiyomi.network.asObservableSuccess
|
||||
import eu.kanade.tachiyomi.network.awaitSuccess
|
||||
import eu.kanade.tachiyomi.util.asJsoup
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.Request
|
||||
import okhttp3.Response
|
||||
import org.jsoup.nodes.Document
|
||||
import org.jsoup.nodes.Element
|
||||
import rx.Observable
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
import java.lang.Exception
|
||||
@ -39,8 +37,6 @@ abstract class DooPlay(
|
||||
|
||||
override val supportsLatest = true
|
||||
|
||||
override val client: OkHttpClient = network.client
|
||||
|
||||
override fun headersBuilder() = super.headersBuilder().add("Referer", baseUrl)
|
||||
|
||||
protected open val preferences: SharedPreferences by lazy {
|
||||
@ -185,16 +181,14 @@ abstract class DooPlay(
|
||||
return AnimesPage(animes, hasNextPage)
|
||||
}
|
||||
|
||||
override fun fetchSearchAnime(page: Int, query: String, filters: AnimeFilterList): Observable<AnimesPage> {
|
||||
override suspend fun getSearchAnime(page: Int, query: String, filters: AnimeFilterList): AnimesPage {
|
||||
return if (query.startsWith(PREFIX_SEARCH)) {
|
||||
val path = query.removePrefix(PREFIX_SEARCH)
|
||||
client.newCall(GET("$baseUrl/$path", headers))
|
||||
.asObservableSuccess()
|
||||
.map { response ->
|
||||
searchAnimeByPathParse(response)
|
||||
}
|
||||
.awaitSuccess()
|
||||
.use(::searchAnimeByPathParse)
|
||||
} else {
|
||||
super.fetchSearchAnime(page, query, filters)
|
||||
super.getSearchAnime(page, query, filters)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -17,14 +17,10 @@ import eu.kanade.tachiyomi.multisrc.dopeflix.dto.VideoDto
|
||||
import eu.kanade.tachiyomi.multisrc.dopeflix.extractors.DopeFlixExtractor
|
||||
import eu.kanade.tachiyomi.network.GET
|
||||
import eu.kanade.tachiyomi.util.asJsoup
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.awaitAll
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import eu.kanade.tachiyomi.util.parallelCatchingFlatMapBlocking
|
||||
import okhttp3.Headers
|
||||
import okhttp3.HttpUrl
|
||||
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.Request
|
||||
import okhttp3.Response
|
||||
import org.jsoup.nodes.Document
|
||||
@ -45,8 +41,6 @@ abstract class DopeFlix(
|
||||
|
||||
override val supportsLatest = true
|
||||
|
||||
override val client: OkHttpClient = network.cloudflareClient
|
||||
|
||||
private val preferences: SharedPreferences by lazy {
|
||||
Injekt.get<Application>().getSharedPreferences("source_$id", 0x0000)
|
||||
}
|
||||
@ -191,7 +185,7 @@ abstract class DopeFlix(
|
||||
val doc = response.asJsoup()
|
||||
val episodeReferer = Headers.headersOf("Referer", response.request.header("referer")!!)
|
||||
return doc.select("ul.fss-list a.btn-play")
|
||||
.parallelMap { server ->
|
||||
.parallelCatchingFlatMapBlocking { server ->
|
||||
val name = server.selectFirst("span")!!.text()
|
||||
val id = server.attr("data-id")
|
||||
val url = "$baseUrl/ajax/sources/$id"
|
||||
@ -199,19 +193,17 @@ abstract class DopeFlix(
|
||||
.use { it.body.string() }
|
||||
val sourceUrl = reqBody.substringAfter("\"link\":\"")
|
||||
.substringBefore("\"")
|
||||
runCatching {
|
||||
when {
|
||||
"DoodStream" in name ->
|
||||
DoodExtractor(client).videoFromUrl(sourceUrl)
|
||||
?.let(::listOf)
|
||||
"Vidcloud" in name || "UpCloud" in name -> {
|
||||
val video = extractor.getVideoDto(sourceUrl)
|
||||
getVideosFromServer(video, name)
|
||||
}
|
||||
else -> null
|
||||
when {
|
||||
"DoodStream" in name ->
|
||||
DoodExtractor(client).videoFromUrl(sourceUrl)
|
||||
?.let(::listOf)
|
||||
"Vidcloud" in name || "UpCloud" in name -> {
|
||||
val video = extractor.getVideoDto(sourceUrl)
|
||||
getVideosFromServer(video, name)
|
||||
}
|
||||
}.getOrNull() ?: emptyList()
|
||||
}.flatten()
|
||||
else -> null
|
||||
}.orEmpty()
|
||||
}
|
||||
}
|
||||
|
||||
private fun getVideosFromServer(video: VideoDto, name: String): List<Video> {
|
||||
@ -343,11 +335,6 @@ abstract class DopeFlix(
|
||||
}
|
||||
|
||||
// ============================= Utilities ==============================
|
||||
private inline fun <A, B> Iterable<A>.parallelMap(crossinline f: suspend (A) -> B): List<B> =
|
||||
runBlocking {
|
||||
map { async(Dispatchers.Default) { f(it) } }.awaitAll()
|
||||
}
|
||||
|
||||
private fun HttpUrl.Builder.addIfNotBlank(query: String, value: String): HttpUrl.Builder {
|
||||
if (value.isNotBlank()) {
|
||||
addQueryParameter(query, value)
|
||||
|
@ -16,13 +16,14 @@ import eu.kanade.tachiyomi.animesource.online.ParsedAnimeHttpSource
|
||||
import eu.kanade.tachiyomi.multisrc.zorotheme.dto.HtmlResponse
|
||||
import eu.kanade.tachiyomi.multisrc.zorotheme.dto.SourcesResponse
|
||||
import eu.kanade.tachiyomi.network.GET
|
||||
import eu.kanade.tachiyomi.network.await
|
||||
import eu.kanade.tachiyomi.util.parallelCatchingFlatMap
|
||||
import eu.kanade.tachiyomi.util.parallelMapNotNull
|
||||
import eu.kanade.tachiyomi.util.parseAs
|
||||
import kotlinx.serialization.json.Json
|
||||
import okhttp3.Headers
|
||||
import okhttp3.HttpUrl
|
||||
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.Request
|
||||
import okhttp3.Response
|
||||
import org.jsoup.nodes.Document
|
||||
@ -39,8 +40,6 @@ abstract class ZoroTheme(
|
||||
|
||||
override val supportsLatest = true
|
||||
|
||||
override val client: OkHttpClient = network.client
|
||||
|
||||
private val json: Json by injectLazy()
|
||||
|
||||
val preferences: SharedPreferences by lazy {
|
||||
@ -210,7 +209,7 @@ abstract class ZoroTheme(
|
||||
)
|
||||
|
||||
override suspend fun getVideoList(episode: SEpisode): List<Video> {
|
||||
val response = client.newCall(videoListRequest(episode)).execute()
|
||||
val response = client.newCall(videoListRequest(episode)).await()
|
||||
|
||||
val episodeReferer = response.request.header("referer")!!
|
||||
val typeSelection = preferences.typeToggle
|
||||
@ -230,7 +229,7 @@ abstract class ZoroTheme(
|
||||
|
||||
val link = client.newCall(
|
||||
GET("$baseUrl/ajax$ajaxRoute/episode/sources?id=$id", apiHeaders(episodeReferer)),
|
||||
).execute().parseAs<SourcesResponse>().link ?: ""
|
||||
).await().parseAs<SourcesResponse>().link ?: ""
|
||||
|
||||
VideoData(type, link, name)
|
||||
}
|
||||
@ -250,11 +249,6 @@ abstract class ZoroTheme(
|
||||
override fun videoUrlParse(document: Document) = throw Exception("not used")
|
||||
|
||||
// ============================= Utilities ==============================
|
||||
|
||||
private inline fun <reified T> Response.parseAs(): T {
|
||||
return use { it.body.string() }.let(json::decodeFromString)
|
||||
}
|
||||
|
||||
private fun Set<String>.contains(s: String, ignoreCase: Boolean): Boolean {
|
||||
return any { it.equals(s, ignoreCase) }
|
||||
}
|
||||
|
@ -81,7 +81,6 @@ interface ThemeSourceGenerator {
|
||||
| extClass = '.${source.className}'
|
||||
| extFactory = '$themePkg'
|
||||
| extVersionCode = ${baseVersionCode + source.overrideVersionCode + MULTISRC_LIBRARY_VERSION}
|
||||
| libVersion = '13'
|
||||
| ${if (source.isNsfw) "containsNsfw = true\n" else ""}
|
||||
|}
|
||||
|$defaultAdditionalGradleText
|
||||
|
Reference in New Issue
Block a user