feat:单个在线文件支持直接导入

pull/1879/head
Xwite 3 years ago
parent 1b1584de9e
commit a5f4ff16bc
  1. 21
      app/src/main/java/io/legado/app/model/localBook/LocalBook.kt
  2. 6
      app/src/main/java/io/legado/app/ui/book/info/BookInfoActivity.kt
  3. 31
      app/src/main/java/io/legado/app/ui/book/info/BookInfoViewModel.kt

@ -88,16 +88,16 @@ object LocalBook {
fun importFile( fun importFile(
str: String, str: String,
fileName: String, fileName: String,
source: BaseSource? = null source: BaseSource? = null,
onLineBook: Book? = null
): Book { ): Book {
val bytes = when { val bytes = when {
str.isAbsUrl() -> AnalyzeUrl(str, source = source).getByteArray() str.isAbsUrl() -> AnalyzeUrl(str, source = source).getByteArray()
str.isDataUrl() -> Base64.decode(str.substringAfter("base64,"), Base64.DEFAULT) str.isDataUrl() -> Base64.decode(str.substringAfter("base64,"), Base64.DEFAULT)
else -> throw NoStackTraceException("在线导入书籍支持http/https/DataURL") else -> throw NoStackTraceException("在线导入书籍支持http/https/DataURL")
} }
//从文件头识别文件格式 val localBook = importFile(bytes, fileName)
return mergeBook(localBook, onLineBook)
return importFile(bytes, fileName)
} }
fun importFile( fun importFile(
@ -230,4 +230,17 @@ object LocalBook {
Uri.fromFile(file) Uri.fromFile(file)
} }
} }
//文件类书源 合并在线书籍信息 在线 > 本地
private fun mergeBook(localBook: Book, onLineBook: Book?): Book {
onLineBook ?: return localBook
val mergeBook = localBook
mergeBook.name = if (onLineBook.name.isBlank()) localBook.name else onLineBook.name
mergeBook.author = if (onLineBook.author.isBlank()) localBook.author else onLineBook.author
mergeBook.coverUrl = onLineBook.coverUrl
mergeBook.intro = if (onLineBook.intro.isNullOrBlank()) localBook.intro else onLineBook.intro
mergeBook.save()
return mergeBook
}
} }

@ -279,7 +279,11 @@ class BookInfoActivity :
} }
tvRead.setOnClickListener { tvRead.setOnClickListener {
viewModel.bookData.value?.let { viewModel.bookData.value?.let {
readBook(it) if (viewModel.isImportBookOnLine) {
viewModel.importBookFileOnLine()
} else {
readBook(it)
}
} ?: toastOnUi("Book is null") } ?: toastOnUi("Book is null")
} }
tvShelf.setOnClickListener { tvShelf.setOnClickListener {

@ -7,6 +7,7 @@ import androidx.lifecycle.viewModelScope
import io.legado.app.R import io.legado.app.R
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.BookType
import io.legado.app.constant.EventBus import io.legado.app.constant.EventBus
import io.legado.app.data.appDb import io.legado.app.data.appDb
import io.legado.app.data.entities.Book import io.legado.app.data.entities.Book
@ -30,6 +31,7 @@ class BookInfoViewModel(application: Application) : BaseViewModel(application) {
var inBookshelf = false var inBookshelf = false
var bookSource: BookSource? = null var bookSource: BookSource? = null
private var changeSourceCoroutine: Coroutine<*>? = null private var changeSourceCoroutine: Coroutine<*>? = null
var isImportBookOnLine = false
fun initData(intent: Intent) { fun initData(intent: Intent) {
execute { execute {
@ -73,9 +75,10 @@ class BookInfoViewModel(application: Application) : BaseViewModel(application) {
upCoverByRule(book) upCoverByRule(book)
bookSource = if (book.isLocalBook()) null else bookSource = if (book.isLocalBook()) null else
appDb.bookSourceDao.getBookSource(book.origin) appDb.bookSourceDao.getBookSource(book.origin)
isImportBookOnLine = bookSource?.bookSourceType ?: BookType.local == BookType.file
if (book.tocUrl.isEmpty()) { if (book.tocUrl.isEmpty()) {
loadBookInfo(book) loadBookInfo(book)
} else { } else if (!isImportBookOnLine) {
val chapterList = appDb.bookChapterDao.getChapterList(book.bookUrl) val chapterList = appDb.bookChapterDao.getChapterList(book.bookUrl)
if (chapterList.isNotEmpty()) { if (chapterList.isNotEmpty()) {
chapterListData.postValue(chapterList) chapterListData.postValue(chapterList)
@ -108,7 +111,7 @@ class BookInfoViewModel(application: Application) : BaseViewModel(application) {
execute(scope) { execute(scope) {
if (book.isLocalBook()) { if (book.isLocalBook()) {
loadChapter(book, scope) loadChapter(book, scope)
} else { } else if (!isImportBookOnLine) {
bookSource?.let { bookSource -> bookSource?.let { bookSource ->
WebBook.getBookInfo(this, bookSource, book, canReName = canReName) WebBook.getBookInfo(this, bookSource, book, canReName = canReName)
.onSuccess(IO) { .onSuccess(IO) {
@ -282,4 +285,28 @@ class BookInfoViewModel(application: Application) : BaseViewModel(application) {
} }
} }
} }
fun importBookFileOnLine() {
execute {
//下载类书源的目录链接视为文件链接
val book = bookData.value!!
val fileUrl = book.tocUrl
//切下载链接获取文件名
var fileName = fileUrl.substringAfterLast("/")
if (fileName.isEmpty()) {
fileName = book.name
}
LocalBook.importFile(fileUrl, fileName, bookSource, book)
}.onSuccess {
bookData.postValue(it)
LocalBook.getChapterList(it).let { toc ->
chapterListData.postValue(toc)
}
isImportBookOnLine = false
inBookshelf = true
}.onError {
context.toastOnUi("自动导入出错\n${it.localizedMessage}")
}
}
} }
Loading…
Cancel
Save