From 5d9173d3f7c68be44d78223cbd5f4b5901afe3ac Mon Sep 17 00:00:00 2001 From: Aria Moradi Date: Wed, 20 Jan 2021 00:04:12 +0330 Subject: [PATCH] pages api done --- .../eu/kanade/tachiyomi/source/model/Page.kt | 4 +- .../kanade/tachiyomi/source/model/SChapter.kt | 2 +- .../main/kotlin/ir/armor/tachidesk/Main.kt | 7 +- .../ir/armor/tachidesk/database/DBMangaer.kt | 2 + .../database/dataclass/ChapterDataClass.kt | 4 +- .../database/dataclass/PageDataClass.kt | 6 ++ .../tachidesk/database/table/ChapterTable.kt | 14 +++ .../kotlin/ir/armor/tachidesk/util/Chapter.kt | 87 +++++++++++++++++++ .../kotlin/ir/armor/tachidesk/util/Manga.kt | 22 ----- webUI/react/src/components/ChapterCard.tsx | 7 +- webUI/react/src/screens/Manga.tsx | 2 +- webUI/react/src/typings.d.ts | 4 +- 12 files changed, 128 insertions(+), 33 deletions(-) create mode 100644 server/src/main/kotlin/ir/armor/tachidesk/database/dataclass/PageDataClass.kt create mode 100644 server/src/main/kotlin/ir/armor/tachidesk/database/table/ChapterTable.kt create mode 100644 server/src/main/kotlin/ir/armor/tachidesk/util/Chapter.kt diff --git a/server/src/main/kotlin/eu/kanade/tachiyomi/source/model/Page.kt b/server/src/main/kotlin/eu/kanade/tachiyomi/source/model/Page.kt index 16f099a..2590bd0 100644 --- a/server/src/main/kotlin/eu/kanade/tachiyomi/source/model/Page.kt +++ b/server/src/main/kotlin/eu/kanade/tachiyomi/source/model/Page.kt @@ -1,6 +1,6 @@ package eu.kanade.tachiyomi.source.model -//import android.net.Uri +import android.net.Uri import eu.kanade.tachiyomi.network.ProgressListener import rx.subjects.Subject @@ -8,7 +8,7 @@ open class Page( val index: Int, val url: String = "", var imageUrl: String? = null, -// @Transient var uri: Uri? = null // Deprecated but can't be deleted due to extensions + @Transient var uri: Uri? = null // Deprecated but can't be deleted due to extensions ): ProgressListener { val number: Int diff --git a/server/src/main/kotlin/eu/kanade/tachiyomi/source/model/SChapter.kt b/server/src/main/kotlin/eu/kanade/tachiyomi/source/model/SChapter.kt index f53bbe8..43ad954 100644 --- a/server/src/main/kotlin/eu/kanade/tachiyomi/source/model/SChapter.kt +++ b/server/src/main/kotlin/eu/kanade/tachiyomi/source/model/SChapter.kt @@ -12,7 +12,7 @@ interface SChapter : Serializable { var chapter_number: Float - var scanlator: String? + var scanlator: String? fun copyFrom(other: SChapter) { name = other.name diff --git a/server/src/main/kotlin/ir/armor/tachidesk/Main.kt b/server/src/main/kotlin/ir/armor/tachidesk/Main.kt index 9020780..65cb55b 100644 --- a/server/src/main/kotlin/ir/armor/tachidesk/Main.kt +++ b/server/src/main/kotlin/ir/armor/tachidesk/Main.kt @@ -76,12 +76,15 @@ class Main { ctx.json(getManga(mangaId)) } - app.get("/api/v1/chapters/:mangaId/") { ctx -> + app.get("/api/v1/manga/:mangaId/chapters") { ctx -> val mangaId = ctx.pathParam("mangaId").toInt() ctx.json(getChapterList(mangaId)) } - + app.get("/api/v1/chapter/:chapterId") { ctx -> + val chapterId = ctx.pathParam("chapterId").toInt() + ctx.json(getPages(chapterId)) + } } diff --git a/server/src/main/kotlin/ir/armor/tachidesk/database/DBMangaer.kt b/server/src/main/kotlin/ir/armor/tachidesk/database/DBMangaer.kt index ed833e6..1a83571 100644 --- a/server/src/main/kotlin/ir/armor/tachidesk/database/DBMangaer.kt +++ b/server/src/main/kotlin/ir/armor/tachidesk/database/DBMangaer.kt @@ -1,6 +1,7 @@ package ir.armor.tachidesk.database import ir.armor.tachidesk.Config +import ir.armor.tachidesk.database.table.ChapterTable import ir.armor.tachidesk.database.table.ExtensionsTable import ir.armor.tachidesk.database.table.MangaTable import ir.armor.tachidesk.database.table.SourceTable @@ -22,5 +23,6 @@ fun makeDataBaseTables() { SchemaUtils.create(ExtensionsTable) SchemaUtils.create(SourceTable) SchemaUtils.create(MangaTable) + SchemaUtils.create(ChapterTable) } } \ No newline at end of file diff --git a/server/src/main/kotlin/ir/armor/tachidesk/database/dataclass/ChapterDataClass.kt b/server/src/main/kotlin/ir/armor/tachidesk/database/dataclass/ChapterDataClass.kt index 6793172..7ff499a 100644 --- a/server/src/main/kotlin/ir/armor/tachidesk/database/dataclass/ChapterDataClass.kt +++ b/server/src/main/kotlin/ir/armor/tachidesk/database/dataclass/ChapterDataClass.kt @@ -1,9 +1,11 @@ package ir.armor.tachidesk.database.dataclass data class ChapterDataClass( + val id: Int, val url: String, val name: String, - val date_upload: String, + val date_upload: Long, val chapter_number: Float, val scanlator: String?, + val mangaId: Int, ) \ No newline at end of file diff --git a/server/src/main/kotlin/ir/armor/tachidesk/database/dataclass/PageDataClass.kt b/server/src/main/kotlin/ir/armor/tachidesk/database/dataclass/PageDataClass.kt new file mode 100644 index 0000000..a7ce55c --- /dev/null +++ b/server/src/main/kotlin/ir/armor/tachidesk/database/dataclass/PageDataClass.kt @@ -0,0 +1,6 @@ +package ir.armor.tachidesk.database.dataclass + +data class PageDataClass( + val index: Int, + var imageUrl: String, +) \ No newline at end of file diff --git a/server/src/main/kotlin/ir/armor/tachidesk/database/table/ChapterTable.kt b/server/src/main/kotlin/ir/armor/tachidesk/database/table/ChapterTable.kt new file mode 100644 index 0000000..d94fdf0 --- /dev/null +++ b/server/src/main/kotlin/ir/armor/tachidesk/database/table/ChapterTable.kt @@ -0,0 +1,14 @@ +package ir.armor.tachidesk.database.table + +import eu.kanade.tachiyomi.source.model.SManga +import org.jetbrains.exposed.dao.id.IntIdTable + +object ChapterTable : IntIdTable() { + val url = varchar("url", 2048) + val name = varchar("name", 512) + val date_upload = long("date_upload").default(0) + val chapter_number = float("chapter_number").default(-1f) + val scanlator = varchar("scanlator",128).nullable() + + val manga = reference("manga", MangaTable) +} \ No newline at end of file diff --git a/server/src/main/kotlin/ir/armor/tachidesk/util/Chapter.kt b/server/src/main/kotlin/ir/armor/tachidesk/util/Chapter.kt new file mode 100644 index 0000000..ce307ec --- /dev/null +++ b/server/src/main/kotlin/ir/armor/tachidesk/util/Chapter.kt @@ -0,0 +1,87 @@ +package ir.armor.tachidesk.util + +import eu.kanade.tachiyomi.source.model.Page +import eu.kanade.tachiyomi.source.model.SChapter +import eu.kanade.tachiyomi.source.model.SManga +import eu.kanade.tachiyomi.source.online.HttpSource +import ir.armor.tachidesk.database.dataclass.ChapterDataClass +import ir.armor.tachidesk.database.dataclass.PageDataClass +import ir.armor.tachidesk.database.entity.MangaEntity +import ir.armor.tachidesk.database.table.ChapterTable +import ir.armor.tachidesk.database.table.MangaTable +import org.jetbrains.exposed.sql.insertAndGetId +import org.jetbrains.exposed.sql.select +import org.jetbrains.exposed.sql.transactions.transaction + + +fun getChapterList(mangaId: Int): List { + val mangaDetails = getManga(mangaId) + val source = getHttpSource(mangaDetails.sourceId) + + val chapterList = source.fetchChapterList( + SManga.create().apply { + title = mangaDetails.title + url = mangaDetails.url + } + ).toBlocking().first() + + return transaction { + chapterList.forEach { fetchedChapter -> + val chapterEntry = ChapterTable.select { ChapterTable.url eq fetchedChapter.url }.firstOrNull() + if (chapterEntry == null) { + ChapterTable.insertAndGetId { + it[url] = fetchedChapter.url + it[name] = fetchedChapter.name + it[date_upload] = fetchedChapter.date_upload + it[chapter_number] = fetchedChapter.chapter_number + it[scanlator] = fetchedChapter.scanlator + + it[manga] = mangaId + } + } + } + + + return@transaction chapterList.map { + ChapterDataClass( + ChapterTable.select { ChapterTable.url eq it.url }.firstOrNull()!![ChapterTable.id].value, + it.url, + it.name, + it.date_upload, + it.chapter_number, + it.scanlator, + mangaId + ) + } + } +} + +fun getPages(chapterId: Int): List { + return transaction { + val chapterEntry = ChapterTable.select { ChapterTable.id eq chapterId }.firstOrNull()!! + val mangaId = chapterEntry[ChapterTable.manga].value + val mangaEntry = MangaTable.select { MangaTable.id eq mangaId }.firstOrNull()!! + val source = getHttpSource(mangaEntry[MangaTable.sourceReference].value) + + val pagesList = source.fetchPageList( + SChapter.create().apply { + url = chapterEntry[ChapterTable.url] + name = chapterEntry[ChapterTable.name] + } + ).toBlocking().first() + + return@transaction pagesList.map { + PageDataClass( + it.index, + getTrueImageUrl(it,source) + ) + } + } + +} + +fun getTrueImageUrl(page: Page, source: HttpSource): String { + return if ( page.imageUrl == null){ + source.fetchImageUrl(page).toBlocking().first()!! + } else page.imageUrl!! +} diff --git a/server/src/main/kotlin/ir/armor/tachidesk/util/Manga.kt b/server/src/main/kotlin/ir/armor/tachidesk/util/Manga.kt index ca6f1ec..623ce61 100644 --- a/server/src/main/kotlin/ir/armor/tachidesk/util/Manga.kt +++ b/server/src/main/kotlin/ir/armor/tachidesk/util/Manga.kt @@ -1,7 +1,6 @@ package ir.armor.tachidesk.util import eu.kanade.tachiyomi.source.model.SManga -import ir.armor.tachidesk.database.dataclass.ChapterDataClass import ir.armor.tachidesk.database.dataclass.MangaDataClass import ir.armor.tachidesk.database.table.MangaStatus import ir.armor.tachidesk.database.table.MangaTable @@ -77,24 +76,3 @@ fun getManga(mangaId: Int): MangaDataClass { } } -fun getChapterList(mangaId: Int): List { - val mangaDetails = getManga(mangaId) - val source = getHttpSource(mangaDetails.sourceId) - - val chapterList = source.fetchChapterList( - SManga.create().apply { - title = mangaDetails.title - url = mangaDetails.url - } - ).toBlocking().first() - - return chapterList.map { - ChapterDataClass( - it.url, - it.name, - it.date_upload.toString(), - it.chapter_number, - it.scanlator, - ) - } -} \ No newline at end of file diff --git a/webUI/react/src/components/ChapterCard.tsx b/webUI/react/src/components/ChapterCard.tsx index 2b43f43..be3b05f 100644 --- a/webUI/react/src/components/ChapterCard.tsx +++ b/webUI/react/src/components/ChapterCard.tsx @@ -39,6 +39,8 @@ export default function ChapterCard(props: IProps) { const classes = useStyles(); const { chapter } = props; + const dateStr = chapter.date_upload && new Date(chapter.date_upload).toISOString().slice(0, 10); + return ( <>
  • @@ -53,13 +55,12 @@ export default function ChapterCard(props: IProps) { {chapter.scanlator} {chapter.scanlator && ' '} - {chapter.date_upload - && new Date(chapter.date_upload).toISOString().slice(0, 10)} + {dateStr}
    - +
    diff --git a/webUI/react/src/screens/Manga.tsx b/webUI/react/src/screens/Manga.tsx index 5b23746..52ed6cb 100644 --- a/webUI/react/src/screens/Manga.tsx +++ b/webUI/react/src/screens/Manga.tsx @@ -16,7 +16,7 @@ export default function Manga() { }, []); useEffect(() => { - fetch(`http://127.0.0.1:4567/api/v1/chapters/${id}/`) + fetch(`http://127.0.0.1:4567/api/v1/manga/${id}/chapters`) .then((response) => response.json()) .then((data) => setChapters(data)); }, []); diff --git a/webUI/react/src/typings.d.ts b/webUI/react/src/typings.d.ts index 50bf420..d064afc 100644 --- a/webUI/react/src/typings.d.ts +++ b/webUI/react/src/typings.d.ts @@ -23,9 +23,11 @@ interface IManga { } interface IChapter { + id: number url: string name: string - date_upload: string + date_upload: number chapter_number: number scanlator: String + mangaId: number }