From 4ace76f508a366ce130f59c3b46e60b791dfa017 Mon Sep 17 00:00:00 2001 From: Syer10 Date: Tue, 23 Jun 2026 17:07:25 -0400 Subject: [PATCH] Update to latest Mihon extension lib --- .../kanade/tachiyomi/network/NetworkHelper.kt | 3 - .../interceptor/IgnoreGzipInterceptor.kt | 21 ---- .../tachiyomi/source/local/LocalSource.kt | 2 +- .../mutations/ExtensionStoreMutation.kt | 1 + .../graphql/queries/ExtensionQuery.kt | 20 ++-- .../tachidesk/graphql/queries/SourceQuery.kt | 22 ++-- .../graphql/queries/filter/Filter.kt | 34 +++--- .../graphql/types/ExtensionStoreType.kt | 2 + .../tachidesk/graphql/types/ExtensionType.kt | 10 +- .../tachidesk/graphql/types/SourceType.kt | 12 +- .../suwayomi/tachidesk/manga/impl/Source.kt | 6 +- .../manga/impl/extension/Extension.kt | 36 +++--- .../impl/extension/ExtensionStoreService.kt | 108 ++++++++++++------ .../manga/impl/extension/ExtensionsList.kt | 8 +- .../extension/github/NetworkExtensionStore.kt | 55 ++++----- .../github/NetworkLegacyExtension.kt | 8 +- .../github/NetworkLegacyExtensionRepo.kt | 1 + .../tachidesk/manga/impl/util/PackageTools.kt | 5 + .../manga/model/dataclass/ExtensionInfo.kt | 13 +-- .../manga/model/dataclass/ExtensionStore.kt | 1 + .../manga/model/table/ExtensionStoreTable.kt | 1 + .../manga/model/table/ExtensionTable.kt | 2 +- .../manga/model/table/SourceTable.kt | 4 +- .../M0057_AddNewExtensionApiFields.kt | 11 +- .../migration/M0058_AddExtensionStore.kt | 1 + 25 files changed, 206 insertions(+), 181 deletions(-) delete mode 100644 server/src/main/kotlin/eu/kanade/tachiyomi/network/interceptor/IgnoreGzipInterceptor.kt diff --git a/server/src/main/kotlin/eu/kanade/tachiyomi/network/NetworkHelper.kt b/server/src/main/kotlin/eu/kanade/tachiyomi/network/NetworkHelper.kt index 6e339ee2b..89aa8b1de 100644 --- a/server/src/main/kotlin/eu/kanade/tachiyomi/network/NetworkHelper.kt +++ b/server/src/main/kotlin/eu/kanade/tachiyomi/network/NetworkHelper.kt @@ -9,7 +9,6 @@ package eu.kanade.tachiyomi.network import android.content.Context import eu.kanade.tachiyomi.network.interceptor.CloudflareInterceptor -import eu.kanade.tachiyomi.network.interceptor.IgnoreGzipInterceptor import eu.kanade.tachiyomi.network.interceptor.UncaughtExceptionInterceptor import eu.kanade.tachiyomi.network.interceptor.UserAgentInterceptor import io.github.oshai.kotlinlogging.KotlinLogging @@ -84,8 +83,6 @@ class NetworkHelper( ), ).addInterceptor(UncaughtExceptionInterceptor()) .addInterceptor(UserAgentInterceptor(::defaultUserAgentProvider)) - .addNetworkInterceptor(IgnoreGzipInterceptor()) - .addNetworkInterceptor(BrotliInterceptor) // if (preferences.verboseLogging().get()) { val httpLoggingInterceptor = diff --git a/server/src/main/kotlin/eu/kanade/tachiyomi/network/interceptor/IgnoreGzipInterceptor.kt b/server/src/main/kotlin/eu/kanade/tachiyomi/network/interceptor/IgnoreGzipInterceptor.kt deleted file mode 100644 index f1331a576..000000000 --- a/server/src/main/kotlin/eu/kanade/tachiyomi/network/interceptor/IgnoreGzipInterceptor.kt +++ /dev/null @@ -1,21 +0,0 @@ -package eu.kanade.tachiyomi.network.interceptor - -import okhttp3.Interceptor -import okhttp3.Response - -/** - * To use [okhttp3.brotli.BrotliInterceptor] as a network interceptor, - * add [IgnoreGzipInterceptor] right before it. - * - * This nullifies the transparent gzip of [okhttp3.internal.http.BridgeInterceptor] - * so gzip and Brotli are explicitly handled by the [okhttp3.brotli.BrotliInterceptor]. - */ -class IgnoreGzipInterceptor : Interceptor { - override fun intercept(chain: Interceptor.Chain): Response { - var request = chain.request() - if (request.header("Accept-Encoding") == "gzip") { - request = request.newBuilder().removeHeader("Accept-Encoding").build() - } - return chain.proceed(request) - } -} diff --git a/server/src/main/kotlin/eu/kanade/tachiyomi/source/local/LocalSource.kt b/server/src/main/kotlin/eu/kanade/tachiyomi/source/local/LocalSource.kt index 43258ab81..0dc2b986a 100644 --- a/server/src/main/kotlin/eu/kanade/tachiyomi/source/local/LocalSource.kt +++ b/server/src/main/kotlin/eu/kanade/tachiyomi/source/local/LocalSource.kt @@ -483,7 +483,7 @@ class LocalSource( it[versionCode] = 0 it[lang] = LANG it[extensionLib] = "1.2" - it[contentRating] = 0 + it[contentWarning] = 0 it[isInstalled] = true } diff --git a/server/src/main/kotlin/suwayomi/tachidesk/graphql/mutations/ExtensionStoreMutation.kt b/server/src/main/kotlin/suwayomi/tachidesk/graphql/mutations/ExtensionStoreMutation.kt index 39c29669b..1fa9b190d 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/graphql/mutations/ExtensionStoreMutation.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/graphql/mutations/ExtensionStoreMutation.kt @@ -95,6 +95,7 @@ class ExtensionStoreMutation { contactDiscord = it.contactDiscord, indexUrl = it.indexUrl, isLegacy = it.isLegacy, + extensionListUrl = it.extensionListUrl, ) }, ) diff --git a/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/ExtensionQuery.kt b/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/ExtensionQuery.kt index ac41cecf7..be0ab67f2 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/ExtensionQuery.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/ExtensionQuery.kt @@ -21,7 +21,7 @@ import org.jetbrains.exposed.v1.jdbc.selectAll import org.jetbrains.exposed.v1.jdbc.transactions.transaction import suwayomi.tachidesk.graphql.directives.RequireAuth import suwayomi.tachidesk.graphql.queries.filter.BooleanFilter -import suwayomi.tachidesk.graphql.queries.filter.ContentRatingFilter +import suwayomi.tachidesk.graphql.queries.filter.ContentWarningFilter import suwayomi.tachidesk.graphql.queries.filter.Filter import suwayomi.tachidesk.graphql.queries.filter.HasGetOp import suwayomi.tachidesk.graphql.queries.filter.IntFilter @@ -43,7 +43,7 @@ import suwayomi.tachidesk.graphql.server.primitives.lessNotUnique import suwayomi.tachidesk.graphql.server.primitives.maybeSwap import suwayomi.tachidesk.graphql.types.ExtensionNodeList import suwayomi.tachidesk.graphql.types.ExtensionType -import suwayomi.tachidesk.manga.model.dataclass.ContentRating +import suwayomi.tachidesk.manga.model.dataclass.ContentWarning import suwayomi.tachidesk.manga.model.table.ExtensionTable import java.util.concurrent.CompletableFuture @@ -108,9 +108,9 @@ class ExtensionQuery { val versionCode: Int? = null, val versionCodeLong: Long? = null, val lang: String? = null, - @GraphQLDeprecated("", ReplaceWith("contentRating")) + @GraphQLDeprecated("", ReplaceWith("contentWarning")) val isNsfw: Boolean? = null, - val contentRating: ContentRating? = null, + val contentWarning: ContentWarning? = null, val isInstalled: Boolean? = null, val hasUpdate: Boolean? = null, val isObsolete: Boolean? = null, @@ -129,10 +129,10 @@ class ExtensionQuery { opAnd.eq(versionCodeLong, ExtensionTable.versionCode) opAnd.eq(lang, ExtensionTable.lang) opAnd.eq( - isNsfw?.let { if (it) ContentRating.PORNOGRAPHIC.ordinal else ContentRating.SAFE.ordinal }, - ExtensionTable.contentRating, + isNsfw?.let { if (it) ContentWarning.MIXED.ordinal else ContentWarning.SAFE.ordinal }, + ExtensionTable.contentWarning, ) - opAnd.eq(contentRating?.ordinal, ExtensionTable.contentRating) + opAnd.eq(contentWarning?.ordinal, ExtensionTable.contentWarning) opAnd.eq(isInstalled, ExtensionTable.isInstalled) opAnd.eq(hasUpdate, ExtensionTable.hasUpdate) opAnd.eq(isObsolete, ExtensionTable.isObsolete) @@ -156,9 +156,9 @@ class ExtensionQuery { val versionCode: IntFilter? = null, val versionCodeLong: LongFilter? = null, val lang: StringFilter? = null, - @GraphQLDeprecated("", ReplaceWith("storeIndexUrl")) + @GraphQLDeprecated("", ReplaceWith("contentWarning")) val isNsfw: BooleanFilter? = null, - val contentRating: ContentRatingFilter? = null, + val contentWarning: ContentWarningFilter? = null, val isInstalled: BooleanFilter? = null, val hasUpdate: BooleanFilter? = null, val isObsolete: BooleanFilter? = null, @@ -179,7 +179,7 @@ class ExtensionQuery { andFilterWithCompareString(ExtensionTable.versionName, versionName), andFilterWithCompare(ExtensionTable.versionCode, versionCodeLong), andFilterWithCompareString(ExtensionTable.lang, lang), - andFilterWithCompareEnum(ExtensionTable.contentRating, contentRating), + andFilterWithCompareEnum(ExtensionTable.contentWarning, contentWarning), andFilterWithCompare(ExtensionTable.isInstalled, isInstalled), andFilterWithCompare(ExtensionTable.hasUpdate, hasUpdate), andFilterWithCompare(ExtensionTable.isObsolete, isObsolete), diff --git a/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/SourceQuery.kt b/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/SourceQuery.kt index be4db4bb4..f5f0c5726 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/SourceQuery.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/SourceQuery.kt @@ -15,13 +15,14 @@ import org.jetbrains.exposed.v1.core.Op import org.jetbrains.exposed.v1.core.SortOrder import org.jetbrains.exposed.v1.core.eq import org.jetbrains.exposed.v1.core.greater +import org.jetbrains.exposed.v1.core.greaterEq import org.jetbrains.exposed.v1.core.less import org.jetbrains.exposed.v1.core.neq import org.jetbrains.exposed.v1.jdbc.selectAll import org.jetbrains.exposed.v1.jdbc.transactions.transaction import suwayomi.tachidesk.graphql.directives.RequireAuth import suwayomi.tachidesk.graphql.queries.filter.BooleanFilter -import suwayomi.tachidesk.graphql.queries.filter.ContentRatingFilter +import suwayomi.tachidesk.graphql.queries.filter.ContentWarningFilter import suwayomi.tachidesk.graphql.queries.filter.Filter import suwayomi.tachidesk.graphql.queries.filter.HasGetOp import suwayomi.tachidesk.graphql.queries.filter.LongFilter @@ -42,7 +43,7 @@ import suwayomi.tachidesk.graphql.server.primitives.lessNotUnique import suwayomi.tachidesk.graphql.server.primitives.maybeSwap import suwayomi.tachidesk.graphql.types.SourceNodeList import suwayomi.tachidesk.graphql.types.SourceType -import suwayomi.tachidesk.manga.model.dataclass.ContentRating +import suwayomi.tachidesk.manga.model.dataclass.ContentWarning import suwayomi.tachidesk.manga.model.table.SourceTable import java.util.concurrent.CompletableFuture @@ -95,9 +96,9 @@ class SourceQuery { val id: Long? = null, val name: String? = null, val lang: String? = null, - @GraphQLDeprecated("replace with contentRating == ContentRating.PORNOGRAPHIC", ReplaceWith("contentRating")) + @GraphQLDeprecated("replace with contentWarning == ContentRating.MIXED", ReplaceWith("contentWarning")) val isNsfw: Boolean? = null, - val contentRating: ContentRating? = null, + val contentWarning: ContentWarning? = null, ) : HasGetOp { override fun getOp(): Op? { val opAnd = OpAnd() @@ -106,13 +107,12 @@ class SourceQuery { opAnd.eq(lang, SourceTable.lang) opAnd.andWhere(isNsfw) { if (it) { - SourceTable.contentRating eq ContentRating.PORNOGRAPHIC.ordinal + SourceTable.contentWarning greaterEq ContentWarning.MIXED.ordinal } else { - SourceTable.contentRating neq - ContentRating.PORNOGRAPHIC.ordinal + SourceTable.contentWarning less ContentWarning.MIXED.ordinal } } - opAnd.andWhere(contentRating) { SourceTable.contentRating eq it.ordinal } + opAnd.andWhere(contentWarning) { SourceTable.contentWarning eq it.ordinal } return opAnd.op } @@ -122,9 +122,9 @@ class SourceQuery { val id: LongFilter? = null, val name: StringFilter? = null, val lang: StringFilter? = null, - @GraphQLDeprecated("replace with contentRating == ContentRating.PORNOGRAPHIC", ReplaceWith("contentRating")) + @GraphQLDeprecated("replace with contentWarning", ReplaceWith("contentWarning")) val isNsfw: BooleanFilter? = null, - val contentRating: ContentRatingFilter? = null, + val contentWarning: ContentWarningFilter? = null, override val and: List? = null, override val or: List? = null, override val not: SourceFilter? = null, @@ -134,7 +134,7 @@ class SourceQuery { andFilterWithCompareEntity(SourceTable.id, id), andFilterWithCompareString(SourceTable.name, name), andFilterWithCompareString(SourceTable.lang, lang), - andFilterWithCompareEnum(SourceTable.contentRating, contentRating), + andFilterWithCompareEnum(SourceTable.contentWarning, contentWarning), ) } diff --git a/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/filter/Filter.kt b/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/filter/Filter.kt index ac8fd5cc3..98ca11b5d 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/filter/Filter.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/filter/Filter.kt @@ -28,7 +28,7 @@ import org.jetbrains.exposed.v1.core.upperCase import org.jetbrains.exposed.v1.core.wrap import org.jetbrains.exposed.v1.jdbc.Query import org.jetbrains.exposed.v1.jdbc.andWhere -import suwayomi.tachidesk.manga.model.dataclass.ContentRating +import suwayomi.tachidesk.manga.model.dataclass.ContentWarning class ILikeEscapeOp( expr1: Expression<*>, @@ -330,23 +330,23 @@ data class DoubleFilter( ) } -data class ContentRatingFilter( +data class ContentWarningFilter( override val isNull: Boolean? = null, - override val equalTo: ContentRating? = null, - override val notEqualTo: ContentRating? = null, - override val notEqualToAll: List? = null, - override val notEqualToAny: List? = null, - override val distinctFrom: ContentRating? = null, - override val distinctFromAll: List? = null, - override val distinctFromAny: List? = null, - override val notDistinctFrom: ContentRating? = null, - override val `in`: List? = null, - override val notIn: List? = null, - override val lessThan: ContentRating? = null, - override val lessThanOrEqualTo: ContentRating? = null, - override val greaterThan: ContentRating? = null, - override val greaterThanOrEqualTo: ContentRating? = null, -) : ComparableScalarFilter + override val equalTo: ContentWarning? = null, + override val notEqualTo: ContentWarning? = null, + override val notEqualToAll: List? = null, + override val notEqualToAny: List? = null, + override val distinctFrom: ContentWarning? = null, + override val distinctFromAll: List? = null, + override val distinctFromAny: List? = null, + override val notDistinctFrom: ContentWarning? = null, + override val `in`: List? = null, + override val notIn: List? = null, + override val lessThan: ContentWarning? = null, + override val lessThanOrEqualTo: ContentWarning? = null, + override val greaterThan: ContentWarning? = null, + override val greaterThanOrEqualTo: ContentWarning? = null, +) : ComparableScalarFilter data class StringFilter( override val isNull: Boolean? = null, diff --git a/server/src/main/kotlin/suwayomi/tachidesk/graphql/types/ExtensionStoreType.kt b/server/src/main/kotlin/suwayomi/tachidesk/graphql/types/ExtensionStoreType.kt index bcf9cbeb9..2106a4f79 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/graphql/types/ExtensionStoreType.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/graphql/types/ExtensionStoreType.kt @@ -26,6 +26,7 @@ class ExtensionStoreType( val contactDiscord: String?, val indexUrl: String, val isLegacy: Boolean, + val extensionListUrl: String?, ) : Node { constructor(row: ResultRow) : this( name = row[ExtensionStoreTable.name], @@ -35,6 +36,7 @@ class ExtensionStoreType( contactDiscord = row[ExtensionStoreTable.contactDiscord], indexUrl = row[ExtensionStoreTable.indexUrl], isLegacy = row[ExtensionStoreTable.isLegacy], + extensionListUrl = row[ExtensionStoreTable.extensionListUrl], ) fun extensions(dataFetchingEnvironment: DataFetchingEnvironment): CompletableFuture = diff --git a/server/src/main/kotlin/suwayomi/tachidesk/graphql/types/ExtensionType.kt b/server/src/main/kotlin/suwayomi/tachidesk/graphql/types/ExtensionType.kt index 746375fe6..c276370f7 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/graphql/types/ExtensionType.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/graphql/types/ExtensionType.kt @@ -18,7 +18,7 @@ import suwayomi.tachidesk.graphql.server.primitives.Node import suwayomi.tachidesk.graphql.server.primitives.NodeList import suwayomi.tachidesk.graphql.server.primitives.PageInfo import suwayomi.tachidesk.manga.impl.extension.Extension -import suwayomi.tachidesk.manga.model.dataclass.ContentRating +import suwayomi.tachidesk.manga.model.dataclass.ContentWarning import suwayomi.tachidesk.manga.model.table.ExtensionTable import java.util.concurrent.CompletableFuture @@ -41,9 +41,9 @@ class ExtensionType( val versionCode: Int, val versionCodeLong: Long, val lang: String, - @GraphQLDeprecated("Removed in extension api v1.6", ReplaceWith("contentRating")) + @GraphQLDeprecated("Removed in extension api v1.6", ReplaceWith("contentWarning")) val isNsfw: Boolean, - val contentRating: ContentRating, + val contentWarning: ContentWarning, val isInstalled: Boolean, val hasUpdate: Boolean, val isObsolete: Boolean, @@ -61,8 +61,8 @@ class ExtensionType( versionCode = row[ExtensionTable.versionCode].toInt(), versionCodeLong = row[ExtensionTable.versionCode], lang = row[ExtensionTable.lang], - isNsfw = row[ExtensionTable.contentRating] == ContentRating.PORNOGRAPHIC.ordinal, - contentRating = ContentRating.valueOf(row[ExtensionTable.contentRating]), + isNsfw = row[ExtensionTable.contentWarning] >= ContentWarning.MIXED.ordinal, + contentWarning = ContentWarning.valueOf(row[ExtensionTable.contentWarning]), isInstalled = row[ExtensionTable.isInstalled], hasUpdate = row[ExtensionTable.hasUpdate], isObsolete = row[ExtensionTable.isObsolete], diff --git a/server/src/main/kotlin/suwayomi/tachidesk/graphql/types/SourceType.kt b/server/src/main/kotlin/suwayomi/tachidesk/graphql/types/SourceType.kt index acd9f4e13..94d41b58e 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/graphql/types/SourceType.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/graphql/types/SourceType.kt @@ -26,7 +26,7 @@ import suwayomi.tachidesk.manga.impl.Source.getSourcePreferencesRaw import suwayomi.tachidesk.manga.impl.extension.Extension import suwayomi.tachidesk.manga.impl.util.source.GetCatalogueSource import suwayomi.tachidesk.manga.impl.util.source.GetCatalogueSource.getCatalogueSourceOrStub -import suwayomi.tachidesk.manga.model.dataclass.ContentRating +import suwayomi.tachidesk.manga.model.dataclass.ContentWarning import suwayomi.tachidesk.manga.model.table.ExtensionTable import suwayomi.tachidesk.manga.model.table.SourceTable import java.util.concurrent.CompletableFuture @@ -42,12 +42,11 @@ class SourceType( val id: Long, val name: String, val lang: String, - val message: String?, - val contentRating: ContentRating, + val contentWarning: ContentWarning, val iconUrl: String, val supportsLatest: Boolean, val isConfigurable: Boolean, - @GraphQLDeprecated("", ReplaceWith("contentRating")) + @GraphQLDeprecated("", ReplaceWith("contentWarning")) val isNsfw: Boolean, val displayName: String, val homeUrl: String?, @@ -58,12 +57,11 @@ class SourceType( id = row[SourceTable.id].value, name = row[SourceTable.name], lang = row[SourceTable.lang], - message = row[SourceTable.message], - contentRating = ContentRating.valueOf(row[SourceTable.contentRating]), + contentWarning = ContentWarning.valueOf(row[SourceTable.contentWarning]), iconUrl = Extension.proxyExtensionIconUrl(sourceExtension[ExtensionTable.pkgName]), supportsLatest = catalogueSource.supportsLatest, isConfigurable = catalogueSource is ConfigurableSource, - isNsfw = row[SourceTable.contentRating] == ContentRating.PORNOGRAPHIC.ordinal, + isNsfw = row[SourceTable.contentWarning] >= ContentWarning.MIXED.ordinal, displayName = catalogueSource.toString(), homeUrl = runCatching { (catalogueSource as? HttpSource)?.getHomeUrl() }.getOrNull(), baseUrl = runCatching { (catalogueSource as? HttpSource)?.baseUrl }.getOrNull(), diff --git a/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/Source.kt b/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/Source.kt index aeba5c9a2..87db6f6d2 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/Source.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/Source.kt @@ -29,7 +29,7 @@ import suwayomi.tachidesk.manga.impl.extension.Extension.proxyExtensionIconUrl import suwayomi.tachidesk.manga.impl.util.source.GetCatalogueSource.getCatalogueSourceOrNull import suwayomi.tachidesk.manga.impl.util.source.GetCatalogueSource.getCatalogueSourceOrStub import suwayomi.tachidesk.manga.impl.util.source.GetCatalogueSource.unregisterCatalogueSource -import suwayomi.tachidesk.manga.model.dataclass.ContentRating +import suwayomi.tachidesk.manga.model.dataclass.ContentWarning import suwayomi.tachidesk.manga.model.dataclass.SourceDataClass import suwayomi.tachidesk.manga.model.table.ExtensionTable import suwayomi.tachidesk.manga.model.table.SourceMetaTable @@ -53,7 +53,7 @@ object Source { iconUrl = proxyExtensionIconUrl(sourceExtension[ExtensionTable.pkgName]), supportsLatest = catalogueSource.supportsLatest, isConfigurable = catalogueSource is ConfigurableSource, - isNsfw = it[SourceTable.contentRating] == ContentRating.PORNOGRAPHIC.ordinal, + isNsfw = it[SourceTable.contentWarning] >= ContentWarning.MIXED.ordinal, displayName = catalogueSource.toString(), baseUrl = runCatching { (catalogueSource as? HttpSource)?.baseUrl }.getOrNull(), ) @@ -74,7 +74,7 @@ object Source { iconUrl = proxyExtensionIconUrl(extension[ExtensionTable.pkgName]), supportsLatest = catalogueSource.supportsLatest, isConfigurable = catalogueSource is ConfigurableSource, - isNsfw = source[SourceTable.contentRating] == ContentRating.PORNOGRAPHIC.ordinal, + isNsfw = source[SourceTable.contentWarning] >= ContentWarning.MIXED.ordinal, displayName = catalogueSource.toString(), baseUrl = runCatching { (catalogueSource as? HttpSource)?.baseUrl }.getOrNull(), ) diff --git a/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/extension/Extension.kt b/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/extension/Extension.kt index 7dd0fd7a7..55c92b526 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/extension/Extension.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/extension/Extension.kt @@ -32,6 +32,9 @@ import suwayomi.tachidesk.manga.impl.util.PackageTools import suwayomi.tachidesk.manga.impl.util.PackageTools.EXTENSION_FEATURE import suwayomi.tachidesk.manga.impl.util.PackageTools.LIB_VERSION_MAX import suwayomi.tachidesk.manga.impl.util.PackageTools.LIB_VERSION_MIN +import suwayomi.tachidesk.manga.impl.util.PackageTools.METADATA_CONTENT_WARNING +import suwayomi.tachidesk.manga.impl.util.PackageTools.METADATA_EXTENSION_LIB +import suwayomi.tachidesk.manga.impl.util.PackageTools.METADATA_NAME import suwayomi.tachidesk.manga.impl.util.PackageTools.METADATA_NSFW import suwayomi.tachidesk.manga.impl.util.PackageTools.METADATA_SOURCE_CLASS import suwayomi.tachidesk.manga.impl.util.PackageTools.dex2jar @@ -42,7 +45,7 @@ import suwayomi.tachidesk.manga.impl.util.source.GetCatalogueSource import suwayomi.tachidesk.manga.impl.util.storage.ImageResponse.clearCachedImage import suwayomi.tachidesk.manga.impl.util.storage.ImageResponse.getImageResponse import suwayomi.tachidesk.manga.impl.util.storage.ImageResponse.saveImage -import suwayomi.tachidesk.manga.model.dataclass.ContentRating +import suwayomi.tachidesk.manga.model.dataclass.ContentWarning import suwayomi.tachidesk.manga.model.table.ExtensionTable import suwayomi.tachidesk.manga.model.table.SourceTable import suwayomi.tachidesk.server.ApplicationDirs @@ -151,7 +154,10 @@ object Extension { // throw Exception("This apk is not a signed with the official tachiyomi signature") // } - val isNsfw = packageInfo.applicationInfo.metaData.getString(METADATA_NSFW) == "1" + var contentWarning = packageInfo.applicationInfo.metaData.getInt(METADATA_CONTENT_WARNING) + if (contentWarning == 0) { + contentWarning = packageInfo.applicationInfo.metaData.getInt(METADATA_NSFW) + } val className = packageInfo.packageName + packageInfo.applicationInfo.metaData.getString(METADATA_SOURCE_CLASS) @@ -184,9 +190,16 @@ object Extension { } val extensionName = - packageInfo.applicationInfo.nonLocalizedLabel - .toString() - .substringAfter("Tachiyomi: ") + packageInfo.applicationInfo.metaData.getString(METADATA_NAME) + ?: packageInfo.applicationInfo.nonLocalizedLabel + .toString() + .substringAfter("Tachiyomi: ") + + val extensionLibVersion = + packageInfo.applicationInfo.metaData + .getString(METADATA_EXTENSION_LIB) + .takeUnless { it == "0" } + ?: packageInfo.versionName.substringBeforeLast('.') // update extension info transaction { @@ -197,14 +210,9 @@ object Extension { it[this.pkgName] = packageInfo.packageName it[versionName] = packageInfo.versionName it[versionCode] = packageInfo.versionCode.toLong() + it[extensionLib] = extensionLibVersion it[lang] = extensionLang - // todo will change - it[contentRating] = - if (isNsfw) { - ContentRating.PORNOGRAPHIC.ordinal - } else { - ContentRating.SAFE.ordinal - } + it[this.contentWarning] = contentWarning } } @@ -229,7 +237,7 @@ object Extension { it[name] = httpSource.name it[lang] = httpSource.lang it[extension] = extensionId - it[contentRating] = if (isNsfw) ContentRating.PORNOGRAPHIC.ordinal else ContentRating.SAFE.ordinal + it[this.contentWarning] = contentWarning } logger.debug { "Installed source ${httpSource.name} (${httpSource.lang}) with id:${httpSource.id}" } } @@ -397,7 +405,7 @@ object Extension { it[versionName] = targetExtension.versionName it[versionCode] = targetExtension.versionCode it[lang] = targetExtension.lang - it[contentRating] = targetExtension.contentRating.ordinal + it[contentWarning] = targetExtension.contentWarning.ordinal it[iconUrl] = targetExtension.iconUrl it[hasUpdate] = false } diff --git a/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/extension/ExtensionStoreService.kt b/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/extension/ExtensionStoreService.kt index 55c71ece4..7103ef407 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/extension/ExtensionStoreService.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/extension/ExtensionStoreService.kt @@ -15,6 +15,9 @@ import kotlinx.serialization.decodeFromByteArray import kotlinx.serialization.json.Json import kotlinx.serialization.json.okio.decodeFromBufferedSource import kotlinx.serialization.protobuf.ProtoBuf +import okio.BufferedSource +import okio.buffer +import okio.gzip import org.jetbrains.exposed.v1.core.eq import org.jetbrains.exposed.v1.core.inList import org.jetbrains.exposed.v1.jdbc.deleteWhere @@ -41,45 +44,45 @@ object ExtensionStoreService { val protoBuf: ProtoBuf by injectLazy() val json: Json by injectLazy() - suspend fun fetch(indexUrl: String): ExtensionStore = fetch(indexUrl, forceV2 = false) - - private suspend fun fetch( - indexUrl: String, - forceV2: Boolean, - ): ExtensionStore { - var updatedIndexUrl = indexUrl + suspend fun fetch(indexUrl: String): ExtensionStore { + var updatedIndexUrl: String = indexUrl return try { - network.client.newCall(GET(indexUrl)).awaitSuccess().body.source().use { source -> - try { - protoBuf.decodeFromByteArray(source.peek().readByteArray()) - } catch (e: IllegalArgumentException) { - logger.debug { "Failed to decode as protobuf, trying JSON" } - try { - json.decodeFromBufferedSource(source.peek()) - } catch (e: IllegalArgumentException) { - if (forceV2) throw e - logger.debug { "Failed to decode as NetworkExtensionStore, trying LegacyExtensionRepo" } - val legacyIndex = - try { - json.decodeFromBufferedSource(source.peek()) - } catch (e: IllegalArgumentException) { + val response = network.client.newCall(GET(updatedIndexUrl)).awaitSuccess() + response.body.source().decompressIfGzipped().use { source -> + val networkStore = + when (source.peek().readByte()) { + // "[..." + 0x5B.toByte() -> { + run { if (!indexUrl.endsWith("/index.min.json")) { - throw e + throw IllegalArgumentException("Provided legacy store url is not valid") } - logger.debug { "Checking for new repo.json format" } updatedIndexUrl = indexUrl.replace("/index.min.json", "/repo.json") network.client.newCall(GET(updatedIndexUrl)).awaitSuccess().body.source().use { json.decodeFromBufferedSource(it) } } + } - if (legacyIndex.indexV2 != null) { - return fetch(legacyIndex.indexV2, forceV2 = true) - } else { - legacyIndex + // "{..." + 0x7B.toByte() -> { + try { + json.decodeFromBufferedSource(source.peek()) + } catch (_: IllegalArgumentException) { + json.decodeFromBufferedSource(source) + } + } + + else -> { + protoBuf.decodeFromByteArray(source.readByteArray()) } } - }.toExtensionStore(updatedIndexUrl) + + if (networkStore is NetworkLegacyExtensionRepo && networkStore.indexV2 != null) { + return fetch(networkStore.indexV2) + } + + networkStore.toExtensionStore(updatedIndexUrl) } } catch (e: Exception) { if (e is CancellationException) throw e @@ -105,6 +108,7 @@ object ExtensionStoreService { it[contactDiscord] = store.contact.discord it[indexUrl] = store.indexUrl it[isLegacy] = store.isLegacy + it[extensionListUrl] = store.extensionListUrl } } else { ExtensionStoreTable.update({ ExtensionStoreTable.indexUrl eq store.indexUrl }) { @@ -114,6 +118,7 @@ object ExtensionStoreService { it[contactWebsite] = store.contact.website it[contactDiscord] = store.contact.discord it[isLegacy] = store.isLegacy + it[extensionListUrl] = store.extensionListUrl } } } @@ -210,17 +215,33 @@ object ExtensionStoreService { suspend fun getExtensions(store: ExtensionStore): List { val extensions = - if (!store.isLegacy) { - val response = network.client.newCall(GET(store.indexUrl)).awaitSuccess() - response.body - .source() - .use { source -> - try { - protoBuf.decodeFromByteArray(source.peek().readByteArray()) - } catch (_: IllegalArgumentException) { - json.decodeFromBufferedSource(source.peek()) + if (store.extensionListUrl != null) { + val response = network.client.newCall(GET(store.extensionListUrl)).awaitSuccess() + response.body.source().decompressIfGzipped().use { source -> + when (source.peek().readByte()) { + // "{..." + 0x7B.toByte() -> { + json.decodeFromBufferedSource(source) + } + + else -> { + protoBuf.decodeFromByteArray( + source.readByteArray(), + ) } }.toExtensionInfos(store) + } + } else if (!store.isLegacy) { + val response = network.client.newCall(GET(store.indexUrl)).awaitSuccess() + response.body.source().decompressIfGzipped().use { source -> + when (source.peek().readByte()) { + // "{..." + 0x7B.toByte() -> json.decodeFromBufferedSource(source) + + else -> protoBuf.decodeFromByteArray(source.readByteArray()) + }.extensionList!! + .toExtensionInfos(store) + } } else { val storeBaseUrl = store.indexUrl.removeSuffix("/repo.json") val response = network.client.newCall(GET("$storeBaseUrl/index.min.json")).awaitSuccess() @@ -232,4 +253,17 @@ object ExtensionStoreService { } return extensions } + + private fun BufferedSource.decompressIfGzipped(): BufferedSource { + val isGzip = + peek().use { peeked -> + try { + peeked.readShort().toInt() == 0x1f8b + } catch (_: Exception) { + false + } + } + + return if (isGzip) gzip().buffer() else this + } } diff --git a/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/extension/ExtensionsList.kt b/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/extension/ExtensionsList.kt index 20d97c6cf..fc4fbafdc 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/extension/ExtensionsList.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/extension/ExtensionsList.kt @@ -22,7 +22,7 @@ import org.jetbrains.exposed.v1.jdbc.statements.toExecutable import org.jetbrains.exposed.v1.jdbc.transactions.transaction import org.jetbrains.exposed.v1.jdbc.update import suwayomi.tachidesk.manga.impl.extension.Extension.proxyExtensionIconUrl -import suwayomi.tachidesk.manga.model.dataclass.ContentRating +import suwayomi.tachidesk.manga.model.dataclass.ContentWarning import suwayomi.tachidesk.manga.model.dataclass.ExtensionDataClass import suwayomi.tachidesk.manga.model.dataclass.ExtensionInfo import suwayomi.tachidesk.manga.model.table.ExtensionTable @@ -81,7 +81,7 @@ object ExtensionsList { versionName = it[ExtensionTable.versionName], versionCode = it[ExtensionTable.versionCode].toInt(), lang = it[ExtensionTable.lang], - isNsfw = it[ExtensionTable.contentRating] == ContentRating.PORNOGRAPHIC.ordinal, + isNsfw = it[ExtensionTable.contentWarning] >= ContentWarning.MIXED.ordinal, installed = it[ExtensionTable.isInstalled], hasUpdate = it[ExtensionTable.hasUpdate], obsolete = it[ExtensionTable.isObsolete], @@ -173,7 +173,7 @@ object ExtensionsList { this[ExtensionTable.versionName] = foundExtension.versionName this[ExtensionTable.versionCode] = foundExtension.versionCode this[ExtensionTable.lang] = foundExtension.lang - this[ExtensionTable.contentRating] = foundExtension.contentRating.ordinal + this[ExtensionTable.contentWarning] = foundExtension.contentWarning.ordinal this[ExtensionTable.apkUrl] = foundExtension.apkUrl this[ExtensionTable.iconUrl] = foundExtension.iconUrl } @@ -190,7 +190,7 @@ object ExtensionsList { this[ExtensionTable.versionName] = foundExtension.versionName this[ExtensionTable.versionCode] = foundExtension.versionCode this[ExtensionTable.lang] = foundExtension.lang - this[ExtensionTable.contentRating] = foundExtension.contentRating.ordinal + this[ExtensionTable.contentWarning] = foundExtension.contentWarning.ordinal this[ExtensionTable.apkUrl] = foundExtension.apkUrl this[ExtensionTable.iconUrl] = foundExtension.iconUrl } diff --git a/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/extension/github/NetworkExtensionStore.kt b/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/extension/github/NetworkExtensionStore.kt index 657b331cd..624078909 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/extension/github/NetworkExtensionStore.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/extension/github/NetworkExtensionStore.kt @@ -11,7 +11,7 @@ import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.Serializable import kotlinx.serialization.json.JsonNames import kotlinx.serialization.protobuf.ProtoNumber -import suwayomi.tachidesk.manga.model.dataclass.ContentRating +import suwayomi.tachidesk.manga.model.dataclass.ContentWarning import suwayomi.tachidesk.manga.model.dataclass.ExtensionInfo import suwayomi.tachidesk.manga.model.dataclass.ExtensionSource import suwayomi.tachidesk.manga.model.dataclass.ExtensionStore @@ -23,7 +23,8 @@ data class NetworkExtensionStore( @ProtoNumber(2) val badgeLabel: String, @ProtoNumber(3) val signingKey: String, @ProtoNumber(4) val contact: Contact, - @ProtoNumber(5) val extensions: List, + @ProtoNumber(101) val extensionList: ExtensionList?, + @ProtoNumber(102) val extensionListUrl: String?, ) : BaseNetworkExtensionStore { @Serializable data class Contact( @@ -31,6 +32,11 @@ data class NetworkExtensionStore( @ProtoNumber(2) val discord: String?, ) + @Serializable + data class ExtensionList( + @ProtoNumber(1) val extensions: List, + ) + @Serializable data class Extension( @ProtoNumber(1) val name: String, @@ -55,27 +61,23 @@ data class NetworkExtensionStore( @ProtoNumber(3) val language: String, @ProtoNumber(4) val homeUrl: String = "", @ProtoNumber(5) val mirrorUrls: List = emptyList(), - @ProtoNumber(6) val contentRating: ContentRating = ContentRating.SAFE, + @ProtoNumber(6) val contentWarning: ContentWarning = ContentWarning.SAFE, @ProtoNumber(7) val message: String? = null, ) @Serializable - enum class ContentRating { + enum class ContentWarning { @ProtoNumber(0) - @JsonNames("CONTENT_RATING_SAFE") + @JsonNames("CONTENT_WARNING_SAFE") SAFE, @ProtoNumber(1) - @JsonNames("CONTENT_RATING_SUGGESTIVE") - SUGGESTIVE, + @JsonNames("CONTENT_WARNING_MIXED") + MIXED, @ProtoNumber(2) - @JsonNames("CONTENT_RATING_EROTICA") - EROTICA, - - @ProtoNumber(3) - @JsonNames("CONTENT_RATING_PORNOGRAPHIC") - PORNOGRAPHIC, + @JsonNames("CONTENT_WARNING_NSFW") + NSFW, } override fun toExtensionStore(indexUrl: String): ExtensionStore = @@ -90,10 +92,11 @@ data class NetworkExtensionStore( discord = contact.discord, ), isLegacy = false, + extensionListUrl = extensionListUrl, ) } -fun NetworkExtensionStore.toExtensionInfos(store: ExtensionStore): List = +fun NetworkExtensionStore.ExtensionList.toExtensionInfos(store: ExtensionStore): List = extensions.map { extension -> val lang = extension.sources.map { it.language }.toSet() ExtensionInfo( @@ -106,13 +109,12 @@ fun NetworkExtensionStore.toExtensionInfos(store: ExtensionStore): List ContentRating.SAFE - NetworkExtensionStore.ContentRating.SUGGESTIVE -> ContentRating.SUGGESTIVE - NetworkExtensionStore.ContentRating.EROTICA -> ContentRating.EROTICA - NetworkExtensionStore.ContentRating.PORNOGRAPHIC -> ContentRating.PORNOGRAPHIC - null -> ContentRating.SAFE + contentWarning = + when (extension.sources.maxOfOrNull { it.contentWarning }) { + NetworkExtensionStore.ContentWarning.SAFE -> ContentWarning.SAFE + NetworkExtensionStore.ContentWarning.MIXED -> ContentWarning.MIXED + NetworkExtensionStore.ContentWarning.NSFW -> ContentWarning.NSFW + null -> ContentWarning.SAFE }, sources = extension.sources.map { source -> @@ -122,12 +124,11 @@ fun NetworkExtensionStore.toExtensionInfos(store: ExtensionStore): List ContentRating.SAFE - NetworkExtensionStore.ContentRating.SUGGESTIVE -> ContentRating.SUGGESTIVE - NetworkExtensionStore.ContentRating.EROTICA -> ContentRating.EROTICA - NetworkExtensionStore.ContentRating.PORNOGRAPHIC -> ContentRating.PORNOGRAPHIC + contentWarning = + when (source.contentWarning) { + NetworkExtensionStore.ContentWarning.SAFE -> ContentWarning.SAFE + NetworkExtensionStore.ContentWarning.MIXED -> ContentWarning.MIXED + NetworkExtensionStore.ContentWarning.NSFW -> ContentWarning.NSFW }, ) }, diff --git a/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/extension/github/NetworkLegacyExtension.kt b/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/extension/github/NetworkLegacyExtension.kt index 894b95984..bffa2bc66 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/extension/github/NetworkLegacyExtension.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/extension/github/NetworkLegacyExtension.kt @@ -9,7 +9,7 @@ package suwayomi.tachidesk.manga.impl.extension.github import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.Serializable -import suwayomi.tachidesk.manga.model.dataclass.ContentRating +import suwayomi.tachidesk.manga.model.dataclass.ContentWarning import suwayomi.tachidesk.manga.model.dataclass.ExtensionInfo import suwayomi.tachidesk.manga.model.dataclass.ExtensionSource import suwayomi.tachidesk.manga.model.dataclass.ExtensionStore @@ -49,7 +49,7 @@ fun NetworkLegacyExtension.toExtensionInfo( versionCode = code, versionName = version, lang = lang, - contentRating = if (nsfw == 1) ContentRating.PORNOGRAPHIC else ContentRating.SAFE, + contentWarning = if (nsfw == 1) ContentWarning.MIXED else ContentWarning.SAFE, sources = if (sources.isNullOrEmpty()) { listOf( @@ -59,7 +59,7 @@ fun NetworkLegacyExtension.toExtensionInfo( lang = lang, homeUrl = "", message = null, - contentRating = if (nsfw == 1) ContentRating.PORNOGRAPHIC else ContentRating.SAFE, + contentWarning = if (nsfw == 1) ContentWarning.MIXED else ContentWarning.SAFE, ), ) } else { @@ -70,7 +70,7 @@ fun NetworkLegacyExtension.toExtensionInfo( lang = source.lang, homeUrl = source.baseUrl, message = null, - contentRating = if (nsfw == 1) ContentRating.PORNOGRAPHIC else ContentRating.SAFE, + contentWarning = if (nsfw == 1) ContentWarning.MIXED else ContentWarning.SAFE, ) } }, diff --git a/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/extension/github/NetworkLegacyExtensionRepo.kt b/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/extension/github/NetworkLegacyExtensionRepo.kt index c02097dbc..1963e1ce2 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/extension/github/NetworkLegacyExtensionRepo.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/extension/github/NetworkLegacyExtensionRepo.kt @@ -36,5 +36,6 @@ data class NetworkLegacyExtensionRepo( discord = null, ), isLegacy = true, + extensionListUrl = null, ) } diff --git a/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/util/PackageTools.kt b/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/util/PackageTools.kt index 1e880c874..1671be0a7 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/util/PackageTools.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/util/PackageTools.kt @@ -40,6 +40,11 @@ object PackageTools { const val METADATA_SOURCE_CLASS = "tachiyomi.extension.class" const val METADATA_SOURCE_FACTORY = "tachiyomi.extension.factory" const val METADATA_NSFW = "tachiyomi.extension.nsfw" + + const val METADATA_NAME = "tachiyomix.name" + const val METADATA_EXTENSION_LIB = "tachiyomix.extensionLib" + const val METADATA_CONTENT_WARNING = "tachiyomix.contentWarning" + const val LIB_VERSION_MIN = 1.3 const val LIB_VERSION_MAX = 1.6 diff --git a/server/src/main/kotlin/suwayomi/tachidesk/manga/model/dataclass/ExtensionInfo.kt b/server/src/main/kotlin/suwayomi/tachidesk/manga/model/dataclass/ExtensionInfo.kt index ead7d44ef..22c0b1b17 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/manga/model/dataclass/ExtensionInfo.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/manga/model/dataclass/ExtensionInfo.kt @@ -17,7 +17,7 @@ data class ExtensionInfo( val versionCode: Long, val versionName: String, val lang: String, - val contentRating: ContentRating, + val contentWarning: ContentWarning, val sources: List, ) @@ -27,17 +27,16 @@ data class ExtensionSource( val lang: String, val homeUrl: String, val message: String?, - val contentRating: ContentRating, + val contentWarning: ContentWarning, ) -enum class ContentRating { +enum class ContentWarning { SAFE, - SUGGESTIVE, - EROTICA, - PORNOGRAPHIC, + MIXED, + NSFW, ; companion object { - fun valueOf(contentRating: Int) = entries.find { it.ordinal == contentRating } ?: SAFE + fun valueOf(contentWarning: Int) = entries.find { it.ordinal == contentWarning } ?: SAFE } } diff --git a/server/src/main/kotlin/suwayomi/tachidesk/manga/model/dataclass/ExtensionStore.kt b/server/src/main/kotlin/suwayomi/tachidesk/manga/model/dataclass/ExtensionStore.kt index 869f38489..4fad0b5d6 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/manga/model/dataclass/ExtensionStore.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/manga/model/dataclass/ExtensionStore.kt @@ -14,6 +14,7 @@ data class ExtensionStore( val signingKey: String, val contact: Contact, val isLegacy: Boolean, + val extensionListUrl: String?, ) { data class Contact( val website: String, diff --git a/server/src/main/kotlin/suwayomi/tachidesk/manga/model/table/ExtensionStoreTable.kt b/server/src/main/kotlin/suwayomi/tachidesk/manga/model/table/ExtensionStoreTable.kt index 5bba810ef..1c638b437 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/manga/model/table/ExtensionStoreTable.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/manga/model/table/ExtensionStoreTable.kt @@ -17,4 +17,5 @@ object ExtensionStoreTable : IntIdTable() { val contactWebsite = varchar("contact_website", 2048) val contactDiscord = varchar("contact_discord", 2048).nullable() val isLegacy = bool("is_legacy").default(false) + val extensionListUrl = varchar("extension_list_url", 2048).nullable() } diff --git a/server/src/main/kotlin/suwayomi/tachidesk/manga/model/table/ExtensionTable.kt b/server/src/main/kotlin/suwayomi/tachidesk/manga/model/table/ExtensionTable.kt index 863647b18..4d0f63fa5 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/manga/model/table/ExtensionTable.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/manga/model/table/ExtensionTable.kt @@ -28,7 +28,7 @@ object ExtensionTable : IntIdTable() { val versionName = varchar("version_name", 16) val versionCode = long("version_code") val lang = varchar("lang", 32) - val contentRating = integer("content_rating") + val contentWarning = integer("content_warning") val isInstalled = bool("is_installed").default(false) val hasUpdate = bool("has_update").default(false) diff --git a/server/src/main/kotlin/suwayomi/tachidesk/manga/model/table/SourceTable.kt b/server/src/main/kotlin/suwayomi/tachidesk/manga/model/table/SourceTable.kt index f3bfbe52f..09e77a1c3 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/manga/model/table/SourceTable.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/manga/model/table/SourceTable.kt @@ -8,13 +8,11 @@ package suwayomi.tachidesk.manga.model.table * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ import org.jetbrains.exposed.v1.core.dao.id.IdTable -import suwayomi.tachidesk.manga.model.table.columns.unlimitedVarchar object SourceTable : IdTable() { override val id = long("id").entityId() val name = varchar("name", 128) val lang = varchar("lang", 32) val extension = reference("extension", ExtensionTable) - val message = unlimitedVarchar("message").nullable() - val contentRating = integer("content_rating").default(0) + val contentWarning = integer("content_warning").default(0) } diff --git a/server/src/main/kotlin/suwayomi/tachidesk/server/database/migration/M0057_AddNewExtensionApiFields.kt b/server/src/main/kotlin/suwayomi/tachidesk/server/database/migration/M0057_AddNewExtensionApiFields.kt index 4b50bf38e..af5f69c71 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/server/database/migration/M0057_AddNewExtensionApiFields.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/server/database/migration/M0057_AddNewExtensionApiFields.kt @@ -9,7 +9,7 @@ package suwayomi.tachidesk.server.database.migration import de.neonew.exposed.migrations.helpers.SQLMigration import suwayomi.tachidesk.graphql.types.DatabaseType -import suwayomi.tachidesk.manga.model.dataclass.ContentRating +import suwayomi.tachidesk.manga.model.dataclass.ContentWarning import suwayomi.tachidesk.server.database.migration.helpers.MAYBE_TYPE_PREFIX import suwayomi.tachidesk.server.database.migration.helpers.UNLIMITED_TEXT import suwayomi.tachidesk.server.database.migration.helpers.toSqlName @@ -43,12 +43,11 @@ class M0057_AddNewExtensionApiFields : SQLMigration() { } } ALTER TABLE EXTENSION ADD COLUMN apk_url VARCHAR(2048); - ALTER TABLE EXTENSION ADD COLUMN content_rating INTEGER DEFAULT 0; - UPDATE EXTENSION SET content_rating = ${ContentRating.PORNOGRAPHIC.ordinal} WHERE is_nsfw = TRUE; + ALTER TABLE EXTENSION ADD COLUMN content_warning INTEGER DEFAULT 0; + UPDATE EXTENSION SET content_warning = ${ContentWarning.MIXED.ordinal} WHERE is_nsfw = TRUE; ALTER TABLE EXTENSION DROP COLUMN is_nsfw; - ALTER TABLE SOURCE ADD COLUMN message $UNLIMITED_TEXT; - ALTER TABLE SOURCE ADD COLUMN content_rating INTEGER DEFAULT 0; - UPDATE SOURCE SET content_rating = ${ContentRating.PORNOGRAPHIC.ordinal} WHERE is_nsfw = TRUE; + ALTER TABLE SOURCE ADD COLUMN content_warning INTEGER DEFAULT 0; + UPDATE SOURCE SET content_warning = ${ContentWarning.MIXED.ordinal} WHERE is_nsfw = TRUE; ALTER TABLE SOURCE DROP COLUMN is_nsfw; diff --git a/server/src/main/kotlin/suwayomi/tachidesk/server/database/migration/M0058_AddExtensionStore.kt b/server/src/main/kotlin/suwayomi/tachidesk/server/database/migration/M0058_AddExtensionStore.kt index 13ff8bb1d..f498be1f0 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/server/database/migration/M0058_AddExtensionStore.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/server/database/migration/M0058_AddExtensionStore.kt @@ -21,6 +21,7 @@ class M0058_AddExtensionStore : AddTableMigration() { val contactWebsite = varchar("contact_website", 2048) val contactDiscord = varchar("contact_discord", 2048).nullable() val isLegacy = bool("is_legacy").default(false) + val extensionListUrl = varchar("extension_list_url", 2048).nullable() } override val tables: Array