diff --git a/.idea/deploymentTargetDropDown.xml b/.idea/deploymentTargetDropDown.xml index bcfc24b8..9ecfdc78 100644 --- a/.idea/deploymentTargetDropDown.xml +++ b/.idea/deploymentTargetDropDown.xml @@ -1,17 +1,6 @@ - - - - - - - - - - - @@ -23,6 +12,6 @@ - + \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 39b4fbbf..b23e9fc6 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -38,7 +38,7 @@ android { minSdkVersion 16 targetSdkVersion 31 versionCode 69 - versionName "5.3.1" + versionName "5.3.2" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" vectorDrawables.useSupportLibrary = true } diff --git a/app/release/output-metadata.json b/app/release/output-metadata.json index 380915a2..409af542 100644 --- a/app/release/output-metadata.json +++ b/app/release/output-metadata.json @@ -12,7 +12,7 @@ "filters": [], "attributes": [], "versionCode": 69, - "versionName": "5.3.1", + "versionName": "5.3.2", "outputFile": "app-release.apk" } ], diff --git a/app/src/main/java/xyz/quaver/pupil/Pupil.kt b/app/src/main/java/xyz/quaver/pupil/Pupil.kt index c274e6db..47b53f07 100644 --- a/app/src/main/java/xyz/quaver/pupil/Pupil.kt +++ b/app/src/main/java/xyz/quaver/pupil/Pupil.kt @@ -84,7 +84,6 @@ lateinit var runtime: QuickJs private set class Pupil : Application() { - companion object { lateinit var instance: Pupil private set diff --git a/app/src/main/java/xyz/quaver/pupil/hitomi/common.kt b/app/src/main/java/xyz/quaver/pupil/hitomi/common.kt index a36e6328..6c86cd4b 100644 --- a/app/src/main/java/xyz/quaver/pupil/hitomi/common.kt +++ b/app/src/main/java/xyz/quaver/pupil/hitomi/common.kt @@ -16,16 +16,14 @@ package xyz.quaver.pupil.hitomi -import kotlinx.coroutines.Job -import kotlinx.coroutines.asCoroutineDispatcher -import kotlinx.coroutines.runBlocking -import kotlinx.coroutines.withContext +import kotlinx.coroutines.* import kotlinx.serialization.Serializable import kotlinx.serialization.decodeFromString import kotlinx.serialization.json.Json import okhttp3.Request import xyz.quaver.pupil.client import xyz.quaver.pupil.runtime +import xyz.quaver.pupil.runtimeReady import java.io.IOException import java.net.URL import java.util.concurrent.Executors @@ -84,11 +82,11 @@ data class GalleryInfo( val groups: List? = null, val parodys: List? = null, val tags: List? = null, - val related: List, - val languages: List, + val related: List = emptyList(), + val languages: List = emptyList(), val characters: List? = null, - val scene_indexes: List, - val files: List + val scene_indexes: List? = emptyList(), + val files: List = emptyList() ) val json = Json { @@ -135,13 +133,16 @@ val evaluationContext = Executors.newSingleThreadExecutor().asCoroutineDispatche object gg { suspend fun m(g: Int): Int = withContext(evaluationContext) { + while (!runtimeReady) delay(1000) runtime.evaluate("gg.m($g)").toString().toInt() } suspend fun b(): String = withContext(evaluationContext) { + while (!runtimeReady) delay(1000) runtime.evaluate("gg.b").toString() } suspend fun s(h: String): String = withContext(evaluationContext) { + while (!runtimeReady) delay(1000) runtime.evaluate("gg.s('$h')").toString() } } diff --git a/app/src/main/java/xyz/quaver/pupil/hitomi/galleryblock.kt b/app/src/main/java/xyz/quaver/pupil/hitomi/galleryblock.kt index 4868d6aa..eb52a8d7 100644 --- a/app/src/main/java/xyz/quaver/pupil/hitomi/galleryblock.kt +++ b/app/src/main/java/xyz/quaver/pupil/hitomi/galleryblock.kt @@ -71,7 +71,7 @@ data class GalleryBlock( val type: String, val language: String, val relatedTags: List, - val groups: List + val groups: List = emptyList() ) suspend fun getGalleryBlock(galleryID: Int) : GalleryBlock { diff --git a/app/src/main/java/xyz/quaver/pupil/services/DownloadService.kt b/app/src/main/java/xyz/quaver/pupil/services/DownloadService.kt index be93aa2c..85b8246e 100644 --- a/app/src/main/java/xyz/quaver/pupil/services/DownloadService.kt +++ b/app/src/main/java/xyz/quaver/pupil/services/DownloadService.kt @@ -220,28 +220,23 @@ class DownloadService : Service() { CoroutineScope(Dispatchers.IO).launch { runCatching { - response.also { - if (it.code() != 200) throw IOException( - "$galleryID $index ${response.request().url()} CODE ${it.code()}" + val image = response.also { if (it.code() != 200) throw IOException( "$galleryID $index ${response.request().url()} CODE ${it.code()}" ) }.body()?.use { it.bytes() } ?: throw Exception("Response null") + val padding = ceil(progress[galleryID]?.size?.let { log10(it.toFloat()) } ?: 0F).toInt() + + Cache.getInstance(this@DownloadService, galleryID) + .putImage(index, "${index.toString().padStart(padding, '0')}.$ext", image) + + progress[galleryID]?.set(index, Float.POSITIVE_INFINITY) + notify(galleryID) + + if (isCompleted(galleryID)) { + if (DownloadManager.getInstance(this@DownloadService) + .getDownloadFolder(galleryID) != null ) - }.body()?.use { - val padding = ceil(progress[galleryID]?.size?.let { log10(it.toFloat()) } ?: 0F).toInt() + Cache.getInstance(this@DownloadService, galleryID).moveToDownload() - Cache.getInstance(this@DownloadService, galleryID) - .putImage(index, "${index.toString().padStart(padding, '0')}.$ext", it.byteStream()) - - progress[galleryID]?.set(index, Float.POSITIVE_INFINITY) - notify(galleryID) - - if (isCompleted(galleryID)) { - if (DownloadManager.getInstance(this@DownloadService) - .getDownloadFolder(galleryID) != null - ) - Cache.getInstance(this@DownloadService, galleryID).moveToDownload() - - startId?.let { stopSelf(it) } - } - } ?: throw Exception("Response null") + startId?.let { stopSelf(it) } + } }.onFailure { FirebaseCrashlytics.getInstance().recordException(it) } @@ -329,7 +324,8 @@ class DownloadService : Service() { } if (isCompleted(galleryID)) { - Cache.getInstance(this@DownloadService, galleryID).moveToDownload() + if (DownloadManager.getInstance(this@DownloadService).getDownloadFolder(galleryID) != null) + Cache.getInstance(this@DownloadService, galleryID).moveToDownload() notificationManager.cancel(galleryID) startId?.let { stopSelf(it) } diff --git a/app/src/main/java/xyz/quaver/pupil/ui/fragment/ManageStorageFragment.kt b/app/src/main/java/xyz/quaver/pupil/ui/fragment/ManageStorageFragment.kt index 0999f08d..55d8bb62 100644 --- a/app/src/main/java/xyz/quaver/pupil/ui/fragment/ManageStorageFragment.kt +++ b/app/src/main/java/xyz/quaver/pupil/ui/fragment/ManageStorageFragment.kt @@ -43,6 +43,7 @@ import xyz.quaver.io.util.readText import xyz.quaver.io.util.writeText import xyz.quaver.pupil.R import xyz.quaver.pupil.histories +import xyz.quaver.pupil.hitomi.json import xyz.quaver.pupil.util.byteToString import xyz.quaver.pupil.util.downloader.Cache import xyz.quaver.pupil.util.downloader.DownloadManager @@ -118,7 +119,7 @@ class ManageStorageFragment : PreferenceFragmentCompat(), Preference.OnPreferenc if (!metadataFile.exists()) return@forEach val metadata = metadataFile.readText()?.let { - Json.decodeFromString(it) + json.decodeFromString(it) } ?: return@forEach val galleryID = metadata.galleryBlock?.id ?: metadata.galleryInfo?.id?.toIntOrNull() ?: return@forEach diff --git a/app/src/main/java/xyz/quaver/pupil/util/downloader/Cache.kt b/app/src/main/java/xyz/quaver/pupil/util/downloader/Cache.kt index 65a8e83e..84ec746d 100644 --- a/app/src/main/java/xyz/quaver/pupil/util/downloader/Cache.kt +++ b/app/src/main/java/xyz/quaver/pupil/util/downloader/Cache.kt @@ -21,12 +21,9 @@ package xyz.quaver.pupil.util.downloader import android.content.Context import android.content.ContextWrapper import android.net.Uri -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch +import kotlinx.coroutines.* import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock -import kotlinx.coroutines.withContext import kotlinx.serialization.Serializable import kotlinx.serialization.decodeFromString import kotlinx.serialization.encodeToString @@ -35,35 +32,50 @@ import okhttp3.Request import xyz.quaver.io.FileX import xyz.quaver.io.util.* import xyz.quaver.pupil.client -import xyz.quaver.pupil.hitomi.GalleryBlock -import xyz.quaver.pupil.hitomi.GalleryInfo -import xyz.quaver.pupil.hitomi.getGalleryBlock -import xyz.quaver.pupil.hitomi.getGalleryInfo +import xyz.quaver.pupil.hitomi.* import java.io.File import java.io.IOException import java.io.InputStream import java.util.concurrent.ConcurrentHashMap @Serializable -data class OldGalleryBlock( - val code: String, - val id: Int, - val galleryUrl: String, - val thumbnails: List, - val title: String, - val artists: List, - val series: List, - val type: String, - val language: String, - val relatedTags: List +data class OldGalleryInfo( + val language_localname: String? = null, + val language: String? = null, + val date: String? = null, + val files: List, + val id: Int? = null, + val type: String? = null, + val title: String? = null ) +@Serializable +data class OldGalleryFiles( + val width: Int, + val hash: String, + val haswebp: Int = 0, + val name: String, + val height: Int, + val hasavif: Int = 0, + val hasavifsmalltn: Int? = 0 +) + +@Serializable +data class OldMetadata( + var galleryBlock: GalleryBlock? = null, + var reader: OldGalleryInfo? = null, + var imageList: MutableList? = null +) { + fun copy(): OldMetadata = OldMetadata(galleryBlock, reader, imageList?.let { MutableList(it.size) { i -> it[i] } }) +} + @Serializable data class Metadata( var galleryBlock: GalleryBlock? = null, var galleryInfo: GalleryInfo? = null, var imageList: MutableList? = null ) { + constructor(old: OldMetadata) : this(old.galleryBlock, getGalleryInfo(old.galleryBlock?.id ?: throw Exception()), old.imageList) fun copy(): Metadata = Metadata(galleryBlock, galleryInfo, imageList?.let { MutableList(it.size) { i -> it[i] } }) } @@ -90,9 +102,13 @@ class Cache private constructor(context: Context, val galleryID: Int) : ContextW var metadata = kotlin.runCatching { findFile(".metadata")?.readText()?.let { metadata -> - Json.decodeFromString(metadata) + kotlin.runCatching { + json.decodeFromString(metadata) + }.getOrElse { + Metadata(json.decodeFromString(metadata)) + } } - }.getOrNull() ?: Metadata() + }.onFailure { it.printStackTrace() }.getOrNull() ?: Metadata() val downloadFolder: FileX? get() = DownloadManager.getInstance(this).getDownloadFolder(galleryID) @@ -179,14 +195,11 @@ class Cache private constructor(context: Context, val galleryID: Int) : ContextW metadata.imageList?.getOrNull(index)?.let { findFile(it) } @Suppress("BlockingMethodInNonBlockingContext") - fun putImage(index: Int, fileName: String, data: InputStream) { + suspend fun putImage(index: Int, fileName: String, data: ByteArray) = coroutineScope { val file = cacheFolder.getChild(fileName) if (!file.exists()) file.createNewFile() - file.outputStream()?.use { - data.copyTo(it) - } setMetadata { metadata -> metadata.imageList!![index] = fileName } } diff --git a/app/src/main/java/xyz/quaver/pupil/util/misc.kt b/app/src/main/java/xyz/quaver/pupil/util/misc.kt index 44884445..43671f18 100644 --- a/app/src/main/java/xyz/quaver/pupil/util/misc.kt +++ b/app/src/main/java/xyz/quaver/pupil/util/misc.kt @@ -77,8 +77,8 @@ fun OkHttpClient.Builder.proxyInfo(proxyInfo: ProxyInfo) = this.apply { val formatMap = mapOf (String)>( "-id-" to { id.toString() }, "-title-" to { title }, - "-artist-" to { artists.joinToString() }, - "-group-" to { groups.joinToString() } + "-artist-" to { if (artists.isNotEmpty()) artists.joinToString() else "N/A" }, + "-group-" to { if (groups.isNotEmpty()) groups.joinToString() else "N/A" } // TODO ) /**