2021-02-06 19:02:12 +01:00
package org.mosad.teapod.ui.activity.main.viewmodel
import android.app.Application
2021-07-10 23:37:16 +02:00
import android.util.Log
2021-02-06 19:02:12 +01:00
import androidx.lifecycle.AndroidViewModel
2021-12-28 20:32:44 +01:00
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.joinAll
import kotlinx.coroutines.launch
import org.mosad.teapod.parser.crunchyroll.Crunchyroll
import org.mosad.teapod.parser.crunchyroll.NoneEpisodes
import org.mosad.teapod.parser.crunchyroll.NoneSeasons
import org.mosad.teapod.parser.crunchyroll.NoneSeries
import org.mosad.teapod.preferences.Preferences
2021-02-06 19:02:12 +01:00
import org.mosad.teapod.util.DataTypes.MediaType
2021-12-28 20:32:44 +01:00
import org.mosad.teapod.util.Meta
2021-07-10 23:37:16 +02:00
import org.mosad.teapod.util.tmdb.TMDBApiController
import org.mosad.teapod.util.tmdb.TMDBResult
2021-07-25 19:15:31 +02:00
import org.mosad.teapod.util.tmdb.TMDBTVSeason
2021-02-06 19:02:12 +01:00
/ * *
* handle media , next ep and tmdb
2021-07-11 12:56:21 +02:00
* TODO this lives in activity , is this correct ?
2021-02-06 19:02:12 +01:00
* /
class MediaFragmentViewModel ( application : Application ) : AndroidViewModel ( application ) {
2021-12-28 20:32:44 +01:00
// var mediaCrunchy = NoneItem
// internal set
var seriesCrunchy = NoneSeries // TODO it seems movies also series?
2021-12-20 22:14:58 +01:00
internal set
var seasonsCrunchy = NoneSeasons
internal set
var episodesCrunchy = NoneEpisodes
internal set
2021-07-17 13:15:14 +02:00
var tmdbResult : TMDBResult ? = null // TODO rename
2021-02-06 19:02:12 +01:00
internal set
2021-07-25 19:15:31 +02:00
var tmdbTVSeason : TMDBTVSeason ? = null
2021-07-11 12:56:21 +02:00
internal set
var mediaMeta : Meta ? = null
internal set
2021-02-06 19:02:12 +01:00
2021-12-28 20:32:44 +01:00
/ * *
* @param crunchyId the crunchyroll series id
* /
2021-12-20 22:14:58 +01:00
suspend fun loadCrunchy ( crunchyId : String ) {
val tmdbApiController = TMDBApiController ( )
2021-12-28 20:32:44 +01:00
// load series and seasons info in parallel
listOf (
viewModelScope . launch { seriesCrunchy = Crunchyroll . series ( crunchyId ) } ,
viewModelScope . launch { seasonsCrunchy = Crunchyroll . seasons ( crunchyId ) }
) . joinAll ( )
2021-12-20 22:14:58 +01:00
2021-12-28 20:32:44 +01:00
println ( " series: $seriesCrunchy " )
2021-12-27 21:14:35 +01:00
println ( " seasons: $seasonsCrunchy " )
2021-12-20 22:14:58 +01:00
2021-12-28 20:32:44 +01:00
// load the preferred season (preferred language, language per season, not per stream)
val preferredSeasonId = seasonsCrunchy . getPreferredSeasonId ( Preferences . preferredLocal )
episodesCrunchy = Crunchyroll . episodes ( preferredSeasonId )
2021-12-27 21:14:35 +01:00
println ( " episodes: $episodesCrunchy " )
2021-12-20 22:14:58 +01:00
// TODO check if metaDB knows the title
2021-12-28 20:32:44 +01:00
// use tmdb search to get media info TODO media type is hardcoded, use episodeNumber? (if null it should be a movie)
2021-12-20 22:14:58 +01:00
mediaMeta = null // set mediaMeta to null, if metaDB doesn't know the media
2021-12-28 20:32:44 +01:00
val tmdbId = tmdbApiController . search ( seriesCrunchy . title , MediaType . TVSHOW )
2021-12-20 22:14:58 +01:00
tmdbResult = when ( MediaType . TVSHOW ) {
MediaType . MOVIE -> tmdbApiController . getMovieDetails ( tmdbId )
MediaType . TVSHOW -> tmdbApiController . getTVShowDetails ( tmdbId )
else -> null
}
}
2021-02-06 19:02:12 +01:00
/ * *
* set media , tmdb and nextEpisode
2021-07-11 12:56:21 +02:00
* TODO run aod and tmdb load parallel
2021-02-06 19:02:12 +01:00
* /
2021-12-27 21:14:35 +01:00
// suspend fun loadAoD(aodId: Int) {
// val tmdbApiController = TMDBApiController()
// media = AoDParser.getMediaById(aodId)
//
// // check if metaDB knows the title
// val tmdbId: Int = if (MetaDBController.mediaList.media.contains(aodId)) {
// // load media info from metaDB
// val metaDB = MetaDBController()
// mediaMeta = when (media.type) {
// MediaType.MOVIE -> metaDB.getMovieMetadata(media.aodId)
// MediaType.TVSHOW -> metaDB.getTVShowMetadata(media.aodId)
// else -> null
// }
//
// mediaMeta?.tmdbId ?: -1
// } else {
// // use tmdb search to get media info
// mediaMeta = null // set mediaMeta to null, if metaDB doesn't know the media
// tmdbApiController.search(stripTitleInfo(media.title), media.type)
// }
//
// tmdbResult = when (media.type) {
// MediaType.MOVIE -> tmdbApiController.getMovieDetails(tmdbId)
// MediaType.TVSHOW -> tmdbApiController.getTVShowDetails(tmdbId)
// else -> null
// }
//
// // get season info, if metaDB knows the tv show
// tmdbTVSeason = if (media.type == MediaType.TVSHOW && mediaMeta != null) {
// val tvShowMeta = mediaMeta as TVShowMeta
// tmdbApiController.getTVSeasonDetails(tvShowMeta.tmdbId, tvShowMeta.tmdbSeasonNumber)
// } else {
// null
// }
//
// if (media.type == MediaType.TVSHOW) {
// //nextEpisode = media.episodes.firstOrNull{ !it.watched } ?: media.episodes.first()
// nextEpisodeId = media.playlist.firstOrNull { !it.watched }?.mediaId
// ?: media.playlist.first().mediaId
// }
// }
2021-02-06 19:02:12 +01:00
/ * *
2021-08-31 19:47:18 +02:00
* get the next episode based on episodeId
2021-02-06 19:02:12 +01:00
* if no matching is found , use first episode
* /
2021-08-31 19:47:18 +02:00
fun updateNextEpisode ( episodeId : Int ) {
2021-12-28 20:32:44 +01:00
// TODO reimplement if needed
// if (media.type == MediaType.MOVIE) return // return if movie
//
// nextEpisodeId = media.playlist.firstOrNull { it.index > media.getEpisodeById(episodeId).index }?.mediaId
// ?: media.playlist.first().mediaId
2021-02-06 19:02:12 +01:00
}
2021-07-10 23:37:16 +02:00
// remove unneeded info from the media title before searching
private fun stripTitleInfo ( title : String ) : String {
return title . replace ( " (Sub) " , " " )
. replace ( Regex ( " -? \\ s?[0-9]+. \\ s?(Staffel|Season) " ) , " " )
. replace ( Regex ( " (Staffel|Season) \\ s?[0-9]+ " ) , " " )
. trim ( )
}
/ * * guess Season from title
* if the title ends with a number , that could be the season
* if the title ends with Regex ( " -? \\ s?[0-9]+. \\ s?(Staffel|Season) " ) or
* Regex ( " (Staffel|Season) \\ s?[0-9]+ " ) , that is the season information
* /
private fun guessSeasonFromTitle ( title : String ) : Int {
val helpTitle = title . replace ( " (Sub) " , " " ) . trim ( )
Log . d ( " test " , " helpTitle: $helpTitle " )
return if ( helpTitle . last ( ) . isDigit ( ) ) {
helpTitle . last ( ) . digitToInt ( )
} else {
Regex ( " ([0-9]+. \\ s?(Staffel|Season))|((Staffel|Season) \\ s?[0-9]+) " )
. find ( helpTitle )
?. value ?. filter { it . isDigit ( ) } ?. toInt ( ) ?: 1
}
}
2021-02-06 19:02:12 +01:00
}