mirror of
https://github.com/aniyomiorg/aniyomi.git
synced 2024-11-29 01:29:02 +03:00
improve getting links
This commit is contained in:
parent
d387b8c76f
commit
8423e9e35f
11 changed files with 144 additions and 14 deletions
|
@ -20,17 +20,20 @@ import eu.kanade.tachiyomi.data.download.DownloadManager
|
|||
import eu.kanade.tachiyomi.data.download.DownloadService
|
||||
import eu.kanade.tachiyomi.data.library.LibraryUpdateService
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.source.AnimeSourceManager
|
||||
import eu.kanade.tachiyomi.source.SourceManager
|
||||
import eu.kanade.tachiyomi.ui.anime.AnimeController
|
||||
import eu.kanade.tachiyomi.ui.main.MainActivity
|
||||
import eu.kanade.tachiyomi.ui.manga.MangaController
|
||||
import eu.kanade.tachiyomi.ui.reader.ReaderActivity
|
||||
import eu.kanade.tachiyomi.ui.watcher.WatcherActivity
|
||||
import eu.kanade.tachiyomi.util.lang.awaitSingle
|
||||
import eu.kanade.tachiyomi.util.lang.launchIO
|
||||
import eu.kanade.tachiyomi.util.storage.DiskUtil
|
||||
import eu.kanade.tachiyomi.util.storage.getUriCompat
|
||||
import eu.kanade.tachiyomi.util.system.notificationManager
|
||||
import eu.kanade.tachiyomi.util.system.toast
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
|
@ -433,7 +436,8 @@ class NotificationReceiver : BroadcastReceiver() {
|
|||
* @param episode episode that needs to be opened
|
||||
*/
|
||||
internal fun openEpisodePendingActivity(context: Context, anime: Anime, episode: Episode): PendingIntent {
|
||||
val newIntent = WatcherActivity.newIntent(context, anime, episode)
|
||||
val source = Injekt.get<AnimeSourceManager>().getOrStub(anime.source)
|
||||
val newIntent = WatcherActivity.newIntent(context, anime, episode, runBlocking { source.fetchEpisodeLink(episode).awaitSingle() })
|
||||
return PendingIntent.getActivity(context, anime.id.hashCode(), newIntent, PendingIntent.FLAG_UPDATE_CURRENT)
|
||||
}
|
||||
|
||||
|
|
|
@ -37,13 +37,21 @@ interface AnimeSource : tachiyomi.source.AnimeSource {
|
|||
fun fetchAnimeDetails(anime: SAnime): Observable<SAnime>
|
||||
|
||||
/**
|
||||
* Returns an observable with all the available chapters for a anime.
|
||||
* Returns an observable with all the available episodes for an anime.
|
||||
*
|
||||
* @param anime the anime to update.
|
||||
*/
|
||||
@Deprecated("Use getEpisodeList instead")
|
||||
fun fetchEpisodeList(anime: SAnime): Observable<List<SEpisode>>
|
||||
|
||||
/**
|
||||
* Returns an observable with a link for the episode of an anime.
|
||||
*
|
||||
* @param episode the episode to get the link for.
|
||||
*/
|
||||
@Deprecated("Use getEpisodeList instead")
|
||||
fun fetchEpisodeLink(episode: SEpisode): Observable<String>
|
||||
|
||||
/**
|
||||
* Returns an observable with the list of pages a chapter has.
|
||||
*
|
||||
|
@ -64,7 +72,7 @@ interface AnimeSource : tachiyomi.source.AnimeSource {
|
|||
}
|
||||
|
||||
/**
|
||||
* [1.x API] Get all the available chapters for a anime.
|
||||
* [1.x API] Get all the available episodes for a anime.
|
||||
*/
|
||||
@Suppress("DEPRECATION")
|
||||
override suspend fun getEpisodeList(anime: AnimeInfo): List<EpisodeInfo> {
|
||||
|
@ -72,6 +80,14 @@ interface AnimeSource : tachiyomi.source.AnimeSource {
|
|||
.map { it.toEpisodeInfo() }
|
||||
}
|
||||
|
||||
/**
|
||||
* [1.x API] Get a link for the episode of an anime.
|
||||
*/
|
||||
@Suppress("DEPRECATION")
|
||||
override suspend fun getEpisodeLink(episode: EpisodeInfo): String {
|
||||
return fetchEpisodeLink(episode.toSEpisode()).awaitSingle()
|
||||
}
|
||||
|
||||
/**
|
||||
* [1.x API] Get the list of pages a chapter has.
|
||||
*/
|
||||
|
|
|
@ -62,6 +62,10 @@ open class AnimeSourceManager(private val context: Context) {
|
|||
return Observable.error(getSourceNotInstalledException())
|
||||
}
|
||||
|
||||
override fun fetchEpisodeLink(episode: SEpisode): Observable<String> {
|
||||
return Observable.error(getSourceNotInstalledException())
|
||||
}
|
||||
|
||||
override fun fetchPageList(episode: SEpisode): Observable<List<Page>> {
|
||||
return Observable.error(getSourceNotInstalledException())
|
||||
}
|
||||
|
|
|
@ -203,6 +203,12 @@ class LocalAnimeSource(private val context: Context) : AnimeCatalogueSource {
|
|||
return Observable.just(episodes)
|
||||
}
|
||||
|
||||
override fun fetchEpisodeLink(episode: SEpisode): Observable<String> {
|
||||
val link = episode.url
|
||||
|
||||
return Observable.just(link)
|
||||
}
|
||||
|
||||
/**
|
||||
* Strips the anime title from a episode name, matching only based on alphanumeric and whitespace
|
||||
* characters.
|
||||
|
|
|
@ -218,6 +218,14 @@ abstract class AnimeHttpSource : AnimeCatalogueSource {
|
|||
}
|
||||
}
|
||||
|
||||
override fun fetchEpisodeLink(episode: SEpisode): Observable<String> {
|
||||
return client.newCall(episodeLinkRequest(episode))
|
||||
.asObservableSuccess()
|
||||
.map { response ->
|
||||
episodeLinkParse(response)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the request for updating the episode list. Override only if it's needed to override
|
||||
* the url, send different headers or request method like POST.
|
||||
|
@ -228,6 +236,16 @@ abstract class AnimeHttpSource : AnimeCatalogueSource {
|
|||
return GET(baseUrl + anime.url, headers)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the request for getting the episode link. Override only if it's needed to override
|
||||
* the url, send different headers or request method like POST.
|
||||
*
|
||||
* @param episode the episode to look for links.
|
||||
*/
|
||||
protected open fun episodeLinkRequest(episode: SEpisode): Request {
|
||||
return GET(baseUrl + episode.url, headers)
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the response from the site and returns a list of episodes.
|
||||
*
|
||||
|
@ -235,6 +253,13 @@ abstract class AnimeHttpSource : AnimeCatalogueSource {
|
|||
*/
|
||||
protected abstract fun episodeListParse(response: Response): List<SEpisode>
|
||||
|
||||
/**
|
||||
* Parses the response from the site and returns a list of episodes.
|
||||
*
|
||||
* @param response the response from the site.
|
||||
*/
|
||||
protected abstract fun episodeLinkParse(response: Response): String
|
||||
|
||||
/**
|
||||
* Returns an observable with the page list for a episode.
|
||||
*
|
||||
|
|
|
@ -159,6 +159,21 @@ abstract class ParsedAnimeHttpSource : AnimeHttpSource() {
|
|||
*/
|
||||
protected abstract fun episodeListSelector(): String
|
||||
|
||||
/**
|
||||
* Parses the response from the site and returns a list of episodes.
|
||||
*
|
||||
* @param response the response from the site.
|
||||
*/
|
||||
override fun episodeLinkParse(response: Response): String {
|
||||
val document = response.asJsoup()
|
||||
return linkFromElement(document.select(episodeLinkSelector()).first())
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Jsoup selector that returns a list of [Element] corresponding to each episode.
|
||||
*/
|
||||
protected abstract fun episodeLinkSelector(): String
|
||||
|
||||
/**
|
||||
* Returns a episode from the given element.
|
||||
*
|
||||
|
@ -166,6 +181,13 @@ abstract class ParsedAnimeHttpSource : AnimeHttpSource() {
|
|||
*/
|
||||
protected abstract fun episodeFromElement(element: Element): SEpisode
|
||||
|
||||
/**
|
||||
* Returns a episode from the given element.
|
||||
*
|
||||
* @param element an element obtained from [episodeListSelector].
|
||||
*/
|
||||
protected abstract fun linkFromElement(element: Element): String
|
||||
|
||||
/**
|
||||
* Parses the response from the site and returns the page list.
|
||||
*
|
||||
|
|
|
@ -79,6 +79,9 @@ import eu.kanade.tachiyomi.util.view.shrinkOnScroll
|
|||
import eu.kanade.tachiyomi.util.view.snack
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import okhttp3.Callback
|
||||
import reactivecircus.flowbinding.recyclerview.scrollEvents
|
||||
import reactivecircus.flowbinding.swiperefreshlayout.refreshes
|
||||
import timber.log.Timber
|
||||
|
@ -722,6 +725,14 @@ class AnimeController :
|
|||
}
|
||||
}
|
||||
|
||||
private fun fetchEpisodeLinksFromSource(manualFetch: Boolean = false, episode: Episode): String {
|
||||
return presenter.fetchEpisodeLinksFromSource(manualFetch, episode)
|
||||
}
|
||||
|
||||
fun onFetchEpisodeLinksError(error: Throwable) {
|
||||
activity?.toast("no links found")
|
||||
}
|
||||
|
||||
fun onEpisodeDownloadUpdate(download: AnimeDownload) {
|
||||
episodesAdapter?.currentItems?.find { it.id == download.episode.id }?.let {
|
||||
episodesAdapter?.updateItem(it, it.status)
|
||||
|
@ -730,11 +741,16 @@ class AnimeController :
|
|||
|
||||
fun openEpisode(episode: Episode, hasAnimation: Boolean = false) {
|
||||
val activity = activity ?: return
|
||||
val intent = WatcherActivity.newIntent(activity, presenter.anime, episode)
|
||||
if (hasAnimation) {
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION)
|
||||
runBlocking {
|
||||
launch {
|
||||
val url = fetchEpisodeLinksFromSource(false, episode)
|
||||
val intent = WatcherActivity.newIntent(activity, presenter.anime, episode, url)
|
||||
if (hasAnimation) {
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION)
|
||||
}
|
||||
startActivityForResult(intent, REQUEST_SECONDS)
|
||||
}
|
||||
}
|
||||
startActivityForResult(intent, REQUEST_SECONDS)
|
||||
}
|
||||
|
||||
override fun onItemClick(view: View?, position: Int): Boolean {
|
||||
|
|
|
@ -3,6 +3,7 @@ package eu.kanade.tachiyomi.ui.anime
|
|||
import android.content.Context
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import com.jakewharton.rxrelay.PublishRelay
|
||||
import eu.kanade.tachiyomi.data.cache.AnimeCoverCache
|
||||
import eu.kanade.tachiyomi.data.database.AnimeDatabaseHelper
|
||||
|
@ -19,6 +20,7 @@ import eu.kanade.tachiyomi.data.track.TrackManager
|
|||
import eu.kanade.tachiyomi.data.track.TrackService
|
||||
import eu.kanade.tachiyomi.source.AnimeSource
|
||||
import eu.kanade.tachiyomi.source.LocalAnimeSource
|
||||
import eu.kanade.tachiyomi.source.model.toEpisodeInfo
|
||||
import eu.kanade.tachiyomi.source.model.toSAnime
|
||||
import eu.kanade.tachiyomi.source.model.toSEpisode
|
||||
import eu.kanade.tachiyomi.ui.anime.episode.EpisodeItem
|
||||
|
@ -31,10 +33,7 @@ import eu.kanade.tachiyomi.util.lang.launchIO
|
|||
import eu.kanade.tachiyomi.util.lang.withUIContext
|
||||
import eu.kanade.tachiyomi.util.system.toast
|
||||
import eu.kanade.tachiyomi.widget.ExtendedNavigationView.Item.TriStateGroup.State
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.awaitAll
|
||||
import kotlinx.coroutines.supervisorScope
|
||||
import kotlinx.coroutines.*
|
||||
import rx.Observable
|
||||
import rx.Subscription
|
||||
import rx.android.schedulers.AndroidSchedulers
|
||||
|
@ -43,6 +42,8 @@ import timber.log.Timber
|
|||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
import java.util.Date
|
||||
import kotlin.coroutines.resume
|
||||
import kotlin.coroutines.suspendCoroutine
|
||||
|
||||
class AnimePresenter(
|
||||
val anime: Anime,
|
||||
|
@ -83,6 +84,11 @@ class AnimePresenter(
|
|||
*/
|
||||
private var fetchEpisodesJob: Job? = null
|
||||
|
||||
/**
|
||||
* Subscription to retrieve the new link of episodes from the source.
|
||||
*/
|
||||
private var fetchEpisodeLinksJob: Job? = null
|
||||
|
||||
/**
|
||||
* Subscription to observe download status changes.
|
||||
*/
|
||||
|
@ -391,6 +397,28 @@ class AnimePresenter(
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests an updated list of episodes from the source.
|
||||
*/
|
||||
fun fetchEpisodeLinksFromSource(manualFetch: Boolean = false, episode: Episode): String {
|
||||
hasRequested = true
|
||||
var link = runBlocking {
|
||||
return@runBlocking suspendCoroutine<String> { continuation ->
|
||||
var link: String
|
||||
presenterScope.launchIO {
|
||||
try {
|
||||
link = source.getEpisodeLink(episode.toEpisodeInfo())
|
||||
continuation.resume(link)
|
||||
} catch (e: Throwable) {
|
||||
withUIContext { view?.onFetchEpisodeLinksError(e) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Log.i("lol", "omg" + link)
|
||||
return link
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the UI after applying the filters.
|
||||
*/
|
||||
|
|
|
@ -43,8 +43,8 @@ import eu.kanade.tachiyomi.ui.base.controller.TabbedController
|
|||
import eu.kanade.tachiyomi.ui.base.controller.ToolbarLiftOnScrollController
|
||||
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
||||
import eu.kanade.tachiyomi.ui.browse.BrowseController
|
||||
import eu.kanade.tachiyomi.ui.browse.source.browse.BrowseSourceController
|
||||
import eu.kanade.tachiyomi.ui.browse.animesource.browse.BrowseAnimeSourceController
|
||||
import eu.kanade.tachiyomi.ui.browse.source.browse.BrowseSourceController
|
||||
import eu.kanade.tachiyomi.ui.browse.source.globalsearch.GlobalSearchController
|
||||
import eu.kanade.tachiyomi.ui.download.DownloadController
|
||||
import eu.kanade.tachiyomi.ui.library.LibraryController
|
||||
|
|
|
@ -42,6 +42,7 @@ class WatcherActivity : AppCompatActivity() {
|
|||
setContentView(R.layout.watcher_activity)
|
||||
playerView = findViewById(R.id.player_view)
|
||||
dataSourceFactory = DefaultDataSourceFactory(this, Util.getUserAgent(this, "xyz.jmir.tachiyomi.mi"))
|
||||
Log.i("uri is ", intent.getStringExtra("uri"))
|
||||
mediaItem = MediaItem.Builder()
|
||||
.setUri(intent.getStringExtra("uri"))
|
||||
.setMimeType(MimeTypes.VIDEO_MP4)
|
||||
|
@ -127,12 +128,13 @@ class WatcherActivity : AppCompatActivity() {
|
|||
}
|
||||
|
||||
companion object {
|
||||
fun newIntent(context: Context, anime: Anime, episode: Episode): Intent {
|
||||
fun newIntent(context: Context, anime: Anime, episode: Episode, url: String): Intent {
|
||||
return Intent(context, WatcherActivity::class.java).apply {
|
||||
putExtra("anime", anime.id)
|
||||
putExtra("episode", episode)
|
||||
putExtra("second", episode.last_second_seen)
|
||||
putExtra("uri", episode.url)
|
||||
putExtra("uri", url)
|
||||
Log.i("bruhh", url)
|
||||
addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,6 +36,13 @@ interface AnimeSource {
|
|||
*/
|
||||
suspend fun getEpisodeList(anime: AnimeInfo): List<EpisodeInfo>
|
||||
|
||||
/**
|
||||
* Returns an observable with all the available chapters for a anime.
|
||||
*
|
||||
* @param anime the anime to update.
|
||||
*/
|
||||
suspend fun getEpisodeLink(episode: EpisodeInfo): String
|
||||
|
||||
/**
|
||||
* Returns an observable with the list of pages a chapter has.
|
||||
*
|
||||
|
|
Loading…
Reference in a new issue