|
|
@@ -1,6 +1,5 @@
|
|
|
package io.legado.app.ui.book.info
|
|
|
|
|
|
-import android.net.Uri
|
|
|
import android.app.Application
|
|
|
import android.content.Intent
|
|
|
import androidx.lifecycle.MutableLiveData
|
|
|
@@ -8,7 +7,6 @@ import androidx.lifecycle.viewModelScope
|
|
|
import io.legado.app.R
|
|
|
import io.legado.app.base.BaseViewModel
|
|
|
import io.legado.app.constant.AppLog
|
|
|
-import io.legado.app.constant.AppPattern
|
|
|
import io.legado.app.constant.BookSourceType
|
|
|
import io.legado.app.constant.BookType
|
|
|
import io.legado.app.constant.EventBus
|
|
|
@@ -21,8 +19,6 @@ import io.legado.app.help.AppWebDav
|
|
|
import io.legado.app.help.book.*
|
|
|
import io.legado.app.help.coroutine.Coroutine
|
|
|
import io.legado.app.lib.webdav.ObjectNotFoundException
|
|
|
-import io.legado.app.model.analyzeRule.AnalyzeRule
|
|
|
-import io.legado.app.model.analyzeRule.AnalyzeUrl
|
|
|
import io.legado.app.model.BookCover
|
|
|
import io.legado.app.model.ReadBook
|
|
|
import io.legado.app.model.localBook.LocalBook
|
|
|
@@ -36,10 +32,11 @@ import kotlinx.coroutines.Dispatchers.IO
|
|
|
class BookInfoViewModel(application: Application) : BaseViewModel(application) {
|
|
|
val bookData = MutableLiveData<Book>()
|
|
|
val chapterListData = MutableLiveData<List<BookChapter>>()
|
|
|
- val webFileData: MutableList<WebFile>? = null
|
|
|
var inBookshelf = false
|
|
|
var bookSource: BookSource? = null
|
|
|
private var changeSourceCoroutine: Coroutine<*>? = null
|
|
|
+ val isImportBookOnLine: Boolean
|
|
|
+ get() = bookSource?.bookSourceType == BookSourceType.file
|
|
|
|
|
|
fun initData(intent: Intent) {
|
|
|
execute {
|
|
|
@@ -85,6 +82,8 @@ class BookInfoViewModel(application: Application) : BaseViewModel(application) {
|
|
|
appDb.bookSourceDao.getBookSource(book.origin)
|
|
|
if (book.tocUrl.isEmpty() && !book.isLocal) {
|
|
|
loadBookInfo(book)
|
|
|
+ } else if (isImportBookOnLine) {
|
|
|
+ chapterListData.postValue(emptyList())
|
|
|
} else {
|
|
|
val chapterList = appDb.bookChapterDao.getChapterList(book.bookUrl)
|
|
|
if (chapterList.isNotEmpty()) {
|
|
|
@@ -157,14 +156,13 @@ class BookInfoViewModel(application: Application) : BaseViewModel(application) {
|
|
|
inBookshelf = true
|
|
|
}
|
|
|
bookData.postValue(book)
|
|
|
+ if (isImportBookOnLine) {
|
|
|
+ appDb.searchBookDao.update(book.toSearchBook())
|
|
|
+ }
|
|
|
if (inBookshelf) {
|
|
|
appDb.bookDao.update(book)
|
|
|
}
|
|
|
- if (it.isWebFile) {
|
|
|
- loadWebFile(book, bookSource, scope)
|
|
|
- } else {
|
|
|
- loadChapter(it, scope)
|
|
|
- }
|
|
|
+ loadChapter(it, scope)
|
|
|
}.onError {
|
|
|
AppLog.put("获取数据信息失败\n${it.localizedMessage}", it)
|
|
|
context.toastOnUi(R.string.error_get_book_info)
|
|
|
@@ -189,7 +187,7 @@ class BookInfoViewModel(application: Application) : BaseViewModel(application) {
|
|
|
appDb.bookChapterDao.insert(*it.toTypedArray())
|
|
|
chapterListData.postValue(it)
|
|
|
}
|
|
|
- } else if (book.isWebFile) {
|
|
|
+ } else if (isImportBookOnLine) {
|
|
|
chapterListData.postValue(emptyList())
|
|
|
} else {
|
|
|
bookSource?.let { bookSource ->
|
|
|
@@ -226,7 +224,6 @@ class BookInfoViewModel(application: Application) : BaseViewModel(application) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-
|
|
|
fun loadGroup(groupId: Long, success: ((groupNames: String?) -> Unit)) {
|
|
|
execute {
|
|
|
appDb.bookGroupDao.getGroupNames(groupId).joinToString(",")
|
|
|
@@ -235,54 +232,6 @@ class BookInfoViewModel(application: Application) : BaseViewModel(application) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private fun loadWebFile(
|
|
|
- book: Book,
|
|
|
- bookSource: BookSource,
|
|
|
- scope: CoroutineScope = viewModelScope
|
|
|
- ) {
|
|
|
- execute(scope) {
|
|
|
- webFileData?.clear()
|
|
|
- val fileName = "${book.name} 作者:${book.author}"
|
|
|
- if (book.downloadUrls.isNullOrEmpty()) {
|
|
|
- val ruleDownloadUrls = bookSource.getBookInfoRule().downloadUrls
|
|
|
- val content = AnalyzeUrl(book.bookUrl, source = bookSource).getStrResponse().body
|
|
|
- val analyzeRule = AnalyzeRule(book, bookSource)
|
|
|
- analyzeRule.setContent(content).setBaseUrl(book.bookUrl)
|
|
|
- analyzeRule.getStringList(ruleDownloadUrls, isUrl = true)?.let {
|
|
|
- parseDownloadUrls(it, fileName)
|
|
|
- } ?: throw NoStackTraceException("Unexpected ruleDownloadUrls")
|
|
|
- } else {
|
|
|
- parseDownloadUrls(book.downloadUrls, fileName)
|
|
|
- }
|
|
|
- }.onError {
|
|
|
- context.toastOnUi("LoadWebFileError\n${it.localizedMessage}")
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- private fun parseDownloadUrls(downloadUrls: List<String>?, fileName: String) {
|
|
|
- val urls = downloadUrls
|
|
|
- urls?.forEach { url ->
|
|
|
- val mFileName = "${fileName}.${LocalBook.parseFileSuffix(url)}"
|
|
|
- val isSupportedFile = AppPattern.bookFileRegex.matches(mFileName)
|
|
|
- webFileData?.add(WebFile(url, mFileName, isSupportedFile))
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- fun importOrDownloadWebFile(webFile: WebFile, success: ((Uri?) -> Unit)?) {
|
|
|
- bookSource ?: return
|
|
|
- execute {
|
|
|
- if (webFile.isSupported) {
|
|
|
- LocalBook.importFileOnLine(webFile.url, webFile.name, bookSource)
|
|
|
- } else {
|
|
|
- LocalBook.saveBookFile(webFile.url, webFile.name, bookSource)
|
|
|
- }
|
|
|
- }.onSuccess {
|
|
|
- success?.invoke(it as? Uri)
|
|
|
- }.onError {
|
|
|
- context.toastOnUi("ImportWebFileError\n${it.localizedMessage}")
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
fun changeTo(source: BookSource, book: Book, toc: List<BookChapter>) {
|
|
|
changeSourceCoroutine?.cancel()
|
|
|
changeSourceCoroutine = execute {
|
|
|
@@ -407,14 +356,4 @@ class BookInfoViewModel(application: Application) : BaseViewModel(application) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- data class WebFile(
|
|
|
- val url: String,
|
|
|
- val name: String,
|
|
|
- val isSupported: Boolean
|
|
|
- ) {
|
|
|
- override fun toString(): String {
|
|
|
- return name
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
}
|