Преглед изворни кода

fix(LocalBook.saveBookFile): 保存前检查是inputstream否为空

Xwite пре 3 година
родитељ
комит
bcb445adf4

+ 4 - 2
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)

+ 2 - 2
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))
                 }

+ 20 - 18
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<BookInfoViewModel.WebFile>(webFiles) { _, webFile, _ ->
-                if (webFile.isSupported) {
-                    /* import */
-                    viewModel.importOrDownloadWebFile<Book>(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<Uri>(webFile) { uri ->
-                                openFileUri(uri, "*/*")
-                            }
+        selector<BookInfoViewModel.WebFile>(
+            R.string.download_and_import_file,
+            webFiles
+        ) { _, webFile, _ ->
+            if (webFile.isSupported) {
+                /* import */
+                viewModel.importOrDownloadWebFile<Book>(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<Uri>(webFile) { uri ->
+                            openFileUri(uri, "*/*")
                         }
-                        noButton()
                     }
+                    noButton()
                 }
             }
         }

+ 3 - 1
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
         }
     }

+ 12 - 0
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
+    }
+}