Improve/Fix E-H redirect, add history handling, fix redirect and library handling
This commit is contained in:
parent
0680e0120f
commit
b98dc6e1a5
@ -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 <--
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
)
|
||||||
|
}
|
@ -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
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user