use suspending functions for coroutines when possible

* fix crash, when media is selected, but MediaFragment is removed before AoDParser could load data
This commit is contained in:
Jannik 2020-11-27 11:06:16 +01:00
parent bb8c8ca85a
commit d01e87bf14
Signed by: Seil0
GPG Key ID: E8459F3723C52C24
4 changed files with 102 additions and 109 deletions

View File

@ -110,18 +110,18 @@ object AoDParser {
* get a media by it's ID (int)
* @return Media
*/
fun getMediaById(mediaId: Int): Media {
suspend fun getMediaById(mediaId: Int): Media {
val media = mediaList.first { it.id == mediaId }
if (media.episodes.isEmpty()) {
loadStreams(media)
loadStreams(media).join()
}
return media
}
// TODO don't use jsoup here
fun sendCallback(callbackPath: String) = GlobalScope.launch {
fun sendCallback(callbackPath: String) = GlobalScope.launch(Dispatchers.IO) {
val headers = mutableMapOf(
Pair("Accept", "application/json, text/javascript, */*; q=0.01"),
Pair("Accept-Language", "de,en-US;q=0.7,en;q=0.3"),
@ -131,13 +131,11 @@ object AoDParser {
)
try {
withContext(Dispatchers.IO) {
Jsoup.connect(baseUrl + callbackPath)
.ignoreContentType(true)
.cookies(sessionCookies)
.headers(headers)
.execute()
}
} catch (ex: IOException) {
Log.e(javaClass.name, "Callback for $callbackPath failed.", ex)
}
@ -213,16 +211,14 @@ object AoDParser {
* load streams for the media path, movies have one episode
* @param media is used as call ba reference
*/
private fun loadStreams(media: Media) = runBlocking {
private suspend fun loadStreams(media: Media) = GlobalScope.launch(Dispatchers.IO) {
if (sessionCookies.isEmpty()) login()
if (!loginSuccess) {
Log.w(javaClass.name, "Login, was not successful.")
return@runBlocking
return@launch
}
withContext(Dispatchers.Default) {
// get the media page
val res = Jsoup.connect(baseUrl + media.link)
.cookies(sessionCookies)
@ -300,7 +296,7 @@ object AoDParser {
"episodenanzahl" -> {
media.info.episodesCount = row.select("td").text()
.substringBefore("/")
.filter{ it.isDigit() }
.filter { it.isDigit() }
.toInt()
}
}
@ -324,8 +320,6 @@ object AoDParser {
}
}
}
}
}
/**
@ -336,7 +330,7 @@ object AoDParser {
return CompletableDeferred(AoDObject(listOf()))
}
return GlobalScope.async {
return GlobalScope.async(Dispatchers.IO) {
val headers = mutableMapOf(
Pair("Accept", "application/json, text/javascript, */*; q=0.01"),
Pair("Accept-Language", "de,en-US;q=0.7,en;q=0.3"),

View File

@ -1,6 +1,7 @@
package org.mosad.teapod.player
import androidx.lifecycle.ViewModel
import kotlinx.coroutines.runBlocking
import org.mosad.teapod.parser.AoDParser
import org.mosad.teapod.ui.fragments.MediaFragment
import org.mosad.teapod.util.DataTypes
@ -25,7 +26,10 @@ class PlayerViewModel : ViewModel() {
mediaId = iMediaId
episodeId = iEpisodeId
runBlocking {
media = AoDParser.getMediaById(mediaId)
}
currentEpisode = media.episodes.first { it.id == episodeId }
nextEpisode = selectNextEpisode()
}

View File

@ -49,12 +49,12 @@ class MediaFragment(private val mediaId: Int) : Fragment() {
super.onViewCreated(view, savedInstanceState)
binding.frameLoading.visibility = View.VISIBLE
GlobalScope.launch {
GlobalScope.launch(Dispatchers.Main) {
// load the streams for the selected media
media = AoDParser.getMediaById(mediaId)
tmdb = TMDBApiController().search(media.info.title, media.type)
withContext(Dispatchers.Main) {
if (this@MediaFragment.isAdded) {
updateGUI()
initActions()
}

View File

@ -3,9 +3,7 @@ package org.mosad.teapod.util
import android.util.Log
import com.google.gson.JsonObject
import com.google.gson.JsonParser
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.async
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.*
import java.net.URL
import java.net.URLEncoder
import org.mosad.teapod.util.DataTypes.MediaType
@ -22,12 +20,12 @@ class TMDBApiController {
private val imageUrl = "https://image.tmdb.org/t/p/w500"
fun search(title: String, type: MediaType): TMDBResponse {
suspend fun search(title: String, type: MediaType): TMDBResponse {
val searchTerm = title.replace("(Sub)", "").trim()
return when (type) {
MediaType.MOVIE -> searchMovie(searchTerm)
MediaType.TVSHOW -> searchTVShow(searchTerm)
MediaType.MOVIE -> searchMovie(searchTerm).await()
MediaType.TVSHOW -> searchTVShow(searchTerm).await()
else -> {
Log.e(javaClass.name, "Wrong Type: $type")
TMDBResponse()
@ -36,17 +34,17 @@ class TMDBApiController {
}
fun searchTVShow(title: String) = runBlocking {
fun searchTVShow(title: String): Deferred<TMDBResponse> {
val url = URL("$searchTVUrl$preparedParameters&query=${URLEncoder.encode(title, "UTF-8")}")
GlobalScope.async {
return GlobalScope.async {
val response = JsonParser.parseString(url.readText()).asJsonObject
//println(response)
return@async if (response.get("total_results").asInt > 0) {
if (response.get("total_results").asInt > 0) {
response.get("results").asJsonArray.first().asJsonObject.let {
val id = getStringNotNull(it,"id").toInt()
val overview = getStringNotNull(it,"overview")
val id = getStringNotNull(it, "id").toInt()
val overview = getStringNotNull(it, "overview")
val posterPath = getStringNotNullPrefix(it, "poster_path", imageUrl)
val backdropPath = getStringNotNullPrefix(it, "backdrop_path", imageUrl)
@ -55,18 +53,17 @@ class TMDBApiController {
} else {
TMDBResponse()
}
}.await()
}
}
fun searchMovie(title: String) = runBlocking {
fun searchMovie(title: String): Deferred<TMDBResponse> {
val url = URL("$searchMovieUrl$preparedParameters&query=${URLEncoder.encode(title, "UTF-8")}")
GlobalScope.async {
return GlobalScope.async {
val response = JsonParser.parseString(url.readText()).asJsonObject
//println(response)
return@async if (response.get("total_results").asInt > 0) {
if (response.get("total_results").asInt > 0) {
response.get("results").asJsonArray.first().asJsonObject.let {
val id = getStringNotNull(it,"id").toInt()
val overview = getStringNotNull(it,"overview")
@ -79,9 +76,7 @@ class TMDBApiController {
} else {
TMDBResponse()
}
}.await()
}
}
/**