本地书籍无权限则保存到自己选定的文件夹

This commit is contained in:
gedoor 2022-01-01 11:04:41 +08:00
parent f40b1c391d
commit 43d8714d2b
5 changed files with 31 additions and 59 deletions

View File

@ -11,6 +11,11 @@
* 正文出现缺字漏字、内容缺失、排版错乱等情况,有可能是净化规则或简繁转换出现问题。 * 正文出现缺字漏字、内容缺失、排版错乱等情况,有可能是净化规则或简繁转换出现问题。
* 漫画源看书显示乱码,**阅读与其他软件的源并不通用**,请导入阅读的支持的漫画源! * 漫画源看书显示乱码,**阅读与其他软件的源并不通用**,请导入阅读的支持的漫画源!
**2021/01/01**
* 修复本地txt问题,不在拷贝到私有目录,可以正常打开
* 优化txt目录识别,取目录数量最多的规则
**2021/12/28** **2021/12/28**
* 用阅读打开本地朗读引擎文件和主体配置文件也可以导入 * 用阅读打开本地朗读引擎文件和主体配置文件也可以导入

View File

@ -2,12 +2,13 @@ package io.legado.app.model.localBook
import android.graphics.Bitmap import android.graphics.Bitmap
import android.graphics.BitmapFactory import android.graphics.BitmapFactory
import android.net.Uri
import android.text.TextUtils import android.text.TextUtils
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.help.BookHelp import io.legado.app.utils.FileUtils
import io.legado.app.utils.* import io.legado.app.utils.HtmlFormatter
import io.legado.app.utils.MD5Utils
import io.legado.app.utils.externalFiles
import me.ag2s.epublib.domain.EpubBook import me.ag2s.epublib.domain.EpubBook
import me.ag2s.epublib.domain.Resource import me.ag2s.epublib.domain.Resource
import me.ag2s.epublib.domain.TOCReference import me.ag2s.epublib.domain.TOCReference
@ -23,36 +24,14 @@ import java.io.IOException
import java.io.InputStream import java.io.InputStream
import java.nio.charset.Charset import java.nio.charset.Charset
import java.util.* import java.util.*
import java.util.zip.ZipFile
class EpubFile(var book: Book) { class EpubFile(var book: Book) {
companion object { companion object {
private var eFile: EpubFile? = null private var eFile: EpubFile? = null
fun getFile(book: Book): File {
val file = BookHelp.downloadDir.getFile(
BookHelp.cacheFolderName,
book.getFolderName(),
"index.epubx"
)
if (!file.exists()) {
val input = if (book.bookUrl.isContentScheme()) {
val uri = Uri.parse(book.bookUrl)
appCtx.contentResolver.openInputStream(uri)
} else {
File(book.bookUrl).inputStream()
}
if (input != null) {
FileUtils.writeInputStream(file, input)
}
}
return file
}
@Synchronized @Synchronized
private fun getEFile(book: Book): EpubFile { private fun getEFile(book: Book): EpubFile {
getFile(book)
if (eFile == null || eFile?.book?.bookUrl != book.bookUrl) { if (eFile == null || eFile?.book?.bookUrl != book.bookUrl) {
eFile = EpubFile(book) eFile = EpubFile(book)
//对于Epub文件默认不启用替换 //对于Epub文件默认不启用替换
@ -126,9 +105,9 @@ class EpubFile(var book: Book) {
/*重写epub文件解析代码直接读出压缩包文件生成Resources给epublib这样的好处是可以逐一修改某些文件的格式错误*/ /*重写epub文件解析代码直接读出压缩包文件生成Resources给epublib这样的好处是可以逐一修改某些文件的格式错误*/
private fun readEpub(): EpubBook? { private fun readEpub(): EpubBook? {
try { try {
val file = getFile(book) val bis = LocalBook.getBookInputStream(book)
//通过懒加载读取epub //通过懒加载读取epub
return EpubReader().readEpubLazy(ZipFile(file), "utf-8") return EpubReader().readEpub(bis, "utf-8")
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e) Timber.e(e)
} }

View File

@ -15,6 +15,9 @@ import io.legado.app.utils.*
import splitties.init.appCtx import splitties.init.appCtx
import timber.log.Timber import timber.log.Timber
import java.io.File import java.io.File
import java.io.FileInputStream
import java.io.FileNotFoundException
import java.io.InputStream
import java.util.regex.Matcher import java.util.regex.Matcher
import java.util.regex.Pattern import java.util.regex.Pattern
import javax.script.SimpleBindings import javax.script.SimpleBindings
@ -26,6 +29,15 @@ object LocalBook {
FileUtils.createFolderIfNotExist(appCtx.externalFiles, folderName) FileUtils.createFolderIfNotExist(appCtx.externalFiles, folderName)
} }
@Throws(FileNotFoundException::class)
fun getBookInputStream(book: Book): InputStream {
if (book.bookUrl.isContentScheme()) {
val uri = Uri.parse(book.bookUrl)
return appCtx.contentResolver.openInputStream(uri)!!
}
return FileInputStream(File(book.bookUrl))
}
@Throws(Exception::class) @Throws(Exception::class)
fun getChapterList(book: Book): ArrayList<BookChapter> { fun getChapterList(book: Book): ArrayList<BookChapter> {
val chapters = when { val chapters = when {
@ -150,14 +162,12 @@ object LocalBook {
fun deleteBook(book: Book, deleteOriginal: Boolean) { fun deleteBook(book: Book, deleteOriginal: Boolean) {
kotlin.runCatching { kotlin.runCatching {
if (book.isLocalTxt() || book.isUmd()) { if (book.isLocalTxt() || book.isUmd()) {
val bookFile = cacheFolder.getFile(book.originName) cacheFolder.getFile(book.originName).delete()
bookFile.delete()
} }
if (book.isEpub()) { if (book.isEpub()) {
val bookFile = EpubFile.getFile(book).parentFile FileUtils.delete(
if (bookFile != null && bookFile.exists()) { cacheFolder.getFile(book.getFolderName())
FileUtils.delete(bookFile, true) )
}
} }
if (deleteOriginal) { if (deleteOriginal) {

View File

@ -1,6 +1,5 @@
package io.legado.app.model.localBook package io.legado.app.model.localBook
import android.net.Uri
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
@ -9,12 +8,7 @@ import io.legado.app.help.DefaultData
import io.legado.app.utils.EncodingDetect import io.legado.app.utils.EncodingDetect
import io.legado.app.utils.MD5Utils import io.legado.app.utils.MD5Utils
import io.legado.app.utils.StringUtils import io.legado.app.utils.StringUtils
import io.legado.app.utils.isContentScheme
import splitties.init.appCtx
import java.io.File
import java.io.FileInputStream
import java.io.FileNotFoundException import java.io.FileNotFoundException
import java.io.InputStream
import java.nio.charset.Charset import java.nio.charset.Charset
import java.util.regex.Matcher import java.util.regex.Matcher
import java.util.regex.Pattern import java.util.regex.Pattern
@ -28,7 +22,7 @@ class TextFile(private val book: Book) {
fun getChapterList(): ArrayList<BookChapter> { fun getChapterList(): ArrayList<BookChapter> {
var rulePattern: Pattern? = null var rulePattern: Pattern? = null
if (book.charset == null || book.tocUrl.isNotEmpty()) { if (book.charset == null || book.tocUrl.isNotEmpty()) {
getBookInputStream(book).use { bis -> LocalBook.getBookInputStream(book).use { bis ->
val buffer = ByteArray(BUFFER_SIZE) val buffer = ByteArray(BUFFER_SIZE)
var blockContent: String var blockContent: String
bis.read(buffer) bis.read(buffer)
@ -55,7 +49,7 @@ class TextFile(private val book: Book) {
private fun analyze(pattern: Pattern?): ArrayList<BookChapter> { private fun analyze(pattern: Pattern?): ArrayList<BookChapter> {
val toc = arrayListOf<BookChapter>() val toc = arrayListOf<BookChapter>()
getBookInputStream(book).use { bis -> LocalBook.getBookInputStream(book).use { bis ->
var tocRule: TxtTocRule? = null var tocRule: TxtTocRule? = null
val buffer = ByteArray(BUFFER_SIZE) val buffer = ByteArray(BUFFER_SIZE)
var blockContent: String var blockContent: String
@ -279,7 +273,7 @@ class TextFile(private val book: Book) {
fun getContent(book: Book, bookChapter: BookChapter): String { fun getContent(book: Book, bookChapter: BookChapter): String {
val count = (bookChapter.end!! - bookChapter.start!!).toInt() val count = (bookChapter.end!! - bookChapter.start!!).toInt()
val buffer = ByteArray(count) val buffer = ByteArray(count)
getBookInputStream(book).use { bis -> LocalBook.getBookInputStream(book).use { bis ->
bis.skip(bookChapter.start!!) bis.skip(bookChapter.start!!)
bis.read(buffer) bis.read(buffer)
} }
@ -288,15 +282,6 @@ class TextFile(private val book: Book) {
.replace("^[\\n\\s]+".toRegex(), "  ") .replace("^[\\n\\s]+".toRegex(), "  ")
} }
@Throws(FileNotFoundException::class)
private fun getBookInputStream(book: Book): InputStream {
if (book.bookUrl.isContentScheme()) {
val uri = Uri.parse(book.bookUrl)
return appCtx.contentResolver.openInputStream(uri)!!
}
return FileInputStream(File(book.bookUrl))
}
private fun getTocRules(): List<TxtTocRule> { private fun getTocRules(): List<TxtTocRule> {
var rules = appDb.txtTocRuleDao.enabled var rules = appDb.txtTocRuleDao.enabled
if (rules.isEmpty()) { if (rules.isEmpty()) {

View File

@ -1,12 +1,10 @@
package io.legado.app.model.localBook package io.legado.app.model.localBook
import android.net.Uri
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.utils.FileUtils import io.legado.app.utils.FileUtils
import io.legado.app.utils.MD5Utils import io.legado.app.utils.MD5Utils
import io.legado.app.utils.externalFiles import io.legado.app.utils.externalFiles
import io.legado.app.utils.isContentScheme
import me.ag2s.umdlib.domain.UmdBook import me.ag2s.umdlib.domain.UmdBook
import me.ag2s.umdlib.umd.UmdReader import me.ag2s.umdlib.umd.UmdReader
import splitties.init.appCtx import splitties.init.appCtx
@ -87,12 +85,7 @@ class UmdFile(var book: Book) {
} }
private fun readUmd(): UmdBook? { private fun readUmd(): UmdBook? {
val input = if (book.bookUrl.isContentScheme()) { val input = LocalBook.getBookInputStream(book)
val uri = Uri.parse(book.bookUrl)
appCtx.contentResolver.openInputStream(uri)
} else {
File(book.bookUrl).inputStream()
}
return UmdReader().read(input) return UmdReader().read(input)
} }