remove dead delegatedsources (#701)

This commit is contained in:
Basara-Hatake 2022-10-15 18:08:26 +02:00 committed by GitHub
parent 555697b30b
commit 7fd4f5ee97
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 3 additions and 719 deletions

View File

@ -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: 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) * 8Muses (EroMuse)
* HBrowse * HBrowse
* HentaiCafe (inside Foolside)
* Hitomi.la
* Mangadex * Mangadex
* NHentai * NHentai
* PervEden (EN and IT)
* Puruin * Puruin
* Tsumino * Tsumino

View File

@ -299,21 +299,6 @@
<data android:pathPattern="/g/..*" /> <data android:pathPattern="/g/..*" />
</intent-filter> </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 --> <!-- Tsumino -->
<intent-filter> <intent-filter>
<action android:name="android.intent.action.VIEW" /> <action android:name="android.intent.action.VIEW" />
@ -330,22 +315,6 @@
<data android:pathPattern="/Read/View/..*" /> <data android:pathPattern="/Read/View/..*" />
<data android:pathPattern="/Book/Info/..*" /> <data android:pathPattern="/Book/Info/..*" />
</intent-filter> </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 --> <!-- Pururin -->
<intent-filter> <intent-filter>
<action android:name="android.intent.action.VIEW" /> <action android:name="android.intent.action.VIEW" />

View File

@ -9,8 +9,6 @@ import eu.kanade.domain.category.model.Category
import eu.kanade.domain.library.model.LibraryGroup import eu.kanade.domain.library.model.LibraryGroup
import eu.kanade.domain.library.model.LibraryManga import eu.kanade.domain.library.model.LibraryManga
import eu.kanade.tachiyomi.ui.library.LibraryPresenter 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.isEhBasedManga
import exh.source.mangaDexSourceIds import exh.source.mangaDexSourceIds
import exh.source.nHentaiSourceIds import exh.source.nHentaiSourceIds
@ -56,9 +54,7 @@ class LibraryStateImpl : LibraryState {
override val showCleanTitles: Boolean by derivedStateOf { override val showCleanTitles: Boolean by derivedStateOf {
selection.any { selection.any {
it.manga.isEhBasedManga() || it.manga.isEhBasedManga() ||
it.manga.source in nHentaiSourceIds || it.manga.source in nHentaiSourceIds
it.manga.source == PERV_EDEN_EN_SOURCE_ID ||
it.manga.source == PERV_EDEN_IT_SOURCE_ID
} }
} }
override val showAddToMangadex: Boolean by derivedStateOf { override val showAddToMangadex: Boolean by derivedStateOf {

View File

@ -76,10 +76,8 @@ import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.source.getNameForMangaInfo import eu.kanade.tachiyomi.source.getNameForMangaInfo
import eu.kanade.tachiyomi.source.online.MetadataSource import eu.kanade.tachiyomi.source.online.MetadataSource
import eu.kanade.tachiyomi.source.online.all.EHentai 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.MangaDex
import eu.kanade.tachiyomi.source.online.all.NHentai 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.EightMuses
import eu.kanade.tachiyomi.source.online.english.HBrowse import eu.kanade.tachiyomi.source.online.english.HBrowse
import eu.kanade.tachiyomi.source.online.english.Pururin 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.EHentaiDescription
import exh.ui.metadata.adapters.EightMusesDescription import exh.ui.metadata.adapters.EightMusesDescription
import exh.ui.metadata.adapters.HBrowseDescription import exh.ui.metadata.adapters.HBrowseDescription
import exh.ui.metadata.adapters.HitomiDescription
import exh.ui.metadata.adapters.MangaDexDescription import exh.ui.metadata.adapters.MangaDexDescription
import exh.ui.metadata.adapters.NHentaiDescription import exh.ui.metadata.adapters.NHentaiDescription
import exh.ui.metadata.adapters.PervEdenDescription
import exh.ui.metadata.adapters.PururinDescription import exh.ui.metadata.adapters.PururinDescription
import exh.ui.metadata.adapters.TsuminoDescription import exh.ui.metadata.adapters.TsuminoDescription
@ -873,18 +869,12 @@ fun metadataDescription(source: Source): MetadataDescriptionComposable? {
is EHentai -> { state, openMetadataViewer, search -> is EHentai -> { state, openMetadataViewer, search ->
EHentaiDescription(state, openMetadataViewer, search) EHentaiDescription(state, openMetadataViewer, search)
} }
is Hitomi -> { state, openMetadataViewer, _ ->
HitomiDescription(state, openMetadataViewer)
}
is MangaDex -> { state, openMetadataViewer, _ -> is MangaDex -> { state, openMetadataViewer, _ ->
MangaDexDescription(state, openMetadataViewer) MangaDexDescription(state, openMetadataViewer)
} }
is NHentai -> { state, openMetadataViewer, _ -> is NHentai -> { state, openMetadataViewer, _ ->
NHentaiDescription(state, openMetadataViewer) NHentaiDescription(state, openMetadataViewer)
} }
is PervEden -> { state, openMetadataViewer, _ ->
PervEdenDescription(state, openMetadataViewer)
}
is EightMuses -> { state, openMetadataViewer, _ -> is EightMuses -> { state, openMetadataViewer, _ ->
EightMusesDescription(state, openMetadataViewer) EightMusesDescription(state, openMetadataViewer)
} }

View File

@ -12,11 +12,9 @@ import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.HttpSource import eu.kanade.tachiyomi.source.online.HttpSource
import eu.kanade.tachiyomi.source.online.all.EHentai 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.MangaDex
import eu.kanade.tachiyomi.source.online.all.MergedSource import eu.kanade.tachiyomi.source.online.all.MergedSource
import eu.kanade.tachiyomi.source.online.all.NHentai 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.EightMuses
import eu.kanade.tachiyomi.source.online.english.HBrowse import eu.kanade.tachiyomi.source.online.english.HBrowse
import eu.kanade.tachiyomi.source.online.english.Pururin 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.EnhancedHttpSource
import exh.source.HBROWSE_SOURCE_ID import exh.source.HBROWSE_SOURCE_ID
import exh.source.MERGED_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.PURURIN_SOURCE_ID
import exh.source.TSUMINO_SOURCE_ID import exh.source.TSUMINO_SOURCE_ID
import exh.source.handleSourceLibrary import exh.source.handleSourceLibrary
@ -292,25 +288,6 @@ class SourceManager(
"eu.kanade.tachiyomi.extension.en.eightmuses.EightMuses", "eu.kanade.tachiyomi.extension.en.eightmuses.EightMuses",
EightMuses::class, 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( DelegatedSource(
"NHentai", "NHentai",
fillInSourceId, fillInSourceId,

View File

@ -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)
}
}
}
}

View File

@ -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()
}
}

View File

@ -36,8 +36,6 @@ import eu.kanade.tachiyomi.util.system.toast
import exh.favorites.FavoritesIntroDialog import exh.favorites.FavoritesIntroDialog
import exh.favorites.FavoritesSyncStatus import exh.favorites.FavoritesSyncStatus
import exh.source.MERGED_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.isEhBasedManga import exh.source.isEhBasedManga
import exh.source.mangaDexSourceIds import exh.source.mangaDexSourceIds
import exh.source.nHentaiSourceIds import exh.source.nHentaiSourceIds
@ -336,9 +334,7 @@ class LibraryController(
private fun cleanTitles() { private fun cleanTitles() {
val mangas = presenter.selection.filter { val mangas = presenter.selection.filter {
it.manga.isEhBasedManga() || it.manga.isEhBasedManga() ||
it.manga.source in nHentaiSourceIds || it.manga.source in nHentaiSourceIds
it.manga.source == PERV_EDEN_EN_SOURCE_ID ||
it.manga.source == PERV_EDEN_IT_SOURCE_ID
} }
presenter.cleanTitles(mangas) presenter.cleanTitles(mangas)
presenter.clearSelection() presenter.clearSelection()

View File

@ -38,7 +38,6 @@ import eu.kanade.tachiyomi.network.NetworkPreferences
import eu.kanade.tachiyomi.network.PREF_DOH_CLOUDFLARE import eu.kanade.tachiyomi.network.PREF_DOH_CLOUDFLARE
import eu.kanade.tachiyomi.source.Source import eu.kanade.tachiyomi.source.Source
import eu.kanade.tachiyomi.source.SourceManager 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.source.online.all.NHentai
import eu.kanade.tachiyomi.ui.reader.setting.OrientationType import eu.kanade.tachiyomi.ui.reader.setting.OrientationType
import eu.kanade.tachiyomi.ui.reader.setting.ReaderPreferences 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.EH_SOURCE_ID
import exh.source.HBROWSE_SOURCE_ID import exh.source.HBROWSE_SOURCE_ID
import exh.source.MERGED_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.source.TSUMINO_SOURCE_ID
import exh.util.nullIfBlank import exh.util.nullIfBlank
import exh.util.under import exh.util.under
@ -139,13 +136,7 @@ object EXHMigrations {
updateManga.awaitAll(mangaUpdates) updateManga.awaitAll(mangaUpdates)
} }
} }
if (oldVersion under 5) {
// Migrate Hitomi source IDs
updateSourceId(Hitomi.otherId, 6910)
}
if (oldVersion under 6) { if (oldVersion under 6) {
updateSourceId(PERV_EDEN_EN_SOURCE_ID, 6905)
updateSourceId(PERV_EDEN_IT_SOURCE_ID, 6906)
updateSourceId(NHentai.otherId, 6907) updateSourceId(NHentai.otherId, 6907)
} }
if (oldVersion under 7) { if (oldVersion under 7) {
@ -518,14 +509,6 @@ object EXHMigrations {
} }
fun migrateBackupEntry(manga: Manga) { 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) { if (manga.source == 6907L) {
// Migrate the old source to the delegated one // Migrate the old source to the delegated one
manga.source = NHentai.otherId manga.source = NHentai.otherId
@ -538,10 +521,6 @@ object EXHMigrations {
manga.source = TSUMINO_SOURCE_ID manga.source = TSUMINO_SOURCE_ID
} }
if (manga.source == 6910L) {
manga.source = Hitomi.otherId
}
if (manga.source == 6912L) { if (manga.source == 6912L) {
manga.source = HBROWSE_SOURCE_ID manga.source = HBROWSE_SOURCE_ID
manga.url = manga.url + "/c00001/" manga.url = manga.url + "/c00001/"

View File

@ -3,10 +3,8 @@ package exh.source
import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.source.Source import eu.kanade.tachiyomi.source.Source
import eu.kanade.tachiyomi.source.SourceManager 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.MangaDex
import eu.kanade.tachiyomi.source.online.all.NHentai 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.EightMuses
import eu.kanade.tachiyomi.source.online.english.HBrowse import eu.kanade.tachiyomi.source.online.english.HBrowse
import eu.kanade.tachiyomi.source.online.english.Pururin 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 LEWD_SOURCE_SERIES = 6900L
const val EH_SOURCE_ID = LEWD_SOURCE_SERIES + 1 const val EH_SOURCE_ID = LEWD_SOURCE_SERIES + 1
const val EXH_SOURCE_ID = LEWD_SOURCE_SERIES + 2 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 PURURIN_SOURCE_ID = 2221515250486218861
const val TSUMINO_SOURCE_ID = 6707338697138388238 const val TSUMINO_SOURCE_ID = 6707338697138388238
const val EIGHTMUSES_SOURCE_ID = 1802675169972965535 const val EIGHTMUSES_SOURCE_ID = 1802675169972965535
@ -35,8 +31,6 @@ private val DELEGATED_METADATA_SOURCES by lazy {
Tsumino::class, Tsumino::class,
HBrowse::class, HBrowse::class,
EightMuses::class, EightMuses::class,
Hitomi::class,
PervEden::class,
NHentai::class, NHentai::class,
) )
} }
@ -44,8 +38,6 @@ private val DELEGATED_METADATA_SOURCES by lazy {
// Used to speed up isLewdSource // Used to speed up isLewdSource
var metadataDelegatedSourceIds: List<Long> = emptyList() var metadataDelegatedSourceIds: List<Long> = emptyList()
var hitomiSourceIds: List<Long> = emptyList()
var nHentaiSourceIds: List<Long> = emptyList() var nHentaiSourceIds: List<Long> = emptyList()
var mangaDexSourceIds: List<Long> = emptyList() var mangaDexSourceIds: List<Long> = emptyList()
@ -64,13 +56,6 @@ fun handleSourceLibrary() {
.map { it.value.sourceId } .map { it.value.sourceId }
.sorted() .sorted()
hitomiSourceIds = SourceManager.currentDelegatedSources
.filter {
it.value.newSourceClass == Hitomi::class
}
.map { it.value.sourceId }
.sorted()
nHentaiSourceIds = SourceManager.currentDelegatedSources nHentaiSourceIds = SourceManager.currentDelegatedSources
.filter { .filter {
it.value.newSourceClass == NHentai::class it.value.newSourceClass == NHentai::class
@ -89,7 +74,7 @@ fun handleSourceLibrary() {
EH_SOURCE_ID, EH_SOURCE_ID,
EXH_SOURCE_ID, EXH_SOURCE_ID,
PURURIN_SOURCE_ID, PURURIN_SOURCE_ID,
) + hitomiSourceIds + nHentaiSourceIds ) + nHentaiSourceIds
} }
// This method MUST be fast! // This method MUST be fast!

View File

@ -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()
}
},
)
}

View File

@ -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()
}
},
)
}

View File

@ -48,7 +48,6 @@ private fun isHentaiSource(source: String): Boolean {
source.contains("pururin", true) || source.contains("pururin", true) ||
source.contains("simply hentai", true) || source.contains("simply hentai", true) ||
source.contains("tsumino", true) || source.contains("tsumino", true) ||
source.contains("hitomi.la", true) ||
source.contains("8muses", true) || source.contains("8muses", true) ||
source.contains("hbrowse", true) || source.contains("hbrowse", true) ||
source.contains("nhentai", true) || source.contains("nhentai", true) ||

View File

@ -6,7 +6,6 @@ import exh.source.EH_SOURCE_ID
import exh.source.EXH_SOURCE_ID import exh.source.EXH_SOURCE_ID
import exh.source.PURURIN_SOURCE_ID import exh.source.PURURIN_SOURCE_ID
import exh.source.TSUMINO_SOURCE_ID import exh.source.TSUMINO_SOURCE_ID
import exh.source.hitomiSourceIds
import exh.source.mangaDexSourceIds import exh.source.mangaDexSourceIds
import exh.source.nHentaiSourceIds import exh.source.nHentaiSourceIds
import java.util.Locale import java.util.Locale
@ -22,7 +21,6 @@ object SourceTagsUtil {
sourceId == EXH_SOURCE_ID || sourceId == EXH_SOURCE_ID ||
sourceId == EH_SOURCE_ID || sourceId == EH_SOURCE_ID ||
sourceId in nHentaiSourceIds || sourceId in nHentaiSourceIds ||
sourceId in hitomiSourceIds ||
sourceId in mangaDexSourceIds || sourceId in mangaDexSourceIds ||
sourceId == PURURIN_SOURCE_ID || sourceId == PURURIN_SOURCE_ID ||
sourceId == TSUMINO_SOURCE_ID sourceId == TSUMINO_SOURCE_ID
@ -34,7 +32,6 @@ object SourceTagsUtil {
} }
if (parsed?.namespace != null) { if (parsed?.namespace != null) {
when (sourceId) { when (sourceId) {
in hitomiSourceIds -> wrapTagHitomi(parsed.namespace!!, parsed.name.substringBefore('|').trim())
in nHentaiSourceIds -> wrapTagNHentai(parsed.namespace!!, parsed.name.substringBefore('|').trim()) in nHentaiSourceIds -> wrapTagNHentai(parsed.namespace!!, parsed.name.substringBefore('|').trim())
in mangaDexSourceIds -> parsed.name in mangaDexSourceIds -> parsed.name
PURURIN_SOURCE_ID -> parsed.name.substringBefore('|').trim() PURURIN_SOURCE_ID -> parsed.name.substringBefore('|').trim()
@ -55,12 +52,6 @@ object SourceTagsUtil {
"$namespace:$tag$" "$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)) { private fun wrapTagNHentai(namespace: String, tag: String) = if (tag.contains(spaceRegex)) {
if (namespace == "tag") { if (namespace == "tag") {
""""$tag"""" """"$tag""""

View File

@ -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"
}
}

View File

@ -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()
}
}

View File

@ -5,10 +5,8 @@ import eu.kanade.tachiyomi.source.model.SManga
import exh.metadata.metadata.EHentaiSearchMetadata import exh.metadata.metadata.EHentaiSearchMetadata
import exh.metadata.metadata.EightMusesSearchMetadata import exh.metadata.metadata.EightMusesSearchMetadata
import exh.metadata.metadata.HBrowseSearchMetadata import exh.metadata.metadata.HBrowseSearchMetadata
import exh.metadata.metadata.HitomiSearchMetadata
import exh.metadata.metadata.MangaDexSearchMetadata import exh.metadata.metadata.MangaDexSearchMetadata
import exh.metadata.metadata.NHentaiSearchMetadata import exh.metadata.metadata.NHentaiSearchMetadata
import exh.metadata.metadata.PervEdenSearchMetadata
import exh.metadata.metadata.PururinSearchMetadata import exh.metadata.metadata.PururinSearchMetadata
import exh.metadata.metadata.TsuminoSearchMetadata import exh.metadata.metadata.TsuminoSearchMetadata
import exh.metadata.sql.models.SearchMetadata import exh.metadata.sql.models.SearchMetadata
@ -163,10 +161,8 @@ abstract class RaisedSearchMetadata {
subclass(EHentaiSearchMetadata::class) subclass(EHentaiSearchMetadata::class)
subclass(EightMusesSearchMetadata::class) subclass(EightMusesSearchMetadata::class)
subclass(HBrowseSearchMetadata::class) subclass(HBrowseSearchMetadata::class)
subclass(HitomiSearchMetadata::class)
subclass(MangaDexSearchMetadata::class) subclass(MangaDexSearchMetadata::class)
subclass(NHentaiSearchMetadata::class) subclass(NHentaiSearchMetadata::class)
subclass(PervEdenSearchMetadata::class)
subclass(PururinSearchMetadata::class) subclass(PururinSearchMetadata::class)
subclass(TsuminoSearchMetadata::class) subclass(TsuminoSearchMetadata::class)
} }