🛠️ Improve Chapter parsing

* Made parsing more universal (more books are supported)
This commit is contained in:
Acclorite 2024-09-28 12:53:02 +03:00
parent e6014866cf
commit e04bb0aca7
8 changed files with 27 additions and 24 deletions

View file

@ -3,7 +3,6 @@ package ua.acclorite.book_story
import android.app.Application
import android.app.NotificationChannel
import android.app.NotificationManager
import android.content.Context
import dagger.hilt.android.HiltAndroidApp
import ua.acclorite.book_story.data.local.notification.UpdatesNotificationService
@ -23,7 +22,7 @@ class Application : Application() {
)
val notificationManager = getSystemService(
Context.NOTIFICATION_SERVICE
NOTIFICATION_SERVICE
) as NotificationManager
notificationManager.createNotificationChannel(channel)
}

View file

@ -19,7 +19,7 @@ class BookMapperImpl @Inject constructor() : BookMapper {
author = book.author.getAsString(),
textPath = book.textPath,
description = book.description,
image = if (book.coverImage != null) book.coverImage.toString() else null,
image = book.coverImage?.toString(),
category = book.category,
chapters = book.chapters
)

View file

@ -7,11 +7,10 @@ import javax.inject.Inject
class DocumentParser @Inject constructor() {
/**
* Parses document to get it's text.
* If [fragment] is not null, searches document for specific [fragment].
*
* @return Parsed text line by line.
*/
suspend fun Document.parseDocument(fragment: String?): List<String> {
suspend fun Document.parseDocument(): List<String> {
val lines = mutableListOf<String>()
yield()
@ -32,10 +31,6 @@ class DocumentParser @Inject constructor() {
yield()
body()
.run {
fragment?.let { return@run getElementById(it) ?: this }
this
}
.wholeText()
.lines()
.forEach { line ->

View file

@ -107,7 +107,7 @@ class EpubTextParser @Inject constructor(
it.readText()
}
val chapter = documentParser.run { Jsoup.parse(content).parseDocument(fragment = null) }
val chapter = documentParser.run { Jsoup.parse(content).parseDocument() }
if (chapter.isEmpty()) {
Log.w(EPUB_TAG, "Chapter ${entry.name} is empty.")
return@forEach
@ -146,7 +146,7 @@ class EpubTextParser @Inject constructor(
private suspend fun parseWithToc(tocEntry: ZipEntry, zip: ZipFile): List<ChapterWithText>? {
Log.i(EPUB_TAG, "TOC Entry: ${tocEntry.name}")
val chapters = mutableListOf<ChapterWithText>()
val chapters = mutableMapOf<String, ChapterWithText>()
var emptyChapters = 0
var chapterTextIndex = -1
var chapterIndex = 1
@ -172,12 +172,22 @@ class EpubTextParser @Inject constructor(
return null
}
val uri = Uri.parse(this) ?: return@run this to null
(uri.path ?: this) to uri.fragment
Uri.parse(this).path ?: this
}
if (chapters.containsKey(chapterSrc)) {
chapters[chapterSrc] = chapters[chapterSrc]!!.run {
copy(
chapter = chapter.copy(
title = "${chapter.title} / $chapterTitle"
)
)
}
return@forEach
}
zip.entries().asSequence().find { entry ->
entry.name.endsWith(chapterSrc.first)
entry.name.endsWith(chapterSrc)
}.apply {
if (this == null) {
Log.e(EPUB_TAG, "No chapter entry found: $chapterTitle")
@ -191,9 +201,7 @@ class EpubTextParser @Inject constructor(
}
val chapter = documentParser.run {
Jsoup.parse(content).parseDocument(
fragment = chapterSrc.second
).dropWhile {
Jsoup.parse(content).parseDocument().dropWhile {
it == chapterTitle // Remove chapter title if present
}
}
@ -203,8 +211,9 @@ class EpubTextParser @Inject constructor(
return@forEach
}
chapters.add(
ChapterWithText(
chapters.put(
key = chapterSrc,
value = ChapterWithText(
chapter = Chapter(
index = chapters.size,
title = chapterTitle,
@ -231,6 +240,6 @@ class EpubTextParser @Inject constructor(
return null
}
return chapters
return chapters.values.toList().sortedBy { it.chapter.index }
}
}

View file

@ -23,7 +23,7 @@ class HtmTextParser @Inject constructor(
Log.i(HTM_TAG, "Started HTM parsing: ${file.name}.")
return try {
val lines = documentParser.run { Jsoup.parse(file).parseDocument(null) }
val lines = documentParser.run { Jsoup.parse(file).parseDocument() }
yield()

View file

@ -23,7 +23,7 @@ class HtmlTextParser @Inject constructor(
Log.i(HTML_TAG, "Started HTML parsing: ${file.name}.")
return try {
val lines = documentParser.run { Jsoup.parse(file).parseDocument(null) }
val lines = documentParser.run { Jsoup.parse(file).parseDocument() }
yield()

View file

@ -72,7 +72,7 @@ fun AnimatedTopAppBar(
Box(modifier = Modifier.fillMaxWidth()) {
animatedTopBars.forEach { data ->
CustomAnimatedVisibility(
visible = data.contentVisibility ?: false,
visible = data.contentVisibility == true,
enter = fadeIn(spring(stiffness = Spring.StiffnessMediumLow)),
exit = fadeOut(spring(stiffness = Spring.StiffnessMediumLow))
) {

View file

@ -244,7 +244,7 @@ class Navigator @AssistedInject constructor(
savedStateHandle[USE_BACK_ANIM] = useBackAnimation
savedStateHandle[CURRENT_SCREEN] = backStack.value.last()
backStack.value.removeLast()
backStack.value.removeAt(backStack.value.lastIndex)
}
}