diff --git a/app/src/main/java/io/legado/app/help/storage/BookWebDav.kt b/app/src/main/java/io/legado/app/help/storage/BookWebDav.kt index 9a299512f..5af0231f0 100644 --- a/app/src/main/java/io/legado/app/help/storage/BookWebDav.kt +++ b/app/src/main/java/io/legado/app/help/storage/BookWebDav.kt @@ -38,7 +38,7 @@ object BookWebDav { return url } - suspend fun initWebDav(): Boolean { + private suspend fun initWebDav(): Boolean { val account = appCtx.getPrefString(PreferKey.webDavAccount) val password = appCtx.getPrefString(PreferKey.webDavPassword) if (!account.isNullOrBlank() && !password.isNullOrBlank()) { @@ -122,19 +122,16 @@ object BookWebDav { } } - suspend fun exportWebDav(path: String, fileName: String) { + suspend fun exportWebDav(byteArray: ByteArray, fileName: String) { try { if (initWebDav()) { // 默认导出到legado文件夹下exports目录 val exportsWebDavUrl = rootWebDavUrl + EncoderUtils.escape("exports") + "/" // 在legado文件夹创建exports目录,如果不存在的话 WebDav(exportsWebDavUrl).makeAsDir() - val file = File("${path}${File.separator}${fileName}") // 如果导出的本地文件存在,开始上传 - if (file.exists()) { - val putUrl = exportsWebDavUrl + fileName - WebDav(putUrl).upload("${path}${File.separator}${fileName}") - } + val putUrl = exportsWebDavUrl + fileName + WebDav(putUrl).upload(byteArray) } } catch (e: Exception) { Handler(Looper.getMainLooper()).post { diff --git a/app/src/main/java/io/legado/app/ui/book/cache/CacheViewModel.kt b/app/src/main/java/io/legado/app/ui/book/cache/CacheViewModel.kt index 4a060c991..28c7d1500 100644 --- a/app/src/main/java/io/legado/app/ui/book/cache/CacheViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/book/cache/CacheViewModel.kt @@ -16,6 +16,7 @@ import io.legado.app.help.storage.BookWebDav import io.legado.app.utils.* import splitties.init.appCtx import java.io.File +import java.nio.charset.Charset class CacheViewModel(application: Application) : BaseViewModel(application) { @@ -38,20 +39,24 @@ class CacheViewModel(application: Application) : BaseViewModel(application) { } } + @Suppress("BlockingMethodInNonBlockingContext") private suspend fun export(doc: DocumentFile, book: Book) { val filename = "${book.name} by ${book.author}.txt" - val content = getAllContents(book) - DocumentUtils.createFileIfNotExist(doc, filename) - ?.writeText(context, content) - if (appCtx.getPrefBoolean(PreferKey.webDavCacheBackup, false)) { - FileUtils.createFileIfNotExist( - File(FileUtils.getCachePath()), - filename - ).writeText(content) // 写出文件到cache目录 - // 导出到webdav - BookWebDav.exportWebDav(FileUtils.getCachePath(), filename) - // 上传完删除cache文件 - FileUtils.deleteFile("${FileUtils.getCachePath()}${File.separator}${filename}") + DocumentUtils.delete(doc, filename) + DocumentUtils.createFileIfNotExist(doc, filename)?.let { bookDoc -> + val stringBuilder = StringBuilder() + context.contentResolver.openOutputStream(bookDoc.uri, "wa")?.use { bookOs -> + getAllContents(book) { + bookOs.write(it.toByteArray(Charset.forName(AppConfig.exportCharset))) + stringBuilder.append(it) + } + } + if (appCtx.getPrefBoolean(PreferKey.webDavCacheBackup, false)) { + // 导出到webdav + val byteArray = + stringBuilder.toString().toByteArray(Charset.forName(AppConfig.exportCharset)) + BookWebDav.exportWebDav(byteArray, filename) + } } getSrcList(book).forEach { val vFile = BookHelp.getImage(book, it.third) @@ -67,10 +72,17 @@ class CacheViewModel(application: Application) : BaseViewModel(application) { private suspend fun export(file: File, book: Book) { val filename = "${book.name} by ${book.author}.txt" - FileUtils.createFileIfNotExist(file, filename) - .writeText(getAllContents(book)) + val bookPath = FileUtils.getPath(file, filename) + val bookFile = FileUtils.createFileWithReplace(bookPath) + val stringBuilder = StringBuilder() + getAllContents(book) { + bookFile.appendText(it, Charset.forName(AppConfig.exportCharset)) + stringBuilder.append(it) + } if (appCtx.getPrefBoolean(PreferKey.webDavCacheBackup, false)) { - BookWebDav.exportWebDav(file.absolutePath, filename) // 导出到webdav + val byteArray = + stringBuilder.toString().toByteArray(Charset.forName(AppConfig.exportCharset)) + BookWebDav.exportWebDav(byteArray, filename) // 导出到webdav } getSrcList(book).forEach { val vFile = BookHelp.getImage(book, it.third) @@ -86,23 +98,18 @@ class CacheViewModel(application: Application) : BaseViewModel(application) { } } - private suspend fun getAllContents(book: Book): String { + private suspend fun getAllContents(book: Book, append: (text: String) -> Unit) { val useReplace = AppConfig.exportUseReplace val contentProcessor = ContentProcessor(book.name, book.origin) - val stringBuilder = StringBuilder() - stringBuilder.append(book.name) - .append("\n") - .append(context.getString(R.string.author_show, book.author)) + append("${book.name}\n${context.getString(R.string.author_show, book.author)}") appDb.bookChapterDao.getChapterList(book.bookUrl).forEach { chapter -> BookHelp.getContent(book, chapter).let { content -> val content1 = contentProcessor .getContent(book, chapter.title, content ?: "null", false, useReplace) .joinToString("\n") - stringBuilder.append("\n\n") - .append(content1) + append.invoke("\n\n$content1") } } - return stringBuilder.toString() } private fun getSrcList(book: Book): ArrayList> { diff --git a/app/src/main/java/io/legado/app/utils/DocumentUtils.kt b/app/src/main/java/io/legado/app/utils/DocumentUtils.kt index 860c25f18..4a4341a0d 100644 --- a/app/src/main/java/io/legado/app/utils/DocumentUtils.kt +++ b/app/src/main/java/io/legado/app/utils/DocumentUtils.kt @@ -5,6 +5,7 @@ import android.database.Cursor import android.net.Uri import android.provider.DocumentsContract import androidx.documentfile.provider.DocumentFile +import java.nio.charset.Charset import java.util.* @@ -16,6 +17,11 @@ object DocumentUtils { return parent.findFile(fileName)?.exists() ?: false } + fun delete(root: DocumentFile, fileName: String, vararg subDirs: String) { + val parent: DocumentFile? = createFolderIfNotExist(root, *subDirs) + parent?.findFile(fileName)?.delete() + } + fun createFileIfNotExist( root: DocumentFile, fileName: String, @@ -47,8 +53,13 @@ object DocumentUtils { @JvmStatic @Throws(Exception::class) - fun writeText(context: Context, data: String, fileUri: Uri): Boolean { - return writeBytes(context, data.toByteArray(), fileUri) + fun writeText( + context: Context, + data: String, + fileUri: Uri, + charset: Charset = Charsets.UTF_8 + ): Boolean { + return writeBytes(context, data.toByteArray(charset), fileUri) } @JvmStatic @@ -143,8 +154,8 @@ data class DocItem( } @Throws(Exception::class) -fun DocumentFile.writeText(context: Context, data: String) { - DocumentUtils.writeText(context, data, this.uri) +fun DocumentFile.writeText(context: Context, data: String, charset: Charset = Charsets.UTF_8) { + DocumentUtils.writeText(context, data, this.uri, charset) } @Throws(Exception::class)