diff --git a/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/Chapter.kt b/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/Chapter.kt index aa187dea0..a14b937dd 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/Chapter.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/Chapter.kt @@ -100,6 +100,10 @@ object Chapter { } } } + + MangaTable.update({ MangaTable.id eq mangaId }) { + it[MangaTable.chaptersLastFetchedAt] = Instant.now().epochSecond + } } // clear any orphaned/duplicate chapters that are in the db but not in `chapterList` diff --git a/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/Manga.kt b/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/Manga.kt index 6f04fc49f..6a6ae4ca3 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/Manga.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/Manga.kt @@ -42,6 +42,7 @@ import uy.kohesive.injekt.injectLazy import java.io.File import java.io.IOException import java.io.InputStream +import java.time.Instant object Manga { private fun truncate(text: String?, maxLength: Int): String? { @@ -90,6 +91,8 @@ object Manga { it[MangaTable.realUrl] = runCatching { (source as? HttpSource)?.mangaDetailsRequest(sManga)?.url?.toString() }.getOrNull() + + it[MangaTable.lastFetchedAt] = Instant.now().epochSecond } } @@ -117,6 +120,8 @@ object Manga { getSource(mangaEntry[MangaTable.sourceReference]), getMangaMetaMap(mangaId), mangaEntry[MangaTable.realUrl], + mangaEntry[MangaTable.lastFetchedAt], + mangaEntry[MangaTable.chaptersLastFetchedAt], true ) } @@ -142,6 +147,8 @@ object Manga { getSource(mangaEntry[MangaTable.sourceReference]), getMangaMetaMap(mangaId), mangaEntry[MangaTable.realUrl], + mangaEntry[MangaTable.lastFetchedAt], + mangaEntry[MangaTable.chaptersLastFetchedAt], false ) diff --git a/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/MangaList.kt b/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/MangaList.kt index 7f19b2c42..3aa66c3e3 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/MangaList.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/MangaList.kt @@ -88,6 +88,8 @@ object MangaList { 0, meta = getMangaMetaMap(mangaId), realUrl = mangaEntry[MangaTable.realUrl], + lastFetchedAt = mangaEntry[MangaTable.lastFetchedAt], + chaptersLastFetchedAt = mangaEntry[MangaTable.chaptersLastFetchedAt], freshData = true ) } else { @@ -111,6 +113,8 @@ object MangaList { mangaEntry[MangaTable.inLibraryAt], meta = getMangaMetaMap(mangaId), realUrl = mangaEntry[MangaTable.realUrl], + lastFetchedAt = mangaEntry[MangaTable.lastFetchedAt], + chaptersLastFetchedAt = mangaEntry[MangaTable.chaptersLastFetchedAt], freshData = false ) } diff --git a/server/src/main/kotlin/suwayomi/tachidesk/manga/model/dataclass/MangaDataClass.kt b/server/src/main/kotlin/suwayomi/tachidesk/manga/model/dataclass/MangaDataClass.kt index 3ce843e40..9c3a9de82 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/manga/model/dataclass/MangaDataClass.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/manga/model/dataclass/MangaDataClass.kt @@ -9,6 +9,7 @@ package suwayomi.tachidesk.manga.model.dataclass import suwayomi.tachidesk.manga.impl.util.lang.trimAll import suwayomi.tachidesk.manga.model.table.MangaStatus +import java.time.Instant data class MangaDataClass( val id: Int, @@ -33,11 +34,16 @@ data class MangaDataClass( val meta: Map = emptyMap(), val realUrl: String? = null, + var lastFetchedAt: Long? = 0, + var chaptersLastFetchedAt: Long? = 0, val freshData: Boolean = false, var unreadCount: Int? = null, var downloadCount: Int? = null, - var chapterCount: Int? = null + var chapterCount: Int? = null, + + val age: Long? = if (lastFetchedAt == null) 0 else Instant.now().epochSecond.minus(lastFetchedAt), + val chaptersAge: Long? = if (chaptersLastFetchedAt == null) null else Instant.now().epochSecond.minus(chaptersLastFetchedAt) ) data class PagedMangaListDataClass( diff --git a/server/src/main/kotlin/suwayomi/tachidesk/manga/model/table/MangaTable.kt b/server/src/main/kotlin/suwayomi/tachidesk/manga/model/table/MangaTable.kt index 4a3798d88..792b30f73 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/manga/model/table/MangaTable.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/manga/model/table/MangaTable.kt @@ -38,6 +38,9 @@ object MangaTable : IntIdTable() { /** the real url of a manga used for the "open in WebView" feature */ val realUrl = varchar("real_url", 2048).nullable() + + val lastFetchedAt = long("last_fetched_at").default(0) + val chaptersLastFetchedAt = long("chapters_last_fetched_at").default(0) } fun MangaTable.toDataClass(mangaEntry: ResultRow) = @@ -59,7 +62,9 @@ fun MangaTable.toDataClass(mangaEntry: ResultRow) = mangaEntry[inLibrary], mangaEntry[inLibraryAt], meta = getMangaMetaMap(mangaEntry[id].value), - realUrl = mangaEntry[realUrl] + realUrl = mangaEntry[realUrl], + lastFetchedAt = mangaEntry[lastFetchedAt], + chaptersLastFetchedAt = mangaEntry[chaptersLastFetchedAt] ) enum class MangaStatus(val value: Int) { diff --git a/server/src/main/kotlin/suwayomi/tachidesk/server/database/migration/M0020_AddMangaLastFetchedAtColumns.kt b/server/src/main/kotlin/suwayomi/tachidesk/server/database/migration/M0020_AddMangaLastFetchedAtColumns.kt new file mode 100644 index 000000000..9422626b1 --- /dev/null +++ b/server/src/main/kotlin/suwayomi/tachidesk/server/database/migration/M0020_AddMangaLastFetchedAtColumns.kt @@ -0,0 +1,18 @@ +package suwayomi.tachidesk.server.database.migration + +/* + * Copyright (C) Contributors to the Suwayomi project + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +import de.neonew.exposed.migrations.helpers.SQLMigration + +@Suppress("ClassName", "unused") +class M0020_AddMangaLastFetchedAtColumns : SQLMigration() { + override val sql = """ + ALTER TABLE Manga ADD COLUMN last_fetched_at BIGINT DEFAULT 0; + ALTER TABLE Manga ADD COLUMN chapters_last_fetched_at BIGINT DEFAULT 0; + """.trimIndent() +}