mirror of
https://github.com/mihonapp/mihon.git
synced 2025-06-27 11:37:51 +02:00
Add extension/source blacklist
This commit is contained in:
@ -42,6 +42,7 @@ open class App : Application() {
|
|||||||
override fun onCreate() {
|
override fun onCreate() {
|
||||||
super.onCreate()
|
super.onCreate()
|
||||||
if (BuildConfig.DEBUG) Timber.plant(Timber.DebugTree())
|
if (BuildConfig.DEBUG) Timber.plant(Timber.DebugTree())
|
||||||
|
setupExhLogging() // EXH logging
|
||||||
|
|
||||||
Injekt = InjektScope(DefaultRegistrar())
|
Injekt = InjektScope(DefaultRegistrar())
|
||||||
Injekt.importModule(AppModule(this))
|
Injekt.importModule(AppModule(this))
|
||||||
@ -50,7 +51,6 @@ open class App : Application() {
|
|||||||
setupNotificationChannels()
|
setupNotificationChannels()
|
||||||
GlobalScope.launch { deleteOldMetadataRealm() } // Delete old metadata DB (EH)
|
GlobalScope.launch { deleteOldMetadataRealm() } // Delete old metadata DB (EH)
|
||||||
Reprint.initialize(this) //Setup fingerprint (EH)
|
Reprint.initialize(this) //Setup fingerprint (EH)
|
||||||
setupExhLogging() // EXH logging
|
|
||||||
|
|
||||||
LocaleHelper.updateConfiguration(this, resources.configuration)
|
LocaleHelper.updateConfiguration(this, resources.configuration)
|
||||||
}
|
}
|
||||||
@ -110,6 +110,8 @@ open class App : Application() {
|
|||||||
|
|
||||||
// EXH
|
// EXH
|
||||||
private fun setupExhLogging() {
|
private fun setupExhLogging() {
|
||||||
|
EHLogLevel.init(this)
|
||||||
|
|
||||||
val logLevel = if(BuildConfig.DEBUG || EHLogLevel.shouldLog(EHLogLevel.EXTRA)) {
|
val logLevel = if(BuildConfig.DEBUG || EHLogLevel.shouldLog(EHLogLevel.EXTRA)) {
|
||||||
LogLevel.ALL
|
LogLevel.ALL
|
||||||
} else {
|
} else {
|
||||||
|
@ -184,4 +184,6 @@ object PreferenceKeys {
|
|||||||
const val eh_showTransitionPages = "eh_show_transition_pages"
|
const val eh_showTransitionPages = "eh_show_transition_pages"
|
||||||
|
|
||||||
const val eh_logLevel = "eh_log_level"
|
const val eh_logLevel = "eh_log_level"
|
||||||
|
|
||||||
|
const val eh_enableSourceBlacklist = "eh_enable_source_blacklist"
|
||||||
}
|
}
|
||||||
|
@ -257,4 +257,6 @@ class PreferencesHelper(val context: Context) {
|
|||||||
fun eh_showTransitionPages() = rxPrefs.getBoolean(Keys.eh_showTransitionPages, true)
|
fun eh_showTransitionPages() = rxPrefs.getBoolean(Keys.eh_showTransitionPages, true)
|
||||||
|
|
||||||
fun eh_logLevel() = rxPrefs.getInteger(Keys.eh_logLevel, 0)
|
fun eh_logLevel() = rxPrefs.getInteger(Keys.eh_logLevel, 0)
|
||||||
|
|
||||||
|
fun eh_enableSourceBlacklist() = rxPrefs.getBoolean(Keys.eh_enableSourceBlacklist, true)
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package eu.kanade.tachiyomi.extension
|
package eu.kanade.tachiyomi.extension
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import com.elvishew.xlog.XLog
|
||||||
import com.jakewharton.rxrelay.BehaviorRelay
|
import com.jakewharton.rxrelay.BehaviorRelay
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||||
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
||||||
@ -13,6 +14,7 @@ import eu.kanade.tachiyomi.extension.util.ExtensionInstaller
|
|||||||
import eu.kanade.tachiyomi.extension.util.ExtensionLoader
|
import eu.kanade.tachiyomi.extension.util.ExtensionLoader
|
||||||
import eu.kanade.tachiyomi.source.SourceManager
|
import eu.kanade.tachiyomi.source.SourceManager
|
||||||
import eu.kanade.tachiyomi.util.launchNow
|
import eu.kanade.tachiyomi.util.launchNow
|
||||||
|
import exh.source.BlacklistedSources
|
||||||
import kotlinx.coroutines.async
|
import kotlinx.coroutines.async
|
||||||
import rx.Observable
|
import rx.Observable
|
||||||
import rx.android.schedulers.AndroidSchedulers
|
import rx.android.schedulers.AndroidSchedulers
|
||||||
@ -111,6 +113,7 @@ class ExtensionManager(
|
|||||||
installedExtensions = extensions
|
installedExtensions = extensions
|
||||||
.filterIsInstance<LoadResult.Success>()
|
.filterIsInstance<LoadResult.Success>()
|
||||||
.map { it.extension }
|
.map { it.extension }
|
||||||
|
.filterNotBlacklisted()
|
||||||
installedExtensions
|
installedExtensions
|
||||||
.flatMap { it.sources }
|
.flatMap { it.sources }
|
||||||
// overwrite is needed until the bundled sources are removed
|
// overwrite is needed until the bundled sources are removed
|
||||||
@ -119,7 +122,24 @@ class ExtensionManager(
|
|||||||
untrustedExtensions = extensions
|
untrustedExtensions = extensions
|
||||||
.filterIsInstance<LoadResult.Untrusted>()
|
.filterIsInstance<LoadResult.Untrusted>()
|
||||||
.map { it.extension }
|
.map { it.extension }
|
||||||
|
.filterNotBlacklisted()
|
||||||
}
|
}
|
||||||
|
// EXH -->
|
||||||
|
fun <T : Extension> Iterable<T>.filterNotBlacklisted(): List<T> {
|
||||||
|
val blacklistEnabled = preferences.eh_enableSourceBlacklist().getOrDefault()
|
||||||
|
return filter {
|
||||||
|
if(it.isBlacklisted(blacklistEnabled)) {
|
||||||
|
XLog.d("[EXH] Removing blacklisted extension: (name: String, pkgName: %s)!", it.name, it.pkgName)
|
||||||
|
false
|
||||||
|
} else true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Extension.isBlacklisted(blacklistEnabled: Boolean =
|
||||||
|
preferences.eh_enableSourceBlacklist().getOrDefault()): Boolean {
|
||||||
|
return pkgName in BlacklistedSources.BLACKLISTED_EXTENSIONS && blacklistEnabled
|
||||||
|
}
|
||||||
|
// EXH <--
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the relay of the installed extensions as an observable.
|
* Returns the relay of the installed extensions as an observable.
|
||||||
@ -150,7 +170,7 @@ class ExtensionManager(
|
|||||||
.onErrorReturn { emptyList() }
|
.onErrorReturn { emptyList() }
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.subscribe { availableExtensions = it }
|
.subscribe { availableExtensions = it.filterNotBlacklisted() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -173,7 +193,7 @@ class ExtensionManager(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (changed) {
|
if (changed) {
|
||||||
installedExtensions = mutInstalledExtensions
|
installedExtensions = mutInstalledExtensions.filterNotBlacklisted()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -258,6 +278,11 @@ class ExtensionManager(
|
|||||||
* @param extension The extension to be registered.
|
* @param extension The extension to be registered.
|
||||||
*/
|
*/
|
||||||
private fun registerNewExtension(extension: Extension.Installed) {
|
private fun registerNewExtension(extension: Extension.Installed) {
|
||||||
|
if(extension.isBlacklisted()) {
|
||||||
|
XLog.d("[EXH] Removing blacklisted extension: (name: String, pkgName: %s)!", extension.name, extension.pkgName)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
installedExtensions += extension
|
installedExtensions += extension
|
||||||
extension.sources.forEach { sourceManager.registerSource(it) }
|
extension.sources.forEach { sourceManager.registerSource(it) }
|
||||||
}
|
}
|
||||||
@ -269,6 +294,11 @@ class ExtensionManager(
|
|||||||
* @param extension The extension to be registered.
|
* @param extension The extension to be registered.
|
||||||
*/
|
*/
|
||||||
private fun registerUpdatedExtension(extension: Extension.Installed) {
|
private fun registerUpdatedExtension(extension: Extension.Installed) {
|
||||||
|
if(extension.isBlacklisted()) {
|
||||||
|
XLog.d("[EXH] Removing blacklisted extension: (name: String, pkgName: %s)!", extension.name, extension.pkgName)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
val mutInstalledExtensions = installedExtensions.toMutableList()
|
val mutInstalledExtensions = installedExtensions.toMutableList()
|
||||||
val oldExtension = mutInstalledExtensions.find { it.pkgName == extension.pkgName }
|
val oldExtension = mutInstalledExtensions.find { it.pkgName == extension.pkgName }
|
||||||
if (oldExtension != null) {
|
if (oldExtension != null) {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package eu.kanade.tachiyomi.source
|
package eu.kanade.tachiyomi.source
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import com.elvishew.xlog.XLog
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.source.model.Page
|
import eu.kanade.tachiyomi.source.model.Page
|
||||||
import eu.kanade.tachiyomi.source.model.SChapter
|
import eu.kanade.tachiyomi.source.model.SChapter
|
||||||
@ -20,6 +21,7 @@ import exh.EXH_SOURCE_ID
|
|||||||
import exh.PERV_EDEN_EN_SOURCE_ID
|
import exh.PERV_EDEN_EN_SOURCE_ID
|
||||||
import exh.PERV_EDEN_IT_SOURCE_ID
|
import exh.PERV_EDEN_IT_SOURCE_ID
|
||||||
import exh.metadata.metadata.PervEdenLang
|
import exh.metadata.metadata.PervEdenLang
|
||||||
|
import exh.source.BlacklistedSources
|
||||||
import exh.source.DelegatedHttpSource
|
import exh.source.DelegatedHttpSource
|
||||||
import exh.source.EnhancedHttpSource
|
import exh.source.EnhancedHttpSource
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
@ -67,15 +69,23 @@ open class SourceManager(private val context: Context) {
|
|||||||
fun getCatalogueSources() = sourcesMap.values.filterIsInstance<CatalogueSource>()
|
fun getCatalogueSources() = sourcesMap.values.filterIsInstance<CatalogueSource>()
|
||||||
|
|
||||||
internal fun registerSource(source: Source, overwrite: Boolean = false) {
|
internal fun registerSource(source: Source, overwrite: Boolean = false) {
|
||||||
|
// EXH -->
|
||||||
val sourceQName = source::class.qualifiedName
|
val sourceQName = source::class.qualifiedName
|
||||||
val delegate = DELEGATED_SOURCES[sourceQName]
|
val delegate = DELEGATED_SOURCES[sourceQName]
|
||||||
val newSource = if(source is HttpSource && delegate != null) {
|
val newSource = if(source is HttpSource && delegate != null) {
|
||||||
Timber.d("[EXH] Delegating source: %s -> %s!", sourceQName, delegate.newSourceClass.qualifiedName)
|
XLog.d("[EXH] Delegating source: %s -> %s!", sourceQName, delegate.newSourceClass.qualifiedName)
|
||||||
EnhancedHttpSource(
|
EnhancedHttpSource(
|
||||||
source,
|
source,
|
||||||
delegate.newSourceClass.constructors.find { it.parameters.size == 1 }!!.call(source)
|
delegate.newSourceClass.constructors.find { it.parameters.size == 1 }!!.call(source)
|
||||||
)
|
)
|
||||||
} else source
|
} else source
|
||||||
|
|
||||||
|
if(source.id in BlacklistedSources.BLACKLISTED_EXT_SOURCES) {
|
||||||
|
XLog.d("[EXH] Removing blacklisted source: (id: %s, name: %s, lang: %s)!", source.id, source.name, (source as? CatalogueSource)?.lang)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// EXH <--
|
||||||
|
|
||||||
if (overwrite || !sourcesMap.containsKey(source.id)) {
|
if (overwrite || !sourcesMap.containsKey(source.id)) {
|
||||||
sourcesMap[source.id] = newSource
|
sourcesMap[source.id] = newSource
|
||||||
}
|
}
|
||||||
|
@ -113,30 +113,42 @@ class SettingsAdvancedController : SettingsController() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
switchPreference {
|
preferenceCategory {
|
||||||
title = "Enable delegated sources"
|
title = "Developer tools"
|
||||||
key = PreferenceKeys.eh_delegateSources
|
isPersistent = false
|
||||||
defaultValue = true
|
|
||||||
summary = "Apply TachiyomiEH enhancements to the following sources if they are installed: ${DELEGATED_SOURCES.values.joinToString { it.sourceName }}"
|
|
||||||
}
|
|
||||||
|
|
||||||
intListPreference {
|
switchPreference {
|
||||||
key = PreferenceKeys.eh_logLevel
|
title = "Enable delegated sources"
|
||||||
title = "Log level"
|
key = PreferenceKeys.eh_delegateSources
|
||||||
|
defaultValue = true
|
||||||
|
summary = "Apply ${context.getString(R.string.app_name)} enhancements to the following sources if they are installed: ${DELEGATED_SOURCES.values.joinToString { it.sourceName }}"
|
||||||
|
}
|
||||||
|
|
||||||
entries = EHLogLevel.values().map {
|
intListPreference {
|
||||||
"${it.name.toLowerCase().capitalize()} (${it.description})"
|
key = PreferenceKeys.eh_logLevel
|
||||||
}.toTypedArray()
|
title = "Log level"
|
||||||
entryValues = EHLogLevel.values().mapIndexed { index, _ -> "$index" }.toTypedArray()
|
|
||||||
defaultValue = "0"
|
|
||||||
|
|
||||||
summary = "Changing this can impact app performance. Force-restart app after changing. Current value: %s"
|
entries = EHLogLevel.values().map {
|
||||||
}
|
"${it.name.toLowerCase().capitalize()} (${it.description})"
|
||||||
|
}.toTypedArray()
|
||||||
|
entryValues = EHLogLevel.values().mapIndexed { index, _ -> "$index" }.toTypedArray()
|
||||||
|
defaultValue = "0"
|
||||||
|
|
||||||
preference {
|
summary = "Changing this can impact app performance. Force-restart app after changing. Current value: %s"
|
||||||
title = "Open debug menu"
|
}
|
||||||
summary = Html.fromHtml("DO NOT TOUCH THIS MENU UNLESS YOU KNOW WHAT YOU ARE DOING! <font color='red'>IT CAN CORRUPT YOUR LIBRARY!</font>")
|
|
||||||
onClick { router.pushController(SettingsDebugController().withFadeTransaction()) }
|
switchPreference {
|
||||||
|
title = "Enable source blacklist"
|
||||||
|
key = PreferenceKeys.eh_enableSourceBlacklist
|
||||||
|
defaultValue = true
|
||||||
|
summary = "Hide extensions/sources that are incompatible with ${context.getString(R.string.app_name)}. Force-restart app after changing."
|
||||||
|
}
|
||||||
|
|
||||||
|
preference {
|
||||||
|
title = "Open debug menu"
|
||||||
|
summary = Html.fromHtml("DO NOT TOUCH THIS MENU UNLESS YOU KNOW WHAT YOU ARE DOING! <font color='red'>IT CAN CORRUPT YOUR LIBRARY!</font>")
|
||||||
|
onClick { router.pushController(SettingsDebugController().withFadeTransaction()) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// <-- EXH
|
// <-- EXH
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ import eu.kanade.tachiyomi.data.database.resolvers.MangaUrlPutResolver
|
|||||||
import eu.kanade.tachiyomi.data.database.tables.MangaTable
|
import eu.kanade.tachiyomi.data.database.tables.MangaTable
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||||
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
||||||
|
import exh.source.BlacklistedSources
|
||||||
import rx.Observable
|
import rx.Observable
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
import java.net.URI
|
import java.net.URI
|
||||||
@ -87,35 +88,22 @@ object EXHMigrations {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Allow importing of nhentai extension backups
|
// Allow importing of nhentai extension backups
|
||||||
if(manga.source == 3122156392225024195) {
|
if(manga.source in BlacklistedSources.NHENTAI_EXT_SOURCES) {
|
||||||
manga.source = NHENTAI_SOURCE_ID
|
manga.source = NHENTAI_SOURCE_ID
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Allow importing of English PervEden extension backups
|
||||||
|
if(manga.source in BlacklistedSources.PERVEDEN_EN_EXT_SOURCES) {
|
||||||
|
manga.source = PERV_EDEN_EN_SOURCE_ID
|
||||||
|
}
|
||||||
|
|
||||||
// Allow importing of Italian PervEden extension backups
|
// Allow importing of Italian PervEden extension backups
|
||||||
if(manga.source == 1433898225963724122) {
|
if(manga.source in BlacklistedSources.PERVEDEN_IT_EXT_SOURCES) {
|
||||||
manga.source = PERV_EDEN_IT_SOURCE_ID
|
manga.source = PERV_EDEN_IT_SOURCE_ID
|
||||||
}
|
}
|
||||||
|
|
||||||
if(manga.source in listOf(
|
// Allow importing of EHentai extension backups
|
||||||
8100626124886895451,
|
if(manga.source in BlacklistedSources.EHENTAI_EXT_SOURCES) {
|
||||||
57122881048805941,
|
|
||||||
4678440076103929247,
|
|
||||||
1876021963378735852,
|
|
||||||
3955189842350477641,
|
|
||||||
4348288691341764259,
|
|
||||||
773611868725221145,
|
|
||||||
5759417018342755550,
|
|
||||||
825187715438990384,
|
|
||||||
6116711405602166104,
|
|
||||||
7151438547982231541,
|
|
||||||
2171445159732592630,
|
|
||||||
3032959619549451093,
|
|
||||||
5980349886941016589,
|
|
||||||
6073266008352078708,
|
|
||||||
5499077866612745456,
|
|
||||||
6140480779421365791
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
manga.source = EH_SOURCE_ID
|
manga.source = EH_SOURCE_ID
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
package exh.log
|
package exh.log
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||||
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
||||||
import uy.kohesive.injekt.Injekt
|
|
||||||
import uy.kohesive.injekt.api.get
|
|
||||||
|
|
||||||
enum class EHLogLevel(val description: String) {
|
enum class EHLogLevel(val description: String) {
|
||||||
MINIMAL("critical errors only"),
|
MINIMAL("critical errors only"),
|
||||||
@ -11,12 +10,15 @@ enum class EHLogLevel(val description: String) {
|
|||||||
EXTREME("network inspection mode");
|
EXTREME("network inspection mode");
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val curLogLevel by lazy {
|
private var curLogLevel: Int? = null
|
||||||
Injekt.get<PreferencesHelper>().eh_logLevel().getOrDefault()
|
|
||||||
|
fun init(context: Context) {
|
||||||
|
curLogLevel = PreferencesHelper(context)
|
||||||
|
.eh_logLevel().getOrDefault()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun shouldLog(requiredLogLevel: EHLogLevel): Boolean {
|
fun shouldLog(requiredLogLevel: EHLogLevel): Boolean {
|
||||||
return curLogLevel >= requiredLogLevel.ordinal
|
return curLogLevel!! >= requiredLogLevel.ordinal
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
38
app/src/main/java/exh/source/BlacklistedSources.kt
Normal file
38
app/src/main/java/exh/source/BlacklistedSources.kt
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
package exh.source
|
||||||
|
|
||||||
|
object BlacklistedSources {
|
||||||
|
val NHENTAI_EXT_SOURCES = listOf(3122156392225024195)
|
||||||
|
val PERVEDEN_EN_EXT_SOURCES = listOf(4673633799850248749)
|
||||||
|
val PERVEDEN_IT_EXT_SOURCES = listOf(1433898225963724122)
|
||||||
|
val EHENTAI_EXT_SOURCES = listOf(
|
||||||
|
8100626124886895451,
|
||||||
|
57122881048805941,
|
||||||
|
4678440076103929247,
|
||||||
|
1876021963378735852,
|
||||||
|
3955189842350477641,
|
||||||
|
4348288691341764259,
|
||||||
|
773611868725221145,
|
||||||
|
5759417018342755550,
|
||||||
|
825187715438990384,
|
||||||
|
6116711405602166104,
|
||||||
|
7151438547982231541,
|
||||||
|
2171445159732592630,
|
||||||
|
3032959619549451093,
|
||||||
|
5980349886941016589,
|
||||||
|
6073266008352078708,
|
||||||
|
5499077866612745456,
|
||||||
|
6140480779421365791
|
||||||
|
)
|
||||||
|
|
||||||
|
val BLACKLISTED_EXT_SOURCES = NHENTAI_EXT_SOURCES +
|
||||||
|
PERVEDEN_EN_EXT_SOURCES +
|
||||||
|
PERVEDEN_IT_EXT_SOURCES +
|
||||||
|
EHENTAI_EXT_SOURCES
|
||||||
|
|
||||||
|
val BLACKLISTED_EXTENSIONS = listOf(
|
||||||
|
"eu.kanade.tachiyomi.extension.all.ehentai",
|
||||||
|
"eu.kanade.tachiyomi.extension.all.nhentai",
|
||||||
|
"eu.kanade.tachiyomi.extension.en.perveden",
|
||||||
|
"eu.kanade.tachiyomi.extension.it.perveden"
|
||||||
|
)
|
||||||
|
}
|
Reference in New Issue
Block a user