diff --git a/server/src/main/kotlin/ir/armor/tachidesk/Main.kt b/server/src/main/kotlin/ir/armor/tachidesk/Main.kt index 0d10ebe..0e031dd 100644 --- a/server/src/main/kotlin/ir/armor/tachidesk/Main.kt +++ b/server/src/main/kotlin/ir/armor/tachidesk/Main.kt @@ -6,8 +6,12 @@ package ir.armor.tachidesk import eu.kanade.tachiyomi.App import io.javalin.Javalin +import ir.armor.tachidesk.util.addMangaToCategory import ir.armor.tachidesk.util.addMangaToLibrary import ir.armor.tachidesk.util.applicationSetup +import ir.armor.tachidesk.util.createCategory +import ir.armor.tachidesk.util.getCategoryList +import ir.armor.tachidesk.util.getCategoryMangaList import ir.armor.tachidesk.util.getChapter import ir.armor.tachidesk.util.getChapterList import ir.armor.tachidesk.util.getExtensionIcon @@ -21,12 +25,15 @@ import ir.armor.tachidesk.util.getSourceList import ir.armor.tachidesk.util.getThumbnail import ir.armor.tachidesk.util.installAPK import ir.armor.tachidesk.util.openInBrowser +import ir.armor.tachidesk.util.removeCategory import ir.armor.tachidesk.util.removeExtension +import ir.armor.tachidesk.util.removeMangaFromCategory import ir.armor.tachidesk.util.removeMangaFromLibrary import ir.armor.tachidesk.util.sourceFilters import ir.armor.tachidesk.util.sourceGlobalSearch import ir.armor.tachidesk.util.sourceSearch import ir.armor.tachidesk.util.systemTray +import ir.armor.tachidesk.util.updateCategory import org.kodein.di.DI import org.kodein.di.conf.global import xyz.nulldev.androidcompat.AndroidCompat @@ -165,12 +172,18 @@ class Main { // adds the manga to category app.get("api/v1/manga/:mangaId/category/:categoryId") { ctx -> - // TODO + val mangaId = ctx.pathParam("mangaId").toInt() + val categoryId = ctx.pathParam("categoryId").toInt() + addMangaToCategory(mangaId, categoryId) + ctx.status(200) } // removes the manga from the category app.delete("api/v1/manga/:mangaId/category/:categoryId") { ctx -> - // TODO + val mangaId = ctx.pathParam("mangaId").toInt() + val categoryId = ctx.pathParam("categoryId").toInt() + removeMangaFromCategory(mangaId, categoryId) + ctx.status(200) } app.get("/api/v1/manga/:mangaId/chapters") { ctx -> @@ -221,22 +234,37 @@ class Main { // category list app.get("/api/v1/category/") { ctx -> - // TODO + ctx.json(getCategoryList()) } // category create app.post("/api/v1/category/") { ctx -> - // TODO + val name = ctx.formParam("name")!! + val isLanding = ctx.formParam("isLanding", "false").toBoolean() + createCategory(name, isLanding) + ctx.status(200) } // category modification - app.patch("/api/v1/category/:categoryId") { ctx -> - // TODO + app.put("/api/v1/category/:categoryId") { ctx -> + val categoryId = ctx.pathParam("categoryId").toInt() + val name = ctx.formParam("name")!! + val isLanding = ctx.formParam("isLanding").toBoolean() + updateCategory(categoryId, name, isLanding) + ctx.status(200) + } + + // category delete + app.delete("/api/v1/category/:categoryId") { ctx -> + val categoryId = ctx.pathParam("categoryId").toInt() + removeCategory(categoryId) + ctx.status(200) } // returns the manga list associated with a category app.get("/api/v1/category/:categoryId") { ctx -> - // TODO + val categoryId = ctx.pathParam("categoryId").toInt() + ctx.json(getCategoryMangaList(categoryId)) } } } 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 7625116..04ed427 100644 --- a/server/src/main/kotlin/ir/armor/tachidesk/database/DBMangaer.kt +++ b/server/src/main/kotlin/ir/armor/tachidesk/database/DBMangaer.kt @@ -5,6 +5,7 @@ package ir.armor.tachidesk.database * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ import ir.armor.tachidesk.Config +import ir.armor.tachidesk.database.table.CategoryMangaTable import ir.armor.tachidesk.database.table.CategoryTable import ir.armor.tachidesk.database.table.ChapterTable import ir.armor.tachidesk.database.table.ExtensionTable @@ -34,5 +35,6 @@ fun makeDataBaseTables() { SchemaUtils.create(ChapterTable) SchemaUtils.create(PageTable) SchemaUtils.create(CategoryTable) + SchemaUtils.create(CategoryMangaTable) } } diff --git a/server/src/main/kotlin/ir/armor/tachidesk/database/dataclass/CategoryDataClass.kt b/server/src/main/kotlin/ir/armor/tachidesk/database/dataclass/CategoryDataClass.kt new file mode 100644 index 0000000..6687b0d --- /dev/null +++ b/server/src/main/kotlin/ir/armor/tachidesk/database/dataclass/CategoryDataClass.kt @@ -0,0 +1,10 @@ +package ir.armor.tachidesk.database.dataclass + +/* 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/. */ + +data class CategoryDataClass( + val name: String, + val isLanding: Boolean +) diff --git a/server/src/main/kotlin/ir/armor/tachidesk/database/table/CategoryMangaTable.kt b/server/src/main/kotlin/ir/armor/tachidesk/database/table/CategoryMangaTable.kt new file mode 100644 index 0000000..dee38f2 --- /dev/null +++ b/server/src/main/kotlin/ir/armor/tachidesk/database/table/CategoryMangaTable.kt @@ -0,0 +1,12 @@ +package ir.armor.tachidesk.database.table + +import org.jetbrains.exposed.dao.id.IntIdTable + +/* 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/. */ + +object CategoryMangaTable : IntIdTable() { + val category = reference("category", CategoryTable) + val manga = reference("manga", MangaTable) +} diff --git a/server/src/main/kotlin/ir/armor/tachidesk/database/table/CategoryTable.kt b/server/src/main/kotlin/ir/armor/tachidesk/database/table/CategoryTable.kt index 9f7e437..ae2af4d 100644 --- a/server/src/main/kotlin/ir/armor/tachidesk/database/table/CategoryTable.kt +++ b/server/src/main/kotlin/ir/armor/tachidesk/database/table/CategoryTable.kt @@ -4,9 +4,16 @@ package ir.armor.tachidesk.database.table * 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 ir.armor.tachidesk.database.dataclass.CategoryDataClass import org.jetbrains.exposed.dao.id.IntIdTable +import org.jetbrains.exposed.sql.ResultRow object CategoryTable : IntIdTable() { val name = varchar("name", 64) val isLanding = bool("is_landing").default(false) } + +fun CategoryTable.toDataClass(categoryEntry: ResultRow) = CategoryDataClass( + categoryEntry[CategoryTable.name], + categoryEntry[CategoryTable.isLanding], +) diff --git a/server/src/main/kotlin/ir/armor/tachidesk/util/Category.kt b/server/src/main/kotlin/ir/armor/tachidesk/util/Category.kt new file mode 100644 index 0000000..80ad67d --- /dev/null +++ b/server/src/main/kotlin/ir/armor/tachidesk/util/Category.kt @@ -0,0 +1,48 @@ +package ir.armor.tachidesk.util + +import ir.armor.tachidesk.database.dataclass.CategoryDataClass +import ir.armor.tachidesk.database.table.CategoryTable +import ir.armor.tachidesk.database.table.toDataClass +import org.jetbrains.exposed.sql.deleteWhere +import org.jetbrains.exposed.sql.insert +import org.jetbrains.exposed.sql.select +import org.jetbrains.exposed.sql.selectAll +import org.jetbrains.exposed.sql.transactions.transaction +import org.jetbrains.exposed.sql.update + +/* 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/. */ + +fun createCategory(name: String, isLanding: Boolean) { + transaction { + if (CategoryTable.select { CategoryTable.name eq name }.firstOrNull() == null) + CategoryTable.insert { + it[CategoryTable.name] = name + it[CategoryTable.isLanding] = isLanding + } + } +} + +fun updateCategory(categoryId: Int, name: String, isLanding: Boolean) { + transaction { + CategoryTable.update({ CategoryTable.id eq categoryId }) { + it[CategoryTable.name] = name + it[CategoryTable.isLanding] = isLanding + } + } +} + +fun removeCategory(categoryId: Int) { + transaction { + CategoryTable.deleteWhere { CategoryTable.id eq categoryId } + } +} + +fun getCategoryList(): List { + return transaction { + CategoryTable.selectAll().map { + CategoryTable.toDataClass(it) + } + } +} diff --git a/server/src/main/kotlin/ir/armor/tachidesk/util/CategoryManga.kt b/server/src/main/kotlin/ir/armor/tachidesk/util/CategoryManga.kt new file mode 100644 index 0000000..9903f44 --- /dev/null +++ b/server/src/main/kotlin/ir/armor/tachidesk/util/CategoryManga.kt @@ -0,0 +1,40 @@ +package ir.armor.tachidesk.util + +import ir.armor.tachidesk.database.dataclass.MangaDataClass +import ir.armor.tachidesk.database.table.CategoryMangaTable +import ir.armor.tachidesk.database.table.MangaTable +import ir.armor.tachidesk.database.table.toDataClass +import org.jetbrains.exposed.sql.and +import org.jetbrains.exposed.sql.deleteWhere +import org.jetbrains.exposed.sql.insert +import org.jetbrains.exposed.sql.select +import org.jetbrains.exposed.sql.transactions.transaction + +/* 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/. */ + +fun addMangaToCategory(mangaId: Int, categoryId: Int) { + transaction { + if (CategoryMangaTable.select { (CategoryMangaTable.category eq categoryId) and (CategoryMangaTable.manga eq mangaId) }.firstOrNull() == null) { + CategoryMangaTable.insert { + it[CategoryMangaTable.category] = categoryId + it[CategoryMangaTable.manga] = mangaId + } + } + } +} + +fun removeMangaFromCategory(mangaId: Int, categoryId: Int) { + transaction { + CategoryMangaTable.deleteWhere { (CategoryMangaTable.category eq categoryId) and (CategoryMangaTable.manga eq mangaId) } + } +} + +fun getCategoryMangaList(categoryId: Int): List { + return transaction { + CategoryMangaTable.innerJoin(MangaTable).select { CategoryMangaTable.category eq categoryId }.map { + MangaTable.toDataClass(it) + } + } +}