From 4c274eb0624c93cc1abd457e55e266bfe9e1c2a5 Mon Sep 17 00:00:00 2001 From: Jannik Date: Mon, 19 Oct 2020 19:59:53 +0200 Subject: [PATCH] made AoDParser an object --- .../java/org/mosad/teapod/MainActivity.kt | 33 +--- .../java/org/mosad/teapod/parser/AoDParser.kt | 148 +++++++++++------- .../teapod/ui/fragments/AccountFragment.kt | 2 +- .../teapod/ui/fragments/MediaFragment.kt | 2 +- 4 files changed, 101 insertions(+), 84 deletions(-) diff --git a/app/src/main/java/org/mosad/teapod/MainActivity.kt b/app/src/main/java/org/mosad/teapod/MainActivity.kt index c9dd3a7..efc049f 100644 --- a/app/src/main/java/org/mosad/teapod/MainActivity.kt +++ b/app/src/main/java/org/mosad/teapod/MainActivity.kt @@ -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.") } diff --git a/app/src/main/java/org/mosad/teapod/parser/AoDParser.kt b/app/src/main/java/org/mosad/teapod/parser/AoDParser.kt index 7028848..f9b5644 100644 --- a/app/src/main/java/org/mosad/teapod/parser/AoDParser.kt +++ b/app/src/main/java/org/mosad/teapod/parser/AoDParser.kt @@ -1,3 +1,25 @@ +/** + * Teapod + * + * Copyright 2020 + * + * 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() - private var loginSuccess = false + private var sessionCookies = mutableMapOf() + private var csrfToken: String = "" + private var loginSuccess = false - val mediaList = arrayListOf() - val itemMediaList = arrayListOf() - val newEpisodesList = arrayListOf() - } + val mediaList = arrayListOf() + val itemMediaList = arrayListOf() + val newEpisodesList = arrayListOf() 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 = 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) - } - - } - } diff --git a/app/src/main/java/org/mosad/teapod/ui/fragments/AccountFragment.kt b/app/src/main/java/org/mosad/teapod/ui/fragments/AccountFragment.kt index 8441302..da90bb6 100644 --- a/app/src/main/java/org/mosad/teapod/ui/fragments/AccountFragment.kt +++ b/app/src/main/java/org/mosad/teapod/ui/fragments/AccountFragment.kt @@ -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.") } diff --git a/app/src/main/java/org/mosad/teapod/ui/fragments/MediaFragment.kt b/app/src/main/java/org/mosad/teapod/ui/fragments/MediaFragment.kt index b6622b3..26ee7bb 100644 --- a/app/src/main/java/org/mosad/teapod/ui/fragments/MediaFragment.kt +++ b/app/src/main/java/org/mosad/teapod/ui/fragments/MediaFragment.kt @@ -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() }