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
This commit is contained in:
Jobobby04 2023-10-27 17:14:38 -04:00
parent 7565e51f95
commit 6ba8318b8a
7 changed files with 84 additions and 36 deletions

View File

@ -123,7 +123,7 @@ fun WebViewScreenContent(
view: WebView?, view: WebView?,
request: WebResourceRequest?, request: WebResourceRequest?,
): Boolean { ): Boolean {
request?.let { request?.let {
// Don't attempt to open blobs as webpages // Don't attempt to open blobs as webpages
if (it.url.toString().startsWith("blob:http")) { if (it.url.toString().startsWith("blob:http")) {
return false return false

View File

@ -9,9 +9,11 @@ import eu.kanade.tachiyomi.util.storage.saveTo
import kotlinx.serialization.decodeFromString import kotlinx.serialization.decodeFromString
import kotlinx.serialization.encodeToString import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import okhttp3.Response import logcat.LogPriority
import okio.Source
import okio.buffer import okio.buffer
import okio.sink import okio.sink
import tachiyomi.core.util.system.logcat
import tachiyomi.domain.manga.model.Manga import tachiyomi.domain.manga.model.Manga
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy
import java.io.File import java.io.File
@ -159,7 +161,7 @@ class PagePreviewCache(private val context: Context) {
* @throws IOException page error. * @throws IOException page error.
*/ */
@Throws(IOException::class) @Throws(IOException::class)
fun putImageToCache(imageUrl: String, response: Response) { fun putImageToCache(imageUrl: String, source: Source) {
// Initialize editor (edits the values for an entry). // Initialize editor (edits the values for an entry).
var editor: DiskLruCache.Editor? = null 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") editor = diskCache.edit(key) ?: throw IOException("Unable to edit key")
// Get OutputStream and write page with Okio. // Get OutputStream and write page with Okio.
response.body.source().saveTo(editor.newOutputStream(0)) source.buffer().saveTo(editor.newOutputStream(0))
diskCache.flush() diskCache.flush()
editor.commit() editor.commit()
} finally { } finally {
response.body.close() source.close()
editor?.abortUnlessCommitted() editor?.abortUnlessCommitted()
} }
} }
@ -207,6 +209,7 @@ class PagePreviewCache(private val context: Context) {
// Remove file from cache. // Remove file from cache.
diskCache.remove(key) diskCache.remove(key)
} catch (e: Exception) { } catch (e: Exception) {
logcat(LogPriority.WARN, e) { "Failed to remove file from cache" }
false false
} }
} }

View File

@ -24,8 +24,6 @@ import okhttp3.Response
import okhttp3.internal.http.HTTP_NOT_MODIFIED import okhttp3.internal.http.HTTP_NOT_MODIFIED
import okio.Path.Companion.toOkioPath import okio.Path.Companion.toOkioPath
import okio.Source import okio.Source
import okio.buffer
import okio.sink
import tachiyomi.core.util.system.logcat import tachiyomi.core.util.system.logcat
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy
import java.io.File import java.io.File
@ -39,7 +37,9 @@ import java.io.File
class PagePreviewFetcher( class PagePreviewFetcher(
private val page: PagePreview, private val page: PagePreview,
private val options: Options, private val options: Options,
private val pagePreviewFileLazy: Lazy<File>, private val pagePreviewFile: () -> File,
private val isInCache: () -> Boolean,
private val writeToCache: (Source) -> Unit,
private val diskCacheKeyLazy: Lazy<String>, private val diskCacheKeyLazy: Lazy<String>,
private val sourceLazy: Lazy<PagePreviewSource?>, private val sourceLazy: Lazy<PagePreviewSource?>,
private val callFactoryLazy: Lazy<Call.Factory>, private val callFactoryLazy: Lazy<Call.Factory>,
@ -62,14 +62,14 @@ class PagePreviewFetcher(
} }
private suspend fun httpLoader(): FetchResult { private suspend fun httpLoader(): FetchResult {
if (pagePreviewFileLazy.value.exists() && options.diskCachePolicy.readEnabled) { if (isInCache() && options.diskCachePolicy.readEnabled) {
return fileLoader(pagePreviewFileLazy.value) return fileLoader(pagePreviewFile())
} }
var snapshot = readFromDiskCache() var snapshot = readFromDiskCache()
try { try {
// Fetch from disk cache // Fetch from disk cache
if (snapshot != null) { if (snapshot != null) {
val snapshotPagePreviewCache = moveSnapshotToPagePreviewCache(snapshot, pagePreviewFileLazy.value) val snapshotPagePreviewCache = moveSnapshotToPagePreviewCache(snapshot)
if (snapshotPagePreviewCache != null) { if (snapshotPagePreviewCache != null) {
// Read from page preview cache // Read from page preview cache
return fileLoader(snapshotPagePreviewCache) return fileLoader(snapshotPagePreviewCache)
@ -88,7 +88,7 @@ class PagePreviewFetcher(
val responseBody = checkNotNull(response.body) { "Null response source" } val responseBody = checkNotNull(response.body) { "Null response source" }
try { try {
// Read from page preview cache after page preview updated // Read from page preview cache after page preview updated
val responsePagePreviewCache = writeResponseToPagePreviewCache(response, pagePreviewFileLazy.value) val responsePagePreviewCache = writeResponseToPagePreviewCache(response)
if (responsePagePreviewCache != null) { if (responsePagePreviewCache != null) {
return fileLoader(responsePagePreviewCache) return fileLoader(responsePagePreviewCache)
} }
@ -153,45 +153,44 @@ class PagePreviewFetcher(
return request.build() return request.build()
} }
private fun moveSnapshotToPagePreviewCache(snapshot: DiskCache.Snapshot, cacheFile: File): File? { private fun moveSnapshotToPagePreviewCache(snapshot: DiskCache.Snapshot): File? {
return try { return try {
diskCacheLazy.value.run { diskCacheLazy.value.run {
fileSystem.source(snapshot.data).use { input -> fileSystem.source(snapshot.data).use { input ->
writeSourceToPagePreviewCache(input, cacheFile) writeSourceToPagePreviewCache(input)
} }
remove(diskCacheKey) remove(diskCacheKey)
} }
cacheFile.takeIf { it.exists() } return if (isInCache()) {
pagePreviewFile()
} else {
null
}
} catch (e: Exception) { } 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 null
} }
} }
private fun writeResponseToPagePreviewCache(response: Response, cacheFile: File): File? { private fun writeResponseToPagePreviewCache(response: Response): File? {
if (!options.diskCachePolicy.writeEnabled) return null if (!options.diskCachePolicy.writeEnabled) return null
return try { return try {
response.peekBody(Long.MAX_VALUE).source().use { input -> 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) { } 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 null
} }
} }
private fun writeSourceToPagePreviewCache(input: Source, cacheFile: File) { private fun writeSourceToPagePreviewCache(input: Source) {
cacheFile.parentFile?.mkdirs() writeToCache(input)
cacheFile.delete()
try {
cacheFile.sink().buffer().use { output ->
output.writeAll(input)
}
} catch (e: Exception) {
cacheFile.delete()
throw e
}
} }
private fun readFromDiskCache(): DiskCache.Snapshot? { private fun readFromDiskCache(): DiskCache.Snapshot? {
@ -232,7 +231,9 @@ class PagePreviewFetcher(
return PagePreviewFetcher( return PagePreviewFetcher(
page = data, page = data,
options = options, 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) }, diskCacheKeyLazy = lazy { PagePreviewKeyer().key(data, options) },
sourceLazy = lazy { sourceManager.get(data.source) as? PagePreviewSource }, sourceLazy = lazy { sourceManager.get(data.source) as? PagePreviewSource },
callFactoryLazy = callFactoryLazy, callFactoryLazy = callFactoryLazy,

View File

@ -1156,7 +1156,7 @@ class EHentai(
.map { .map {
PagePreviewInfo( PagePreviewInfo(
it.attr("alt").toInt(), it.attr("alt").toInt(),
imageUrl = it.attr("src") imageUrl = it.attr("src"),
) )
} }
} }

View File

@ -180,6 +180,7 @@ class MainActivity : BaseActivity() {
libraryPreferences = libraryPreferences, libraryPreferences = libraryPreferences,
readerPreferences = Injekt.get(), readerPreferences = Injekt.get(),
backupPreferences = Injekt.get(), backupPreferences = Injekt.get(),
pagePreviewCache = Injekt.get(),
) )
} else { } else {
false false

View File

@ -21,6 +21,7 @@ import eu.kanade.domain.ui.UiPreferences
import eu.kanade.tachiyomi.BuildConfig import eu.kanade.tachiyomi.BuildConfig
import eu.kanade.tachiyomi.core.security.SecurityPreferences import eu.kanade.tachiyomi.core.security.SecurityPreferences
import eu.kanade.tachiyomi.data.backup.BackupCreatorJob 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.database.models.Manga
import eu.kanade.tachiyomi.data.library.LibraryUpdateJob import eu.kanade.tachiyomi.data.library.LibraryUpdateJob
import eu.kanade.tachiyomi.data.preference.MANGA_NON_COMPLETED 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.contentOrNull
import kotlinx.serialization.json.jsonArray import kotlinx.serialization.json.jsonArray
import kotlinx.serialization.json.jsonPrimitive import kotlinx.serialization.json.jsonPrimitive
import logcat.LogPriority
import tachiyomi.core.preference.PreferenceStore import tachiyomi.core.preference.PreferenceStore
import tachiyomi.core.util.system.logcat import tachiyomi.core.util.system.logcat
import tachiyomi.data.DatabaseHandler import tachiyomi.data.DatabaseHandler
@ -102,6 +104,7 @@ object EXHMigrations {
libraryPreferences: LibraryPreferences, libraryPreferences: LibraryPreferences,
readerPreferences: ReaderPreferences, readerPreferences: ReaderPreferences,
backupPreferences: BackupPreferences, backupPreferences: BackupPreferences,
pagePreviewCache: PagePreviewCache,
): Boolean { ): Boolean {
val lastVersionCode = preferenceStore.getInt("eh_last_version_code", 0) val lastVersionCode = preferenceStore.getInt("eh_last_version_code", 0)
val oldVersion = lastVersionCode.get() val oldVersion = lastVersionCode.get()
@ -515,6 +518,20 @@ object EXHMigrations {
val trackManager = Injekt.get<TrackManager>() val trackManager = Injekt.get<TrackManager>()
trackManager.mdList.logout() 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) // if (oldVersion under 1) { } (1 is current release version)
// do stuff here when releasing changed crap // do stuff here when releasing changed crap

View File

@ -17,6 +17,7 @@ import eu.kanade.domain.source.service.SourcePreferences
import eu.kanade.domain.ui.UiPreferences import eu.kanade.domain.ui.UiPreferences
import eu.kanade.tachiyomi.core.security.SecurityPreferences import eu.kanade.tachiyomi.core.security.SecurityPreferences
import eu.kanade.tachiyomi.data.backup.models.Backup 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.network.NetworkPreferences
import eu.kanade.tachiyomi.source.SourceManager import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.source.online.all.NHentai import eu.kanade.tachiyomi.source.online.all.NHentai
@ -57,17 +58,42 @@ object DebugFunctions {
val getExhFavoriteMangaWithMetadata: GetExhFavoriteMangaWithMetadata by injectLazy() val getExhFavoriteMangaWithMetadata: GetExhFavoriteMangaWithMetadata by injectLazy()
val getSearchMetadata: GetSearchMetadata by injectLazy() val getSearchMetadata: GetSearchMetadata by injectLazy()
val getAllManga: GetAllManga by injectLazy() val getAllManga: GetAllManga by injectLazy()
val pagePreviewCache: PagePreviewCache by injectLazy()
fun forceUpgradeMigration() { fun forceUpgradeMigration() {
val lastVersionCode = prefsStore.getInt("eh_last_version_code", 0) val lastVersionCode = prefsStore.getInt("eh_last_version_code", 0)
lastVersionCode.set(1) 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() { fun forceSetupJobs() {
val lastVersionCode = prefsStore.getInt("eh_last_version_code", 0) val lastVersionCode = prefsStore.getInt("eh_last_version_code", 0)
lastVersionCode.set(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() { fun resetAgedFlagInEXHManga() {
@ -187,7 +213,7 @@ object DebugFunctions {
""" """
{ {
id: ${info.id}, id: ${info.id},
isPeriodic: ${j.extras["EXTRA_IS_PERIODIC"]}, isPeriodic: ${j.extras.getBoolean("EXTRA_IS_PERIODIC")},
state: ${info.state.name}, state: ${info.state.name},
tags: [ tags: [
${info.tags.joinToString(separator = ",\n ")} ${info.tags.joinToString(separator = ",\n ")}