mirror of
https://github.com/tachiyomiorg/tachiyomi.git
synced 2024-11-12 21:35:18 +01:00
Using new cache for non-library manga
So it doesn't refetch covers already in cache
This commit is contained in:
parent
20e81073aa
commit
38fac8341d
@ -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?) {
|
||||||
|
@ -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()
|
||||||
}
|
}
|
||||||
|
@ -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,29 +64,31 @@ 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) {
|
||||||
return fileLoader(coverFile)
|
if (!manga.favorite) {
|
||||||
}
|
coverFile.setLastModified(Date().time)
|
||||||
if (!manga.favorite) {
|
|
||||||
val (response, body) = awaitGetCall(manga)
|
|
||||||
|
|
||||||
return SourceResult(
|
|
||||||
source = body.source(),
|
|
||||||
mimeType = getMimeType(manga.thumbnail_url!!, body),
|
|
||||||
dataSource = if (response.cacheResponse != null) DataSource.DISK else DataSource.NETWORK
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
val (_, body) = awaitGetCall(manga, !options.networkCachePolicy.readEnabled)
|
|
||||||
|
|
||||||
val tmpFile = File(coverFile.absolutePath + "_tmp")
|
|
||||||
body.source().use { input ->
|
|
||||||
tmpFile.sink().buffer().use { output ->
|
|
||||||
output.writeAll(input)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tmpFile.renameTo(coverFile)
|
|
||||||
return fileLoader(coverFile)
|
return fileLoader(coverFile)
|
||||||
}
|
}
|
||||||
|
val (_, body) = awaitGetCall(
|
||||||
|
manga, if (manga.favorite) {
|
||||||
|
!options.networkCachePolicy.readEnabled
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
val tmpFile = File(coverFile.absolutePath + "_tmp")
|
||||||
|
body.source().use { input ->
|
||||||
|
tmpFile.sink().buffer().use { output ->
|
||||||
|
output.writeAll(input)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tmpFile.renameTo(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,
|
||||||
|
Loading…
Reference in New Issue
Block a user