Generate ComicInfo.xml on download
This commit is contained in:
1 parent
41f8168c28
commit
d6a58d5d34
4 files changed
+155
-6
No files matched your search
@@ -372,7 +372,7 @@ object EhEngine {
|
||||
}
|
||||
}.fetchUsingAsText(String::parseAs)
|
||||
|
||||
suspend fun fillGalleryListByApi(galleryInfoList: List<GalleryInfo>, referer: String) =
|
||||
suspend fun fillGalleryListByApi(galleryInfoList: List<GalleryInfo>, referer: String? = null) =
|
||||
galleryInfoList.chunked(MAX_REQUEST_SIZE).chunked(MAX_SEQUENTIAL_REQUESTS).forEachIndexed { index, chunk ->
|
||||
if (index != 0) {
|
||||
delay(REQUEST_INTERVAL)
|
||||
|
||||
@@ -0,0 +1,122 @@
|
||||
package com.hippo.ehviewer.spider
|
||||
|
||||
import com.hippo.ehviewer.client.EhTagDatabase
|
||||
import com.hippo.ehviewer.client.EhUrl
|
||||
import com.hippo.ehviewer.client.data.GalleryInfo
|
||||
import com.hippo.unifile.UniFile
|
||||
import com.hippo.unifile.openOutputStream
|
||||
import java.io.OutputStreamWriter
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
import nl.adaptivity.xmlutil.XmlDeclMode
|
||||
import nl.adaptivity.xmlutil.core.XmlVersion
|
||||
import nl.adaptivity.xmlutil.newGenericWriter
|
||||
import nl.adaptivity.xmlutil.serialization.XML
|
||||
import nl.adaptivity.xmlutil.serialization.XmlElement
|
||||
import nl.adaptivity.xmlutil.xmlStreaming
|
||||
|
||||
const val COMIC_INFO_FILE = "ComicInfo.xml"
|
||||
|
||||
private val xml = XML {
|
||||
recommended {
|
||||
ignoreUnknownChildren()
|
||||
}
|
||||
xmlDeclMode = XmlDeclMode.Charset
|
||||
xmlVersion = XmlVersion.XML10
|
||||
}
|
||||
|
||||
fun GalleryInfo.getComicInfo(): ComicInfo {
|
||||
val artists = mutableListOf<String>()
|
||||
val groups = mutableListOf<String>()
|
||||
val characters = mutableListOf<String>()
|
||||
val parodies = mutableListOf<String>()
|
||||
val tags = mutableListOf<String>()
|
||||
simpleTags?.forEach {
|
||||
val (namespace, tag) = it.split(':', limit = 2)
|
||||
when (namespace) {
|
||||
"artist", "cosplayer" -> artists.add(tag)
|
||||
"group" -> groups.add(tag)
|
||||
"character" -> characters.add(tag)
|
||||
"parody" -> if (tag != "original") parodies.add(tag)
|
||||
"language", "reclass" -> Unit
|
||||
else -> tags.add("${EhTagDatabase.namespaceToPrefix(namespace)}:$tag")
|
||||
}
|
||||
}
|
||||
return ComicInfo(
|
||||
series = title,
|
||||
alternateSeries = titleJpn.takeUnless { it.isNullOrBlank() },
|
||||
writer = groups.takeUnless { it.isEmpty() }?.joinToString(),
|
||||
penciller = artists.takeUnless { it.isEmpty() }?.joinToString(),
|
||||
genre = tags.takeUnless { it.isEmpty() }?.joinToString(),
|
||||
web = EhUrl.getGalleryDetailUrl(gid, token),
|
||||
pageCount = pages,
|
||||
languageISO = simpleLanguage?.lowercase(),
|
||||
characters = characters.takeUnless { it.isEmpty() }?.joinToString(),
|
||||
teams = parodies.takeUnless { it.isEmpty() }?.joinToString(),
|
||||
communityRating = "%.1f".format(rating),
|
||||
)
|
||||
}
|
||||
|
||||
fun ComicInfo.write(file: UniFile) {
|
||||
file.openOutputStream().use {
|
||||
it.channel.truncate(0)
|
||||
OutputStreamWriter(it, Charsets.UTF_8).use { writer ->
|
||||
xmlStreaming.newGenericWriter(writer).use { xmlWriter ->
|
||||
xml.encodeToWriter(xmlWriter, ComicInfo.serializer(), this)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class ComicInfo(
|
||||
@XmlElement
|
||||
@SerialName("Series")
|
||||
val series: String?,
|
||||
|
||||
@XmlElement
|
||||
@SerialName("AlternateSeries")
|
||||
val alternateSeries: String?,
|
||||
|
||||
@XmlElement
|
||||
@SerialName("Writer")
|
||||
val writer: String?,
|
||||
|
||||
@XmlElement
|
||||
@SerialName("Penciller")
|
||||
val penciller: String?,
|
||||
|
||||
@XmlElement
|
||||
@SerialName("Genre")
|
||||
val genre: String?,
|
||||
|
||||
@XmlElement
|
||||
@SerialName("Web")
|
||||
val web: String?,
|
||||
|
||||
@XmlElement
|
||||
@SerialName("PageCount")
|
||||
val pageCount: Int,
|
||||
|
||||
@XmlElement
|
||||
@SerialName("LanguageISO")
|
||||
val languageISO: String?,
|
||||
|
||||
@XmlElement
|
||||
@SerialName("Characters")
|
||||
val characters: String?,
|
||||
|
||||
@XmlElement
|
||||
@SerialName("Teams")
|
||||
val teams: String?,
|
||||
|
||||
@XmlElement
|
||||
@SerialName("CommunityRating")
|
||||
val communityRating: String?,
|
||||
) {
|
||||
@SerialName("xmlns:xsi")
|
||||
val xmlSchemaInstance: String = "http://www.w3.org/2001/XMLSchema-instance"
|
||||
|
||||
@SerialName("xsi:noNamespaceSchemaLocation")
|
||||
val xmlSchemaLocation: String = "https://raw.githubusercontent.com/anansi-project/comicinfo/main/schema/v2.0/ComicInfo.xsd"
|
||||
}
|
||||
@@ -41,6 +41,7 @@ import com.hippo.ehviewer.image.Image
|
||||
import com.hippo.ehviewer.util.ExceptionUtils
|
||||
import com.hippo.unifile.UniFile
|
||||
import eu.kanade.tachiyomi.util.lang.launchIO
|
||||
import eu.kanade.tachiyomi.util.lang.withNonCancellableContext
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
import kotlin.time.Duration.Companion.milliseconds
|
||||
import kotlin.time.Duration.Companion.seconds
|
||||
@@ -431,6 +432,21 @@ class SpiderQueen private constructor(val galleryInfo: GalleryInfo) : CoroutineS
|
||||
mSpiderInfo.saveToCache()
|
||||
}
|
||||
|
||||
private suspend fun writeComicInfo() {
|
||||
mSpiderDen.downloadDir?.run {
|
||||
createFile(COMIC_INFO_FILE)?.also {
|
||||
runCatching {
|
||||
withNonCancellableContext {
|
||||
EhEngine.fillGalleryListByApi(listOf(galleryInfo))
|
||||
}
|
||||
galleryInfo.getComicInfo().write(it)
|
||||
}.onFailure {
|
||||
it.printStackTrace()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun isStateDone(state: Int): Boolean {
|
||||
return state == STATE_FINISHED || state == STATE_FAILED
|
||||
}
|
||||
@@ -493,7 +509,13 @@ class SpiderQueen private constructor(val galleryInfo: GalleryInfo) : CoroutineS
|
||||
val gid = galleryInfo.gid
|
||||
return (sQueenMap[gid] ?: SpiderQueen(galleryInfo).also { sQueenMap[gid] = it }).apply {
|
||||
setMode(mode)
|
||||
launchIO { updateMode() }
|
||||
launchIO {
|
||||
// Will create download dir if not exists
|
||||
updateMode()
|
||||
if (mode == MODE_DOWNLOAD) {
|
||||
writeComicInfo()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ ktor = "3.0.0-beta-1"
|
||||
okhttp3 = "5.0.0-alpha.12"
|
||||
okio = "3.7.0"
|
||||
splitties = "3.0.0"
|
||||
xmlutil = "0.86.3"
|
||||
|
||||
[libraries]
|
||||
aboutlibraries-core = { module = "com.mikepenz:aboutlibraries-core", version.ref = "aboutlibraries" }
|
||||
@@ -92,9 +93,6 @@ jsoup = "org.jsoup:jsoup:1.17.2"
|
||||
|
||||
kotlinx-coroutines-android = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-android", version.ref = "kotlinx-coroutines" }
|
||||
kotlinx-datetime = { module = "org.jetbrains.kotlinx:kotlinx-datetime", version.ref = "kotlinx-datetime" }
|
||||
kotlinx-serialization-cbor = { module = "org.jetbrains.kotlinx:kotlinx-serialization-cbor", version.ref = "kotlinx-serialization" }
|
||||
kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinx-serialization" }
|
||||
kotlinx-serialization-json-okio = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json-okio", version.ref = "kotlinx-serialization" }
|
||||
|
||||
ktor-client-okhttp = { module = "io.ktor:ktor-client-okhttp", version.ref = "ktor" }
|
||||
|
||||
@@ -110,6 +108,13 @@ r8 = { module = "com.android.tools:r8", version.ref = "android-tools-r8" }
|
||||
|
||||
reorderable = "sh.calvin.reorderable:reorderable:1.2.0"
|
||||
|
||||
serialization-cbor = { module = "org.jetbrains.kotlinx:kotlinx-serialization-cbor", version.ref = "kotlinx-serialization" }
|
||||
serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinx-serialization" }
|
||||
serialization-json-okio = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json-okio", version.ref = "kotlinx-serialization" }
|
||||
|
||||
serialization-xml-core = { module = "io.github.pdvrieze.xmlutil:core-android", version.ref = "xmlutil" }
|
||||
serialization-xml = { module = "io.github.pdvrieze.xmlutil:serialization-android", version.ref = "xmlutil" }
|
||||
|
||||
splitties-appctx = { module = "com.louiscad.splitties:splitties-appctx", version.ref = "splitties" }
|
||||
splitties-arch-room = { module = "com.louiscad.splitties:splitties-arch-room", version.ref = "splitties" }
|
||||
splitties-preferences = { module = "com.louiscad.splitties:splitties-preferences", version.ref = "splitties" }
|
||||
@@ -120,7 +125,7 @@ androidx-navigation = ["androidx-navigation-compose", "androidx-navigation-ui"]
|
||||
coil = ["coil-compose", "coil-gif", "coil-network"]
|
||||
compose = ["compose-foundation", "compose-material-icons-extended", "compose-material3", "compose-material3-windowsizeclass", "compose-ui-util"]
|
||||
cronet = ["cronet-api", "cronet-gms"]
|
||||
kotlinx-serialization = ["kotlinx-serialization-cbor", "kotlinx-serialization-json", "kotlinx-serialization-json-okio"]
|
||||
kotlinx-serialization = ["serialization-cbor", "serialization-json", "serialization-json-okio", "serialization-xml-core", "serialization-xml"]
|
||||
ktor = ["ktor-client-okhttp"]
|
||||
okhttp = ["okhttp-android"]
|
||||
splitties = ["splitties-appctx", "splitties-arch-room", "splitties-preferences", "splitties-systemservices"]
|
||||
|
||||
Reference in new issue
Block a user