made AoDParser an object
This commit is contained in:
parent
a25ec81f6b
commit
4c274eb062
|
@ -32,18 +32,11 @@ import androidx.fragment.app.commit
|
|||
import com.google.android.material.bottomnavigation.BottomNavigationView
|
||||
import kotlinx.android.synthetic.main.activity_main.*
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.mosad.teapod.parser.AoDParser
|
||||
import org.mosad.teapod.preferences.EncryptedPreferences
|
||||
import org.mosad.teapod.ui.fragments.MediaFragment
|
||||
import org.mosad.teapod.ui.fragments.AccountFragment
|
||||
import org.mosad.teapod.ui.components.LoginDialog
|
||||
import org.mosad.teapod.ui.fragments.HomeFragment
|
||||
import org.mosad.teapod.ui.fragments.LibraryFragment
|
||||
import org.mosad.teapod.ui.fragments.SearchFragment
|
||||
import org.mosad.teapod.ui.fragments.LoadingFragment
|
||||
import org.mosad.teapod.ui.fragments.*
|
||||
import org.mosad.teapod.util.StorageController
|
||||
import org.mosad.teapod.util.TMDBApiController
|
||||
import kotlin.system.measureTimeMillis
|
||||
|
@ -117,27 +110,11 @@ class MainActivity : AppCompatActivity(), BottomNavigationView.OnNavigationItemS
|
|||
showLoginDialog(true)
|
||||
} else {
|
||||
// try to login in, as most sites can only bee loaded once loged in
|
||||
if (!AoDParser().login()) showLoginDialog(false)
|
||||
if (!AoDParser.login()) showLoginDialog(false)
|
||||
}
|
||||
|
||||
StorageController.load(this)
|
||||
|
||||
// move to AoDParser
|
||||
val newEPJob = GlobalScope.async {
|
||||
AoDParser().listNewEpisodes()
|
||||
}
|
||||
|
||||
val listJob = GlobalScope.async {
|
||||
AoDParser().listAnimes() // initially load all media
|
||||
}
|
||||
|
||||
runBlocking {
|
||||
newEPJob.await()
|
||||
listJob.await()
|
||||
}
|
||||
|
||||
|
||||
// TODO load home screen, can be parallel to listAnimes
|
||||
AoDParser.initialLoading()
|
||||
}
|
||||
Log.i(javaClass.name, "login and list in $time ms")
|
||||
}
|
||||
|
@ -156,7 +133,7 @@ class MainActivity : AppCompatActivity(), BottomNavigationView.OnNavigationItemS
|
|||
}
|
||||
|
||||
// load the streams for the selected media
|
||||
val media = AoDParser().getMediaById(mediaId)
|
||||
val media = AoDParser.getMediaById(mediaId)
|
||||
val tmdb = TMDBApiController().search(media.info.title, media.type)
|
||||
|
||||
val mediaFragment = MediaFragment(media, tmdb)
|
||||
|
@ -182,7 +159,7 @@ class MainActivity : AppCompatActivity(), BottomNavigationView.OnNavigationItemS
|
|||
LoginDialog(this, firstTry).positiveButton {
|
||||
EncryptedPreferences.saveCredentials(login, password, context)
|
||||
|
||||
if (!AoDParser().login()) {
|
||||
if (!AoDParser.login()) {
|
||||
showLoginDialog(false)
|
||||
Log.w(javaClass.name, "Login failed, please try again.")
|
||||
}
|
||||
|
|
|
@ -1,3 +1,25 @@
|
|||
/**
|
||||
* Teapod
|
||||
*
|
||||
* Copyright 2020 <seil0@mosad.xyz>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.mosad.teapod.parser
|
||||
|
||||
import android.util.Log
|
||||
|
@ -13,26 +35,21 @@ import org.mosad.teapod.util.Media
|
|||
import java.io.IOException
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* maybe AoDParser as object would be useful
|
||||
*/
|
||||
class AoDParser {
|
||||
object AoDParser {
|
||||
|
||||
private val baseUrl = "https://www.anime-on-demand.de"
|
||||
private val loginPath = "/users/sign_in"
|
||||
private val libraryPath = "/animes"
|
||||
private const val baseUrl = "https://www.anime-on-demand.de"
|
||||
private const val loginPath = "/users/sign_in"
|
||||
private const val libraryPath = "/animes"
|
||||
|
||||
private val userAgent = "Mozilla/5.0 (X11; Linux x86_64; rv:80.0) Gecko/20100101 Firefox/80.0"
|
||||
private const val userAgent = "Mozilla/5.0 (X11; Linux x86_64; rv:80.0) Gecko/20100101 Firefox/80.0"
|
||||
|
||||
companion object {
|
||||
private var csrfToken: String = ""
|
||||
private var sessionCookies = mutableMapOf<String, String>()
|
||||
private var loginSuccess = false
|
||||
private var sessionCookies = mutableMapOf<String, String>()
|
||||
private var csrfToken: String = ""
|
||||
private var loginSuccess = false
|
||||
|
||||
val mediaList = arrayListOf<Media>()
|
||||
val itemMediaList = arrayListOf<ItemMedia>()
|
||||
val newEpisodesList = arrayListOf<ItemMedia>()
|
||||
}
|
||||
val mediaList = arrayListOf<Media>()
|
||||
val itemMediaList = arrayListOf<ItemMedia>()
|
||||
val newEpisodesList = arrayListOf<ItemMedia>()
|
||||
|
||||
fun login(): Boolean = runBlocking {
|
||||
|
||||
|
@ -74,9 +91,64 @@ class AoDParser {
|
|||
}
|
||||
|
||||
/**
|
||||
* list all animes from the website
|
||||
* initially load all media and home screen data
|
||||
* -> blocking
|
||||
*/
|
||||
fun listAnimes(): ArrayList<Media> = runBlocking {
|
||||
fun initialLoading() = runBlocking {
|
||||
val newEPJob = GlobalScope.async {
|
||||
listNewEpisodes()
|
||||
}
|
||||
|
||||
val listJob = GlobalScope.async {
|
||||
listAnimes()
|
||||
}
|
||||
|
||||
newEPJob.await()
|
||||
listJob.await()
|
||||
}
|
||||
|
||||
/**
|
||||
* get a media by it's ID (int)
|
||||
* @return Media
|
||||
*/
|
||||
fun getMediaById(mediaId: Int): Media {
|
||||
val media = mediaList.first { it.id == mediaId }
|
||||
|
||||
if (media.episodes.isEmpty()) {
|
||||
loadStreams(media)
|
||||
}
|
||||
|
||||
return media
|
||||
}
|
||||
|
||||
// TODO don't use jsoup here
|
||||
fun sendCallback(callbackPath: String) = GlobalScope.launch {
|
||||
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"),
|
||||
Pair("Accept-Encoding", "gzip, deflate, br"),
|
||||
Pair("X-CSRF-Token", csrfToken),
|
||||
Pair("X-Requested-With", "XMLHttpRequest"),
|
||||
)
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* load all media from aod into itemMediaList and mediaList
|
||||
*/
|
||||
private fun listAnimes() = runBlocking {
|
||||
if (sessionCookies.isEmpty()) login()
|
||||
|
||||
withContext(Dispatchers.Default) {
|
||||
|
@ -109,12 +181,13 @@ class AoDParser {
|
|||
}
|
||||
|
||||
Log.i(javaClass.name, "Total library size is: ${mediaList.size}")
|
||||
|
||||
return@withContext mediaList
|
||||
}
|
||||
}
|
||||
|
||||
fun listNewEpisodes() = runBlocking {
|
||||
/**
|
||||
* load all new episodes from AoD into newEpisodesList
|
||||
*/
|
||||
private fun listNewEpisodes() = runBlocking {
|
||||
if (sessionCookies.isEmpty()) login()
|
||||
|
||||
withContext(Dispatchers.Default) {
|
||||
|
@ -137,16 +210,6 @@ class AoDParser {
|
|||
}
|
||||
}
|
||||
|
||||
fun getMediaById(mediaId: Int): Media {
|
||||
val media = mediaList.first { it.id == mediaId }
|
||||
|
||||
if (media.episodes.isEmpty()) {
|
||||
loadStreams(media)
|
||||
}
|
||||
|
||||
return media
|
||||
}
|
||||
|
||||
/**
|
||||
* load streams for the media path, movies have one episode
|
||||
* @param media is used as call ba reference
|
||||
|
@ -283,27 +346,4 @@ class AoDParser {
|
|||
}
|
||||
}
|
||||
|
||||
fun sendCallback(callbackPath: String) = GlobalScope.launch {
|
||||
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"),
|
||||
Pair("Accept-Encoding", "gzip, deflate, br"),
|
||||
Pair("X-CSRF-Token", csrfToken),
|
||||
Pair("X-Requested-With", "XMLHttpRequest"),
|
||||
)
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@ class AccountFragment : Fragment() {
|
|||
LoginDialog(requireContext(), firstTry).positiveButton {
|
||||
EncryptedPreferences.saveCredentials(login, password, context)
|
||||
|
||||
if (!AoDParser().login()) {
|
||||
if (!AoDParser.login()) {
|
||||
showLoginDialog(false)
|
||||
Log.w(javaClass.name, "Login failed, please try again.")
|
||||
}
|
||||
|
|
|
@ -117,7 +117,7 @@ class MediaFragment(private val media: Media, private val tmdb: TMDBResponse) :
|
|||
playStream(media.episodes[position].streamUrl)
|
||||
|
||||
// update watched state
|
||||
AoDParser().sendCallback(media.episodes[position].watchedCallback)
|
||||
AoDParser.sendCallback(media.episodes[position].watchedCallback)
|
||||
adapterRecEpisodes.updateWatchedState(true, position)
|
||||
adapterRecEpisodes.notifyDataSetChanged()
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue