diff --git a/server/src/main/kotlin/eu/kanade/tachiyomi/extension/api/ExtensionGithubApi.kt b/server/src/main/kotlin/eu/kanade/tachiyomi/extension/api/ExtensionGithubApi.kt deleted file mode 100644 index 6eb0f33..0000000 --- a/server/src/main/kotlin/eu/kanade/tachiyomi/extension/api/ExtensionGithubApi.kt +++ /dev/null @@ -1,52 +0,0 @@ -package eu.kanade.tachiyomi.extension.api - -/* - * 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 eu.kanade.tachiyomi.extension.model.Extension -import eu.kanade.tachiyomi.extension.util.ExtensionLoader -import ir.armor.tachidesk.model.dataclass.ExtensionDataClass - -object ExtensionGithubApi { - const val BASE_URL = "https://raw.githubusercontent.com" - const val REPO_URL_PREFIX = "$BASE_URL/tachiyomiorg/tachiyomi-extensions/repo" - - private fun parseResponse(json: JsonArray): List { - return json - .map { it.asJsonObject } - .filter { element -> - val versionName = element["version"].string - val libVersion = versionName.substringBeforeLast('.').toDouble() - libVersion >= ExtensionLoader.LIB_VERSION_MIN && libVersion <= ExtensionLoader.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")}" - - Extension.Available(name, pkgName, versionName, versionCode, lang, nsfw, apkName, icon) - } - } - - suspend fun findExtensions(): List { - - val response = ExtensionGithubService.getRepo() - return parseResponse(response) - } - - fun getApkUrl(extension: ExtensionDataClass): String { - return "$REPO_URL_PREFIX/apk/${extension.apkName}" - } -} diff --git a/server/src/main/kotlin/eu/kanade/tachiyomi/extension/model/Extension.kt b/server/src/main/kotlin/eu/kanade/tachiyomi/extension/model/Extension.kt deleted file mode 100644 index 480c3b0..0000000 --- a/server/src/main/kotlin/eu/kanade/tachiyomi/extension/model/Extension.kt +++ /dev/null @@ -1,47 +0,0 @@ -package eu.kanade.tachiyomi.extension.model - -import eu.kanade.tachiyomi.source.Source - -sealed class Extension { - - abstract val name: String - abstract val pkgName: String - abstract val versionName: String - abstract val versionCode: Int - abstract val lang: String? - abstract val isNsfw: Boolean - - data class Installed( - override val name: String, - override val pkgName: String, - override val versionName: String, - override val versionCode: Int, - override val lang: String, - override val isNsfw: Boolean, - val sources: List, - val hasUpdate: Boolean = false, - val isObsolete: Boolean = false, - val isUnofficial: Boolean = false - ) : Extension() - - data class Available( - override val name: String, - override val pkgName: String, - override val versionName: String, - override val versionCode: Int, - override val lang: String, - override val isNsfw: Boolean, - val apkName: String, - val iconUrl: String - ) : Extension() - - data class Untrusted( - override val name: String, - override val pkgName: String, - override val versionName: String, - override val versionCode: Int, - val signatureHash: String, - override val lang: String? = null, - override val isNsfw: Boolean = false - ) : Extension() -} diff --git a/server/src/main/kotlin/eu/kanade/tachiyomi/extension/model/InstallStep.kt b/server/src/main/kotlin/eu/kanade/tachiyomi/extension/model/InstallStep.kt deleted file mode 100644 index 43bb519..0000000 --- a/server/src/main/kotlin/eu/kanade/tachiyomi/extension/model/InstallStep.kt +++ /dev/null @@ -1,9 +0,0 @@ -package eu.kanade.tachiyomi.extension.model - -enum class InstallStep { - Pending, Downloading, Installing, Installed, Error; - - fun isCompleted(): Boolean { - return this == Installed || this == Error - } -} diff --git a/server/src/main/kotlin/eu/kanade/tachiyomi/extension/model/LoadResult.kt b/server/src/main/kotlin/eu/kanade/tachiyomi/extension/model/LoadResult.kt deleted file mode 100644 index 0cf470f..0000000 --- a/server/src/main/kotlin/eu/kanade/tachiyomi/extension/model/LoadResult.kt +++ /dev/null @@ -1,10 +0,0 @@ -package eu.kanade.tachiyomi.extension.model - -sealed class LoadResult { - - class Success(val extension: Extension.Installed) : LoadResult() - class Untrusted(val extension: Extension.Untrusted) : LoadResult() - class Error(val message: String? = null) : LoadResult() { - constructor(exception: Throwable) : this(exception.message) - } -} diff --git a/server/src/main/kotlin/eu/kanade/tachiyomi/extension/util/ExtensionLoader.kt b/server/src/main/kotlin/eu/kanade/tachiyomi/extension/util/ExtensionLoader.kt deleted file mode 100644 index 4cff898..0000000 --- a/server/src/main/kotlin/eu/kanade/tachiyomi/extension/util/ExtensionLoader.kt +++ /dev/null @@ -1,234 +0,0 @@ -package eu.kanade.tachiyomi.extension.util - -/* - * 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 android.annotation.SuppressLint -// import android.content.Context -// import android.content.pm.PackageInfo -// import android.content.pm.PackageManager -// import dalvik.system.PathClassLoader -// import eu.kanade.tachiyomi.data.preference.PreferenceValues -// import eu.kanade.tachiyomi.data.preference.PreferencesHelper -// import eu.kanade.tachiyomi.util.lang.Hash -// import kotlinx.coroutines.async -// import kotlinx.coroutines.runBlocking -// import timber.log.Timber -// import uy.kohesive.injekt.injectLazy - -/** - * Class that handles the loading of the extensions installed in the system. - */ -// @SuppressLint("PackageManagerGetSignatures") -internal object ExtensionLoader { - -// private val preferences: PreferencesHelper by injectLazy() -// private val allowNsfwSource by lazy { -// preferences.allowNsfwSource().get() -// } - - private const val EXTENSION_FEATURE = "tachiyomi.extension" - private const val METADATA_SOURCE_CLASS = "tachiyomi.extension.class" - private const val METADATA_NSFW = "tachiyomi.extension.nsfw" - const val LIB_VERSION_MIN = 1.2 - const val LIB_VERSION_MAX = 1.2 - -// private const val PACKAGE_FLAGS = PackageManager.GET_CONFIGURATIONS or PackageManager.GET_SIGNATURES - - // inorichi's key - private const val officialSignature = "7ce04da7773d41b489f4693a366c36bcd0a11fc39b547168553c285bd7348e23" - /** - * List of the trusted signatures. - */ -// var trustedSignatures = mutableSetOf() + preferences.trustedSignatures().get() + officialSignature - - /** - * Return a list of all the installed extensions initialized concurrently. - * - * @param context The application context. - */ -// fun loadExtensions(context: Context): List { -// val pkgManager = context.packageManager -// val installedPkgs = pkgManager.getInstalledPackages(PACKAGE_FLAGS) -// val extPkgs = installedPkgs.filter { isPackageAnExtension(it) } -// -// if (extPkgs.isEmpty()) return emptyList() -// -// // Load each extension concurrently and wait for completion -// return runBlocking { -// val deferred = extPkgs.map { -// async { loadExtension(context, it.packageName, it) } -// } -// deferred.map { it.await() } -// } -// } - - /** - * Attempts to load an extension from the given package name. It checks if the extension - * contains the required feature flag before trying to load it. - */ -// fun loadExtensionFromPkgName(context: Context, pkgName: String): LoadResult { -// val pkgInfo = try { -// context.packageManager.getPackageInfo(pkgName, PACKAGE_FLAGS) -// } catch (error: PackageManager.NameNotFoundException) { -// // Unlikely, but the package may have been uninstalled at this point -// return LoadResult.Error(error) -// } -// if (!isPackageAnExtension(pkgInfo)) { -// return LoadResult.Error("Tried to load a package that wasn't a extension") -// } -// return loadExtension(context, pkgName, pkgInfo) -// } - - /** - * Loads an extension given its package name. - * - * @param context The application context. - * @param pkgName The package name of the extension to load. - * @param pkgInfo The package info of the extension. - */ -// private fun loadExtension(context: Context, pkgName: String, pkgInfo: PackageInfo): LoadResult { -// val pkgManager = context.packageManager -// -// val appInfo = try { -// pkgManager.getApplicationInfo(pkgName, PackageManager.GET_META_DATA) -// } catch (error: PackageManager.NameNotFoundException) { -// // Unlikely, but the package may have been uninstalled at this point -// return LoadResult.Error(error) -// } -// -// val extName = pkgManager.getApplicationLabel(appInfo).toString().substringAfter("Tachiyomi: ") -// val versionName = pkgInfo.versionName -// val versionCode = pkgInfo.versionCode -// -// if (versionName.isNullOrEmpty()) { -// val exception = Exception("Missing versionName for extension $extName") -// Timber.w(exception) -// return LoadResult.Error(exception) -// } -// -// // Validate lib version -// val libVersion = versionName.substringBeforeLast('.').toDouble() -// if (libVersion < LIB_VERSION_MIN || libVersion > LIB_VERSION_MAX) { -// val exception = Exception( -// "Lib version is $libVersion, while only versions " + -// "$LIB_VERSION_MIN to $LIB_VERSION_MAX are allowed" -// ) -// Timber.w(exception) -// return LoadResult.Error(exception) -// } -// -// val signatureHash = getSignatureHash(pkgInfo) -// -// if (signatureHash == null) { -// return LoadResult.Error("Package $pkgName isn't signed") -// } else if (signatureHash !in trustedSignatures) { -// val extension = Extension.Untrusted(extName, pkgName, versionName, versionCode, signatureHash) -// Timber.w("Extension $pkgName isn't trusted") -// return LoadResult.Untrusted(extension) -// } -// -// val isNsfw = appInfo.metaData.getInt(METADATA_NSFW) == 1 -// if (allowNsfwSource == PreferenceValues.NsfwAllowance.BLOCKED && isNsfw) { -// return LoadResult.Error("NSFW extension $pkgName not allowed") -// } -// -// val classLoader = PathClassLoader(appInfo.sourceDir, null, context.classLoader) -// -// val sources = appInfo.metaData.getString(METADATA_SOURCE_CLASS)!! -// .split(";") -// .map { -// val sourceClass = it.trim() -// if (sourceClass.startsWith(".")) { -// pkgInfo.packageName + sourceClass -// } else { -// sourceClass -// } -// } -// .flatMap { -// try { -// when (val obj = Class.forName(it, false, classLoader).newInstance()) { -// is Source -> listOf(obj) -// is SourceFactory -> { -// if (isSourceNsfw(obj)) { -// emptyList() -// } else { -// obj.createSources() -// } -// } -// else -> throw Exception("Unknown source class type! ${obj.javaClass}") -// } -// } catch (e: Throwable) { -// Timber.e(e, "Extension load error: $extName.") -// return LoadResult.Error(e) -// } -// } -// .filter { !isSourceNsfw(it) } -// -// val langs = sources.filterIsInstance() -// .map { it.lang } -// .toSet() -// val lang = when (langs.size) { -// 0 -> "" -// 1 -> langs.first() -// else -> "all" -// } -// -// val extension = Extension.Installed( -// extName, -// pkgName, -// versionName, -// versionCode, -// lang, -// isNsfw, -// sources, -// isUnofficial = signatureHash != officialSignature -// ) -// return LoadResult.Success(extension) -// } - - /** - * Returns true if the given package is an extension. - * - * @param pkgInfo The package info of the application. - */ -// private fun isPackageAnExtension(pkgInfo: PackageInfo): Boolean { -// return pkgInfo.reqFeatures.orEmpty().any { it.name == EXTENSION_FEATURE } -// } - - /** - * Returns the signature hash of the package or null if it's not signed. - * - * @param pkgInfo The package info of the application. - */ -// private fun getSignatureHash(pkgInfo: PackageInfo): String? { -// val signatures = pkgInfo.signatures -// return if (signatures != null && signatures.isNotEmpty()) { -// Hash.sha256(signatures.first().toByteArray()) -// } else { -// null -// } -// } - - /** - * Checks whether a Source or SourceFactory is annotated with @Nsfw. - */ -// private fun isSourceNsfw(clazz: Any): Boolean { -// if (allowNsfwSource == PreferenceValues.NsfwAllowance.ALLOWED) { -// return false -// } -// -// if (clazz !is Source && clazz !is SourceFactory) { -// return false -// } -// -// // Annotations are proxied, hence this janky way of checking for them -// return clazz.javaClass.annotations -// .flatMap { it.javaClass.interfaces.map { it.simpleName } } -// .firstOrNull { it == Nsfw::class.java.simpleName } != null -// } -} diff --git a/server/src/main/kotlin/ir/armor/tachidesk/impl/Source.kt b/server/src/main/kotlin/ir/armor/tachidesk/impl/Source.kt index 0852ddd..68a1398 100644 --- a/server/src/main/kotlin/ir/armor/tachidesk/impl/Source.kt +++ b/server/src/main/kotlin/ir/armor/tachidesk/impl/Source.kt @@ -7,7 +7,7 @@ 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.getExtensionIconUrl +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 diff --git a/server/src/main/kotlin/ir/armor/tachidesk/impl/Extension.kt b/server/src/main/kotlin/ir/armor/tachidesk/impl/extension/Extension.kt similarity index 98% rename from server/src/main/kotlin/ir/armor/tachidesk/impl/Extension.kt rename to server/src/main/kotlin/ir/armor/tachidesk/impl/extension/Extension.kt index 26d7cef..536299e 100644 --- a/server/src/main/kotlin/ir/armor/tachidesk/impl/Extension.kt +++ b/server/src/main/kotlin/ir/armor/tachidesk/impl/extension/Extension.kt @@ -1,4 +1,4 @@ -package ir.armor.tachidesk.impl +package ir.armor.tachidesk.impl.extension /* * Copyright (C) Contributors to the Suwayomi project @@ -8,13 +8,13 @@ package ir.armor.tachidesk.impl * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ import android.net.Uri -import eu.kanade.tachiyomi.extension.api.ExtensionGithubApi import eu.kanade.tachiyomi.network.GET 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.ExtensionsList.extensionTableAsDataClass +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 diff --git a/server/src/main/kotlin/ir/armor/tachidesk/impl/ExtensionsList.kt b/server/src/main/kotlin/ir/armor/tachidesk/impl/extension/ExtensionsList.kt similarity index 93% rename from server/src/main/kotlin/ir/armor/tachidesk/impl/ExtensionsList.kt rename to server/src/main/kotlin/ir/armor/tachidesk/impl/extension/ExtensionsList.kt index c373e54..f807412 100644 --- a/server/src/main/kotlin/ir/armor/tachidesk/impl/ExtensionsList.kt +++ b/server/src/main/kotlin/ir/armor/tachidesk/impl/extension/ExtensionsList.kt @@ -1,4 +1,4 @@ -package ir.armor.tachidesk.impl +package ir.armor.tachidesk.impl.extension /* * Copyright (C) Contributors to the Suwayomi project @@ -7,9 +7,9 @@ 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 eu.kanade.tachiyomi.extension.api.ExtensionGithubApi -import eu.kanade.tachiyomi.extension.model.Extension -import ir.armor.tachidesk.impl.Extension.getExtensionIconUrl +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 @@ -25,7 +25,7 @@ object ExtensionsList { private val logger = KotlinLogging.logger {} var lastUpdateCheck: Long = 0 - var updateMap = ConcurrentHashMap() + var updateMap = ConcurrentHashMap() /** 60,000 milliseconds = 60 seconds */ private const val ExtensionUpdateDelayTime = 60 * 1000 @@ -63,7 +63,7 @@ object ExtensionsList { } } - private fun updateExtensionDatabase(foundExtensions: List) { + private fun updateExtensionDatabase(foundExtensions: List) { transaction { foundExtensions.forEach { foundExtension -> val extensionRecord = ExtensionTable.select { ExtensionTable.pkgName eq foundExtension.pkgName }.firstOrNull() diff --git a/server/src/main/kotlin/eu/kanade/tachiyomi/extension/api/ExtensionGithubService.kt b/server/src/main/kotlin/ir/armor/tachidesk/impl/extension/github/ExtensionGithubApi.kt similarity index 53% rename from server/src/main/kotlin/eu/kanade/tachiyomi/extension/api/ExtensionGithubService.kt rename to server/src/main/kotlin/ir/armor/tachidesk/impl/extension/github/ExtensionGithubApi.kt index 478a707..ab3d81e 100644 --- a/server/src/main/kotlin/eu/kanade/tachiyomi/extension/api/ExtensionGithubService.kt +++ b/server/src/main/kotlin/ir/armor/tachidesk/impl/extension/github/ExtensionGithubApi.kt @@ -1,7 +1,18 @@ -package eu.kanade.tachiyomi.extension.api +package ir.armor.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 ir.armor.tachidesk.model.dataclass.ExtensionDataClass import okhttp3.Headers import okhttp3.Interceptor import okhttp3.Interceptor.Chain @@ -13,10 +24,44 @@ import okio.buffer import uy.kohesive.injekt.injectLazy import java.io.IOException -/** - * Used to get the extension repo listing from GitHub. - */ -object ExtensionGithubService { +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 fun parseResponse(json: JsonArray): List { + return json + .map { it.asJsonObject } + .filter { element -> + val versionName = element["version"].string + val libVersion = versionName.substringBeforeLast('.') + libVersion == 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 { + 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() @@ -31,9 +76,9 @@ object ExtensionGithubService { .build() } - suspend fun getRepo(): com.google.gson.JsonArray { + private fun getRepo(): com.google.gson.JsonArray { val request = Request.Builder() - .url("${ExtensionGithubApi.REPO_URL_PREFIX}/index.json.gz") + .url("$REPO_URL_PREFIX/index.json.gz") .build() val response = client.newCall(request).execute().use { response -> response.body!!.string() } diff --git a/server/src/main/kotlin/ir/armor/tachidesk/impl/extension/github/OnlineExtension.kt b/server/src/main/kotlin/ir/armor/tachidesk/impl/extension/github/OnlineExtension.kt new file mode 100644 index 0000000..12f9a27 --- /dev/null +++ b/server/src/main/kotlin/ir/armor/tachidesk/impl/extension/github/OnlineExtension.kt @@ -0,0 +1,12 @@ +package ir.armor.tachidesk.impl.extension.github + +data class OnlineExtension( + val name: String, + val pkgName: String, + val versionName: String, + val versionCode: Int, + val lang: String, + val isNsfw: Boolean, + val apkName: String, + val iconUrl: String +) diff --git a/server/src/main/kotlin/ir/armor/tachidesk/server/JavalinSetup.kt b/server/src/main/kotlin/ir/armor/tachidesk/server/JavalinSetup.kt index c5b1976..2ed62ad 100644 --- a/server/src/main/kotlin/ir/armor/tachidesk/server/JavalinSetup.kt +++ b/server/src/main/kotlin/ir/armor/tachidesk/server/JavalinSetup.kt @@ -13,11 +13,6 @@ 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.Extension.getExtensionIcon -import ir.armor.tachidesk.impl.Extension.installExtension -import ir.armor.tachidesk.impl.Extension.uninstallExtension -import ir.armor.tachidesk.impl.Extension.updateExtension -import ir.armor.tachidesk.impl.ExtensionsList.getExtensionList import ir.armor.tachidesk.impl.Library.addMangaToLibrary import ir.armor.tachidesk.impl.Library.getLibraryMangas import ir.armor.tachidesk.impl.Library.removeMangaFromLibrary @@ -33,6 +28,11 @@ 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.openInBrowser import kotlinx.coroutines.CoroutineScope diff --git a/server/src/test/kotlin/ir/armor/tachidesk/TestExtensions.kt b/server/src/test/kotlin/ir/armor/tachidesk/TestExtensions.kt index 397f850..de277fe 100644 --- a/server/src/test/kotlin/ir/armor/tachidesk/TestExtensions.kt +++ b/server/src/test/kotlin/ir/armor/tachidesk/TestExtensions.kt @@ -10,11 +10,11 @@ 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.Extension.installExtension -import ir.armor.tachidesk.impl.Extension.uninstallExtension -import ir.armor.tachidesk.impl.Extension.updateExtension -import ir.armor.tachidesk.impl.ExtensionsList.getExtensionList 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