wip: 🚧 upload user icon from app

This commit is contained in:
Toby Bridle
2024-07-07 01:59:24 +01:00
parent 9332dfddc6
commit 5d170b8fa9
3 changed files with 76 additions and 13 deletions

View File

@@ -14,6 +14,10 @@ import ani.dantotsu.settings.saving.PrefName
import ani.dantotsu.snackString
import ani.dantotsu.toast
import ani.dantotsu.util.Logger
import eu.kanade.tachiyomi.network.NetworkHelper
import okhttp3.Cookie
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import java.util.Calendar
object Anilist {
@@ -163,7 +167,8 @@ object Anilist {
force: Boolean = false,
useToken: Boolean = true,
show: Boolean = false,
cache: Int? = null
cache: Int? = null,
extraHeaders: Map<String, String>? = null
): T? {
return try {
if (show) Logger.log("Anilist Query: $query")
@@ -182,10 +187,23 @@ object Anilist {
if (token != null || force) {
if (token != null && useToken) headers["Authorization"] = "Bearer $token"
val _cookies =
Injekt.get<NetworkHelper>().cookieJar.manager?.getCookie("https://anilist.co/user/${Anilist.userid}")
val cookies = mutableMapOf<String, String>()
_cookies?.split(";")?.forEach {
val pieces = it.split('=')
val name = it.split('=')[0].trim()
cookies[name] =
pieces.takeLast(pieces.size - 1).asReversed().joinToString("=").trim()
}
Logger.log(extraHeaders.toString())
Logger.log(cookies.toString())
val json = client.post(
"https://graphql.anilist.co/",
headers,
(extraHeaders
?: mapOf()) + headers + mapOf("Cookie" to "laravel_session=${cookies["laravel_session"]}"),
data = data,
cacheTime = cache ?: 10
)

View File

@@ -1,12 +1,19 @@
package ani.dantotsu.connections.anilist
import android.util.Log
import ani.dantotsu.client
import ani.dantotsu.connections.anilist.Anilist.executeQuery
import ani.dantotsu.connections.anilist.api.FuzzyDate
import ani.dantotsu.connections.anilist.api.Query
import ani.dantotsu.connections.anilist.api.ToggleLike
import ani.dantotsu.currContext
import ani.dantotsu.util.Logger
import com.google.gson.Gson
import eu.kanade.tachiyomi.network.NetworkHelper
import kotlinx.serialization.json.JsonObject
import org.checkerframework.checker.regex.qual.Regex
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
class AnilistMutations {
@@ -154,17 +161,47 @@ class AnilistMutations {
}
suspend fun saveUserAvatar(base64Avatar: String): JsonObject? {
val imageFormat = getImageFormat(base64Avatar)
val base64WithPrefix = "data:image/$imageFormat;base64,${base64Avatar.removePrefix("data:image/$imageFormat;base64,")}"
val query = "mutation(\$avatar: String) { SaveUserAvatar(avatar: \$avatar) { id avatar { large medium } } }"
val variables = """{"avatar":"$base64WithPrefix"}"""
return executeQuery(query, variables)
val cookies = mutableMapOf<String, String>()
val _cookies = Injekt.get<NetworkHelper>().cookieJar.manager
_cookies?.getCookie("https://anilist.co/user/${Anilist.userid}")?.split(";")?.forEach {
val pieces = it.split('=')
val name = it.split('=')[0].trim()
cookies[name] = pieces.takeLast(pieces.size - 1).asReversed().joinToString("=").trim()
}
val regexPattern = """window\.al_token\s*=\s*".*?"""".toRegex()
val xsrf = regexPattern.find(
client.get(
"https://anilist.co/settings", headers = mapOf(
"Authorization" to "Bearer ${Anilist.token}",
"Accept" to "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
"Cookie" to "laravel_session=${cookies["laravel_session"]}"
)
).text
)?.value?.substringAfter('"')?.substringBefore('"')
/*
mutation($avatar:String){SaveUserAvatar(avatar:$avatar){id avatar{large medium}}}
*/
val query =
"mutation(\$avatar:String){SaveUserAvatar(avatar:\$avatar){id avatar{large medium}}}\n"
val variables = """{"avatar":"$base64Avatar"}"""
Log.d("IMAGE", "$query\n$variables")
val queryResult: JsonObject? = executeQuery(
query,
variables,
useToken = true,
extraHeaders = mapOf("schema" to "internal", "x-csrf-token" to (xsrf ?: ""), "content-type" to "application/json")
)
Log.d("QUERY RESULT", queryResult.toString())
return queryResult
}
suspend fun saveUserBanner(base64Banner: String): JsonObject? {
val imageFormat = getImageFormat(base64Banner)
val base64WithPrefix = "data:image/$imageFormat;base64,${base64Banner.removePrefix("data:image/$imageFormat;base64,")}"
val query = "mutation(\$banner: String) { SaveUserBanner(banner: \$banner) { id bannerImage } }"
val base64WithPrefix =
"data:image/$imageFormat;base64,${base64Banner.removePrefix("data:image/$imageFormat;base64,")}"
val query =
"mutation(\$banner: String) { SaveUserBanner(banner: \$banner) { id bannerImage } }"
val variables = """{"banner":"$base64WithPrefix"}"""
return executeQuery(query, variables)
}

View File

@@ -129,6 +129,10 @@ class ProfileActivity : AppCompatActivity(), AppBarLayout.OnOffsetChangedListene
})
bindingProfileAppBar = ItemProfileAppBarBinding.bind(binding.root).apply {
val intent = Intent(context, CookieCatcher::class.java)
.putExtra("url", "https://anilist.co/user/${Anilist.userid}")
.putExtra("headers", "{\"Authorization: ${Anilist.token}\"")
ContextCompat.startActivity(context, intent, null)
binding.profileProgressBar.visibility = View.GONE
editProfileAvatar.visibility = View.GONE
editProfileBanner.visibility = View.GONE
@@ -296,7 +300,7 @@ class ProfileActivity : AppCompatActivity(), AppBarLayout.OnOffsetChangedListene
)
viewIds.forEach { viewId ->
findViewById<View>(viewId).apply {
findViewById<View>(viewId)?.apply {
visibility = if (visibility == View.VISIBLE) View.GONE else View.VISIBLE
}
}
@@ -335,7 +339,6 @@ class ProfileActivity : AppCompatActivity(), AppBarLayout.OnOffsetChangedListene
}
private fun saveProfileImages() {
val avatarBitmap = (bindingProfileAppBar.profileUserAvatar.drawable as? BitmapDrawable)?.bitmap
val bannerBitmap = (bindingProfileAppBar.profileBannerImage.drawable as? BitmapDrawable)?.bitmap
if (avatarBitmap != null && bannerBitmap != null) {
@@ -368,14 +371,19 @@ class ProfileActivity : AppCompatActivity(), AppBarLayout.OnOffsetChangedListene
private fun bitmapToBase64(bitmap: Bitmap): String {
val outputStream = ByteArrayOutputStream()
bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream)
val base64 = Base64.encodeToString(outputStream.toByteArray(), Base64.NO_WRAP)
val imageFormat = when (bitmap.config) {
Bitmap.Config.ARGB_8888 -> "png"
Bitmap.Config.RGB_565 -> "png"
Bitmap.Config.ALPHA_8 -> "png"
else -> "jpeg"
}
bitmap.compress(
if (imageFormat == "png") Bitmap.CompressFormat.PNG else Bitmap.CompressFormat.JPEG,
100,
outputStream
)
val base64 = Base64.encodeToString(outputStream.toByteArray(), Base64.NO_WRAP)
return "data:image/$imageFormat;base64,$base64"
}