Files
TachiyomiSY/app/src/main/java/exh/debug/DebugFunctions.kt
T
2020-08-15 15:57:07 -04:00

355 lines
14 KiB
Kotlin

package exh.debug
import android.app.Application
import com.github.salomonbrys.kotson.array
import com.github.salomonbrys.kotson.jsonObject
import com.github.salomonbrys.kotson.obj
import com.github.salomonbrys.kotson.string
import com.google.gson.JsonParser
import com.pushtorefresh.storio.sqlite.queries.RawQuery
import eu.kanade.tachiyomi.data.database.DatabaseHelper
import eu.kanade.tachiyomi.data.database.tables.MangaTable
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.source.CatalogueSource
import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.source.SourceManager.Companion.currentDelegatedSources
import exh.EH_SOURCE_ID
import exh.EXHMigrations
import exh.EXHSavedSearch
import exh.EXH_SOURCE_ID
import exh.eh.EHentaiThrottleManager
import exh.eh.EHentaiUpdateWorker
import exh.metadata.metadata.EHentaiSearchMetadata
import exh.metadata.metadata.base.getFlatMetadataForManga
import exh.metadata.metadata.base.insertFlatMetadata
import exh.util.await
import exh.util.cancellable
import exh.util.jobScheduler
import java.lang.RuntimeException
import kotlinx.coroutines.flow.asFlow
import kotlinx.coroutines.flow.mapNotNull
import kotlinx.coroutines.flow.toList
import kotlinx.coroutines.runBlocking
import timber.log.Timber
import uy.kohesive.injekt.injectLazy
import xyz.nulldev.ts.api.http.serializer.FilterSerializer
object DebugFunctions {
val app: Application by injectLazy()
val db: DatabaseHelper by injectLazy()
val prefs: PreferencesHelper by injectLazy()
val sourceManager: SourceManager by injectLazy()
fun forceUpgradeMigration() {
prefs.eh_lastVersionCode().set(1)
EXHMigrations.upgrade(prefs)
}
fun forceSetupJobs() {
prefs.eh_lastVersionCode().set(0)
EXHMigrations.upgrade(prefs)
}
fun resetAgedFlagInEXHManga() {
runBlocking {
val metadataManga = db.getFavoriteMangaWithMetadata().await()
val allManga = metadataManga.asFlow().cancellable().mapNotNull { manga ->
if (manga.source != EH_SOURCE_ID && manga.source != EXH_SOURCE_ID) {
null
} else manga
}.toList()
allManga.forEach { manga ->
val meta = db.getFlatMetadataForManga(manga.id!!).await()?.raise<EHentaiSearchMetadata>() ?: return@forEach
// remove age flag
meta.aged = false
db.insertFlatMetadata(meta.flatten()).await()
}
}
}
private val throttleManager = EHentaiThrottleManager()
fun getDelegatedSourceList(): String = currentDelegatedSources.map { it.value.sourceName + " : " + it.value.sourceId + " : " + it.value.factory }.joinToString(separator = "\n")
fun resetEHGalleriesForUpdater() {
throttleManager.resetThrottle()
runBlocking {
val metadataManga = db.getFavoriteMangaWithMetadata().await()
val allManga = metadataManga.asFlow().cancellable().mapNotNull { manga ->
if (manga.source != EH_SOURCE_ID && manga.source != EXH_SOURCE_ID) {
null
} else manga
}.toList()
val eh = sourceManager.get(EH_SOURCE_ID)
val ex = sourceManager.get(EXH_SOURCE_ID)
allManga.forEach { manga ->
throttleManager.throttle()
(
when (manga.source) {
EH_SOURCE_ID -> eh
EXH_SOURCE_ID -> ex
else -> return@forEach
}
)?.fetchMangaDetails(manga)?.map { networkManga ->
manga.copyFrom(networkManga)
manga.initialized = true
db.insertManga(manga).executeAsBlocking()
}
}
}
}
fun getEHMangaListWithAgedFlagInfo(): String {
val galleries = mutableListOf(String())
runBlocking {
val metadataManga = db.getFavoriteMangaWithMetadata().await()
val allManga = metadataManga.asFlow().cancellable().mapNotNull { manga ->
if (manga.source != EH_SOURCE_ID && manga.source != EXH_SOURCE_ID) {
null
} else manga
}.toList()
allManga.forEach { manga ->
val meta = db.getFlatMetadataForManga(manga.id!!).await()?.raise<EHentaiSearchMetadata>() ?: return@forEach
galleries += "Aged: ${meta.aged}\t Title: ${manga.title}"
}
}
return galleries.joinToString(",\n")
}
fun countAgedFlagInEXHManga(): Int {
var agedAmount = 0
runBlocking {
val metadataManga = db.getFavoriteMangaWithMetadata().await()
val allManga = metadataManga.asFlow().cancellable().mapNotNull { manga ->
if (manga.source != EH_SOURCE_ID && manga.source != EXH_SOURCE_ID) {
null
} else manga
}.toList()
allManga.forEach { manga ->
val meta = db.getFlatMetadataForManga(manga.id!!).await()?.raise<EHentaiSearchMetadata>() ?: return@forEach
if (meta.aged) {
// remove age flag
agedAmount++
}
}
}
return agedAmount
}
fun addAllMangaInDatabaseToLibrary() {
db.inTransaction {
db.lowLevel().executeSQL(
RawQuery.builder()
.query(
"""
UPDATE ${MangaTable.TABLE}
SET ${MangaTable.COL_FAVORITE} = 1
""".trimIndent()
)
.affectsTables(MangaTable.TABLE)
.build()
)
}
}
fun countMangaInDatabaseInLibrary() = db.getMangas().executeAsBlocking().count { it.favorite }
fun countMangaInDatabaseNotInLibrary() = db.getMangas().executeAsBlocking().count { !it.favorite }
fun countMangaInDatabase() = db.getMangas().executeAsBlocking().size
fun countMetadataInDatabase() = db.getSearchMetadata().executeAsBlocking().size
fun countMangaInLibraryWithMissingMetadata() = db.getMangas().executeAsBlocking().count {
it.favorite && db.getSearchMetadataForManga(it.id!!).executeAsBlocking() == null
}
fun clearSavedSearches() = prefs.eh_savedSearches().set(emptySet())
fun listAllSources() = sourceManager.getCatalogueSources().joinToString("\n") {
"${it.id}: ${it.name} (${it.lang.toUpperCase()})"
}
fun listAllSourcesClassName() = sourceManager.getCatalogueSources().joinToString("\n") {
"${it::class.qualifiedName}: ${it.name} (${it.lang.toUpperCase()})"
}
fun listVisibleSources() = sourceManager.getVisibleCatalogueSources().joinToString("\n") {
"${it.id}: ${it.name} (${it.lang.toUpperCase()})"
}
fun listAllHttpSources() = sourceManager.getOnlineSources().joinToString("\n") {
"${it.id}: ${it.name} (${it.lang.toUpperCase()})"
}
fun listVisibleHttpSources() = sourceManager.getVisibleOnlineSources().joinToString("\n") {
"${it.id}: ${it.name} (${it.lang.toUpperCase()})"
}
fun convertAllEhentaiGalleriesToExhentai() = convertSources(EH_SOURCE_ID, EXH_SOURCE_ID)
fun convertAllExhentaiGalleriesToEhentai() = convertSources(EXH_SOURCE_ID, EH_SOURCE_ID)
fun testLaunchEhentaiBackgroundUpdater(): String {
return EHentaiUpdateWorker.launchBackgroundTest(app)
}
fun rescheduleEhentaiBackgroundUpdater() {
EHentaiUpdateWorker.scheduleBackground(app)
}
fun listScheduledJobs() = app.jobScheduler.allPendingJobs.map { j ->
"""
{
info: ${j.id},
isPeriod: ${j.isPeriodic},
isPersisted: ${j.isPersisted},
intervalMillis: ${j.intervalMillis},
}
""".trimIndent()
}.joinToString(",\n")
fun cancelAllScheduledJobs() = app.jobScheduler.cancelAll()
private fun convertSources(from: Long, to: Long) {
db.lowLevel().executeSQL(
RawQuery.builder()
.query(
"""
UPDATE ${MangaTable.TABLE}
SET ${MangaTable.COL_SOURCE} = $to
WHERE ${MangaTable.COL_SOURCE} = $from
""".trimIndent()
)
.affectsTables(MangaTable.TABLE)
.build()
)
}
fun copyEHentaiSavedSearchesToExhentai() {
runBlocking {
val filterSerializer = FilterSerializer()
val source = sourceManager.get(EH_SOURCE_ID) as? CatalogueSource ?: return@runBlocking
val newSource = sourceManager.get(EXH_SOURCE_ID) as? CatalogueSource ?: return@runBlocking
val savedSearches = prefs.eh_savedSearches().get().mapNotNull {
try {
val id = it.substringBefore(':').toLong()
if (id != source.id) return@mapNotNull null
val content = JsonParser.parseString(it.substringAfter(':')).obj
val originalFilters = source.getFilterList()
filterSerializer.deserialize(originalFilters, content["filters"].array)
EXHSavedSearch(
content["name"].string,
content["query"].string,
originalFilters
)
} catch (t: RuntimeException) {
// Load failed
Timber.e(t, "Failed to load saved search!")
t.printStackTrace()
null
}
}.toMutableList()
savedSearches += prefs.eh_savedSearches().get().mapNotNull {
try {
val id = it.substringBefore(':').toLong()
if (id != newSource.id) return@mapNotNull null
val content = JsonParser.parseString(it.substringAfter(':')).obj
val originalFilters = source.getFilterList()
filterSerializer.deserialize(originalFilters, content["filters"].array)
EXHSavedSearch(
content["name"].string,
content["query"].string,
originalFilters
)
} catch (t: RuntimeException) {
// Load failed
Timber.e(t, "Failed to load saved search!")
t.printStackTrace()
null
}
}.filterNot { newSavedSearch -> savedSearches.any { it.name == newSavedSearch.name } }
val otherSerialized = prefs.eh_savedSearches().get().filter {
!it.startsWith("${newSource.id}:")
}
val newSerialized = savedSearches.map {
"${newSource.id}:" + jsonObject(
"name" to it.name,
"query" to it.query,
"filters" to filterSerializer.serialize(it.filterList)
).toString()
}
prefs.eh_savedSearches().set((otherSerialized + newSerialized).toSet())
}
}
fun copyExhentaiSavedSearchesToEHentai() {
runBlocking {
val filterSerializer = FilterSerializer()
val source = sourceManager.get(EXH_SOURCE_ID) as? CatalogueSource ?: return@runBlocking
val newSource = sourceManager.get(EH_SOURCE_ID) as? CatalogueSource ?: return@runBlocking
val savedSearches = prefs.eh_savedSearches().get().mapNotNull {
try {
val id = it.substringBefore(':').toLong()
if (id != source.id) return@mapNotNull null
val content = JsonParser.parseString(it.substringAfter(':')).obj
val originalFilters = source.getFilterList()
filterSerializer.deserialize(originalFilters, content["filters"].array)
EXHSavedSearch(
content["name"].string,
content["query"].string,
originalFilters
)
} catch (t: RuntimeException) {
// Load failed
Timber.e(t, "Failed to load saved search!")
t.printStackTrace()
null
}
}.toMutableList()
savedSearches += prefs.eh_savedSearches().get().mapNotNull {
try {
val id = it.substringBefore(':').toLong()
if (id != newSource.id) return@mapNotNull null
val content = JsonParser.parseString(it.substringAfter(':')).obj
val originalFilters = source.getFilterList()
filterSerializer.deserialize(originalFilters, content["filters"].array)
EXHSavedSearch(
content["name"].string,
content["query"].string,
originalFilters
)
} catch (t: RuntimeException) {
// Load failed
Timber.e(t, "Failed to load saved search!")
t.printStackTrace()
null
}
}.filterNot { newSavedSearch -> savedSearches.any { it.name == newSavedSearch.name } }
val otherSerialized = prefs.eh_savedSearches().get().filter {
!it.startsWith("${newSource.id}:")
}
val newSerialized = savedSearches.map {
"${newSource.id}:" + jsonObject(
"name" to it.name,
"query" to it.query,
"filters" to filterSerializer.serialize(it.filterList)
).toString()
}
prefs.eh_savedSearches().set((otherSerialized + newSerialized).toSet())
}
}
}