本地书籍界面支持导入压缩文件

This commit is contained in:
Xwite
2023-03-16 17:56:23 +08:00
parent 72d37fa715
commit 9b00b6cef7
4 changed files with 35 additions and 12 deletions
@@ -25,7 +25,7 @@ object AppPattern {
//本地书籍支持类型 //本地书籍支持类型
val bookFileRegex = Regex(".*\\.(txt|epub|umd|pdf)", RegexOption.IGNORE_CASE) val bookFileRegex = Regex(".*\\.(txt|epub|umd|pdf)", RegexOption.IGNORE_CASE)
//压缩文件支持类型 //压缩文件支持类型
val archiveFileRegex = Regex(".*\\.(zip|rar|7z)", RegexOption.IGNORE_CASE) val archiveFileRegex = Regex(".*\\.(zip|rar|7z)$", RegexOption.IGNORE_CASE)
/** /**
* 所有标点 * 所有标点
@@ -188,9 +188,10 @@ object LocalBook {
return book return book
} }
/* 导入压缩包内的书籍 */
fun importArchiveFile( fun importArchiveFile(
uri: Uri, uri: Uri,
saveFileName: String, saveFileName: String? = null
filter: ((String) -> Boolean)? = null filter: ((String) -> Boolean)? = null
): List<Book> { ): List<Book> {
val files = ArchiveUtils.deCompress(uri, filter = filter) val files = ArchiveUtils.deCompress(uri, filter = filter)
@@ -198,13 +199,34 @@ object LocalBook {
return files.map { return files.map {
saveBookFile( saveBookFile(
FileInputStream(it), FileInputStream(it),
saveFileName saveFileName ?: it.name
).let { ).let {
importFile(it) importFile(it)
} }
} }
} }
/* 批量导入 支持自动导入压缩包的支持书籍 */
fun importFiles(uris: List<Uri>) {
var errorCount = 0
uris.forEach { uri ->
val fileDoc = FileDoc.fromUri(uri, false)
kotlin.runCatching {
if (ArchiveUtils.isArchive(fileDoc.name)) {
importArchiveFile(uri) {
it.matches(AppPattern.bookFileRegex)
}
} else {
importFile(uri)
}
}.onFailure {
AppLog.put("ImportFile Error:\nFile ${fileDoc.toString()}\n${it.localizedMessage}", it)
errorCount = errorCount + 1
}
}
if (errorCount == uris.size) throw NoStackTraceException("ImportFiles Error:\nAll input files occur error")
}
/** /**
* 从文件分析书籍必要信息(书名 作者等) * 从文件分析书籍必要信息(书名 作者等)
*/ */
@@ -5,6 +5,7 @@ import android.net.Uri
import androidx.documentfile.provider.DocumentFile import androidx.documentfile.provider.DocumentFile
import io.legado.app.base.BaseViewModel import io.legado.app.base.BaseViewModel
import io.legado.app.constant.AppLog import io.legado.app.constant.AppLog
import io.legado.app.constant.AppPattern.archiveFileRegex
import io.legado.app.constant.AppPattern.bookFileRegex import io.legado.app.constant.AppPattern.bookFileRegex
import io.legado.app.constant.PreferKey import io.legado.app.constant.PreferKey
import io.legado.app.model.localBook.LocalBook import io.legado.app.model.localBook.LocalBook
@@ -84,9 +85,11 @@ class ImportBookViewModel(application: Application) : BaseViewModel(application)
fun addToBookshelf(uriList: HashSet<String>, finally: () -> Unit) { fun addToBookshelf(uriList: HashSet<String>, finally: () -> Unit) {
execute { execute {
val fileUris = mutableListOf<Uri>()
uriList.forEach { uriList.forEach {
LocalBook.importFile(Uri.parse(it)) fileUris.add(Uri.parse(it))
} }
LocalBook.importFiles(fileUris)
}.onError { }.onError {
context.toastOnUi("添加书架失败,请尝试重新选择文件夹") context.toastOnUi("添加书架失败,请尝试重新选择文件夹")
AppLog.put("添加书架失败\n${it.localizedMessage}", it) AppLog.put("添加书架失败\n${it.localizedMessage}", it)
@@ -118,7 +121,7 @@ class ImportBookViewModel(application: Application) : BaseViewModel(application)
when { when {
item.name.startsWith(".") -> false item.name.startsWith(".") -> false
item.isDir -> true item.isDir -> true
else -> item.name.matches(bookFileRegex) else -> item.name.matches(bookFileRegex) || item.name.matches(archiveFileRegex)
} }
} }
dataCallback?.setItems(docList!!) dataCallback?.setItems(docList!!)
@@ -149,7 +152,8 @@ class ImportBookViewModel(application: Application) : BaseViewModel(application)
} }
if (docItem.isDir) { if (docItem.isDir) {
scanDoc(docItem, false, scope) scanDoc(docItem, false, scope)
} else if (docItem.name.matches(bookFileRegex)) { } else if (docItem.name.matches(bookFileRegex) || docItem.name.matches(archiveFileRegex)
) {
list.add(docItem) list.add(docItem)
} }
} }
@@ -2,6 +2,7 @@ package io.legado.app.utils
import android.net.Uri import android.net.Uri
import androidx.documentfile.provider.DocumentFile import androidx.documentfile.provider.DocumentFile
import io.legado.app.constant.AppPattern.archiveFileRegex
import io.legado.app.utils.compress.RarUtils import io.legado.app.utils.compress.RarUtils
import io.legado.app.utils.compress.SevenZipUtils import io.legado.app.utils.compress.SevenZipUtils
import io.legado.app.utils.compress.ZipUtils import io.legado.app.utils.compress.ZipUtils
@@ -95,12 +96,8 @@ object ArchiveUtils {
} }
} }
fun checkAchieve(name: String) { fun checkAchieve(name: String): Boolean {
if ( if (archiveFileRegex.matches(name)) return true
name.endsWith(".zip", ignoreCase = true) ||
name.endsWith(".rar", ignoreCase = true) ||
name.endsWith(".7z", ignoreCase = true)
) return
throw IllegalArgumentException("Unexpected file suffix: Only 7z rar zip Accepted") throw IllegalArgumentException("Unexpected file suffix: Only 7z rar zip Accepted")
} }