komikku/app/src/main/java/exh/debug/DebugFunctions.kt

313 lines
12 KiB
Kotlin
Raw Normal View History

package exh.debug
2019-04-18 23:40:13 +02:00
import android.app.Application
2020-09-17 15:05:19 +02:00
import com.elvishew.xlog.XLog
import com.pushtorefresh.storio.sqlite.queries.RawQuery
import eu.kanade.tachiyomi.data.database.DatabaseHelper
import eu.kanade.tachiyomi.data.database.models.toMangaInfo
import eu.kanade.tachiyomi.data.database.tables.MangaTable
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.source.CatalogueSource
2019-04-14 18:12:58 +02:00
import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.source.model.toSManga
import eu.kanade.tachiyomi.util.lang.await
2019-04-14 18:12:58 +02:00
import exh.EH_SOURCE_ID
2020-02-22 11:12:30 +01:00
import exh.EXHMigrations
import exh.EXH_SOURCE_ID
import exh.eh.EHentaiThrottleManager
2019-04-18 23:40:13 +02:00
import exh.eh.EHentaiUpdateWorker
2020-02-10 20:04:16 +01:00
import exh.metadata.metadata.EHentaiSearchMetadata
import exh.metadata.metadata.base.getFlatMetadataForManga
import exh.metadata.metadata.base.insertFlatMetadata
import exh.savedsearches.JsonSavedSearch
2020-02-10 20:04:16 +01:00
import exh.util.cancellable
import exh.util.executeOnIO
import exh.util.jobScheduler
2020-02-10 20:04:16 +01:00
import kotlinx.coroutines.flow.asFlow
import kotlinx.coroutines.flow.mapNotNull
import kotlinx.coroutines.flow.toList
import kotlinx.coroutines.runBlocking
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import uy.kohesive.injekt.injectLazy
import java.lang.RuntimeException
2020-11-25 21:57:05 +01:00
@Suppress("unused")
object DebugFunctions {
2019-04-18 23:40:13 +02:00
val app: Application by injectLazy()
val db: DatabaseHelper by injectLazy()
val prefs: PreferencesHelper by injectLazy()
2019-04-14 18:12:58 +02:00
val sourceManager: SourceManager by injectLazy()
2020-02-22 11:12:30 +01:00
fun forceUpgradeMigration() {
2020-11-30 20:35:31 +01:00
prefs.ehLastVersionCode().set(1)
2020-02-22 11:12:30 +01:00
EXHMigrations.upgrade(prefs)
}
2020-08-14 04:15:09 +02:00
fun forceSetupJobs() {
2020-11-30 20:35:31 +01:00
prefs.ehLastVersionCode().set(0)
2020-08-14 04:15:09 +02:00
EXHMigrations.upgrade(prefs)
}
2020-02-10 20:04:16 +01:00
fun resetAgedFlagInEXHManga() {
runBlocking {
val metadataManga = db.getFavoriteMangaWithMetadata().executeOnIO()
2020-02-10 20:04:16 +01:00
val allManga = metadataManga.asFlow().cancellable().mapNotNull { manga ->
2020-05-02 06:46:24 +02:00
if (manga.source != EH_SOURCE_ID && manga.source != EXH_SOURCE_ID) {
2020-08-14 04:15:09 +02:00
null
} else manga
2020-02-10 20:04:16 +01:00
}.toList()
2020-08-14 04:15:09 +02:00
allManga.forEach { manga ->
val meta = db.getFlatMetadataForManga(manga.id!!).executeAsBlocking()?.raise<EHentaiSearchMetadata>() ?: return@forEach
2020-08-14 04:15:09 +02:00
// remove age flag
meta.aged = false
db.insertFlatMetadata(meta.flatten()).await()
2020-02-10 20:04:16 +01:00
}
}
}
private val throttleManager = EHentaiThrottleManager()
2020-02-10 20:04:16 +01:00
2020-10-28 00:52:32 +01:00
fun getDelegatedSourceList(): String = SourceManager.currentDelegatedSources.map { it.value.sourceName + " : " + it.value.sourceId + " : " + it.value.factory }.joinToString(separator = "\n")
fun resetEHGalleriesForUpdater() {
throttleManager.resetThrottle()
runBlocking {
val metadataManga = db.getFavoriteMangaWithMetadata().executeOnIO()
val allManga = metadataManga.asFlow().cancellable().mapNotNull { manga ->
if (manga.source != EH_SOURCE_ID && manga.source != EXH_SOURCE_ID) {
2020-08-14 04:15:09 +02:00
null
} else manga
}.toList()
2020-08-14 04:15:09 +02:00
val eh = sourceManager.get(EH_SOURCE_ID)
val ex = sourceManager.get(EXH_SOURCE_ID)
2020-08-14 04:15:09 +02:00
allManga.forEach { manga ->
throttleManager.throttle()
2020-08-14 04:15:09 +02:00
(
when (manga.source) {
EH_SOURCE_ID -> eh
EXH_SOURCE_ID -> ex
else -> return@forEach
}
)?.getMangaDetails(manga.toMangaInfo())?.let { networkManga ->
manga.copyFrom(networkManga.toSManga())
2020-08-14 04:15:09 +02:00
manga.initialized = true
db.insertManga(manga).executeAsBlocking()
}
}
}
}
fun getEHMangaListWithAgedFlagInfo(): String {
2020-05-17 01:44:12 +02:00
val galleries = mutableListOf(String())
runBlocking {
val metadataManga = db.getFavoriteMangaWithMetadata().executeOnIO()
2020-05-17 01:44:12 +02:00
val allManga = metadataManga.asFlow().cancellable().mapNotNull { manga ->
if (manga.source != EH_SOURCE_ID && manga.source != EXH_SOURCE_ID) {
2020-08-14 04:15:09 +02:00
null
} else manga
2020-05-17 01:44:12 +02:00
}.toList()
2020-08-14 04:15:09 +02:00
allManga.forEach { manga ->
val meta = db.getFlatMetadataForManga(manga.id!!).executeAsBlocking()?.raise<EHentaiSearchMetadata>() ?: return@forEach
2020-08-14 04:15:09 +02:00
galleries += "Aged: ${meta.aged}\t Title: ${manga.title}"
2020-05-17 01:44:12 +02:00
}
}
return galleries.joinToString(",\n")
}
fun countAgedFlagInEXHManga(): Int {
var agedAmount = 0
runBlocking {
val metadataManga = db.getFavoriteMangaWithMetadata().executeAsBlocking()
2020-05-17 01:44:12 +02:00
val allManga = metadataManga.asFlow().cancellable().mapNotNull { manga ->
if (manga.source != EH_SOURCE_ID && manga.source != EXH_SOURCE_ID) {
2020-08-14 04:15:09 +02:00
null
} else manga
2020-05-17 01:44:12 +02:00
}.toList()
2020-08-14 04:15:09 +02:00
allManga.forEach { manga ->
val meta = db.getFlatMetadataForManga(manga.id!!).executeAsBlocking()?.raise<EHentaiSearchMetadata>() ?: return@forEach
2020-08-14 04:15:09 +02:00
if (meta.aged) {
2020-05-17 01:44:12 +02:00
// remove age flag
agedAmount++
}
}
}
return agedAmount
}
fun addAllMangaInDatabaseToLibrary() {
db.inTransaction {
2020-05-02 06:46:24 +02:00
db.lowLevel().executeSQL(
RawQuery.builder()
.query(
"""
UPDATE ${MangaTable.TABLE}
SET ${MangaTable.COL_FAVORITE} = 1
""".trimIndent()
)
.affectsTables(MangaTable.TABLE)
2020-05-02 06:46:24 +02:00
.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
}
2020-11-30 20:35:31 +01:00
fun clearSavedSearches() = prefs.savedSearches().set(emptySet())
2019-04-14 18:12:58 +02:00
fun listAllSources() = sourceManager.getCatalogueSources().joinToString("\n") {
2019-04-14 18:12:58 +02:00
"${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()})"
}
2019-04-14 18:12:58 +02:00
fun convertAllEhentaiGalleriesToExhentai() = convertSources(EH_SOURCE_ID, EXH_SOURCE_ID)
fun convertAllExhentaiGalleriesToEhentai() = convertSources(EXH_SOURCE_ID, EH_SOURCE_ID)
2020-05-17 01:44:12 +02:00
fun testLaunchEhentaiBackgroundUpdater(): String {
return EHentaiUpdateWorker.launchBackgroundTest(app)
2019-04-18 23:40:13 +02:00
}
fun rescheduleEhentaiBackgroundUpdater() {
2020-04-22 23:26:46 +02:00
EHentaiUpdateWorker.scheduleBackground(app)
}
2020-04-22 23:26:46 +02:00
fun listScheduledJobs() = app.jobScheduler.allPendingJobs.map { j ->
"""
2020-05-02 06:46:24 +02:00
{
info: ${j.id},
isPeriod: ${j.isPeriodic},
isPersisted: ${j.isPersisted},
intervalMillis: ${j.intervalMillis},
}
2020-04-22 23:26:46 +02:00
""".trimIndent()
}.joinToString(",\n")
2020-04-22 23:26:46 +02:00
fun cancelAllScheduledJobs() = app.jobScheduler.cancelAll()
2019-04-14 18:12:58 +02:00
private fun convertSources(from: Long, to: Long) {
2020-05-02 06:46:24 +02:00
db.lowLevel().executeSQL(
RawQuery.builder()
.query(
"""
UPDATE ${MangaTable.TABLE}
SET ${MangaTable.COL_SOURCE} = $to
WHERE ${MangaTable.COL_SOURCE} = $from
""".trimIndent()
)
2019-04-14 18:12:58 +02:00
.affectsTables(MangaTable.TABLE)
2020-05-02 06:46:24 +02:00
.build()
)
2019-04-14 18:12:58 +02:00
}
fun copyEHentaiSavedSearchesToExhentai() {
runBlocking {
2020-08-14 04:15:09 +02:00
val source = sourceManager.get(EH_SOURCE_ID) as? CatalogueSource ?: return@runBlocking
val newSource = sourceManager.get(EXH_SOURCE_ID) as? CatalogueSource ?: return@runBlocking
2020-11-30 20:35:31 +01:00
val savedSearches = prefs.savedSearches().get().mapNotNull {
try {
val id = it.substringBefore(':').toLong()
if (id != source.id) return@mapNotNull null
Json.decodeFromString<JsonSavedSearch>(it.substringAfter(':'))
} catch (t: RuntimeException) {
// Load failed
2020-11-25 21:57:05 +01:00
XLog.tag("DebugFunctions").e("Failed to load saved search!", t)
t.printStackTrace()
null
}
}.toMutableList()
2020-11-30 20:35:31 +01:00
savedSearches += prefs.savedSearches().get().mapNotNull {
try {
val id = it.substringBefore(':').toLong()
if (id != newSource.id) return@mapNotNull null
Json.decodeFromString<JsonSavedSearch>(it.substringAfter(':'))
} catch (t: RuntimeException) {
// Load failed
2020-11-25 21:57:05 +01:00
XLog.tag("DebugFunctions").e("Failed to load saved search!", t)
t.printStackTrace()
null
}
}.filterNot { newSavedSearch -> savedSearches.any { it.name == newSavedSearch.name } }
2020-11-30 20:35:31 +01:00
val otherSerialized = prefs.savedSearches().get().filter {
!it.startsWith("${newSource.id}:")
}
val newSerialized = savedSearches.map {
"${newSource.id}:" + Json.encodeToString(it)
}
2020-11-30 20:35:31 +01:00
prefs.savedSearches().set((otherSerialized + newSerialized).toSet())
}
}
fun copyExhentaiSavedSearchesToEHentai() {
runBlocking {
2020-08-14 04:15:09 +02:00
val source = sourceManager.get(EXH_SOURCE_ID) as? CatalogueSource ?: return@runBlocking
val newSource = sourceManager.get(EH_SOURCE_ID) as? CatalogueSource ?: return@runBlocking
2020-11-30 20:35:31 +01:00
val savedSearches = prefs.savedSearches().get().mapNotNull {
try {
val id = it.substringBefore(':').toLong()
if (id != source.id) return@mapNotNull null
Json.decodeFromString<JsonSavedSearch>(it.substringAfter(':'))
} catch (t: RuntimeException) {
// Load failed
2020-11-25 21:57:05 +01:00
XLog.tag("DebugFunctions").e("Failed to load saved search!", t)
t.printStackTrace()
null
}
}.toMutableList()
2020-11-30 20:35:31 +01:00
savedSearches += prefs.savedSearches().get().mapNotNull {
try {
val id = it.substringBefore(':').toLong()
if (id != newSource.id) return@mapNotNull null
Json.decodeFromString<JsonSavedSearch>(it.substringAfter(':'))
} catch (t: RuntimeException) {
// Load failed
2020-11-25 21:57:05 +01:00
XLog.tag("DebugFunctions").e("Failed to load saved search!", t)
t.printStackTrace()
null
}
}.filterNot { newSavedSearch -> savedSearches.any { it.name == newSavedSearch.name } }
2020-11-30 20:35:31 +01:00
val otherSerialized = prefs.savedSearches().get().filter {
!it.startsWith("${newSource.id}:")
}
val newSerialized = savedSearches.map {
"${newSource.id}:" + Json.encodeToString(it)
}
2020-11-30 20:35:31 +01:00
prefs.savedSearches().set((otherSerialized + newSerialized).toSet())
}
}
2020-02-10 20:04:16 +01:00
}