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

This commit is contained in:
Xwite
2023-03-10 08:11:03 +08:00
parent 16415a95f2
commit bcb445adf4
5 changed files with 41 additions and 23 deletions
@@ -13,6 +13,7 @@ import io.legado.app.data.entities.BaseSource
import io.legado.app.data.entities.Book import io.legado.app.data.entities.Book
import io.legado.app.data.entities.BookChapter import io.legado.app.data.entities.BookChapter
import io.legado.app.exception.NoStackTraceException import io.legado.app.exception.NoStackTraceException
import io.legado.app.exception.EmptyFileException
import io.legado.app.exception.TocEmptyException import io.legado.app.exception.TocEmptyException
import io.legado.app.help.AppWebDav import io.legado.app.help.AppWebDav
import io.legado.app.help.book.* import io.legado.app.help.book.*
@@ -258,7 +259,7 @@ object LocalBook {
): Uri { ): Uri {
AppConfig.defaultBookTreeUri AppConfig.defaultBookTreeUri
?: throw NoStackTraceException("没有设置书籍保存位置!") ?: throw NoStackTraceException("没有设置书籍保存位置!")
val bytes = when { val inputStream = when {
str.isAbsUrl() -> AnalyzeUrl(str, source = source).getInputStream() str.isAbsUrl() -> AnalyzeUrl(str, source = source).getInputStream()
str.isDataUrl() -> ByteArrayInputStream( str.isDataUrl() -> ByteArrayInputStream(
Base64.decode( Base64.decode(
@@ -268,7 +269,7 @@ object LocalBook {
) )
else -> throw NoStackTraceException("在线导入书籍支持http/https/DataURL") else -> throw NoStackTraceException("在线导入书籍支持http/https/DataURL")
} }
return saveBookFile(bytes, fileName) return saveBookFile(inputStream, fileName)
} }
/** /**
@@ -289,6 +290,7 @@ object LocalBook {
inputStream: InputStream, inputStream: InputStream,
fileName: String fileName: String
): Uri { ): Uri {
if (inputStream.isEmpty()) throw EmptyFileException("Unexpected empty inputStream")
val defaultBookTreeUri = AppConfig.defaultBookTreeUri val defaultBookTreeUri = AppConfig.defaultBookTreeUri
if (defaultBookTreeUri.isNullOrBlank()) throw NoStackTraceException("没有设置书籍保存位置!") if (defaultBookTreeUri.isNullOrBlank()) throw NoStackTraceException("没有设置书籍保存位置!")
val treeUri = Uri.parse(defaultBookTreeUri) val treeUri = Uri.parse(defaultBookTreeUri)
@@ -4,13 +4,13 @@ import io.legado.app.data.appDb
import io.legado.app.data.entities.Book import io.legado.app.data.entities.Book
import io.legado.app.data.entities.BookChapter import io.legado.app.data.entities.BookChapter
import io.legado.app.data.entities.TxtTocRule import io.legado.app.data.entities.TxtTocRule
import io.legado.app.exception.EmptyFileException
import io.legado.app.help.DefaultData import io.legado.app.help.DefaultData
import io.legado.app.utils.EncodingDetect import io.legado.app.utils.EncodingDetect
import io.legado.app.utils.MD5Utils import io.legado.app.utils.MD5Utils
import io.legado.app.utils.StringUtils import io.legado.app.utils.StringUtils
import io.legado.app.utils.Utf8BomUtils import io.legado.app.utils.Utf8BomUtils
import java.io.FileNotFoundException import java.io.FileNotFoundException
import java.lang.IllegalArgumentException
import java.nio.charset.Charset import java.nio.charset.Charset
import java.util.regex.Matcher import java.util.regex.Matcher
import java.util.regex.Pattern import java.util.regex.Pattern
@@ -99,7 +99,7 @@ class TextFile(private val book: Book) {
LocalBook.getBookInputStream(book).use { bis -> LocalBook.getBookInputStream(book).use { bis ->
val buffer = ByteArray(bufferSize) val buffer = ByteArray(bufferSize)
val length = bis.read(buffer) 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()) { if (book.charset.isNullOrBlank()) {
book.charset = EncodingDetect.getEncode(buffer.copyOf(length)) book.charset = EncodingDetect.getEncode(buffer.copyOf(length))
} }
@@ -24,6 +24,7 @@ import io.legado.app.help.AppWebDav
import io.legado.app.help.book.* import io.legado.app.help.book.*
import io.legado.app.help.config.AppConfig import io.legado.app.help.config.AppConfig
import io.legado.app.lib.dialogs.alert 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.backgroundColor
import io.legado.app.lib.theme.bottomBackground import io.legado.app.lib.theme.bottomBackground
import io.legado.app.lib.theme.getPrimaryTextColor import io.legado.app.lib.theme.getPrimaryTextColor
@@ -502,26 +503,27 @@ class BookInfoActivity :
toastOnUi("Unexpected webFileData") toastOnUi("Unexpected webFileData")
return return
} }
alert(titleResource = R.string.download_and_import_file) { selector<BookInfoViewModel.WebFile>(
items<BookInfoViewModel.WebFile>(webFiles) { _, webFile, _ -> R.string.download_and_import_file,
if (webFile.isSupported) { webFiles
/* import */ ) { _, webFile, _ ->
viewModel.importOrDownloadWebFile<Book>(webFile) { if (webFile.isSupported) {
onClick?.invoke(it) /* import */
} viewModel.importOrDownloadWebFile<Book>(webFile) {
} else { onClick?.invoke(it)
alert( }
title = getString(R.string.draw), } else {
message = getString(R.string.file_not_supported, webFile.name) alert(
) { title = getString(R.string.draw),
neutralButton(R.string.open_fun) { message = getString(R.string.file_not_supported, webFile.name)
/* download only */ ) {
viewModel.importOrDownloadWebFile<Uri>(webFile) { uri -> neutralButton(R.string.open_fun) {
openFileUri(uri, "*/*") /* download only */
} viewModel.importOrDownloadWebFile<Uri>(webFile) { uri ->
openFileUri(uri, "*/*")
} }
noButton()
} }
noButton()
} }
} }
} }
@@ -17,6 +17,7 @@ import io.legado.app.data.entities.Book
import io.legado.app.data.entities.BookChapter import io.legado.app.data.entities.BookChapter
import io.legado.app.data.entities.BookSource import io.legado.app.data.entities.BookSource
import io.legado.app.exception.NoStackTraceException import io.legado.app.exception.NoStackTraceException
import io.legado.app.exception.EmptyFileException
import io.legado.app.help.AppWebDav import io.legado.app.help.AppWebDav
import io.legado.app.help.book.* import io.legado.app.help.book.*
import io.legado.app.help.coroutine.Coroutine import io.legado.app.help.coroutine.Coroutine
@@ -266,6 +267,7 @@ class BookInfoViewModel(application: Application) : BaseViewModel(application) {
success?.invoke(it as T) success?.invoke(it as T)
}.onError { }.onError {
context.toastOnUi("ImportWebFileError\n${it.localizedMessage}") context.toastOnUi("ImportWebFileError\n${it.localizedMessage}")
webFiles.remove(webFile)
}.onFinally { }.onFinally {
waitDialogData.postValue(false) waitDialogData.postValue(false)
} }
@@ -386,10 +388,10 @@ class BookInfoViewModel(application: Application) : BaseViewModel(application) {
} }
private fun changeToLocalBook(localBook: Book): Book { private fun changeToLocalBook(localBook: Book): Book {
inBookshelf = true
return LocalBook.mergeBook(localBook, bookData.value).let { return LocalBook.mergeBook(localBook, bookData.value).let {
bookData.postValue(it) bookData.postValue(it)
loadChapter(it) loadChapter(it)
inBookshelf = true
it it
} }
} }
@@ -23,3 +23,15 @@ fun InputStream?.contains(str: String): Boolean {
return scanner.findWithinHorizon(str, 0) != null 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
}
}