merge(fix): 227-url-decoding into develop
This commit is contained in:
commit
19db53473d
5 changed files with 50 additions and 31 deletions
|
|
@ -16,6 +16,8 @@ import ua.acclorite.book_story.core.helpers.clearMarkdown
|
|||
import ua.acclorite.book_story.core.helpers.containsVisibleText
|
||||
import ua.acclorite.book_story.domain.model.reader.ReaderText
|
||||
import java.io.File
|
||||
import java.net.URLDecoder
|
||||
import java.nio.charset.StandardCharsets
|
||||
import java.util.zip.ZipEntry
|
||||
import java.util.zip.ZipFile
|
||||
import javax.inject.Inject
|
||||
|
|
@ -71,7 +73,7 @@ class DocumentParser @Inject constructor(
|
|||
if (!link.startsWith("http") || element.wholeText().isBlank()) return@forEach
|
||||
|
||||
if (link.startsWith("http://")) {
|
||||
link = link.replace("http://", "https://")
|
||||
link = link.replaceFirst("http://", "https://")
|
||||
}
|
||||
|
||||
element.prepend("[")
|
||||
|
|
@ -84,6 +86,7 @@ class DocumentParser @Inject constructor(
|
|||
.trim()
|
||||
.substringAfterLast(File.separator)
|
||||
.lowercase()
|
||||
.let { src -> URLDecoder.decode(src, StandardCharsets.UTF_8.name()) }
|
||||
.takeIf {
|
||||
it.containsVisibleText() && imageEntries?.any { image ->
|
||||
it == image.name.substringAfterLast(File.separator).lowercase()
|
||||
|
|
@ -103,6 +106,7 @@ class DocumentParser @Inject constructor(
|
|||
.trim()
|
||||
.substringAfterLast(File.separator)
|
||||
.lowercase()
|
||||
.let { src -> URLDecoder.decode(src, StandardCharsets.UTF_8.name()) }
|
||||
.takeIf {
|
||||
it.containsVisibleText() && imageEntries?.any { image ->
|
||||
it == image.name.substringAfterLast(File.separator).lowercase()
|
||||
|
|
|
|||
|
|
@ -11,6 +11,5 @@ import ua.acclorite.book_story.data.model.library.BookWithCover
|
|||
|
||||
|
||||
interface FileParser {
|
||||
|
||||
suspend fun parse(cachedFile: CachedFile): BookWithCover?
|
||||
}
|
||||
|
|
@ -10,6 +10,5 @@ import ua.acclorite.book_story.data.model.file.CachedFile
|
|||
import ua.acclorite.book_story.domain.model.reader.ReaderText
|
||||
|
||||
interface TextParser {
|
||||
|
||||
suspend fun parse(cachedFile: CachedFile): List<ReaderText>
|
||||
}
|
||||
|
|
@ -11,6 +11,7 @@ import android.graphics.BitmapFactory
|
|||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.jsoup.Jsoup
|
||||
import org.jsoup.parser.Parser
|
||||
import ua.acclorite.book_story.R
|
||||
import ua.acclorite.book_story.core.ui.UIText
|
||||
import ua.acclorite.book_story.data.model.file.CachedFile
|
||||
|
|
@ -18,6 +19,8 @@ import ua.acclorite.book_story.data.model.library.BookWithCover
|
|||
import ua.acclorite.book_story.data.parser.FileParser
|
||||
import ua.acclorite.book_story.domain.model.library.Book
|
||||
import java.io.File
|
||||
import java.net.URLDecoder
|
||||
import java.nio.charset.StandardCharsets
|
||||
import java.util.zip.ZipFile
|
||||
import javax.inject.Inject
|
||||
|
||||
|
|
@ -40,7 +43,7 @@ class EpubFileParser @Inject constructor() : FileParser {
|
|||
.getInputStream(opfEntry)
|
||||
.bufferedReader()
|
||||
.use { it.readText() }
|
||||
val document = Jsoup.parse(opfContent)
|
||||
val document = Jsoup.parse(opfContent, Parser.xmlParser())
|
||||
|
||||
val title = document.select("metadata > dc|title").text().trim().run {
|
||||
ifBlank {
|
||||
|
|
@ -67,18 +70,24 @@ class EpubFileParser @Inject constructor() : FileParser {
|
|||
val coverImage = document
|
||||
.select("metadata > meta[name=cover]")
|
||||
.attr("content")
|
||||
.run {
|
||||
if (isNotBlank()) {
|
||||
.let { coverId ->
|
||||
if (coverId.isNotBlank()) {
|
||||
document
|
||||
.select("manifest > item[id=$this]")
|
||||
.select("manifest > item[id=$coverId]")
|
||||
.attr("href")
|
||||
.apply { if (isNotBlank()) return@run this }
|
||||
.also { src ->
|
||||
if (src.isBlank()) return@also
|
||||
return@let src
|
||||
}
|
||||
}
|
||||
|
||||
document
|
||||
.select("manifest > item[media-type*=image]")
|
||||
.firstOrNull()?.attr("href")
|
||||
.firstOrNull()
|
||||
?.attr("href")
|
||||
?.also { src -> if (src.isBlank()) return@let null }
|
||||
}
|
||||
?.let { src -> URLDecoder.decode(src, StandardCharsets.UTF_8.name()) }
|
||||
|
||||
book = BookWithCover(
|
||||
book = Book(
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ import kotlinx.coroutines.awaitAll
|
|||
import kotlinx.coroutines.withContext
|
||||
import kotlinx.coroutines.yield
|
||||
import org.jsoup.Jsoup
|
||||
import org.jsoup.parser.Parser
|
||||
import ua.acclorite.book_story.core.data.ExtensionsData
|
||||
import ua.acclorite.book_story.core.helpers.addAll
|
||||
import ua.acclorite.book_story.core.helpers.containsVisibleText
|
||||
|
|
@ -25,6 +26,8 @@ import ua.acclorite.book_story.data.parser.DocumentParser
|
|||
import ua.acclorite.book_story.data.parser.TextParser
|
||||
import ua.acclorite.book_story.domain.model.reader.ReaderText
|
||||
import java.io.File
|
||||
import java.net.URLDecoder
|
||||
import java.nio.charset.StandardCharsets
|
||||
import java.util.concurrent.ConcurrentLinkedQueue
|
||||
import java.util.zip.ZipEntry
|
||||
import java.util.zip.ZipFile
|
||||
|
|
@ -117,7 +120,7 @@ class EpubTextParser @Inject constructor(
|
|||
val unformattedText = ConcurrentLinkedQueue<Pair<Int, List<ReaderText>>>()
|
||||
|
||||
// Asynchronously getting all chapters with text
|
||||
val jobs = chapterEntries.mapIndexed { index, entry ->
|
||||
chapterEntries.mapIndexed { index, entry ->
|
||||
async(dispatcher) {
|
||||
yield()
|
||||
|
||||
|
|
@ -131,8 +134,7 @@ class EpubTextParser @Inject constructor(
|
|||
|
||||
yield()
|
||||
}
|
||||
}
|
||||
jobs.awaitAll()
|
||||
}.awaitAll()
|
||||
|
||||
// Sorting chapters in correct order
|
||||
readerText.addAll {
|
||||
|
|
@ -167,7 +169,7 @@ class EpubTextParser @Inject constructor(
|
|||
zip.getInputStream(entry)
|
||||
}.bufferedReader().use { it.readText() }
|
||||
var readerText = documentParser.parseDocument(
|
||||
document = Jsoup.parse(content),
|
||||
document = Jsoup.parse(content, Parser.htmlParser()),
|
||||
zipFile = zip,
|
||||
imageEntries = imageEntries,
|
||||
includeChapter = false
|
||||
|
|
@ -236,21 +238,21 @@ class EpubTextParser @Inject constructor(
|
|||
}
|
||||
|
||||
val source = navPoint.selectFirst("content")?.attr("src")?.trim()
|
||||
.let { source ->
|
||||
if (source.isNullOrBlank()) return@forEach
|
||||
source.toUri().path ?: source
|
||||
}.substringAfterLast(File.separator)
|
||||
.also { src -> if (src.isNullOrBlank()) return@forEach }
|
||||
.let { src -> URLDecoder.decode(src, StandardCharsets.UTF_8.name()) }
|
||||
.let { src -> src.toUri().path ?: src }
|
||||
.substringAfterLast(File.separator)
|
||||
|
||||
val parent = navPoint.parent()
|
||||
.let { parent ->
|
||||
if (parent == null) return@let null
|
||||
?.let { parent ->
|
||||
if (!parent.tagName().equals("navPoint", ignoreCase = true)) return@let null
|
||||
|
||||
val parentSource = parent.selectFirst("content")?.attr("src")?.trim()
|
||||
.let { parentSource ->
|
||||
if (parentSource.isNullOrBlank()) return@forEach
|
||||
parentSource.toUri().path ?: parentSource
|
||||
}.substringAfterLast(File.separator)
|
||||
.also { src -> if (src.isNullOrBlank()) return@forEach }
|
||||
.let { src -> URLDecoder.decode(src, StandardCharsets.UTF_8.name()) }
|
||||
.let { src -> src.toUri().path ?: src }
|
||||
.substringAfterLast(File.separator)
|
||||
|
||||
if (parentSource == source) return@let null
|
||||
return@let parentSource
|
||||
}
|
||||
|
|
@ -278,9 +280,7 @@ class EpubTextParser @Inject constructor(
|
|||
chapterTitleMap: Map<Source, ReaderText.Chapter>?
|
||||
): ReaderText.Chapter? {
|
||||
if (chapterTitleMap.isNullOrEmpty()) return null
|
||||
return chapterTitleMap.getOrElse(chapterSource.substringAfterLast(File.separator)) {
|
||||
null
|
||||
}
|
||||
return chapterTitleMap.getOrElse(chapterSource.substringAfterLast(File.separator)) { null }
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -297,19 +297,27 @@ class EpubTextParser @Inject constructor(
|
|||
val opfContent = getInputStream(opfEntry).bufferedReader().use {
|
||||
it.readText()
|
||||
}
|
||||
val document = Jsoup.parse(opfContent)
|
||||
val document = Jsoup.parse(opfContent, Parser.xmlParser())
|
||||
val zipEntries = entries().toList()
|
||||
|
||||
val manifestItems = document.select("manifest > item").associate {
|
||||
it.attr("id") to it.attr("href")
|
||||
it.attr("id").to(
|
||||
it.attr("href").let { src ->
|
||||
URLDecoder.decode(src, StandardCharsets.UTF_8.name())
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
document.select("spine > itemref").mapNotNull { itemRef ->
|
||||
val spineId = itemRef.attr("idref")
|
||||
val chapterSource = manifestItems[spineId]
|
||||
?.substringAfterLast(File.separator)
|
||||
?.lowercase()
|
||||
?: return@mapNotNull null
|
||||
.let { src ->
|
||||
if (src.isNullOrBlank()) return@mapNotNull null
|
||||
URLDecoder.decode(
|
||||
src.substringAfterLast(File.separator).lowercase(),
|
||||
StandardCharsets.UTF_8.name()
|
||||
)
|
||||
}
|
||||
|
||||
zipEntries.find { entry ->
|
||||
entry.name.substringAfterLast(File.separator).lowercase() == chapterSource
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue