Using new cache for non-library manga

So it doesn't refetch covers already in cache
This commit is contained in:
Jay 2020-08-09 20:01:27 -04:00
parent 20e81073aa
commit 38fac8341d
3 changed files with 74 additions and 23 deletions

View File

@ -19,6 +19,7 @@ import uy.kohesive.injekt.api.get
import java.io.File import java.io.File
import java.io.IOException import java.io.IOException
import java.io.InputStream import java.io.InputStream
import java.util.concurrent.TimeUnit
/** /**
* Class used to create cover cache. * Class used to create cover cache.
@ -33,6 +34,7 @@ class CoverCache(val context: Context) {
companion object { companion object {
private const val COVERS_DIR = "covers" private const val COVERS_DIR = "covers"
private const val CUSTOM_COVERS_DIR = "covers/custom" private const val CUSTOM_COVERS_DIR = "covers/custom"
private const val ONLINE_COVERS_DIR = "online_covers"
} }
/** Cache directory used for cache management.*/ /** Cache directory used for cache management.*/
@ -41,6 +43,19 @@ class CoverCache(val context: Context) {
/** Cache directory used for custom cover cache management.*/ /** Cache directory used for custom cover cache management.*/
private val customCoverCacheDir = getCacheDir(CUSTOM_COVERS_DIR) private val customCoverCacheDir = getCacheDir(CUSTOM_COVERS_DIR)
/** Cache directory used for covers not in library management.*/
private val onlineCoverDirectory = File(context.cacheDir, ONLINE_COVERS_DIR).also { it.mkdirs() }
private val maxOnlineCacheSize = 50L * 1024L * 1024L // 50 MB
private var lastClean = 0L
/**
* The interval after which this cache should be invalidated. 1 hour shouldn't cause major
* issues, as the cache is only used for UI feedback.
*/
private val renewInterval = TimeUnit.HOURS.toMillis(1)
fun getChapterCacheSize(): String { fun getChapterCacheSize(): String {
return Formatter.formatFileSize(context, DiskUtil.getDirectorySize(cacheDir)) return Formatter.formatFileSize(context, DiskUtil.getDirectorySize(cacheDir))
} }
@ -71,6 +86,33 @@ class CoverCache(val context: Context) {
} }
} }
/**
* Clear out online covers until its under a certain size
*/
fun deleteCachedCovers() {
if (lastClean + renewInterval < System.currentTimeMillis()) {
GlobalScope.launch(Dispatchers.IO) {
val directory = onlineCoverDirectory
val size = DiskUtil.getDirectorySize(directory)
if (size <= maxOnlineCacheSize) {
return@launch
}
var deletedSize = 0L
val files = directory.listFiles()?.sortedBy { it.lastModified() }?.iterator()
?: return@launch
while (files.hasNext()) {
val file = files.next()
deletedSize += file.length()
file.delete()
if (size - deletedSize <= maxOnlineCacheSize) {
break
}
}
}
lastClean = System.currentTimeMillis()
}
}
/** /**
* Returns the custom cover from cache. * Returns the custom cover from cache.
* *
@ -117,7 +159,15 @@ class CoverCache(val context: Context) {
* @return cover image. * @return cover image.
*/ */
fun getCoverFile(manga: Manga): File { fun getCoverFile(manga: Manga): File {
return File(cacheDir, manga.key()) return if (manga.favorite) {
File(cacheDir, manga.key())
} else {
getOnlineCoverFile(manga)
}
}
fun getOnlineCoverFile(manga: Manga): File {
return File(onlineCoverDirectory, manga.key())
} }
fun deleteFromCache(name: String?) { fun deleteFromCache(name: String?) {

View File

@ -7,7 +7,6 @@ import coil.ImageLoader
import coil.decode.GifDecoder import coil.decode.GifDecoder
import coil.decode.ImageDecoderDecoder import coil.decode.ImageDecoderDecoder
import coil.decode.SvgDecoder import coil.decode.SvgDecoder
import coil.util.CoilUtils
import com.chuckerteam.chucker.api.ChuckerInterceptor import com.chuckerteam.chucker.api.ChuckerInterceptor
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
@ -29,7 +28,6 @@ class CoilSetup(context: Context) {
add(ByteArrayFetcher()) add(ByteArrayFetcher())
}.okHttpClient { }.okHttpClient {
OkHttpClient.Builder() OkHttpClient.Builder()
.cache(CoilUtils.createDefaultCache(context))
.addInterceptor(ChuckerInterceptor(context)) .addInterceptor(ChuckerInterceptor(context))
.build() .build()
} }

View File

@ -27,6 +27,7 @@ import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy
import java.io.File import java.io.File
import java.util.Date
class MangaFetcher : Fetcher<Manga> { class MangaFetcher : Fetcher<Manga> {
@ -63,18 +64,18 @@ class MangaFetcher : Fetcher<Manga> {
} }
val coverFile = coverCache.getCoverFile(manga) val coverFile = coverCache.getCoverFile(manga)
if (coverFile.exists() && options.diskCachePolicy.readEnabled) { if (coverFile.exists() && options.diskCachePolicy.readEnabled) {
if (!manga.favorite) {
coverFile.setLastModified(Date().time)
}
return fileLoader(coverFile) return fileLoader(coverFile)
} }
if (!manga.favorite) { val (_, body) = awaitGetCall(
val (response, body) = awaitGetCall(manga) manga, if (manga.favorite) {
!options.networkCachePolicy.readEnabled
return SourceResult(
source = body.source(),
mimeType = getMimeType(manga.thumbnail_url!!, body),
dataSource = if (response.cacheResponse != null) DataSource.DISK else DataSource.NETWORK
)
} else { } else {
val (_, body) = awaitGetCall(manga, !options.networkCachePolicy.readEnabled) false
}
)
val tmpFile = File(coverFile.absolutePath + "_tmp") val tmpFile = File(coverFile.absolutePath + "_tmp")
body.source().use { input -> body.source().use { input ->
@ -84,8 +85,10 @@ class MangaFetcher : Fetcher<Manga> {
} }
tmpFile.renameTo(coverFile) tmpFile.renameTo(coverFile)
return fileLoader(coverFile) if (manga.favorite) {
coverCache.deleteCachedCovers()
} }
return fileLoader(coverFile)
} }
private suspend fun awaitGetCall(manga: Manga, onlyCache: Boolean = false): Pair<Response, private suspend fun awaitGetCall(manga: Manga, onlyCache: Boolean = false): Pair<Response,