Add compress to CBZ on download (#6360)

This commit is contained in:
Seishirou101 2022-01-01 19:22:35 +00:00 committed by arkon
parent 22615f5981
commit 5336c5b46e
9 changed files with 78 additions and 6 deletions

View File

@ -143,7 +143,7 @@ class DownloadCache(
mangaDirs.values.forEach { mangaDir ->
val chapterDirs = mangaDir.dir.listFiles()
.orEmpty()
.mapNotNull { it.name }
.mapNotNull { it.name?.replace(".cbz", "") }
.toHashSet()
mangaDir.files = chapterDirs

View File

@ -39,7 +39,7 @@ class DownloadManager(
/**
* Downloads provider, used to retrieve the folders where the chapters are or should be stored.
*/
private val provider = DownloadProvider(context)
val provider = DownloadProvider(context)
/**
* Cache of downloaded chapters.

View File

@ -148,10 +148,14 @@ class DownloadProvider(private val context: Context) {
* @param chapter the chapter to query.
*/
fun getValidChapterDirNames(chapter: Chapter): List<String> {
val chapterName = getChapterDirName(chapter)
return listOf(
getChapterDirName(chapter),
// Folder of images
chapterName,
// Archived chapters
"$chapterName.cbz",
// TODO: remove this
// Legacy chapter directory name used in v0.9.2 and before
DiskUtil.buildValidFilename(chapter.name)
)

View File

@ -12,6 +12,7 @@ import eu.kanade.tachiyomi.data.database.models.Chapter
import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.download.model.Download
import eu.kanade.tachiyomi.data.download.model.DownloadQueue
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.source.UnmeteredSource
import eu.kanade.tachiyomi.source.model.Page
@ -35,7 +36,11 @@ import rx.android.schedulers.AndroidSchedulers
import rx.schedulers.Schedulers
import rx.subscriptions.CompositeSubscription
import uy.kohesive.injekt.injectLazy
import java.io.BufferedOutputStream
import java.io.File
import java.util.zip.CRC32
import java.util.zip.ZipEntry
import java.util.zip.ZipOutputStream
/**
* This class is the one in charge of downloading chapters.
@ -60,6 +65,8 @@ class Downloader(
private val chapterCache: ChapterCache by injectLazy()
private val preferences: PreferencesHelper by injectLazy()
/**
* Store for persisting downloads across restarts.
*/
@ -484,13 +491,51 @@ class Downloader(
// Only rename the directory if it's downloaded.
if (download.status == Download.State.DOWNLOADED) {
if (preferences.saveChaptersAsCBZ().get()) {
archiveChapter(mangaDir, dirname, tmpDir)
} else {
tmpDir.renameTo(dirname)
}
cache.addChapter(dirname, mangaDir, download.manga)
DiskUtil.createNoMediaFile(tmpDir, context)
}
}
/**
* Archive the chapter pages as a CBZ.
*/
private fun archiveChapter(
mangaDir: UniFile,
dirname: String,
tmpDir: UniFile,
) {
val zip = mangaDir.createFile("$dirname.cbz.tmp")
ZipOutputStream(BufferedOutputStream(zip.openOutputStream())).use { zipOut ->
zipOut.setMethod(ZipEntry.STORED)
tmpDir.listFiles()?.forEach { img ->
img.openInputStream().use { input ->
val data = input.readBytes()
val size = img.length()
val entry = ZipEntry(img.name).apply {
val crc = CRC32().apply {
update(data)
}
setCrc(crc.value)
compressedSize = size
setSize(size)
}
zipOut.putNextEntry(entry)
zipOut.write(data)
}
}
}
zip.renameTo("$dirname.cbz")
tmpDir.delete()
}
/**
* Completes a download. This method is called in the main thread.
*/

View File

@ -202,6 +202,8 @@ class PreferencesHelper(val context: Context) {
fun downloadOnlyOverWifi() = prefs.getBoolean(Keys.downloadOnlyOverWifi, true)
fun saveChaptersAsCBZ() = flowPrefs.getBoolean("save_chapter_as_cbz", false)
fun folderPerManga() = prefs.getBoolean(Keys.folderPerManga, false)
fun numberOfBackups() = flowPrefs.getInt("backup_slots", 1)

View File

@ -2,6 +2,7 @@ package eu.kanade.tachiyomi.ui.reader.loader
import android.app.Application
import android.net.Uri
import com.hippo.unifile.UniFile
import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.download.DownloadManager
import eu.kanade.tachiyomi.source.Source
@ -10,6 +11,7 @@ import eu.kanade.tachiyomi.ui.reader.model.ReaderChapter
import eu.kanade.tachiyomi.ui.reader.model.ReaderPage
import rx.Observable
import uy.kohesive.injekt.injectLazy
import java.io.File
/**
* Loader used to load a chapter from the downloaded chapters.
@ -28,6 +30,20 @@ class DownloadPageLoader(
* Returns an observable containing the pages found on this downloaded chapter.
*/
override fun getPages(): Observable<List<ReaderPage>> {
val chapterPath = downloadManager.provider.findChapterDir(chapter.chapter, manga, source)
return if (chapterPath?.isFile == true) {
getPagesFromArchive(chapterPath)
} else {
getPagesFromDirectory()
}
}
private fun getPagesFromArchive(chapterPath: UniFile): Observable<List<ReaderPage>> {
val loader = ZipPageLoader(File(chapterPath.filePath!!))
return loader.getPages()
}
private fun getPagesFromDirectory(): Observable<List<ReaderPage>> {
return downloadManager.buildPageList(source, manga, chapter.chapter)
.map { pages ->
pages.map { page ->

View File

@ -68,6 +68,10 @@ class SettingsDownloadController : SettingsController() {
titleRes = R.string.connected_to_wifi
defaultValue = true
}
switchPreference {
bindTo(preferences.saveChaptersAsCBZ())
titleRes = R.string.save_chapter_as_cbz
}
preferenceCategory {
titleRes = R.string.pref_category_delete_chapters

View File

@ -398,6 +398,7 @@
<string name="pref_category_auto_download">Auto-download</string>
<string name="pref_download_new">Download new chapters</string>
<string name="pref_download_new_categories_details">Manga in excluded categories will not be downloaded even if they are also in included categories.</string>
<string name="save_chapter_as_cbz">Save as CBZ archive</string>
<!-- Tracking section -->
<string name="tracking_guide">Tracking guide</string>