refactor:在线书籍文件导入

pull/1874/head
Xwite 3 years ago
parent eee9097273
commit 08a3b95b43
  1. 44
      app/src/main/java/io/legado/app/api/controller/BookController.kt
  2. 14
      app/src/main/java/io/legado/app/help/JsExtensions.kt
  3. 61
      app/src/main/java/io/legado/app/model/localBook/LocalBook.kt

@ -1,9 +1,7 @@
package io.legado.app.api.controller package io.legado.app.api.controller
import android.net.Uri import android.net.Uri
import android.util.Base64
import androidx.core.graphics.drawable.toBitmap import androidx.core.graphics.drawable.toBitmap
import androidx.documentfile.provider.DocumentFile
import io.legado.app.api.ReturnData import io.legado.app.api.ReturnData
import io.legado.app.constant.PreferKey import io.legado.app.constant.PreferKey
import io.legado.app.data.appDb import io.legado.app.data.appDb
@ -12,7 +10,6 @@ import io.legado.app.data.entities.BookSource
import io.legado.app.help.BookHelp import io.legado.app.help.BookHelp
import io.legado.app.help.CacheManager import io.legado.app.help.CacheManager
import io.legado.app.help.ContentProcessor import io.legado.app.help.ContentProcessor
import io.legado.app.help.config.AppConfig
import io.legado.app.help.glide.ImageLoader import io.legado.app.help.glide.ImageLoader
import io.legado.app.help.storage.AppWebDav import io.legado.app.help.storage.AppWebDav
import io.legado.app.model.BookCover import io.legado.app.model.BookCover
@ -27,7 +24,6 @@ import kotlinx.coroutines.delay
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import splitties.init.appCtx import splitties.init.appCtx
import java.io.File import java.io.File
import java.io.FileOutputStream
object BookController { object BookController {
@ -248,45 +244,7 @@ object BookController {
val fileData = parameters["fileData"]?.firstOrNull() val fileData = parameters["fileData"]?.firstOrNull()
?: return returnData.setErrorMsg("fileData 不能为空") ?: return returnData.setErrorMsg("fileData 不能为空")
kotlin.runCatching { kotlin.runCatching {
val defaultBookTreeUri = AppConfig.defaultBookTreeUri LocalBook.importFile(fileData, fileName)
if (defaultBookTreeUri.isNullOrBlank()) return returnData.setErrorMsg("没有设置书籍保存位置!")
val treeUri = Uri.parse(defaultBookTreeUri)
val fileBytes =
Base64.decode(fileData.substringAfter("base64,"), Base64.DEFAULT)
val uri = if (treeUri.isContentScheme()) {
val treeDoc = DocumentFile.fromTreeUri(appCtx, treeUri)
var doc = treeDoc!!.findFile(fileName)
if (doc == null) {
doc = treeDoc.createFile(FileUtils.getMimeType(fileName), fileName)
?: throw SecurityException("Permission Denial")
}
appCtx.contentResolver.openOutputStream(doc.uri)!!.use { oStream ->
oStream.write(fileBytes)
}
doc.uri
} else {
val treeFile = File(treeUri.path!!)
val file = treeFile.getFile(fileName)
FileOutputStream(file).use { oStream ->
oStream.write(fileBytes)
}
Uri.fromFile(file)
}
val nameAuthor = LocalBook.analyzeNameAuthor(fileName)
val book = Book(
bookUrl = uri.toString(),
name = nameAuthor.first,
author = nameAuthor.second,
originName = fileName,
coverUrl = FileUtils.getPath(
appCtx.externalFiles,
"covers",
"${MD5Utils.md5Encode16(uri.toString())}.jpg"
)
)
if (book.isEpub()) EpubFile.upBookInfo(book)
if (book.isUmd()) UmdFile.upBookInfo(book)
appDb.bookDao.insert(book)
}.onFailure { }.onFailure {
return when (it) { return when (it) {
is SecurityException -> returnData.setErrorMsg("需重新设置书籍保存位置!") is SecurityException -> returnData.setErrorMsg("需重新设置书籍保存位置!")

@ -197,12 +197,10 @@ interface JsExtensions {
*js实现读取cookie *js实现读取cookie
*/ */
fun getCookie(tag: String, key: String? = null): String { fun getCookie(tag: String, key: String? = null): String {
val cookie = CookieStore.getCookie(tag)
val cookieMap = CookieStore.cookieToMap(cookie)
return if (key != null) { return if (key != null) {
cookieMap[key] ?: "" CookieStore.getKey(tag, key)
} else { } else {
cookie CookieStore.getCookie(tag)
} }
} }
@ -470,10 +468,8 @@ interface JsExtensions {
* @return zip指定文件的数据 * @return zip指定文件的数据
*/ */
fun getZipByteArrayContent(url: String, path: String): ByteArray? { fun getZipByteArrayContent(url: String, path: String): ByteArray? {
val bytes = if (url.startsWith("http://") || url.startsWith("https://")) { val bytes = if (url.isAbsUrl()) {
runBlocking { AnalyzeUrl(url, source = getSource()).getByteArray()
return@runBlocking okHttpClient.newCallResponseBody { url(url) }.bytes()
}
} else { } else {
StringUtils.hexStringToByte(url) StringUtils.hexStringToByte(url)
} }
@ -517,7 +513,7 @@ interface JsExtensions {
str.isAbsUrl() -> runBlocking { str.isAbsUrl() -> runBlocking {
var x = CacheManager.getByteArray(key) var x = CacheManager.getByteArray(key)
if (x == null) { if (x == null) {
x = okHttpClient.newCallResponseBody { url(str) }.bytes() x = AnalyzeUrl(str, source = getSource()).getByteArray()
x.let { x.let {
CacheManager.put(key, it) CacheManager.put(key, it)
} }

@ -1,6 +1,7 @@
package io.legado.app.model.localBook package io.legado.app.model.localBook
import android.net.Uri import android.net.Uri
import android.util.Base64
import androidx.documentfile.provider.DocumentFile import androidx.documentfile.provider.DocumentFile
import com.script.SimpleBindings import com.script.SimpleBindings
import io.legado.app.R import io.legado.app.R
@ -8,13 +9,17 @@ import io.legado.app.constant.AppConst
import io.legado.app.data.appDb import io.legado.app.data.appDb
import io.legado.app.data.entities.Book import io.legado.app.data.entities.Book
import io.legado.app.data.entities.BookChapter import io.legado.app.data.entities.BookChapter
import io.legado.app.data.entities.BaseSource
import io.legado.app.exception.TocEmptyException import io.legado.app.exception.TocEmptyException
import io.legado.app.exception.NoStackTraceException
import io.legado.app.help.BookHelp import io.legado.app.help.BookHelp
import io.legado.app.help.config.AppConfig import io.legado.app.help.config.AppConfig
import io.legado.app.model.analyzeRule.AnalyzeUrl
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.io.FileInputStream import java.io.FileInputStream
import java.io.FileOutputStream
import java.io.FileNotFoundException import java.io.FileNotFoundException
import java.io.InputStream import java.io.InputStream
import java.util.regex.Pattern import java.util.regex.Pattern
@ -79,6 +84,32 @@ object LocalBook {
} }
} }
//导入在线的文件
fun importFile(
str: String,
fileName: String,
source: BaseSource? = null
): Book {
val bytes = when {
str.isAbsUrl() -> AnalyzeUrl(str, source = source).getByteArray()
str.isDataUrl() -> Base64.decode(str.substringAfter("base64,"), Base64.DEFAULT)
else -> throw NoStackTraceException("在线导入书籍支持http/https/DataURL")
}
//从文件头识别文件格式
return importFile(bytes, fileName)
}
fun importFile(
bytes: ByteArray,
fileName: String
): Book {
return saveBookFile(bytes, fileName).let {
importFile(it)
}
}
//导入本地文件
fun importFile(uri: Uri): Book { fun importFile(uri: Uri): Book {
val bookUrl: String val bookUrl: String
val updateTime: Long val updateTime: Long
@ -119,7 +150,7 @@ object LocalBook {
return book return book
} }
fun analyzeNameAuthor(fileName: String): Pair<String, String> { private fun analyzeNameAuthor(fileName: String): Pair<String, String> {
val tempFileName = fileName.substringBeforeLast(".") val tempFileName = fileName.substringBeforeLast(".")
var name: String var name: String
var author: String var author: String
@ -171,4 +202,32 @@ object LocalBook {
} }
} }
} }
private fun saveBookFile(
bytes: ByteArray,
fileName: String
): Uri {
val defaultBookTreeUri = AppConfig.defaultBookTreeUri
if (defaultBookTreeUri.isNullOrBlank()) throw NoStackTraceException("没有设置书籍保存位置!")
val treeUri = Uri.parse(defaultBookTreeUri)
return if (treeUri.isContentScheme()) {
val treeDoc = DocumentFile.fromTreeUri(appCtx, treeUri)
var doc = treeDoc!!.findFile(fileName)
if (doc == null) {
doc = treeDoc.createFile(FileUtils.getMimeType(fileName), fileName)
?: throw SecurityException("Permission Denial")
}
appCtx.contentResolver.openOutputStream(doc.uri)!!.use { oStream ->
oStream.write(bytes)
}
doc.uri
} else {
val treeFile = File(treeUri.path!!)
val file = treeFile.getFile(fileName)
FileOutputStream(file).use { oStream ->
oStream.write(bytes)
}
Uri.fromFile(file)
}
}
} }

Loading…
Cancel
Save