Delegate Pururin.io
This commit is contained in:
parent
68de7b516e
commit
5195cb8eda
@ -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
|
||||
|
@ -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>)
|
||||
}
|
||||
}
|
||||
|
@ -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}"
|
||||
}
|
||||
}
|
@ -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 {
|
||||
|
@ -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"
|
||||
}
|
||||
|
@ -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)
|
||||
|
||||
|
5
app/src/main/java/exh/util/StringUtil.kt
Normal file
5
app/src/main/java/exh/util/StringUtil.kt
Normal 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() }
|
Loading…
x
Reference in New Issue
Block a user