Просмотр исходного кода

Merge remote-tracking branch 'origin/master'

kunfei 3 лет назад
Родитель
Сommit
797b91beed

+ 1 - 4
app/src/main/java/io/legado/app/data/dao/BookDao.kt

@@ -44,9 +44,6 @@ interface BookDao {
     )
     fun flowLocalNoGroup(): Flow<List<Book>>
 
-    @Query("SELECT bookUrl FROM books WHERE type & ${BookType.local} > 0")
-    fun flowLocalUri(): Flow<List<String>>
-
     @Query("SELECT * FROM books WHERE (`group` & :group) > 0")
     fun flowByGroup(group: Long): Flow<List<Book>>
 
@@ -104,7 +101,7 @@ interface BookDao {
     @Query("select 1 from books where bookUrl = :bookUrl")
     fun has(bookUrl: String): Boolean?
 
-    @Query("select 1 from books where originName = :fileName")
+    @Query("select 1 from books where originName = :fileName or origin like '%' || :fileName")
     fun hasFile(fileName: String): Boolean?
 
     @Insert(onConflict = OnConflictStrategy.REPLACE)

+ 2 - 1
app/src/main/java/io/legado/app/help/book/BookExtensions.kt

@@ -62,7 +62,8 @@ val Book.archiveName: String?
     get() {
         return if (isArchive) {
             // local_book::archive.rar
-            origin.substring(BookType.localTag.length + 2)
+            // webDav::https://...../archive.rar
+            origin.substringAfter("::").substringAfterLast("/")
         } else {
             null
         }

+ 16 - 1
app/src/main/java/io/legado/app/model/localBook/LocalBook.kt

@@ -213,12 +213,27 @@ object LocalBook {
     }
 
    /* 批量导入 支持自动导入压缩包的支持书籍 */
+    fun importFiles(uri: Uri): List<Book> {
+        val books = mutableListOf<Book>()
+        val fileDoc = FileDoc.fromUri(uri, false)
+        if (ArchiveUtils.isArchive(fileDoc.name)) {
+            books.addAll(
+                importArchiveFile(uri) {
+                    it.matches(AppPattern.bookFileRegex)
+                }
+            )
+        } else {
+            books.add(importFile(uri))
+        }
+        return books
+    }
+
     fun importFiles(uris: List<Uri>) {
         var errorCount = 0
         uris.forEach { uri ->
             val fileDoc = FileDoc.fromUri(uri, false)
             kotlin.runCatching {
-               if (ArchiveUtils.isArchive(fileDoc.name)) {
+                if (ArchiveUtils.isArchive(fileDoc.name)) {
                     importArchiveFile(uri) {
                         it.matches(AppPattern.bookFileRegex)
                     }

+ 3 - 1
app/src/main/java/io/legado/app/model/remote/RemoteBookWebDav.kt

@@ -1,6 +1,7 @@
 package io.legado.app.model.remote
 
 import android.net.Uri
+import io.legado.app.constant.AppPattern.archiveFileRegex
 import io.legado.app.constant.AppPattern.bookFileRegex
 import io.legado.app.constant.BookType
 import io.legado.app.data.entities.Book
@@ -39,7 +40,8 @@ class RemoteBookWebDav(
         val remoteWebDavFileList: List<WebDavFile> = WebDav(path, authorization).listFiles()
         //转化远程文件信息到本地对象
         remoteWebDavFileList.forEach { webDavFile ->
-            if (webDavFile.isDir || bookFileRegex.matches(webDavFile.displayName)) {
+            if (webDavFile.isDir || bookFileRegex.matches(webDavFile.displayName) || archiveFileRegex.matches(webDavFile.displayName)
+            ) {
                 //扩展名符合阅读的格式则认为是书籍
                 remoteBooks.add(RemoteBook(webDavFile))
             }

+ 28 - 5
app/src/main/java/io/legado/app/ui/book/import/BaseImportBookActivity.kt

@@ -98,15 +98,16 @@ abstract class BaseImportBookActivity<VM : ViewModel> : VMBaseActivity<ActivityI
             it.matches(AppPattern.bookFileRegex)
         }
         if (fileNames.size == 1) {
-            appDb.bookDao.getBookByFileName(fileNames[0])?.let {
+            val name = fileNames[0]
+            appDb.bookDao.getBookByFileName(name)?.let {
                 startReadBook(it.bookUrl)
-            } ?: toastOnUi(R.string.no_book_found_bookshelf)
+            } ?: showImportAlert(fileDoc, name)
         } else {
-            showSelectBookReadAlert(fileNames)
+            showSelectBookReadAlert(fileDoc, fileNames)
         }
     }
 
-    private fun showSelectBookReadAlert(fileNames: List<String>) {
+    private fun showSelectBookReadAlert(fileDoc: FileDoc, fileNames: List<String>) {
         if (fileNames.isEmpty()) {
             toastOnUi(R.string.unsupport_archivefile_entry)
             return
@@ -117,7 +118,29 @@ abstract class BaseImportBookActivity<VM : ViewModel> : VMBaseActivity<ActivityI
         ) { _, name, _ ->
             appDb.bookDao.getBookByFileName(name)?.let {
                 startReadBook(it.bookUrl)
-            } ?: toastOnUi(R.string.no_book_found_bookshelf)
+            } ?: showImportAlert(fileDoc, name)
+        }
+    }
+
+    open fun addArchiveToBookShelf(
+        fileDoc: FileDoc,
+        fileName: String,
+        onSuccess: (String) -> Unit
+    ) {
+    }
+
+    /* 提示是否重新导入所点击的压缩文件 */
+    private fun showImportAlert(fileDoc: FileDoc, fileName: String) {
+        alert(
+            R.string.draw,
+            R.string.no_book_found_bookshelf
+        ) {
+            okButton {
+                addArchiveToBookShelf(fileDoc, fileName) {
+                    startReadBook(it)
+                }
+            }
+            noButton()
         }
     }
 

+ 7 - 5
app/src/main/java/io/legado/app/ui/book/import/local/ImportBookActivity.kt

@@ -131,11 +131,6 @@ class ImportBookActivity : BaseImportBookActivity<ImportBookViewModel>(),
         viewModel.dataFlowStart = {
             initRootDoc()
         }
-        launch {
-            appDb.bookDao.flowLocal().conflate().collect {
-                adapter.upBookHas(it)
-            }
-        }
         launch {
             viewModel.dataFlow.conflate().collect { docs ->
                 adapter.setItems(docs)
@@ -308,4 +303,11 @@ class ImportBookActivity : BaseImportBookActivity<ImportBookViewModel>(),
         }
     }
 
+    override fun addArchiveToBookShelf(
+        fileDoc: FileDoc,
+        fileName: String,
+        onSuccess: (String) -> Unit
+    ) {
+        viewModel.addArchiveToBookShelf(fileDoc, fileName, onSuccess)
+    }
 }

+ 2 - 21
app/src/main/java/io/legado/app/ui/book/import/local/ImportBookAdapter.kt

@@ -12,6 +12,7 @@ import io.legado.app.data.entities.Book
 import io.legado.app.databinding.ItemImportBookBinding
 import io.legado.app.help.book.archiveName
 import io.legado.app.help.book.isArchive
+import io.legado.app.model.localBook.LocalBook
 import io.legado.app.utils.*
 
 
@@ -19,7 +20,6 @@ class ImportBookAdapter(context: Context, val callBack: CallBack) :
     RecyclerAdapter<FileDoc, ItemImportBookBinding>(context) {
     val selectedUris = hashSetOf<String>()
     var checkableCount = 0
-    private val bookOrArchiveNamesOnBookShelf = arrayListOf<String>()
 
     override fun getViewBinding(parent: ViewGroup): ItemImportBookBinding {
         return ItemImportBookBinding.inflate(inflater, parent, false)
@@ -87,26 +87,7 @@ class ImportBookAdapter(context: Context, val callBack: CallBack) :
     }
 
     private fun isOnBookShelf(fileDoc: FileDoc): Boolean {
-        return bookOrArchiveNamesOnBookShelf.contains(fileDoc.name)
-    }
-
-    @SuppressLint("NotifyDataSetChanged")
-    fun upBookHas(books: List<Book>) {
-        bookOrArchiveNamesOnBookShelf.clear()
-        books.forEach {
-            if (it.isArchive) {
-                bookOrArchiveNamesOnBookShelf.add(
-                    it.archiveName!!
-                )
-            } else {
-                val path = Uri.decode(it.bookUrl)
-                bookOrArchiveNamesOnBookShelf.add(
-                    FileUtils.getName(path)
-                )
-            }
-        }
-        notifyDataSetChanged()
-        upCheckableCount()
+        return LocalBook.isOnBookShelf(fileDoc.name)
     }
 
     private fun upCheckableCount() {

+ 12 - 0
app/src/main/java/io/legado/app/ui/book/import/local/ImportBookViewModel.kt

@@ -97,6 +97,18 @@ class ImportBookViewModel(application: Application) : BaseViewModel(application)
         }
     }
 
+    fun addArchiveToBookShelf(
+        fileDoc: FileDoc,
+        fileName: String,
+        onSuccess: (String) -> Unit
+    ) {
+        LocalBook.importArchiveFile(fileDoc.uri, fileName) {
+            it.contains(fileName)
+        }.firstOrNull()?.run {
+            onSuccess.invoke(bookUrl)
+        }
+    }
+
     fun deleteDoc(uriList: HashSet<String>, finally: () -> Unit) {
         execute {
             uriList.forEach {

+ 6 - 7
app/src/main/java/io/legado/app/ui/book/import/remote/RemoteBookViewModel.kt

@@ -124,18 +124,17 @@ class RemoteBookViewModel(application: Application) : BaseViewModel(application)
 
     fun addToBookshelf(remoteBooks: HashSet<RemoteBook>, finally: () -> Unit) {
         execute {
+            val bookWebDav = remoteBookWebDav
+                ?: throw NoStackTraceException("没有配置webDav")
             remoteBooks.forEach { remoteBook ->
-                val bookWebDav = remoteBookWebDav
-                    ?: throw NoStackTraceException("没有配置webDav")
-                val downloadBookPath = bookWebDav.downloadRemoteBook(remoteBook)
-                downloadBookPath.let {
-                    val localBook = LocalBook.importFile(it)
-                    localBook.origin = BookType.webDavTag + CustomUrl(remoteBook.path)
+                val downloadBookUri = bookWebDav.downloadRemoteBook(remoteBook)
+                LocalBook.importFiles(downloadBookUri).forEach { book ->
+                    book.origin = BookType.webDavTag + CustomUrl(remoteBook.path)
                         .putAttribute(
                             "serverID",
                             bookWebDav.serverID
                         ).toString()
-                    localBook.save()
+                    book.save()
                     remoteBook.isOnBookShelf = true
                 }
             }

+ 16 - 15
app/src/main/java/io/legado/app/utils/UrlUtil.kt

@@ -77,6 +77,21 @@ object UrlUtil {
         conn.instanceFollowRedirects = false
         conn.connect()
 
+        if (AppConfig.recordLog || BuildConfig.DEBUG) {
+            val headers = conn.headerFields
+            val headersString = buildString {
+                headers.forEach { (key, value) ->
+                   value.forEach {
+                       append(key)
+                       append(": ")
+                       append(it)
+                       append("\n")
+                   }
+               }
+            }
+            AppLog.put("${url.toString()} response header:\n$headersString")
+        }
+
         // val fileSize = conn.getContentLengthLong() / 1024
         /** Content-Disposition 存在三种情况 文件名应该用引号 有些用空格
          * filename="filename"
@@ -114,21 +129,7 @@ object UrlUtil {
             val newUrl= URL(URLDecoder.decode(redirectUrl, "UTF-8"))
             getFileNameFromPath(newUrl)
         } else {
-            AppLog.put("Cannot obtain URL file name, enable recordLog for detail")
-            if (AppConfig.recordLog || BuildConfig.DEBUG) {
-                val headers = conn.headerFields
-                val headersString = buildString {
-                    headers.forEach { (key, value) ->
-                       value.forEach {
-                           append(key)
-                           append(": ")
-                           append(it)
-                           append("\n")
-                       }
-                   }
-                }
-                AppLog.put("${url.toString()} response header:\n$headersString")
-            }
+            AppLog.put("Cannot obtain URL file name, enable recordLog for response header")
             null
         }
     }

+ 1 - 1
app/src/main/res/values-es-rES/strings.xml

@@ -1083,5 +1083,5 @@
     <string name="unsupport_archivefile_entry">Cannot find supported files in archive</string>
     <string name="no_books_dir">没有设置书籍保存位置!</string>
     <string name="delete_alert">删除提醒</string>
-    <string name="no_book_found_bookshelf">No book found in bookshelf</string>
+    <string name="no_book_found_bookshelf">No book found in bookshelf, import again ?</string>
 </resources>

+ 1 - 1
app/src/main/res/values-ja-rJP/strings.xml

@@ -1086,5 +1086,5 @@
     <string name="unsupport_archivefile_entry">Cannot find supported files in archive</string>
     <string name="no_books_dir">没有设置书籍保存位置!</string>
     <string name="delete_alert">删除提醒</string>
-    <string name="no_book_found_bookshelf">No book found in bookshelf</string>
+    <string name="no_book_found_bookshelf">No book found in bookshelf, import again ?</string>
 </resources>

+ 1 - 1
app/src/main/res/values-pt-rBR/strings.xml

@@ -1086,5 +1086,5 @@
     <string name="unsupport_archivefile_entry">Cannot find supported files in archive</string>
     <string name="no_books_dir">没有设置书籍保存位置!</string>
     <string name="delete_alert">删除提醒</string>
-    <string name="no_book_found_bookshelf">No book found in bookshelf</string>
+    <string name="no_book_found_bookshelf">No book found in bookshelf, import again ?</string>
 </resources>

+ 1 - 1
app/src/main/res/values-zh-rHK/strings.xml

@@ -1083,5 +1083,5 @@
     <string name="unsupport_archivefile_entry">压缩文件内没有支持的文件</string>
     <string name="no_books_dir">没有设置书籍保存位置!</string>
     <string name="delete_alert">删除提醒</string>
-    <string name="no_book_found_bookshelf">未在书架上找到所选书籍</string>
+    <string name="no_book_found_bookshelf">未在书架上找到所选书籍, 是否重新导入?</string>
 </resources>

+ 1 - 1
app/src/main/res/values-zh-rTW/strings.xml

@@ -1085,5 +1085,5 @@
     <string name="unsupport_archivefile_entry">压缩文件内没有支持的文件</string>
     <string name="no_books_dir">没有设置书籍保存位置!</string>
     <string name="delete_alert">删除提醒</string>
-    <string name="no_book_found_bookshelf">未在书架上找到所选书籍</string>
+    <string name="no_book_found_bookshelf">未在书架上找到所选书籍, 是否重新导入?</string>
 </resources>

+ 1 - 1
app/src/main/res/values-zh/strings.xml

@@ -1085,5 +1085,5 @@
     <string name="unsupport_archivefile_entry">压缩文件内没有支持的文件</string>
     <string name="no_books_dir">没有设置书籍保存位置!</string>
     <string name="delete_alert">删除提醒</string>
-    <string name="no_book_found_bookshelf">未在书架上找到所选书籍</string>
+    <string name="no_book_found_bookshelf">未在书架上找到所选书籍, 是否重新导入?</string>
 </resources>

+ 1 - 1
app/src/main/res/values/strings.xml

@@ -1086,5 +1086,5 @@
     <string name="unsupport_archivefile_entry">Cannot find supported files in archive</string>
     <string name="no_books_dir">没有设置书籍保存位置!</string>
     <string name="delete_alert">删除提醒</string>
-    <string name="no_book_found_bookshelf">No book found in bookshelf</string>
+    <string name="no_book_found_bookshelf">No book found in bookshelf, import again ?</string>
 </resources>