Use ComicInfo.xml for chapter metadata in localSource (#2332)

Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
This commit is contained in:
Radon Rosborough
2025-08-06 16:01:54 -07:00
committed by GitHub
parent 49a84c8914
commit 32257e438e
2 changed files with 38 additions and 10 deletions

View File

@@ -11,6 +11,9 @@ The format is a modified version of [Keep a Changelog](https://keepachangelog.co
- `Other` - for technical stuff. - `Other` - for technical stuff.
## [Unreleased] ## [Unreleased]
### Changed
- LocalSource now reads ComicInfo.xml file for chapter (if available) to display chapter title, number and scanlator ([@raxod502](https://github.com/radian-software)) ([#2332](https://github.com/mihonapp/mihon/pull/2332))
### Fixes ### Fixes
- Fixed scrollbar sometimes not showing during scroll or not reaching the bottom with few items ([@anirudhsnayak](https://github.com/anirudhsnayak)) ([#2304](https://github.com/mihonapp/mihon/pull/2304)) - Fixed scrollbar sometimes not showing during scroll or not reaching the bottom with few items ([@anirudhsnayak](https://github.com/anirudhsnayak)) ([#2304](https://github.com/mihonapp/mihon/pull/2304))

View File

@@ -190,7 +190,7 @@ actual class LocalSource(
noXmlFile == null -> { noXmlFile == null -> {
val chapterArchives = mangaDirFiles.filter(Archive::isSupported) val chapterArchives = mangaDirFiles.filter(Archive::isSupported)
val copiedFile = copyComicInfoFileFromArchive(chapterArchives, mangaDir) val copiedFile = copyComicInfoFileFromChapters(chapterArchives, mangaDir)
if (copiedFile != null) { if (copiedFile != null) {
setMangaDetailsFromComicInfoFile(copiedFile.openInputStream(), manga) setMangaDetailsFromComicInfoFile(copiedFile.openInputStream(), manga)
} else { } else {
@@ -206,13 +206,24 @@ actual class LocalSource(
return@withIOContext manga return@withIOContext manga
} }
private fun copyComicInfoFileFromArchive(chapterArchives: List<UniFile>, folder: UniFile): UniFile? { private fun <T> getComicInfoForChapter(chapter: UniFile, block: (InputStream) -> T): T? {
if (chapter.isDirectory) {
return chapter.findFile(COMIC_INFO_FILE)?.let { file ->
file.openInputStream().use(block)
}
} else {
return chapter.archiveReader(context).use { reader ->
reader.getInputStream(COMIC_INFO_FILE)?.use(block)
}
}
}
private fun copyComicInfoFileFromChapters(chapterArchives: List<UniFile>, folder: UniFile): UniFile? {
for (chapter in chapterArchives) { for (chapter in chapterArchives) {
chapter.archiveReader(context).use { reader -> val file = getComicInfoForChapter(chapter) f@{ stream ->
reader.getInputStream(COMIC_INFO_FILE)?.use { stream -> return@f copyComicInfoFile(stream, folder)
return copyComicInfoFile(stream, folder)
}
} }
if (file != null) return file
} }
return null return null
} }
@@ -225,12 +236,22 @@ actual class LocalSource(
} }
} }
private fun setMangaDetailsFromComicInfoFile(stream: InputStream, manga: SManga) { private fun parseComicInfo(stream: InputStream): ComicInfo {
val comicInfo = AndroidXmlReader(stream, StandardCharsets.UTF_8.name()).use { return AndroidXmlReader(stream, StandardCharsets.UTF_8.name()).use {
xml.decodeFromReader<ComicInfo>(it) xml.decodeFromReader<ComicInfo>(it)
} }
}
manga.copyFromComicInfo(comicInfo) private fun setMangaDetailsFromComicInfoFile(stream: InputStream, manga: SManga) {
manga.copyFromComicInfo(parseComicInfo(stream))
}
private fun setChapterDetailsFromComicInfoFile(stream: InputStream, chapter: SChapter) {
val comicInfo = parseComicInfo(stream)
comicInfo.title?.let { chapter.name = it.value }
comicInfo.number?.value?.toFloatOrNull()?.let { chapter.chapter_number = it }
comicInfo.translator?.let { chapter.scanlator = it.value }
} }
// Chapters // Chapters
@@ -257,6 +278,10 @@ actual class LocalSource(
format.file.epubReader(context).use { epub -> format.file.epubReader(context).use { epub ->
epub.fillMetadata(manga, this) epub.fillMetadata(manga, this)
} }
} else {
getComicInfoForChapter(chapterFile) { stream ->
setChapterDetailsFromComicInfoFile(stream, this)
}
} }
} }
} }