Add EH code.

This commit is contained in:
NerdNumber9
2017-01-02 18:02:10 -05:00
parent a7192e866f
commit caa1e1ef09
32 changed files with 1363 additions and 29 deletions
@@ -0,0 +1,22 @@
package exh.metadata
import exh.metadata.models.ExGalleryMetadata
import io.paperdb.Paper
class MetadataHelper {
fun writeGallery(galleryMetadata: ExGalleryMetadata)
= exGalleryBook().write(galleryMetadata.galleryUniqueIdentifier(), galleryMetadata)
fun fetchMetadata(url: String, exh: Boolean) = ExGalleryMetadata().apply {
this.url = url
this.exh = exh
return exGalleryBook().read<ExGalleryMetadata>(galleryUniqueIdentifier())
}
fun getAllGalleries() = exGalleryBook().allKeys.map {
exGalleryBook().read<ExGalleryMetadata>(it)
}
fun exGalleryBook() = Paper.book("gallery-ex")!!
}
@@ -0,0 +1,47 @@
package exh.metadata
/**
* Metadata utils
*/
fun humanReadableByteCount(bytes: Long, si: Boolean): String {
val unit = if (si) 1000 else 1024
if (bytes < unit) return bytes.toString() + " B"
val exp = (Math.log(bytes.toDouble()) / Math.log(unit.toDouble())).toInt()
val pre = (if (si) "kMGTPE" else "KMGTPE")[exp - 1] + if (si) "" else "i"
return String.format("%.1f %sB", bytes / Math.pow(unit.toDouble(), exp.toDouble()), pre)
}
private val KB_FACTOR: Long = 1000
private val KIB_FACTOR: Long = 1024
private val MB_FACTOR = 1000 * KB_FACTOR
private val MIB_FACTOR = 1024 * KIB_FACTOR
private val GB_FACTOR = 1000 * MB_FACTOR
private val GIB_FACTOR = 1024 * MIB_FACTOR
fun parseHumanReadableByteCount(arg0: String): Double? {
val spaceNdx = arg0.indexOf(" ")
val ret = java.lang.Double.parseDouble(arg0.substring(0, spaceNdx))
when (arg0.substring(spaceNdx + 1)) {
"GB" -> return ret * GB_FACTOR
"GiB" -> return ret * GIB_FACTOR
"MB" -> return ret * MB_FACTOR
"MiB" -> return ret * MIB_FACTOR
"KB" -> return ret * KB_FACTOR
"KiB" -> return ret * KIB_FACTOR
}
return null
}
fun String?.nullIfBlank(): String? = if(isNullOrBlank())
null
else
this
fun <T> ignore(expr: () -> T): T? {
return try { expr() } catch (t: Throwable) { null }
}
fun <K,V> Set<Map.Entry<K,V>>.forEach(action: (K, V) -> Unit) {
forEach { action(it.key, it.value) }
}
@@ -0,0 +1,94 @@
package exh.metadata
import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.util.UrlUtil
import exh.metadata.models.ExGalleryMetadata
import exh.metadata.models.Tag
import exh.plusAssign
import java.text.SimpleDateFormat
import java.util.*
/**
* Copies gallery metadata to a manga object
*/
private const val ARTIST_NAMESPACE = "artist"
private const val AUTHOR_NAMESPACE = "author"
private val ONGOING_SUFFIX = arrayOf(
"[ongoing]",
"(ongoing)",
"{ongoing}"
)
val EX_DATE_FORMAT = SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.US)
fun ExGalleryMetadata.copyTo(manga: Manga) {
exh?.let {
manga.source = if(it)
2
else
1
}
url?.let { manga.url = it }
thumbnailUrl?.let { manga.thumbnail_url = it }
title?.let { manga.title = it }
//Set artist (if we can find one)
tags[ARTIST_NAMESPACE]?.let {
if(it.isNotEmpty()) manga.artist = it.joinToString(transform = Tag::name)
}
//Set author (if we can find one)
tags[AUTHOR_NAMESPACE]?.let {
if(it.isNotEmpty()) manga.author = it.joinToString(transform = Tag::name)
}
//Set genre
genre?.let { manga.genre = it }
//Try to automatically identify if it is ongoing, we try not to be too lenient here to avoid making mistakes
//We default to completed
manga.status = Manga.COMPLETED
title?.let { t ->
ONGOING_SUFFIX.find {
t.endsWith(it, ignoreCase = true)
}?.let {
manga.status = Manga.ONGOING
}
}
//Build a nice looking description out of what we know
val titleDesc = StringBuilder()
title?.let { titleDesc += "Title: $it\n" }
altTitle?.let { titleDesc += "Japanese Title: $it\n" }
val detailsDesc = StringBuilder()
uploader?.let { detailsDesc += "Uploader: $it\n" }
datePosted?.let { detailsDesc += "Posted: ${EX_DATE_FORMAT.format(Date(it))}\n" }
visible?.let { detailsDesc += "Visible: $it\n" }
language?.let {
detailsDesc += "Language: $it"
if(translated == true) detailsDesc += " TR"
detailsDesc += "\n"
}
size?.let { detailsDesc += "File Size: ${humanReadableByteCount(it, true)}\n" }
length?.let { detailsDesc += "Length: $it pages\n" }
favorites?.let { detailsDesc += "Favorited: $it times\n" }
averageRating?.let {
detailsDesc += "Rating: $it"
ratingCount?.let { detailsDesc += " ($it)" }
detailsDesc += "\n"
}
val tagsDesc = StringBuilder("Tags:\n")
//BiConsumer only available in Java 8, don't bother calling forEach directly on 'tags'
tags.entries.forEach { namespace, tags ->
if(tags.isNotEmpty()) {
val joinedTags = tags.joinToString(separator = " ", transform = { "<${it.name}>" })
tagsDesc += "$namespace: $joinedTags\n"
}
}
manga.description = listOf(titleDesc, detailsDesc, tagsDesc)
.filter { it.isNotBlank() }
.joinToString(separator = "\n")
}
@@ -0,0 +1,52 @@
package exh.metadata.models
import android.net.Uri
import java.util.*
/**
* Gallery metadata storage model
*/
class ExGalleryMetadata {
var url: String? = null
var exh: Boolean? = null
var title: String? = null
var altTitle: String? = null
var thumbnailUrl: String? = null
var genre: String? = null
var uploader: String? = null
var datePosted: Long? = null
var parent: String? = null
var visible: String? = null
var language: String? = null
var translated: Boolean? = null
var size: Long? = null
var length: Int? = null
var favorites: Int? = null
var ratingCount: Int? = null
var averageRating: Double? = null
//Being specific about which classes are used in generics to make deserialization easier
var tags: HashMap<String, ArrayList<Tag>> = HashMap()
private fun splitGalleryUrl()
= url?.let {
Uri.parse(it).pathSegments.filterNot(String::isNullOrBlank)
}
fun galleryId() = splitGalleryUrl()?.let { it[it.size - 2] }
fun galleryToken() =
splitGalleryUrl()?.last()
fun galleryUniqueIdentifier() = exh?.let { exh ->
url?.let {
"${if(exh) "EXH" else "EX"}-${galleryId()}-${galleryToken()}"
}
}
}
@@ -0,0 +1,7 @@
package exh.metadata.models
/**
* Simple tag model
*/
data class Tag(var name: String, var light: Boolean)