From 65067e6e015fd2dbddd1c0dd34b3c304ef52ef8f Mon Sep 17 00:00:00 2001 From: Aria Moradi Date: Thu, 10 Nov 2022 02:13:20 +0330 Subject: [PATCH] changes needed for tachiyomi tracker --- .../suwayomi/tachidesk/manga/MangaAPI.kt | 3 ++ .../manga/controller/MangaController.kt | 26 +++++++++++- .../tachidesk/manga/impl/CategoryManga.kt | 6 +-- .../suwayomi/tachidesk/manga/impl/Manga.kt | 40 +++++++++++++++++++ .../manga/model/dataclass/MangaDataClass.kt | 7 ++-- 5 files changed, 74 insertions(+), 8 deletions(-) diff --git a/server/src/main/kotlin/suwayomi/tachidesk/manga/MangaAPI.kt b/server/src/main/kotlin/suwayomi/tachidesk/manga/MangaAPI.kt index ce7db417..db9614a3 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/manga/MangaAPI.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/manga/MangaAPI.kt @@ -12,6 +12,7 @@ import io.javalin.apibuilder.ApiBuilder.get import io.javalin.apibuilder.ApiBuilder.patch import io.javalin.apibuilder.ApiBuilder.path import io.javalin.apibuilder.ApiBuilder.post +import io.javalin.apibuilder.ApiBuilder.put import io.javalin.apibuilder.ApiBuilder.ws import suwayomi.tachidesk.manga.controller.BackupController import suwayomi.tachidesk.manga.controller.CategoryController @@ -54,6 +55,7 @@ object MangaAPI { path("manga") { get("{mangaId}", MangaController.retrieve) + get("{mangaId}/full", MangaController.retrieveFull) get("{mangaId}/thumbnail", MangaController.thumbnail) get("{mangaId}/category", MangaController.categoryList) @@ -69,6 +71,7 @@ object MangaAPI { post("{mangaId}/chapter/batch", MangaController.chapterBatch) get("{mangaId}/chapter/{chapterIndex}", MangaController.chapterRetrieve) patch("{mangaId}/chapter/{chapterIndex}", MangaController.chapterModify) + put("{mangaId}/chapter/{chapterIndex}", MangaController.chapterModify) delete("{mangaId}/chapter/{chapterIndex}", MangaController.chapterDelete) patch("{mangaId}/chapter/{chapterIndex}/meta", MangaController.chapterMeta) diff --git a/server/src/main/kotlin/suwayomi/tachidesk/manga/controller/MangaController.kt b/server/src/main/kotlin/suwayomi/tachidesk/manga/controller/MangaController.kt index 9c02fffb..8769b362 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/manga/controller/MangaController.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/manga/controller/MangaController.kt @@ -33,13 +33,12 @@ import kotlin.time.Duration.Companion.days object MangaController { private val json by DI.global.instance() - /** get manga info */ val retrieve = handler( pathParam("mangaId"), queryParam("onlineFetch", false), documentWith = { withOperation { - summary("Get a manga") + summary("Get manga info") description("Get a manga from the database using a specific id.") } }, @@ -56,6 +55,29 @@ object MangaController { } ) + /** get manga info with all data filled in */ + val retrieveFull = handler( + pathParam("mangaId"), + queryParam("onlineFetch", false), + documentWith = { + withOperation { + summary("Get manga info with all data filled in") + description("Get a manga from the database using a specific id.") + } + }, + behaviorOf = { ctx, mangaId, onlineFetch -> + ctx.future( + future { + Manga.getMangaFull(mangaId, onlineFetch) + } + ) + }, + withResults = { + json(HttpCode.OK) + httpCode(HttpCode.NOT_FOUND) + } + ) + /** manga thumbnail */ val thumbnail = handler( pathParam("mangaId"), diff --git a/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/CategoryManga.kt b/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/CategoryManga.kt index 516410cf..8e1a2f76 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/CategoryManga.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/CategoryManga.kt @@ -81,9 +81,9 @@ object CategoryManga { val transform: (ResultRow) -> MangaDataClass = { val dataClass = MangaTable.toDataClass(it) - dataClass.unreadCount = it[unreadExpression]?.toInt() - dataClass.downloadCount = it[downloadExpression]?.toInt() - dataClass.chapterCount = it[chapterCountExpression]?.toInt() + dataClass.unreadCount = it[unreadExpression] + dataClass.downloadCount = it[downloadExpression] + dataClass.chapterCount = it[chapterCountExpression] dataClass } 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 b92ff295..4778a810 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/Manga.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/Manga.kt @@ -13,6 +13,7 @@ import eu.kanade.tachiyomi.source.local.LocalSource import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.online.HttpSource import org.jetbrains.exposed.sql.ResultRow +import org.jetbrains.exposed.sql.SortOrder import org.jetbrains.exposed.sql.and import org.jetbrains.exposed.sql.insert import org.jetbrains.exposed.sql.select @@ -34,9 +35,11 @@ import suwayomi.tachidesk.manga.impl.util.storage.ImageUtil import suwayomi.tachidesk.manga.impl.util.updateMangaDownloadDir import suwayomi.tachidesk.manga.model.dataclass.MangaDataClass import suwayomi.tachidesk.manga.model.dataclass.toGenreList +import suwayomi.tachidesk.manga.model.table.ChapterTable import suwayomi.tachidesk.manga.model.table.MangaMetaTable import suwayomi.tachidesk.manga.model.table.MangaStatus import suwayomi.tachidesk.manga.model.table.MangaTable +import suwayomi.tachidesk.manga.model.table.toDataClass import suwayomi.tachidesk.server.ApplicationDirs import uy.kohesive.injekt.injectLazy import java.io.File @@ -127,6 +130,40 @@ object Manga { } } + suspend fun getMangaFull(mangaId: Int, onlineFetch: Boolean = false): MangaDataClass { + val mangaDaaClass = getManga(mangaId, onlineFetch) + + return transaction { + val unreadCount = + ChapterTable + .select { (ChapterTable.manga eq mangaId) and (ChapterTable.isRead eq false) } + .count() + + val downloadCount = + ChapterTable + .select { (ChapterTable.manga eq mangaId) and (ChapterTable.isDownloaded eq true) } + .count() + + val chapterCount = + ChapterTable + .select { (ChapterTable.manga eq mangaId) } + .count() + + val lastChapterRead = + ChapterTable + .select { (ChapterTable.manga eq mangaId) } + .orderBy(ChapterTable.sourceOrder to SortOrder.DESC) + .firstOrNull { it[ChapterTable.isRead] } + + mangaDaaClass.unreadCount = unreadCount + mangaDaaClass.downloadCount = downloadCount + mangaDaaClass.chapterCount = chapterCount + mangaDaaClass.lastChapterRead = lastChapterRead?.let { ChapterTable.toDataClass(it) } + + mangaDaaClass + } + } + private fun getMangaDataClass(mangaId: Int, mangaEntry: ResultRow) = MangaDataClass( mangaId, mangaEntry[MangaTable.sourceReference].toString(), @@ -206,6 +243,7 @@ object Manga { GET(thumbnailUrl, source.headers) ).await() } + is LocalSource -> { val imageFile = mangaEntry[MangaTable.thumbnail_url]?.let { val file = File(it) @@ -219,6 +257,7 @@ object Manga { ?: "image/jpeg" imageFile.inputStream() to contentType } + is StubSource -> getImageResponse(saveDir, fileName, useCache) { val thumbnailUrl = mangaEntry[MangaTable.thumbnail_url] ?: throw NullPointerException("No thumbnail found") @@ -226,6 +265,7 @@ object Manga { GET(thumbnailUrl) ).await() } + else -> throw IllegalArgumentException("Unknown source") } } 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 9c3a9de8..8e1e7934 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 @@ -38,9 +38,10 @@ data class MangaDataClass( var chaptersLastFetchedAt: Long? = 0, val freshData: Boolean = false, - var unreadCount: Int? = null, - var downloadCount: Int? = null, - var chapterCount: Int? = null, + var unreadCount: Long? = null, + var downloadCount: Long? = null, + var chapterCount: Long? = null, + var lastChapterRead: ChapterDataClass? = 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)