chore: update extension api
This commit is contained in:
parent
bf33f5d9c8
commit
126bc6134e
6 changed files with 229 additions and 97 deletions
|
@ -88,9 +88,9 @@ android {
|
|||
dependencies {
|
||||
|
||||
// FireBase
|
||||
googleImplementation platform('com.google.firebase:firebase-bom:32.7.4')
|
||||
googleImplementation 'com.google.firebase:firebase-analytics-ktx:21.5.1'
|
||||
googleImplementation 'com.google.firebase:firebase-crashlytics-ktx:18.6.2'
|
||||
googleImplementation platform('com.google.firebase:firebase-bom:32.8.1')
|
||||
googleImplementation 'com.google.firebase:firebase-analytics-ktx:21.6.2'
|
||||
googleImplementation 'com.google.firebase:firebase-crashlytics-ktx:18.6.4'
|
||||
// Core
|
||||
implementation 'androidx.appcompat:appcompat:1.6.1'
|
||||
implementation 'androidx.browser:browser:1.8.0'
|
||||
|
@ -118,7 +118,7 @@ dependencies {
|
|||
implementation 'jp.wasabeef:glide-transformations:4.3.0'
|
||||
|
||||
// Exoplayer
|
||||
ext.exo_version = '1.3.0'
|
||||
ext.exo_version = '1.3.1'
|
||||
implementation "androidx.media3:media3-exoplayer:$exo_version"
|
||||
implementation "androidx.media3:media3-ui:$exo_version"
|
||||
implementation "androidx.media3:media3-exoplayer-hls:$exo_version"
|
||||
|
@ -138,7 +138,7 @@ dependencies {
|
|||
implementation 'com.github.VipulOG:ebook-reader:0.1.6'
|
||||
implementation 'androidx.paging:paging-runtime-ktx:3.2.1'
|
||||
implementation 'com.github.eltos:simpledialogfragments:v3.7'
|
||||
implementation 'com.github.AAChartModel:AAChartCore-Kotlin:93972bc'
|
||||
implementation 'com.github.AAChartModel:AAChartCore-Kotlin:7.2.1'
|
||||
|
||||
// Markwon
|
||||
ext.markwon_version = '4.6.2'
|
||||
|
|
|
@ -245,17 +245,19 @@ class DynamicAnimeParser(extension: AnimeExtension.Installed) : AnimeParser() {
|
|||
} as? AnimeHttpSource ?: (extension.sources[sourceLanguage] as? AnimeCatalogueSource
|
||||
?: return emptyList())
|
||||
return try {
|
||||
val res = source.fetchSearchAnime(1, query, source.getFilterList()).awaitSingle()
|
||||
val res = source.getSearchAnime(1, query, source.getFilterList())
|
||||
Logger.log("query: $query")
|
||||
convertAnimesPageToShowResponse(res)
|
||||
} catch (e: CloudflareBypassException) {
|
||||
Logger.log("Exception in search: $e")
|
||||
Logger.log(e)
|
||||
withContext(Dispatchers.Main) {
|
||||
snackString("Failed to bypass Cloudflare")
|
||||
}
|
||||
emptyList()
|
||||
} catch (e: Exception) {
|
||||
Logger.log("General exception in search: $e")
|
||||
Logger.log(e)
|
||||
emptyList()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package eu.kanade.tachiyomi.animesource
|
|||
|
||||
import eu.kanade.tachiyomi.animesource.model.AnimeFilterList
|
||||
import eu.kanade.tachiyomi.animesource.model.AnimesPage
|
||||
import eu.kanade.tachiyomi.util.lang.awaitSingle
|
||||
import rx.Observable
|
||||
|
||||
interface AnimeCatalogueSource : AnimeSource {
|
||||
|
@ -17,30 +18,63 @@ interface AnimeCatalogueSource : AnimeSource {
|
|||
val supportsLatest: Boolean
|
||||
|
||||
/**
|
||||
* Returns an observable containing a page with a list of anime.
|
||||
* Get a page with a list of anime.
|
||||
*
|
||||
* @since extensions-lib 1.5
|
||||
* @param page the page number to retrieve.
|
||||
*/
|
||||
fun fetchPopularAnime(page: Int): Observable<AnimesPage>
|
||||
@Suppress("DEPRECATION")
|
||||
suspend fun getPopularAnime(page: Int): AnimesPage {
|
||||
return fetchPopularAnime(page).awaitSingle()
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an observable containing a page with a list of anime.
|
||||
* Get a page with a list of anime.
|
||||
*
|
||||
* @since extensions-lib 1.5
|
||||
* @param page the page number to retrieve.
|
||||
* @param query the search query.
|
||||
* @param filters the list of filters to apply.
|
||||
*/
|
||||
fun fetchSearchAnime(page: Int, query: String, filters: AnimeFilterList): Observable<AnimesPage>
|
||||
@Suppress("DEPRECATION")
|
||||
suspend fun getSearchAnime(page: Int, query: String, filters: AnimeFilterList): AnimesPage {
|
||||
return fetchSearchAnime(page, query, filters).awaitSingle()
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an observable containing a page with a list of latest anime updates.
|
||||
* Get a page with a list of latest anime updates.
|
||||
*
|
||||
* @since extensions-lib 1.5
|
||||
* @param page the page number to retrieve.
|
||||
*/
|
||||
fun fetchLatestUpdates(page: Int): Observable<AnimesPage>
|
||||
@Suppress("DEPRECATION")
|
||||
suspend fun getLatestUpdates(page: Int): AnimesPage {
|
||||
return fetchLatestUpdates(page).awaitSingle()
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of filters for the source.
|
||||
*/
|
||||
fun getFilterList(): AnimeFilterList
|
||||
|
||||
// Should be replaced as soon as Anime Extension reach 1.5
|
||||
@Deprecated(
|
||||
"Use the non-RxJava API instead",
|
||||
ReplaceWith("getPopularAnime"),
|
||||
)
|
||||
fun fetchPopularAnime(page: Int): Observable<AnimesPage>
|
||||
|
||||
// Should be replaced as soon as Anime Extension reach 1.5
|
||||
@Deprecated(
|
||||
"Use the non-RxJava API instead",
|
||||
ReplaceWith("getSearchAnime"),
|
||||
)
|
||||
fun fetchSearchAnime(page: Int, query: String, filters: AnimeFilterList): Observable<AnimesPage>
|
||||
|
||||
// Should be replaced as soon as Anime Extension reach 1.5
|
||||
@Deprecated(
|
||||
"Use the non-RxJava API instead",
|
||||
ReplaceWith("getLatestUpdates"),
|
||||
)
|
||||
fun fetchLatestUpdates(page: Int): Observable<AnimesPage>
|
||||
}
|
||||
|
|
|
@ -9,8 +9,11 @@ import eu.kanade.tachiyomi.animesource.model.Video
|
|||
import eu.kanade.tachiyomi.network.GET
|
||||
import eu.kanade.tachiyomi.network.NetworkHelper
|
||||
import eu.kanade.tachiyomi.network.NetworkHelper.Companion.defaultUserAgentProvider
|
||||
import eu.kanade.tachiyomi.network.ProgressListener
|
||||
import eu.kanade.tachiyomi.network.asObservableSuccess
|
||||
import eu.kanade.tachiyomi.network.awaitSuccess
|
||||
import eu.kanade.tachiyomi.network.newCachelessCallWithProgress
|
||||
import eu.kanade.tachiyomi.util.lang.awaitSingle
|
||||
import okhttp3.Headers
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.Request
|
||||
|
@ -25,8 +28,8 @@ import java.util.concurrent.TimeUnit
|
|||
/**
|
||||
* A simple implementation for sources from a website.
|
||||
*/
|
||||
@Suppress("unused")
|
||||
abstract class AnimeHttpSource : AnimeCatalogueSource {
|
||||
|
||||
/**
|
||||
* Network service.
|
||||
*/
|
||||
|
@ -44,16 +47,16 @@ abstract class AnimeHttpSource : AnimeCatalogueSource {
|
|||
open val versionId = 1
|
||||
|
||||
/**
|
||||
* Id of the source. By default it uses a generated id using the first 16 characters (64 bits)
|
||||
* of the MD5 of the string: sourcename/language/versionId
|
||||
* Note the generated id sets the sign bit to 0.
|
||||
* ID of the source. By default it uses a generated id using the first 16 characters (64 bits)
|
||||
* of the MD5 of the string `"${name.lowercase()}/$lang/$versionId"`.
|
||||
*
|
||||
* The ID is generated by the [generateId] function, which can be reused if needed
|
||||
* to generate outdated IDs for cases where the source name or language needs to
|
||||
* be changed but migrations can be avoided.
|
||||
*
|
||||
* Note: the generated ID sets the sign bit to `0`.
|
||||
*/
|
||||
override val id by lazy {
|
||||
val key = "${name.lowercase()}/$lang/$versionId"
|
||||
val bytes = MessageDigest.getInstance("MD5").digest(key.toByteArray())
|
||||
(0..7).map { bytes[it].toLong() and 0xff shl 8 * (7 - it) }
|
||||
.reduce(Long::or) and Long.MAX_VALUE
|
||||
}
|
||||
override val id by lazy { generateId(name, lang, versionId) }
|
||||
|
||||
/**
|
||||
* Headers used for requests.
|
||||
|
@ -66,11 +69,34 @@ abstract class AnimeHttpSource : AnimeCatalogueSource {
|
|||
open val client: OkHttpClient
|
||||
get() = network.client
|
||||
|
||||
/**
|
||||
* Generates a unique ID for the source based on the provided [name], [lang] and
|
||||
* [versionId]. It will use the first 16 characters (64 bits) of the MD5 of the string
|
||||
* `"${name.lowercase()}/$lang/$versionId"`.
|
||||
*
|
||||
* Note: the generated ID sets the sign bit to `0`.
|
||||
*
|
||||
* Can be used to generate outdated IDs, such as when the source name or language
|
||||
* needs to be changed but migrations can be avoided.
|
||||
*
|
||||
* @since extensions-lib 1.5
|
||||
* @param name [String] the name of the source
|
||||
* @param lang [String] the language of the source
|
||||
* @param versionId [Int] the version ID of the source
|
||||
* @return a unique ID for the source
|
||||
*/
|
||||
@Suppress("MemberVisibilityCanBePrivate")
|
||||
protected fun generateId(name: String, lang: String, versionId: Int): Long {
|
||||
val key = "${name.lowercase()}/$lang/$versionId"
|
||||
val bytes = MessageDigest.getInstance("MD5").digest(key.toByteArray())
|
||||
return (0..7).map { bytes[it].toLong() and 0xff shl 8 * (7 - it) }.reduce(Long::or) and Long.MAX_VALUE
|
||||
}
|
||||
|
||||
/**
|
||||
* Headers builder for requests. Implementations can override this method for custom headers.
|
||||
*/
|
||||
protected open fun headersBuilder() = Headers.Builder().apply {
|
||||
add("User-Agent", defaultUserAgentProvider())
|
||||
add("User-Agent", NetworkHelper.defaultUserAgentProvider())
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -84,6 +110,10 @@ abstract class AnimeHttpSource : AnimeCatalogueSource {
|
|||
*
|
||||
* @param page the page number to retrieve.
|
||||
*/
|
||||
@Deprecated(
|
||||
"Use the non-RxJava API instead",
|
||||
ReplaceWith("getPopularAnime"),
|
||||
)
|
||||
override fun fetchPopularAnime(page: Int): Observable<AnimesPage> {
|
||||
return client.newCall(popularAnimeRequest(page))
|
||||
.asObservableSuccess()
|
||||
|
@ -114,11 +144,11 @@ abstract class AnimeHttpSource : AnimeCatalogueSource {
|
|||
* @param query the search query.
|
||||
* @param filters the list of filters to apply.
|
||||
*/
|
||||
override fun fetchSearchAnime(
|
||||
page: Int,
|
||||
query: String,
|
||||
filters: AnimeFilterList
|
||||
): Observable<AnimesPage> {
|
||||
@Deprecated(
|
||||
"Use the non-RxJava API instead",
|
||||
ReplaceWith("getSearchAnime"),
|
||||
)
|
||||
override fun fetchSearchAnime(page: Int, query: String, filters: AnimeFilterList): Observable<AnimesPage> {
|
||||
return Observable.defer {
|
||||
try {
|
||||
client.newCall(searchAnimeRequest(page, query, filters)).asObservableSuccess()
|
||||
|
@ -140,11 +170,7 @@ abstract class AnimeHttpSource : AnimeCatalogueSource {
|
|||
* @param query the search query.
|
||||
* @param filters the list of filters to apply.
|
||||
*/
|
||||
protected abstract fun searchAnimeRequest(
|
||||
page: Int,
|
||||
query: String,
|
||||
filters: AnimeFilterList
|
||||
): Request
|
||||
protected abstract fun searchAnimeRequest(page: Int, query: String, filters: AnimeFilterList): Request
|
||||
|
||||
/**
|
||||
* Parses the response from the site and returns a [AnimesPage] object.
|
||||
|
@ -158,6 +184,10 @@ abstract class AnimeHttpSource : AnimeCatalogueSource {
|
|||
*
|
||||
* @param page the page number to retrieve.
|
||||
*/
|
||||
@Deprecated(
|
||||
"Use the non-RxJava API instead",
|
||||
ReplaceWith("getLatestUpdates"),
|
||||
)
|
||||
override fun fetchLatestUpdates(page: Int): Observable<AnimesPage> {
|
||||
return client.newCall(latestUpdatesRequest(page))
|
||||
.asObservableSuccess()
|
||||
|
@ -181,11 +211,18 @@ abstract class AnimeHttpSource : AnimeCatalogueSource {
|
|||
protected abstract fun latestUpdatesParse(response: Response): AnimesPage
|
||||
|
||||
/**
|
||||
* Returns an observable with the updated details for a nanime. Normally it's not needed to
|
||||
* override this method.
|
||||
* Get the updated details for a anime.
|
||||
* Normally it's not needed to override this method.
|
||||
*
|
||||
* @param anime the anime to be updated.
|
||||
* @return the updated anime.
|
||||
*/
|
||||
@Suppress("DEPRECATION")
|
||||
override suspend fun getAnimeDetails(anime: SAnime): SAnime {
|
||||
return fetchAnimeDetails(anime).awaitSingle()
|
||||
}
|
||||
|
||||
@Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getAnimeDetails"))
|
||||
override fun fetchAnimeDetails(anime: SAnime): Observable<SAnime> {
|
||||
return client.newCall(animeDetailsRequest(anime))
|
||||
.asObservableSuccess()
|
||||
|
@ -212,11 +249,23 @@ abstract class AnimeHttpSource : AnimeCatalogueSource {
|
|||
protected abstract fun animeDetailsParse(response: Response): SAnime
|
||||
|
||||
/**
|
||||
* Returns an observable with the updated episode list for an anime. Normally it's not needed to
|
||||
* override this method. If an anime is licensed an empty episode list observable is returned
|
||||
* Get all the available episodes for an anime.
|
||||
* Normally it's not needed to override this method.
|
||||
*
|
||||
* @param anime the anime to look for episodes.
|
||||
* @param anime the anime to update.
|
||||
* @return the chapters for the manga.
|
||||
* @throws LicensedEntryItemsException if a anime is licensed and therefore no episodes are available.
|
||||
*/
|
||||
@Suppress("DEPRECATION")
|
||||
override suspend fun getEpisodeList(anime: SAnime): List<SEpisode> {
|
||||
if (anime.status == SAnime.LICENSED) {
|
||||
throw LicensedEntryItemsException()
|
||||
}
|
||||
|
||||
return fetchEpisodeList(anime).awaitSingle()
|
||||
}
|
||||
|
||||
@Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getEpisodeList"))
|
||||
override fun fetchEpisodeList(anime: SAnime): Observable<List<SEpisode>> {
|
||||
return if (anime.status != SAnime.LICENSED) {
|
||||
client.newCall(episodeListRequest(anime))
|
||||
|
@ -225,7 +274,7 @@ abstract class AnimeHttpSource : AnimeCatalogueSource {
|
|||
episodeListParse(response)
|
||||
}
|
||||
} else {
|
||||
Observable.error(Exception("Licensed - No episodes to show"))
|
||||
Observable.error(LicensedEntryItemsException())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -247,10 +296,25 @@ abstract class AnimeHttpSource : AnimeCatalogueSource {
|
|||
protected abstract fun episodeListParse(response: Response): List<SEpisode>
|
||||
|
||||
/**
|
||||
* Returns an observable with the page list for a chapter.
|
||||
* Parses the response from the site and returns a SEpisode Object.
|
||||
*
|
||||
* @param episode the episode whose video list has to be fetched.
|
||||
* @param response the response from the site.
|
||||
*/
|
||||
protected abstract fun episodeVideoParse(response: Response): SEpisode
|
||||
|
||||
/**
|
||||
* Get the list of videos a episode has. Videos should be returned
|
||||
* in the expected order; the index is ignored.
|
||||
*
|
||||
* @param episode the episode.
|
||||
* @return the videos for the episode.
|
||||
*/
|
||||
@Suppress("DEPRECATION")
|
||||
override suspend fun getVideoList(episode: SEpisode): List<Video> {
|
||||
return fetchVideoList(episode).awaitSingle()
|
||||
}
|
||||
|
||||
@Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getVideoList"))
|
||||
override fun fetchVideoList(episode: SEpisode): Observable<List<Video>> {
|
||||
return client.newCall(videoListRequest(episode))
|
||||
.asObservableSuccess()
|
||||
|
@ -287,8 +351,15 @@ abstract class AnimeHttpSource : AnimeCatalogueSource {
|
|||
* Returns an observable with the page containing the source url of the image. If there's any
|
||||
* error, it will return null instead of throwing an exception.
|
||||
*
|
||||
* @since extensions-lib 1.5
|
||||
* @param video the video whose source image has to be fetched.
|
||||
*/
|
||||
@Suppress("DEPRECATION")
|
||||
open suspend fun getVideoUrl(video: Video): String {
|
||||
return fetchVideoUrl(video).awaitSingle()
|
||||
}
|
||||
|
||||
@Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getVideoUrl"))
|
||||
open fun fetchVideoUrl(video: Video): Observable<String> {
|
||||
return client.newCall(videoUrlRequest(video))
|
||||
.asObservableSuccess()
|
||||
|
@ -313,39 +384,82 @@ abstract class AnimeHttpSource : AnimeCatalogueSource {
|
|||
protected abstract fun videoUrlParse(response: Response): String
|
||||
|
||||
/**
|
||||
* Returns an observable with the response of the source image.
|
||||
* Returns the response of the source video.
|
||||
* Typically does not need to be overridden.
|
||||
*
|
||||
* @param video the page whose source image has to be downloaded.
|
||||
* @since extensions-lib 1.5
|
||||
* @param request the http request for the video that has to be downloaded.
|
||||
* @param listener the progress listener that has to be attached to the http request
|
||||
*/
|
||||
fun fetchVideo(video: Video): Observable<Response> {
|
||||
val animeDownloadClient = client.newBuilder()
|
||||
.callTimeout(30, TimeUnit.MINUTES)
|
||||
.build()
|
||||
return animeDownloadClient.newCachelessCallWithProgress(
|
||||
videoRequest(
|
||||
video,
|
||||
video.totalBytesDownloaded
|
||||
), video
|
||||
)
|
||||
.asObservableSuccess()
|
||||
suspend fun getVideo(
|
||||
request: Request,
|
||||
listener: ProgressListener,
|
||||
): Response {
|
||||
return client.newCachelessCallWithProgress(request, listener)
|
||||
.awaitSuccess()
|
||||
}
|
||||
|
||||
fun getVideoSize(
|
||||
video: Video,
|
||||
tries: Int,
|
||||
): Long {
|
||||
val headers = Headers.Builder().addAll(video.headers ?: headers).add("Range", "bytes=0-1").build()
|
||||
val request = GET(video.videoUrl!!, headers)
|
||||
val response = client.newCall(request).execute()
|
||||
// parse the response headers to get the size of the video, in particular the content-range header
|
||||
val contentRange = response.header("Content-Range")
|
||||
if (contentRange != null) {
|
||||
return contentRange.split("/")[1].toLong()
|
||||
}
|
||||
if (tries > 0) {
|
||||
return getVideoSize(video, tries - 1)
|
||||
}
|
||||
return -1L
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the request for getting the source image. Override only if it's needed to override
|
||||
* Returns the request for getting the source image, with range header attributes. Override only if it's needed to override
|
||||
* the url, send different headers or request method like POST.
|
||||
*
|
||||
* If end is over start than the request is a range request
|
||||
* If end if equal or less than start then the request is initial-point request
|
||||
*
|
||||
* @param video the video whose link has to be fetched
|
||||
* @param start starting byte of chunk
|
||||
* @param end ending byte of chunk
|
||||
*/
|
||||
protected open fun videoRequest(video: Video, bytes: Long = 0L): Request {
|
||||
fun videoRequest(
|
||||
video: Video,
|
||||
start: Long,
|
||||
end: Long,
|
||||
): Request {
|
||||
val headers = video.headers ?: headers
|
||||
val newHeaders = if (bytes > 0L) {
|
||||
Headers.Builder().addAll(headers).add("Range", "bytes=$bytes-").build()
|
||||
val newHeaders =
|
||||
if (end - start > 0L) {
|
||||
Headers.Builder().addAll(headers).add("Range", "bytes=$start-$end").build()
|
||||
} else if (start >= 0L) {
|
||||
Headers.Builder().addAll(headers).add("Range", "bytes=$start-").build()
|
||||
} else {
|
||||
// logcat(LogPriority.ERROR) { "Error: end-start is less than 0" }
|
||||
null
|
||||
}
|
||||
return GET(video.videoUrl!!, newHeaders ?: headers)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the request for getting the source image without range header attributes. Override only if it's needed to override
|
||||
* the url, send different headers or request method like POST.
|
||||
*
|
||||
*
|
||||
* @param video the video whose link has to be fetched
|
||||
*/
|
||||
|
||||
fun safeVideoRequest(
|
||||
video: Video,
|
||||
): Request {
|
||||
return GET(video.videoUrl!!, video.headers ?: headers)
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns the url of the episode without the scheme and domain. It saves some redundancy from
|
||||
* database and the urls could still work after a domain change.
|
||||
|
@ -405,8 +519,8 @@ abstract class AnimeHttpSource : AnimeCatalogueSource {
|
|||
* @param episode the episode
|
||||
* @return url of the episode
|
||||
*/
|
||||
open fun getChapterUrl(episode: SEpisode): String {
|
||||
return episode.url.toString()
|
||||
open fun getEpisodeUrl(episode: SEpisode): String {
|
||||
return episode.url
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -423,3 +537,5 @@ abstract class AnimeHttpSource : AnimeCatalogueSource {
|
|||
*/
|
||||
override fun getFilterList() = AnimeFilterList()
|
||||
}
|
||||
|
||||
class LicensedEntryItemsException : RuntimeException()
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
package eu.kanade.tachiyomi.animesource.online
|
||||
|
||||
import eu.kanade.tachiyomi.animesource.model.Video
|
||||
import rx.Observable
|
||||
|
||||
fun AnimeHttpSource.fetchUrlFromVideo(video: Video): Observable<Video> {
|
||||
return Observable.just(video)
|
||||
.filter { !it.videoUrl.isNullOrEmpty() }
|
||||
.mergeWith(fetchRemainingVideoUrlsFromVideoList(video))
|
||||
}
|
||||
|
||||
private fun AnimeHttpSource.fetchRemainingVideoUrlsFromVideoList(video: Video): Observable<Video> {
|
||||
return Observable.just(video)
|
||||
.filter { it.videoUrl.isNullOrEmpty() }
|
||||
.concatMap { getVideoUrl(it) }
|
||||
}
|
||||
|
||||
private fun AnimeHttpSource.getVideoUrl(video: Video): Observable<Video> {
|
||||
video.status = Video.State.LOAD_VIDEO
|
||||
return fetchVideoUrl(video)
|
||||
.doOnError { video.status = Video.State.ERROR }
|
||||
.onErrorReturn { null }
|
||||
.doOnNext { video.videoUrl = it }
|
||||
.map { video }
|
||||
}
|
|
@ -10,6 +10,7 @@ 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.util.storage.DiskUtil
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import rx.Observable
|
||||
import tachiyomi.core.util.lang.withIOContext
|
||||
import tachiyomi.domain.entries.anime.model.Anime
|
||||
|
@ -35,17 +36,21 @@ class LocalAnimeSource(
|
|||
override val supportsLatest = true
|
||||
|
||||
// Browse related
|
||||
override suspend fun getPopularAnime(page: Int) = getSearchAnime(page, "", POPULAR_FILTERS)
|
||||
|
||||
override suspend fun getLatestUpdates(page: Int) = getSearchAnime(page, "", LATEST_FILTERS)
|
||||
|
||||
@Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getPopularAnime"))
|
||||
override fun fetchPopularAnime(page: Int) = fetchSearchAnime(page, "", POPULAR_FILTERS)
|
||||
|
||||
@Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getLatestUpdates"))
|
||||
override fun fetchLatestUpdates(page: Int) = fetchSearchAnime(page, "", LATEST_FILTERS)
|
||||
|
||||
override fun fetchSearchAnime(
|
||||
page: Int,
|
||||
query: String,
|
||||
filters: AnimeFilterList
|
||||
): Observable<AnimesPage> {
|
||||
//return emptyObservable()
|
||||
return Observable.just(AnimesPage(emptyList(), false))
|
||||
@Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getSearchAnime"))
|
||||
override fun fetchSearchAnime(page: Int, query: String, filters: AnimeFilterList): Observable<AnimesPage> {
|
||||
return runBlocking {
|
||||
Observable.just(getSearchAnime(page, query, filters))
|
||||
}
|
||||
}
|
||||
|
||||
// Anime details related
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue