|
|
@ -1,16 +1,15 @@ |
|
|
|
package io.legado.app.help |
|
|
|
package io.legado.app.help |
|
|
|
|
|
|
|
|
|
|
|
import android.net.Uri |
|
|
|
|
|
|
|
import androidx.documentfile.provider.DocumentFile |
|
|
|
|
|
|
|
import com.github.houbb.opencc4j.core.impl.ZhConvertBootstrap |
|
|
|
import com.github.houbb.opencc4j.core.impl.ZhConvertBootstrap |
|
|
|
import io.legado.app.App |
|
|
|
import io.legado.app.App |
|
|
|
import io.legado.app.R |
|
|
|
|
|
|
|
import io.legado.app.constant.EventBus |
|
|
|
import io.legado.app.constant.EventBus |
|
|
|
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.ReplaceRule |
|
|
|
import io.legado.app.data.entities.ReplaceRule |
|
|
|
import io.legado.app.model.localBook.AnalyzeTxtFile |
|
|
|
import io.legado.app.model.localBook.AnalyzeTxtFile |
|
|
|
import io.legado.app.utils.* |
|
|
|
import io.legado.app.utils.FileUtils |
|
|
|
|
|
|
|
import io.legado.app.utils.MD5Utils |
|
|
|
|
|
|
|
import io.legado.app.utils.postEvent |
|
|
|
import kotlinx.coroutines.Dispatchers.IO |
|
|
|
import kotlinx.coroutines.Dispatchers.IO |
|
|
|
import kotlinx.coroutines.Dispatchers.Main |
|
|
|
import kotlinx.coroutines.Dispatchers.Main |
|
|
|
import kotlinx.coroutines.withContext |
|
|
|
import kotlinx.coroutines.withContext |
|
|
@ -21,12 +20,9 @@ import kotlin.math.min |
|
|
|
|
|
|
|
|
|
|
|
object BookHelp { |
|
|
|
object BookHelp { |
|
|
|
private const val cacheFolderName = "book_cache" |
|
|
|
private const val cacheFolderName = "book_cache" |
|
|
|
val downloadPath: String |
|
|
|
private val downloadDir: File = |
|
|
|
get() = App.INSTANCE.getPrefString(R.string.pk_download_path) |
|
|
|
App.INSTANCE.getExternalFilesDir(null) |
|
|
|
?: App.INSTANCE.getExternalFilesDir(null)?.absolutePath |
|
|
|
?: App.INSTANCE.cacheDir |
|
|
|
?: App.INSTANCE.cacheDir.absolutePath |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private val downloadUri get() = Uri.parse(downloadPath) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private fun bookFolderName(book: Book): String { |
|
|
|
private fun bookFolderName(book: Book): String { |
|
|
|
return formatFolderName(book.name) + MD5Utils.md5Encode16(book.bookUrl) |
|
|
|
return formatFolderName(book.name) + MD5Utils.md5Encode16(book.bookUrl) |
|
|
@ -41,107 +37,54 @@ object BookHelp { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
fun clearCache() { |
|
|
|
fun clearCache() { |
|
|
|
if (downloadPath.isContentPath()) { |
|
|
|
|
|
|
|
DocumentFile.fromTreeUri(App.INSTANCE, downloadUri) |
|
|
|
|
|
|
|
?.findFile(cacheFolderName) |
|
|
|
|
|
|
|
?.delete() |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
FileUtils.deleteFile( |
|
|
|
FileUtils.deleteFile( |
|
|
|
FileUtils.getPath( |
|
|
|
FileUtils.getPath( |
|
|
|
File(downloadPath), |
|
|
|
downloadDir, |
|
|
|
subDirs = *arrayOf(cacheFolderName) |
|
|
|
subDirs = *arrayOf(cacheFolderName) |
|
|
|
) |
|
|
|
) |
|
|
|
) |
|
|
|
) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Synchronized |
|
|
|
@Synchronized |
|
|
|
fun saveContent(book: Book, bookChapter: BookChapter, content: String) { |
|
|
|
fun saveContent(book: Book, bookChapter: BookChapter, content: String) { |
|
|
|
if (content.isEmpty()) return |
|
|
|
if (content.isEmpty()) return |
|
|
|
if (downloadPath.isContentPath()) { |
|
|
|
|
|
|
|
DocumentFile.fromTreeUri(App.INSTANCE, downloadUri)?.let { root -> |
|
|
|
|
|
|
|
DocumentUtils.createFileIfNotExist( |
|
|
|
|
|
|
|
root, |
|
|
|
|
|
|
|
formatChapterName(bookChapter), |
|
|
|
|
|
|
|
subDirs = *arrayOf(cacheFolderName, bookFolderName(book)) |
|
|
|
|
|
|
|
)?.uri?.writeText(App.INSTANCE, content) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
FileUtils.createFileIfNotExist( |
|
|
|
FileUtils.createFileIfNotExist( |
|
|
|
File(downloadPath), |
|
|
|
downloadDir, |
|
|
|
formatChapterName(bookChapter), |
|
|
|
formatChapterName(bookChapter), |
|
|
|
subDirs = *arrayOf(cacheFolderName, bookFolderName(book)) |
|
|
|
subDirs = *arrayOf(cacheFolderName, bookFolderName(book)) |
|
|
|
).writeText(content) |
|
|
|
).writeText(content) |
|
|
|
} |
|
|
|
|
|
|
|
postEvent(EventBus.SAVE_CONTENT, bookChapter) |
|
|
|
postEvent(EventBus.SAVE_CONTENT, bookChapter) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
fun getChapterFiles(book: Book): List<String> { |
|
|
|
fun getChapterFiles(book: Book): List<String> { |
|
|
|
val fileNameList = arrayListOf<String>() |
|
|
|
val fileNameList = arrayListOf<String>() |
|
|
|
if (downloadPath.isContentPath()) { |
|
|
|
|
|
|
|
DocumentFile.fromTreeUri(App.INSTANCE, downloadUri)?.let { root -> |
|
|
|
|
|
|
|
DocumentUtils.createFolderIfNotExist( |
|
|
|
|
|
|
|
root, |
|
|
|
|
|
|
|
subDirs = *arrayOf(cacheFolderName, bookFolderName(book)) |
|
|
|
|
|
|
|
)?.let { bookDoc -> |
|
|
|
|
|
|
|
DocumentUtils.listFiles(App.INSTANCE, bookDoc.uri).forEach { |
|
|
|
|
|
|
|
fileNameList.add(it.name) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
FileUtils.createFolderIfNotExist( |
|
|
|
FileUtils.createFolderIfNotExist( |
|
|
|
File(downloadPath), |
|
|
|
downloadDir, |
|
|
|
subDirs = *arrayOf(cacheFolderName, bookFolderName(book)) |
|
|
|
subDirs = *arrayOf(cacheFolderName, bookFolderName(book)) |
|
|
|
).list()?.let { |
|
|
|
).list()?.let { |
|
|
|
fileNameList.addAll(it) |
|
|
|
fileNameList.addAll(it) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return fileNameList |
|
|
|
return fileNameList |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
fun hasContent(book: Book, bookChapter: BookChapter): Boolean { |
|
|
|
fun hasContent(book: Book, bookChapter: BookChapter): Boolean { |
|
|
|
when { |
|
|
|
return if (book.isLocalBook()) { |
|
|
|
book.isLocalBook() -> { |
|
|
|
true |
|
|
|
return true |
|
|
|
} else { |
|
|
|
} |
|
|
|
FileUtils.exists( |
|
|
|
downloadPath.isContentPath() -> { |
|
|
|
downloadDir, |
|
|
|
DocumentFile.fromTreeUri(App.INSTANCE, downloadUri)?.let { root -> |
|
|
|
|
|
|
|
return DocumentUtils.exists( |
|
|
|
|
|
|
|
root, |
|
|
|
|
|
|
|
formatChapterName(bookChapter), |
|
|
|
|
|
|
|
subDirs = *arrayOf(cacheFolderName, bookFolderName(book)) |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else -> { |
|
|
|
|
|
|
|
return FileUtils.exists( |
|
|
|
|
|
|
|
File(downloadPath), |
|
|
|
|
|
|
|
formatChapterName(bookChapter), |
|
|
|
formatChapterName(bookChapter), |
|
|
|
subDirs = *arrayOf(cacheFolderName, bookFolderName(book)) |
|
|
|
subDirs = *arrayOf(cacheFolderName, bookFolderName(book)) |
|
|
|
) |
|
|
|
) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
return false |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fun getContent(book: Book, bookChapter: BookChapter): String? { |
|
|
|
fun getContent(book: Book, bookChapter: BookChapter): String? { |
|
|
|
when { |
|
|
|
if (book.isLocalBook()) { |
|
|
|
book.isLocalBook() -> { |
|
|
|
|
|
|
|
return AnalyzeTxtFile.getContent(book, bookChapter) |
|
|
|
return AnalyzeTxtFile.getContent(book, bookChapter) |
|
|
|
} |
|
|
|
} else { |
|
|
|
downloadPath.isContentPath() -> { |
|
|
|
|
|
|
|
DocumentFile.fromTreeUri(App.INSTANCE, downloadUri)?.let { root -> |
|
|
|
|
|
|
|
return DocumentUtils.getDirDocument( |
|
|
|
|
|
|
|
root, |
|
|
|
|
|
|
|
subDirs = *arrayOf(cacheFolderName, bookFolderName(book)) |
|
|
|
|
|
|
|
)?.findFile(formatChapterName(bookChapter)) |
|
|
|
|
|
|
|
?.uri?.readText(App.INSTANCE) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else -> { |
|
|
|
|
|
|
|
val file = FileUtils.getFile( |
|
|
|
val file = FileUtils.getFile( |
|
|
|
File(downloadPath), |
|
|
|
downloadDir, |
|
|
|
formatChapterName(bookChapter), |
|
|
|
formatChapterName(bookChapter), |
|
|
|
subDirs = *arrayOf(cacheFolderName, bookFolderName(book)) |
|
|
|
subDirs = *arrayOf(cacheFolderName, bookFolderName(book)) |
|
|
|
) |
|
|
|
) |
|
|
@ -149,31 +92,20 @@ object BookHelp { |
|
|
|
return file.readText() |
|
|
|
return file.readText() |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return null |
|
|
|
return null |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
fun delContent(book: Book, bookChapter: BookChapter) { |
|
|
|
fun delContent(book: Book, bookChapter: BookChapter) { |
|
|
|
when { |
|
|
|
if (book.isLocalBook()) { |
|
|
|
book.isLocalBook() -> return |
|
|
|
return |
|
|
|
downloadPath.isContentPath() -> { |
|
|
|
} else { |
|
|
|
DocumentFile.fromTreeUri(App.INSTANCE, downloadUri)?.let { root -> |
|
|
|
|
|
|
|
DocumentUtils.getDirDocument( |
|
|
|
|
|
|
|
root, |
|
|
|
|
|
|
|
subDirs = *arrayOf(cacheFolderName, bookFolderName(book)) |
|
|
|
|
|
|
|
)?.findFile(formatChapterName(bookChapter)) |
|
|
|
|
|
|
|
?.delete() |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else -> { |
|
|
|
|
|
|
|
FileUtils.createFileIfNotExist( |
|
|
|
FileUtils.createFileIfNotExist( |
|
|
|
File(downloadPath), |
|
|
|
downloadDir, |
|
|
|
formatChapterName(bookChapter), |
|
|
|
formatChapterName(bookChapter), |
|
|
|
subDirs = *arrayOf(cacheFolderName, bookFolderName(book)) |
|
|
|
subDirs = *arrayOf(cacheFolderName, bookFolderName(book)) |
|
|
|
).delete() |
|
|
|
).delete() |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private fun formatFolderName(folderName: String): String { |
|
|
|
private fun formatFolderName(folderName: String): String { |
|
|
|
return folderName.replace("[\\\\/:*?\"<>|.]".toRegex(), "") |
|
|
|
return folderName.replace("[\\\\/:*?\"<>|.]".toRegex(), "") |
|
|
|