From b98dc6e1a54ae4053378ee6dac4de49f96b9ab37 Mon Sep 17 00:00:00 2001 From: Jobobby04 Date: Tue, 8 Feb 2022 19:47:40 -0500 Subject: [PATCH] Improve/Fix E-H redirect, add history handling, fix redirect and library handling --- .../data/database/queries/HistoryQueries.kt | 8 ++ .../resolvers/HistoryChapterIdPutResolver.kt | 32 +++++++ .../tachiyomi/ui/manga/MangaPresenter.kt | 2 +- .../main/java/exh/eh/EHentaiUpdateHelper.kt | 90 ++++++++++++++++--- 4 files changed, 118 insertions(+), 14 deletions(-) create mode 100644 app/src/main/java/eu/kanade/tachiyomi/data/database/resolvers/HistoryChapterIdPutResolver.kt diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/database/queries/HistoryQueries.kt b/app/src/main/java/eu/kanade/tachiyomi/data/database/queries/HistoryQueries.kt index bcf27cc29..97c9ef75d 100755 --- a/app/src/main/java/eu/kanade/tachiyomi/data/database/queries/HistoryQueries.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/database/queries/HistoryQueries.kt @@ -5,6 +5,7 @@ import com.pushtorefresh.storio.sqlite.queries.RawQuery import eu.kanade.tachiyomi.data.database.DbProvider import eu.kanade.tachiyomi.data.database.models.History import eu.kanade.tachiyomi.data.database.models.MangaChapterHistory +import eu.kanade.tachiyomi.data.database.resolvers.HistoryChapterIdPutResolver import eu.kanade.tachiyomi.data.database.resolvers.HistoryLastReadPutResolver import eu.kanade.tachiyomi.data.database.resolvers.MangaChapterHistoryGetResolver import eu.kanade.tachiyomi.data.database.tables.HistoryTable @@ -96,4 +97,11 @@ interface HistoryQueries : DbProvider { .build() ) .prepare() + + // SY --> + fun updateHistoryChapterIds(history: List) = db.put() + .objects(history) + .withPutResolver(HistoryChapterIdPutResolver()) + .prepare() + // SY <-- } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/database/resolvers/HistoryChapterIdPutResolver.kt b/app/src/main/java/eu/kanade/tachiyomi/data/database/resolvers/HistoryChapterIdPutResolver.kt new file mode 100644 index 000000000..f6b6c71dc --- /dev/null +++ b/app/src/main/java/eu/kanade/tachiyomi/data/database/resolvers/HistoryChapterIdPutResolver.kt @@ -0,0 +1,32 @@ +package eu.kanade.tachiyomi.data.database.resolvers + +import androidx.core.content.contentValuesOf +import com.pushtorefresh.storio.sqlite.StorIOSQLite +import com.pushtorefresh.storio.sqlite.operations.put.PutResolver +import com.pushtorefresh.storio.sqlite.operations.put.PutResult +import com.pushtorefresh.storio.sqlite.queries.UpdateQuery +import eu.kanade.tachiyomi.data.database.inTransactionReturn +import eu.kanade.tachiyomi.data.database.models.History +import eu.kanade.tachiyomi.data.database.tables.HistoryTable + +class HistoryChapterIdPutResolver : PutResolver() { + + override fun performPut(db: StorIOSQLite, history: History) = db.inTransactionReturn { + val updateQuery = mapToUpdateQuery(history) + val contentValues = mapToContentValues(history) + + val numberOfRowsUpdated = db.lowLevel().update(updateQuery, contentValues) + PutResult.newUpdateResult(numberOfRowsUpdated, updateQuery.table()) + } + + fun mapToUpdateQuery(history: History) = UpdateQuery.builder() + .table(HistoryTable.TABLE) + .where("${HistoryTable.COL_ID} = ?") + .whereArgs(history.id) + .build() + + fun mapToContentValues(history: History) = + contentValuesOf( + HistoryTable.COL_CHAPTER_ID to history.chapter_id + ) +} diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaPresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaPresenter.kt index 98e268979..87acddd6c 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaPresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaPresenter.kt @@ -255,7 +255,7 @@ class MangaPresenter( val ourChapterUrls = chapters.map { it.url }.toSet() val acceptedChapterUrls = acceptedChain.chapters.map { it.url }.toSet() val update = (ourChapterUrls - acceptedChapterUrls).isNotEmpty() - redirectFlow.tryEmit( + redirectFlow.emit( EXHRedirect( acceptedChain.manga, update diff --git a/app/src/main/java/exh/eh/EHentaiUpdateHelper.kt b/app/src/main/java/exh/eh/EHentaiUpdateHelper.kt index b59e924db..d6b27d666 100644 --- a/app/src/main/java/exh/eh/EHentaiUpdateHelper.kt +++ b/app/src/main/java/exh/eh/EHentaiUpdateHelper.kt @@ -3,16 +3,20 @@ package exh.eh import android.content.Context import eu.kanade.tachiyomi.data.database.DatabaseHelper import eu.kanade.tachiyomi.data.database.models.Chapter +import eu.kanade.tachiyomi.data.database.models.History import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.database.models.MangaCategory import exh.util.executeOnIO +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.async +import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.map import uy.kohesive.injekt.injectLazy import java.io.File -data class ChapterChain(val manga: Manga, val chapters: List) +data class ChapterChain(val manga: Manga, val chapters: List, val history: List) class EHentaiUpdateHelper(context: Context) { val parentLookupTable = @@ -38,10 +42,22 @@ class EHentaiUpdateHelper(context: Context) { .map { mangaIds -> mangaIds .mapNotNull { mangaId -> - (db.getManga(mangaId).executeOnIO() ?: return@mapNotNull null) to db.getChapters(mangaId).executeOnIO() - } - .map { - ChapterChain(it.first, it.second) + coroutineScope { + val manga = async(Dispatchers.IO) { + db.getManga(mangaId).executeAsBlocking() + } + val chapterList = async(Dispatchers.IO) { + db.getChapters(mangaId).executeAsBlocking() + } + val history = async(Dispatchers.IO) { + db.getHistoryByMangaId(mangaId).executeAsBlocking() + } + ChapterChain( + manga.await() ?: return@coroutineScope null, + chapterList.await(), + history.await() + ) + } } .filter { it.manga.source == sourceId } } @@ -57,26 +73,46 @@ class EHentaiUpdateHelper(context: Context) { val toDiscard = chains.filter { it.manga.favorite && it.manga.id != accepted.manga.id } val chainsAsChapters = chains.flatMap { it.chapters } + val chainsAsHistory = chains.flatMap { it.history } if (toDiscard.isNotEmpty()) { // Copy chain chapters to curChapters val (newChapters, new) = getChapterList(accepted, toDiscard, chainsAsChapters) + val (history, urlHistory) = getHistory(newChapters, chainsAsChapters, chainsAsHistory) toDiscard.forEach { it.manga.favorite = false it.manga.date_added = 0 } - accepted.manga.favorite = true - accepted.manga.date_added = System.currentTimeMillis() + if (!accepted.manga.favorite) { + accepted.manga.favorite = true + accepted.manga.date_added = System.currentTimeMillis() + } - val newAccepted = ChapterChain(accepted.manga, newChapters) + val newAccepted = ChapterChain(accepted.manga, newChapters, history + urlHistory.map { it.second }) val rootsToMutate = toDiscard + newAccepted db.inTransaction { // Apply changes to all manga db.insertMangas(rootsToMutate.map { it.manga }).executeAsBlocking() // Insert new chapters for accepted manga - db.insertChapters(newAccepted.chapters).executeAsBlocking() + val chapterPutResults = db.insertChapters(newAccepted.chapters).executeAsBlocking().results() + + // Get a updated history list + val newHistory = urlHistory.mapNotNull { (url, history) -> + val result = chapterPutResults.firstNotNullOfOrNull { (chapter, result) -> + if (chapter.url == url) { + result.insertedId() + } else null + } + if (result != null) { + history.chapter_id = result + history + } else null + } + history + // Copy the new history chapter ids + db.updateHistoryChapterIds(newHistory).executeAsBlocking() + // Copy categories from all chains to accepted manga val newCategories = rootsToMutate.flatMap { db.getCategoriesForManga(it.manga).executeAsBlocking() @@ -100,7 +136,35 @@ class EHentaiUpdateHelper(context: Context) { } } - private fun getChapterList(accepted: ChapterChain, toDiscard: List, chainsAsChapters: List): Pair, Boolean> { + private fun getHistory( + newChapters: List, + chainsAsChapters: List, + chainsAsHistory: List + ): Pair, List>> { + return chainsAsHistory.filter { history -> + val oldChapter = chainsAsChapters.find { it.id == history.chapter_id } + val newChapter = newChapters.find { it.url == oldChapter?.url } + if (oldChapter != newChapter && newChapter?.id != null) { + history.chapter_id = newChapter.id!! + true + } else false + } to chainsAsHistory.mapNotNull { history -> + val oldChapter = chainsAsChapters.find { it.id == history.chapter_id } + val newChapter = newChapters.find { it.url == oldChapter?.url } + if (oldChapter != newChapter && newChapter?.id == null) { + val url = newChapter?.url ?: return@mapNotNull null + url to history + } else { + null + } + } + } + + private fun getChapterList( + accepted: ChapterChain, + toDiscard: List, + chainsAsChapters: List + ): Pair, Boolean> { var new = false return toDiscard .flatMap { chain -> @@ -139,11 +203,11 @@ class EHentaiUpdateHelper(context: Context) { } } .sortedBy { it.date_upload } - .apply { - mapIndexed { index, chapter -> + .let { chapters -> + chapters.onEachIndexed { index, chapter -> chapter.name = "v${index + 1}: " + chapter.name.substringAfter(" ") chapter.chapter_number = index + 1f - chapter.source_order = lastIndex - index + chapter.source_order = chapters.lastIndex - index } } to new }