Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package io.legado.app.help
|
||||
|
||||
import android.content.Context
|
||||
import android.net.Uri
|
||||
import io.legado.app.R
|
||||
import io.legado.app.constant.AppLog
|
||||
import io.legado.app.constant.PreferKey
|
||||
@@ -207,6 +208,21 @@ object AppWebDav {
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun exportWebDav(uri: Uri, fileName: String) {
|
||||
if (!NetworkUtils.isAvailable()) return
|
||||
try {
|
||||
authorization?.let {
|
||||
// 如果导出的本地文件存在,开始上传
|
||||
val putUrl = exportsWebDavUrl + fileName
|
||||
WebDav(putUrl, it).upload(uri, "text/plain")
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
val msg = "WebDav导出\n${e.localizedMessage}"
|
||||
AppLog.put(msg, e)
|
||||
appCtx.toastOnUi(msg)
|
||||
}
|
||||
}
|
||||
|
||||
fun uploadBookProgress(book: Book) {
|
||||
val authorization = authorization ?: return
|
||||
if (!syncBookProgress) return
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package io.legado.app.lib.webdav
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.net.Uri
|
||||
import io.legado.app.constant.AppLog
|
||||
import io.legado.app.exception.NoStackTraceException
|
||||
import io.legado.app.help.http.newCallResponse
|
||||
@@ -8,6 +9,7 @@ import io.legado.app.help.http.okHttpClient
|
||||
import io.legado.app.help.http.text
|
||||
import io.legado.app.utils.NetworkUtils
|
||||
import io.legado.app.utils.printOnDebug
|
||||
import io.legado.app.utils.toRequestBody
|
||||
import kotlinx.coroutines.Dispatchers.IO
|
||||
import kotlinx.coroutines.withContext
|
||||
import okhttp3.Interceptor
|
||||
@@ -316,6 +318,26 @@ open class WebDav(val path: String, val authorization: Authorization) {
|
||||
}
|
||||
}
|
||||
|
||||
@Throws(WebDavException::class)
|
||||
suspend fun upload(uri: Uri, contentType: String) {
|
||||
// 务必注意RequestBody不要嵌套,不然上传时内容可能会被追加多余的文件信息
|
||||
kotlin.runCatching {
|
||||
withContext(IO) {
|
||||
val fileBody = uri.toRequestBody(contentType.toMediaType())
|
||||
val url = httpUrl ?: throw NoStackTraceException("url不能为空")
|
||||
webDavClient.newCallResponse {
|
||||
url(url)
|
||||
put(fileBody)
|
||||
}.let {
|
||||
checkResult(it)
|
||||
}
|
||||
}
|
||||
}.onFailure {
|
||||
AppLog.put("WebDav上传失败\n${it.localizedMessage}", it)
|
||||
throw WebDavException("WebDav上传失败\n${it.localizedMessage}")
|
||||
}
|
||||
}
|
||||
|
||||
@Throws(WebDavException::class)
|
||||
suspend fun downloadInputStream(): InputStream {
|
||||
val url = httpUrl ?: throw WebDavException("WebDav下载出错\nurl为空")
|
||||
|
||||
+16
-19
@@ -122,7 +122,9 @@ class CacheViewModel(application: Application) : BaseViewModel(application) {
|
||||
exportMsg[book.bookUrl] = context.getString(R.string.export_success)
|
||||
upAdapterLiveData.postValue(book.bookUrl)
|
||||
}.onFinally {
|
||||
exportNumber--
|
||||
mutex.withLock {
|
||||
exportNumber--
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,14 +134,9 @@ class CacheViewModel(application: Application) : BaseViewModel(application) {
|
||||
DocumentUtils.delete(doc, filename)
|
||||
val bookDoc = DocumentUtils.createFileIfNotExist(doc, filename)
|
||||
?: throw NoStackTraceException("创建文档失败,请尝试重新设置导出文件夹")
|
||||
val stringBuilder = StringBuilder()
|
||||
val exportToWebDav = AppConfig.exportToWebDav
|
||||
context.contentResolver.openOutputStream(bookDoc.uri, "wa")?.use { bookOs ->
|
||||
getAllContents(book) { text, srcList ->
|
||||
bookOs.write(text.toByteArray(Charset.forName(AppConfig.exportCharset)))
|
||||
if (exportToWebDav) {
|
||||
stringBuilder.append(text)
|
||||
}
|
||||
srcList?.forEach {
|
||||
val vFile = BookHelp.getImage(book, it.third)
|
||||
if (vFile.exists()) {
|
||||
@@ -154,9 +151,7 @@ class CacheViewModel(application: Application) : BaseViewModel(application) {
|
||||
}
|
||||
if (AppConfig.exportToWebDav) {
|
||||
// 导出到webdav
|
||||
val byteArray =
|
||||
stringBuilder.toString().toByteArray(Charset.forName(AppConfig.exportCharset))
|
||||
AppWebDav.exportWebDav(byteArray, filename)
|
||||
AppWebDav.exportWebDav(bookDoc.uri, filename)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,13 +159,8 @@ class CacheViewModel(application: Application) : BaseViewModel(application) {
|
||||
val filename = "${getExportFileName(book)}.txt"
|
||||
val bookPath = FileUtils.getPath(file, filename)
|
||||
val bookFile = FileUtils.createFileWithReplace(bookPath)
|
||||
val stringBuilder = StringBuilder()
|
||||
val exportToWebDav = AppConfig.exportToWebDav
|
||||
getAllContents(book) { text, srcList ->
|
||||
bookFile.appendText(text, Charset.forName(AppConfig.exportCharset))
|
||||
if (exportToWebDav) {
|
||||
stringBuilder.append(text)
|
||||
}
|
||||
srcList?.forEach {
|
||||
val vFile = BookHelp.getImage(book, it.third)
|
||||
if (vFile.exists()) {
|
||||
@@ -185,9 +175,7 @@ class CacheViewModel(application: Application) : BaseViewModel(application) {
|
||||
}
|
||||
}
|
||||
if (AppConfig.exportToWebDav) {
|
||||
val byteArray =
|
||||
stringBuilder.toString().toByteArray(Charset.forName(AppConfig.exportCharset))
|
||||
AppWebDav.exportWebDav(byteArray, filename) // 导出到webdav
|
||||
AppWebDav.exportWebDav(Uri.fromFile(bookFile), filename) // 导出到webdav
|
||||
}
|
||||
}
|
||||
|
||||
@@ -299,7 +287,9 @@ class CacheViewModel(application: Application) : BaseViewModel(application) {
|
||||
exportMsg[book.bookUrl] = context.getString(R.string.export_success)
|
||||
upAdapterLiveData.postValue(book.bookUrl)
|
||||
}.onFinally {
|
||||
exportNumber--
|
||||
mutex.withLock {
|
||||
exportNumber--
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -322,7 +312,10 @@ class CacheViewModel(application: Application) : BaseViewModel(application) {
|
||||
context.contentResolver.openOutputStream(bookDoc.uri, "wa")?.use { bookOs ->
|
||||
EpubWriter().write(epubBook, bookOs)
|
||||
}
|
||||
|
||||
if (AppConfig.exportToWebDav) {
|
||||
// 导出到webdav
|
||||
AppWebDav.exportWebDav(bookDoc.uri, filename)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -344,6 +337,10 @@ class CacheViewModel(application: Application) : BaseViewModel(application) {
|
||||
setEpubContent(contentModel, book, epubBook)
|
||||
@Suppress("BlockingMethodInNonBlockingContext")
|
||||
EpubWriter().write(epubBook, FileOutputStream(bookFile))
|
||||
if (AppConfig.exportToWebDav) {
|
||||
// 导出到webdav
|
||||
AppWebDav.exportWebDav(Uri.fromFile(bookFile), filename)
|
||||
}
|
||||
}
|
||||
|
||||
private fun setAssets(doc: DocumentFile, book: Book, epubBook: EpubBook): String {
|
||||
|
||||
@@ -10,6 +10,11 @@ import io.legado.app.constant.AppLog
|
||||
import io.legado.app.exception.NoStackTraceException
|
||||
import io.legado.app.lib.permission.Permissions
|
||||
import io.legado.app.lib.permission.PermissionsCompat
|
||||
import okhttp3.MediaType
|
||||
import okhttp3.RequestBody
|
||||
import okio.BufferedSink
|
||||
import okio.source
|
||||
import splitties.init.appCtx
|
||||
import java.io.File
|
||||
import java.io.FileInputStream
|
||||
import java.io.InputStream
|
||||
@@ -197,4 +202,22 @@ fun Uri.inputStream(context: Context): Result<InputStream> {
|
||||
throw e
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun Uri.toRequestBody(contentType: MediaType? = null): RequestBody {
|
||||
val uri = this
|
||||
return object : RequestBody() {
|
||||
override fun contentType() = contentType
|
||||
|
||||
override fun contentLength(): Long {
|
||||
val length = uri.inputStream(appCtx).getOrThrow().available().toLong()
|
||||
return if (length > 0) length else -1
|
||||
}
|
||||
|
||||
override fun writeTo(sink: BufferedSink) {
|
||||
uri.inputStream(appCtx).getOrThrow().source().use { source ->
|
||||
sink.writeAll(source)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user