mirror of
https://github.com/mihonapp/mihon.git
synced 2025-11-14 13:08:56 +01:00
Update manga metadata on library update with sqldelight (#7293)
Co-Authored-By: Ivan Iskandar <12537387+ivaniskandar@users.noreply.github.com> Co-authored-by: Ivan Iskandar <12537387+ivaniskandar@users.noreply.github.com>
This commit is contained in:
@@ -20,8 +20,9 @@ import eu.kanade.domain.history.interactor.RemoveHistoryByMangaId
|
||||
import eu.kanade.domain.history.interactor.UpsertHistory
|
||||
import eu.kanade.domain.history.repository.HistoryRepository
|
||||
import eu.kanade.domain.manga.interactor.GetFavoritesBySourceId
|
||||
import eu.kanade.domain.manga.interactor.GetMangaById
|
||||
import eu.kanade.domain.manga.interactor.ResetViewerFlags
|
||||
import eu.kanade.domain.manga.interactor.UpdateMangaLastUpdate
|
||||
import eu.kanade.domain.manga.interactor.UpdateManga
|
||||
import eu.kanade.domain.manga.repository.MangaRepository
|
||||
import eu.kanade.domain.source.interactor.GetEnabledSources
|
||||
import eu.kanade.domain.source.interactor.GetLanguagesWithSources
|
||||
@@ -43,9 +44,10 @@ class DomainModule : InjektModule {
|
||||
override fun InjektRegistrar.registerInjectables() {
|
||||
addSingletonFactory<MangaRepository> { MangaRepositoryImpl(get()) }
|
||||
addFactory { GetFavoritesBySourceId(get()) }
|
||||
addFactory { GetMangaById(get()) }
|
||||
addFactory { GetNextChapter(get()) }
|
||||
addFactory { ResetViewerFlags(get()) }
|
||||
addFactory { UpdateMangaLastUpdate(get()) }
|
||||
addFactory { UpdateManga(get()) }
|
||||
|
||||
addSingletonFactory<ChapterRepository> { ChapterRepositoryImpl(get()) }
|
||||
addFactory { UpdateChapter(get()) }
|
||||
|
||||
@@ -5,7 +5,7 @@ import eu.kanade.domain.chapter.model.Chapter
|
||||
import eu.kanade.domain.chapter.model.toChapterUpdate
|
||||
import eu.kanade.domain.chapter.model.toDbChapter
|
||||
import eu.kanade.domain.chapter.repository.ChapterRepository
|
||||
import eu.kanade.domain.manga.interactor.UpdateMangaLastUpdate
|
||||
import eu.kanade.domain.manga.interactor.UpdateManga
|
||||
import eu.kanade.domain.manga.model.Manga
|
||||
import eu.kanade.domain.manga.model.toDbManga
|
||||
import eu.kanade.tachiyomi.data.download.DownloadManager
|
||||
@@ -24,7 +24,7 @@ class SyncChaptersWithSource(
|
||||
private val downloadManager: DownloadManager = Injekt.get(),
|
||||
private val chapterRepository: ChapterRepository = Injekt.get(),
|
||||
private val shouldUpdateDbChapter: ShouldUpdateDbChapter = Injekt.get(),
|
||||
private val updateMangaLastUpdate: UpdateMangaLastUpdate = Injekt.get(),
|
||||
private val updateManga: UpdateManga = Injekt.get(),
|
||||
) {
|
||||
|
||||
suspend fun await(
|
||||
@@ -171,7 +171,7 @@ class SyncChaptersWithSource(
|
||||
|
||||
// Set this manga as updated since chapters were changed
|
||||
// Note that last_update actually represents last time the chapter list changed at all
|
||||
updateMangaLastUpdate.await(manga.id, Date().time)
|
||||
updateManga.awaitUpdateLastUpdate(manga.id)
|
||||
|
||||
@Suppress("ConvertArgumentToSet") // See tachiyomiorg/tachiyomi#6372.
|
||||
return Pair(updatedToAdd.subtract(reAdded).toList(), toDelete.subtract(reAdded).toList())
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
package eu.kanade.domain.manga.interactor
|
||||
|
||||
import eu.kanade.domain.manga.model.Manga
|
||||
import eu.kanade.domain.manga.repository.MangaRepository
|
||||
import eu.kanade.tachiyomi.util.system.logcat
|
||||
import logcat.LogPriority
|
||||
|
||||
class GetMangaById(
|
||||
private val mangaRepository: MangaRepository,
|
||||
) {
|
||||
|
||||
suspend fun await(id: Long): Manga? {
|
||||
return try {
|
||||
mangaRepository.getMangaById(id)
|
||||
} catch (e: Exception) {
|
||||
logcat(LogPriority.ERROR, e)
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package eu.kanade.domain.manga.interactor
|
||||
|
||||
import eu.kanade.domain.manga.model.Manga
|
||||
import eu.kanade.domain.manga.model.MangaUpdate
|
||||
import eu.kanade.domain.manga.model.hasCustomCover
|
||||
import eu.kanade.domain.manga.model.isLocal
|
||||
import eu.kanade.domain.manga.model.toDbManga
|
||||
import eu.kanade.domain.manga.repository.MangaRepository
|
||||
import eu.kanade.tachiyomi.data.cache.CoverCache
|
||||
import tachiyomi.source.model.MangaInfo
|
||||
import java.util.Date
|
||||
|
||||
class UpdateManga(
|
||||
private val mangaRepository: MangaRepository,
|
||||
) {
|
||||
|
||||
suspend fun awaitUpdateFromSource(
|
||||
localManga: Manga,
|
||||
remoteManga: MangaInfo,
|
||||
manualFetch: Boolean,
|
||||
coverCache: CoverCache,
|
||||
): Boolean {
|
||||
// if the manga isn't a favorite, set its title from source and update in db
|
||||
val title = if (!localManga.favorite) remoteManga.title else null
|
||||
|
||||
// Never refresh covers if the url is empty to avoid "losing" existing covers
|
||||
val updateCover = remoteManga.cover.isNotEmpty() && (manualFetch || localManga.thumbnailUrl != remoteManga.cover)
|
||||
val coverLastModified = if (updateCover) {
|
||||
when {
|
||||
localManga.isLocal() -> Date().time
|
||||
localManga.hasCustomCover(coverCache) -> {
|
||||
coverCache.deleteFromCache(localManga.toDbManga(), false)
|
||||
null
|
||||
}
|
||||
else -> {
|
||||
coverCache.deleteFromCache(localManga.toDbManga(), false)
|
||||
Date().time
|
||||
}
|
||||
}
|
||||
} else null
|
||||
|
||||
return mangaRepository.update(
|
||||
MangaUpdate(
|
||||
id = localManga.id,
|
||||
title = title?.takeIf { it.isNotEmpty() },
|
||||
coverLastModified = coverLastModified,
|
||||
author = remoteManga.author,
|
||||
artist = remoteManga.artist,
|
||||
description = remoteManga.description,
|
||||
genre = remoteManga.genres,
|
||||
thumbnailUrl = remoteManga.cover.takeIf { it.isNotEmpty() },
|
||||
status = remoteManga.status.toLong(),
|
||||
initialized = true,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
suspend fun awaitUpdateLastUpdate(mangaId: Long): Boolean {
|
||||
return mangaRepository.update(MangaUpdate(id = mangaId, lastUpdate = Date().time))
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
package eu.kanade.domain.manga.interactor
|
||||
|
||||
import eu.kanade.domain.manga.repository.MangaRepository
|
||||
|
||||
class UpdateMangaLastUpdate(
|
||||
private val mangaRepository: MangaRepository,
|
||||
) {
|
||||
|
||||
suspend fun await(mangaId: Long, lastUpdate: Long) {
|
||||
mangaRepository.updateLastUpdate(mangaId, lastUpdate)
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,11 @@
|
||||
package eu.kanade.domain.manga.model
|
||||
|
||||
import eu.kanade.tachiyomi.data.cache.CoverCache
|
||||
import eu.kanade.tachiyomi.source.LocalSource
|
||||
import eu.kanade.tachiyomi.source.model.SManga
|
||||
import tachiyomi.source.model.MangaInfo
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
import eu.kanade.tachiyomi.data.database.models.Manga as DbManga
|
||||
|
||||
data class Manga(
|
||||
@@ -62,3 +67,20 @@ fun Manga.toDbManga(): DbManga = DbManga.create(url, title, source).also {
|
||||
it.chapter_flags = chapterFlags.toInt()
|
||||
it.cover_last_modified = coverLastModified
|
||||
}
|
||||
|
||||
fun Manga.toMangaInfo(): MangaInfo = MangaInfo(
|
||||
artist = artist ?: "",
|
||||
author = author ?: "",
|
||||
cover = thumbnailUrl ?: "",
|
||||
description = description ?: "",
|
||||
genres = genre ?: emptyList(),
|
||||
key = url,
|
||||
status = status.toInt(),
|
||||
title = title,
|
||||
)
|
||||
|
||||
fun Manga.isLocal(): Boolean = source == LocalSource.ID
|
||||
|
||||
fun Manga.hasCustomCover(coverCache: CoverCache = Injekt.get()): Boolean {
|
||||
return coverCache.getCustomCoverFile(id).exists()
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
package eu.kanade.domain.manga.model
|
||||
|
||||
data class MangaUpdate(
|
||||
val id: Long,
|
||||
val source: Long? = null,
|
||||
val favorite: Boolean? = null,
|
||||
val lastUpdate: Long? = null,
|
||||
val dateAdded: Long? = null,
|
||||
val viewerFlags: Long? = null,
|
||||
val chapterFlags: Long? = null,
|
||||
val coverLastModified: Long? = null,
|
||||
val url: String? = null,
|
||||
val title: String? = null,
|
||||
val artist: String? = null,
|
||||
val author: String? = null,
|
||||
val description: String? = null,
|
||||
val genre: List<String>? = null,
|
||||
val status: Long? = null,
|
||||
val thumbnailUrl: String? = null,
|
||||
val initialized: Boolean? = null,
|
||||
)
|
||||
@@ -1,13 +1,16 @@
|
||||
package eu.kanade.domain.manga.repository
|
||||
|
||||
import eu.kanade.domain.manga.model.Manga
|
||||
import eu.kanade.domain.manga.model.MangaUpdate
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
interface MangaRepository {
|
||||
|
||||
suspend fun getMangaById(id: Long): Manga
|
||||
|
||||
fun getFavoritesBySourceId(sourceId: Long): Flow<List<Manga>>
|
||||
|
||||
suspend fun resetViewerFlags(): Boolean
|
||||
|
||||
suspend fun updateLastUpdate(mangaId: Long, lastUpdate: Long)
|
||||
suspend fun update(update: MangaUpdate): Boolean
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user