Sfoglia il codice sorgente

Merge pull request #1878 from Xwite/master

feat:文件类书源支持
kunfei 4 anni fa
parent
commit
b4d01bf431

+ 17 - 4
app/src/main/java/io/legado/app/model/localBook/LocalBook.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")
         }
         }
-        //从文件头识别文件格式
-        
-        return importFile(bytes, fileName)
+        val localBook = importFile(bytes, fileName)
+        return mergeBook(localBook, onLineBook)
     }
     }
 
 
     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
+    }
+
 }
 }

+ 6 - 2
app/src/main/java/io/legado/app/ui/book/info/BookInfoActivity.kt

@@ -100,7 +100,7 @@ class BookInfoActivity :
         binding.scrollView.setBackgroundColor(backgroundColor)
         binding.scrollView.setBackgroundColor(backgroundColor)
         binding.flAction.setBackgroundColor(bottomBackground)
         binding.flAction.setBackgroundColor(bottomBackground)
         binding.tvShelf.setTextColor(getPrimaryTextColor(ColorUtils.isColorLight(bottomBackground)))
         binding.tvShelf.setTextColor(getPrimaryTextColor(ColorUtils.isColorLight(bottomBackground)))
-        binding.tvToc.text = getString(R.string.toc_s, getString(R.string.loading))
+        binding.tvToc.text = getString(R.string.toc_s, getString(R.string.
         viewModel.bookData.observe(this) { showBook(it) }
         viewModel.bookData.observe(this) { showBook(it) }
         viewModel.chapterListData.observe(this) { upLoading(false, it) }
         viewModel.chapterListData.observe(this) { upLoading(false, it) }
         viewModel.initData(intent)
         viewModel.initData(intent)
@@ -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 {

+ 29 - 2
app/src/main/java/io/legado/app/ui/book/info/BookInfoViewModel.kt

@@ -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}")
+        }
+    }
+
 }
 }