disable action bar, use tmdb for poster and description
This commit is contained in:
parent
ae20e74702
commit
90fe084557
|
@ -18,6 +18,7 @@ import org.mosad.teapod.ui.home.HomeFragment
|
||||||
import org.mosad.teapod.ui.library.LibraryFragment
|
import org.mosad.teapod.ui.library.LibraryFragment
|
||||||
import org.mosad.teapod.ui.search.SearchFragment
|
import org.mosad.teapod.ui.search.SearchFragment
|
||||||
import org.mosad.teapod.util.Media
|
import org.mosad.teapod.util.Media
|
||||||
|
import org.mosad.teapod.util.TMDBApiController
|
||||||
|
|
||||||
class MainActivity : AppCompatActivity(), BottomNavigationView.OnNavigationItemSelectedListener {
|
class MainActivity : AppCompatActivity(), BottomNavigationView.OnNavigationItemSelectedListener {
|
||||||
|
|
||||||
|
@ -90,7 +91,9 @@ class MainActivity : AppCompatActivity(), BottomNavigationView.OnNavigationItemS
|
||||||
fun showDetailFragment(media: Media) {
|
fun showDetailFragment(media: Media) {
|
||||||
media.episodes = AoDParser().loadStreams(media) // load the streams for the selected media
|
media.episodes = AoDParser().loadStreams(media) // load the streams for the selected media
|
||||||
|
|
||||||
val mediaFragment = MediaFragment(media)
|
val tmdb = TMDBApiController().search(media.title, media.type)
|
||||||
|
|
||||||
|
val mediaFragment = MediaFragment(media, tmdb)
|
||||||
supportFragmentManager.commit {
|
supportFragmentManager.commit {
|
||||||
add(R.id.nav_host_fragment, mediaFragment, "MediaFragment")
|
add(R.id.nav_host_fragment, mediaFragment, "MediaFragment")
|
||||||
addToBackStack(null)
|
addToBackStack(null)
|
||||||
|
|
|
@ -14,7 +14,7 @@ import kotlin.collections.ArrayList
|
||||||
|
|
||||||
class AoDParser {
|
class AoDParser {
|
||||||
|
|
||||||
private val baseURL = "https://www.anime-on-demand.de"
|
private val baseUrl = "https://www.anime-on-demand.de"
|
||||||
private val loginPath = "/users/sign_in"
|
private val loginPath = "/users/sign_in"
|
||||||
private val libraryPath = "/animes"
|
private val libraryPath = "/animes"
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ class AoDParser {
|
||||||
|
|
||||||
withContext(Dispatchers.Default) {
|
withContext(Dispatchers.Default) {
|
||||||
// get the authenticity token
|
// get the authenticity token
|
||||||
val resAuth = Jsoup.connect(baseURL + loginPath)
|
val resAuth = Jsoup.connect(baseUrl + loginPath)
|
||||||
.header("User-Agent", userAgent)
|
.header("User-Agent", userAgent)
|
||||||
.execute()
|
.execute()
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@ class AoDParser {
|
||||||
Pair("authenticity_token", authenticityToken)
|
Pair("authenticity_token", authenticityToken)
|
||||||
)
|
)
|
||||||
|
|
||||||
val resLogin = Jsoup.connect(baseURL + loginPath)
|
val resLogin = Jsoup.connect(baseUrl + loginPath)
|
||||||
.method(Connection.Method.POST)
|
.method(Connection.Method.POST)
|
||||||
.data(data)
|
.data(data)
|
||||||
.postDataCharset("UTF-8")
|
.postDataCharset("UTF-8")
|
||||||
|
@ -72,7 +72,7 @@ class AoDParser {
|
||||||
if (sessionCookies.isEmpty()) login()
|
if (sessionCookies.isEmpty()) login()
|
||||||
|
|
||||||
withContext(Dispatchers.Default) {
|
withContext(Dispatchers.Default) {
|
||||||
val resAnimes = Jsoup.connect(baseURL + libraryPath)
|
val resAnimes = Jsoup.connect(baseUrl + libraryPath)
|
||||||
.cookies(sessionCookies)
|
.cookies(sessionCookies)
|
||||||
.get()
|
.get()
|
||||||
|
|
||||||
|
@ -115,7 +115,7 @@ class AoDParser {
|
||||||
|
|
||||||
withContext(Dispatchers.Default) {
|
withContext(Dispatchers.Default) {
|
||||||
|
|
||||||
val res = Jsoup.connect(baseURL + media.link)
|
val res = Jsoup.connect(baseUrl + media.link)
|
||||||
.cookies(sessionCookies)
|
.cookies(sessionCookies)
|
||||||
.get()
|
.get()
|
||||||
|
|
||||||
|
@ -144,7 +144,7 @@ class AoDParser {
|
||||||
Pair("X-Requested-With", "XMLHttpRequest"),
|
Pair("X-Requested-With", "XMLHttpRequest"),
|
||||||
)
|
)
|
||||||
|
|
||||||
val res = Jsoup.connect(baseURL + playlistPath)
|
val res = Jsoup.connect(baseUrl + playlistPath)
|
||||||
.ignoreContentType(true)
|
.ignoreContentType(true)
|
||||||
.cookies(sessionCookies)
|
.cookies(sessionCookies)
|
||||||
.headers(headers)
|
.headers(headers)
|
||||||
|
|
|
@ -15,8 +15,9 @@ import org.mosad.teapod.R
|
||||||
import org.mosad.teapod.util.DataTypes.MediaType
|
import org.mosad.teapod.util.DataTypes.MediaType
|
||||||
import org.mosad.teapod.util.EpisodesAdapter
|
import org.mosad.teapod.util.EpisodesAdapter
|
||||||
import org.mosad.teapod.util.Media
|
import org.mosad.teapod.util.Media
|
||||||
|
import org.mosad.teapod.util.TMDBResponse
|
||||||
|
|
||||||
class MediaFragment(private val media: Media) : Fragment() {
|
class MediaFragment(private val media: Media, private val tmdb: TMDBResponse) : Fragment() {
|
||||||
|
|
||||||
private lateinit var adapterRecEpisodes: EpisodesAdapter
|
private lateinit var adapterRecEpisodes: EpisodesAdapter
|
||||||
private lateinit var viewManager: RecyclerView.LayoutManager
|
private lateinit var viewManager: RecyclerView.LayoutManager
|
||||||
|
@ -30,13 +31,20 @@ class MediaFragment(private val media: Media) : Fragment() {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
// generic gui
|
// generic gui
|
||||||
Glide.with(requireContext()).load(media.posterLink).into(image_poster)
|
|
||||||
text_title.text = media.title
|
text_title.text = media.title
|
||||||
text_desc.text = media.shortDesc
|
|
||||||
|
if (tmdb.posterUrl.isNotEmpty()) {
|
||||||
|
Glide.with(requireContext()).load(tmdb.posterUrl).into(image_poster)
|
||||||
|
text_desc.text = tmdb.overview
|
||||||
|
Log.d(javaClass.name, "TMDB data present")
|
||||||
|
} else {
|
||||||
|
Glide.with(requireContext()).load(media.posterLink).into(image_poster)
|
||||||
|
text_desc.text = media.shortDesc
|
||||||
|
Log.d(javaClass.name, "No TMDB data present, using Aod")
|
||||||
|
}
|
||||||
|
|
||||||
// specific gui
|
// specific gui
|
||||||
if (media.type == MediaType.TVSHOW) {
|
if (media.type == MediaType.TVSHOW) {
|
||||||
// TODO
|
|
||||||
val episodeTitles = media.episodes.map { it.title }
|
val episodeTitles = media.episodes.map { it.title }
|
||||||
|
|
||||||
adapterRecEpisodes = EpisodesAdapter(episodeTitles)
|
adapterRecEpisodes = EpisodesAdapter(episodeTitles)
|
||||||
|
|
|
@ -31,8 +31,10 @@ class LibraryFragment : Fragment() {
|
||||||
|
|
||||||
// create and set the adapter, needs context
|
// create and set the adapter, needs context
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
adapter = CustomAdapter(requireContext(), AoDParser.mediaList)
|
context?.let {
|
||||||
list_library.adapter = adapter
|
adapter = CustomAdapter(it, AoDParser.mediaList)
|
||||||
|
list_library.adapter = adapter
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@ import org.mosad.teapod.util.Media
|
||||||
|
|
||||||
class SearchFragment : Fragment() {
|
class SearchFragment : Fragment() {
|
||||||
|
|
||||||
|
private val instance = this
|
||||||
private lateinit var adapter : CustomAdapter
|
private lateinit var adapter : CustomAdapter
|
||||||
|
|
||||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||||
|
@ -32,13 +33,14 @@ class SearchFragment : Fragment() {
|
||||||
|
|
||||||
// create and set the adapter, needs context
|
// create and set the adapter, needs context
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
adapter = CustomAdapter(requireContext(), AoDParser.mediaList)
|
context?.let {
|
||||||
list_search.adapter = adapter
|
adapter = CustomAdapter(it, AoDParser.mediaList)
|
||||||
//adapter.notifyDataSetChanged()
|
list_search.adapter = adapter
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
initActions()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
initActions()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun initActions() {
|
private fun initActions() {
|
||||||
|
|
|
@ -14,4 +14,6 @@ data class Media(val title: String, val link: String, val type: DataTypes.MediaT
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data class Episode(val title: String = "", val streamUrl: String = "", var watched: Boolean = false)
|
data class Episode(val title: String = "", val streamUrl: String = "", val posterLink: String = "", var watched: Boolean = false)
|
||||||
|
|
||||||
|
data class TMDBResponse(val title: String = "", val overview: String = "", val posterUrl: String = "", val backdropUrl: String = "")
|
||||||
|
|
|
@ -0,0 +1,88 @@
|
||||||
|
package org.mosad.teapod.util
|
||||||
|
|
||||||
|
import android.util.Log
|
||||||
|
import com.google.gson.JsonParser
|
||||||
|
import kotlinx.coroutines.GlobalScope
|
||||||
|
import kotlinx.coroutines.async
|
||||||
|
import kotlinx.coroutines.runBlocking
|
||||||
|
import java.net.URL
|
||||||
|
import java.net.URLEncoder
|
||||||
|
import org.mosad.teapod.util.DataTypes.MediaType
|
||||||
|
|
||||||
|
class TMDBApiController {
|
||||||
|
|
||||||
|
private val apiUrl = "https://api.themoviedb.org/3"
|
||||||
|
private val searchMovieUrl = "$apiUrl/search/movie"
|
||||||
|
private val searchTVUrl = "$apiUrl/search/tv"
|
||||||
|
private val apiKey = "de959cf9c07a08b5ca7cb51cda9a40c2"
|
||||||
|
private val language = "de"
|
||||||
|
private val preparedParamters = "?api_key=$apiKey&language=$language"
|
||||||
|
|
||||||
|
private val imageUrl = "https://image.tmdb.org/t/p/w500"
|
||||||
|
|
||||||
|
fun search(title: String, type: MediaType): TMDBResponse {
|
||||||
|
return when (type) {
|
||||||
|
MediaType.MOVIE -> {
|
||||||
|
val test = searchMovie(title)
|
||||||
|
println("test: $test")
|
||||||
|
test
|
||||||
|
}
|
||||||
|
MediaType.TVSHOW -> {
|
||||||
|
val test = searchTVShow(title)
|
||||||
|
println("test: $test")
|
||||||
|
test
|
||||||
|
}
|
||||||
|
MediaType.OTHER -> {
|
||||||
|
Log.e(javaClass.name, "Error")
|
||||||
|
TMDBResponse()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fun searchTVShow(title: String) = runBlocking {
|
||||||
|
val url = URL("$searchTVUrl$preparedParamters&query=${URLEncoder.encode(title, "UTF-8")}")
|
||||||
|
|
||||||
|
GlobalScope.async {
|
||||||
|
val response = JsonParser.parseString(url.readText()).asJsonObject
|
||||||
|
println(response)
|
||||||
|
|
||||||
|
return@async if (response.get("total_results").asInt > 0) {
|
||||||
|
response.get("results").asJsonArray.first().let {
|
||||||
|
val overview = it.asJsonObject.get("overview").asString
|
||||||
|
val posterPath = imageUrl + it.asJsonObject.get("poster_path").asString
|
||||||
|
val backdropPath = imageUrl + it.asJsonObject.get("backdrop_path").asString
|
||||||
|
|
||||||
|
TMDBResponse("", overview, posterPath, backdropPath)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
TMDBResponse()
|
||||||
|
}
|
||||||
|
}.await()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fun searchMovie(title: String) = runBlocking {
|
||||||
|
val url = URL("$searchMovieUrl$preparedParamters&query=${URLEncoder.encode(title, "UTF-8")}")
|
||||||
|
|
||||||
|
GlobalScope.async {
|
||||||
|
val response = JsonParser.parseString(url.readText()).asJsonObject
|
||||||
|
println(response)
|
||||||
|
|
||||||
|
return@async if (response.get("total_results").asInt > 0) {
|
||||||
|
response.get("results").asJsonArray.first().let {
|
||||||
|
val overview = it.asJsonObject.get("overview").asString
|
||||||
|
val posterPath = imageUrl + it.asJsonObject.get("poster_path").asString
|
||||||
|
val backdropPath = imageUrl + it.asJsonObject.get("backdrop_path").asString
|
||||||
|
|
||||||
|
TMDBResponse("", overview, posterPath, backdropPath)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
TMDBResponse()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}.await()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -20,11 +20,11 @@
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/image_poster"
|
android:id="@+id/image_poster"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="108dp"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center"
|
android:layout_gravity="center"
|
||||||
android:layout_marginTop="40dp"
|
android:layout_marginTop="20dp"
|
||||||
android:src="@drawable/ic_launcher_background"
|
android:minHeight="200dp"
|
||||||
/>
|
android:src="@drawable/ic_launcher_background" />
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/button_play"
|
android:id="@+id/button_play"
|
||||||
|
|
|
@ -7,9 +7,9 @@
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:paddingStart="7dp"
|
android:paddingStart="7dp"
|
||||||
android:paddingTop="2dp"
|
android:paddingTop="3dp"
|
||||||
android:paddingEnd="7dp"
|
android:paddingEnd="7dp"
|
||||||
android:paddingBottom="3dp">
|
android:paddingBottom="5dp">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/text_title"
|
android:id="@+id/text_title"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<resources>
|
<resources>
|
||||||
<!-- Base application theme. -->
|
<!-- Base application theme. -->
|
||||||
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
|
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
|
||||||
<!-- Customize your theme here. -->
|
<!-- Customize your theme here. -->
|
||||||
<item name="colorPrimary">@color/colorPrimary</item>
|
<item name="colorPrimary">@color/colorPrimary</item>
|
||||||
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
|
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
|
||||||
|
|
Loading…
Reference in New Issue