fix(LocalBook.saveBookFile): 保存前检查是inputstream否为空
This commit is contained in:
@@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user