Merge branch 'master' into anime

This commit is contained in:
Aria Moradi 2021-05-27 02:16:07 +04:30
commit 921a0a3361
90 changed files with 600 additions and 475 deletions

View File

@ -12,7 +12,7 @@ import net.harawata.appdirs.AppDirsFactory
val ApplicationRootDir: String
get(): String {
return System.getProperty(
"ir.armor.tachidesk.rootDir",
"suwayomi.server.rootDir",
AppDirsFactory.getInstance().getUserDataDir("Tachidesk", null, null)
)
}

View File

@ -17,4 +17,4 @@ fun setLogLevel(level: Level) {
}
fun debugLogsEnabled(config: Config)
= System.getProperty("ir.armor.tachidesk.debugLogsEnabled", config.getString("server.debugLogsEnabled")).toBoolean()
= System.getProperty("suwayomi.server.debugLogsEnabled", config.getString("server.debugLogsEnabled")).toBoolean()

View File

@ -52,7 +52,16 @@ yay -S tachidesk
```
### Docker
Check [arbuilder's repo](https://github.com/arbuilder/Tachidesk-docker) out for more details and the dockerfile.
Check our Offical Docker release [Tachidesk Container](https://github.com/orgs/Suwayomi/packages/container/package/tachidesk) or use [arbuilder's](https://github.com/arbuilder/Tachidesk-docker) tachidesk docker repo for installation. Source code for our container is available at [docker-tachidesk](https://github.com/Suwayomi/docker-tachidesk). By default the server will be running on http://localhost:4567 open this url in your browser.
Install from the command line:
```
$ docker pull ghcr.io/suwayomi/tachidesk
```
Run Container from the command line:
```
$ docker run -p 4567:4567 ghcr.io/suwayomi/tachidesk
```
### Using Tachidesk Remotely
You can run Tachidesk on your computer or a server and connect to it remotely through the web interface with a web browser on any device including a mobile or tablet or even your smart TV!, this method of using Tachidesk is only recommended if you are a power user and know what you are doing.

View File

@ -5,7 +5,7 @@ plugins {
}
allprojects {
group = "ir.armor.tachidesk"
group = "suwayomi"
version = "1.0"

View File

@ -1 +1 @@
jre\bin\java -Dir.armor.tachidesk.debugLogsEnabled=true -jar Tachidesk.jar
jre\bin\java -Dsuwayomi.server.debugLogsEnabled=true -jar Tachidesk.jar

View File

@ -1 +1 @@
jre\bin\javaw "-Dir.armor.tachidesk.webInterface=electron" "-Dir.armor.tachidesk.electronPath=electron/electron.exe" -jar Tachidesk.jar
jre\bin\javaw "-Dsuwayomi.server.webInterface=electron" "-Dsuwayomi.server.electronPath=electron/electron.exe" -jar Tachidesk.jar

View File

@ -73,14 +73,14 @@ dependencies {
testImplementation(kotlin("test-junit5"))
}
val MainClass = "ir.armor.tachidesk.MainKt"
val MainClass = "suwayomi.MainKt"
application {
mainClass.set(MainClass)
// for testing electron
// applicationDefaultJvmArgs = listOf(
// "-Dir.armor.tachidesk.webInterface=electron",
// "-Dir.armor.tachidesk.electronPath=/usr/bin/electron"
// "-Dsuwayomi.tachidesk.webInterface=electron",
// "-Dsuwayomi.tachidesk.electronPath=/usr/bin/electron"
// )
}
@ -96,7 +96,8 @@ sourceSets {
val tachideskVersion = "v0.3.9"
// counts commit count on master
val tachideskRevision = Runtime
val tachideskRevision = runCatching {
Runtime
.getRuntime()
.exec("git rev-list HEAD --count")
.let { process ->
@ -108,10 +109,11 @@ val tachideskRevision = Runtime
"r" + output.trim()
}
}.getOrDefault("r0")
buildConfig {
clsName = "BuildConfig"
packageName = "ir.armor.tachidesk.server"
packageName = "suwayomi.server"
buildConfigField("String", "NAME", rootProject.name)

View File

@ -1,4 +1,4 @@
package ir.armor.tachidesk
package suwayomi
/*
* Copyright (C) Contributors to the Suwayomi project
@ -7,8 +7,8 @@ package ir.armor.tachidesk
* 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.server.JavalinSetup.javalinSetup
import ir.armor.tachidesk.server.applicationSetup
import suwayomi.server.JavalinSetup.javalinSetup
import suwayomi.server.applicationSetup
fun main() {
applicationSetup()

View File

@ -0,0 +1,79 @@
package suwayomi.server
import io.javalin.Javalin
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.future.future
import mu.KotlinLogging
import suwayomi.server.util.Browser
import suwayomi.tachidesk.TachideskAPI
import java.io.IOException
import java.util.concurrent.CompletableFuture
import kotlin.concurrent.thread
/*
* 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/. */
object JavalinSetup {
private val logger = KotlinLogging.logger {}
private val scope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
fun <T> future(block: suspend CoroutineScope.() -> T): CompletableFuture<T> {
return scope.future(block = block)
}
fun javalinSetup() {
var hasWebUiBundled = false
val app = Javalin.create { config ->
try {
// if the bellow line throws an exception then webUI is not bundled
this::class.java.getResource("/react/index.html")
// no exception so we can tell javalin to serve webUI
hasWebUiBundled = true
config.addStaticFiles("/react")
config.addSinglePageRoot("/", "/react/index.html")
} catch (e: RuntimeException) {
logger.warn("react build files are missing.")
hasWebUiBundled = false
}
config.enableCorsForAllOrigins()
}.events { event ->
event.serverStarted {
if (hasWebUiBundled && serverConfig.initialOpenInBrowserEnabled) {
Browser.openInBrowser()
}
}
}.start(serverConfig.ip, serverConfig.port)
// when JVM is prompted to shutdown, stop javalin gracefully
Runtime.getRuntime().addShutdownHook(
thread(start = false) {
app.stop()
}
)
app.exception(NullPointerException::class.java) { e, ctx ->
logger.error("NullPointerException while handling the request", e)
ctx.status(404)
}
app.exception(NoSuchElementException::class.java) { e, ctx ->
logger.error("NoSuchElementException while handling the request", e)
ctx.status(404)
}
app.exception(IOException::class.java) { e, ctx ->
logger.error("IOException while handling the request", e)
ctx.status(500)
ctx.result(e.message ?: "Internal Server Error")
}
TachideskAPI.defineEndpoints(app)
}
}

View File

@ -1,4 +1,4 @@
package ir.armor.tachidesk.server
package suwayomi.server
/*
* Copyright (C) Contributors to the Suwayomi project

View File

@ -1,4 +1,4 @@
package ir.armor.tachidesk.server
package suwayomi.server
/*
* Copyright (C) Contributors to the Suwayomi project
@ -8,14 +8,14 @@ package ir.armor.tachidesk.server
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
import eu.kanade.tachiyomi.App
import ir.armor.tachidesk.model.database.databaseUp
import ir.armor.tachidesk.server.util.AppMutex.handleAppMutex
import ir.armor.tachidesk.server.util.SystemTray.systemTray
import mu.KotlinLogging
import org.kodein.di.DI
import org.kodein.di.bind
import org.kodein.di.conf.global
import org.kodein.di.singleton
import suwayomi.server.util.AppMutex.handleAppMutex
import suwayomi.server.util.SystemTray.systemTray
import suwayomi.tachidesk.model.database.databaseUp
import xyz.nulldev.androidcompat.AndroidCompat
import xyz.nulldev.androidcompat.AndroidCompatInitializer
import xyz.nulldev.ts.config.ApplicationRootDir

View File

@ -1,4 +1,4 @@
package ir.armor.tachidesk.server.impl_internal
package suwayomi.server.impl
/*
* Copyright (C) Contributors to the Suwayomi project
@ -7,7 +7,7 @@ package ir.armor.tachidesk.server.impl_internal
* 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.server.BuildConfig
import suwayomi.server.BuildConfig
data class AboutDataClass(
val name: String,

View File

@ -1,4 +1,4 @@
package ir.armor.tachidesk.server.util
package suwayomi.server.util
import mu.KotlinLogging
import kotlin.system.exitProcess

View File

@ -1,4 +1,4 @@
package ir.armor.tachidesk.server.util
package suwayomi.server.util
/*
* Copyright (C) Contributors to the Suwayomi project
@ -8,15 +8,17 @@ package ir.armor.tachidesk.server.util
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
import io.javalin.plugin.json.JavalinJackson
import ir.armor.tachidesk.server.impl_internal.AboutDataClass
import ir.armor.tachidesk.server.serverConfig
import ir.armor.tachidesk.server.util.AppMutex.AppMutexStat.Clear
import ir.armor.tachidesk.server.util.AppMutex.AppMutexStat.OtherApplicationRunning
import ir.armor.tachidesk.server.util.AppMutex.AppMutexStat.TachideskInstanceRunning
import ir.armor.tachidesk.server.util.Browser.openInBrowser
import mu.KotlinLogging
import okhttp3.OkHttpClient
import okhttp3.Request.Builder
import suwayomi.server.impl.AboutDataClass
import suwayomi.server.serverConfig
import suwayomi.server.util.AppMutex.AppMutexStat.Clear
import suwayomi.server.util.AppMutex.AppMutexStat.OtherApplicationRunning
import suwayomi.server.util.AppMutex.AppMutexStat.TachideskInstanceRunning
import suwayomi.server.util.Browser.openInBrowser
import suwayomi.server.util.ExitCode.MutexCheckFailedAnotherAppRunning
import suwayomi.server.util.ExitCode.MutexCheckFailedTachideskRunning
import java.io.IOException
import java.util.concurrent.TimeUnit
@ -67,11 +69,11 @@ object AppMutex {
logger.info("Aborting startup.")
shutdownApp(ExitCode.MutexCheckFailedTachideskRunning)
shutdownApp(MutexCheckFailedTachideskRunning)
}
OtherApplicationRunning -> {
logger.error("A non Tachidesk application is running on $appIP:${serverConfig.port}, aborting startup.")
shutdownApp(ExitCode.MutexCheckFailedAnotherAppRunning)
shutdownApp(MutexCheckFailedAnotherAppRunning)
}
}
}

View File

@ -1,4 +1,4 @@
package ir.armor.tachidesk.server.util
package suwayomi.server.util
/*
* Copyright (C) Contributors to the Suwayomi project
@ -8,7 +8,7 @@ package ir.armor.tachidesk.server.util
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
import dorkbox.util.Desktop
import ir.armor.tachidesk.server.serverConfig
import suwayomi.server.serverConfig
object Browser {
private val appIP = if (serverConfig.ip == "0.0.0.0") "127.0.0.1" else serverConfig.ip
@ -18,11 +18,11 @@ object Browser {
fun openInBrowser() {
val openInElectron = System.getProperty("ir.armor.tachidesk.webInterface")?.equals("electron")
val openInElectron = System.getProperty("suwayomi.server.webInterface")?.equals("electron")
if (openInElectron == true) {
try {
val electronPath = System.getProperty("ir.armor.tachidesk.electronPath")!!
val electronPath = System.getProperty("suwayomi.server.electronPath")!!
electronInstances.add(ProcessBuilder(electronPath, appBaseUrl).start())
} catch (e: Throwable) { // cover both java.lang.Exception and java.lang.Error
e.printStackTrace()

View File

@ -1,4 +1,4 @@
package ir.armor.tachidesk.server.util
package suwayomi.server.util
/*
* Copyright (C) Contributors to the Suwayomi project
@ -10,11 +10,11 @@ package ir.armor.tachidesk.server.util
import dorkbox.systemTray.MenuItem
import dorkbox.systemTray.SystemTray
import dorkbox.util.CacheUtil
import ir.armor.tachidesk.server.BuildConfig
import ir.armor.tachidesk.server.ServerConfig
import ir.armor.tachidesk.server.serverConfig
import ir.armor.tachidesk.server.util.Browser.openInBrowser
import ir.armor.tachidesk.server.util.ExitCode.Success
import suwayomi.server.BuildConfig
import suwayomi.server.ServerConfig
import suwayomi.server.serverConfig
import suwayomi.server.util.Browser.openInBrowser
import suwayomi.server.util.ExitCode.Success
object SystemTray {
fun systemTray(): SystemTray? {

View File

@ -1,116 +1,53 @@
package ir.armor.tachidesk.server
import io.javalin.Javalin
import ir.armor.tachidesk.impl.Category.createCategory
import ir.armor.tachidesk.impl.Category.getCategoryList
import ir.armor.tachidesk.impl.Category.removeCategory
import ir.armor.tachidesk.impl.Category.reorderCategory
import ir.armor.tachidesk.impl.Category.updateCategory
import ir.armor.tachidesk.impl.CategoryManga.addMangaToCategory
import ir.armor.tachidesk.impl.CategoryManga.getCategoryMangaList
import ir.armor.tachidesk.impl.CategoryManga.getMangaCategories
import ir.armor.tachidesk.impl.CategoryManga.removeMangaFromCategory
import ir.armor.tachidesk.impl.Chapter.getChapter
import ir.armor.tachidesk.impl.Chapter.getChapterList
import ir.armor.tachidesk.impl.Chapter.modifyChapter
import ir.armor.tachidesk.impl.Library
import ir.armor.tachidesk.impl.Library.getLibraryMangas
import ir.armor.tachidesk.impl.Manga.getManga
import ir.armor.tachidesk.impl.Manga.getMangaThumbnail
import ir.armor.tachidesk.impl.MangaList.getMangaList
import ir.armor.tachidesk.impl.Page.getPageImage
import ir.armor.tachidesk.impl.Search.sourceFilters
import ir.armor.tachidesk.impl.Search.sourceGlobalSearch
import ir.armor.tachidesk.impl.Search.sourceSearch
import ir.armor.tachidesk.impl.Source.getSource
import ir.armor.tachidesk.impl.Source.getSourceList
import ir.armor.tachidesk.impl.backup.BackupFlags
import ir.armor.tachidesk.impl.backup.legacy.LegacyBackupExport.createLegacyBackup
import ir.armor.tachidesk.impl.backup.legacy.LegacyBackupImport.restoreLegacyBackup
import ir.armor.tachidesk.impl.extension.Extension.getExtensionIcon
import ir.armor.tachidesk.impl.extension.Extension.installExtension
import ir.armor.tachidesk.impl.extension.Extension.uninstallExtension
import ir.armor.tachidesk.impl.extension.Extension.updateExtension
import ir.armor.tachidesk.impl.extension.ExtensionsList.getExtensionList
import ir.armor.tachidesk.server.impl_internal.About.getAbout
import ir.armor.tachidesk.server.util.Browser
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.future.future
import mu.KotlinLogging
import java.io.IOException
import java.text.SimpleDateFormat
import java.util.Date
import java.util.concurrent.CompletableFuture
import kotlin.concurrent.thread
package suwayomi.tachidesk
/*
* 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/. */
object JavalinSetup {
private val logger = KotlinLogging.logger {}
private val scope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
private fun <T> future(block: suspend CoroutineScope.() -> T): CompletableFuture<T> {
return scope.future(block = block)
}
fun javalinSetup() {
var hasWebUiBundled = false
val app = Javalin.create { config ->
try {
// if the bellow line throws an exception then webUI is not bundled
this::class.java.getResource("/react/index.html")
// no exception so we can tell javalin to serve webUI
hasWebUiBundled = true
config.addStaticFiles("/react")
config.addSinglePageRoot("/", "/react/index.html")
} catch (e: RuntimeException) {
logger.warn("react build files are missing.")
hasWebUiBundled = false
}
config.enableCorsForAllOrigins()
}.events { event ->
event.serverStarted {
if (hasWebUiBundled && serverConfig.initialOpenInBrowserEnabled) {
Browser.openInBrowser()
}
}
}.start(serverConfig.ip, serverConfig.port)
// when JVM is prompted to shutdown, stop javalin gracefully
Runtime.getRuntime().addShutdownHook(
thread(start = false) {
app.stop()
}
)
app.exception(NullPointerException::class.java) { e, ctx ->
logger.error("NullPointerException while handling the request", e)
ctx.status(404)
}
app.exception(NoSuchElementException::class.java) { e, ctx ->
logger.error("NoSuchElementException while handling the request", e)
ctx.status(404)
}
app.exception(IOException::class.java) { e, ctx ->
logger.error("IOException while handling the request", e)
ctx.status(500)
ctx.result(e.message ?: "Internal Server Error")
}
import io.javalin.Javalin
import suwayomi.server.JavalinSetup
import suwayomi.server.JavalinSetup.future
import suwayomi.server.impl.About
import suwayomi.tachidesk.impl.Category
import suwayomi.tachidesk.impl.CategoryManga.addMangaToCategory
import suwayomi.tachidesk.impl.CategoryManga.getCategoryMangaList
import suwayomi.tachidesk.impl.CategoryManga.getMangaCategories
import suwayomi.tachidesk.impl.CategoryManga.removeMangaFromCategory
import suwayomi.tachidesk.impl.Chapter.getChapter
import suwayomi.tachidesk.impl.Chapter.getChapterList
import suwayomi.tachidesk.impl.Chapter.modifyChapter
import suwayomi.tachidesk.impl.Library.addMangaToLibrary
import suwayomi.tachidesk.impl.Library.getLibraryMangas
import suwayomi.tachidesk.impl.Library.removeMangaFromLibrary
import suwayomi.tachidesk.impl.Manga.getManga
import suwayomi.tachidesk.impl.Manga.getMangaThumbnail
import suwayomi.tachidesk.impl.MangaList.getMangaList
import suwayomi.tachidesk.impl.Page.getPageImage
import suwayomi.tachidesk.impl.Search.sourceFilters
import suwayomi.tachidesk.impl.Search.sourceGlobalSearch
import suwayomi.tachidesk.impl.Search.sourceSearch
import suwayomi.tachidesk.impl.Source.getSource
import suwayomi.tachidesk.impl.Source.getSourceList
import suwayomi.tachidesk.impl.backup.BackupFlags
import suwayomi.tachidesk.impl.backup.legacy.LegacyBackupExport.createLegacyBackup
import suwayomi.tachidesk.impl.backup.legacy.LegacyBackupImport.restoreLegacyBackup
import suwayomi.tachidesk.impl.extension.Extension.getExtensionIcon
import suwayomi.tachidesk.impl.extension.Extension.installExtension
import suwayomi.tachidesk.impl.extension.Extension.uninstallExtension
import suwayomi.tachidesk.impl.extension.Extension.updateExtension
import suwayomi.tachidesk.impl.extension.ExtensionsList.getExtensionList
import java.text.SimpleDateFormat
import java.util.Date
object TachideskAPI {
fun defineEndpoints(app: Javalin) {
// list all extensions
app.get("/api/v1/extension/list") { ctx ->
ctx.json(
future {
JavalinSetup.future {
getExtensionList()
}
)
@ -121,7 +58,7 @@ object JavalinSetup {
val pkgName = ctx.pathParam("pkgName")
ctx.json(
future {
JavalinSetup.future {
installExtension(pkgName)
}
)
@ -132,7 +69,7 @@ object JavalinSetup {
val pkgName = ctx.pathParam("pkgName")
ctx.json(
future {
JavalinSetup.future {
updateExtension(pkgName)
}
)
@ -151,7 +88,7 @@ object JavalinSetup {
val apkName = ctx.pathParam("apkName")
ctx.result(
future { getExtensionIcon(apkName) }
JavalinSetup.future { getExtensionIcon(apkName) }
.thenApply {
ctx.header("content-type", it.second)
it.first
@ -175,7 +112,7 @@ object JavalinSetup {
val sourceId = ctx.pathParam("sourceId").toLong()
val pageNum = ctx.pathParam("pageNum").toInt()
ctx.json(
future {
JavalinSetup.future {
getMangaList(sourceId, pageNum, popular = true)
}
)
@ -186,7 +123,7 @@ object JavalinSetup {
val sourceId = ctx.pathParam("sourceId").toLong()
val pageNum = ctx.pathParam("pageNum").toInt()
ctx.json(
future {
JavalinSetup.future {
getMangaList(sourceId, pageNum, popular = false)
}
)
@ -198,7 +135,7 @@ object JavalinSetup {
val onlineFetch = ctx.queryParam("onlineFetch", "false").toBoolean()
ctx.json(
future {
JavalinSetup.future {
getManga(mangaId, onlineFetch)
}
)
@ -209,7 +146,7 @@ object JavalinSetup {
val mangaId = ctx.pathParam("mangaId").toInt()
ctx.result(
future { getMangaThumbnail(mangaId) }
JavalinSetup.future { getMangaThumbnail(mangaId) }
.thenApply {
ctx.header("content-type", it.second)
it.first
@ -245,14 +182,14 @@ object JavalinSetup {
val onlineFetch = ctx.queryParam("onlineFetch")?.toBoolean()
ctx.json(future { getChapterList(mangaId, onlineFetch) })
ctx.json(JavalinSetup.future { getChapterList(mangaId, onlineFetch) })
}
// used to display a chapter, get a chapter in order to show it's pages
app.get("/api/v1/manga/:mangaId/chapter/:chapterIndex") { ctx ->
val chapterIndex = ctx.pathParam("chapterIndex").toInt()
val mangaId = ctx.pathParam("mangaId").toInt()
ctx.json(future { getChapter(chapterIndex, mangaId) })
ctx.json(JavalinSetup.future { getChapter(chapterIndex, mangaId) })
}
// used to modify a chapter's parameters
@ -277,7 +214,7 @@ object JavalinSetup {
val index = ctx.pathParam("index").toInt()
ctx.result(
future { getPageImage(mangaId, chapterIndex, index) }
JavalinSetup.future { getPageImage(mangaId, chapterIndex, index) }
.thenApply {
ctx.header("content-type", it.second)
it.first
@ -306,7 +243,7 @@ object JavalinSetup {
val sourceId = ctx.pathParam("sourceId").toLong()
val searchTerm = ctx.pathParam("searchTerm")
val pageNum = ctx.pathParam("pageNum").toInt()
ctx.json(future { sourceSearch(sourceId, searchTerm, pageNum) })
ctx.json(JavalinSetup.future { sourceSearch(sourceId, searchTerm, pageNum) })
}
// source filter list
@ -320,7 +257,7 @@ object JavalinSetup {
val mangaId = ctx.pathParam("mangaId").toInt()
ctx.result(
future { Library.addMangaToLibrary(mangaId) }
JavalinSetup.future { addMangaToLibrary(mangaId) }
)
}
@ -329,7 +266,7 @@ object JavalinSetup {
val mangaId = ctx.pathParam("mangaId").toInt()
ctx.result(
future { Library.removeMangaFromLibrary(mangaId) }
JavalinSetup.future { removeMangaFromLibrary(mangaId) }
)
}
@ -340,19 +277,19 @@ object JavalinSetup {
// category list
app.get("/api/v1/category/") { ctx ->
ctx.json(getCategoryList())
ctx.json(Category.getCategoryList())
}
// category create
app.post("/api/v1/category/") { ctx ->
val name = ctx.formParam("name")!!
createCategory(name)
Category.createCategory(name)
ctx.status(200)
}
// returns some static info of the current app build
app.get("/api/v1/about/") { ctx ->
ctx.json(getAbout())
ctx.json(About.getAbout())
}
// category modification
@ -360,7 +297,7 @@ object JavalinSetup {
val categoryId = ctx.pathParam("categoryId").toInt()
val name = ctx.formParam("name")
val isDefault = ctx.formParam("default")?.toBoolean()
updateCategory(categoryId, name, isDefault)
Category.updateCategory(categoryId, name, isDefault)
ctx.status(200)
}
@ -369,14 +306,14 @@ object JavalinSetup {
val categoryId = ctx.pathParam("categoryId").toInt()
val from = ctx.formParam("from")!!.toInt()
val to = ctx.formParam("to")!!.toInt()
reorderCategory(categoryId, from, to)
Category.reorderCategory(categoryId, from, to)
ctx.status(200)
}
// category delete
app.delete("/api/v1/category/:categoryId") { ctx ->
val categoryId = ctx.pathParam("categoryId").toInt()
removeCategory(categoryId)
Category.removeCategory(categoryId)
ctx.status(200)
}
@ -398,7 +335,7 @@ object JavalinSetup {
// expects a Tachiyomi legacy backup json as a file upload, the file must be named "backup.json"
app.post("/api/v1/backup/legacy/import/file") { ctx ->
ctx.result(
future {
JavalinSetup.future {
restoreLegacyBackup(ctx.uploadedFile("backup.json")!!.content)
}
)
@ -408,7 +345,7 @@ object JavalinSetup {
app.get("/api/v1/backup/legacy/export") { ctx ->
ctx.contentType("application/json")
ctx.result(
future {
JavalinSetup.future {
createLegacyBackup(
BackupFlags(
includeManga = true,
@ -430,7 +367,7 @@ object JavalinSetup {
ctx.header("Content-Disposition", "attachment; filename=\"tachidesk_$currentDate.json\"")
ctx.result(
future {
JavalinSetup.future {
createLegacyBackup(
BackupFlags(
includeManga = true,

View File

@ -1,4 +1,4 @@
package ir.armor.tachidesk.impl
package suwayomi.tachidesk.impl
/*
* Copyright (C) Contributors to the Suwayomi project
@ -7,11 +7,6 @@ package ir.armor.tachidesk.impl
* 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.impl.CategoryManga.removeMangaFromCategory
import ir.armor.tachidesk.model.database.table.CategoryMangaTable
import ir.armor.tachidesk.model.database.table.CategoryTable
import ir.armor.tachidesk.model.database.table.toDataClass
import ir.armor.tachidesk.model.dataclass.CategoryDataClass
import org.jetbrains.exposed.sql.SortOrder
import org.jetbrains.exposed.sql.deleteWhere
import org.jetbrains.exposed.sql.insert
@ -19,6 +14,11 @@ 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
import suwayomi.tachidesk.impl.CategoryManga.removeMangaFromCategory
import suwayomi.tachidesk.model.database.table.CategoryMangaTable
import suwayomi.tachidesk.model.database.table.CategoryTable
import suwayomi.tachidesk.model.database.table.toDataClass
import suwayomi.tachidesk.model.dataclass.CategoryDataClass
object Category {
/**

View File

@ -1,4 +1,4 @@
package ir.armor.tachidesk.impl
package suwayomi.tachidesk.impl
/*
* Copyright (C) Contributors to the Suwayomi project
@ -7,12 +7,6 @@ package ir.armor.tachidesk.impl
* 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.model.database.table.CategoryMangaTable
import ir.armor.tachidesk.model.database.table.CategoryTable
import ir.armor.tachidesk.model.database.table.MangaTable
import ir.armor.tachidesk.model.database.table.toDataClass
import ir.armor.tachidesk.model.dataclass.CategoryDataClass
import ir.armor.tachidesk.model.dataclass.MangaDataClass
import org.jetbrains.exposed.sql.SortOrder
import org.jetbrains.exposed.sql.and
import org.jetbrains.exposed.sql.deleteWhere
@ -20,6 +14,12 @@ import org.jetbrains.exposed.sql.insert
import org.jetbrains.exposed.sql.select
import org.jetbrains.exposed.sql.transactions.transaction
import org.jetbrains.exposed.sql.update
import suwayomi.tachidesk.model.database.table.CategoryMangaTable
import suwayomi.tachidesk.model.database.table.CategoryTable
import suwayomi.tachidesk.model.database.table.MangaTable
import suwayomi.tachidesk.model.database.table.toDataClass
import suwayomi.tachidesk.model.dataclass.CategoryDataClass
import suwayomi.tachidesk.model.dataclass.MangaDataClass
object CategoryManga {
fun addMangaToCategory(mangaId: Int, categoryId: Int) {

View File

@ -1,4 +1,4 @@
package ir.armor.tachidesk.impl
package suwayomi.tachidesk.impl
/*
* Copyright (C) Contributors to the Suwayomi project
@ -9,14 +9,6 @@ package ir.armor.tachidesk.impl
import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga
import ir.armor.tachidesk.impl.Manga.getManga
import ir.armor.tachidesk.impl.util.GetHttpSource.getHttpSource
import ir.armor.tachidesk.impl.util.lang.awaitSingle
import ir.armor.tachidesk.model.database.table.ChapterTable
import ir.armor.tachidesk.model.database.table.MangaTable
import ir.armor.tachidesk.model.database.table.PageTable
import ir.armor.tachidesk.model.database.table.toDataClass
import ir.armor.tachidesk.model.dataclass.ChapterDataClass
import org.jetbrains.exposed.sql.SortOrder.DESC
import org.jetbrains.exposed.sql.and
import org.jetbrains.exposed.sql.deleteWhere
@ -24,6 +16,14 @@ import org.jetbrains.exposed.sql.insert
import org.jetbrains.exposed.sql.select
import org.jetbrains.exposed.sql.transactions.transaction
import org.jetbrains.exposed.sql.update
import suwayomi.tachidesk.impl.Manga.getManga
import suwayomi.tachidesk.impl.util.GetHttpSource.getHttpSource
import suwayomi.tachidesk.impl.util.lang.awaitSingle
import suwayomi.tachidesk.model.database.table.ChapterTable
import suwayomi.tachidesk.model.database.table.MangaTable
import suwayomi.tachidesk.model.database.table.PageTable
import suwayomi.tachidesk.model.database.table.toDataClass
import suwayomi.tachidesk.model.dataclass.ChapterDataClass
object Chapter {
/** get chapter list when showing a manga */

View File

@ -1,4 +1,4 @@
package ir.armor.tachidesk.impl
package suwayomi.tachidesk.impl
/*
* Copyright (C) Contributors to the Suwayomi project
@ -7,18 +7,18 @@ package ir.armor.tachidesk.impl
* 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.impl.Manga.getManga
import ir.armor.tachidesk.model.database.table.CategoryMangaTable
import ir.armor.tachidesk.model.database.table.CategoryTable
import ir.armor.tachidesk.model.database.table.MangaTable
import ir.armor.tachidesk.model.database.table.toDataClass
import ir.armor.tachidesk.model.dataclass.MangaDataClass
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
import org.jetbrains.exposed.sql.update
import suwayomi.tachidesk.impl.Manga.getManga
import suwayomi.tachidesk.model.database.table.CategoryMangaTable
import suwayomi.tachidesk.model.database.table.CategoryTable
import suwayomi.tachidesk.model.database.table.MangaTable
import suwayomi.tachidesk.model.database.table.toDataClass
import suwayomi.tachidesk.model.dataclass.MangaDataClass
object Library {
// TODO: `Category.isLanding` is to handle the default categories a new library manga gets,

View File

@ -1,4 +1,4 @@
package ir.armor.tachidesk.impl
package suwayomi.tachidesk.impl
/*
* Copyright (C) Contributors to the Suwayomi project
@ -9,23 +9,23 @@ package ir.armor.tachidesk.impl
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.source.model.SManga
import ir.armor.tachidesk.impl.MangaList.proxyThumbnailUrl
import ir.armor.tachidesk.impl.Source.getSource
import ir.armor.tachidesk.impl.util.GetHttpSource.getHttpSource
import ir.armor.tachidesk.impl.util.await
import ir.armor.tachidesk.impl.util.lang.awaitSingle
import ir.armor.tachidesk.impl.util.storage.CachedImageResponse.clearCachedImage
import ir.armor.tachidesk.impl.util.storage.CachedImageResponse.getCachedImageResponse
import ir.armor.tachidesk.model.database.table.MangaStatus
import ir.armor.tachidesk.model.database.table.MangaTable
import ir.armor.tachidesk.model.dataclass.MangaDataClass
import ir.armor.tachidesk.server.ApplicationDirs
import org.jetbrains.exposed.sql.select
import org.jetbrains.exposed.sql.transactions.transaction
import org.jetbrains.exposed.sql.update
import org.kodein.di.DI
import org.kodein.di.conf.global
import org.kodein.di.instance
import suwayomi.server.ApplicationDirs
import suwayomi.tachidesk.impl.MangaList.proxyThumbnailUrl
import suwayomi.tachidesk.impl.Source.getSource
import suwayomi.tachidesk.impl.util.GetHttpSource.getHttpSource
import suwayomi.tachidesk.impl.util.lang.awaitSingle
import suwayomi.tachidesk.impl.util.network.await
import suwayomi.tachidesk.impl.util.storage.CachedImageResponse.clearCachedImage
import suwayomi.tachidesk.impl.util.storage.CachedImageResponse.getCachedImageResponse
import suwayomi.tachidesk.model.database.table.MangaStatus
import suwayomi.tachidesk.model.database.table.MangaTable
import suwayomi.tachidesk.model.dataclass.MangaDataClass
import java.io.InputStream
object Manga {

View File

@ -1,4 +1,4 @@
package ir.armor.tachidesk.impl
package suwayomi.tachidesk.impl
/*
* Copyright (C) Contributors to the Suwayomi project
@ -8,15 +8,15 @@ package ir.armor.tachidesk.impl
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
import eu.kanade.tachiyomi.source.model.MangasPage
import ir.armor.tachidesk.impl.util.GetHttpSource.getHttpSource
import ir.armor.tachidesk.impl.util.lang.awaitSingle
import ir.armor.tachidesk.model.database.table.MangaStatus
import ir.armor.tachidesk.model.database.table.MangaTable
import ir.armor.tachidesk.model.dataclass.MangaDataClass
import ir.armor.tachidesk.model.dataclass.PagedMangaListDataClass
import org.jetbrains.exposed.sql.insertAndGetId
import org.jetbrains.exposed.sql.select
import org.jetbrains.exposed.sql.transactions.transaction
import suwayomi.tachidesk.impl.util.GetHttpSource.getHttpSource
import suwayomi.tachidesk.impl.util.lang.awaitSingle
import suwayomi.tachidesk.model.database.table.MangaStatus
import suwayomi.tachidesk.model.database.table.MangaTable
import suwayomi.tachidesk.model.dataclass.MangaDataClass
import suwayomi.tachidesk.model.dataclass.PagedMangaListDataClass
object MangaList {
fun proxyThumbnailUrl(mangaId: Int): String {

View File

@ -1,4 +1,4 @@
package ir.armor.tachidesk.impl
package suwayomi.tachidesk.impl
/*
* Copyright (C) Contributors to the Suwayomi project
@ -9,14 +9,6 @@ package ir.armor.tachidesk.impl
import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.online.HttpSource
import ir.armor.tachidesk.impl.util.GetHttpSource.getHttpSource
import ir.armor.tachidesk.impl.util.lang.awaitSingle
import ir.armor.tachidesk.impl.util.storage.CachedImageResponse.getCachedImageResponse
import ir.armor.tachidesk.impl.util.storage.SafePath
import ir.armor.tachidesk.model.database.table.ChapterTable
import ir.armor.tachidesk.model.database.table.MangaTable
import ir.armor.tachidesk.model.database.table.PageTable
import ir.armor.tachidesk.server.ApplicationDirs
import org.jetbrains.exposed.sql.and
import org.jetbrains.exposed.sql.select
import org.jetbrains.exposed.sql.transactions.transaction
@ -24,6 +16,14 @@ import org.jetbrains.exposed.sql.update
import org.kodein.di.DI
import org.kodein.di.conf.global
import org.kodein.di.instance
import suwayomi.server.ApplicationDirs
import suwayomi.tachidesk.impl.util.GetHttpSource.getHttpSource
import suwayomi.tachidesk.impl.util.lang.awaitSingle
import suwayomi.tachidesk.impl.util.storage.CachedImageResponse.getCachedImageResponse
import suwayomi.tachidesk.impl.util.storage.SafePath
import suwayomi.tachidesk.model.database.table.ChapterTable
import suwayomi.tachidesk.model.database.table.MangaTable
import suwayomi.tachidesk.model.database.table.PageTable
import java.io.File
import java.io.InputStream

View File

@ -1,4 +1,4 @@
package ir.armor.tachidesk.impl
package suwayomi.tachidesk.impl
/*
* Copyright (C) Contributors to the Suwayomi project
@ -7,10 +7,10 @@ package ir.armor.tachidesk.impl
* 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.impl.MangaList.processEntries
import ir.armor.tachidesk.impl.util.GetHttpSource.getHttpSource
import ir.armor.tachidesk.impl.util.lang.awaitSingle
import ir.armor.tachidesk.model.dataclass.PagedMangaListDataClass
import suwayomi.tachidesk.impl.MangaList.processEntries
import suwayomi.tachidesk.impl.util.GetHttpSource.getHttpSource
import suwayomi.tachidesk.impl.util.lang.awaitSingle
import suwayomi.tachidesk.model.dataclass.PagedMangaListDataClass
object Search {
// TODO

View File

@ -1,4 +1,4 @@
package ir.armor.tachidesk.impl
package suwayomi.tachidesk.impl
/*
* Copyright (C) Contributors to the Suwayomi project
@ -7,15 +7,15 @@ package ir.armor.tachidesk.impl
* 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.impl.extension.Extension.getExtensionIconUrl
import ir.armor.tachidesk.impl.util.GetHttpSource.getHttpSource
import ir.armor.tachidesk.model.database.table.ExtensionTable
import ir.armor.tachidesk.model.database.table.SourceTable
import ir.armor.tachidesk.model.dataclass.SourceDataClass
import mu.KotlinLogging
import org.jetbrains.exposed.sql.select
import org.jetbrains.exposed.sql.selectAll
import org.jetbrains.exposed.sql.transactions.transaction
import suwayomi.tachidesk.impl.extension.Extension.getExtensionIconUrl
import suwayomi.tachidesk.impl.util.GetHttpSource.getHttpSource
import suwayomi.tachidesk.model.database.table.ExtensionTable
import suwayomi.tachidesk.model.database.table.SourceTable
import suwayomi.tachidesk.model.dataclass.SourceDataClass
object Source {
private val logger = KotlinLogging.logger {}

View File

@ -1,4 +1,4 @@
package ir.armor.tachidesk.impl.backup
package suwayomi.tachidesk.impl.backup
/*
* Copyright (C) Contributors to the Suwayomi project

View File

@ -1,4 +1,4 @@
package ir.armor.tachidesk.impl.backup.legacy
package suwayomi.tachidesk.impl.backup.legacy
/*
* Copyright (C) Contributors to the Suwayomi project
@ -11,16 +11,16 @@ import com.github.salomonbrys.kotson.registerTypeAdapter
import com.github.salomonbrys.kotson.registerTypeHierarchyAdapter
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import ir.armor.tachidesk.impl.backup.legacy.models.DHistory
import ir.armor.tachidesk.impl.backup.legacy.serializer.CategoryTypeAdapter
import ir.armor.tachidesk.impl.backup.legacy.serializer.ChapterTypeAdapter
import ir.armor.tachidesk.impl.backup.legacy.serializer.HistoryTypeAdapter
import ir.armor.tachidesk.impl.backup.legacy.serializer.MangaTypeAdapter
import ir.armor.tachidesk.impl.backup.legacy.serializer.TrackTypeAdapter
import ir.armor.tachidesk.impl.backup.models.CategoryImpl
import ir.armor.tachidesk.impl.backup.models.ChapterImpl
import ir.armor.tachidesk.impl.backup.models.MangaImpl
import ir.armor.tachidesk.impl.backup.models.TrackImpl
import suwayomi.tachidesk.impl.backup.legacy.models.DHistory
import suwayomi.tachidesk.impl.backup.legacy.serializer.CategoryTypeAdapter
import suwayomi.tachidesk.impl.backup.legacy.serializer.ChapterTypeAdapter
import suwayomi.tachidesk.impl.backup.legacy.serializer.HistoryTypeAdapter
import suwayomi.tachidesk.impl.backup.legacy.serializer.MangaTypeAdapter
import suwayomi.tachidesk.impl.backup.legacy.serializer.TrackTypeAdapter
import suwayomi.tachidesk.impl.backup.models.CategoryImpl
import suwayomi.tachidesk.impl.backup.models.ChapterImpl
import suwayomi.tachidesk.impl.backup.models.MangaImpl
import suwayomi.tachidesk.impl.backup.models.TrackImpl
import java.util.Date
open class LegacyBackupBase {

View File

@ -1,4 +1,4 @@
package ir.armor.tachidesk.impl.backup.legacy
package suwayomi.tachidesk.impl.backup.legacy
/*
* Copyright (C) Contributors to the Suwayomi project
@ -12,20 +12,20 @@ import com.google.gson.JsonArray
import com.google.gson.JsonElement
import com.google.gson.JsonObject
import eu.kanade.tachiyomi.source.LocalSource
import ir.armor.tachidesk.impl.Category.getCategoryList
import ir.armor.tachidesk.impl.CategoryManga.getMangaCategories
import ir.armor.tachidesk.impl.backup.BackupFlags
import ir.armor.tachidesk.impl.backup.legacy.models.Backup
import ir.armor.tachidesk.impl.backup.legacy.models.Backup.CURRENT_VERSION
import ir.armor.tachidesk.impl.backup.models.CategoryImpl
import ir.armor.tachidesk.impl.backup.models.ChapterImpl
import ir.armor.tachidesk.impl.backup.models.Manga
import ir.armor.tachidesk.impl.backup.models.MangaImpl
import ir.armor.tachidesk.impl.util.GetHttpSource.getHttpSource
import ir.armor.tachidesk.model.database.table.ChapterTable
import ir.armor.tachidesk.model.database.table.MangaTable
import org.jetbrains.exposed.sql.select
import org.jetbrains.exposed.sql.transactions.transaction
import suwayomi.tachidesk.impl.Category.getCategoryList
import suwayomi.tachidesk.impl.CategoryManga.getMangaCategories
import suwayomi.tachidesk.impl.backup.BackupFlags
import suwayomi.tachidesk.impl.backup.legacy.models.Backup
import suwayomi.tachidesk.impl.backup.legacy.models.Backup.CURRENT_VERSION
import suwayomi.tachidesk.impl.backup.models.CategoryImpl
import suwayomi.tachidesk.impl.backup.models.ChapterImpl
import suwayomi.tachidesk.impl.backup.models.Manga
import suwayomi.tachidesk.impl.backup.models.MangaImpl
import suwayomi.tachidesk.impl.util.GetHttpSource.getHttpSource
import suwayomi.tachidesk.model.database.table.ChapterTable
import suwayomi.tachidesk.model.database.table.MangaTable
object LegacyBackupExport : LegacyBackupBase() {

View File

@ -1,4 +1,4 @@
package ir.armor.tachidesk.impl.backup.legacy
package suwayomi.tachidesk.impl.backup.legacy
import com.github.salomonbrys.kotson.fromJson
import com.google.gson.JsonArray
@ -7,28 +7,28 @@ import com.google.gson.JsonObject
import com.google.gson.JsonParser
import eu.kanade.tachiyomi.source.Source
import eu.kanade.tachiyomi.source.model.SManga
import ir.armor.tachidesk.impl.Category.createCategory
import ir.armor.tachidesk.impl.Category.getCategoryList
import ir.armor.tachidesk.impl.backup.legacy.LegacyBackupValidator.ValidationResult
import ir.armor.tachidesk.impl.backup.legacy.LegacyBackupValidator.validate
import ir.armor.tachidesk.impl.backup.legacy.models.Backup
import ir.armor.tachidesk.impl.backup.legacy.models.DHistory
import ir.armor.tachidesk.impl.backup.models.CategoryImpl
import ir.armor.tachidesk.impl.backup.models.Chapter
import ir.armor.tachidesk.impl.backup.models.ChapterImpl
import ir.armor.tachidesk.impl.backup.models.Manga
import ir.armor.tachidesk.impl.backup.models.MangaImpl
import ir.armor.tachidesk.impl.backup.models.Track
import ir.armor.tachidesk.impl.backup.models.TrackImpl
import ir.armor.tachidesk.impl.util.GetHttpSource.getHttpSource
import ir.armor.tachidesk.impl.util.lang.awaitSingle
import ir.armor.tachidesk.model.database.table.MangaTable
import mu.KotlinLogging
import org.jetbrains.exposed.sql.and
import org.jetbrains.exposed.sql.insert
import org.jetbrains.exposed.sql.select
import org.jetbrains.exposed.sql.transactions.transaction
import org.jetbrains.exposed.sql.update
import suwayomi.tachidesk.impl.Category.createCategory
import suwayomi.tachidesk.impl.Category.getCategoryList
import suwayomi.tachidesk.impl.backup.legacy.LegacyBackupValidator.ValidationResult
import suwayomi.tachidesk.impl.backup.legacy.LegacyBackupValidator.validate
import suwayomi.tachidesk.impl.backup.legacy.models.Backup
import suwayomi.tachidesk.impl.backup.legacy.models.DHistory
import suwayomi.tachidesk.impl.backup.models.CategoryImpl
import suwayomi.tachidesk.impl.backup.models.Chapter
import suwayomi.tachidesk.impl.backup.models.ChapterImpl
import suwayomi.tachidesk.impl.backup.models.Manga
import suwayomi.tachidesk.impl.backup.models.MangaImpl
import suwayomi.tachidesk.impl.backup.models.Track
import suwayomi.tachidesk.impl.backup.models.TrackImpl
import suwayomi.tachidesk.impl.util.GetHttpSource.getHttpSource
import suwayomi.tachidesk.impl.util.lang.awaitSingle
import suwayomi.tachidesk.model.database.table.MangaTable
import java.io.InputStream
import java.util.Date

View File

@ -1,4 +1,4 @@
package ir.armor.tachidesk.impl.backup.legacy
package suwayomi.tachidesk.impl.backup.legacy
/*
* Copyright (C) Contributors to the Suwayomi project
@ -8,10 +8,10 @@ package ir.armor.tachidesk.impl.backup.legacy
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
import com.google.gson.JsonObject
import ir.armor.tachidesk.impl.backup.legacy.models.Backup
import ir.armor.tachidesk.model.database.table.SourceTable
import org.jetbrains.exposed.sql.select
import org.jetbrains.exposed.sql.transactions.transaction
import suwayomi.tachidesk.impl.backup.legacy.models.Backup
import suwayomi.tachidesk.model.database.table.SourceTable
object LegacyBackupValidator {
data class ValidationResult(val missingSources: List<String>, val missingTrackers: List<String>)

View File

@ -1,4 +1,4 @@
package ir.armor.tachidesk.impl.backup.legacy.models
package suwayomi.tachidesk.impl.backup.legacy.models
import java.text.SimpleDateFormat
import java.util.Date

View File

@ -1,3 +1,3 @@
package ir.armor.tachidesk.impl.backup.legacy.models
package suwayomi.tachidesk.impl.backup.legacy.models
data class DHistory(val url: String, val lastRead: Long)

View File

@ -1,8 +1,8 @@
package ir.armor.tachidesk.impl.backup.legacy.serializer
package suwayomi.tachidesk.impl.backup.legacy.serializer
import com.github.salomonbrys.kotson.typeAdapter
import com.google.gson.TypeAdapter
import ir.armor.tachidesk.impl.backup.models.CategoryImpl
import suwayomi.tachidesk.impl.backup.models.CategoryImpl
/**
* JSON Serializer used to write / read [CategoryImpl] to / from json

View File

@ -1,9 +1,9 @@
package ir.armor.tachidesk.impl.backup.legacy.serializer
package suwayomi.tachidesk.impl.backup.legacy.serializer
import com.github.salomonbrys.kotson.typeAdapter
import com.google.gson.TypeAdapter
import com.google.gson.stream.JsonToken
import ir.armor.tachidesk.impl.backup.models.ChapterImpl
import suwayomi.tachidesk.impl.backup.models.ChapterImpl
/**
* JSON Serializer used to write / read [ChapterImpl] to / from json

View File

@ -1,8 +1,8 @@
package ir.armor.tachidesk.impl.backup.legacy.serializer
package suwayomi.tachidesk.impl.backup.legacy.serializer
import com.github.salomonbrys.kotson.typeAdapter
import com.google.gson.TypeAdapter
import ir.armor.tachidesk.impl.backup.legacy.models.DHistory
import suwayomi.tachidesk.impl.backup.legacy.models.DHistory
/**
* JSON Serializer used to write / read [DHistory] to / from json

View File

@ -1,8 +1,8 @@
package ir.armor.tachidesk.impl.backup.legacy.serializer
package suwayomi.tachidesk.impl.backup.legacy.serializer
import com.github.salomonbrys.kotson.typeAdapter
import com.google.gson.TypeAdapter
import ir.armor.tachidesk.impl.backup.models.MangaImpl
import suwayomi.tachidesk.impl.backup.models.MangaImpl
/**
* JSON Serializer used to write / read [MangaImpl] to / from json

View File

@ -1,9 +1,9 @@
package ir.armor.tachidesk.impl.backup.legacy.serializer
package suwayomi.tachidesk.impl.backup.legacy.serializer
import com.github.salomonbrys.kotson.typeAdapter
import com.google.gson.TypeAdapter
import com.google.gson.stream.JsonToken
import ir.armor.tachidesk.impl.backup.models.TrackImpl
import suwayomi.tachidesk.impl.backup.models.TrackImpl
/**
* JSON Serializer used to write / read [TrackImpl] to / from json

View File

@ -1,4 +1,4 @@
package ir.armor.tachidesk.impl.backup.models
package suwayomi.tachidesk.impl.backup.models
import java.io.Serializable

View File

@ -1,4 +1,4 @@
package ir.armor.tachidesk.impl.backup.models
package suwayomi.tachidesk.impl.backup.models
class CategoryImpl : Category {

View File

@ -1,4 +1,4 @@
package ir.armor.tachidesk.impl.backup.models
package suwayomi.tachidesk.impl.backup.models
import eu.kanade.tachiyomi.source.model.SChapter
import java.io.Serializable

View File

@ -1,7 +1,7 @@
package ir.armor.tachidesk.impl.backup.models
package suwayomi.tachidesk.impl.backup.models
import ir.armor.tachidesk.model.database.table.ChapterTable
import org.jetbrains.exposed.sql.ResultRow
import suwayomi.tachidesk.model.database.table.ChapterTable
class ChapterImpl : Chapter {

View File

@ -1,4 +1,4 @@
package ir.armor.tachidesk.impl.backup.models
package suwayomi.tachidesk.impl.backup.models
import java.io.Serializable

View File

@ -1,4 +1,4 @@
package ir.armor.tachidesk.impl.backup.models
package suwayomi.tachidesk.impl.backup.models
/**
* Object containing the history statistics of a chapter

View File

@ -1,4 +1,4 @@
package ir.armor.tachidesk.impl.backup.models
package suwayomi.tachidesk.impl.backup.models
class LibraryManga : MangaImpl() {

View File

@ -1,6 +1,7 @@
package ir.armor.tachidesk.impl.backup.models
package suwayomi.tachidesk.impl.backup.models
import eu.kanade.tachiyomi.source.model.SManga
// import tachiyomi.source.model.MangaInfo
interface Manga : SManga {

View File

@ -1,4 +1,4 @@
package ir.armor.tachidesk.impl.backup.models
package suwayomi.tachidesk.impl.backup.models
class MangaCategory {

View File

@ -1,3 +1,3 @@
package ir.armor.tachidesk.impl.backup.models
package suwayomi.tachidesk.impl.backup.models
class MangaChapter(val manga: Manga, val chapter: Chapter)

View File

@ -1,4 +1,4 @@
package ir.armor.tachidesk.impl.backup.models
package suwayomi.tachidesk.impl.backup.models
/**
* Object containing manga, chapter and history

View File

@ -1,7 +1,7 @@
package ir.armor.tachidesk.impl.backup.models
package suwayomi.tachidesk.impl.backup.models
import ir.armor.tachidesk.model.database.table.MangaTable
import org.jetbrains.exposed.sql.ResultRow
import suwayomi.tachidesk.model.database.table.MangaTable
open class MangaImpl : Manga {

View File

@ -1,4 +1,4 @@
package ir.armor.tachidesk.impl.backup.models
package suwayomi.tachidesk.impl.backup.models
import java.io.Serializable

View File

@ -1,4 +1,4 @@
package ir.armor.tachidesk.impl.backup.models
package suwayomi.tachidesk.impl.backup.models
class TrackImpl : Track {

View File

@ -1,4 +1,4 @@
package ir.armor.tachidesk.impl.download
package suwayomi.tachidesk.impl.download
import org.jetbrains.exposed.sql.ResultRow
import java.util.concurrent.LinkedBlockingQueue

View File

@ -1,4 +1,4 @@
package ir.armor.tachidesk.impl.extension
package suwayomi.tachidesk.impl.extension
/*
* Copyright (C) Contributors to the Suwayomi project
@ -13,23 +13,6 @@ import eu.kanade.tachiyomi.network.NetworkHelper
import eu.kanade.tachiyomi.source.CatalogueSource
import eu.kanade.tachiyomi.source.Source
import eu.kanade.tachiyomi.source.SourceFactory
import ir.armor.tachidesk.impl.extension.ExtensionsList.extensionTableAsDataClass
import ir.armor.tachidesk.impl.extension.github.ExtensionGithubApi
import ir.armor.tachidesk.impl.util.PackageTools.EXTENSION_FEATURE
import ir.armor.tachidesk.impl.util.PackageTools.LIB_VERSION_MAX
import ir.armor.tachidesk.impl.util.PackageTools.LIB_VERSION_MIN
import ir.armor.tachidesk.impl.util.PackageTools.METADATA_NSFW
import ir.armor.tachidesk.impl.util.PackageTools.METADATA_SOURCE_CLASS
import ir.armor.tachidesk.impl.util.PackageTools.dex2jar
import ir.armor.tachidesk.impl.util.PackageTools.getPackageInfo
import ir.armor.tachidesk.impl.util.PackageTools.getSignatureHash
import ir.armor.tachidesk.impl.util.PackageTools.loadExtensionSources
import ir.armor.tachidesk.impl.util.PackageTools.trustedSignatures
import ir.armor.tachidesk.impl.util.await
import ir.armor.tachidesk.impl.util.storage.CachedImageResponse.getCachedImageResponse
import ir.armor.tachidesk.model.database.table.ExtensionTable
import ir.armor.tachidesk.model.database.table.SourceTable
import ir.armor.tachidesk.server.ApplicationDirs
import mu.KotlinLogging
import okhttp3.Request
import okio.buffer
@ -42,6 +25,23 @@ import org.jetbrains.exposed.sql.update
import org.kodein.di.DI
import org.kodein.di.conf.global
import org.kodein.di.instance
import suwayomi.server.ApplicationDirs
import suwayomi.tachidesk.impl.extension.ExtensionsList.extensionTableAsDataClass
import suwayomi.tachidesk.impl.extension.github.ExtensionGithubApi
import suwayomi.tachidesk.impl.util.PackageTools.EXTENSION_FEATURE
import suwayomi.tachidesk.impl.util.PackageTools.LIB_VERSION_MAX
import suwayomi.tachidesk.impl.util.PackageTools.LIB_VERSION_MIN
import suwayomi.tachidesk.impl.util.PackageTools.METADATA_NSFW
import suwayomi.tachidesk.impl.util.PackageTools.METADATA_SOURCE_CLASS
import suwayomi.tachidesk.impl.util.PackageTools.dex2jar
import suwayomi.tachidesk.impl.util.PackageTools.getPackageInfo
import suwayomi.tachidesk.impl.util.PackageTools.getSignatureHash
import suwayomi.tachidesk.impl.util.PackageTools.loadExtensionSources
import suwayomi.tachidesk.impl.util.PackageTools.trustedSignatures
import suwayomi.tachidesk.impl.util.network.await
import suwayomi.tachidesk.impl.util.storage.CachedImageResponse.getCachedImageResponse
import suwayomi.tachidesk.model.database.table.ExtensionTable
import suwayomi.tachidesk.model.database.table.SourceTable
import uy.kohesive.injekt.injectLazy
import java.io.File
import java.io.InputStream

View File

@ -1,4 +1,4 @@
package ir.armor.tachidesk.impl.extension
package suwayomi.tachidesk.impl.extension
/*
* Copyright (C) Contributors to the Suwayomi project
@ -7,11 +7,6 @@ package ir.armor.tachidesk.impl.extension
* 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.impl.extension.Extension.getExtensionIconUrl
import ir.armor.tachidesk.impl.extension.github.ExtensionGithubApi
import ir.armor.tachidesk.impl.extension.github.OnlineExtension
import ir.armor.tachidesk.model.database.table.ExtensionTable
import ir.armor.tachidesk.model.dataclass.ExtensionDataClass
import mu.KotlinLogging
import org.jetbrains.exposed.sql.deleteWhere
import org.jetbrains.exposed.sql.insert
@ -19,6 +14,11 @@ 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
import suwayomi.tachidesk.impl.extension.Extension.getExtensionIconUrl
import suwayomi.tachidesk.impl.extension.github.ExtensionGithubApi
import suwayomi.tachidesk.impl.extension.github.OnlineExtension
import suwayomi.tachidesk.model.database.table.ExtensionTable
import suwayomi.tachidesk.model.dataclass.ExtensionDataClass
import java.util.concurrent.ConcurrentHashMap
object ExtensionsList {

View File

@ -0,0 +1,80 @@
package suwayomi.tachidesk.impl.extension.github
/*
* 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 com.github.salomonbrys.kotson.int
import com.github.salomonbrys.kotson.string
import com.google.gson.JsonArray
import com.google.gson.JsonParser
import eu.kanade.tachiyomi.network.NetworkHelper
import okhttp3.Request
import suwayomi.tachidesk.impl.util.network.UnzippingInterceptor
import suwayomi.tachidesk.model.dataclass.ExtensionDataClass
import uy.kohesive.injekt.injectLazy
object AnimeExtensionGithubApi {
const val BASE_URL = "https://raw.githubusercontent.com"
const val REPO_URL_PREFIX = "$BASE_URL/jmir1/tachiyomi-extensions/repo"
private const val LIB_VERSION_MIN = 1.3
private const val LIB_VERSION_MAX = 1.3
private fun parseResponse(json: JsonArray): List<OnlineExtension> {
return json
.map { it.asJsonObject }
.filter { element ->
val versionName = element["version"].string
val libVersion = versionName.substringBeforeLast('.').toDouble()
libVersion in LIB_VERSION_MIN..LIB_VERSION_MAX
}
.map { element ->
val name = element["name"].string.substringAfter("Tachiyomi: ")
val pkgName = element["pkg"].string
val apkName = element["apk"].string
val versionName = element["version"].string
val versionCode = element["code"].int
val lang = element["lang"].string
val nsfw = element["nsfw"].int == 1
val icon = "$REPO_URL_PREFIX/icon/${apkName.replace(".apk", ".png")}"
OnlineExtension(name, pkgName, versionName, versionCode, lang, nsfw, apkName, icon)
}
}
suspend fun findExtensions(): List<OnlineExtension> {
val response = getRepo()
return parseResponse(response)
}
fun getApkUrl(extension: ExtensionDataClass): String {
return "$REPO_URL_PREFIX/apk/${extension.apkName}"
}
private val client by lazy {
val network: NetworkHelper by injectLazy()
network.client.newBuilder()
.addNetworkInterceptor { chain ->
val originalResponse = chain.proceed(chain.request())
originalResponse.newBuilder()
.header("Content-Encoding", "gzip")
.header("Content-Type", "application/json")
.build()
}
.addInterceptor(UnzippingInterceptor())
.build()
}
private fun getRepo(): com.google.gson.JsonArray {
val request = Request.Builder()
.url("$REPO_URL_PREFIX/index.json.gz")
.build()
val response = client.newCall(request).execute().use { response -> response.body!!.string() }
return JsonParser.parseString(response).asJsonArray
}
}

View File

@ -1,4 +1,4 @@
package ir.armor.tachidesk.impl.extension.github
package suwayomi.tachidesk.impl.extension.github
/*
* Copyright (C) Contributors to the Suwayomi project
@ -12,32 +12,25 @@ import com.github.salomonbrys.kotson.string
import com.google.gson.JsonArray
import com.google.gson.JsonParser
import eu.kanade.tachiyomi.network.NetworkHelper
import ir.armor.tachidesk.model.dataclass.ExtensionDataClass
import okhttp3.Headers
import okhttp3.Interceptor
import okhttp3.Interceptor.Chain
import okhttp3.Request
import okhttp3.Response
import okhttp3.internal.http.RealResponseBody
import okio.GzipSource
import okio.buffer
import suwayomi.tachidesk.impl.util.network.UnzippingInterceptor
import suwayomi.tachidesk.model.dataclass.ExtensionDataClass
import uy.kohesive.injekt.injectLazy
import java.io.IOException
object ExtensionGithubApi {
const val BASE_URL = "https://raw.githubusercontent.com"
const val REPO_URL_PREFIX = "$BASE_URL/tachiyomiorg/tachiyomi-extensions/repo"
private const val LIB_VERSION_MIN = "1.2"
private const val LIB_VERSION_MAX = "1.2"
private const val LIB_VERSION_MIN = 1.2
private const val LIB_VERSION_MAX = 1.2
private fun parseResponse(json: JsonArray): List<OnlineExtension> {
return json
.map { it.asJsonObject }
.filter { element ->
val versionName = element["version"].string
val libVersion = versionName.substringBeforeLast('.')
libVersion == LIB_VERSION_MAX
val libVersion = versionName.substringBeforeLast('.').toDouble()
libVersion in LIB_VERSION_MIN..LIB_VERSION_MAX
}
.map { element ->
val name = element["name"].string.substringAfter("Tachiyomi: ")
@ -85,35 +78,3 @@ object ExtensionGithubApi {
return JsonParser.parseString(response).asJsonArray
}
}
// ref: https://stackoverflow.com/questions/51901333/okhttp-3-how-to-decompress-gzip-deflate-response-manually-using-java-android
private class UnzippingInterceptor : Interceptor {
@Throws(IOException::class)
override fun intercept(chain: Chain): Response {
val response: Response = chain.proceed(chain.request())
return unzip(response)
}
@Throws(IOException::class)
private fun unzip(response: Response): Response {
if (response.body == null) {
return response
}
// check if we have gzip response
val contentEncoding: String? = response.headers["Content-Encoding"]
// this is used to decompress gzipped responses
return if (contentEncoding != null && contentEncoding == "gzip") {
val body = response.body!!
val contentLength: Long = body.contentLength()
val responseBody = GzipSource(body.source())
val strippedHeaders: Headers = response.headers.newBuilder().build()
response.newBuilder().headers(strippedHeaders)
.body(RealResponseBody(body.contentType().toString(), contentLength, responseBody.buffer()))
.build()
} else {
response
}
}
}

View File

@ -1,4 +1,4 @@
package ir.armor.tachidesk.impl.extension.github
package suwayomi.tachidesk.impl.extension.github
data class OnlineExtension(
val name: String,

View File

@ -1,4 +1,4 @@
package ir.armor.tachidesk.impl.util
package suwayomi.tachidesk.impl.util
/*
* Copyright (C) Contributors to the Suwayomi project
@ -10,15 +10,15 @@ package ir.armor.tachidesk.impl.util
import eu.kanade.tachiyomi.source.Source
import eu.kanade.tachiyomi.source.SourceFactory
import eu.kanade.tachiyomi.source.online.HttpSource
import ir.armor.tachidesk.impl.util.PackageTools.loadExtensionSources
import ir.armor.tachidesk.model.database.table.ExtensionTable
import ir.armor.tachidesk.model.database.table.SourceTable
import ir.armor.tachidesk.server.ApplicationDirs
import org.jetbrains.exposed.sql.select
import org.jetbrains.exposed.sql.transactions.transaction
import org.kodein.di.DI
import org.kodein.di.conf.global
import org.kodein.di.instance
import suwayomi.server.ApplicationDirs
import suwayomi.tachidesk.impl.util.PackageTools.loadExtensionSources
import suwayomi.tachidesk.model.database.table.ExtensionTable
import suwayomi.tachidesk.model.database.table.SourceTable
import java.util.concurrent.ConcurrentHashMap
object GetHttpSource {

View File

@ -1,4 +1,4 @@
package ir.armor.tachidesk.impl.util
package suwayomi.tachidesk.impl.util
import android.content.pm.PackageInfo
import android.content.pm.Signature
@ -7,7 +7,6 @@ import com.googlecode.d2j.dex.Dex2jar
import com.googlecode.d2j.reader.MultiDexFileReader
import com.googlecode.dex2jar.tools.BaksmaliBaseDexExceptionHandler
import eu.kanade.tachiyomi.util.lang.Hash
import ir.armor.tachidesk.server.ApplicationDirs
import mu.KotlinLogging
import net.dongliu.apk.parser.ApkFile
import net.dongliu.apk.parser.ApkParsers
@ -16,6 +15,7 @@ import org.kodein.di.conf.global
import org.kodein.di.instance
import org.w3c.dom.Element
import org.w3c.dom.Node
import suwayomi.server.ApplicationDirs
import xyz.nulldev.androidcompat.pm.InstalledPackage.Companion.toList
import xyz.nulldev.androidcompat.pm.toPackageInfo
import java.io.File
@ -41,11 +41,12 @@ object PackageTools {
const val METADATA_SOURCE_FACTORY = "tachiyomi.extension.factory"
const val METADATA_NSFW = "tachiyomi.extension.nsfw"
const val LIB_VERSION_MIN = 1.2
const val LIB_VERSION_MAX = 1.2
const val LIB_VERSION_MAX = 1.3
private const val officialSignature = "7ce04da7773d41b489f4693a366c36bcd0a11fc39b547168553c285bd7348e23" // inorichi's key
private const val animeSignature = "50ab1d1e3a20d204d0ad6d334c7691c632e41b98dfa132bf385695fdfa63839c" // jmir1's key
private const val unofficialSignature = "64feb21075ba97ebc9cc981243645b331595c111cef1b0d084236a0403b00581" // ArMor's key
var trustedSignatures = mutableSetOf<String>() + officialSignature + unofficialSignature
var trustedSignatures = mutableSetOf<String>() + officialSignature + animeSignature + unofficialSignature
/**
* Convert dex to jar, a wrapper for the dex2jar library

View File

@ -1,4 +1,4 @@
package ir.armor.tachidesk.impl.util.lang
package suwayomi.tachidesk.impl.util.lang
/*
* Copyright (C) Contributors to the Suwayomi project

View File

@ -1,4 +1,4 @@
package ir.armor.tachidesk.impl.util
package suwayomi.tachidesk.impl.util.network
/*
* Copyright (C) Contributors to the Suwayomi project
@ -13,7 +13,6 @@ import okhttp3.Callback
import okhttp3.Response
import okhttp3.internal.closeQuietly
import java.io.IOException
import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException
// Based on https://github.com/gildor/kotlin-coroutines-okhttp

View File

@ -0,0 +1,49 @@
package suwayomi.tachidesk.impl.util.network
import okhttp3.Headers
import okhttp3.Interceptor
import okhttp3.Interceptor.Chain
import okhttp3.Response
import okhttp3.internal.http.RealResponseBody
import okio.GzipSource
import okio.buffer
import java.io.IOException
/*
* 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/. */
// ref: https://stackoverflow.com/questions/51901333/okhttp-3-how-to-decompress-gzip-deflate-response-manually-using-java-android
class UnzippingInterceptor : Interceptor {
@Throws(IOException::class)
override fun intercept(chain: Chain): Response {
val response: Response = chain.proceed(chain.request())
return unzip(response)
}
@Throws(IOException::class)
private fun unzip(response: Response): Response {
if (response.body == null) {
return response
}
// check if we have gzip response
val contentEncoding: String? = response.headers["Content-Encoding"]
// this is used to decompress gzipped responses
return if (contentEncoding != null && contentEncoding == "gzip") {
val body = response.body!!
val contentLength: Long = body.contentLength()
val responseBody = GzipSource(body.source())
val strippedHeaders: Headers = response.headers.newBuilder().build()
response.newBuilder().headers(strippedHeaders)
.body(RealResponseBody(body.contentType().toString(), contentLength, responseBody.buffer()))
.build()
} else {
response
}
}
}

View File

@ -1,4 +1,4 @@
package ir.armor.tachidesk.impl.util.storage
package suwayomi.tachidesk.impl.util.storage
/*
* Copyright (C) Contributors to the Suwayomi project

View File

@ -1,5 +1,9 @@
package ir.armor.tachidesk.impl.util.storage
package suwayomi.tachidesk.impl.util.storage
import suwayomi.tachidesk.impl.util.storage.ImageUtil.ImageType.GIF
import suwayomi.tachidesk.impl.util.storage.ImageUtil.ImageType.JPG
import suwayomi.tachidesk.impl.util.storage.ImageUtil.ImageType.PNG
import suwayomi.tachidesk.impl.util.storage.ImageUtil.ImageType.WEBP
import java.io.InputStream
/*
@ -32,16 +36,16 @@ object ImageUtil {
}
if (bytes.compareWith(charByteArrayOf(0xFF, 0xD8, 0xFF))) {
return ImageType.JPG
return JPG
}
if (bytes.compareWith(charByteArrayOf(0x89, 0x50, 0x4E, 0x47))) {
return ImageType.PNG
return PNG
}
if (bytes.compareWith("GIF8".toByteArray())) {
return ImageType.GIF
return GIF
}
if (bytes.compareWith("RIFF".toByteArray())) {
return ImageType.WEBP
return WEBP
}
} catch (e: Exception) {
}

View File

@ -1,4 +1,4 @@
package ir.armor.tachidesk.impl.util.storage
package suwayomi.tachidesk.impl.util.storage
/*
* Copyright (C) Contributors to the Suwayomi project

View File

@ -1,4 +1,4 @@
package ir.armor.tachidesk.impl.util.storage
package suwayomi.tachidesk.impl.util.storage
/*
* Copyright (C) Contributors to the Suwayomi project

View File

@ -1,4 +1,4 @@
package ir.armor.tachidesk.model.database
package suwayomi.tachidesk.model.database
/*
* Copyright (C) Contributors to the Suwayomi project
@ -7,13 +7,13 @@ package ir.armor.tachidesk.model.database
* 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.model.database.migration.lib.loadMigrationsFrom
import ir.armor.tachidesk.model.database.migration.lib.runMigrations
import ir.armor.tachidesk.server.ApplicationDirs
import org.jetbrains.exposed.sql.Database
import org.kodein.di.DI
import org.kodein.di.conf.global
import org.kodein.di.instance
import suwayomi.server.ApplicationDirs
import suwayomi.tachidesk.model.database.migration.lib.loadMigrationsFrom
import suwayomi.tachidesk.model.database.migration.lib.runMigrations
object DBManager {
val db by lazy {
@ -27,6 +27,6 @@ fun databaseUp() {
val db = DBManager.db
db.useNestedTransactions = true
val migrations = loadMigrationsFrom("ir.armor.tachidesk.model.database.migration")
val migrations = loadMigrationsFrom("suwayomi.tachidesk.model.database.migration")
runMigrations(migrations)
}

View File

@ -1,4 +1,4 @@
package ir.armor.tachidesk.model.database.migration
package suwayomi.tachidesk.model.database.migration
/*
* Copyright (C) Contributors to the Suwayomi project
@ -8,11 +8,11 @@ package ir.armor.tachidesk.model.database.migration
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
import eu.kanade.tachiyomi.source.model.SManga
import ir.armor.tachidesk.model.database.migration.lib.Migration
import org.jetbrains.exposed.dao.id.IdTable
import org.jetbrains.exposed.dao.id.IntIdTable
import org.jetbrains.exposed.sql.SchemaUtils
import org.jetbrains.exposed.sql.transactions.transaction
import suwayomi.tachidesk.model.database.migration.lib.Migration
@Suppress("ClassName", "unused")
class M0001_Initial : Migration() {
@ -104,10 +104,10 @@ class M0001_Initial : Migration() {
}
}
private class CategoryMangaTable : IntIdTable() {
private class CategoryMangaTable(categoryTable: CategoryTable, mangaTable: MangaTable) : IntIdTable() {
init {
reference("category", ir.armor.tachidesk.model.database.table.CategoryTable)
reference("manga", ir.armor.tachidesk.model.database.table.MangaTable)
reference("category", categoryTable)
reference("manga", mangaTable)
}
}
@ -120,7 +120,7 @@ class M0001_Initial : Migration() {
val chapterTable = ChapterTable(mangaTable)
val pageTable = PageTable(chapterTable)
val categoryTable = CategoryTable()
val categoryMangaTable = CategoryMangaTable()
val categoryMangaTable = CategoryMangaTable(categoryTable, mangaTable)
SchemaUtils.create(
extensionTable,
sourceTable,

View File

@ -1,4 +1,4 @@
package ir.armor.tachidesk.model.database.migration
package suwayomi.tachidesk.model.database.migration
/*
* Copyright (C) Contributors to the Suwayomi project
@ -7,9 +7,9 @@ package ir.armor.tachidesk.model.database.migration
* 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.model.database.migration.lib.Migration
import org.jetbrains.exposed.sql.transactions.TransactionManager
import org.jetbrains.exposed.sql.vendors.currentDialect
import suwayomi.tachidesk.model.database.migration.lib.Migration
@Suppress("ClassName", "unused")
class M0002_ChapterTableIndexRename : Migration() {

View File

@ -1,16 +1,16 @@
package ir.armor.tachidesk.model.database.migration
import ir.armor.tachidesk.model.database.migration.lib.Migration
import org.jetbrains.exposed.sql.transactions.TransactionManager
import org.jetbrains.exposed.sql.vendors.currentDialect
package suwayomi.tachidesk.model.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 org.jetbrains.exposed.sql.transactions.TransactionManager
import org.jetbrains.exposed.sql.vendors.currentDialect
import suwayomi.tachidesk.model.database.migration.lib.Migration
@Suppress("ClassName", "unused")
class M0003_DefaultCategory : Migration() {
/** this migration renamed CategoryTable.IS_LANDING to ChapterTable.IS_DEFAULT */

View File

@ -1,4 +1,4 @@
package ir.armor.tachidesk.model.database.migration.lib
package suwayomi.tachidesk.model.database.migration.lib
/*
* Copyright (C) Contributors to the Suwayomi project

View File

@ -1,4 +1,4 @@
package ir.armor.tachidesk.model.database.migration.lib
package suwayomi.tachidesk.model.database.migration.lib
/*
* Copyright (C) Contributors to the Suwayomi project

View File

@ -1,4 +1,4 @@
package ir.armor.tachidesk.model.database.migration.lib
package suwayomi.tachidesk.model.database.migration.lib
/*
* Copyright (C) Contributors to the Suwayomi project
@ -10,7 +10,6 @@ package ir.armor.tachidesk.model.database.migration.lib
// originally licenced under MIT by Andreas Mausch, Changes are licenced under Mozilla Public License, v. 2.0.
// adopted from: https://gitlab.com/andreas-mausch/exposed-migrations/-/tree/4bf853c18a24d0170eda896ddbb899cb01233595
import ir.armor.tachidesk.server.ServerConfig
import mu.KotlinLogging
import org.jetbrains.exposed.dao.id.EntityID
import org.jetbrains.exposed.sql.Database
@ -18,6 +17,7 @@ import org.jetbrains.exposed.sql.SchemaUtils.create
import org.jetbrains.exposed.sql.exists
import org.jetbrains.exposed.sql.transactions.TransactionManager
import org.jetbrains.exposed.sql.transactions.transaction
import suwayomi.server.ServerConfig
import java.nio.file.FileSystems
import java.nio.file.Files
import java.nio.file.Paths
@ -63,7 +63,7 @@ fun runMigrations(migrations: List<Migration>, database: Database = TransactionM
@OptIn(ExperimentalPathApi::class)
private fun getTopLevelClasses(packageName: String): List<Class<*>> {
ServerConfig::class.java.getResource("/" + "ir.armor.tachidesk.model.database.migration".replace('.', '/'))
ServerConfig::class.java.getResource("/" + "suwayomi.tachidesk.model.database.migration".replace('.', '/'))
val path = "/" + packageName.replace('.', '/')
val uri = ServerConfig::class.java.getResource(path).toURI()

View File

@ -1,4 +1,4 @@
package ir.armor.tachidesk.model.database.table
package suwayomi.tachidesk.model.database.table
/*
* Copyright (C) Contributors to the Suwayomi project

View File

@ -1,4 +1,4 @@
package ir.armor.tachidesk.model.database.table
package suwayomi.tachidesk.model.database.table
/*
* Copyright (C) Contributors to the Suwayomi project
@ -7,9 +7,9 @@ package ir.armor.tachidesk.model.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.model.dataclass.CategoryDataClass
import org.jetbrains.exposed.dao.id.IntIdTable
import org.jetbrains.exposed.sql.ResultRow
import suwayomi.tachidesk.model.dataclass.CategoryDataClass
object CategoryTable : IntIdTable() {
val name = varchar("name", 64)
@ -19,7 +19,7 @@ object CategoryTable : IntIdTable() {
fun CategoryTable.toDataClass(categoryEntry: ResultRow) = CategoryDataClass(
categoryEntry[this.id].value,
categoryEntry[this.order],
categoryEntry[this.name],
categoryEntry[this.isDefault],
categoryEntry[order],
categoryEntry[name],
categoryEntry[isDefault],
)

View File

@ -1,4 +1,4 @@
package ir.armor.tachidesk.model.database.table
package suwayomi.tachidesk.model.database.table
/*
* Copyright (C) Contributors to the Suwayomi project
@ -7,9 +7,9 @@ package ir.armor.tachidesk.model.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.model.dataclass.ChapterDataClass
import org.jetbrains.exposed.dao.id.IntIdTable
import org.jetbrains.exposed.sql.ResultRow
import suwayomi.tachidesk.model.dataclass.ChapterDataClass
object ChapterTable : IntIdTable() {
val url = varchar("url", 2048)
@ -30,14 +30,14 @@ object ChapterTable : IntIdTable() {
fun ChapterTable.toDataClass(chapterEntry: ResultRow) =
ChapterDataClass(
chapterEntry[this.url],
chapterEntry[this.name],
chapterEntry[this.date_upload],
chapterEntry[this.chapter_number],
chapterEntry[this.scanlator],
chapterEntry[this.manga].value,
chapterEntry[this.isRead],
chapterEntry[this.isBookmarked],
chapterEntry[this.lastPageRead],
chapterEntry[this.chapterIndex],
chapterEntry[url],
chapterEntry[name],
chapterEntry[date_upload],
chapterEntry[chapter_number],
chapterEntry[scanlator],
chapterEntry[manga].value,
chapterEntry[isRead],
chapterEntry[isBookmarked],
chapterEntry[lastPageRead],
chapterEntry[chapterIndex],
)

View File

@ -1,4 +1,4 @@
package ir.armor.tachidesk.model.database.table
package suwayomi.tachidesk.model.database.table
/*
* Copyright (C) Contributors to the Suwayomi project

View File

@ -1,4 +1,4 @@
package ir.armor.tachidesk.model.database.table
package suwayomi.tachidesk.model.database.table
/*
* Copyright (C) Contributors to the Suwayomi project
@ -8,10 +8,11 @@ package ir.armor.tachidesk.model.database.table
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
import eu.kanade.tachiyomi.source.model.SManga
import ir.armor.tachidesk.impl.MangaList.proxyThumbnailUrl
import ir.armor.tachidesk.model.dataclass.MangaDataClass
import org.jetbrains.exposed.dao.id.IntIdTable
import org.jetbrains.exposed.sql.ResultRow
import suwayomi.tachidesk.impl.MangaList.proxyThumbnailUrl
import suwayomi.tachidesk.model.database.table.MangaStatus.Companion
import suwayomi.tachidesk.model.dataclass.MangaDataClass
object MangaTable : IntIdTable() {
val url = varchar("url", 2048)
@ -37,20 +38,20 @@ object MangaTable : IntIdTable() {
fun MangaTable.toDataClass(mangaEntry: ResultRow) =
MangaDataClass(
mangaEntry[this.id].value,
mangaEntry[this.sourceReference].toString(),
mangaEntry[sourceReference].toString(),
mangaEntry[this.url],
mangaEntry[this.title],
mangaEntry[url],
mangaEntry[title],
proxyThumbnailUrl(mangaEntry[this.id].value),
mangaEntry[this.initialized],
mangaEntry[initialized],
mangaEntry[this.artist],
mangaEntry[this.author],
mangaEntry[this.description],
mangaEntry[this.genre],
MangaStatus.valueOf(mangaEntry[this.status]).name,
mangaEntry[this.inLibrary]
mangaEntry[artist],
mangaEntry[author],
mangaEntry[description],
mangaEntry[genre],
Companion.valueOf(mangaEntry[status]).name,
mangaEntry[inLibrary]
)
enum class MangaStatus(val status: Int) {

View File

@ -1,4 +1,4 @@
package ir.armor.tachidesk.model.database.table
package suwayomi.tachidesk.model.database.table
/*
* Copyright (C) Contributors to the Suwayomi project

View File

@ -1,4 +1,4 @@
package ir.armor.tachidesk.model.database.table
package suwayomi.tachidesk.model.database.table
/*
* Copyright (C) Contributors to the Suwayomi project

View File

@ -1,4 +1,4 @@
package ir.armor.tachidesk.model.dataclass
package suwayomi.tachidesk.model.dataclass
/*
* Copyright (C) Contributors to the Suwayomi project

View File

@ -1,4 +1,4 @@
package ir.armor.tachidesk.model.dataclass
package suwayomi.tachidesk.model.dataclass
/*
* Copyright (C) Contributors to the Suwayomi project

View File

@ -1,4 +1,4 @@
package ir.armor.tachidesk.model.dataclass
package suwayomi.tachidesk.model.dataclass
/*
* Copyright (C) Contributors to the Suwayomi project

View File

@ -1,4 +1,4 @@
package ir.armor.tachidesk.model.dataclass
package suwayomi.tachidesk.model.dataclass
/*
* Copyright (C) Contributors to the Suwayomi project
@ -7,7 +7,7 @@ package ir.armor.tachidesk.model.dataclass
* 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.model.database.table.MangaStatus
import suwayomi.tachidesk.model.database.table.MangaStatus
data class MangaDataClass(
val id: Int,

View File

@ -1,4 +1,4 @@
package ir.armor.tachidesk.model.dataclass
package suwayomi.tachidesk.model.dataclass
/*
* Copyright (C) Contributors to the Suwayomi project

View File

@ -1,4 +1,4 @@
package ir.armor.tachidesk.model.dataclass
package suwayomi.tachidesk.model.dataclass
/*
* Copyright (C) Contributors to the Suwayomi project

View File

@ -1,4 +1,4 @@
package ir.armor.tachidesk
package suwayomi
/*
* Copyright (C) Contributors to the Suwayomi project
@ -10,15 +10,6 @@ package ir.armor.tachidesk
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.impl.Source.getSourceList
import ir.armor.tachidesk.impl.extension.Extension.installExtension
import ir.armor.tachidesk.impl.extension.Extension.uninstallExtension
import ir.armor.tachidesk.impl.extension.Extension.updateExtension
import ir.armor.tachidesk.impl.extension.ExtensionsList.getExtensionList
import ir.armor.tachidesk.impl.util.GetHttpSource.getHttpSource
import ir.armor.tachidesk.impl.util.lang.awaitSingle
import ir.armor.tachidesk.model.dataclass.ExtensionDataClass
import ir.armor.tachidesk.server.applicationSetup
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.awaitAll
@ -30,6 +21,15 @@ import org.junit.jupiter.api.BeforeAll
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.TestInstance
import rx.Observable
import suwayomi.server.applicationSetup
import suwayomi.tachidesk.impl.Source.getSourceList
import suwayomi.tachidesk.impl.extension.Extension.installExtension
import suwayomi.tachidesk.impl.extension.Extension.uninstallExtension
import suwayomi.tachidesk.impl.extension.Extension.updateExtension
import suwayomi.tachidesk.impl.extension.ExtensionsList.getExtensionList
import suwayomi.tachidesk.impl.util.GetHttpSource.getHttpSource
import suwayomi.tachidesk.impl.util.lang.awaitSingle
import suwayomi.tachidesk.model.dataclass.ExtensionDataClass
import java.io.File
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
@ -48,7 +48,7 @@ class TestExtensions {
@BeforeAll
fun setup() {
val dataRoot = File("tmp/TestDesk").absolutePath
System.setProperty("ir.armor.tachidesk.rootDir", dataRoot)
System.setProperty("suwayomi.tachidesk.rootDir", dataRoot)
applicationSetup()
setLoggingEnabled(false)

View File

@ -1,4 +1,4 @@
package ir.armor.tachidesk
package suwayomi
/*
* Copyright (C) Contributors to the Suwayomi project