NerdNumber9 603fd84753 Rewrite tag searching to use SQL
Fix EHentai/ExHentai
Fix hitomi.la
Fix hitomi.la crashing application
Rewrite hitomi.la search engine to be faster, use less CPU and require no preloading
Fix nhentai
Add additional filters to nhentai
Fix PervEden
Introduce delegated sources
Rewrite HentaiCafe to be a delegated source
Introduce ability to save/load search presets
Temporarily disable misbehaving native Tachiyomi migrations
Fix tap-to-search-tag breaking on aliased tags
Add debug menu
Add experimental automatic captcha solver
Add app name to wakelock names
Add ability to interrupt metadata migrator
Fix incognito open-in-browser being zoomed in immediately when it's opened
2019-04-06 07:35:36 -04:00

186 lines
5.5 KiB
Kotlin
Executable File

package exh.metadata.models
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.data.preference.getOrDefault
import eu.kanade.tachiyomi.source.model.SManga
import exh.metadata.*
import exh.plusAssign
import io.realm.RealmList
import io.realm.RealmObject
import io.realm.annotations.Ignore
import io.realm.annotations.Index
import io.realm.annotations.PrimaryKey
import io.realm.annotations.RealmClass
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import java.util.*
/**
* NHentai metadata
*/
@RealmClass
open class NHentaiMetadata : RealmObject(), SearchableGalleryMetadata {
@PrimaryKey
override var uuid: String = UUID.randomUUID().toString()
var nhId: Long? = null
var url get() = nhId?.let { "$BASE_URL/g/$it" }
set(a) {
a?.let {
nhId = nhUrlToId(a)
}
}
@Index
override var uploader: String? = null
var uploadDate: Long? = null
var favoritesCount: Long? = null
var mediaId: String? = null
@Index
var japaneseTitle: String? = null
@Index
var englishTitle: String? = null
@Index
var shortTitle: String? = null
var coverImageType: String? = null
var pageImageTypes: RealmList<PageImageType> = RealmList()
var thumbnailImageType: String? = null
var scanlator: String? = null
override var tags: RealmList<Tag> = RealmList()
override fun getTitles() = listOf(japaneseTitle, englishTitle, shortTitle).filterNotNull()
@Ignore
override val titleFields = TITLE_FIELDS
@Index
override var mangaId: Long? = null
class EmptyQuery : GalleryQuery<NHentaiMetadata>(NHentaiMetadata::class)
class UrlQuery(
val url: String
) : GalleryQuery<NHentaiMetadata>(NHentaiMetadata::class) {
override fun transform() = Query(
nhUrlToId(url)
)
}
class Query(
val nhId: Long
) : GalleryQuery<NHentaiMetadata>(NHentaiMetadata::class) {
override fun map() = mapOf(
::nhId to Query::nhId
)
}
override fun copyTo(manga: SManga) {
url?.let { manga.url = it }
if(mediaId != null)
NHentaiMetadata.typeToExtension(thumbnailImageType)?.let {
manga.thumbnail_url = "https://t.nhentai.net/galleries/$mediaId/${
if(Injekt.get<PreferencesHelper>().eh_nh_useHighQualityThumbs().getOrDefault())
"cover"
else
"thumb"
}.$it"
}
manga.title = englishTitle ?: japaneseTitle ?: shortTitle!!
//Set artist (if we can find one)
tags.filter { it.namespace == NHENTAI_ARTIST_NAMESPACE }.let {
if(it.isNotEmpty()) manga.artist = it.joinToString(transform = { it.name!! })
}
var category: String? = null
tags.filter { it.namespace == NHENTAI_CATEGORIES_NAMESPACE }.let {
if(it.isNotEmpty()) category = it.joinToString(transform = { it.name!! })
}
//Copy tags -> genres
manga.genre = joinEmulatedTagsToGenreString(this)
//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 = SManga.COMPLETED
englishTitle?.let { t ->
ONGOING_SUFFIX.find {
t.endsWith(it, ignoreCase = true)
}?.let {
manga.status = SManga.ONGOING
}
}
val titleDesc = StringBuilder()
englishTitle?.let { titleDesc += "English Title: $it\n" }
japaneseTitle?.let { titleDesc += "Japanese Title: $it\n" }
shortTitle?.let { titleDesc += "Short Title: $it\n" }
val detailsDesc = StringBuilder()
category?.let { detailsDesc += "Category: $it\n" }
uploadDate?.let { detailsDesc += "Upload Date: ${EX_DATE_FORMAT.format(Date(it * 1000))}\n" }
pageImageTypes.size.let { detailsDesc += "Length: $it pages\n" }
favoritesCount?.let { detailsDesc += "Favorited: $it times\n" }
scanlator?.nullIfBlank()?.let { detailsDesc += "Scanlator: $it\n" }
val tagsDesc = buildTagsDescription(this)
manga.description = listOf(titleDesc.toString(), detailsDesc.toString(), tagsDesc.toString())
.filter(String::isNotBlank)
.joinToString(separator = "\n")
}
companion object {
val BASE_URL = "https://nhentai.net"
private const val NHENTAI_ARTIST_NAMESPACE = "artist"
private const val NHENTAI_CATEGORIES_NAMESPACE = "category"
fun typeToExtension(t: String?) =
when(t) {
"p" -> "png"
"j" -> "jpg"
else -> null
}
fun nhUrlToId(url: String)
= url.split("/").last { it.isNotBlank() }.toLong()
val TITLE_FIELDS = listOf(
NHentaiMetadata::japaneseTitle.name,
NHentaiMetadata::englishTitle.name,
NHentaiMetadata::shortTitle.name
)
}
}
@RealmClass
open class PageImageType(var type: String? = null): RealmObject() {
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
other as PageImageType
if (type != other.type) return false
return true
}
override fun hashCode() = type?.hashCode() ?: 0
override fun toString() = "PageImageType(type=$type)"
}