feat(library): Filter MangaDex DMCA library entries with search keyword mangadex-dmca (#936)

* Filter MangaDex DMCA entries with search keyword `mangadex-dmca`

* Load from raw file

* using IO dispatcher

---------

Co-authored-by: az4521 <18432684+az4521@users.noreply.github.com>
This commit is contained in:
Cuong-Tran 2025-05-27 21:27:06 +07:00 committed by GitHub
parent 4db0a96b6c
commit 83b32b4c0a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 1908 additions and 0 deletions

View file

@ -2,6 +2,7 @@ package eu.kanade.tachiyomi.ui.library
import android.app.Application
import android.content.Context
import android.util.Log
import androidx.compose.runtime.Immutable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.setValue
@ -48,6 +49,7 @@ import exh.search.QueryComponent
import exh.search.SearchEngine
import exh.search.Text
import exh.source.EH_SOURCE_ID
import exh.source.MANGADEX_IDS
import exh.source.MERGED_SOURCE_ID
import exh.source.isEhBasedManga
import exh.source.isMetadataSource
@ -335,6 +337,12 @@ class LibraryScreenModel(
}
}
}
screenModelScope.launchIO {
if (mangaDexDmcaUuids.isEmpty()) {
mangaDexDmcaUuids = loadMangaDexDmcaUuids(context = Injekt.get<Application>())
}
}
// KMK <--
}
@ -1058,6 +1066,15 @@ class LibraryScreenModel(
private suspend fun filterLibrary(unfiltered: List<LibraryItem>, query: String?, loggedInTrackServices: Map<Long, TriState>): List<LibraryItem> {
return if (unfiltered.isNotEmpty() && !query.isNullOrBlank()) {
// AZ -->
if (query.trim().lowercase() == "mangadex-dmca") {
// Special easter egg query
return unfiltered.fastFilter {
it.libraryManga.manga.source in MANGADEX_IDS &&
it.libraryManga.manga.url.removePrefix("/manga/").lowercase() in mangaDexDmcaUuids
}
}
// AZ <--
// Prepare filter object
val parsedQuery = searchEngine.parseQuery(query)
val mangaWithMetaIds = getIdsOfFavoriteMangaWithMetadata.await()
@ -1607,4 +1624,33 @@ class LibraryScreenModel(
return LibraryToolbarTitle(title, count)
}
}
// KMK -->
companion object {
/** List of MangaDex UUIDs subject to DMCA takedowns */
@Volatile
private var mangaDexDmcaUuids = hashSetOf<String>()
/**
* Loads the list of MangaDex UUIDs subject to DMCA takedowns from an external file.
* The file should be placed at res/raw/mangadex_dmca_uuids.txt, one UUID per line.
*/
private suspend fun loadMangaDexDmcaUuids(context: Context): HashSet<String> = withIOContext {
try {
val inputStream = context.resources.openRawResource(
eu.kanade.tachiyomi.R.raw.mangadex_dmca_uuids,
)
inputStream.bufferedReader().useLines { lines ->
lines.map { it.trim().lowercase() }
.filter { it.isNotEmpty() && !it.startsWith("#") }
.toHashSet()
}
} catch (e: Exception) {
// Log the error and return an empty set if the file cannot be read.
Log.e("LibraryScreenModel", "Error loading MangaDex DMCA UUIDs", e)
hashSetOf()
}
}
}
// KMK <--
}

File diff suppressed because it is too large Load diff