pull/862/head
gedoor 4 years ago
parent 0f7ff10e3c
commit 05b6435b71
  1. 9
      app/src/main/java/io/legado/app/help/storage/BookWebDav.kt
  2. 49
      app/src/main/java/io/legado/app/ui/book/cache/CacheViewModel.kt
  3. 19
      app/src/main/java/io/legado/app/utils/DocumentUtils.kt

@ -38,7 +38,7 @@ object BookWebDav {
return url return url
} }
suspend fun initWebDav(): Boolean { private suspend fun initWebDav(): Boolean {
val account = appCtx.getPrefString(PreferKey.webDavAccount) val account = appCtx.getPrefString(PreferKey.webDavAccount)
val password = appCtx.getPrefString(PreferKey.webDavPassword) val password = appCtx.getPrefString(PreferKey.webDavPassword)
if (!account.isNullOrBlank() && !password.isNullOrBlank()) { 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 { try {
if (initWebDav()) { if (initWebDav()) {
// 默认导出到legado文件夹下exports目录 // 默认导出到legado文件夹下exports目录
val exportsWebDavUrl = rootWebDavUrl + EncoderUtils.escape("exports") + "/" val exportsWebDavUrl = rootWebDavUrl + EncoderUtils.escape("exports") + "/"
// 在legado文件夹创建exports目录,如果不存在的话 // 在legado文件夹创建exports目录,如果不存在的话
WebDav(exportsWebDavUrl).makeAsDir() WebDav(exportsWebDavUrl).makeAsDir()
val file = File("${path}${File.separator}${fileName}")
// 如果导出的本地文件存在,开始上传 // 如果导出的本地文件存在,开始上传
if (file.exists()) {
val putUrl = exportsWebDavUrl + fileName val putUrl = exportsWebDavUrl + fileName
WebDav(putUrl).upload("${path}${File.separator}${fileName}") WebDav(putUrl).upload(byteArray)
}
} }
} catch (e: Exception) { } catch (e: Exception) {
Handler(Looper.getMainLooper()).post { Handler(Looper.getMainLooper()).post {

@ -16,6 +16,7 @@ import io.legado.app.help.storage.BookWebDav
import io.legado.app.utils.* import io.legado.app.utils.*
import splitties.init.appCtx import splitties.init.appCtx
import java.io.File import java.io.File
import java.nio.charset.Charset
class CacheViewModel(application: Application) : BaseViewModel(application) { 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) { private suspend fun export(doc: DocumentFile, book: Book) {
val filename = "${book.name} by ${book.author}.txt" val filename = "${book.name} by ${book.author}.txt"
val content = getAllContents(book) DocumentUtils.delete(doc, filename)
DocumentUtils.createFileIfNotExist(doc, filename) DocumentUtils.createFileIfNotExist(doc, filename)?.let { bookDoc ->
?.writeText(context, content) 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)) { if (appCtx.getPrefBoolean(PreferKey.webDavCacheBackup, false)) {
FileUtils.createFileIfNotExist(
File(FileUtils.getCachePath()),
filename
).writeText(content) // 写出文件到cache目录
// 导出到webdav // 导出到webdav
BookWebDav.exportWebDav(FileUtils.getCachePath(), filename) val byteArray =
// 上传完删除cache文件 stringBuilder.toString().toByteArray(Charset.forName(AppConfig.exportCharset))
FileUtils.deleteFile("${FileUtils.getCachePath()}${File.separator}${filename}") BookWebDav.exportWebDav(byteArray, filename)
}
} }
getSrcList(book).forEach { getSrcList(book).forEach {
val vFile = BookHelp.getImage(book, it.third) 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) { private suspend fun export(file: File, book: Book) {
val filename = "${book.name} by ${book.author}.txt" val filename = "${book.name} by ${book.author}.txt"
FileUtils.createFileIfNotExist(file, filename) val bookPath = FileUtils.getPath(file, filename)
.writeText(getAllContents(book)) 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)) { 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 { getSrcList(book).forEach {
val vFile = BookHelp.getImage(book, it.third) 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 useReplace = AppConfig.exportUseReplace
val contentProcessor = ContentProcessor(book.name, book.origin) val contentProcessor = ContentProcessor(book.name, book.origin)
val stringBuilder = StringBuilder() append("${book.name}\n${context.getString(R.string.author_show, book.author)}")
stringBuilder.append(book.name)
.append("\n")
.append(context.getString(R.string.author_show, book.author))
appDb.bookChapterDao.getChapterList(book.bookUrl).forEach { chapter -> appDb.bookChapterDao.getChapterList(book.bookUrl).forEach { chapter ->
BookHelp.getContent(book, chapter).let { content -> BookHelp.getContent(book, chapter).let { content ->
val content1 = contentProcessor val content1 = contentProcessor
.getContent(book, chapter.title, content ?: "null", false, useReplace) .getContent(book, chapter.title, content ?: "null", false, useReplace)
.joinToString("\n") .joinToString("\n")
stringBuilder.append("\n\n") append.invoke("\n\n$content1")
.append(content1)
} }
} }
return stringBuilder.toString()
} }
private fun getSrcList(book: Book): ArrayList<Triple<String, Int, String>> { private fun getSrcList(book: Book): ArrayList<Triple<String, Int, String>> {

@ -5,6 +5,7 @@ import android.database.Cursor
import android.net.Uri import android.net.Uri
import android.provider.DocumentsContract import android.provider.DocumentsContract
import androidx.documentfile.provider.DocumentFile import androidx.documentfile.provider.DocumentFile
import java.nio.charset.Charset
import java.util.* import java.util.*
@ -16,6 +17,11 @@ object DocumentUtils {
return parent.findFile(fileName)?.exists() ?: false 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( fun createFileIfNotExist(
root: DocumentFile, root: DocumentFile,
fileName: String, fileName: String,
@ -47,8 +53,13 @@ object DocumentUtils {
@JvmStatic @JvmStatic
@Throws(Exception::class) @Throws(Exception::class)
fun writeText(context: Context, data: String, fileUri: Uri): Boolean { fun writeText(
return writeBytes(context, data.toByteArray(), fileUri) context: Context,
data: String,
fileUri: Uri,
charset: Charset = Charsets.UTF_8
): Boolean {
return writeBytes(context, data.toByteArray(charset), fileUri)
} }
@JvmStatic @JvmStatic
@ -143,8 +154,8 @@ data class DocItem(
} }
@Throws(Exception::class) @Throws(Exception::class)
fun DocumentFile.writeText(context: Context, data: String) { fun DocumentFile.writeText(context: Context, data: String, charset: Charset = Charsets.UTF_8) {
DocumentUtils.writeText(context, data, this.uri) DocumentUtils.writeText(context, data, this.uri, charset)
} }
@Throws(Exception::class) @Throws(Exception::class)

Loading…
Cancel
Save