add crunchyroll login and browse (no parsing for now)
This commit is contained in:
parent
eafefd9a51
commit
e7d057bfb8
|
@ -1,6 +1,9 @@
|
|||
apply plugin: 'com.android.application'
|
||||
apply plugin: 'kotlin-android'
|
||||
apply plugin: 'kotlin-android-extensions'
|
||||
plugins {
|
||||
id 'com.android.application'
|
||||
id 'kotlin-android'
|
||||
id 'kotlin-android-extensions'
|
||||
id 'org.jetbrains.kotlin.plugin.serialization' version "$kotlin_version"
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion 30
|
||||
|
@ -43,6 +46,7 @@ dependencies {
|
|||
implementation fileTree(dir: "libs", include: ["*.jar"])
|
||||
implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
|
||||
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.2'
|
||||
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.3.1")
|
||||
|
||||
implementation 'androidx.core:core-ktx:1.6.0'
|
||||
implementation 'androidx.appcompat:appcompat:1.3.1'
|
||||
|
@ -68,6 +72,10 @@ dependencies {
|
|||
implementation 'com.afollestad.material-dialogs:core:3.3.0'
|
||||
implementation 'com.afollestad.material-dialogs:bottomsheets:3.3.0'
|
||||
|
||||
implementation 'com.github.kittinunf.fuel:fuel:2.3.1'
|
||||
implementation 'com.github.kittinunf.fuel:fuel-android:2.3.1'
|
||||
implementation 'com.github.kittinunf.fuel:fuel-json:2.3.1'
|
||||
|
||||
testImplementation 'junit:junit:4.13.2'
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
|
||||
|
|
|
@ -0,0 +1,105 @@
|
|||
package org.mosad.teapod.parser.crunchyroll
|
||||
|
||||
import com.github.kittinunf.fuel.Fuel
|
||||
import com.github.kittinunf.fuel.core.FuelError
|
||||
import com.github.kittinunf.fuel.json.FuelJson
|
||||
import com.github.kittinunf.fuel.json.responseJson
|
||||
import com.github.kittinunf.result.Result
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.decodeFromString
|
||||
import kotlinx.serialization.json.Json
|
||||
|
||||
private val json = Json { ignoreUnknownKeys = true }
|
||||
|
||||
class Cruncyroll {
|
||||
|
||||
private val baseUrl = "https://beta-api.crunchyroll.com"
|
||||
|
||||
private var accessToken = ""
|
||||
private var tokenType = ""
|
||||
|
||||
fun login(username: String, password: String): Boolean = runBlocking {
|
||||
val tokenEndpoint = "/auth/v1/token"
|
||||
|
||||
val formData = listOf(
|
||||
"username" to username,
|
||||
"password" to password,
|
||||
"grant_type" to "password",
|
||||
"scope" to "offline_access"
|
||||
)
|
||||
|
||||
withContext(Dispatchers.IO) {
|
||||
val (request, response, result) = Fuel.post("$baseUrl$tokenEndpoint", parameters = formData)
|
||||
.header("Content-Type", "application/x-www-form-urlencoded")
|
||||
.appendHeader(
|
||||
"Authorization",
|
||||
"Basic "
|
||||
)
|
||||
.responseJson()
|
||||
|
||||
result.component1()?.obj()?.let {
|
||||
accessToken = it.get("access_token").toString()
|
||||
tokenType = it.get("token_type").toString()
|
||||
}
|
||||
|
||||
// println("request: $request")
|
||||
// println("response: $response")
|
||||
// println("response: $result")
|
||||
|
||||
println("login complete with code ${response.statusCode}")
|
||||
|
||||
return@withContext response.statusCode == 200
|
||||
}
|
||||
|
||||
return@runBlocking false
|
||||
}
|
||||
|
||||
// TODO get/post difference
|
||||
private suspend fun requestA(endpoint: String): Result<FuelJson, FuelError> = coroutineScope {
|
||||
return@coroutineScope (Dispatchers.IO) {
|
||||
val (request, response, result) = Fuel.get("$baseUrl$endpoint")
|
||||
.header("Authorization", "$tokenType $accessToken")
|
||||
.responseJson()
|
||||
|
||||
// println("request request: $request")
|
||||
// println("request response: $response")
|
||||
// println("request result: $result")
|
||||
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
// 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() {
|
||||
val browseEndpoint = "/content/v1/browse"
|
||||
|
||||
val result = requestA(browseEndpoint)
|
||||
|
||||
println("${result.component1()?.obj()?.get("total")}")
|
||||
|
||||
val test = json.decodeFromString<Test>(result.component1()?.obj()?.toString()!!)
|
||||
println(test)
|
||||
|
||||
}
|
||||
|
||||
suspend fun search() {
|
||||
val searchEndpoint = "/content/v1/search"
|
||||
|
||||
val result = requestA(searchEndpoint)
|
||||
|
||||
println("${result.component1()?.obj()?.get("total")}")
|
||||
|
||||
val test = json.decodeFromString<Test>(result.component1()?.obj()?.toString()!!)
|
||||
println(test)
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -36,6 +36,7 @@ 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.preferences.EncryptedPreferences
|
||||
import org.mosad.teapod.preferences.Preferences
|
||||
import org.mosad.teapod.ui.activity.main.fragments.AccountFragment
|
||||
|
@ -150,26 +151,38 @@ class MainActivity : AppCompatActivity(), NavigationBarView.OnItemSelectedListen
|
|||
EncryptedPreferences.readCredentials(this)
|
||||
StorageController.load(this)
|
||||
|
||||
// show onboarding
|
||||
// show onboarding TODO rework
|
||||
if (EncryptedPreferences.password.isEmpty()) {
|
||||
showOnboarding()
|
||||
} else {
|
||||
try {
|
||||
if (!AoDParser.login()) {
|
||||
showLoginDialog()
|
||||
}
|
||||
} catch (ex: SocketTimeoutException) {
|
||||
Log.w(javaClass.name, "Timeout during login!")
|
||||
val crunchy = Cruncyroll()
|
||||
crunchy.login(EncryptedPreferences.login, EncryptedPreferences.password)
|
||||
println("after login")
|
||||
|
||||
// show waring dialog before finishing
|
||||
MaterialDialog(this).show {
|
||||
title(R.string.dialog_timeout_head)
|
||||
message(R.string.dialog_timeout_desc)
|
||||
onDismiss { exitAndRemoveTask() }
|
||||
}
|
||||
}
|
||||
runBlocking { crunchy.browse() }
|
||||
}
|
||||
|
||||
|
||||
|
||||
// if (EncryptedPreferences.password.isEmpty()) {
|
||||
// showOnboarding()
|
||||
// } else {
|
||||
// try {
|
||||
// if (!AoDParser.login()) {
|
||||
// showLoginDialog()
|
||||
// }
|
||||
// } catch (ex: SocketTimeoutException) {
|
||||
// Log.w(javaClass.name, "Timeout during login!")
|
||||
//
|
||||
// // show waring dialog before finishing
|
||||
// MaterialDialog(this).show {
|
||||
// title(R.string.dialog_timeout_head)
|
||||
// message(R.string.dialog_timeout_desc)
|
||||
// onDismiss { exitAndRemoveTask() }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
runBlocking { loadingJob.await() } // wait for initial loading to finish
|
||||
}
|
||||
Log.i(javaClass.name, "loading and login in $time ms")
|
||||
|
|
Loading…
Reference in New Issue