From f3917d9d5e7e0540c262b10cfec70fadc9cb769e Mon Sep 17 00:00:00 2001 From: gedoor Date: Wed, 9 Dec 2020 21:22:27 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/io/legado/app/data/dao/BookDao.kt | 19 ------ .../legado/app/data/entities/BookProgress.kt | 6 +- .../app/help/storage/SyncBookProgress.kt | 58 +++++++++---------- .../io/legado/app/help/storage/WebDavHelp.kt | 27 ++++----- .../java/io/legado/app/lib/webdav/WebDav.kt | 22 +++++++ .../app/ui/book/read/ReadBookActivity.kt | 5 +- .../app/ui/book/read/ReadBookViewModel.kt | 7 +++ .../legado/app/ui/welcome/WelcomeActivity.kt | 2 - 8 files changed, 75 insertions(+), 71 deletions(-) diff --git a/app/src/main/java/io/legado/app/data/dao/BookDao.kt b/app/src/main/java/io/legado/app/data/dao/BookDao.kt index 8794296f6..aedc577f7 100644 --- a/app/src/main/java/io/legado/app/data/dao/BookDao.kt +++ b/app/src/main/java/io/legado/app/data/dao/BookDao.kt @@ -4,7 +4,6 @@ import androidx.lifecycle.LiveData import androidx.room.* import io.legado.app.constant.BookType import io.legado.app.data.entities.Book -import io.legado.app.data.entities.BookProgress @Dao interface BookDao { @@ -81,22 +80,4 @@ interface BookDao { @Query("update books set `group` = :newGroupId where `group` = :oldGroupId") fun upGroup(oldGroupId: Long, newGroupId: Long) - @get:Query("select bookUrl, tocUrl, origin, originName, durChapterIndex, durChapterPos, durChapterTime, durChapterTitle from books") - val allBookProgress: List - - @Query( - """ - update books set - durChapterIndex = :durChapterIndex, durChapterPos = :durChapterPos, - durChapterTime = :durChapterTime, durChapterTitle = :durChapterTitle - where bookUrl = :bookUrl and durChapterTime < :durChapterTime - """ - ) - fun upBookProgress( - bookUrl: String, - durChapterIndex: Int, - durChapterPos: Int, - durChapterTime: Long, - durChapterTitle: String? - ) } \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/data/entities/BookProgress.kt b/app/src/main/java/io/legado/app/data/entities/BookProgress.kt index bb9d4e0c5..e5d1e5c35 100644 --- a/app/src/main/java/io/legado/app/data/entities/BookProgress.kt +++ b/app/src/main/java/io/legado/app/data/entities/BookProgress.kt @@ -1,10 +1,8 @@ package io.legado.app.data.entities data class BookProgress( - val bookUrl: String, - val tocUrl: String = "", - var origin: String = "", - var originName: String = "", + val name: String, + val author: String, val durChapterIndex: Int, val durChapterPos: Int, val durChapterTime: Long, diff --git a/app/src/main/java/io/legado/app/help/storage/SyncBookProgress.kt b/app/src/main/java/io/legado/app/help/storage/SyncBookProgress.kt index 06c681f8a..b18efde89 100644 --- a/app/src/main/java/io/legado/app/help/storage/SyncBookProgress.kt +++ b/app/src/main/java/io/legado/app/help/storage/SyncBookProgress.kt @@ -1,50 +1,50 @@ package io.legado.app.help.storage -import io.legado.app.App +import io.legado.app.data.entities.Book import io.legado.app.data.entities.BookProgress import io.legado.app.help.coroutine.Coroutine import io.legado.app.lib.webdav.WebDav -import io.legado.app.utils.FileUtils import io.legado.app.utils.GSON -import io.legado.app.utils.fromJsonArray +import io.legado.app.utils.fromJsonObject @Suppress("BlockingMethodInNonBlockingContext") object SyncBookProgress { - const val fileName = "bookProgress.json" - private val file = FileUtils.createFileIfNotExist(App.INSTANCE.cacheDir, fileName) - private val webDavUrl = "${WebDavHelp.rootWebDavUrl}$fileName" - fun uploadBookProgress() { + private val webDavUrl = "${WebDavHelp.rootWebDavUrl}bookProgress/" + + fun uploadBookProgress(book: Book) { Coroutine.async { - val value = App.db.bookDao.allBookProgress - if (value.isNotEmpty()) { - val json = GSON.toJson(value) - file.writeText(json) - if (WebDavHelp.initWebDav()) { - WebDav(webDavUrl).upload(file.absolutePath) - } + val bookProgress = BookProgress( + name = book.name, + author = book.author, + durChapterIndex = book.durChapterIndex, + durChapterPos = book.durChapterPos, + durChapterTime = book.durChapterTime, + durChapterTitle = book.durChapterTitle + ) + val json = GSON.toJson(bookProgress) + val url = getUrl(book) + if (WebDavHelp.initWebDav()) { + WebDav(webDavUrl).makeAsDir() + WebDav(url).upload(json.toByteArray()) } } } - fun downloadBookProgress() { - Coroutine.async { - if (WebDavHelp.initWebDav()) { - WebDav(webDavUrl).downloadTo(file.absolutePath, true) - if (file.exists()) { - val json = file.readText() - GSON.fromJsonArray(json)?.forEach { - App.db.bookDao.upBookProgress( - bookUrl = it.bookUrl, - durChapterIndex = it.durChapterIndex, - durChapterPos = it.durChapterPos, - durChapterTime = it.durChapterTime, - durChapterTitle = it.durChapterTitle - ) - } + fun getBookProgress(book: Book): BookProgress? { + if (WebDavHelp.initWebDav()) { + val url = getUrl(book) + WebDav(url).download()?.let { byteArray -> + val json = String(byteArray) + GSON.fromJsonObject(json)?.let { + return it } } } + return null } + private fun getUrl(book: Book): String { + return webDavUrl + book.name + "_" + book.author + ".json" + } } \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/help/storage/WebDavHelp.kt b/app/src/main/java/io/legado/app/help/storage/WebDavHelp.kt index ae6e34ffb..b656c1ca2 100644 --- a/app/src/main/java/io/legado/app/help/storage/WebDavHelp.kt +++ b/app/src/main/java/io/legado/app/help/storage/WebDavHelp.kt @@ -18,7 +18,6 @@ import org.jetbrains.anko.toast import java.io.File import java.text.SimpleDateFormat import java.util.* -import kotlin.math.min object WebDavHelp { private const val defaultWebDavUrl = "https://dav.jianguoyun.com/dav/" @@ -55,9 +54,10 @@ object WebDavHelp { if (initWebDav()) { var files = WebDav(url).listFiles() files = files.reversed() - for (index: Int in 0 until min(10, files.size)) { - files[index].displayName?.let { - names.add(it) + files.forEach { + val name = it.displayName + if (name?.startsWith("backup") == true) { + names.add(name) } } } @@ -85,16 +85,12 @@ object WebDavHelp { private fun restoreWebDav(name: String) { Coroutine.async { rootWebDavUrl.let { - if (name == SyncBookProgress.fileName) { - SyncBookProgress.downloadBookProgress() - } else { - val webDav = WebDav(it + name) - webDav.downloadTo(zipFilePath, true) - @Suppress("BlockingMethodInNonBlockingContext") - ZipUtils.unzipFile(zipFilePath, Backup.backupPath) - Restore.restoreDatabase() - Restore.restoreConfig() - } + val webDav = WebDav(it + name) + webDav.downloadTo(zipFilePath, true) + @Suppress("BlockingMethodInNonBlockingContext") + ZipUtils.unzipFile(zipFilePath, Backup.backupPath) + Restore.restoreDatabase() + Restore.restoreConfig() } }.onError { App.INSTANCE.toast("WebDavError:${it.localizedMessage}") @@ -122,6 +118,7 @@ object WebDavHelp { } } } + fun exportWebDav(path: String, fileName: String) { try { if (initWebDav()) { @@ -131,7 +128,7 @@ object WebDavHelp { WebDav(exportsWebDavUrl).makeAsDir() val file = File("${path}${File.separator}${fileName}") // 如果导出的本地文件存在,开始上传 - if(file.exists()) { + if (file.exists()) { val putUrl = exportsWebDavUrl + fileName WebDav(putUrl).upload("${path}${File.separator}${fileName}") } diff --git a/app/src/main/java/io/legado/app/lib/webdav/WebDav.kt b/app/src/main/java/io/legado/app/lib/webdav/WebDav.kt index 73ac6f141..a9586e2a8 100644 --- a/app/src/main/java/io/legado/app/lib/webdav/WebDav.kt +++ b/app/src/main/java/io/legado/app/lib/webdav/WebDav.kt @@ -50,6 +50,7 @@ class WebDav(urlStr: String) { var exists = false var parent = "" var urlName = "" + var contentType = "" /** * 填充文件信息。实例化WebDAVFile对象时,并没有将远程文件的信息填充到实例中。需要手动填充! @@ -139,6 +140,9 @@ class WebDav(urlStr: String) { try { webDavFile = WebDav(baseUrl + fileName) webDavFile.displayName = fileName + webDavFile.contentType = element + .getElementsByTag("d:getcontenttype") + .getOrNull(0)?.text() ?: "" if (href.isEmpty()) { webDavFile.urlName = if (parent.isEmpty()) url.file.replace("/", "") @@ -188,6 +192,11 @@ class WebDav(urlStr: String) { return true } + fun download(): ByteArray? { + val inputS = getInputStream() ?: return null + return inputS.readBytes() + } + /** * 上传文件 */ @@ -207,6 +216,19 @@ class WebDav(urlStr: String) { return false } + fun upload(byteArray: ByteArray, contentType: String? = null): Boolean { + val mediaType = contentType?.let { MediaType.parse(it) } + // 务必注意RequestBody不要嵌套,不然上传时内容可能会被追加多余的文件信息 + val fileBody = RequestBody.create(mediaType, byteArray) + httpUrl?.let { + val request = Request.Builder() + .url(it) + .put(fileBody) + return execRequest(request) + } + return false + } + /** * 执行请求,获取响应结果 * @param requestBuilder 因为还需要追加验证信息,所以此处传递Request.Builder的对象,而不是Request的对象 diff --git a/app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt b/app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt index ebed4ee51..bd0f2f4f0 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt @@ -138,7 +138,9 @@ class ReadBookActivity : ReadBookBaseActivity(), } upSystemUiVisibility() if (!BuildConfig.DEBUG) { - SyncBookProgress.uploadBookProgress() + ReadBook.book?.let { + SyncBookProgress.uploadBookProgress(it) + } Backup.autoBack(this) } } @@ -814,7 +816,6 @@ class ReadBookActivity : ReadBookBaseActivity(), binding.readView.onDestroy() ReadBook.msg = null if (!BuildConfig.DEBUG) { - SyncBookProgress.uploadBookProgress() Backup.autoBack(this) } } diff --git a/app/src/main/java/io/legado/app/ui/book/read/ReadBookViewModel.kt b/app/src/main/java/io/legado/app/ui/book/read/ReadBookViewModel.kt index a224114d7..f70501f12 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/ReadBookViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/ReadBookViewModel.kt @@ -11,6 +11,7 @@ import io.legado.app.data.entities.SearchBook import io.legado.app.help.AppConfig import io.legado.app.help.BookHelp import io.legado.app.help.IntentDataHelp +import io.legado.app.help.storage.SyncBookProgress import io.legado.app.model.localBook.LocalBook import io.legado.app.model.webBook.WebBook import io.legado.app.service.BaseReadAloudService @@ -46,6 +47,12 @@ class ReadBookViewModel(application: Application) : BaseViewModel(application) { private fun initBook(book: Book) { if (ReadBook.book?.bookUrl != book.bookUrl) { + SyncBookProgress.getBookProgress(book)?.let { + book.durChapterIndex = it.durChapterIndex + book.durChapterPos = it.durChapterPos + book.durChapterTime = it.durChapterTime + book.durChapterTitle = it.durChapterTitle + } ReadBook.resetData(book) isInitFinish = true if (!book.isLocalBook() && ReadBook.webBook == null) { diff --git a/app/src/main/java/io/legado/app/ui/welcome/WelcomeActivity.kt b/app/src/main/java/io/legado/app/ui/welcome/WelcomeActivity.kt index 7a50480b6..49fd459fd 100644 --- a/app/src/main/java/io/legado/app/ui/welcome/WelcomeActivity.kt +++ b/app/src/main/java/io/legado/app/ui/welcome/WelcomeActivity.kt @@ -10,7 +10,6 @@ import io.legado.app.constant.PreferKey import io.legado.app.databinding.ActivityWelcomeBinding import io.legado.app.help.AppConfig import io.legado.app.help.coroutine.Coroutine -import io.legado.app.help.storage.SyncBookProgress import io.legado.app.lib.theme.accentColor import io.legado.app.ui.book.read.ReadBookActivity import io.legado.app.ui.main.MainActivity @@ -50,7 +49,6 @@ open class WelcomeActivity : BaseActivity() { else -> null } } - SyncBookProgress.downloadBookProgress() binding.root.postDelayed({ startMainActivity() }, 500) }