add rudimentary parsing for browsing results
This commit is contained in:
		| @ -14,7 +14,7 @@ android { | |||||||
|         minSdkVersion 23 |         minSdkVersion 23 | ||||||
|         targetSdkVersion 30 |         targetSdkVersion 30 | ||||||
|         versionCode 4200 //00.04.200 |         versionCode 4200 //00.04.200 | ||||||
|         versionName "0.5.0-alpha2" |         versionName "1.0.0-alpha1" | ||||||
|  |  | ||||||
|         testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" |         testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" | ||||||
|         resValue "string", "build_time", buildTime() |         resValue "string", "build_time", buildTime() | ||||||
|  | |||||||
| @ -1,7 +1,9 @@ | |||||||
| package org.mosad.teapod.parser.crunchyroll | package org.mosad.teapod.parser.crunchyroll | ||||||
| 
 | 
 | ||||||
|  | import android.util.Log | ||||||
| import com.github.kittinunf.fuel.Fuel | import com.github.kittinunf.fuel.Fuel | ||||||
| import com.github.kittinunf.fuel.core.FuelError | 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.FuelJson | ||||||
| import com.github.kittinunf.fuel.json.responseJson | import com.github.kittinunf.fuel.json.responseJson | ||||||
| import com.github.kittinunf.result.Result | import com.github.kittinunf.result.Result | ||||||
| @ -12,7 +14,7 @@ import kotlinx.serialization.json.Json | |||||||
| 
 | 
 | ||||||
| private val json = Json { ignoreUnknownKeys = true } | private val json = Json { ignoreUnknownKeys = true } | ||||||
| 
 | 
 | ||||||
| class Cruncyroll { | object Crunchyroll { | ||||||
| 
 | 
 | ||||||
|     private val baseUrl = "https://beta-api.crunchyroll.com" |     private val baseUrl = "https://beta-api.crunchyroll.com" | ||||||
| 
 | 
 | ||||||
| @ -47,7 +49,7 @@ class Cruncyroll { | |||||||
| //            println("response: $response") | //            println("response: $response") | ||||||
| //            println("response: $result") | //            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 |             return@withContext response.statusCode == 200 | ||||||
|         } |         } | ||||||
| @ -56,9 +58,9 @@ class Cruncyroll { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // TODO get/post difference |     // 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) { |         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") |                 .header("Authorization", "$tokenType $accessToken") | ||||||
|                 .responseJson() |                 .responseJson() | ||||||
| 
 | 
 | ||||||
| @ -71,34 +73,30 @@ class Cruncyroll { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // TESTING |     // 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 |     // TODO sort_by, default alphabetical, n, locale de-DE, categories | ||||||
|     suspend fun browse() { |     suspend fun browse(sortBy: SortBy = SortBy.ALPHABETICAL, n: Int = 10): BrowseResult { | ||||||
|         val browseEndpoint = "/content/v1/browse" |         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 browseResult = json.decodeFromString<BrowseResult>(result.component1()?.obj()?.toString()!!) | ||||||
| 
 | //        println(browseResult.items.size) | ||||||
|         val test = json.decodeFromString<Test>(result.component1()?.obj()?.toString()!!) |  | ||||||
|         println(test) |  | ||||||
| 
 | 
 | ||||||
|  |         return json.decodeFromString<BrowseResult>(result.component1()?.obj()?.toString()!!) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     // TODO | ||||||
|     suspend fun search() { |     suspend fun search() { | ||||||
|         val searchEndpoint = "/content/v1/search" |         val searchEndpoint = "/content/v1/search" | ||||||
| 
 |         val result = request(searchEndpoint) | ||||||
|         val result = requestA(searchEndpoint) |  | ||||||
| 
 | 
 | ||||||
|         println("${result.component1()?.obj()?.get("total")}") |         println("${result.component1()?.obj()?.get("total")}") | ||||||
| 
 | 
 | ||||||
|         val test = json.decodeFromString<Test>(result.component1()?.obj()?.toString()!!) |         val test = json.decodeFromString<BrowseResult>(result.component1()?.obj()?.toString()!!) | ||||||
|         println(test) |         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.appcompat.app.AppCompatActivity | ||||||
| import androidx.fragment.app.Fragment | import androidx.fragment.app.Fragment | ||||||
| import androidx.fragment.app.commit | import androidx.fragment.app.commit | ||||||
| import com.afollestad.materialdialogs.MaterialDialog |  | ||||||
| import com.afollestad.materialdialogs.callbacks.onDismiss |  | ||||||
| import com.google.android.material.navigation.NavigationBarView | import com.google.android.material.navigation.NavigationBarView | ||||||
| import kotlinx.coroutines.* | import kotlinx.coroutines.* | ||||||
| import org.mosad.teapod.R | import org.mosad.teapod.R | ||||||
| import org.mosad.teapod.databinding.ActivityMainBinding | import org.mosad.teapod.databinding.ActivityMainBinding | ||||||
| import org.mosad.teapod.parser.AoDParser | 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.EncryptedPreferences | ||||||
| import org.mosad.teapod.preferences.Preferences | import org.mosad.teapod.preferences.Preferences | ||||||
| import org.mosad.teapod.ui.activity.main.fragments.AccountFragment | 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.DataTypes | ||||||
| import org.mosad.teapod.util.MetaDBController | import org.mosad.teapod.util.MetaDBController | ||||||
| import org.mosad.teapod.util.StorageController | import org.mosad.teapod.util.StorageController | ||||||
| import org.mosad.teapod.util.exitAndRemoveTask |  | ||||||
| import java.net.SocketTimeoutException |  | ||||||
| import kotlin.system.measureTimeMillis | import kotlin.system.measureTimeMillis | ||||||
|  |  | ||||||
| class MainActivity : AppCompatActivity(), NavigationBarView.OnItemSelectedListener { | class MainActivity : AppCompatActivity(), NavigationBarView.OnItemSelectedListener { | ||||||
| @ -155,11 +151,8 @@ class MainActivity : AppCompatActivity(), NavigationBarView.OnItemSelectedListen | |||||||
|             if (EncryptedPreferences.password.isEmpty()) { |             if (EncryptedPreferences.password.isEmpty()) { | ||||||
|                 showOnboarding() |                 showOnboarding() | ||||||
|             } else { |             } else { | ||||||
|                 val crunchy = Cruncyroll() |                 Crunchyroll.login(EncryptedPreferences.login, EncryptedPreferences.password) | ||||||
|                 crunchy.login(EncryptedPreferences.login, EncryptedPreferences.password) |                 //runBlocking { Crunchyroll.browse() } | ||||||
|                 println("after login") |  | ||||||
|  |  | ||||||
|                 runBlocking { crunchy.browse() } |  | ||||||
|             } |             } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | |||||||
| @ -9,6 +9,8 @@ import androidx.lifecycle.lifecycleScope | |||||||
| import kotlinx.coroutines.launch | import kotlinx.coroutines.launch | ||||||
| import org.mosad.teapod.databinding.FragmentLibraryBinding | import org.mosad.teapod.databinding.FragmentLibraryBinding | ||||||
| import org.mosad.teapod.parser.AoDParser | 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.adapter.MediaItemAdapter | ||||||
| import org.mosad.teapod.util.decoration.MediaItemDecoration | import org.mosad.teapod.util.decoration.MediaItemDecoration | ||||||
| import org.mosad.teapod.util.showFragment | import org.mosad.teapod.util.showFragment | ||||||
| @ -30,7 +32,14 @@ class LibraryFragment : Fragment() { | |||||||
|         lifecycleScope.launch { |         lifecycleScope.launch { | ||||||
|             // create and set the adapter, needs context |             // create and set the adapter, needs context | ||||||
|             context?.let { |             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, _ -> |                 adapter.onItemClick = { mediaId, _ -> | ||||||
|                     activity?.showFragment(MediaFragment(mediaId)) |                     activity?.showFragment(MediaFragment(mediaId)) | ||||||
|                 } |                 } | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user