api stuff

This commit is contained in:
LagradOst 2021-05-16 20:28:00 +02:00
parent 22f2a8810e
commit 0fa16e3bbc
8 changed files with 228 additions and 94 deletions

View file

@ -143,6 +143,8 @@ interface LoadResponse {
}
data class AnimeLoadResponse(
val engName: String?,
val japName: String?,
override val name: String,
override val url: String,
override val apiName: String,
@ -151,9 +153,8 @@ data class AnimeLoadResponse(
override val posterUrl: String?,
override val year: Int?,
val dubEpisodes: ArrayList<String>?,
val subEpisodes: ArrayList<String>?,
val otherName: String?,
val dubEpisodes: ArrayList<Any>?,
val subEpisodes: ArrayList<Any>?,
val showStatus: ShowStatus?,
val tags: ArrayList<String>?,

View file

@ -5,11 +5,21 @@ import com.fasterxml.jackson.module.kotlin.readValue
import com.lagradost.cloudstream3.*
import java.net.URLEncoder
import java.util.*
import kotlin.collections.ArrayList
class ShiroProvider : MainAPI() {
companion object {
var token: String? = null
fun getType(t: String): TvType {
return when (t) {
"TV" -> TvType.Anime
"OVA" -> TvType.ONA
"movie" -> TvType.Movie
else -> TvType.Anime
}
}
}
fun autoLoadToken(): Boolean {
@ -45,7 +55,7 @@ class ShiroProvider : MainAPI() {
@JsonProperty("episodeCount") val episodeCount: String,
@JsonProperty("language") val language: String,
@JsonProperty("type") val type: String,
@JsonProperty("year") val year: String,
@JsonProperty("year") val year: String?,
@JsonProperty("canonicalTitle") val canonicalTitle: String,
@JsonProperty("english") val english: String?,
)
@ -72,51 +82,121 @@ class ShiroProvider : MainAPI() {
@JsonProperty("status") val status: String,
)
data class ShiroVideo(
@JsonProperty("video_id") val video_id: String,
@JsonProperty("host") val host: String,
)
data class ShiroEpisodes(
@JsonProperty("anime") val anime: AnimePageData?,
@JsonProperty("anime_slug") val anime_slug: String,
@JsonProperty("create") val create: String,
@JsonProperty("dayOfTheWeek") val dayOfTheWeek: String,
@JsonProperty("episode_number") val episode_number: Int,
@JsonProperty("slug") val slug: String,
@JsonProperty("update") val update: String,
@JsonProperty("_id") val _id: String,
@JsonProperty("videos") val videos: List<ShiroVideo>,
)
data class AnimePageData(
@JsonProperty("banner") val banner: String?,
@JsonProperty("canonicalTitle") val canonicalTitle: String?,
@JsonProperty("episodeCount") val episodeCount: String,
@JsonProperty("genres") val genres: List<String>?,
@JsonProperty("image") val image: String,
@JsonProperty("japanese") val japanese: String?,
@JsonProperty("english") val english: String?,
@JsonProperty("language") val language: String,
@JsonProperty("name") val name: String,
@JsonProperty("slug") val slug: String,
@JsonProperty("synopsis") val synopsis: String,
@JsonProperty("type") val type: String?,
@JsonProperty("views") val views: Int?,
@JsonProperty("year") val year: String?,
@JsonProperty("_id") val _id: String,
@JsonProperty("episodes") var episodes: List<ShiroEpisodes>?,
@JsonProperty("synonyms") var synonyms: List<String>?,
@JsonProperty("status") val status: String?,
@JsonProperty("schedule") val schedule: String?,
)
data class AnimePage(
@JsonProperty("data") val data: AnimePageData,
@JsonProperty("status") val status: String,
)
override fun search(query: String): ArrayList<Any>? {
try {
if (!autoLoadToken()) return null
val returnValue: ArrayList<Any> = ArrayList()
val response = khttp.get("https://tapi.shiro.is/advanced?search=${
URLEncoder.encode(
query,
"UTF-8"
)
}&token=$token".replace("+", "%20"))
println(response.text)
val mapped = response.let { mapper.readValue<ShiroFullSearchResponse>(it.text) }
for (i in mapped.data.nav.currentPage.items) {
if (!autoLoadToken()) return null
val returnValue: ArrayList<Any> = ArrayList()
val response = khttp.get("https://tapi.shiro.is/advanced?search=${
URLEncoder.encode(
query,
"UTF-8"
)
}&token=$token".replace("+", "%20"))
if (response.text == "{\"status\":\"Found\",\"data\":[]}") return returnValue // OR ELSE WILL CAUSE WEIRD ERROR
val type = when (i.type) {
"TV" -> TvType.Anime
"OVA" -> TvType.ONA
"movie" -> TvType.Movie
else -> TvType.Anime
}
val isDubbed = i.language == "dubbed"
val set: EnumSet<DubStatus> = EnumSet.noneOf(DubStatus::class.java)
val mapped = response.let { mapper.readValue<ShiroFullSearchResponse>(it.text) }
for (i in mapped.data.nav.currentPage.items) {
val type = getType(i.type)
val isDubbed = i.language == "dubbed"
val set: EnumSet<DubStatus> = EnumSet.noneOf(DubStatus::class.java)
if (isDubbed)
set.add(DubStatus.HasDub)
else
set.add(DubStatus.HasSub)
val episodeCount = i.episodeCount.toInt()
if (isDubbed)
set.add(DubStatus.HasDub)
else
set.add(DubStatus.HasSub)
val episodeCount = i.episodeCount.toInt()
returnValue.add(AnimeSearchResponse(
i.english ?: i.canonicalTitle,
"$mainUrl/${i.slug}",
this.name,
type,
"https://cdn.shiro.is/${i.image}",
i.year.toInt(),
i.canonicalTitle,
set,
if (isDubbed) episodeCount else null,
if (!isDubbed) episodeCount else null,
))
}
return returnValue
} catch (e: Exception) {
return null
returnValue.add(AnimeSearchResponse(
i.english ?: i.canonicalTitle,
"$mainUrl/${i.slug}",
this.name,
type,
"https://cdn.shiro.is/${i.image}",
i.year?.toIntOrNull(),
i.canonicalTitle,
set,
if (isDubbed) episodeCount else null,
if (!isDubbed) episodeCount else null,
))
}
return returnValue
}
override fun load(url: String): Any? {
if (!autoLoadToken()) return null
val rurl = "https://tapi.shiro.is/anime/slug/${url}?token=${token}"
val response = khttp.get(rurl, timeout = 120.0)
val mapped = response.let { mapper.readValue<AnimePage>(it.text) }
val data = mapped.data
val isDubbed = data.language == "dubbed"
val episodes = ArrayList<Any>(data.episodes ?: ArrayList())
val status = when (data.status) {
"current" -> ShowStatus.Ongoing
"finished" -> ShowStatus.Completed
else -> null
}
return AnimeLoadResponse(
data.english,
data.japanese,
data.canonicalTitle ?: data.name.replace("Dubbed", ""),
url,
this.name,
getType(data.type ?: ""),
"https://cdn.shiro.is/${data.image}",
data.year?.toIntOrNull(),
if (isDubbed) episodes else null,
if (!isDubbed) episodes else null,
status,
ArrayList(data.genres ?: ArrayList()),
data.synopsis,
ArrayList(data.synonyms ?: ArrayList()),
null,
null,
)
}
}

View file

@ -0,0 +1,29 @@
package com.lagradost.cloudstream3.ui.result
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import com.lagradost.cloudstream3.R
class ResultFragment : Fragment() {
private lateinit var viewModel: ResultViewModel
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
viewModel =
ViewModelProvider(this).get(ResultViewModel::class.java)
return inflater.inflate(R.layout.fragment_result, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
}
}

View file

@ -0,0 +1,7 @@
package com.lagradost.cloudstream3.ui.result
import androidx.lifecycle.ViewModel
class ResultViewModel : ViewModel() {
}

View file

@ -1,18 +1,15 @@
package com.lagradost.cloudstream3.ui.search
import android.content.DialogInterface
import android.content.res.Configuration
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.widget.SearchView
import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.preference.PreferenceManager
import androidx.recyclerview.widget.RecyclerView
@ -22,8 +19,9 @@ import com.lagradost.cloudstream3.APIHolder.getApiSettings
import com.lagradost.cloudstream3.R
import com.lagradost.cloudstream3.UIHelper.fixPaddingStatusbar
import com.lagradost.cloudstream3.UIHelper.getGridIsCompact
import com.lagradost.cloudstream3.mvvm.Resource
import com.lagradost.cloudstream3.mvvm.observe
import kotlinx.android.synthetic.main.fragment_search.*
import kotlin.concurrent.thread
class SearchFragment : Fragment() {
@ -106,19 +104,7 @@ class SearchFragment : Fragment() {
override fun onQueryTextSubmit(query: String): Boolean {
search_exit_icon.alpha = 0f
search_loading_bar.alpha = 1f
thread {
val data = allApi.search(query)//MainActivity.activeAPI.search(query)
activity?.runOnUiThread {
if (data == null) {
Toast.makeText(activity, "Server error", Toast.LENGTH_LONG).show()
} else {
(cardSpace.adapter as SearchAdapter).cardList = data
(cardSpace.adapter as SearchAdapter).notifyDataSetChanged()
}
search_exit_icon.alpha = 1f
search_loading_bar.alpha = 0f
}
}
searchViewModel.search(query)
return true
}
@ -127,6 +113,20 @@ class SearchFragment : Fragment() {
}
})
observe(searchViewModel.searchResponse) {
when (it) {
is Resource.Success -> {
(cardSpace.adapter as SearchAdapter).cardList = it.value
(cardSpace.adapter as SearchAdapter).notifyDataSetChanged()
}
is Resource.Failure -> {
Toast.makeText(activity, "Server error", Toast.LENGTH_LONG).show()
}
}
search_exit_icon.alpha = 1f
search_loading_bar.alpha = 0f
}
main_search.onActionViewExpanded()
}

View file

@ -3,20 +3,24 @@ package com.lagradost.cloudstream3.ui.search
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.lagradost.cloudstream3.APIHolder.apis
import com.lagradost.cloudstream3.MainAPI
import com.lagradost.cloudstream3.mvvm.Resource
import com.lagradost.cloudstream3.mvvm.safeApiCall
import kotlinx.coroutines.launch
class SearchViewModel : ViewModel() {
val api: MainAPI = apis[0]
private val _text = MutableLiveData<String>().apply {
value = "This is dashboard Fragment"
}
val text: LiveData<String> = _text
private val _searchResponse: MutableLiveData<Resource<ArrayList<Any>>> = MutableLiveData()
val searchResponse: LiveData<Resource<ArrayList<Any>>> get() = _searchResponse
val api : MainAPI = apis[0]
fun search(query: String) = viewModelScope.launch {
val data = safeApiCall {
api.search(query)
}
suspend fun search(query: String) = safeApiCall {
api.search(query)
_searchResponse.postValue(data as Resource<ArrayList<Any>>?)
}
}

View file

@ -1,35 +1,42 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:configChanges="orientation|screenSize|screenLayout|keyboardHidden"
android:paddingTop="0dp">
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/nav_view"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="0dp"
android:layout_marginEnd="0dp"
android:background="@color/darkBackground"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:menu="@menu/bottom_nav_menu"/>
<fragment
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:layout_constraintBottom_toTopOf="@id/nav_view"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="@navigation/mobile_navigation"
/>
android:id="@+id/homeRoot"
>
<androidx.constraintlayout.widget.ConstraintLayout android:layout_height="match_parent"
android:layout_width="match_parent">
</androidx.constraintlayout.widget.ConstraintLayout>
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/nav_view"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="@color/darkBackground"
app:itemRippleColor="@color/colorRipple"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:menu="@menu/bottom_nav_menu"
app:layout_constraintBottom_toBottomOf="parent"/>
<fragment
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="0dp"
app:defaultNavHost="true"
app:layout_constraintBottom_toTopOf="@+id/nav_view"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="@navigation/mobile_navigation"
app:layout_constraintEnd_toEndOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</FrameLayout>
</FrameLayout>

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
</androidx.constraintlayout.widget.ConstraintLayout>