From d0fbb3539f3b6a4aa5dfdb3510cf32aca57d4e77 Mon Sep 17 00:00:00 2001 From: FooIbar <118464521+FooIbar@users.noreply.github.com> Date: Wed, 28 Feb 2024 16:06:08 +0800 Subject: [PATCH] Initial save downloaded gallery as cbz archive (#808) * Initial save downloaded gallery as cbz archive * Make save as cbz archive opt-in --- .../main/kotlin/com/hippo/ehviewer/Settings.kt | 1 + .../hippo/ehviewer/download/DownloadManager.kt | 4 ++++ .../com/hippo/ehviewer/spider/SpiderDen.kt | 16 ++++++++++++++++ .../com/hippo/ehviewer/spider/SpiderQueen.kt | 13 ++++++++++++- .../hippo/ehviewer/ui/settings/DownloadScreen.kt | 4 ++++ app/src/main/res/values-zh-rCN/strings.xml | 1 + app/src/main/res/values/strings.xml | 1 + 7 files changed, 39 insertions(+), 1 deletion(-) diff --git a/app/src/main/kotlin/com/hippo/ehviewer/Settings.kt b/app/src/main/kotlin/com/hippo/ehviewer/Settings.kt index 1238f1045..1b278009f 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/Settings.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/Settings.kt @@ -152,6 +152,7 @@ object Settings : DataStorePreferences(null) { var harmonizeCategoryColor by boolPref("harmonize_category_color", true) var preloadThumbAggressively by boolPref("preload_thumb_aggressively", false) var downloadOriginImage by boolPref("download_origin_image", false) + var saveAsCbz by boolPref("save_as_cbz", false) var archiveMetadata by boolPref("archive_metadata", true) var enableCronet by boolPref("enable_cronet", true) var recentFavCat by intPref("recent_fav_cat", FavListUrlBuilder.FAV_CAT_LOCAL) diff --git a/app/src/main/kotlin/com/hippo/ehviewer/download/DownloadManager.kt b/app/src/main/kotlin/com/hippo/ehviewer/download/DownloadManager.kt index 680b2f975..92b2b7853 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/download/DownloadManager.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/download/DownloadManager.kt @@ -612,6 +612,10 @@ object DownloadManager : OnSpiderListener, CoroutineScope { mCurrentSpider?.let { spider -> mCurrentSpider = null spider.removeOnSpiderListener(DownloadManager) + if (finished == total && Settings.saveAsCbz) { + // Delay file deletion to `SpiderQueen.stop` as they may still be in use by reader + spider.mSpiderDen.archive() + } SpiderQueen.releaseSpiderQueen(spider, SpiderQueen.MODE_DOWNLOAD) } mCurrentTask?.let { info -> diff --git a/app/src/main/kotlin/com/hippo/ehviewer/spider/SpiderDen.kt b/app/src/main/kotlin/com/hippo/ehviewer/spider/SpiderDen.kt index dd13d90af..25f69563b 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/spider/SpiderDen.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/spider/SpiderDen.kt @@ -238,6 +238,22 @@ class SpiderDen(val info: GalleryInfo) { } } + suspend fun archive() { + downloadDir?.run { + val filename = "${info.gid}.cbz" + findFile(filename) ?: createFile(filename)?.let { file -> + runCatching { + val success = exportAsCbz(file) + check(success) + }.onFailure { + logcat(it) + file.delete() + throw it + } + } + } + } + suspend fun exportAsCbz(file: UniFile) = resourceScope { val comicInfo = closeable { val f = downloadDir!! / COMIC_INFO_FILE diff --git a/app/src/main/kotlin/com/hippo/ehviewer/spider/SpiderQueen.kt b/app/src/main/kotlin/com/hippo/ehviewer/spider/SpiderQueen.kt index d97bc44d3..db5f3e9a4 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/spider/SpiderQueen.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/spider/SpiderQueen.kt @@ -242,7 +242,17 @@ class SpiderQueen private constructor(val galleryInfo: GalleryInfo) : CoroutineS launchIO { queenScope.cancel() runCatching { - writeSpiderInfoToLocal() + val dir = mSpiderDen.downloadDir + if (Settings.saveAsCbz && dir?.findFile("${galleryInfo.gid}.cbz") != null) { + dir.listFiles().forEach { + if (it.name?.matches(filenamePattern) == true) { + it.delete() + } + } + dir.findFile(SPIDER_INFO_FILENAME)?.delete() + } else { + writeSpiderInfoToLocal() + } }.onFailure { logcat(it) } @@ -469,6 +479,7 @@ class SpiderQueen private constructor(val galleryInfo: GalleryInfo) : CoroutineS const val STATE_FAILED = 3 const val SPIDER_INFO_FILENAME = ".ehviewer" private val sQueenMap = LongSparseArray() + private val filenamePattern = Regex("^\\d{8}\\.\\w{3,4}") fun obtainSpiderQueen(galleryInfo: GalleryInfo, @Mode mode: Int): SpiderQueen { val gid = galleryInfo.gid diff --git a/app/src/main/kotlin/com/hippo/ehviewer/ui/settings/DownloadScreen.kt b/app/src/main/kotlin/com/hippo/ehviewer/ui/settings/DownloadScreen.kt index c31d536b0..4524f8fbf 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/ui/settings/DownloadScreen.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/ui/settings/DownloadScreen.kt @@ -146,6 +146,10 @@ fun DownloadScreen(navigator: DestinationsNavigator) { summary = stringResource(id = R.string.settings_download_download_origin_image_summary), value = Settings::downloadOriginImage, ) + SwitchPreference( + title = stringResource(id = R.string.settings_download_save_as_cbz), + value = Settings::saveAsCbz, + ) SwitchPreference( title = stringResource(id = R.string.settings_download_archive_metadata), summary = stringResource(id = R.string.settings_download_archive_metadata_summary), diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 6a67a1072..3c8af217a 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -330,6 +330,7 @@ 向后预载 %s 张图片 下载原图 警告!可能需要 GP + 保存为 CBZ 压缩包 压缩包元数据 下载压缩包时生成 ComicInfo.xml 允许媒体扫描 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 5638f6527..778f08947 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -377,6 +377,7 @@ Preload next %s image Download original image Caution! May require GP + Save as CBZ archive Archive metadata Generate ComicInfo.xml on archive download Restore download items