From 6ba8318b8a0ddc74ab3482471d5ca2ffba23dcfb Mon Sep 17 00:00:00 2001 From: Jobobby04 Date: Fri, 27 Oct 2023 17:14:38 -0400 Subject: [PATCH] Fix page previews cache (cherry picked from commit d600ddc11ad496ab5c8b879b18e6bb1187a05799) # Conflicts: # app/build.gradle.kts # app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt # app/src/main/java/exh/EXHMigrations.kt # app/src/main/java/exh/debug/DebugFunctions.kt --- .../webview/WebViewScreenContent.kt | 2 +- .../tachiyomi/data/cache/PagePreviewCache.kt | 11 ++-- .../tachiyomi/data/coil/PagePreviewFetcher.kt | 55 ++++++++++--------- .../tachiyomi/source/online/all/EHentai.kt | 2 +- .../kanade/tachiyomi/ui/main/MainActivity.kt | 1 + app/src/main/java/exh/EXHMigrations.kt | 17 ++++++ app/src/main/java/exh/debug/DebugFunctions.kt | 32 ++++++++++- 7 files changed, 84 insertions(+), 36 deletions(-) diff --git a/app/src/main/java/eu/kanade/presentation/webview/WebViewScreenContent.kt b/app/src/main/java/eu/kanade/presentation/webview/WebViewScreenContent.kt index 9ed61803b..a5b18ca3e 100644 --- a/app/src/main/java/eu/kanade/presentation/webview/WebViewScreenContent.kt +++ b/app/src/main/java/eu/kanade/presentation/webview/WebViewScreenContent.kt @@ -123,7 +123,7 @@ fun WebViewScreenContent( view: WebView?, request: WebResourceRequest?, ): Boolean { - request?.let { + request?.let { // Don't attempt to open blobs as webpages if (it.url.toString().startsWith("blob:http")) { return false diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/cache/PagePreviewCache.kt b/app/src/main/java/eu/kanade/tachiyomi/data/cache/PagePreviewCache.kt index bbb7c6ba1..21f3eda3d 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/cache/PagePreviewCache.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/cache/PagePreviewCache.kt @@ -9,9 +9,11 @@ import eu.kanade.tachiyomi.util.storage.saveTo import kotlinx.serialization.decodeFromString import kotlinx.serialization.encodeToString import kotlinx.serialization.json.Json -import okhttp3.Response +import logcat.LogPriority +import okio.Source import okio.buffer import okio.sink +import tachiyomi.core.util.system.logcat import tachiyomi.domain.manga.model.Manga import uy.kohesive.injekt.injectLazy import java.io.File @@ -159,7 +161,7 @@ class PagePreviewCache(private val context: Context) { * @throws IOException page error. */ @Throws(IOException::class) - fun putImageToCache(imageUrl: String, response: Response) { + fun putImageToCache(imageUrl: String, source: Source) { // Initialize editor (edits the values for an entry). var editor: DiskLruCache.Editor? = null @@ -169,12 +171,12 @@ class PagePreviewCache(private val context: Context) { editor = diskCache.edit(key) ?: throw IOException("Unable to edit key") // Get OutputStream and write page with Okio. - response.body.source().saveTo(editor.newOutputStream(0)) + source.buffer().saveTo(editor.newOutputStream(0)) diskCache.flush() editor.commit() } finally { - response.body.close() + source.close() editor?.abortUnlessCommitted() } } @@ -207,6 +209,7 @@ class PagePreviewCache(private val context: Context) { // Remove file from cache. diskCache.remove(key) } catch (e: Exception) { + logcat(LogPriority.WARN, e) { "Failed to remove file from cache" } false } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/coil/PagePreviewFetcher.kt b/app/src/main/java/eu/kanade/tachiyomi/data/coil/PagePreviewFetcher.kt index 50a212c4c..432a4069a 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/coil/PagePreviewFetcher.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/coil/PagePreviewFetcher.kt @@ -24,8 +24,6 @@ import okhttp3.Response import okhttp3.internal.http.HTTP_NOT_MODIFIED import okio.Path.Companion.toOkioPath import okio.Source -import okio.buffer -import okio.sink import tachiyomi.core.util.system.logcat import uy.kohesive.injekt.injectLazy import java.io.File @@ -39,7 +37,9 @@ import java.io.File class PagePreviewFetcher( private val page: PagePreview, private val options: Options, - private val pagePreviewFileLazy: Lazy, + private val pagePreviewFile: () -> File, + private val isInCache: () -> Boolean, + private val writeToCache: (Source) -> Unit, private val diskCacheKeyLazy: Lazy, private val sourceLazy: Lazy, private val callFactoryLazy: Lazy, @@ -62,14 +62,14 @@ class PagePreviewFetcher( } private suspend fun httpLoader(): FetchResult { - if (pagePreviewFileLazy.value.exists() && options.diskCachePolicy.readEnabled) { - return fileLoader(pagePreviewFileLazy.value) + if (isInCache() && options.diskCachePolicy.readEnabled) { + return fileLoader(pagePreviewFile()) } var snapshot = readFromDiskCache() try { // Fetch from disk cache if (snapshot != null) { - val snapshotPagePreviewCache = moveSnapshotToPagePreviewCache(snapshot, pagePreviewFileLazy.value) + val snapshotPagePreviewCache = moveSnapshotToPagePreviewCache(snapshot) if (snapshotPagePreviewCache != null) { // Read from page preview cache return fileLoader(snapshotPagePreviewCache) @@ -88,7 +88,7 @@ class PagePreviewFetcher( val responseBody = checkNotNull(response.body) { "Null response source" } try { // Read from page preview cache after page preview updated - val responsePagePreviewCache = writeResponseToPagePreviewCache(response, pagePreviewFileLazy.value) + val responsePagePreviewCache = writeResponseToPagePreviewCache(response) if (responsePagePreviewCache != null) { return fileLoader(responsePagePreviewCache) } @@ -153,45 +153,44 @@ class PagePreviewFetcher( return request.build() } - private fun moveSnapshotToPagePreviewCache(snapshot: DiskCache.Snapshot, cacheFile: File): File? { + private fun moveSnapshotToPagePreviewCache(snapshot: DiskCache.Snapshot): File? { return try { diskCacheLazy.value.run { fileSystem.source(snapshot.data).use { input -> - writeSourceToPagePreviewCache(input, cacheFile) + writeSourceToPagePreviewCache(input) } remove(diskCacheKey) } - cacheFile.takeIf { it.exists() } + return if (isInCache()) { + pagePreviewFile() + } else { + null + } } catch (e: Exception) { - logcat(LogPriority.ERROR, e) { "Failed to write snapshot data to page preview cache ${cacheFile.name}" } + logcat(LogPriority.ERROR, e) { "Failed to write snapshot data to page preview cache $diskCacheKey" } null } } - private fun writeResponseToPagePreviewCache(response: Response, cacheFile: File): File? { + private fun writeResponseToPagePreviewCache(response: Response): File? { if (!options.diskCachePolicy.writeEnabled) return null return try { response.peekBody(Long.MAX_VALUE).source().use { input -> - writeSourceToPagePreviewCache(input, cacheFile) + writeSourceToPagePreviewCache(input) + } + return if (isInCache()) { + pagePreviewFile() + } else { + null } - cacheFile.takeIf { it.exists() } } catch (e: Exception) { - logcat(LogPriority.ERROR, e) { "Failed to write response data to page preview cache ${cacheFile.name}" } + logcat(LogPriority.ERROR, e) { "Failed to write response data to page preview cache $diskCacheKey" } null } } - private fun writeSourceToPagePreviewCache(input: Source, cacheFile: File) { - cacheFile.parentFile?.mkdirs() - cacheFile.delete() - try { - cacheFile.sink().buffer().use { output -> - output.writeAll(input) - } - } catch (e: Exception) { - cacheFile.delete() - throw e - } + private fun writeSourceToPagePreviewCache(input: Source) { + writeToCache(input) } private fun readFromDiskCache(): DiskCache.Snapshot? { @@ -232,7 +231,9 @@ class PagePreviewFetcher( return PagePreviewFetcher( page = data, options = options, - pagePreviewFileLazy = lazy { pagePreviewCache.getImageFile(data.imageUrl) }, + pagePreviewFile = { pagePreviewCache.getImageFile(data.imageUrl) }, + isInCache = { pagePreviewCache.isImageInCache(data.imageUrl) }, + writeToCache = { pagePreviewCache.putImageToCache(data.imageUrl, it) }, diskCacheKeyLazy = lazy { PagePreviewKeyer().key(data, options) }, sourceLazy = lazy { sourceManager.get(data.source) as? PagePreviewSource }, callFactoryLazy = callFactoryLazy, diff --git a/app/src/main/java/eu/kanade/tachiyomi/source/online/all/EHentai.kt b/app/src/main/java/eu/kanade/tachiyomi/source/online/all/EHentai.kt index 3aad2d3bf..25354a022 100755 --- a/app/src/main/java/eu/kanade/tachiyomi/source/online/all/EHentai.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/source/online/all/EHentai.kt @@ -1156,7 +1156,7 @@ class EHentai( .map { PagePreviewInfo( it.attr("alt").toInt(), - imageUrl = it.attr("src") + imageUrl = it.attr("src"), ) } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt index 15c381833..82044db2d 100755 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt @@ -180,6 +180,7 @@ class MainActivity : BaseActivity() { libraryPreferences = libraryPreferences, readerPreferences = Injekt.get(), backupPreferences = Injekt.get(), + pagePreviewCache = Injekt.get(), ) } else { false diff --git a/app/src/main/java/exh/EXHMigrations.kt b/app/src/main/java/exh/EXHMigrations.kt index 9c6ce359b..dff924b27 100644 --- a/app/src/main/java/exh/EXHMigrations.kt +++ b/app/src/main/java/exh/EXHMigrations.kt @@ -21,6 +21,7 @@ import eu.kanade.domain.ui.UiPreferences import eu.kanade.tachiyomi.BuildConfig import eu.kanade.tachiyomi.core.security.SecurityPreferences import eu.kanade.tachiyomi.data.backup.BackupCreatorJob +import eu.kanade.tachiyomi.data.cache.PagePreviewCache import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.library.LibraryUpdateJob import eu.kanade.tachiyomi.data.preference.MANGA_NON_COMPLETED @@ -56,6 +57,7 @@ import kotlinx.serialization.json.JsonObject import kotlinx.serialization.json.contentOrNull import kotlinx.serialization.json.jsonArray import kotlinx.serialization.json.jsonPrimitive +import logcat.LogPriority import tachiyomi.core.preference.PreferenceStore import tachiyomi.core.util.system.logcat import tachiyomi.data.DatabaseHandler @@ -102,6 +104,7 @@ object EXHMigrations { libraryPreferences: LibraryPreferences, readerPreferences: ReaderPreferences, backupPreferences: BackupPreferences, + pagePreviewCache: PagePreviewCache, ): Boolean { val lastVersionCode = preferenceStore.getInt("eh_last_version_code", 0) val oldVersion = lastVersionCode.get() @@ -515,6 +518,20 @@ object EXHMigrations { val trackManager = Injekt.get() trackManager.mdList.logout() } + if (oldVersion under 51) { + pagePreviewCache.clear() + File(context.cacheDir, PagePreviewCache.PARAMETER_CACHE_DIRECTORY).listFiles()?.forEach { + if (it.name == "journal" || it.name.startsWith("journal.")) { + return@forEach + } + + try { + it.delete() + } catch (e: Exception) { + logcat(LogPriority.WARN, e) { "Failed to remove file from cache" } + } + } + } // if (oldVersion under 1) { } (1 is current release version) // do stuff here when releasing changed crap diff --git a/app/src/main/java/exh/debug/DebugFunctions.kt b/app/src/main/java/exh/debug/DebugFunctions.kt index c3eb1ba55..5c7109a83 100644 --- a/app/src/main/java/exh/debug/DebugFunctions.kt +++ b/app/src/main/java/exh/debug/DebugFunctions.kt @@ -17,6 +17,7 @@ import eu.kanade.domain.source.service.SourcePreferences import eu.kanade.domain.ui.UiPreferences import eu.kanade.tachiyomi.core.security.SecurityPreferences import eu.kanade.tachiyomi.data.backup.models.Backup +import eu.kanade.tachiyomi.data.cache.PagePreviewCache import eu.kanade.tachiyomi.network.NetworkPreferences import eu.kanade.tachiyomi.source.SourceManager import eu.kanade.tachiyomi.source.online.all.NHentai @@ -57,17 +58,42 @@ object DebugFunctions { val getExhFavoriteMangaWithMetadata: GetExhFavoriteMangaWithMetadata by injectLazy() val getSearchMetadata: GetSearchMetadata by injectLazy() val getAllManga: GetAllManga by injectLazy() + val pagePreviewCache: PagePreviewCache by injectLazy() fun forceUpgradeMigration() { val lastVersionCode = prefsStore.getInt("eh_last_version_code", 0) lastVersionCode.set(1) - EXHMigrations.upgrade(app, prefsStore, basePrefs, uiPrefs, networkPrefs, sourcePrefs, securityPrefs, libraryPrefs, readerPrefs, backupPrefs) + EXHMigrations.upgrade( + context = app, + preferenceStore = prefsStore, + basePreferences = basePrefs, + uiPreferences = uiPrefs, + networkPreferences = networkPrefs, + sourcePreferences = sourcePrefs, + securityPreferences = securityPrefs, + libraryPreferences = libraryPrefs, + readerPreferences = readerPrefs, + backupPreferences = backupPrefs, + pagePreviewCache = pagePreviewCache, + ) } fun forceSetupJobs() { val lastVersionCode = prefsStore.getInt("eh_last_version_code", 0) lastVersionCode.set(0) - EXHMigrations.upgrade(app, prefsStore, basePrefs, uiPrefs, networkPrefs, sourcePrefs, securityPrefs, libraryPrefs, readerPrefs, backupPrefs) + EXHMigrations.upgrade( + context = app, + preferenceStore = prefsStore, + basePreferences = basePrefs, + uiPreferences = uiPrefs, + networkPreferences = networkPrefs, + sourcePreferences = sourcePrefs, + securityPreferences = securityPrefs, + libraryPreferences = libraryPrefs, + readerPreferences = readerPrefs, + backupPreferences = backupPrefs, + pagePreviewCache = pagePreviewCache, + ) } fun resetAgedFlagInEXHManga() { @@ -187,7 +213,7 @@ object DebugFunctions { """ { id: ${info.id}, - isPeriodic: ${j.extras["EXTRA_IS_PERIODIC"]}, + isPeriodic: ${j.extras.getBoolean("EXTRA_IS_PERIODIC")}, state: ${info.state.name}, tags: [ ${info.tags.joinToString(separator = ",\n ")}