From c473fce19a0edf9a9323fcba2a667571eb076471 Mon Sep 17 00:00:00 2001 From: Jannik Date: Fri, 9 Oct 2020 15:18:52 +0200 Subject: [PATCH] add OnItemClickListener --- .../java/org/mosad/teapod/parser/AoDParser.kt | 100 ++++++++++++++---- .../teapod/ui/library/LibraryFragment.kt | 22 +++- .../org/mosad/teapod/util/CustomAdapter.kt | 3 +- .../java/org/mosad/teapod/util/DataTypes.kt | 2 +- app/src/main/res/layout/activity_main.xml | 5 +- 5 files changed, 101 insertions(+), 31 deletions(-) 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 335ebd1..4ddc2cf 100644 --- a/app/src/main/java/org/mosad/teapod/parser/AoDParser.kt +++ b/app/src/main/java/org/mosad/teapod/parser/AoDParser.kt @@ -1,8 +1,7 @@ package org.mosad.teapod.parser -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.runBlocking -import kotlinx.coroutines.withContext +import kotlinx.coroutines.* +import org.json.JSONObject import org.jsoup.Connection import org.jsoup.Jsoup import org.mosad.teapod.util.GUIMedia @@ -12,20 +11,20 @@ class AoDParser { private val baseURL = "https://www.anime-on-demand.de" private val loginPath = "/users/sign_in" + // TODO private val login = "" private val pwd = "" - private fun login(): MutableMap = runBlocking { + private var sessionCookies = mutableMapOf() + private var loginSuccess = false + private fun login() = runBlocking { val userAgent = "Mozilla/5.0 (X11; Linux x86_64; rv:80.0) Gecko/20100101 Firefox/80.0" withContext(Dispatchers.Default) { - val con = Jsoup.connect(baseURL) - - // get the authenticity token - val resAuth = con.url(baseURL + loginPath)//Jsoup.connect(baseURL + loginPath) + val resAuth = Jsoup.connect(baseURL + loginPath) .header("User-Agent", userAgent) .execute() @@ -52,40 +51,99 @@ class AoDParser { //println(resLogin.body()) - val loginSuccess = resLogin.body().contains("Hallo, du bist jetzt angemeldet.") + loginSuccess = resLogin.body().contains("Hallo, du bist jetzt angemeldet.") println("Status: ${resLogin.statusCode()} (${resLogin.statusMessage()}), login successful: $loginSuccess") - return@withContext resLogin.cookies() + sessionCookies = resLogin.cookies() } } // https://www.anime-on-demand.de/animes - fun listAnime(): ArrayList = runBlocking { + fun listAnimes(): ArrayList = runBlocking { + if (sessionCookies.isEmpty()) login() + withContext(Dispatchers.Default) { - val cookies = login() - - val res = Jsoup.connect("$baseURL/animes") - .cookies(cookies) + .cookies(sessionCookies) .get() //println(res) - val anime = arrayListOf() + val animes = arrayListOf() res.select("div.animebox").forEach { val media = GUIMedia( it.select("h3.animebox-title").text(), it.select("p.animebox-image").select("img").attr("src"), - it.select("p.animebox-link").select("a").attr("href"), - it.select("p.animebox-shorttext").text() + it.select("p.animebox-shorttext").text(), + it.select("p.animebox-link").select("a").attr("href") ) - anime.add(media) + animes.add(media) } - println("got ${anime.size} anime") + println("got ${animes.size} anime") - return@withContext anime + return@withContext animes + } + } + + fun loadDetails(mediaPath: String) = runBlocking { + if (sessionCookies.isEmpty()) login() + + if (!loginSuccess) { + println("please log in") + return@runBlocking + } + + withContext(Dispatchers.Default) { + println(baseURL + mediaPath) + + val res = Jsoup.connect(baseURL + mediaPath) + .cookies(sessionCookies) + .get() + + //println(res) + + val playlists = res.select("input.streamstarter_html5").eachAttr("data-playlist") + println(playlists.first()) + + val csrfToken = res.select("meta[name=csrf-token]").attr("content") + println("csrf token is: $csrfToken") + + loadStreamInfo(playlists.first(), csrfToken) + } + } + + private fun loadStreamInfo(playlistPath: String, csrfToken: String) = runBlocking { + withContext(Dispatchers.Default) { + println(baseURL + playlistPath) + + 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"), + ) + + + val res = Jsoup.connect(baseURL + playlistPath) + .ignoreContentType(true) + .cookies(sessionCookies) + .headers(headers) + .execute() + + //println(res.body()) + + // TODO replace with gson + val jsonObject = JSONObject(res.body()) + val sourcesObject = jsonObject.getJSONArray("playlist").get(0).toString() + + val sourcesArray = JSONObject(sourcesObject).getJSONArray("sources") + + for (i in 0 until sourcesArray.length()) { + println(sourcesArray[i].toString()) + } } } diff --git a/app/src/main/java/org/mosad/teapod/ui/library/LibraryFragment.kt b/app/src/main/java/org/mosad/teapod/ui/library/LibraryFragment.kt index 6e85798..2e75e3d 100644 --- a/app/src/main/java/org/mosad/teapod/ui/library/LibraryFragment.kt +++ b/app/src/main/java/org/mosad/teapod/ui/library/LibraryFragment.kt @@ -14,6 +14,8 @@ import org.mosad.teapod.util.GUIMedia class LibraryFragment : Fragment() { + private val parser = AoDParser() + private var mediaList = arrayListOf() private lateinit var adapter : CustomAdapter @@ -24,19 +26,31 @@ class LibraryFragment : Fragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - GlobalScope.launch { - val parser = AoDParser() - mediaList = parser.listAnime() + mediaList = parser.listAnimes() // create and set the adapter, needs context withContext(Dispatchers.Main) { - adapter = CustomAdapter(requireContext(), mediaList)//ArrayAdapter(requireContext(), R.layout.linear_media, R.id.text_title, mediaList) + adapter = CustomAdapter(requireContext(), mediaList) list_library.adapter = adapter //adapter.notifyDataSetChanged() } + } + initActions() + } + + private fun initActions() { + list_library.setOnItemClickListener { parent, view, position, id -> + println("selected item is: ${mediaList[position]}") + showDetailFragment(mediaList[position]) } } + private fun showDetailFragment(media: GUIMedia) { + parser.loadDetails(media.link) + + println("done") + } + } \ No newline at end of file diff --git a/app/src/main/java/org/mosad/teapod/util/CustomAdapter.kt b/app/src/main/java/org/mosad/teapod/util/CustomAdapter.kt index 0872be8..4bb50df 100644 --- a/app/src/main/java/org/mosad/teapod/util/CustomAdapter.kt +++ b/app/src/main/java/org/mosad/teapod/util/CustomAdapter.kt @@ -7,7 +7,6 @@ import android.view.ViewGroup import android.widget.ArrayAdapter import android.widget.ImageView import android.widget.TextView -import androidx.recyclerview.widget.RecyclerView import com.bumptech.glide.Glide import org.mosad.teapod.R @@ -20,7 +19,7 @@ class CustomAdapter(context: Context, private val media: ArrayList) : val imagePoster = view.findViewById(R.id.image_poster) textTitle.text = media[position].title - Glide.with(context).load(media[position].imageLink).into(imagePoster) + Glide.with(context).load(media[position].posterLink).into(imagePoster) return view } diff --git a/app/src/main/java/org/mosad/teapod/util/DataTypes.kt b/app/src/main/java/org/mosad/teapod/util/DataTypes.kt index 58f7683..bbbc393 100644 --- a/app/src/main/java/org/mosad/teapod/util/DataTypes.kt +++ b/app/src/main/java/org/mosad/teapod/util/DataTypes.kt @@ -1,3 +1,3 @@ package org.mosad.teapod.util -data class GUIMedia(val title: String, val imageLink: String, val shortDesc : String, val link: String) \ No newline at end of file +data class GUIMedia(val title: String, val posterLink: String, val shortDesc : String, val link: String) \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 38c0aa8..750eb39 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -3,8 +3,7 @@ xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/container" android:layout_width="match_parent" - android:layout_height="match_parent" - android:paddingTop="?attr/actionBarSize"> + android:layout_height="match_parent">