add rudimentary parsing for browsing results
This commit is contained in:
		| @ -1,7 +1,9 @@ | ||||
| package org.mosad.teapod.parser.crunchyroll | ||||
| 
 | ||||
| import android.util.Log | ||||
| import com.github.kittinunf.fuel.Fuel | ||||
| import com.github.kittinunf.fuel.core.FuelError | ||||
| import com.github.kittinunf.fuel.core.Parameters | ||||
| import com.github.kittinunf.fuel.json.FuelJson | ||||
| import com.github.kittinunf.fuel.json.responseJson | ||||
| import com.github.kittinunf.result.Result | ||||
| @ -12,7 +14,7 @@ import kotlinx.serialization.json.Json | ||||
| 
 | ||||
| private val json = Json { ignoreUnknownKeys = true } | ||||
| 
 | ||||
| class Cruncyroll { | ||||
| object Crunchyroll { | ||||
| 
 | ||||
|     private val baseUrl = "https://beta-api.crunchyroll.com" | ||||
| 
 | ||||
| @ -47,7 +49,7 @@ class Cruncyroll { | ||||
| //            println("response: $response") | ||||
| //            println("response: $result") | ||||
| 
 | ||||
|             println("login complete with code ${response.statusCode}") | ||||
|             Log.i(javaClass.name, "login complete with code ${response.statusCode}") | ||||
| 
 | ||||
|             return@withContext response.statusCode == 200 | ||||
|         } | ||||
| @ -56,9 +58,9 @@ class Cruncyroll { | ||||
|     } | ||||
| 
 | ||||
|     // TODO get/post difference | ||||
|     private suspend fun requestA(endpoint: String): Result<FuelJson, FuelError> = coroutineScope { | ||||
|     private suspend fun request(endpoint: String, params: Parameters = listOf()): Result<FuelJson, FuelError> = coroutineScope { | ||||
|         return@coroutineScope (Dispatchers.IO) { | ||||
|             val (request, response, result) = Fuel.get("$baseUrl$endpoint") | ||||
|             val (request, response, result) = Fuel.get("$baseUrl$endpoint", params) | ||||
|                 .header("Authorization", "$tokenType $accessToken") | ||||
|                 .responseJson() | ||||
| 
 | ||||
| @ -71,34 +73,30 @@ class Cruncyroll { | ||||
|     } | ||||
| 
 | ||||
|     // TESTING | ||||
|     @Serializable | ||||
|     data class Test(val total: Int, val items: List<Item>) | ||||
| 
 | ||||
|     @Serializable | ||||
|     data class Item(val channel_id: String, val description: String) | ||||
| 
 | ||||
|     // TODO sort_by, default alphabetical, n, locale de-DE | ||||
|     suspend fun browse() { | ||||
|     // TODO sort_by, default alphabetical, n, locale de-DE, categories | ||||
|     suspend fun browse(sortBy: SortBy = SortBy.ALPHABETICAL, n: Int = 10): BrowseResult { | ||||
|         val browseEndpoint = "/content/v1/browse" | ||||
|         val parameters = listOf("sort_by" to sortBy.str, "n" to n) | ||||
| 
 | ||||
|         val result = requestA(browseEndpoint) | ||||
|         val result = request(browseEndpoint, parameters) | ||||
| 
 | ||||
|         println("${result.component1()?.obj()?.get("total")}") | ||||
| 
 | ||||
|         val test = json.decodeFromString<Test>(result.component1()?.obj()?.toString()!!) | ||||
|         println(test) | ||||
| //        val browseResult = json.decodeFromString<BrowseResult>(result.component1()?.obj()?.toString()!!) | ||||
| //        println(browseResult.items.size) | ||||
| 
 | ||||
|         return json.decodeFromString<BrowseResult>(result.component1()?.obj()?.toString()!!) | ||||
|     } | ||||
| 
 | ||||
|     // TODO | ||||
|     suspend fun search() { | ||||
|         val searchEndpoint = "/content/v1/search" | ||||
| 
 | ||||
|         val result = requestA(searchEndpoint) | ||||
|         val result = request(searchEndpoint) | ||||
| 
 | ||||
|         println("${result.component1()?.obj()?.get("total")}") | ||||
| 
 | ||||
|         val test = json.decodeFromString<Test>(result.component1()?.obj()?.toString()!!) | ||||
|         println(test) | ||||
|         val test = json.decodeFromString<BrowseResult>(result.component1()?.obj()?.toString()!!) | ||||
|         println(test.items.size) | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
| @ -0,0 +1,34 @@ | ||||
| package org.mosad.teapod.parser.crunchyroll | ||||
|  | ||||
| import kotlinx.serialization.Serializable | ||||
|  | ||||
| /** | ||||
|  * data classes for browse | ||||
|  * TODO make class names more clear/possibly overlapping for now | ||||
|  */ | ||||
| enum class SortBy(val str: String) { | ||||
|     ALPHABETICAL("alphabetical"), | ||||
|     NEWLY_ADDED("newly_added"), | ||||
|     POPULARITY("popularity") | ||||
| } | ||||
|  | ||||
| @Serializable | ||||
| data class BrowseResult(val total: Int, val items: List<Item>) | ||||
|  | ||||
| @Serializable | ||||
| data class Item( | ||||
|     val id: String, | ||||
|     val title: String, | ||||
|     val type: String, | ||||
|     val channel_id: String, | ||||
|     val description: String, | ||||
|     val images: Images | ||||
|     // TODO metadata etc. | ||||
| ) | ||||
|  | ||||
| @Serializable | ||||
| data class Images(val poster_tall: List<List<Poster>>, val poster_wide: List<List<Poster>>) | ||||
| // crunchyroll why? | ||||
|  | ||||
| @Serializable | ||||
| data class Poster(val height: Int, val width: Int, val source: String, val type: String) | ||||
| @ -29,14 +29,12 @@ import android.view.MenuItem | ||||
| import androidx.appcompat.app.AppCompatActivity | ||||
| import androidx.fragment.app.Fragment | ||||
| import androidx.fragment.app.commit | ||||
| import com.afollestad.materialdialogs.MaterialDialog | ||||
| import com.afollestad.materialdialogs.callbacks.onDismiss | ||||
| import com.google.android.material.navigation.NavigationBarView | ||||
| import kotlinx.coroutines.* | ||||
| import org.mosad.teapod.R | ||||
| import org.mosad.teapod.databinding.ActivityMainBinding | ||||
| import org.mosad.teapod.parser.AoDParser | ||||
| import org.mosad.teapod.parser.crunchyroll.Cruncyroll | ||||
| import org.mosad.teapod.parser.crunchyroll.Crunchyroll | ||||
| import org.mosad.teapod.preferences.EncryptedPreferences | ||||
| import org.mosad.teapod.preferences.Preferences | ||||
| import org.mosad.teapod.ui.activity.main.fragments.AccountFragment | ||||
| @ -49,8 +47,6 @@ import org.mosad.teapod.ui.components.LoginDialog | ||||
| import org.mosad.teapod.util.DataTypes | ||||
| import org.mosad.teapod.util.MetaDBController | ||||
| import org.mosad.teapod.util.StorageController | ||||
| import org.mosad.teapod.util.exitAndRemoveTask | ||||
| import java.net.SocketTimeoutException | ||||
| import kotlin.system.measureTimeMillis | ||||
|  | ||||
| class MainActivity : AppCompatActivity(), NavigationBarView.OnItemSelectedListener { | ||||
| @ -155,11 +151,8 @@ class MainActivity : AppCompatActivity(), NavigationBarView.OnItemSelectedListen | ||||
|             if (EncryptedPreferences.password.isEmpty()) { | ||||
|                 showOnboarding() | ||||
|             } else { | ||||
|                 val crunchy = Cruncyroll() | ||||
|                 crunchy.login(EncryptedPreferences.login, EncryptedPreferences.password) | ||||
|                 println("after login") | ||||
|  | ||||
|                 runBlocking { crunchy.browse() } | ||||
|                 Crunchyroll.login(EncryptedPreferences.login, EncryptedPreferences.password) | ||||
|                 //runBlocking { Crunchyroll.browse() } | ||||
|             } | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -9,6 +9,8 @@ import androidx.lifecycle.lifecycleScope | ||||
| import kotlinx.coroutines.launch | ||||
| import org.mosad.teapod.databinding.FragmentLibraryBinding | ||||
| import org.mosad.teapod.parser.AoDParser | ||||
| import org.mosad.teapod.parser.crunchyroll.Crunchyroll | ||||
| import org.mosad.teapod.util.ItemMedia | ||||
| import org.mosad.teapod.util.adapter.MediaItemAdapter | ||||
| import org.mosad.teapod.util.decoration.MediaItemDecoration | ||||
| import org.mosad.teapod.util.showFragment | ||||
| @ -30,7 +32,14 @@ class LibraryFragment : Fragment() { | ||||
|         lifecycleScope.launch { | ||||
|             // create and set the adapter, needs context | ||||
|             context?.let { | ||||
|                 adapter = MediaItemAdapter(AoDParser.guiMediaList) | ||||
|                 // crunchy testing TODO implement lazy loading | ||||
|                 val results = Crunchyroll.browse(n = 50) | ||||
|                 val list = results.items.mapIndexed { index, item -> | ||||
|                     ItemMedia(index, item.title, item.images.poster_wide[0][0].source) | ||||
|                 } | ||||
|  | ||||
|  | ||||
|                 adapter = MediaItemAdapter(list) | ||||
|                 adapter.onItemClick = { mediaId, _ -> | ||||
|                     activity?.showFragment(MediaFragment(mediaId)) | ||||
|                 } | ||||
|  | ||||
		Reference in New Issue
	
	Block a user