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

@ -8,4 +8,4 @@ package eu.kanade.tachiyomi
object AppInfo { object AppInfo {
fun getVersionCode() = BuildConfig.VERSION_CODE fun getVersionCode() = BuildConfig.VERSION_CODE
fun getVersionName() = BuildConfig.VERSION_NAME fun getVersionName() = BuildConfig.VERSION_NAME
} }

View file

@ -143,7 +143,7 @@ class DownloadCache(
mangaDirs.values.forEach { mangaDir -> mangaDirs.values.forEach { mangaDir ->
val chapterDirs = mangaDir.dir.listFiles() val chapterDirs = mangaDir.dir.listFiles()
.orEmpty() .orEmpty()
.mapNotNull { it.name } .mapNotNull { it.name?.replace(".cbz", "") }
.toHashSet() .toHashSet()
mangaDir.files = chapterDirs 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. * 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. * Cache of downloaded chapters.

View file

@ -148,10 +148,14 @@ class DownloadProvider(private val context: Context) {
* @param chapter the chapter to query. * @param chapter the chapter to query.
*/ */
fun getValidChapterDirNames(chapter: Chapter): List<String> { fun getValidChapterDirNames(chapter: Chapter): List<String> {
val chapterName = getChapterDirName(chapter)
return listOf( 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 // Legacy chapter directory name used in v0.9.2 and before
DiskUtil.buildValidFilename(chapter.name) 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.database.models.Manga
import eu.kanade.tachiyomi.data.download.model.Download import eu.kanade.tachiyomi.data.download.model.Download
import eu.kanade.tachiyomi.data.download.model.DownloadQueue 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.SourceManager
import eu.kanade.tachiyomi.source.UnmeteredSource import eu.kanade.tachiyomi.source.UnmeteredSource
import eu.kanade.tachiyomi.source.model.Page import eu.kanade.tachiyomi.source.model.Page
@ -35,7 +36,11 @@ import rx.android.schedulers.AndroidSchedulers
import rx.schedulers.Schedulers import rx.schedulers.Schedulers
import rx.subscriptions.CompositeSubscription import rx.subscriptions.CompositeSubscription
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy
import java.io.BufferedOutputStream
import java.io.File 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. * This class is the one in charge of downloading chapters.
@ -60,6 +65,8 @@ class Downloader(
private val chapterCache: ChapterCache by injectLazy() private val chapterCache: ChapterCache by injectLazy()
private val preferences: PreferencesHelper by injectLazy()
/** /**
* Store for persisting downloads across restarts. * Store for persisting downloads across restarts.
*/ */
@ -484,13 +491,51 @@ class Downloader(
// Only rename the directory if it's downloaded. // Only rename the directory if it's downloaded.
if (download.status == Download.State.DOWNLOADED) { if (download.status == Download.State.DOWNLOADED) {
tmpDir.renameTo(dirname) if (preferences.saveChaptersAsCBZ().get()) {
archiveChapter(mangaDir, dirname, tmpDir)
} else {
tmpDir.renameTo(dirname)
}
cache.addChapter(dirname, mangaDir, download.manga) cache.addChapter(dirname, mangaDir, download.manga)
DiskUtil.createNoMediaFile(tmpDir, context) 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. * 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 downloadOnlyOverWifi() = prefs.getBoolean(Keys.downloadOnlyOverWifi, true)
fun saveChaptersAsCBZ() = flowPrefs.getBoolean("save_chapter_as_cbz", false)
fun folderPerManga() = prefs.getBoolean(Keys.folderPerManga, false) fun folderPerManga() = prefs.getBoolean(Keys.folderPerManga, false)
fun numberOfBackups() = flowPrefs.getInt("backup_slots", 1) 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.app.Application
import android.net.Uri import android.net.Uri
import com.hippo.unifile.UniFile
import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.download.DownloadManager import eu.kanade.tachiyomi.data.download.DownloadManager
import eu.kanade.tachiyomi.source.Source 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 eu.kanade.tachiyomi.ui.reader.model.ReaderPage
import rx.Observable import rx.Observable
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy
import java.io.File
/** /**
* Loader used to load a chapter from the downloaded chapters. * 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. * Returns an observable containing the pages found on this downloaded chapter.
*/ */
override fun getPages(): Observable<List<ReaderPage>> { 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) return downloadManager.buildPageList(source, manga, chapter.chapter)
.map { pages -> .map { pages ->
pages.map { page -> pages.map { page ->

View file

@ -68,6 +68,10 @@ class SettingsDownloadController : SettingsController() {
titleRes = R.string.connected_to_wifi titleRes = R.string.connected_to_wifi
defaultValue = true defaultValue = true
} }
switchPreference {
bindTo(preferences.saveChaptersAsCBZ())
titleRes = R.string.save_chapter_as_cbz
}
preferenceCategory { preferenceCategory {
titleRes = R.string.pref_category_delete_chapters 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_category_auto_download">Auto-download</string>
<string name="pref_download_new">Download new chapters</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="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 --> <!-- Tracking section -->
<string name="tracking_guide">Tracking guide</string> <string name="tracking_guide">Tracking guide</string>