add OnItemClickListener
This commit is contained in:
		| @ -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<String, String> = runBlocking { | ||||
|     private var sessionCookies = mutableMapOf<String, String>() | ||||
|     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<GUIMedia>  = runBlocking { | ||||
|     fun listAnimes(): ArrayList<GUIMedia>  = 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<GUIMedia>() | ||||
|             val animes = arrayListOf<GUIMedia>() | ||||
|             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()) | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|  | ||||
| @ -14,6 +14,8 @@ import org.mosad.teapod.util.GUIMedia | ||||
|  | ||||
| class LibraryFragment : Fragment() { | ||||
|  | ||||
|     private val parser = AoDParser() | ||||
|  | ||||
|     private var mediaList = arrayListOf<GUIMedia>() | ||||
|     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") | ||||
|     } | ||||
|  | ||||
| } | ||||
| @ -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<GUIMedia>) : | ||||
|         val imagePoster = view.findViewById<ImageView>(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 | ||||
|     } | ||||
|  | ||||
| @ -1,3 +1,3 @@ | ||||
| package org.mosad.teapod.util | ||||
|  | ||||
| data class GUIMedia(val title: String, val imageLink: String, val shortDesc : String, val link: String) | ||||
| data class GUIMedia(val title: String, val posterLink: String, val shortDesc : String, val link: String) | ||||
| @ -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"> | ||||
|  | ||||
|     <com.google.android.material.bottomnavigation.BottomNavigationView | ||||
|         android:id="@+id/nav_view" | ||||
| @ -22,7 +21,7 @@ | ||||
|         android:id="@+id/nav_host_fragment" | ||||
|         android:name="androidx.navigation.fragment.NavHostFragment" | ||||
|         android:layout_width="match_parent" | ||||
|         android:layout_height="match_parent" | ||||
|         android:layout_height="0dp" | ||||
|         app:defaultNavHost="true" | ||||
|         app:layout_constraintBottom_toTopOf="@id/nav_view" | ||||
|         app:layout_constraintLeft_toLeftOf="parent" | ||||
|  | ||||
		Reference in New Issue
	
	Block a user