remove dead delegatedsources (#701)
This commit is contained in:
parent
555697b30b
commit
7fd4f5ee97
@ -58,11 +58,8 @@ Custom sources:
|
||||
Additional features for some extensions, features include custom description, opening in app, batch add to library, and a bunch of other things based on the source:
|
||||
* 8Muses (EroMuse)
|
||||
* HBrowse
|
||||
* HentaiCafe (inside Foolside)
|
||||
* Hitomi.la
|
||||
* Mangadex
|
||||
* NHentai
|
||||
* PervEden (EN and IT)
|
||||
* Puruin
|
||||
* Tsumino
|
||||
|
||||
|
@ -299,21 +299,6 @@
|
||||
|
||||
<data android:pathPattern="/g/..*" />
|
||||
</intent-filter>
|
||||
<!-- Perv Eden -->
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
|
||||
<data android:scheme="https" />
|
||||
<data android:scheme="http" />
|
||||
|
||||
<data android:host="perveden.com" />
|
||||
<data android:host="www.perveden.com" />
|
||||
|
||||
<data android:pathPattern="/.*/.*-manga/.*" />
|
||||
</intent-filter>
|
||||
<!-- Tsumino -->
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
@ -330,22 +315,6 @@
|
||||
<data android:pathPattern="/Read/View/..*" />
|
||||
<data android:pathPattern="/Book/Info/..*" />
|
||||
</intent-filter>
|
||||
<!-- Hitomi.la -->
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
|
||||
<data android:scheme="https" />
|
||||
<data android:scheme="http" />
|
||||
|
||||
<data android:host="hitomi.la" />
|
||||
<data android:host="www.hitomi.la" />
|
||||
|
||||
<data android:pathPattern="/reader/..*" />
|
||||
<data android:pathPattern="/galleries/..*" />
|
||||
</intent-filter>
|
||||
<!-- Pururin -->
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
|
@ -9,8 +9,6 @@ import eu.kanade.domain.category.model.Category
|
||||
import eu.kanade.domain.library.model.LibraryGroup
|
||||
import eu.kanade.domain.library.model.LibraryManga
|
||||
import eu.kanade.tachiyomi.ui.library.LibraryPresenter
|
||||
import exh.source.PERV_EDEN_EN_SOURCE_ID
|
||||
import exh.source.PERV_EDEN_IT_SOURCE_ID
|
||||
import exh.source.isEhBasedManga
|
||||
import exh.source.mangaDexSourceIds
|
||||
import exh.source.nHentaiSourceIds
|
||||
@ -56,9 +54,7 @@ class LibraryStateImpl : LibraryState {
|
||||
override val showCleanTitles: Boolean by derivedStateOf {
|
||||
selection.any {
|
||||
it.manga.isEhBasedManga() ||
|
||||
it.manga.source in nHentaiSourceIds ||
|
||||
it.manga.source == PERV_EDEN_EN_SOURCE_ID ||
|
||||
it.manga.source == PERV_EDEN_IT_SOURCE_ID
|
||||
it.manga.source in nHentaiSourceIds
|
||||
}
|
||||
}
|
||||
override val showAddToMangadex: Boolean by derivedStateOf {
|
||||
|
@ -76,10 +76,8 @@ import eu.kanade.tachiyomi.source.SourceManager
|
||||
import eu.kanade.tachiyomi.source.getNameForMangaInfo
|
||||
import eu.kanade.tachiyomi.source.online.MetadataSource
|
||||
import eu.kanade.tachiyomi.source.online.all.EHentai
|
||||
import eu.kanade.tachiyomi.source.online.all.Hitomi
|
||||
import eu.kanade.tachiyomi.source.online.all.MangaDex
|
||||
import eu.kanade.tachiyomi.source.online.all.NHentai
|
||||
import eu.kanade.tachiyomi.source.online.all.PervEden
|
||||
import eu.kanade.tachiyomi.source.online.english.EightMuses
|
||||
import eu.kanade.tachiyomi.source.online.english.HBrowse
|
||||
import eu.kanade.tachiyomi.source.online.english.Pururin
|
||||
@ -92,10 +90,8 @@ import exh.source.getMainSource
|
||||
import exh.ui.metadata.adapters.EHentaiDescription
|
||||
import exh.ui.metadata.adapters.EightMusesDescription
|
||||
import exh.ui.metadata.adapters.HBrowseDescription
|
||||
import exh.ui.metadata.adapters.HitomiDescription
|
||||
import exh.ui.metadata.adapters.MangaDexDescription
|
||||
import exh.ui.metadata.adapters.NHentaiDescription
|
||||
import exh.ui.metadata.adapters.PervEdenDescription
|
||||
import exh.ui.metadata.adapters.PururinDescription
|
||||
import exh.ui.metadata.adapters.TsuminoDescription
|
||||
|
||||
@ -873,18 +869,12 @@ fun metadataDescription(source: Source): MetadataDescriptionComposable? {
|
||||
is EHentai -> { state, openMetadataViewer, search ->
|
||||
EHentaiDescription(state, openMetadataViewer, search)
|
||||
}
|
||||
is Hitomi -> { state, openMetadataViewer, _ ->
|
||||
HitomiDescription(state, openMetadataViewer)
|
||||
}
|
||||
is MangaDex -> { state, openMetadataViewer, _ ->
|
||||
MangaDexDescription(state, openMetadataViewer)
|
||||
}
|
||||
is NHentai -> { state, openMetadataViewer, _ ->
|
||||
NHentaiDescription(state, openMetadataViewer)
|
||||
}
|
||||
is PervEden -> { state, openMetadataViewer, _ ->
|
||||
PervEdenDescription(state, openMetadataViewer)
|
||||
}
|
||||
is EightMuses -> { state, openMetadataViewer, _ ->
|
||||
EightMusesDescription(state, openMetadataViewer)
|
||||
}
|
||||
|
@ -12,11 +12,9 @@ import eu.kanade.tachiyomi.source.model.SChapter
|
||||
import eu.kanade.tachiyomi.source.model.SManga
|
||||
import eu.kanade.tachiyomi.source.online.HttpSource
|
||||
import eu.kanade.tachiyomi.source.online.all.EHentai
|
||||
import eu.kanade.tachiyomi.source.online.all.Hitomi
|
||||
import eu.kanade.tachiyomi.source.online.all.MangaDex
|
||||
import eu.kanade.tachiyomi.source.online.all.MergedSource
|
||||
import eu.kanade.tachiyomi.source.online.all.NHentai
|
||||
import eu.kanade.tachiyomi.source.online.all.PervEden
|
||||
import eu.kanade.tachiyomi.source.online.english.EightMuses
|
||||
import eu.kanade.tachiyomi.source.online.english.HBrowse
|
||||
import eu.kanade.tachiyomi.source.online.english.Pururin
|
||||
@ -30,8 +28,6 @@ import exh.source.EXH_SOURCE_ID
|
||||
import exh.source.EnhancedHttpSource
|
||||
import exh.source.HBROWSE_SOURCE_ID
|
||||
import exh.source.MERGED_SOURCE_ID
|
||||
import exh.source.PERV_EDEN_EN_SOURCE_ID
|
||||
import exh.source.PERV_EDEN_IT_SOURCE_ID
|
||||
import exh.source.PURURIN_SOURCE_ID
|
||||
import exh.source.TSUMINO_SOURCE_ID
|
||||
import exh.source.handleSourceLibrary
|
||||
@ -292,25 +288,6 @@ class SourceManager(
|
||||
"eu.kanade.tachiyomi.extension.en.eightmuses.EightMuses",
|
||||
EightMuses::class,
|
||||
),
|
||||
DelegatedSource(
|
||||
"Hitomi",
|
||||
fillInSourceId,
|
||||
"eu.kanade.tachiyomi.extension.all.hitomi.Hitomi",
|
||||
Hitomi::class,
|
||||
true,
|
||||
),
|
||||
DelegatedSource(
|
||||
"PervEden English",
|
||||
PERV_EDEN_EN_SOURCE_ID,
|
||||
"eu.kanade.tachiyomi.extension.en.perveden.Perveden",
|
||||
PervEden::class,
|
||||
),
|
||||
DelegatedSource(
|
||||
"PervEden Italian",
|
||||
PERV_EDEN_IT_SOURCE_ID,
|
||||
"eu.kanade.tachiyomi.extension.it.perveden.Perveden",
|
||||
PervEden::class,
|
||||
),
|
||||
DelegatedSource(
|
||||
"NHentai",
|
||||
fillInSourceId,
|
||||
|
@ -1,146 +0,0 @@
|
||||
package eu.kanade.tachiyomi.source.online.all
|
||||
|
||||
import android.content.Context
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import eu.kanade.tachiyomi.network.await
|
||||
import eu.kanade.tachiyomi.source.model.FilterList
|
||||
import eu.kanade.tachiyomi.source.model.SManga
|
||||
import eu.kanade.tachiyomi.source.online.HttpSource
|
||||
import eu.kanade.tachiyomi.source.online.MetadataSource
|
||||
import eu.kanade.tachiyomi.source.online.NamespaceSource
|
||||
import eu.kanade.tachiyomi.source.online.UrlImportableSource
|
||||
import eu.kanade.tachiyomi.util.asJsoup
|
||||
import exh.metadata.metadata.HitomiSearchMetadata
|
||||
import exh.metadata.metadata.base.RaisedSearchMetadata
|
||||
import exh.metadata.metadata.base.RaisedTag
|
||||
import exh.source.DelegatedHttpSource
|
||||
import exh.util.urlImportFetchSearchManga
|
||||
import org.jsoup.nodes.Document
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Locale
|
||||
|
||||
class Hitomi(delegate: HttpSource, val context: Context) :
|
||||
DelegatedHttpSource(delegate),
|
||||
MetadataSource<HitomiSearchMetadata, Document>,
|
||||
UrlImportableSource,
|
||||
NamespaceSource {
|
||||
override val metaClass = HitomiSearchMetadata::class
|
||||
override val lang = delegate.lang
|
||||
|
||||
// Support direct URL importing
|
||||
override fun fetchSearchManga(page: Int, query: String, filters: FilterList) =
|
||||
urlImportFetchSearchManga(context, query) {
|
||||
super.fetchSearchManga(page, query, filters)
|
||||
}
|
||||
|
||||
override suspend fun getMangaDetails(manga: SManga): SManga {
|
||||
val response = client.newCall(mangaDetailsRequest(manga)).await()
|
||||
return parseToManga(manga, response.asJsoup())
|
||||
}
|
||||
|
||||
override suspend fun parseIntoMetadata(metadata: HitomiSearchMetadata, input: Document) {
|
||||
with(metadata) {
|
||||
url = input.location()
|
||||
|
||||
tags.clear()
|
||||
|
||||
thumbnailUrl = "https:" + input.selectFirst(".cover img")!!.attr("src")
|
||||
|
||||
val galleryElement = input.selectFirst(".gallery")!!
|
||||
|
||||
title = galleryElement.selectFirst("h1")!!.text()
|
||||
artists = galleryElement.select("h2 a").map { it.text() }
|
||||
tags += artists.map { RaisedTag("artist", it, HitomiSearchMetadata.TAG_TYPE_DEFAULT) }
|
||||
|
||||
input.select(".gallery-info tr").forEach { galleryInfoElement ->
|
||||
val content = galleryInfoElement.child(1)
|
||||
when (galleryInfoElement.child(0).text().lowercase()) {
|
||||
"group" -> {
|
||||
val group = content.text()
|
||||
tags += RaisedTag(
|
||||
"group",
|
||||
group,
|
||||
if (group != "N/A") {
|
||||
HitomiSearchMetadata.TAG_TYPE_DEFAULT
|
||||
} else {
|
||||
RaisedSearchMetadata.TAG_TYPE_VIRTUAL
|
||||
},
|
||||
)
|
||||
}
|
||||
"type" -> {
|
||||
genre = content.text()
|
||||
tags += RaisedTag("genre", genre!!, RaisedSearchMetadata.TAG_TYPE_VIRTUAL)
|
||||
}
|
||||
"series" -> {
|
||||
val series = content.select("a").map { it.text() }
|
||||
tags += series.map {
|
||||
RaisedTag("series", it, HitomiSearchMetadata.TAG_TYPE_DEFAULT)
|
||||
}
|
||||
}
|
||||
"language" -> {
|
||||
language = content.selectFirst("a")?.attr("href")?.split('-')?.get(1)
|
||||
language?.let {
|
||||
tags += RaisedTag("language", it, RaisedSearchMetadata.TAG_TYPE_VIRTUAL)
|
||||
}
|
||||
}
|
||||
"characters" -> {
|
||||
val characters = content.select("a").map { it.text() }
|
||||
tags += characters.map {
|
||||
RaisedTag(
|
||||
"character",
|
||||
it,
|
||||
HitomiSearchMetadata.TAG_TYPE_DEFAULT,
|
||||
)
|
||||
}
|
||||
}
|
||||
"tags" -> {
|
||||
tags += content.select("a").map {
|
||||
val ns = when {
|
||||
it.attr("href").startsWith("/tag/male") -> "male"
|
||||
it.attr("href").startsWith("/tag/female") -> "female"
|
||||
else -> "misc"
|
||||
}
|
||||
RaisedTag(
|
||||
ns,
|
||||
it.text().dropLast(if (ns == "misc") 0 else 2),
|
||||
HitomiSearchMetadata.TAG_TYPE_DEFAULT,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uploadDate = try {
|
||||
DATE_FORMAT.parse(input.selectFirst(".gallery-info .date")!!.text())!!.time
|
||||
} catch (e: Exception) {
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override val matchingHosts = listOf(
|
||||
"hitomi.la",
|
||||
)
|
||||
|
||||
override suspend fun mapUrlToMangaUrl(uri: Uri): String? {
|
||||
val lcFirstPathSegment = uri.pathSegments.firstOrNull()?.lowercase() ?: return null
|
||||
|
||||
if (lcFirstPathSegment != "manga" && lcFirstPathSegment != "reader") {
|
||||
return null
|
||||
}
|
||||
|
||||
return "https://hitomi.la/manga/${uri.pathSegments[1].substringBefore('.')}.html"
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val otherId = 2703068117101782422L
|
||||
private val DATE_FORMAT by lazy {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
SimpleDateFormat("yyyy-MM-dd HH:mm:ssX", Locale.US)
|
||||
} else {
|
||||
SimpleDateFormat("yyyy-MM-dd HH:mm:ss'-05'", Locale.US)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,132 +0,0 @@
|
||||
package eu.kanade.tachiyomi.source.online.all
|
||||
|
||||
import android.content.Context
|
||||
import android.net.Uri
|
||||
import androidx.core.net.toUri
|
||||
import eu.kanade.tachiyomi.network.await
|
||||
import eu.kanade.tachiyomi.source.model.FilterList
|
||||
import eu.kanade.tachiyomi.source.model.SManga
|
||||
import eu.kanade.tachiyomi.source.online.HttpSource
|
||||
import eu.kanade.tachiyomi.source.online.MetadataSource
|
||||
import eu.kanade.tachiyomi.source.online.UrlImportableSource
|
||||
import eu.kanade.tachiyomi.util.asJsoup
|
||||
import exh.metadata.metadata.PervEdenSearchMetadata
|
||||
import exh.metadata.metadata.base.RaisedSearchMetadata
|
||||
import exh.metadata.metadata.base.RaisedTag
|
||||
import exh.source.DelegatedHttpSource
|
||||
import exh.util.urlImportFetchSearchManga
|
||||
import org.jsoup.nodes.Document
|
||||
import org.jsoup.nodes.Element
|
||||
import org.jsoup.nodes.TextNode
|
||||
|
||||
class PervEden(delegate: HttpSource, val context: Context) :
|
||||
DelegatedHttpSource(delegate),
|
||||
MetadataSource<PervEdenSearchMetadata, Document>,
|
||||
UrlImportableSource {
|
||||
override val metaClass = PervEdenSearchMetadata::class
|
||||
override val lang = delegate.lang
|
||||
|
||||
// Support direct URL importing
|
||||
override fun fetchSearchManga(page: Int, query: String, filters: FilterList) =
|
||||
urlImportFetchSearchManga(context, query) {
|
||||
super.fetchSearchManga(page, query, filters)
|
||||
}
|
||||
|
||||
override suspend fun getMangaDetails(manga: SManga): SManga {
|
||||
val response = client.newCall(mangaDetailsRequest(manga)).await()
|
||||
return parseToManga(manga, response.asJsoup())
|
||||
}
|
||||
|
||||
override suspend fun parseIntoMetadata(metadata: PervEdenSearchMetadata, input: Document) {
|
||||
with(metadata) {
|
||||
url = input.location().toUri().path
|
||||
|
||||
pvId = PervEdenSearchMetadata.pvIdFromUrl(url!!)
|
||||
|
||||
lang = this@PervEden.lang
|
||||
|
||||
title = input.getElementsByClass("manga-title").first()?.text()
|
||||
|
||||
thumbnailUrl = "http:" + input.getElementsByClass("mangaImage2").first()?.child(0)?.attr("src")
|
||||
|
||||
val rightBoxElement = input.select(".rightBox:not(.info)").first()
|
||||
|
||||
val newAltTitles = mutableListOf<String>()
|
||||
tags.clear()
|
||||
var inStatus: String? = null
|
||||
rightBoxElement!!.childNodes().forEach {
|
||||
if (it is Element && it.tagName().lowercase() == "h4") {
|
||||
inStatus = it.text().trim()
|
||||
} else {
|
||||
when (inStatus) {
|
||||
"Alternative name(s)" -> {
|
||||
if (it is TextNode) {
|
||||
val text = it.text().trim()
|
||||
if (text.isNotBlank()) {
|
||||
newAltTitles += text
|
||||
}
|
||||
}
|
||||
}
|
||||
"Artist" -> {
|
||||
if (it is Element && it.tagName() == "a") {
|
||||
artist = it.text()
|
||||
tags += RaisedTag(
|
||||
"artist",
|
||||
it.text().lowercase(),
|
||||
RaisedSearchMetadata.TAG_TYPE_VIRTUAL,
|
||||
)
|
||||
}
|
||||
}
|
||||
"Genres" -> {
|
||||
if (it is Element && it.tagName() == "a") {
|
||||
tags += RaisedTag(
|
||||
null,
|
||||
it.text().lowercase(),
|
||||
PervEdenSearchMetadata.TAG_TYPE_DEFAULT,
|
||||
)
|
||||
}
|
||||
}
|
||||
"Type" -> {
|
||||
if (it is TextNode) {
|
||||
val text = it.text().trim()
|
||||
if (text.isNotBlank()) {
|
||||
genre = text
|
||||
}
|
||||
}
|
||||
}
|
||||
"Status" -> {
|
||||
if (it is TextNode) {
|
||||
val text = it.text().trim()
|
||||
if (text.isNotBlank()) {
|
||||
status = text
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
altTitles = newAltTitles
|
||||
|
||||
rating = input.getElementById("rating-score")?.attr("value")?.toFloat()
|
||||
}
|
||||
}
|
||||
|
||||
override val matchingHosts = listOf("www.perveden.com")
|
||||
|
||||
override fun matchesUri(uri: Uri): Boolean {
|
||||
return super.matchesUri(uri) && uri.pathSegments.firstOrNull()?.lowercase() == when (lang) {
|
||||
"en" -> "en-manga"
|
||||
"it" -> "it-manga"
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun mapUrlToMangaUrl(uri: Uri): String {
|
||||
val newUri = "http://www.perveden.com/".toUri().buildUpon()
|
||||
uri.pathSegments.take(3).forEach {
|
||||
newUri.appendPath(it)
|
||||
}
|
||||
return newUri.toString()
|
||||
}
|
||||
}
|
@ -36,8 +36,6 @@ import eu.kanade.tachiyomi.util.system.toast
|
||||
import exh.favorites.FavoritesIntroDialog
|
||||
import exh.favorites.FavoritesSyncStatus
|
||||
import exh.source.MERGED_SOURCE_ID
|
||||
import exh.source.PERV_EDEN_EN_SOURCE_ID
|
||||
import exh.source.PERV_EDEN_IT_SOURCE_ID
|
||||
import exh.source.isEhBasedManga
|
||||
import exh.source.mangaDexSourceIds
|
||||
import exh.source.nHentaiSourceIds
|
||||
@ -336,9 +334,7 @@ class LibraryController(
|
||||
private fun cleanTitles() {
|
||||
val mangas = presenter.selection.filter {
|
||||
it.manga.isEhBasedManga() ||
|
||||
it.manga.source in nHentaiSourceIds ||
|
||||
it.manga.source == PERV_EDEN_EN_SOURCE_ID ||
|
||||
it.manga.source == PERV_EDEN_IT_SOURCE_ID
|
||||
it.manga.source in nHentaiSourceIds
|
||||
}
|
||||
presenter.cleanTitles(mangas)
|
||||
presenter.clearSelection()
|
||||
|
@ -38,7 +38,6 @@ import eu.kanade.tachiyomi.network.NetworkPreferences
|
||||
import eu.kanade.tachiyomi.network.PREF_DOH_CLOUDFLARE
|
||||
import eu.kanade.tachiyomi.source.Source
|
||||
import eu.kanade.tachiyomi.source.SourceManager
|
||||
import eu.kanade.tachiyomi.source.online.all.Hitomi
|
||||
import eu.kanade.tachiyomi.source.online.all.NHentai
|
||||
import eu.kanade.tachiyomi.ui.reader.setting.OrientationType
|
||||
import eu.kanade.tachiyomi.ui.reader.setting.ReaderPreferences
|
||||
@ -54,8 +53,6 @@ import exh.source.BlacklistedSources
|
||||
import exh.source.EH_SOURCE_ID
|
||||
import exh.source.HBROWSE_SOURCE_ID
|
||||
import exh.source.MERGED_SOURCE_ID
|
||||
import exh.source.PERV_EDEN_EN_SOURCE_ID
|
||||
import exh.source.PERV_EDEN_IT_SOURCE_ID
|
||||
import exh.source.TSUMINO_SOURCE_ID
|
||||
import exh.util.nullIfBlank
|
||||
import exh.util.under
|
||||
@ -139,13 +136,7 @@ object EXHMigrations {
|
||||
updateManga.awaitAll(mangaUpdates)
|
||||
}
|
||||
}
|
||||
if (oldVersion under 5) {
|
||||
// Migrate Hitomi source IDs
|
||||
updateSourceId(Hitomi.otherId, 6910)
|
||||
}
|
||||
if (oldVersion under 6) {
|
||||
updateSourceId(PERV_EDEN_EN_SOURCE_ID, 6905)
|
||||
updateSourceId(PERV_EDEN_IT_SOURCE_ID, 6906)
|
||||
updateSourceId(NHentai.otherId, 6907)
|
||||
}
|
||||
if (oldVersion under 7) {
|
||||
@ -518,14 +509,6 @@ object EXHMigrations {
|
||||
}
|
||||
|
||||
fun migrateBackupEntry(manga: Manga) {
|
||||
if (manga.source == 6905L) {
|
||||
manga.source = PERV_EDEN_EN_SOURCE_ID
|
||||
}
|
||||
|
||||
if (manga.source == 6906L) {
|
||||
manga.source = PERV_EDEN_IT_SOURCE_ID
|
||||
}
|
||||
|
||||
if (manga.source == 6907L) {
|
||||
// Migrate the old source to the delegated one
|
||||
manga.source = NHentai.otherId
|
||||
@ -538,10 +521,6 @@ object EXHMigrations {
|
||||
manga.source = TSUMINO_SOURCE_ID
|
||||
}
|
||||
|
||||
if (manga.source == 6910L) {
|
||||
manga.source = Hitomi.otherId
|
||||
}
|
||||
|
||||
if (manga.source == 6912L) {
|
||||
manga.source = HBROWSE_SOURCE_ID
|
||||
manga.url = manga.url + "/c00001/"
|
||||
|
@ -3,10 +3,8 @@ package exh.source
|
||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||
import eu.kanade.tachiyomi.source.Source
|
||||
import eu.kanade.tachiyomi.source.SourceManager
|
||||
import eu.kanade.tachiyomi.source.online.all.Hitomi
|
||||
import eu.kanade.tachiyomi.source.online.all.MangaDex
|
||||
import eu.kanade.tachiyomi.source.online.all.NHentai
|
||||
import eu.kanade.tachiyomi.source.online.all.PervEden
|
||||
import eu.kanade.tachiyomi.source.online.english.EightMuses
|
||||
import eu.kanade.tachiyomi.source.online.english.HBrowse
|
||||
import eu.kanade.tachiyomi.source.online.english.Pururin
|
||||
@ -21,8 +19,6 @@ import eu.kanade.domain.manga.model.Manga as DomainManga
|
||||
const val LEWD_SOURCE_SERIES = 6900L
|
||||
const val EH_SOURCE_ID = LEWD_SOURCE_SERIES + 1
|
||||
const val EXH_SOURCE_ID = LEWD_SOURCE_SERIES + 2
|
||||
const val PERV_EDEN_EN_SOURCE_ID = 4673633799850248749
|
||||
const val PERV_EDEN_IT_SOURCE_ID = 1433898225963724122
|
||||
const val PURURIN_SOURCE_ID = 2221515250486218861
|
||||
const val TSUMINO_SOURCE_ID = 6707338697138388238
|
||||
const val EIGHTMUSES_SOURCE_ID = 1802675169972965535
|
||||
@ -35,8 +31,6 @@ private val DELEGATED_METADATA_SOURCES by lazy {
|
||||
Tsumino::class,
|
||||
HBrowse::class,
|
||||
EightMuses::class,
|
||||
Hitomi::class,
|
||||
PervEden::class,
|
||||
NHentai::class,
|
||||
)
|
||||
}
|
||||
@ -44,8 +38,6 @@ private val DELEGATED_METADATA_SOURCES by lazy {
|
||||
// Used to speed up isLewdSource
|
||||
var metadataDelegatedSourceIds: List<Long> = emptyList()
|
||||
|
||||
var hitomiSourceIds: List<Long> = emptyList()
|
||||
|
||||
var nHentaiSourceIds: List<Long> = emptyList()
|
||||
|
||||
var mangaDexSourceIds: List<Long> = emptyList()
|
||||
@ -64,13 +56,6 @@ fun handleSourceLibrary() {
|
||||
.map { it.value.sourceId }
|
||||
.sorted()
|
||||
|
||||
hitomiSourceIds = SourceManager.currentDelegatedSources
|
||||
.filter {
|
||||
it.value.newSourceClass == Hitomi::class
|
||||
}
|
||||
.map { it.value.sourceId }
|
||||
.sorted()
|
||||
|
||||
nHentaiSourceIds = SourceManager.currentDelegatedSources
|
||||
.filter {
|
||||
it.value.newSourceClass == NHentai::class
|
||||
@ -89,7 +74,7 @@ fun handleSourceLibrary() {
|
||||
EH_SOURCE_ID,
|
||||
EXH_SOURCE_ID,
|
||||
PURURIN_SOURCE_ID,
|
||||
) + hitomiSourceIds + nHentaiSourceIds
|
||||
) + nHentaiSourceIds
|
||||
}
|
||||
|
||||
// This method MUST be fast!
|
||||
|
@ -1,60 +0,0 @@
|
||||
package exh.ui.metadata.adapters
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.viewinterop.AndroidView
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.databinding.DescriptionAdapterHiBinding
|
||||
import eu.kanade.tachiyomi.ui.manga.MangaScreenState
|
||||
import eu.kanade.tachiyomi.util.system.copyToClipboard
|
||||
import exh.metadata.MetadataUtil
|
||||
import exh.metadata.metadata.HitomiSearchMetadata
|
||||
import exh.ui.metadata.adapters.MetadataUIUtil.bindDrawable
|
||||
import java.util.Date
|
||||
|
||||
@Composable
|
||||
fun HitomiDescription(state: MangaScreenState.Success, openMetadataViewer: () -> Unit) {
|
||||
val context = LocalContext.current
|
||||
AndroidView(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
factory = { factoryContext ->
|
||||
DescriptionAdapterHiBinding.inflate(LayoutInflater.from(factoryContext)).root
|
||||
},
|
||||
update = {
|
||||
val meta = state.meta
|
||||
if (meta == null || meta !is HitomiSearchMetadata) return@AndroidView
|
||||
val binding = DescriptionAdapterHiBinding.bind(it)
|
||||
|
||||
binding.genre.text = meta.genre?.let { MetadataUIUtil.getGenreAndColour(context, it) }?.let {
|
||||
binding.genre.setBackgroundColor(it.first)
|
||||
it.second
|
||||
} ?: meta.genre ?: context.getString(R.string.unknown)
|
||||
|
||||
binding.whenPosted.text = MetadataUtil.EX_DATE_FORMAT.format(Date(meta.uploadDate ?: 0))
|
||||
binding.language.text = meta.language ?: context.getString(R.string.unknown)
|
||||
|
||||
binding.moreInfo.bindDrawable(context, R.drawable.ic_info_24dp)
|
||||
|
||||
listOf(
|
||||
binding.genre,
|
||||
binding.language,
|
||||
binding.whenPosted,
|
||||
).forEach { textView ->
|
||||
textView.setOnLongClickListener {
|
||||
context.copyToClipboard(
|
||||
textView.text.toString(),
|
||||
textView.text.toString(),
|
||||
)
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
binding.moreInfo.setOnClickListener {
|
||||
openMetadataViewer()
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
@ -1,70 +0,0 @@
|
||||
package exh.ui.metadata.adapters
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.view.LayoutInflater
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.viewinterop.AndroidView
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.databinding.DescriptionAdapterPeBinding
|
||||
import eu.kanade.tachiyomi.ui.manga.MangaScreenState
|
||||
import eu.kanade.tachiyomi.util.system.copyToClipboard
|
||||
import exh.metadata.metadata.PervEdenSearchMetadata
|
||||
import exh.ui.metadata.adapters.MetadataUIUtil.bindDrawable
|
||||
import java.util.Locale
|
||||
import kotlin.math.round
|
||||
|
||||
@Composable
|
||||
fun PervEdenDescription(state: MangaScreenState.Success, openMetadataViewer: () -> Unit) {
|
||||
val context = LocalContext.current
|
||||
AndroidView(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
factory = { factoryContext ->
|
||||
DescriptionAdapterPeBinding.inflate(LayoutInflater.from(factoryContext)).root
|
||||
},
|
||||
update = {
|
||||
val meta = state.meta
|
||||
if (meta == null || meta !is PervEdenSearchMetadata) return@AndroidView
|
||||
val binding = DescriptionAdapterPeBinding.bind(it)
|
||||
|
||||
binding.genre.text = meta.genre?.let { MetadataUIUtil.getGenreAndColour(context, it) }?.let {
|
||||
binding.genre.setBackgroundColor(it.first)
|
||||
it.second
|
||||
} ?: meta.genre ?: context.getString(R.string.unknown)
|
||||
|
||||
val language = meta.lang
|
||||
binding.language.text = if (language != null) {
|
||||
val local = Locale(language)
|
||||
local.displayName
|
||||
} else {
|
||||
context.getString(R.string.unknown)
|
||||
}
|
||||
|
||||
binding.ratingBar.rating = meta.rating ?: 0F
|
||||
@SuppressLint("SetTextI18n")
|
||||
binding.rating.text = (round((meta.rating ?: 0F) * 100.0) / 100.0).toString() + " - " + MetadataUIUtil.getRatingString(context, meta.rating?.times(2))
|
||||
|
||||
binding.moreInfo.bindDrawable(context, R.drawable.ic_info_24dp)
|
||||
|
||||
listOf(
|
||||
binding.genre,
|
||||
binding.language,
|
||||
binding.rating,
|
||||
).forEach { textView ->
|
||||
textView.setOnLongClickListener {
|
||||
context.copyToClipboard(
|
||||
textView.text.toString(),
|
||||
textView.text.toString(),
|
||||
)
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
binding.moreInfo.setOnClickListener {
|
||||
openMetadataViewer()
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
@ -48,7 +48,6 @@ private fun isHentaiSource(source: String): Boolean {
|
||||
source.contains("pururin", true) ||
|
||||
source.contains("simply hentai", true) ||
|
||||
source.contains("tsumino", true) ||
|
||||
source.contains("hitomi.la", true) ||
|
||||
source.contains("8muses", true) ||
|
||||
source.contains("hbrowse", true) ||
|
||||
source.contains("nhentai", true) ||
|
||||
|
@ -6,7 +6,6 @@ import exh.source.EH_SOURCE_ID
|
||||
import exh.source.EXH_SOURCE_ID
|
||||
import exh.source.PURURIN_SOURCE_ID
|
||||
import exh.source.TSUMINO_SOURCE_ID
|
||||
import exh.source.hitomiSourceIds
|
||||
import exh.source.mangaDexSourceIds
|
||||
import exh.source.nHentaiSourceIds
|
||||
import java.util.Locale
|
||||
@ -22,7 +21,6 @@ object SourceTagsUtil {
|
||||
sourceId == EXH_SOURCE_ID ||
|
||||
sourceId == EH_SOURCE_ID ||
|
||||
sourceId in nHentaiSourceIds ||
|
||||
sourceId in hitomiSourceIds ||
|
||||
sourceId in mangaDexSourceIds ||
|
||||
sourceId == PURURIN_SOURCE_ID ||
|
||||
sourceId == TSUMINO_SOURCE_ID
|
||||
@ -34,7 +32,6 @@ object SourceTagsUtil {
|
||||
}
|
||||
if (parsed?.namespace != null) {
|
||||
when (sourceId) {
|
||||
in hitomiSourceIds -> wrapTagHitomi(parsed.namespace!!, parsed.name.substringBefore('|').trim())
|
||||
in nHentaiSourceIds -> wrapTagNHentai(parsed.namespace!!, parsed.name.substringBefore('|').trim())
|
||||
in mangaDexSourceIds -> parsed.name
|
||||
PURURIN_SOURCE_ID -> parsed.name.substringBefore('|').trim()
|
||||
@ -55,12 +52,6 @@ object SourceTagsUtil {
|
||||
"$namespace:$tag$"
|
||||
}
|
||||
|
||||
private fun wrapTagHitomi(namespace: String, tag: String) = if (tag.contains(spaceRegex)) {
|
||||
"$namespace:$tag".replace("\\s".toRegex(), "_")
|
||||
} else {
|
||||
"$namespace:$tag"
|
||||
}
|
||||
|
||||
private fun wrapTagNHentai(namespace: String, tag: String) = if (tag.contains(spaceRegex)) {
|
||||
if (namespace == "tag") {
|
||||
""""$tag""""
|
||||
|
@ -1,87 +0,0 @@
|
||||
package exh.metadata.metadata
|
||||
|
||||
import android.content.Context
|
||||
import eu.kanade.tachiyomi.source.R
|
||||
import eu.kanade.tachiyomi.source.model.SManga
|
||||
import eu.kanade.tachiyomi.source.model.copy
|
||||
import exh.metadata.MetadataUtil
|
||||
import exh.metadata.metadata.base.RaisedSearchMetadata
|
||||
import exh.util.nullIfEmpty
|
||||
import kotlinx.serialization.Serializable
|
||||
import java.util.Date
|
||||
|
||||
@Serializable
|
||||
class HitomiSearchMetadata : RaisedSearchMetadata() {
|
||||
var url get() = hlId?.let { urlFromHlId(it) }
|
||||
set(a) {
|
||||
a?.let {
|
||||
hlId = hlIdFromUrl(a)
|
||||
}
|
||||
}
|
||||
|
||||
var hlId: String? = null
|
||||
|
||||
var title by titleDelegate(TITLE_TYPE_MAIN)
|
||||
|
||||
var thumbnailUrl: String? = null
|
||||
|
||||
var artists: List<String> = emptyList()
|
||||
|
||||
var genre: String? = null
|
||||
|
||||
var language: String? = null
|
||||
|
||||
var uploadDate: Long? = null
|
||||
|
||||
override fun createMangaInfo(manga: SManga): SManga {
|
||||
val cover = thumbnailUrl
|
||||
|
||||
val title = title
|
||||
|
||||
// Copy tags -> genres
|
||||
val genres = tagsToGenreString()
|
||||
|
||||
val artist = artists.joinToString()
|
||||
|
||||
val status = SManga.UNKNOWN
|
||||
|
||||
val description = "meta"
|
||||
|
||||
return manga.copy(
|
||||
thumbnail_url = cover ?: manga.thumbnail_url,
|
||||
title = title ?: manga.title,
|
||||
genre = genres,
|
||||
artist = artist,
|
||||
status = status,
|
||||
description = description,
|
||||
)
|
||||
}
|
||||
|
||||
override fun getExtraInfoPairs(context: Context): List<Pair<String, String>> {
|
||||
return with(context) {
|
||||
listOfNotNull(
|
||||
getItem(hlId) { getString(R.string.id) },
|
||||
getItem(title) { getString(R.string.title) },
|
||||
getItem(thumbnailUrl) { getString(R.string.thumbnail_url) },
|
||||
getItem(artists.nullIfEmpty(), { it.joinToString() }) { getString(R.string.artist) },
|
||||
getItem(genre) { getString(R.string.genre) },
|
||||
getItem(language) { getString(R.string.language) },
|
||||
getItem(uploadDate, { MetadataUtil.EX_DATE_FORMAT.format(Date(it)) }) { getString(R.string.date_posted) },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val TITLE_TYPE_MAIN = 0
|
||||
|
||||
const val TAG_TYPE_DEFAULT = 0
|
||||
|
||||
const val BASE_URL = "https://hitomi.la"
|
||||
|
||||
fun hlIdFromUrl(url: String) =
|
||||
url.split('/').last().split('-').last().substringBeforeLast('.')
|
||||
|
||||
fun urlFromHlId(id: String) =
|
||||
"$BASE_URL/galleries/$id.html"
|
||||
}
|
||||
}
|
@ -1,96 +0,0 @@
|
||||
package exh.metadata.metadata
|
||||
|
||||
import android.content.Context
|
||||
import androidx.core.net.toUri
|
||||
import eu.kanade.tachiyomi.source.R
|
||||
import eu.kanade.tachiyomi.source.model.SManga
|
||||
import eu.kanade.tachiyomi.source.model.copy
|
||||
import exh.metadata.metadata.base.RaisedSearchMetadata
|
||||
import exh.metadata.metadata.base.RaisedTitle
|
||||
import exh.util.nullIfEmpty
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
class PervEdenSearchMetadata : RaisedSearchMetadata() {
|
||||
var pvId: String? = null
|
||||
|
||||
var url: String? = null
|
||||
var thumbnailUrl: String? = null
|
||||
|
||||
var title by titleDelegate(TITLE_TYPE_MAIN)
|
||||
var altTitles
|
||||
get() = titles.filter { it.type == TITLE_TYPE_ALT }.map { it.title }
|
||||
set(value) {
|
||||
titles.removeAll { it.type == TITLE_TYPE_ALT }
|
||||
titles += value.map { RaisedTitle(it, TITLE_TYPE_ALT) }
|
||||
}
|
||||
|
||||
var artist: String? = null
|
||||
|
||||
var genre: String? = null
|
||||
|
||||
var rating: Float? = null
|
||||
|
||||
var status: String? = null
|
||||
|
||||
var lang: String? = null
|
||||
|
||||
override fun createMangaInfo(manga: SManga): SManga {
|
||||
val key = url
|
||||
val cover = thumbnailUrl
|
||||
|
||||
val title = title
|
||||
|
||||
val artist = artist
|
||||
|
||||
val status = when (status) {
|
||||
"Ongoing" -> SManga.ONGOING
|
||||
"Completed", "Suspended" -> SManga.COMPLETED
|
||||
else -> SManga.UNKNOWN
|
||||
}
|
||||
|
||||
// Copy tags -> genres
|
||||
val genres = tagsToGenreString()
|
||||
|
||||
val description = "meta"
|
||||
|
||||
return manga.copy(
|
||||
url = key ?: manga.url,
|
||||
thumbnail_url = cover ?: manga.thumbnail_url,
|
||||
title = title ?: manga.title,
|
||||
artist = artist ?: manga.artist,
|
||||
status = status,
|
||||
genre = genres,
|
||||
description = description,
|
||||
)
|
||||
}
|
||||
|
||||
override fun getExtraInfoPairs(context: Context): List<Pair<String, String>> {
|
||||
return with(context) {
|
||||
listOfNotNull(
|
||||
getItem(pvId) { getString(R.string.id) },
|
||||
getItem(url) { getString(R.string.url) },
|
||||
getItem(thumbnailUrl) { getString(R.string.thumbnail_url) },
|
||||
getItem(title) { getString(R.string.title) },
|
||||
getItem(altTitles.nullIfEmpty(), { it.joinToString() }) { getString(R.string.alt_titles) },
|
||||
getItem(artist) { getString(R.string.artist) },
|
||||
getItem(genre) { getString(R.string.genre) },
|
||||
getItem(rating) { getString(R.string.average_rating) },
|
||||
getItem(status) { getString(R.string.status) },
|
||||
getItem(lang) { getString(R.string.language) },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val TITLE_TYPE_MAIN = 0
|
||||
private const val TITLE_TYPE_ALT = 1
|
||||
|
||||
const val TAG_TYPE_DEFAULT = 0
|
||||
|
||||
private fun splitGalleryUrl(url: String) =
|
||||
url.toUri().pathSegments.filterNot(String::isNullOrBlank)
|
||||
|
||||
fun pvIdFromUrl(url: String): String = splitGalleryUrl(url).last()
|
||||
}
|
||||
}
|
@ -5,10 +5,8 @@ import eu.kanade.tachiyomi.source.model.SManga
|
||||
import exh.metadata.metadata.EHentaiSearchMetadata
|
||||
import exh.metadata.metadata.EightMusesSearchMetadata
|
||||
import exh.metadata.metadata.HBrowseSearchMetadata
|
||||
import exh.metadata.metadata.HitomiSearchMetadata
|
||||
import exh.metadata.metadata.MangaDexSearchMetadata
|
||||
import exh.metadata.metadata.NHentaiSearchMetadata
|
||||
import exh.metadata.metadata.PervEdenSearchMetadata
|
||||
import exh.metadata.metadata.PururinSearchMetadata
|
||||
import exh.metadata.metadata.TsuminoSearchMetadata
|
||||
import exh.metadata.sql.models.SearchMetadata
|
||||
@ -163,10 +161,8 @@ abstract class RaisedSearchMetadata {
|
||||
subclass(EHentaiSearchMetadata::class)
|
||||
subclass(EightMusesSearchMetadata::class)
|
||||
subclass(HBrowseSearchMetadata::class)
|
||||
subclass(HitomiSearchMetadata::class)
|
||||
subclass(MangaDexSearchMetadata::class)
|
||||
subclass(NHentaiSearchMetadata::class)
|
||||
subclass(PervEdenSearchMetadata::class)
|
||||
subclass(PururinSearchMetadata::class)
|
||||
subclass(TsuminoSearchMetadata::class)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user