Improve/Fix E-H redirect, add history handling, fix redirect and library handling

This commit is contained in:
Jobobby04 2022-02-08 19:47:40 -05:00
parent 0680e0120f
commit b98dc6e1a5
4 changed files with 118 additions and 14 deletions

View File

@ -5,6 +5,7 @@ import com.pushtorefresh.storio.sqlite.queries.RawQuery
import eu.kanade.tachiyomi.data.database.DbProvider import eu.kanade.tachiyomi.data.database.DbProvider
import eu.kanade.tachiyomi.data.database.models.History import eu.kanade.tachiyomi.data.database.models.History
import eu.kanade.tachiyomi.data.database.models.MangaChapterHistory 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.HistoryLastReadPutResolver
import eu.kanade.tachiyomi.data.database.resolvers.MangaChapterHistoryGetResolver import eu.kanade.tachiyomi.data.database.resolvers.MangaChapterHistoryGetResolver
import eu.kanade.tachiyomi.data.database.tables.HistoryTable import eu.kanade.tachiyomi.data.database.tables.HistoryTable
@ -96,4 +97,11 @@ interface HistoryQueries : DbProvider {
.build() .build()
) )
.prepare() .prepare()
// SY -->
fun updateHistoryChapterIds(history: List<History>) = db.put()
.objects(history)
.withPutResolver(HistoryChapterIdPutResolver())
.prepare()
// SY <--
} }

View File

@ -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<History>() {
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
)
}

View File

@ -255,7 +255,7 @@ class MangaPresenter(
val ourChapterUrls = chapters.map { it.url }.toSet() val ourChapterUrls = chapters.map { it.url }.toSet()
val acceptedChapterUrls = acceptedChain.chapters.map { it.url }.toSet() val acceptedChapterUrls = acceptedChain.chapters.map { it.url }.toSet()
val update = (ourChapterUrls - acceptedChapterUrls).isNotEmpty() val update = (ourChapterUrls - acceptedChapterUrls).isNotEmpty()
redirectFlow.tryEmit( redirectFlow.emit(
EXHRedirect( EXHRedirect(
acceptedChain.manga, acceptedChain.manga,
update update

View File

@ -3,16 +3,20 @@ package exh.eh
import android.content.Context import android.content.Context
import eu.kanade.tachiyomi.data.database.DatabaseHelper import eu.kanade.tachiyomi.data.database.DatabaseHelper
import eu.kanade.tachiyomi.data.database.models.Chapter 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.Manga
import eu.kanade.tachiyomi.data.database.models.MangaCategory import eu.kanade.tachiyomi.data.database.models.MangaCategory
import exh.util.executeOnIO 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.Flow
import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy
import java.io.File import java.io.File
data class ChapterChain(val manga: Manga, val chapters: List<Chapter>) data class ChapterChain(val manga: Manga, val chapters: List<Chapter>, val history: List<History>)
class EHentaiUpdateHelper(context: Context) { class EHentaiUpdateHelper(context: Context) {
val parentLookupTable = val parentLookupTable =
@ -38,10 +42,22 @@ class EHentaiUpdateHelper(context: Context) {
.map { mangaIds -> .map { mangaIds ->
mangaIds mangaIds
.mapNotNull { mangaId -> .mapNotNull { mangaId ->
(db.getManga(mangaId).executeOnIO() ?: return@mapNotNull null) to db.getChapters(mangaId).executeOnIO() 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()
)
} }
.map {
ChapterChain(it.first, it.second)
} }
.filter { it.manga.source == sourceId } .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 toDiscard = chains.filter { it.manga.favorite && it.manga.id != accepted.manga.id }
val chainsAsChapters = chains.flatMap { it.chapters } val chainsAsChapters = chains.flatMap { it.chapters }
val chainsAsHistory = chains.flatMap { it.history }
if (toDiscard.isNotEmpty()) { if (toDiscard.isNotEmpty()) {
// Copy chain chapters to curChapters // Copy chain chapters to curChapters
val (newChapters, new) = getChapterList(accepted, toDiscard, chainsAsChapters) val (newChapters, new) = getChapterList(accepted, toDiscard, chainsAsChapters)
val (history, urlHistory) = getHistory(newChapters, chainsAsChapters, chainsAsHistory)
toDiscard.forEach { toDiscard.forEach {
it.manga.favorite = false it.manga.favorite = false
it.manga.date_added = 0 it.manga.date_added = 0
} }
if (!accepted.manga.favorite) {
accepted.manga.favorite = true accepted.manga.favorite = true
accepted.manga.date_added = System.currentTimeMillis() 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 val rootsToMutate = toDiscard + newAccepted
db.inTransaction { db.inTransaction {
// Apply changes to all manga // Apply changes to all manga
db.insertMangas(rootsToMutate.map { it.manga }).executeAsBlocking() db.insertMangas(rootsToMutate.map { it.manga }).executeAsBlocking()
// Insert new chapters for accepted manga // 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 // Copy categories from all chains to accepted manga
val newCategories = rootsToMutate.flatMap { val newCategories = rootsToMutate.flatMap {
db.getCategoriesForManga(it.manga).executeAsBlocking() db.getCategoriesForManga(it.manga).executeAsBlocking()
@ -100,7 +136,35 @@ class EHentaiUpdateHelper(context: Context) {
} }
} }
private fun getChapterList(accepted: ChapterChain, toDiscard: List<ChapterChain>, chainsAsChapters: List<Chapter>): Pair<List<Chapter>, Boolean> { private fun getHistory(
newChapters: List<Chapter>,
chainsAsChapters: List<Chapter>,
chainsAsHistory: List<History>
): Pair<List<History>, List<Pair<String, History>>> {
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<ChapterChain>,
chainsAsChapters: List<Chapter>
): Pair<List<Chapter>, Boolean> {
var new = false var new = false
return toDiscard return toDiscard
.flatMap { chain -> .flatMap { chain ->
@ -139,11 +203,11 @@ class EHentaiUpdateHelper(context: Context) {
} }
} }
.sortedBy { it.date_upload } .sortedBy { it.date_upload }
.apply { .let { chapters ->
mapIndexed { index, chapter -> chapters.onEachIndexed { index, chapter ->
chapter.name = "v${index + 1}: " + chapter.name.substringAfter(" ") chapter.name = "v${index + 1}: " + chapter.name.substringAfter(" ")
chapter.chapter_number = index + 1f chapter.chapter_number = index + 1f
chapter.source_order = lastIndex - index chapter.source_order = chapters.lastIndex - index
} }
} to new } to new
} }