Delegate Pururin.io

This commit is contained in:
NerdNumber9 2019-08-08 13:31:47 -04:00
parent 68de7b516e
commit 5195cb8eda
7 changed files with 113 additions and 34 deletions

View File

@ -154,6 +154,7 @@
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<!-- EH -->
<data
android:host="g.e-hentai.org"
android:pathPrefix="/g/"
@ -170,6 +171,8 @@
android:host="e-hentai.org"
android:pathPrefix="/g/"
android:scheme="https" />
<!-- EXH -->
<data
android:host="exhentai.org"
android:pathPrefix="/g/"
@ -178,6 +181,8 @@
android:host="exhentai.org"
android:pathPrefix="/g/"
android:scheme="https" />
<!-- nhentai -->
<data
android:host="nhentai.net"
android:pathPrefix="/g/"
@ -186,6 +191,8 @@
android:host="nhentai.net"
android:pathPrefix="/g/"
android:scheme="https" />
<!-- Perv Eden -->
<data
android:host="www.perveden.com"
android:pathPattern="/.*/.*-manga/.*"
@ -194,6 +201,8 @@
android:host="www.perveden.com"
android:pathPattern="/.*/.*-manga/.*"
android:scheme="https" />
<!-- Hentai Cafe -->
<data
android:host="hentai.cafe"
android:pathPattern="/.*/.*"
@ -202,6 +211,8 @@
android:host="hentai.cafe"
android:pathPattern="/.*/.*"
android:scheme="https" />
<!-- Tsumino -->
<data
android:host="www.tsumino.com"
android:pathPrefix="/Book/Info/"
@ -218,6 +229,8 @@
android:host="www.tsumino.com"
android:pathPrefix="/Read/View/"
android:scheme="https" />
<!-- Hitomi.la -->
<data
android:host="hitomi.la"
android:pathPrefix="/galleries/"
@ -234,6 +247,16 @@
android:host="hitomi.la"
android:pathPrefix="/reader/"
android:scheme="https" />
<!-- Pururin.io -->
<data
android:host="pururin.io"
android:pathPrefix="/gallery/"
android:scheme="http" />
<data
android:host="pururin.io"
android:pathPrefix="/gallery/"
android:scheme="https" />
</intent-filter>
</activity>
<activity

View File

@ -11,6 +11,7 @@ import eu.kanade.tachiyomi.data.preference.getOrDefault
import eu.kanade.tachiyomi.source.online.HttpSource
import eu.kanade.tachiyomi.source.online.all.*
import eu.kanade.tachiyomi.source.online.english.HentaiCafe
import eu.kanade.tachiyomi.source.online.english.Pururin
import eu.kanade.tachiyomi.source.online.english.Tsumino
import rx.Observable
import exh.EH_SOURCE_ID
@ -149,12 +150,18 @@ open class SourceManager(private val context: Context) {
260868874183818481,
"eu.kanade.tachiyomi.extension.all.foolslide.HentaiCafe",
HentaiCafe::class
),
DelegatedSource(
"Pururin",
2221515250486218861,
"eu.kanade.tachiyomi.extension.en.pururin.Pururin",
Pururin::class
)
).associateBy { it.originalSourcePackageName }
).associateBy { it.originalSourceQualifiedClassName }
data class DelegatedSource(val sourceName: String,
val sourceId: Long,
val originalSourcePackageName: String,
val originalSourceQualifiedClassName: String,
val newSourceClass: KClass<out DelegatedHttpSource>)
}
}

View File

@ -1,13 +1,19 @@
package eu.kanade.tachiyomi.source.online.english
import android.net.Uri
import eu.kanade.tachiyomi.network.asObservableSuccess
import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.MangasPage
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.HttpSource
import eu.kanade.tachiyomi.source.online.LewdSource
import eu.kanade.tachiyomi.source.online.UrlImportableSource
import eu.kanade.tachiyomi.util.asJsoup
import exh.metadata.metadata.PururinSearchMetadata
import exh.metadata.metadata.base.RaisedTag
import exh.source.DelegatedHttpSource
import exh.util.dropBlank
import exh.util.trimAll
import exh.util.urlImportFetchSearchManga
import org.jsoup.nodes.Document
import rx.Observable
@ -26,7 +32,6 @@ class Pururin(delegate: HttpSource) : DelegatedHttpSource(delegate),
//Support direct URL importing
override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable<MangasPage> {
val trimmedIdQuery = query.trim().removePrefix("id:")
// TODO Fetch gallery shortlink
val newQuery = if(trimmedIdQuery.toIntOrNull() ?: -1 >= 0) {
"$baseUrl/gallery/$trimmedIdQuery/-"
} else query
@ -36,6 +41,15 @@ class Pururin(delegate: HttpSource) : DelegatedHttpSource(delegate),
}
}
override fun fetchMangaDetails(manga: SManga): Observable<SManga> {
return client.newCall(mangaDetailsRequest(manga))
.asObservableSuccess()
.flatMap {
parseToManga(manga, it.asJsoup())
.andThen(Observable.just(manga))
}
}
override fun parseIntoMetadata(metadata: PururinSearchMetadata, input: Document) {
val selfLink = input.select("[itemprop=name]").last().parent()
val parsedSelfLink = Uri.parse(selfLink.attr("href")).pathSegments
@ -44,7 +58,52 @@ class Pururin(delegate: HttpSource) : DelegatedHttpSource(delegate),
prId = parsedSelfLink[parsedSelfLink.lastIndex - 1].toIntOrNull()
prShortLink = parsedSelfLink.last()
title =
val contentWrapper = input.selectFirst(".content-wrapper")
title = contentWrapper.selectFirst(".title h1").text()
altTitle = contentWrapper.selectFirst(".alt-title").text()
thumbnailUrl = "https:" + input.selectFirst(".cover-wrapper v-lazy-image").attr("src")
tags.clear()
contentWrapper.select(".table-gallery-info > tbody > tr").forEach { ele ->
val key = ele.child(0).text().toLowerCase()
val value = ele.child(1)
when(key) {
"pages" -> {
val split = value.text().split("(").trimAll().dropBlank()
pages = split.first().toIntOrNull()
fileSize = split.last().removeSuffix(")").trim()
}
"ratings" -> {
ratingCount = value.selectFirst("[itemprop=ratingCount]").attr("content").toIntOrNull()
averageRating = value.selectFirst("[itemprop=ratingValue]").attr("content").toDoubleOrNull()
}
"uploader" -> {
uploaderDisp = value.text()
uploader = Uri.parse(value.child(0).attr("href")).lastPathSegment
}
else -> {
value.select("a").forEach { link ->
val searchUrl = Uri.parse(link.attr("href"))
tags += RaisedTag(
searchUrl.pathSegments[searchUrl.pathSegments.lastIndex - 2],
searchUrl.lastPathSegment!!.substringBefore("."),
PururinSearchMetadata.TAG_TYPE_DEFAULT
)
}
}
}
}
}
}
override val matchingHosts = listOf(
"pururin.io",
"www.pururin.io"
)
override fun mapUrlToMangaUrl(uri: Uri): String? {
return "${PururinSearchMetadata.BASE_URL}/gallery/${uri.pathSegments[1]}/${uri.lastPathSegment}"
}
}

View File

@ -3,6 +3,7 @@ package exh
import eu.kanade.tachiyomi.source.Source
import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.source.online.english.HentaiCafe
import eu.kanade.tachiyomi.source.online.english.Pururin
/**
* Source helpers
@ -21,7 +22,8 @@ const val HITOMI_SOURCE_ID = LEWD_SOURCE_SERIES + 10
const val MERGED_SOURCE_ID = LEWD_SOURCE_SERIES + 69
private val DELEGATED_LEWD_SOURCES = listOf(
HentaiCafe::class
HentaiCafe::class,
Pururin::class
)
private inline fun <reified T> delegatedSourceId(): Long {

View File

@ -14,27 +14,6 @@ class PururinSearchMetadata : RaisedSearchMetadata() {
var thumbnailUrl: String? = null
var artist: String? = null
var artistDisp: String? = null
var circle: String? = null
var circleDisp: String? = null
var parody: String? = null // TODO Mult
var parodyDisp: String? = null
var character: String? = null // TODO Mult
var characterDisp: String? = null
var category: String? = null
var categoryDisp: String? = null
var collection: String? = null
var collectionDisp: String? = null
var language: String? = null
var languageDisp: String? = null
var uploaderDisp: String? = null
var pages: Int? = null
@ -59,9 +38,7 @@ class PururinSearchMetadata : RaisedSearchMetadata() {
manga.thumbnail_url = it
}
(artistDisp ?: artist)?.let {
manga.artist = it
}
manga.artist = tags.ofNamespace(TAG_NAMESPACE_ARTIST).joinToString { it.name }
manga.genre = tagsToGenreString()
@ -70,10 +47,10 @@ class PururinSearchMetadata : RaisedSearchMetadata() {
altTitle?.let { titleDesc += "Japanese Title: $it\n" }
val detailsDesc = StringBuilder()
(uploaderDisp ?: uploader)?.let { detailsDesc += "Uploader: $it"}
pages?.let { detailsDesc += "Length: $it pages" }
fileSize?.let { detailsDesc += "Size: $it" }
ratingCount?.let { detailsDesc += "Rating: $averageRating ($ratingCount)" }
(uploaderDisp ?: uploader)?.let { detailsDesc += "Uploader: $it\n"}
pages?.let { detailsDesc += "Length: $it pages\n" }
fileSize?.let { detailsDesc += "Size: $it\n" }
ratingCount?.let { detailsDesc += "Rating: $averageRating ($ratingCount)\n" }
val tagsDesc = tagsToDescription()
@ -86,7 +63,9 @@ class PururinSearchMetadata : RaisedSearchMetadata() {
private const val TITLE_TYPE_TITLE = 0
private const val TITLE_TYPE_ALT_TITLE = 1
const val TAG_TYPE_CONTENTS = 0
const val TAG_TYPE_DEFAULT = 0
private const val TAG_NAMESPACE_ARTIST = "artist"
val BASE_URL = "https://pururin.io"
}

View File

@ -60,6 +60,10 @@ abstract class RaisedSearchMetadata {
}
}
fun List<RaisedTag>.ofNamespace(ns: String): List<RaisedTag> {
return filter { it.namespace == ns }
}
fun flatten(): FlatMetadata {
require(mangaId != -1L)

View File

@ -0,0 +1,5 @@
package exh.util
fun List<String>.trimAll() = map { it.trim() }
fun List<String>.dropBlank() = filter { it.isNotBlank() }
fun List<String>.dropEmpty() = filter { it.isNotEmpty() }