From 2fa461b9e0648e1096b41701af2f1a8ef5ade865 Mon Sep 17 00:00:00 2001 From: kunfei Date: Wed, 29 Mar 2023 09:23:01 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=81=A2=E5=A4=8D=E5=A4=87?= =?UTF-8?q?=E4=BB=BD=E7=94=A8=E7=9A=84zip=E5=BA=93=E4=B8=8D=E6=94=AF?= =?UTF-8?q?=E6=8C=815.0,6.0=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../io/legado/app/help/storage/Restore.kt | 9 ++- .../source/edit/BookSourceEditViewModel.kt | 7 +- .../io/legado/app/utils/compress/ZipUtils.kt | 73 +++++++++++++++++-- 3 files changed, 75 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/io/legado/app/help/storage/Restore.kt b/app/src/main/java/io/legado/app/help/storage/Restore.kt index a4cd61626..84f1058f0 100644 --- a/app/src/main/java/io/legado/app/help/storage/Restore.kt +++ b/app/src/main/java/io/legado/app/help/storage/Restore.kt @@ -44,12 +44,13 @@ object Restore { } else { ZipUtils.unZipToPath(File(uri.path!!), Backup.backupPath) } + }.onSuccess { + restoreDatabase() + restoreConfig() + LocalConfig.lastBackup = System.currentTimeMillis() }.onFailure { - AppLog.put("恢复复制文件出错\n${it.localizedMessage}", it) + AppLog.put("复制解压文件出错\n${it.localizedMessage}", it) } - restoreDatabase() - restoreConfig() - LocalConfig.lastBackup = System.currentTimeMillis() } suspend fun restoreDatabase(path: String = Backup.backupPath) { diff --git a/app/src/main/java/io/legado/app/ui/book/source/edit/BookSourceEditViewModel.kt b/app/src/main/java/io/legado/app/ui/book/source/edit/BookSourceEditViewModel.kt index e51d9b4c6..92af5a825 100644 --- a/app/src/main/java/io/legado/app/ui/book/source/edit/BookSourceEditViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/book/source/edit/BookSourceEditViewModel.kt @@ -78,17 +78,18 @@ class BookSourceEditViewModel(application: Application) : BaseViewModel(applicat execute { importSource(text) }.onSuccess { - it?.let(finally) ?: context.toastOnUi("格式不对") + finally.invoke(it) }.onError { context.toastOnUi(it.localizedMessage ?: "Error") + it.printOnDebug() } } - suspend fun importSource(text: String): BookSource? { + suspend fun importSource(text: String): BookSource { return when { text.isAbsUrl() -> { val text1 = okHttpClient.newCallStrResponse { url(text) }.body - text1?.let { importSource(text1) } + importSource(text1!!) } text.isJsonArray() -> { if (text.contains("ruleSearchUrl") || text.contains("ruleFindUrl")) { diff --git a/app/src/main/java/io/legado/app/utils/compress/ZipUtils.kt b/app/src/main/java/io/legado/app/utils/compress/ZipUtils.kt index d5f1509d0..1533ddf06 100644 --- a/app/src/main/java/io/legado/app/utils/compress/ZipUtils.kt +++ b/app/src/main/java/io/legado/app/utils/compress/ZipUtils.kt @@ -1,5 +1,6 @@ package io.legado.app.utils.compress +import android.os.Build import io.legado.app.utils.DebugLog import io.legado.app.utils.printOnDebug import kotlinx.coroutines.Dispatchers.IO @@ -193,16 +194,36 @@ object ZipUtils { } @Throws(SecurityException::class) - fun unZipToPath(inputStream: InputStream, path: String, filter: ((String) -> Boolean)? = null): List { - return ZipArchiveInputStream(inputStream).use { - unZipToPath(it, File(path), filter) + fun unZipToPath( + inputStream: InputStream, + path: String, + filter: ((String) -> Boolean)? = null + ): List { + return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + ZipArchiveInputStream(inputStream).use { + unZipToPath(it, File(path), filter) + } + } else { + ZipInputStream(inputStream).use { + unZipToPath(it, File(path), filter) + } } } @Throws(SecurityException::class) - fun unZipToPath(inputStream: InputStream, dir: File, filter: ((String) -> Boolean)? = null): List { - return ZipArchiveInputStream(inputStream).use { - unZipToPath(it, dir, filter) + fun unZipToPath( + inputStream: InputStream, + dir: File, + filter: ((String) -> Boolean)? = null + ): List { + return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + ZipArchiveInputStream(inputStream).use { + unZipToPath(it, dir, filter) + } + } else { + ZipInputStream(inputStream).use { + unZipToPath(it, dir, filter) + } } } @@ -243,6 +264,44 @@ object ZipUtils { return files } + + @Throws(SecurityException::class) + private fun unZipToPath( + zipInputStream: ZipInputStream, + dir: File, + filter: ((String) -> Boolean)? = null + ): List { + val files = arrayListOf() + var entry: ZipEntry? + while (zipInputStream.nextEntry.also { entry = it } != null) { + val entryName = entry!!.name + val entryFile = File(dir, entryName) + if (!entryFile.canonicalPath.startsWith(dir.canonicalPath)) { + throw SecurityException("压缩文件只能解压到指定路径") + } + if (entry!!.isDirectory) { + if (!entryFile.exists()) { + entryFile.mkdirs() + } + continue + } + if (entryFile.parentFile?.exists() != true) { + entryFile.parentFile?.mkdirs() + } + if (filter != null && !filter.invoke(entryName)) continue + if (!entryFile.exists()) { + entryFile.createNewFile() + entryFile.setReadable(true) + entryFile.setExecutable(true) + } + FileOutputStream(entryFile).use { + zipInputStream.copyTo(it) + files.add(entryFile) + } + } + return files + } + /* 遍历目录获取所有文件名 */ @Throws(SecurityException::class) fun getFilesName( @@ -267,7 +326,7 @@ object ZipUtils { } val fileName = entry!!.name if (filter != null && filter.invoke(fileName)) - fileNames.add(fileName) + fileNames.add(fileName) } return fileNames }