From 7c5926dfe68dc6153748c0216089f9d1a0ccf8e6 Mon Sep 17 00:00:00 2001 From: Xwite <1797350009@qq.com> Date: Fri, 10 Mar 2023 08:07:41 +0800 Subject: [PATCH] =?UTF-8?q?fix(LocalBook.saveBookFile):=20=E4=BF=9D?= =?UTF-8?q?=E5=AD=98=E5=89=8D=E6=A3=80=E6=9F=A5=E6=98=AFinputstream?= =?UTF-8?q?=E5=90=A6=E4=B8=BA=E7=A9=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../legado/app/model/localBook/LocalBook.kt | 6 ++- .../io/legado/app/model/localBook/TextFile.kt | 4 +- .../app/ui/book/info/BookInfoActivity.kt | 38 ++++++++++--------- .../app/ui/book/info/BookInfoViewModel.kt | 4 +- .../legado/app/utils/InputStreamExtensions.kt | 12 ++++++ 5 files changed, 41 insertions(+), 23 deletions(-) diff --git a/app/src/main/java/io/legado/app/model/localBook/LocalBook.kt b/app/src/main/java/io/legado/app/model/localBook/LocalBook.kt index 4bd3abb48..0e150f087 100644 --- a/app/src/main/java/io/legado/app/model/localBook/LocalBook.kt +++ b/app/src/main/java/io/legado/app/model/localBook/LocalBook.kt @@ -13,6 +13,7 @@ import io.legado.app.data.entities.BaseSource import io.legado.app.data.entities.Book import io.legado.app.data.entities.BookChapter import io.legado.app.exception.NoStackTraceException +import io.legado.app.exception.EmptyFileException import io.legado.app.exception.TocEmptyException import io.legado.app.help.AppWebDav import io.legado.app.help.book.* @@ -258,7 +259,7 @@ object LocalBook { ): Uri { AppConfig.defaultBookTreeUri ?: throw NoStackTraceException("没有设置书籍保存位置!") - val bytes = when { + val inputStream = when { str.isAbsUrl() -> AnalyzeUrl(str, source = source).getInputStream() str.isDataUrl() -> ByteArrayInputStream( Base64.decode( @@ -268,7 +269,7 @@ object LocalBook { ) else -> throw NoStackTraceException("在线导入书籍支持http/https/DataURL") } - return saveBookFile(bytes, fileName) + return saveBookFile(inputStream, fileName) } /** @@ -289,6 +290,7 @@ object LocalBook { inputStream: InputStream, fileName: String ): Uri { + if (inputStream.isEmpty()) throw EmptyFileException("Unexpected empty inputStream") val defaultBookTreeUri = AppConfig.defaultBookTreeUri if (defaultBookTreeUri.isNullOrBlank()) throw NoStackTraceException("没有设置书籍保存位置!") val treeUri = Uri.parse(defaultBookTreeUri) diff --git a/app/src/main/java/io/legado/app/model/localBook/TextFile.kt b/app/src/main/java/io/legado/app/model/localBook/TextFile.kt index 7f99f5aa1..18f28312b 100644 --- a/app/src/main/java/io/legado/app/model/localBook/TextFile.kt +++ b/app/src/main/java/io/legado/app/model/localBook/TextFile.kt @@ -4,13 +4,13 @@ import io.legado.app.data.appDb import io.legado.app.data.entities.Book import io.legado.app.data.entities.BookChapter import io.legado.app.data.entities.TxtTocRule +import io.legado.app.exception.EmptyFileException import io.legado.app.help.DefaultData import io.legado.app.utils.EncodingDetect import io.legado.app.utils.MD5Utils import io.legado.app.utils.StringUtils import io.legado.app.utils.Utf8BomUtils import java.io.FileNotFoundException -import java.lang.IllegalArgumentException import java.nio.charset.Charset import java.util.regex.Matcher import java.util.regex.Pattern @@ -99,7 +99,7 @@ class TextFile(private val book: Book) { LocalBook.getBookInputStream(book).use { bis -> val buffer = ByteArray(bufferSize) val length = bis.read(buffer) - if (length == -1) throw IllegalArgumentException("Unexpected Empty Txt File") + if (length == -1) throw EmptyFileException("Unexpected Empty Txt File") if (book.charset.isNullOrBlank()) { book.charset = EncodingDetect.getEncode(buffer.copyOf(length)) } diff --git a/app/src/main/java/io/legado/app/ui/book/info/BookInfoActivity.kt b/app/src/main/java/io/legado/app/ui/book/info/BookInfoActivity.kt index 8e6a3d188..7fbc800be 100644 --- a/app/src/main/java/io/legado/app/ui/book/info/BookInfoActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/info/BookInfoActivity.kt @@ -24,6 +24,7 @@ import io.legado.app.help.AppWebDav import io.legado.app.help.book.* import io.legado.app.help.config.AppConfig import io.legado.app.lib.dialogs.alert +import io.legado.app.lib.dialogs.selector import io.legado.app.lib.theme.backgroundColor import io.legado.app.lib.theme.bottomBackground import io.legado.app.lib.theme.getPrimaryTextColor @@ -502,26 +503,27 @@ class BookInfoActivity : toastOnUi("Unexpected webFileData") return } - alert(titleResource = R.string.download_and_import_file) { - items(webFiles) { _, webFile, _ -> - if (webFile.isSupported) { - /* import */ - viewModel.importOrDownloadWebFile(webFile) { - onClick?.invoke(it) - } - } else { - alert( - title = getString(R.string.draw), - message = getString(R.string.file_not_supported, webFile.name) - ) { - neutralButton(R.string.open_fun) { - /* download only */ - viewModel.importOrDownloadWebFile(webFile) { uri -> - openFileUri(uri, "*/*") - } + selector( + R.string.download_and_import_file, + webFiles + ) { _, webFile, _ -> + if (webFile.isSupported) { + /* import */ + viewModel.importOrDownloadWebFile(webFile) { + onClick?.invoke(it) + } + } else { + alert( + title = getString(R.string.draw), + message = getString(R.string.file_not_supported, webFile.name) + ) { + neutralButton(R.string.open_fun) { + /* download only */ + viewModel.importOrDownloadWebFile(webFile) { uri -> + openFileUri(uri, "*/*") } - noButton() } + noButton() } } } diff --git a/app/src/main/java/io/legado/app/ui/book/info/BookInfoViewModel.kt b/app/src/main/java/io/legado/app/ui/book/info/BookInfoViewModel.kt index 633105d7e..ca4156c4d 100644 --- a/app/src/main/java/io/legado/app/ui/book/info/BookInfoViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/book/info/BookInfoViewModel.kt @@ -17,6 +17,7 @@ import io.legado.app.data.entities.Book import io.legado.app.data.entities.BookChapter import io.legado.app.data.entities.BookSource import io.legado.app.exception.NoStackTraceException +import io.legado.app.exception.EmptyFileException import io.legado.app.help.AppWebDav import io.legado.app.help.book.* import io.legado.app.help.coroutine.Coroutine @@ -266,6 +267,7 @@ class BookInfoViewModel(application: Application) : BaseViewModel(application) { success?.invoke(it as T) }.onError { context.toastOnUi("ImportWebFileError\n${it.localizedMessage}") + webFiles.remove(webFile) }.onFinally { waitDialogData.postValue(false) } @@ -386,10 +388,10 @@ class BookInfoViewModel(application: Application) : BaseViewModel(application) { } private fun changeToLocalBook(localBook: Book): Book { - inBookshelf = true return LocalBook.mergeBook(localBook, bookData.value).let { bookData.postValue(it) loadChapter(it) + inBookshelf = true it } } diff --git a/app/src/main/java/io/legado/app/utils/InputStreamExtensions.kt b/app/src/main/java/io/legado/app/utils/InputStreamExtensions.kt index e36814f8e..ae5fa8dd9 100644 --- a/app/src/main/java/io/legado/app/utils/InputStreamExtensions.kt +++ b/app/src/main/java/io/legado/app/utils/InputStreamExtensions.kt @@ -23,3 +23,15 @@ fun InputStream?.contains(str: String): Boolean { return scanner.findWithinHorizon(str, 0) != null } } + +fun InputStream?.isEmpty(): Boolean { + this ?: return true + return if (markSupported()) { + mark(0) + val isEmpty = read(ByteArray(1)) == -1 + reset() + isEmpty + } else { + available() == 0 + } +}