add tv shows support to parser, start implementing account fragment
This commit is contained in:
@ -79,7 +79,7 @@ class MainActivity : AppCompatActivity(), BottomNavigationView.OnNavigationItemS
|
||||
Log.i(javaClass.name, "please login!")
|
||||
|
||||
LoginDialog(this).positiveButton {
|
||||
EncryptedPreferences.saveCredentials(email, password, context)
|
||||
EncryptedPreferences.saveCredentials(login, password, context)
|
||||
}.negativeButton {
|
||||
Log.i(javaClass.name, "Login canceled, exiting.")
|
||||
finish()
|
||||
@ -88,17 +88,14 @@ class MainActivity : AppCompatActivity(), BottomNavigationView.OnNavigationItemS
|
||||
}
|
||||
|
||||
fun showDetailFragment(media: GUIMedia) {
|
||||
val streams = AoDParser().loadStreams(media.link) // load the streams for the selected media
|
||||
val streamMedia = AoDParser().loadStreams(media.link) // load the streams for the selected media
|
||||
|
||||
val mediaFragment = MediaFragment(media, streams)
|
||||
val mediaFragment = MediaFragment(media, streamMedia)
|
||||
supportFragmentManager.commit {
|
||||
add(R.id.nav_host_fragment, mediaFragment, "MediaFragment")
|
||||
addToBackStack(null)
|
||||
show(mediaFragment)
|
||||
}
|
||||
|
||||
println("visible !!!: " + mediaFragment.isVisible)
|
||||
println(supportFragmentManager.backStackEntryCount)
|
||||
}
|
||||
|
||||
fun startPlayer(streamUrl: String) {
|
||||
|
@ -1,11 +1,15 @@
|
||||
package org.mosad.teapod.parser
|
||||
|
||||
import android.util.Log
|
||||
import com.google.gson.JsonParser
|
||||
import kotlinx.coroutines.*
|
||||
import org.jsoup.Connection
|
||||
import org.jsoup.Jsoup
|
||||
import org.mosad.teapod.preferences.EncryptedPreferences
|
||||
import org.mosad.teapod.util.DataTypes.MediaType
|
||||
import org.mosad.teapod.util.GUIMedia
|
||||
import org.mosad.teapod.util.StreamMedia
|
||||
import kotlin.collections.ArrayList
|
||||
|
||||
class AoDParser {
|
||||
|
||||
@ -60,7 +64,9 @@ class AoDParser {
|
||||
}
|
||||
}
|
||||
|
||||
// https://www.anime-on-demand.de/animes
|
||||
/**
|
||||
* list all animes from the website
|
||||
*/
|
||||
fun listAnimes(): ArrayList<GUIMedia> = runBlocking {
|
||||
if (sessionCookies.isEmpty()) login()
|
||||
|
||||
@ -92,12 +98,12 @@ class AoDParser {
|
||||
/**
|
||||
* load streams for the media path
|
||||
*/
|
||||
fun loadStreams(mediaPath: String): List<String> = runBlocking {
|
||||
fun loadStreams(mediaPath: String): StreamMedia = runBlocking {
|
||||
if (sessionCookies.isEmpty()) login()
|
||||
|
||||
if (!loginSuccess) {
|
||||
println("please log in") // TODO
|
||||
return@runBlocking listOf()
|
||||
return@runBlocking StreamMedia(MediaType.OTHER)
|
||||
}
|
||||
|
||||
withContext(Dispatchers.Default) {
|
||||
@ -114,14 +120,20 @@ class AoDParser {
|
||||
//println("first entry: ${playlists.first()}")
|
||||
//println("csrf token is: $csrfToken")
|
||||
|
||||
return@withContext loadStreamInfo(playlists.first(), csrfToken)
|
||||
val type = if (res.select("h2").eachText().filter { it == "Episoden" }.any()) {
|
||||
MediaType.TVSHOW
|
||||
} else {
|
||||
MediaType.MOVIE
|
||||
}
|
||||
|
||||
return@withContext loadStreamInfo(playlists.first(), csrfToken, type)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* load the playlist path and parse it, read the stream info from json
|
||||
*/
|
||||
private fun loadStreamInfo(playlistPath: String, csrfToken: String): List<String> = runBlocking {
|
||||
private fun loadStreamInfo(playlistPath: String, csrfToken: String, type: MediaType): StreamMedia = runBlocking {
|
||||
withContext(Dispatchers.Default) {
|
||||
val headers = mutableMapOf(
|
||||
Pair("Accept", "application/json, text/javascript, */*; q=0.01"),
|
||||
@ -139,13 +151,37 @@ class AoDParser {
|
||||
|
||||
//println(res.body())
|
||||
|
||||
// TODO if it's a series there sources for each episode
|
||||
val sources = JsonParser.parseString(res.body()).asJsonObject
|
||||
.get("playlist").asJsonArray.first().asJsonObject
|
||||
.get("sources").asJsonArray
|
||||
println(type)
|
||||
return@withContext when (type) {
|
||||
MediaType.MOVIE -> {
|
||||
val movie = JsonParser.parseString(res.body()).asJsonObject
|
||||
.get("playlist").asJsonArray
|
||||
|
||||
return@withContext sources.toList().map {
|
||||
it.asJsonObject.get("file").asString
|
||||
val streamList = arrayListOf<String>()
|
||||
movie.first().asJsonObject.get("sources").asJsonArray.toList().forEach {
|
||||
streamList.add(it.asJsonObject.get("file").asString)
|
||||
}
|
||||
|
||||
StreamMedia(MediaType.MOVIE, streamList)
|
||||
}
|
||||
MediaType.TVSHOW -> {
|
||||
val episodes = JsonParser.parseString(res.body()).asJsonObject
|
||||
.get("playlist").asJsonArray
|
||||
|
||||
val streamList = arrayListOf<String>()
|
||||
episodes.forEach {
|
||||
val streamUrl = it.asJsonObject.get("sources").asJsonArray
|
||||
.first().asJsonObject
|
||||
.get("file").asString
|
||||
streamList.add(streamUrl)
|
||||
}
|
||||
|
||||
StreamMedia(MediaType.TVSHOW, streamList)
|
||||
}
|
||||
else -> {
|
||||
Log.e(javaClass.name, "Wrong Type, please report this issue.")
|
||||
StreamMedia(MediaType.OTHER)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,19 +1,23 @@
|
||||
package org.mosad.teapod.ui
|
||||
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import androidx.fragment.app.Fragment
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ArrayAdapter
|
||||
import com.bumptech.glide.Glide
|
||||
import kotlinx.android.synthetic.main.fragment_media.*
|
||||
import org.mosad.teapod.MainActivity
|
||||
import org.mosad.teapod.R
|
||||
import org.mosad.teapod.util.DataTypes.MediaType
|
||||
import org.mosad.teapod.util.GUIMedia
|
||||
import java.net.URL
|
||||
import java.net.URLEncoder
|
||||
import org.mosad.teapod.util.StreamMedia
|
||||
|
||||
class MediaFragment(val media: GUIMedia, val streams: List<String>) : Fragment() {
|
||||
class MediaFragment(private val guiMedia: GUIMedia, private val streamMedia: StreamMedia) : Fragment() {
|
||||
|
||||
private lateinit var adapterEpisodes: ArrayAdapter<String>
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
return inflater.inflate(R.layout.fragment_media, container, false)
|
||||
@ -22,25 +26,51 @@ class MediaFragment(val media: GUIMedia, val streams: List<String>) : Fragment()
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
// load poster
|
||||
Glide.with(requireContext()).load(media.posterLink).into(image_poster)
|
||||
text_title.text = media.title
|
||||
text_desc.text = media.shortDesc
|
||||
// generic gui
|
||||
Glide.with(requireContext()).load(guiMedia.posterLink).into(image_poster)
|
||||
text_title.text = guiMedia.title
|
||||
text_desc.text = guiMedia.shortDesc
|
||||
|
||||
println("media streams: $streams")
|
||||
// specific gui
|
||||
if (streamMedia.type == MediaType.TVSHOW) {
|
||||
val episodes = streamMedia.streams.mapIndexed { index, _ ->
|
||||
"${guiMedia.title} - Ep. ${index + 1}"
|
||||
}
|
||||
|
||||
adapterEpisodes = ArrayAdapter(requireContext(), android.R.layout.simple_list_item_1, episodes)
|
||||
list_episodes.adapter = adapterEpisodes
|
||||
|
||||
} else if (streamMedia.type == MediaType.MOVIE) {
|
||||
list_episodes.visibility = View.GONE
|
||||
}
|
||||
|
||||
|
||||
println("media streams: ${streamMedia.streams}")
|
||||
|
||||
initActions()
|
||||
}
|
||||
|
||||
private fun initActions() {
|
||||
button_play.setOnClickListener { onClickButtonPlay() }
|
||||
button_play.setOnClickListener {
|
||||
onClickButtonPlay()
|
||||
}
|
||||
|
||||
list_episodes.setOnItemClickListener { _, _, position, _ ->
|
||||
playStream(streamMedia.streams[position])
|
||||
}
|
||||
}
|
||||
|
||||
private fun onClickButtonPlay() {
|
||||
println("play ${streams.first()}")
|
||||
when (streamMedia.type) {
|
||||
MediaType.MOVIE -> playStream(streamMedia.streams.first())
|
||||
MediaType.TVSHOW -> playStream(streamMedia.streams.first())
|
||||
MediaType.OTHER -> Log.e(javaClass.name, "Wrong Type, please report this issue.")
|
||||
}
|
||||
}
|
||||
|
||||
private fun playStream(url: String) {
|
||||
val mainActivity = activity as MainActivity
|
||||
mainActivity.startPlayer(streams.first())
|
||||
mainActivity.startPlayer(url)
|
||||
}
|
||||
|
||||
}
|
@ -5,8 +5,12 @@ import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.Fragment
|
||||
import com.afollestad.materialdialogs.MaterialDialog
|
||||
import kotlinx.android.synthetic.main.fragment_account.*
|
||||
import org.mosad.teapod.BuildConfig
|
||||
import org.mosad.teapod.R
|
||||
import org.mosad.teapod.preferences.EncryptedPreferences
|
||||
import org.mosad.teapod.ui.components.LoginDialog
|
||||
|
||||
class AccountFragment : Fragment() {
|
||||
|
||||
@ -17,6 +21,27 @@ class AccountFragment : Fragment() {
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
text_account.text = "This is the Account Fragment"
|
||||
text_account_login.text = EncryptedPreferences.login
|
||||
text_info_about_desc.text = getString(R.string.info_about_desc, BuildConfig.VERSION_NAME, getString(R.string.build_time))
|
||||
|
||||
initActions()
|
||||
}
|
||||
|
||||
private fun initActions() {
|
||||
linear_account_login.setOnClickListener {
|
||||
LoginDialog(requireContext()).positiveButton {
|
||||
EncryptedPreferences.saveCredentials(login, password, context)
|
||||
}.show {
|
||||
login = EncryptedPreferences.login
|
||||
password = ""
|
||||
}
|
||||
}
|
||||
|
||||
linear_about.setOnClickListener {
|
||||
MaterialDialog(requireContext())
|
||||
.title(R.string.info_about)
|
||||
.message(R.string.info_about_dialog)
|
||||
.show()
|
||||
}
|
||||
}
|
||||
}
|
@ -25,8 +25,6 @@ package org.mosad.teapod.ui.components
|
||||
import android.content.Context
|
||||
import android.widget.EditText
|
||||
import com.afollestad.materialdialogs.MaterialDialog
|
||||
import com.afollestad.materialdialogs.WhichButton
|
||||
import com.afollestad.materialdialogs.actions.getActionButton
|
||||
import com.afollestad.materialdialogs.bottomsheets.BottomSheet
|
||||
import com.afollestad.materialdialogs.bottomsheets.setPeekHeight
|
||||
import com.afollestad.materialdialogs.customview.customView
|
||||
@ -40,7 +38,7 @@ class LoginDialog(val context: Context) {
|
||||
private val editTextLogin: EditText
|
||||
private val editTextPassword: EditText
|
||||
|
||||
var email = ""
|
||||
var login = ""
|
||||
var password = ""
|
||||
|
||||
init {
|
||||
@ -61,7 +59,7 @@ class LoginDialog(val context: Context) {
|
||||
|
||||
fun positiveButton(func: LoginDialog.() -> Unit): LoginDialog = apply {
|
||||
dialog.positiveButton {
|
||||
email = editTextLogin.text.toString()
|
||||
login = editTextLogin.text.toString()
|
||||
password = editTextPassword.text.toString()
|
||||
|
||||
func()
|
||||
@ -81,7 +79,7 @@ class LoginDialog(val context: Context) {
|
||||
fun show(func: LoginDialog.() -> Unit): LoginDialog = apply {
|
||||
func()
|
||||
|
||||
editTextLogin.setText(email)
|
||||
editTextLogin.setText(login)
|
||||
editTextPassword.setText(password)
|
||||
|
||||
show()
|
||||
|
@ -19,7 +19,5 @@ class HomeFragment : Fragment() {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
text_home.text = "This is the home fragment"
|
||||
|
||||
println("HomeFragment created")
|
||||
}
|
||||
}
|
@ -48,10 +48,8 @@ class SearchFragment : Fragment() {
|
||||
}
|
||||
|
||||
override fun onQueryTextChange(newText: String?): Boolean {
|
||||
println("new text is: $newText")
|
||||
adapter.filter.filter(newText)
|
||||
adapter.notifyDataSetChanged()
|
||||
|
||||
return false
|
||||
}
|
||||
})
|
||||
|
@ -20,10 +20,6 @@ class CustomAdapter(val context: Context, private val originalMedia: ArrayList<G
|
||||
private var filteredMedia = originalMedia.map { it.copy() }
|
||||
private val customFilter = CustomFilter()
|
||||
|
||||
init {
|
||||
println("initial filtered size is: ${filteredMedia.size}")
|
||||
}
|
||||
|
||||
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
|
||||
val view = convertView ?: LayoutInflater.from(context).inflate(R.layout.linear_media, parent, false)
|
||||
|
||||
@ -68,8 +64,6 @@ class CustomAdapter(val context: Context, private val originalMedia: ArrayList<G
|
||||
results.values = filteredList
|
||||
results.count = filteredList.size
|
||||
|
||||
println("filtered size is: ${results.count}")
|
||||
|
||||
return results
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,17 @@
|
||||
package org.mosad.teapod.util
|
||||
|
||||
class DataTypes {
|
||||
enum class MediaType {
|
||||
OTHER,
|
||||
MOVIE,
|
||||
TVSHOW
|
||||
}
|
||||
}
|
||||
|
||||
data class GUIMedia(val title: String, val posterLink: String, val shortDesc : String, val link: String) {
|
||||
override fun toString(): String {
|
||||
return title
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data class StreamMedia(val type: DataTypes.MediaType, val streams: ArrayList<String> = arrayListOf())
|
Reference in New Issue
Block a user