Fix issue with Gelbooru-type sites. Add Test button to settings. Target Android 16 (API level 36). Update various libraries.

This commit is contained in:
Kevin Alberts 2025-09-04 22:33:44 +02:00
parent f584825082
commit d7c74beb76
6 changed files with 63 additions and 18 deletions

View file

@ -7,15 +7,14 @@ plugins {
android { android {
namespace = "nl.kurocon.plugin.wallpaperprovider.booru" namespace = "nl.kurocon.plugin.wallpaperprovider.booru"
compileSdk = 35 compileSdk = 36
defaultConfig { defaultConfig {
applicationId = "nl.kurocon.plugin.wallpaperprovider.booru" applicationId = "nl.kurocon.plugin.wallpaperprovider.booru"
minSdk = 23 minSdk = 23
targetSdk = 35 targetSdk = 36
versionCode = 2 versionCode = 3
versionName = "1.1" versionName = "1.2"
} }
buildTypes { buildTypes {
@ -39,13 +38,13 @@ android {
} }
dependencies { dependencies {
implementation("androidx.core:core-ktx:1.13.1") implementation("androidx.core:core-ktx:1.17.0")
implementation("androidx.leanback:leanback:1.2.0-alpha04") implementation("androidx.leanback:leanback:1.2.0")
implementation("androidx.appcompat:appcompat:1.7.0") implementation("androidx.appcompat:appcompat:1.7.1")
implementation("com.google.android.material:material:1.12.0") implementation("com.google.android.material:material:1.13.0")
implementation("androidx.preference:preference-ktx:1.2.1") implementation("androidx.preference:preference-ktx:1.2.1")
implementation("com.google.code.gson:gson:2.11.0") implementation("com.google.code.gson:gson:2.13.1")
implementation("com.squareup.okhttp3:okhttp:4.12.0") implementation("com.squareup.okhttp3:okhttp:4.12.0")
implementation("org.json:json:20210307") implementation("org.json:json:20250517")
implementation(project(":api")) implementation(project(":api"))
} }

View file

@ -159,8 +159,12 @@ class BooruAPI(context: Context) {
val responseBody = response.body?.string() ?: throw IOException("Response body is null") val responseBody = response.body?.string() ?: throw IOException("Response body is null")
val jsonBody: JSONObject val jsonBody: JSONObject
var jsonArray: JSONArray
try { try {
jsonBody = JSONObject(responseBody) jsonBody = JSONObject(responseBody)
jsonArray = jsonBody.getJSONArray("post")
} catch (je: JSONException) {
jsonArray = JSONArray(responseBody)
} catch (e: Exception) { } catch (e: Exception) {
// gelbooru returns xml response if request was denied for some reason // gelbooru returns xml response if request was denied for some reason
// i.e. user hit a rate limit because he didn't include api key // i.e. user hit a rate limit because he didn't include api key
@ -169,7 +173,6 @@ class BooruAPI(context: Context) {
// Parse JSON response into BooruImage instances // Parse JSON response into BooruImage instances
val images = mutableListOf<BooruImage>() val images = mutableListOf<BooruImage>()
val jsonArray = jsonBody.getJSONArray("post")
for (i in 0 until jsonArray.length()) { for (i in 0 until jsonArray.length()) {
val jsonObject = jsonArray.getJSONObject(i) val jsonObject = jsonArray.getJSONObject(i)
val imageUrl = jsonObject.optString("file_url") val imageUrl = jsonObject.optString("file_url")

View file

@ -2,16 +2,24 @@ package nl.kurocon.plugin.wallpaperprovider.booru
import android.os.Bundle import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.widget.Toast
import androidx.appcompat.content.res.AppCompatResources import androidx.appcompat.content.res.AppCompatResources
import androidx.leanback.app.GuidedStepSupportFragment import androidx.leanback.app.GuidedStepSupportFragment
import androidx.leanback.widget.GuidanceStylist.Guidance import androidx.leanback.widget.GuidanceStylist.Guidance
import androidx.leanback.widget.GuidedAction import androidx.leanback.widget.GuidedAction
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import nl.kurocon.plugin.wallpaperprovider.booru.PreferencesManager.BooruType.Companion.DANBOORU import nl.kurocon.plugin.wallpaperprovider.booru.PreferencesManager.BooruType.Companion.DANBOORU
import nl.kurocon.plugin.wallpaperprovider.booru.PreferencesManager.BooruType.Companion.GELBOORU import nl.kurocon.plugin.wallpaperprovider.booru.PreferencesManager.BooruType.Companion.GELBOORU
import nl.kurocon.plugin.wallpaperprovider.booru.PreferencesManager.BooruType.Companion.MOEBOORU import nl.kurocon.plugin.wallpaperprovider.booru.PreferencesManager.BooruType.Companion.MOEBOORU
import nl.kurocon.plugin.wallpaperprovider.booru.PreferencesManager.BooruType.Companion.ZEROCHAN
import nl.kurocon.plugin.wallpaperprovider.booru.PreferencesManager.BooruType.Companion.WALLHAVEN import nl.kurocon.plugin.wallpaperprovider.booru.PreferencesManager.BooruType.Companion.WALLHAVEN
import kotlin.CharSequence import nl.kurocon.plugin.wallpaperprovider.booru.PreferencesManager.BooruType.Companion.ZEROCHAN
import java.io.IOException
import java.util.concurrent.Executors
class SettingsFragment : GuidedStepSupportFragment() { class SettingsFragment : GuidedStepSupportFragment() {
override fun onCreateGuidance(savedInstanceState: Bundle?): Guidance { override fun onCreateGuidance(savedInstanceState: Bundle?): Guidance {
@ -135,6 +143,12 @@ class SettingsFragment : GuidedStepSupportFragment() {
.descriptionEditable(true) .descriptionEditable(true)
.build() .build()
actions.add(actionBooruApiKey) actions.add(actionBooruApiKey)
val actionBooruTest = GuidedAction.Builder(context)
.id(ACTION_ID_BOORU_TEST)
.title(R.string.setting_booru_test_title)
.build()
actions.add(actionBooruTest)
} }
override fun onSubGuidedActionClicked(action: GuidedAction): Boolean { override fun onSubGuidedActionClicked(action: GuidedAction): Boolean {
@ -177,6 +191,32 @@ class SettingsFragment : GuidedStepSupportFragment() {
notifyActionChanged(findActionPositionById(ACTION_ID_BOORU_API_KEY)) notifyActionChanged(findActionPositionById(ACTION_ID_BOORU_API_KEY))
PreferencesManager.booruApiKey = params.toString() PreferencesManager.booruApiKey = params.toString()
} }
ACTION_ID_BOORU_TEST -> {
try {
val executor = Executors.newSingleThreadExecutor()
val handler = Handler(Looper.getMainLooper())
executor.execute {
val wallpapers = BooruAPI(requireContext()).getImageUrls(1)
handler.post {
Toast.makeText(
requireContext(),
"Successfully fetched ${wallpapers.size} image",
Toast.LENGTH_LONG
).show()
}
}
} catch (e: IOException) {
CoroutineScope(Dispatchers.IO).launch {
withContext(Dispatchers.Main) {
Toast.makeText(
requireContext(),
"Failed to fetch image: ${e.message}",
Toast.LENGTH_LONG
).show()
}
}
}
}
} }
} }
@ -187,6 +227,7 @@ class SettingsFragment : GuidedStepSupportFragment() {
private const val ACTION_ID_USER_SETTINGS_LABEL = 4L private const val ACTION_ID_USER_SETTINGS_LABEL = 4L
private const val ACTION_ID_BOORU_USER_ID = 5L private const val ACTION_ID_BOORU_USER_ID = 5L
private const val ACTION_ID_BOORU_API_KEY = 6L private const val ACTION_ID_BOORU_API_KEY = 6L
private const val ACTION_ID_BOORU_TEST = 7L
private const val SUBACTION_ID_BOORU_TYPE_DANBOORU = 7L private const val SUBACTION_ID_BOORU_TYPE_DANBOORU = 7L
private const val SUBACTION_ID_BOORU_TYPE_MOEBOORU = 8L private const val SUBACTION_ID_BOORU_TYPE_MOEBOORU = 8L

View file

@ -14,6 +14,7 @@
<string name="setting_booru_tag_search_title">Search query - e.g. \'ratio:16:9 rating:general\'</string> <string name="setting_booru_tag_search_title">Search query - e.g. \'ratio:16:9 rating:general\'</string>
<string name="setting_booru_user_id_title">Booru Username </string> <string name="setting_booru_user_id_title">Booru Username </string>
<string name="setting_booru_api_key_title">Booru API Key</string> <string name="setting_booru_api_key_title">Booru API Key</string>
<string name="setting_booru_test_title">Test settings</string>
<string name="setting_users_title">User settings (optional)</string> <string name="setting_users_title">User settings (optional)</string>
<string name="setting_users_description"> <string name="setting_users_description">

View file

@ -1,6 +1,7 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules. // Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins { plugins {
id("com.android.application") version "8.7.0" apply false id("com.android.application") version "8.12.2" apply false
id("com.android.library") version "8.7.0" apply false id("com.android.library") version "8.12.2" apply false
id("org.jetbrains.kotlin.android") version "2.0.20" apply false id("org.jetbrains.kotlin.android") version "2.0.20" apply false
} }
val defaultTargetSdkVersion by extra(36)

View file

@ -1,6 +1,6 @@
#Sun Dec 31 14:34:51 CET 2023 #Sun Dec 31 14:34:51 CET 2023
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists