From 118c7587d0a4bfc2d7940c955697e56f26c9ff50 Mon Sep 17 00:00:00 2001 From: ForteScarlet Date: Tue, 9 Apr 2024 21:59:57 +0800 Subject: [PATCH 01/16] =?UTF-8?q?=E6=9B=B4=E6=96=B0README?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- buildSrc/src/main/kotlin/R.kt | 9 ++- simbot-component-telegram-api/README.md | 31 ++++++++ simbot-component-telegram-api/README_CN.md | 31 ++++++++ simbot-component-telegram-core/README.md | 81 +++++++++++++++++++++ simbot-component-telegram-stdlib/README.md | 29 ++++++++ simbot-component-telegram-type/README.md | 31 ++++++++ simbot-component-telegram-type/README_CN.md | 31 ++++++++ 7 files changed, 242 insertions(+), 1 deletion(-) diff --git a/buildSrc/src/main/kotlin/R.kt b/buildSrc/src/main/kotlin/R.kt index 503afe5..07dd76f 100644 --- a/buildSrc/src/main/kotlin/R.kt +++ b/buildSrc/src/main/kotlin/R.kt @@ -15,15 +15,22 @@ * If not, see . */ +import love.forte.gradle.common.core.property.systemProp import love.forte.gradle.common.core.repository.Repositories import love.forte.gradle.common.core.repository.SimpleCredentials +import love.forte.gradle.common.publication.SonatypeContact import org.slf4j.LoggerFactory val logger = LoggerFactory.getLogger("Sonatype Userinfo") private val sonatypeUserInfo by lazy { val userInfo = love.forte.gradle.common.publication.sonatypeUserInfoOrNull - + + val username = systemProp(SonatypeContact.SONATYPE_USERNAME) ?: return@lazy null + val password = systemProp(SonatypeContact.SONATYPE_PASSWORD) ?: return@lazy null + logger.info("sonatype.username: {}", username) + logger.info("sonatype.password: {}", password) + if (userInfo == null) { logger.warn("sonatype.username or sonatype.password is null, cannot config nexus publishing.") } diff --git a/simbot-component-telegram-api/README.md b/simbot-component-telegram-api/README.md index f421068..149f346 100644 --- a/simbot-component-telegram-api/README.md +++ b/simbot-component-telegram-api/README.md @@ -2,6 +2,37 @@ > TODO +## Setup + +> [!note] +> Version (`VERSION` below) goes to the [releases](https://github.com/simple-robot/simbot-component-telegram/releases) reference. + +### Gradle + +`build.gradle.kts` + +```kotlin +plugins { + kotlin("...") version "..." +} + +dependencies { + implementation("love.forte.simbot.component:simbot-component-telegram-api:$VERSION") +} +``` + +### Maven + +```xml + + + love.forte.simbot.component + simbot-component-telegram-api-jvm + ${VERSION} + + +``` + ## Supports See [supports](supports.md). diff --git a/simbot-component-telegram-api/README_CN.md b/simbot-component-telegram-api/README_CN.md index a983efb..9bcd796 100644 --- a/simbot-component-telegram-api/README_CN.md +++ b/simbot-component-telegram-api/README_CN.md @@ -2,6 +2,37 @@ > TODO +## 安装 + +> [!note] +> 版本 (即下文的 `VERSION`) 前往 [releases](https://github.com/simple-robot/simbot-component-telegram/releases) 参考. + +### Gradle + +`build.gradle.kts` + +```kotlin +plugins { + kotlin("...") version "..." +} + +dependencies { + implementation("love.forte.simbot.component:simbot-component-telegram-type:$VERSION") +} +``` + +### Maven + +```xml + + + love.forte.simbot.component + simbot-component-telegram-type-jvm + ${VERSION} + + +``` + ## 支持列表 参考 [支持列表](supports.md) diff --git a/simbot-component-telegram-core/README.md b/simbot-component-telegram-core/README.md index 622cd8c..a1c1246 100644 --- a/simbot-component-telegram-core/README.md +++ b/simbot-component-telegram-core/README.md @@ -3,7 +3,88 @@ > [!caution] > WIP +## Setup +To use the simbot component library, you first need to add the core implementation of simbot +(such as the core library (`simbot-core`) or Spring Boot starter (`simbot-core-spring-boot-starter`)), +and then add the component library dependencies of the Telegram (`simbot-component-telegram-core`). + +> [!note] +> The version of simbot core implementation library (`SIMBOT_VERSION` below) goes [here](https://github.com/simple-robot/simpler-robot/releases) for reference; +> +> Telegram Component library versions (`VERSION` below) go to the [releases](https://github.com/simple-robot/simbot-component-telegram/releases) reference. + +**With simbot core** + +### Gradle + +`build.gradle.kts` + +```kotlin +plugins { + kotlin("...") version "..." +} + +dependencies { + implementation("love.forte.simbot:simbot-core:${SIMBOT_VERSION}") + implementation("love.forte.simbot.component:simbot-component-telegram-core:$VERSION") +} +``` + +### Maven + +`pom.xml` + +```xml + + + love.forte.simbot + simbot-core-jvm + ${SIMBOT_VERSION} + + + love.forte.simbot.component + simbot-component-telegram-core-jvm + ${VERSION} + + +``` + +**With simbot spring boot starter** + +### Gradle + +`build.gradle.kts` + +```kotlin +plugins { + kotlin("jvm") version "..." +} + +dependencies { + implementation("love.forte.simbot:simbot-core-spring-boot-starter:${SIMBOT_VERSION}") + implementation("love.forte.simbot.component:simbot-component-telegram-core:$VERSION") +} +``` + +### Maven + +`pom.xml` + +```xml + + + love.forte.simbot + simbot-core-spring-boot-starter + ${SIMBOT_VERSION} + + + love.forte.simbot.component + simbot-component-telegram-core-jvm + ${VERSION} + + +``` ## Examples diff --git a/simbot-component-telegram-stdlib/README.md b/simbot-component-telegram-stdlib/README.md index 68ffc64..089cc63 100644 --- a/simbot-component-telegram-stdlib/README.md +++ b/simbot-component-telegram-stdlib/README.md @@ -3,7 +3,36 @@ > [!caution] > WIP +## Setup +> [!note] +> Version (`VERSION` below) goes to the [releases](https://github.com/simple-robot/simbot-component-telegram/releases) reference. + +### Gradle + +`build.gradle.kts` + +```kotlin +plugins { + kotlin("...") version "..." +} + +dependencies { + implementation("love.forte.simbot.component:simbot-component-telegram-stdlib:$VERSION") +} +``` + +### Maven + +```xml + + + love.forte.simbot.component + simbot-component-telegram-stdlib-jvm + ${VERSION} + + +``` ## Examples diff --git a/simbot-component-telegram-type/README.md b/simbot-component-telegram-type/README.md index beb0289..d3ca28e 100644 --- a/simbot-component-telegram-type/README.md +++ b/simbot-component-telegram-type/README.md @@ -13,3 +13,34 @@ Support platforms: See also: - [Telegram available types](https://core.telegram.org/bots/api#available-types) + +## Setup + +> [!note] +> Version (`VERSION` below) goes to the [releases](https://github.com/simple-robot/simbot-component-telegram/releases) reference. + +### Gradle + +`build.gradle.kts` + +```kotlin +plugins { + kotlin("...") version "..." +} + +dependencies { + implementation("love.forte.simbot.component:simbot-component-telegram-type:$VERSION") +} +``` + +### Maven + +```xml + + + love.forte.simbot.component + simbot-component-telegram-type-jvm + ${VERSION} + + +``` diff --git a/simbot-component-telegram-type/README_CN.md b/simbot-component-telegram-type/README_CN.md index c3837f1..6a44d05 100644 --- a/simbot-component-telegram-type/README_CN.md +++ b/simbot-component-telegram-type/README_CN.md @@ -14,3 +14,34 @@ 更多参考: - [Telegram available types](https://core.telegram.org/bots/api#available-types) + +## 安装 + +> [!note] +> 版本 (即下文的 `VERSION`) 前往 [releases](https://github.com/simple-robot/simbot-component-telegram/releases) 参考. + +### Gradle + +`build.gradle.kts` + +```kotlin +plugins { + kotlin("...") version "..." +} + +dependencies { + implementation("love.forte.simbot.component:simbot-component-telegram-type:$VERSION") +} +``` + +### Maven + +```xml + + + love.forte.simbot.component + simbot-component-telegram-type-jvm + ${VERSION} + + +``` From b60a6c3e4878cf4b31cbee6cfd71da6b9ea5f645 Mon Sep 17 00:00:00 2001 From: ForteScarlet Date: Tue, 9 Apr 2024 22:01:11 +0800 Subject: [PATCH 02/16] =?UTF-8?q?=E6=9B=B4=E6=96=B0README?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 6b71e0d..c915402 100644 --- a/README.md +++ b/README.md @@ -59,7 +59,7 @@ Serialization and network requests are based on [Kotlin serialization](https://g Provides definitions for most types in Telegram and supports serialization based on [Kotlin Serialization](https://github.com/Kotlin/kotlinx.serialization). -👉 [Go to Modules](simbot-component-telegram-type) to learn more. +👉 [Go to the module](simbot-component-telegram-type) to learn more. ### ⭐ API module @@ -71,7 +71,7 @@ is a simple, efficient and lightweight API implementation module. This module provides very little extra implementation. The goal is to preserve the feel of the original API as much as possible without overwrapping it. -👉 [Go to Modules](simbot-component-telegram-api) to learn more. +👉 [Go to the module](simbot-component-telegram-api) to learn more. ### ⭐ Stdlib module @@ -83,7 +83,7 @@ including the ability to subscribe to events. Again, the goal is to provide as much of the feel of the original API as possible without overwrapping it. -👉 [Go to Modules](simbot-component-telegram-stdlib) to learn more. +👉 [Go to the module](simbot-component-telegram-stdlib) to learn more. ### ⭐ Core Component module From e3e5cf18637515fe05a4b587f05fd7b9ac41f5a3 Mon Sep 17 00:00:00 2001 From: ForteScarlet Date: Tue, 9 Apr 2024 22:29:53 +0800 Subject: [PATCH 03/16] =?UTF-8?q?README,=20=E4=BB=A5=E5=8F=8Abuild=20confi?= =?UTF-8?q?g?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- simbot-component-telegram-api/build.gradle.kts | 10 +++++----- simbot-component-telegram-core/build.gradle.kts | 7 +++++++ simbot-component-telegram-stdlib/build.gradle.kts | 12 ++++++------ simbot-component-telegram-type/README.md | 9 +++++++++ simbot-component-telegram-type/README_CN.md | 8 ++++++++ 5 files changed, 35 insertions(+), 11 deletions(-) diff --git a/simbot-component-telegram-api/build.gradle.kts b/simbot-component-telegram-api/build.gradle.kts index 0f54e41..d33021a 100644 --- a/simbot-component-telegram-api/build.gradle.kts +++ b/simbot-component-telegram-api/build.gradle.kts @@ -132,11 +132,11 @@ kotlin.sourceSets.commonMain { } // see https://github.com/google/ksp/issues/567#issuecomment-1510477456 -// tasks.withType>().configureEach { -// if (name != "kspCommonMainKotlinMetadata") { -// dependsOn("kspCommonMainKotlinMetadata") -// } -// } +tasks.withType>().configureEach { + if (name != "kspCommonMainKotlinMetadata") { + dependsOn("kspCommonMainKotlinMetadata") + } +} // // kotlin.sourceSets.commonMain { // kotlin.srcDir("build/generated/ksp/metadata/commonMain/kotlin") diff --git a/simbot-component-telegram-core/build.gradle.kts b/simbot-component-telegram-core/build.gradle.kts index 2df866d..b7e3a2f 100644 --- a/simbot-component-telegram-core/build.gradle.kts +++ b/simbot-component-telegram-core/build.gradle.kts @@ -129,6 +129,13 @@ kotlin.sourceSets.commonMain { tasks.withType { kotlin.srcDir(destinationDirectory) } } +// see https://github.com/google/ksp/issues/567#issuecomment-1510477456 +tasks.withType>().configureEach { + if (name != "kspCommonMainKotlinMetadata") { + dependsOn("kspCommonMainKotlinMetadata") + } +} + tasks.withType().configureEach { dokkaSourceSets.configureEach { suppressGeneratedFiles.set(false) diff --git a/simbot-component-telegram-stdlib/build.gradle.kts b/simbot-component-telegram-stdlib/build.gradle.kts index 61fdb40..01767af 100644 --- a/simbot-component-telegram-stdlib/build.gradle.kts +++ b/simbot-component-telegram-stdlib/build.gradle.kts @@ -122,12 +122,12 @@ kotlin.sourceSets.commonMain { tasks.withType { kotlin.srcDir(destinationDirectory) } } -// // see https://github.com/google/ksp/issues/567#issuecomment-1510477456 -// tasks.withType>().configureEach { -// if(name != "kspCommonMainKotlinMetadata") { -// dependsOn("kspCommonMainKotlinMetadata") -// } -// } +// see https://github.com/google/ksp/issues/567#issuecomment-1510477456 +tasks.withType>().configureEach { + if(name != "kspCommonMainKotlinMetadata") { + dependsOn("kspCommonMainKotlinMetadata") + } +} // // kotlin.sourceSets.commonMain { // kotlin.srcDir("build/generated/ksp/metadata/commonMain/kotlin") diff --git a/simbot-component-telegram-type/README.md b/simbot-component-telegram-type/README.md index d3ca28e..274bbd9 100644 --- a/simbot-component-telegram-type/README.md +++ b/simbot-component-telegram-type/README.md @@ -44,3 +44,12 @@ dependencies { ``` + +## Notes +### Compatibility + +Currently, most types in modules are defined using `data class`. These types are considered to be used for serialization. +When officials modify/extend a type (such as adding fields), binary compatibility of the data class may not be guaranteed +(the parameters of the constructor have changed). + +This change usually increments the `minor` version number. diff --git a/simbot-component-telegram-type/README_CN.md b/simbot-component-telegram-type/README_CN.md index 6a44d05..6fcbec7 100644 --- a/simbot-component-telegram-type/README_CN.md +++ b/simbot-component-telegram-type/README_CN.md @@ -45,3 +45,11 @@ dependencies { ``` + +## 注意事项 +### 兼容性 + +目前此模块中的大部分类型均使用 `data class` 定义,并且它们被认为是用于进行序列化的。 +当官方对API做出修改时(例如增加字段),那么数据类的二进制兼容性可能无法被保证(因为构造函数的字段发生了变化)。 + +这种变更通常会递增 `minor` 版本号。 From 3dfc66cbd4a1ed9c8fababbe4d21e30e6cac9ede Mon Sep 17 00:00:00 2001 From: ForteScarlet Date: Tue, 9 Apr 2024 23:34:07 +0800 Subject: [PATCH 04/16] =?UTF-8?q?detekt=E5=92=8Cpublish=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle.kts | 24 + ...ram-multiplatform-maven-publish.gradle.kts | 44 +- config/detekt/detekt.yml | 784 ++++++++++++++++++ gradle/libs.versions.toml | 3 + .../forte/simbot/telegram/api/ApiRequests.kt | 2 +- .../kotlin/gen2/TelegramTypeGenerator.kt | 10 +- 6 files changed, 856 insertions(+), 11 deletions(-) create mode 100644 config/detekt/detekt.yml diff --git a/build.gradle.kts b/build.gradle.kts index 0a89966..ca5701d 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -16,6 +16,7 @@ */ +import io.gitlab.arturbosch.detekt.Detekt import love.forte.gradle.common.core.project.setup import love.forte.gradle.common.core.repository.Repositories @@ -24,6 +25,7 @@ plugins { `simbot-telegram-changelog-generator` `simbot-telegram-dokka-multi-module` `simbot-telegram-nexus-publish` + alias(libs.plugins.detekt) } setup(P.ComponentTelegram) @@ -62,3 +64,25 @@ idea { } } } + +detekt { + source.setFrom( + "simbot-component-telegram-api", + "simbot-component-telegram-core", + "simbot-component-telegram-stdlib", + "simbot-component-telegram-type", + ) + + config.setFrom(rootDir.resolve("config/detekt/detekt.yml")) + baseline = file("$projectDir/config/detekt/baseline.xml") + parallel = true + reportsDir = rootProject.layout.buildDirectory.dir("detekt/report").get().asFile +} + +// https://detekt.dev/blog/2019/03/03/configure-detekt-on-root-project/ +tasks.withType().configureEach { + exclude("**/resources/") + exclude("**/build/") + exclude("**/*Test/kotlin/") + exclude("**/*Test/java/") +} diff --git a/buildSrc/src/main/kotlin/simbot-telegram-multiplatform-maven-publish.gradle.kts b/buildSrc/src/main/kotlin/simbot-telegram-multiplatform-maven-publish.gradle.kts index e46dad3..2b08893 100644 --- a/buildSrc/src/main/kotlin/simbot-telegram-multiplatform-maven-publish.gradle.kts +++ b/buildSrc/src/main/kotlin/simbot-telegram-multiplatform-maven-publish.gradle.kts @@ -33,16 +33,46 @@ multiplatformConfigPublishing { project = P.ComponentTelegram isSnapshot = project.version.toString().contains("SNAPSHOT", true) - val jarJavadoc by tasks.registering(Jar::class) { - group = "documentation" - archiveClassifier.set("javadoc") - if (!(isSnapshot || isSnapshot() || isSimbotLocal())) { - archiveClassifier.set("javadoc") - from(tasks.findByName("dokkaHtml")) + publishing { + publications.withType { + val dokkaJar = p.tasks.register("${name}DokkaJar", Jar::class) { + group = JavaBasePlugin.DOCUMENTATION_GROUP + description = "Assembles Kotlin docs with Dokka into a Javadoc jar" + archiveClassifier.set("javadoc") + from(tasks.named("dokkaHtml")) + + // Each archive name should be distinct, to avoid implicit dependency issues. + // We use the same format as the sources Jar tasks. + // https://youtrack.jetbrains.com/issue/KT-46466 + archiveBaseName.set("${archiveBaseName.get()}-${name}") + } + artifact(dokkaJar) } } - artifact(jarJavadoc) + // val jarJavadoc by tasks.registering(Jar::class) { + // group = "documentation" + // archiveClassifier.set("javadoc") + // if (!(isSnapshot || isSnapshot() || isSimbotLocal())) { + // archiveClassifier.set("javadoc") + // from(tasks.findByName("dokkaHtml")) + // } + // } + + + // val dokkaJar = p.tasks.register("${publication.name}DokkaJar", Jar::class) { + // group = JavaBasePlugin.DOCUMENTATION_GROUP + // description = "Assembles Kotlin docs with Dokka into a Javadoc jar" + // archiveClassifier.set("javadoc") + // from(tasks.named("dokkaHtml")) + // + // // Each archive name should be distinct, to avoid implicit dependency issues. + // // We use the same format as the sources Jar tasks. + // // https://youtrack.jetbrains.com/issue/KT-46466 + // archiveBaseName.set("${archiveBaseName.get()}-${publication.name}") + // } + + // artifact(dokkaJar) releasesRepository = ReleaseRepository snapshotRepository = SnapshotRepository gpg = Gpg.ofSystemPropOrNull() diff --git a/config/detekt/detekt.yml b/config/detekt/detekt.yml new file mode 100644 index 0000000..8ad57cd --- /dev/null +++ b/config/detekt/detekt.yml @@ -0,0 +1,784 @@ +build: + maxIssues: 1145141919 # 先不限制最大问题 + excludeCorrectable: false + weights: + # complexity: 2 + # LongParameterList: 1 + # style: 1 + # comments: 1 + +config: + validation: true + warningsAsErrors: false + checkExhaustiveness: false + # when writing own rules with new properties, exclude the property path e.g.: 'my_rule_set,.*>.*>[my_property]' + excludes: '' + +processors: + active: true + exclude: + - 'DetektProgressListener' + # - 'KtFileCountProcessor' + # - 'PackageCountProcessor' + # - 'ClassCountProcessor' + # - 'FunctionCountProcessor' + # - 'PropertyCountProcessor' + # - 'ProjectComplexityProcessor' + # - 'ProjectCognitiveComplexityProcessor' + # - 'ProjectLLOCProcessor' + # - 'ProjectCLOCProcessor' + # - 'ProjectLOCProcessor' + # - 'ProjectSLOCProcessor' + # - 'LicenseHeaderLoaderExtension' + +console-reports: + active: true + exclude: + - 'ProjectStatisticsReport' + - 'ComplexityReport' + - 'NotificationReport' + - 'FindingsReport' + - 'FileBasedFindingsReport' + # - 'LiteFindingsReport' + +output-reports: + active: true + exclude: + # - 'TxtOutputReport' + # - 'XmlOutputReport' + # - 'HtmlOutputReport' + # - 'MdOutputReport' + - 'SarifOutputReport' + +comments: + active: true + AbsentOrWrongFileLicense: + active: false + licenseTemplateFile: 'license.template' + licenseTemplateIsRegex: false + CommentOverPrivateFunction: + active: false + CommentOverPrivateProperty: + active: false + DeprecatedBlockTag: + active: false + EndOfSentenceFormat: + active: false + endOfSentenceFormat: '([.?!][ \t\n\r\f<])|([.?!:]$)' + KDocReferencesNonPublicProperty: + active: false + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/androidUnitTest/**', '**/androidInstrumentedTest/**', '**/jsTest/**', '**/iosTest/**'] + OutdatedDocumentation: + active: false + matchTypeParameters: true + matchDeclarationsOrder: true + allowParamOnConstructorProperties: false + UndocumentedPublicClass: + active: false + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/androidUnitTest/**', '**/androidInstrumentedTest/**', '**/jsTest/**', '**/iosTest/**'] + searchInNestedClass: true + searchInInnerClass: true + searchInInnerObject: true + searchInInnerInterface: true + searchInProtectedClass: false + UndocumentedPublicFunction: + active: false + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/androidUnitTest/**', '**/androidInstrumentedTest/**', '**/jsTest/**', '**/iosTest/**'] + searchProtectedFunction: false + UndocumentedPublicProperty: + active: false + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/androidUnitTest/**', '**/androidInstrumentedTest/**', '**/jsTest/**', '**/iosTest/**'] + searchProtectedProperty: false + +complexity: + active: true + CognitiveComplexMethod: + active: false + threshold: 15 + ComplexCondition: + active: true + threshold: 4 + ComplexInterface: + active: false + threshold: 10 + includeStaticDeclarations: false + includePrivateDeclarations: false + ignoreOverloaded: false + CyclomaticComplexMethod: + active: true + threshold: 15 + ignoreSingleWhenExpression: false + ignoreSimpleWhenEntries: false + ignoreNestingFunctions: false + nestingFunctions: + - 'also' + - 'apply' + - 'forEach' + - 'isNotNull' + - 'ifNull' + - 'let' + - 'run' + - 'use' + - 'with' + LabeledExpression: + active: false + ignoredLabels: [] + LargeClass: + active: true + threshold: 600 + LongMethod: + active: true + threshold: 60 + LongParameterList: + active: true + functionThreshold: 6 + constructorThreshold: 7 + ignoreDefaultParameters: false + ignoreDataClasses: true + ignoreAnnotatedParameter: [] + MethodOverloading: + active: false + threshold: 6 + NamedArguments: + active: false + threshold: 3 + ignoreArgumentsMatchingNames: false + NestedBlockDepth: + active: true + threshold: 4 + NestedScopeFunctions: + active: false + threshold: 1 + functions: + - 'kotlin.apply' + - 'kotlin.run' + - 'kotlin.with' + - 'kotlin.let' + - 'kotlin.also' + ReplaceSafeCallChainWithRun: + active: false + StringLiteralDuplication: + active: false + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/androidUnitTest/**', '**/androidInstrumentedTest/**', '**/jsTest/**', '**/iosTest/**'] + threshold: 3 + ignoreAnnotation: true + excludeStringsWithLessThan5Characters: true + ignoreStringsRegex: '$^' + TooManyFunctions: + active: true + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/androidUnitTest/**', '**/androidInstrumentedTest/**', '**/jsTest/**', '**/iosTest/**'] + thresholdInFiles: 11 + thresholdInClasses: 11 + thresholdInInterfaces: 11 + thresholdInObjects: 11 + thresholdInEnums: 11 + ignoreDeprecated: false + ignorePrivate: false + ignoreOverridden: false + +coroutines: + active: true + GlobalCoroutineUsage: + active: false + InjectDispatcher: + active: true + dispatcherNames: + - 'IO' + - 'Default' + - 'Unconfined' + RedundantSuspendModifier: + active: true + SleepInsteadOfDelay: + active: true + SuspendFunSwallowedCancellation: + active: false + SuspendFunWithCoroutineScopeReceiver: + active: false + SuspendFunWithFlowReturnType: + active: true + +empty-blocks: + active: true + EmptyCatchBlock: + active: true + allowedExceptionNameRegex: '_|(ignore|expected).*' + EmptyClassBlock: + active: true + EmptyDefaultConstructor: + active: true + EmptyDoWhileBlock: + active: true + EmptyElseBlock: + active: true + EmptyFinallyBlock: + active: true + EmptyForBlock: + active: true + EmptyFunctionBlock: + active: true + ignoreOverridden: false + EmptyIfBlock: + active: true + EmptyInitBlock: + active: true + EmptyKtFile: + active: true + EmptySecondaryConstructor: + active: true + EmptyTryBlock: + active: true + EmptyWhenBlock: + active: true + EmptyWhileBlock: + active: true + +exceptions: + active: true + ExceptionRaisedInUnexpectedLocation: + active: true + methodNames: + - 'equals' + - 'finalize' + - 'hashCode' + - 'toString' + InstanceOfCheckForException: + active: true + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/androidUnitTest/**', '**/androidInstrumentedTest/**', '**/jsTest/**', '**/iosTest/**'] + NotImplementedDeclaration: + active: false + ObjectExtendsThrowable: + active: false + PrintStackTrace: + active: true + RethrowCaughtException: + active: true + ReturnFromFinally: + active: true + ignoreLabeled: false + SwallowedException: + active: true + ignoredExceptionTypes: + - 'InterruptedException' + - 'MalformedURLException' + - 'NumberFormatException' + - 'ParseException' + allowedExceptionNameRegex: '_|(ignore|expected).*' + ThrowingExceptionFromFinally: + active: true + ThrowingExceptionInMain: + active: false + ThrowingExceptionsWithoutMessageOrCause: + active: true + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/androidUnitTest/**', '**/androidInstrumentedTest/**', '**/jsTest/**', '**/iosTest/**'] + exceptions: + - 'ArrayIndexOutOfBoundsException' + - 'Exception' + - 'IllegalArgumentException' + - 'IllegalMonitorStateException' + - 'IllegalStateException' + - 'IndexOutOfBoundsException' + - 'NullPointerException' + - 'RuntimeException' + - 'Throwable' + ThrowingNewInstanceOfSameException: + active: true + TooGenericExceptionCaught: + active: false + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/androidUnitTest/**', '**/androidInstrumentedTest/**', '**/jsTest/**', '**/iosTest/**'] + exceptionNames: + - 'ArrayIndexOutOfBoundsException' + - 'Error' + - 'Exception' + - 'IllegalMonitorStateException' + - 'IndexOutOfBoundsException' + - 'NullPointerException' + - 'RuntimeException' + - 'Throwable' + allowedExceptionNameRegex: '_|(ignore|expected).*' + TooGenericExceptionThrown: + active: true + exceptionNames: + - 'Error' + - 'Exception' + - 'RuntimeException' + - 'Throwable' + +naming: + active: true + BooleanPropertyNaming: + active: false + allowedPattern: '^(is|has|are)' + ClassNaming: + active: true + classPattern: '[A-Z][a-zA-Z0-9]*' + ConstructorParameterNaming: + active: true + parameterPattern: '[a-z][A-Za-z0-9]*' + privateParameterPattern: '[a-z][A-Za-z0-9]*' + excludeClassPattern: '$^' + EnumNaming: + active: true + enumEntryPattern: '[A-Z][_a-zA-Z0-9]*' + ForbiddenClassName: + active: false + forbiddenName: [] + FunctionMaxLength: + active: false + maximumFunctionNameLength: 30 + FunctionMinLength: + active: false + minimumFunctionNameLength: 3 + FunctionNaming: + active: true + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/androidUnitTest/**', '**/androidInstrumentedTest/**', '**/jsTest/**', '**/iosTest/**'] + functionPattern: '[a-z][a-zA-Z0-9]*' + excludeClassPattern: '$^' + FunctionParameterNaming: + active: true + parameterPattern: '[a-z][A-Za-z0-9]*' + excludeClassPattern: '$^' + InvalidPackageDeclaration: + active: true + rootPackage: '' + requireRootInDeclaration: false + LambdaParameterNaming: + active: false + parameterPattern: '[a-z][A-Za-z0-9]*|_' + MatchingDeclarationName: + active: true + mustBeFirst: true + MemberNameEqualsClassName: + active: true + ignoreOverridden: true + NoNameShadowing: + active: true + NonBooleanPropertyPrefixedWithIs: + active: false + ObjectPropertyNaming: + active: true + constantPattern: '[A-Za-z][_A-Za-z0-9]*' + propertyPattern: '[A-Za-z][_A-Za-z0-9]*' + privatePropertyPattern: '(_)?[A-Za-z][_A-Za-z0-9]*' + PackageNaming: + active: true + packagePattern: '[a-z]+(\.[a-z][A-Za-z0-9]*)*' + TopLevelPropertyNaming: + active: true + constantPattern: '[A-Z][_A-Z0-9]*' + propertyPattern: '[A-Za-z][_A-Za-z0-9]*' + privatePropertyPattern: '_?[A-Za-z][_A-Za-z0-9]*' + VariableMaxLength: + active: false + maximumVariableNameLength: 64 + VariableMinLength: + active: false + minimumVariableNameLength: 1 + VariableNaming: + active: true + variablePattern: '[a-z][A-Za-z0-9]*' + privateVariablePattern: '(_)?[a-z][A-Za-z0-9]*' + excludeClassPattern: '$^' + +performance: + active: true + ArrayPrimitive: + active: true + CouldBeSequence: + active: false + threshold: 3 + ForEachOnRange: + active: true + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/androidUnitTest/**', '**/androidInstrumentedTest/**', '**/jsTest/**', '**/iosTest/**'] + SpreadOperator: + active: true + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/androidUnitTest/**', '**/androidInstrumentedTest/**', '**/jsTest/**', '**/iosTest/**'] + UnnecessaryPartOfBinaryExpression: + active: false + UnnecessaryTemporaryInstantiation: + active: true + +potential-bugs: + active: true + AvoidReferentialEquality: + active: true + forbiddenTypePatterns: + - 'kotlin.String' + CastNullableToNonNullableType: + active: false + CastToNullableType: + active: false + Deprecation: + active: false + DontDowncastCollectionTypes: + active: false + DoubleMutabilityForCollection: + active: true + mutableTypes: + - 'kotlin.collections.MutableList' + - 'kotlin.collections.MutableMap' + - 'kotlin.collections.MutableSet' + - 'java.util.ArrayList' + - 'java.util.LinkedHashSet' + - 'java.util.HashSet' + - 'java.util.LinkedHashMap' + - 'java.util.HashMap' + ElseCaseInsteadOfExhaustiveWhen: + active: false + ignoredSubjectTypes: [] + EqualsAlwaysReturnsTrueOrFalse: + active: true + EqualsWithHashCodeExist: + active: true + ExitOutsideMain: + active: false + ExplicitGarbageCollectionCall: + active: true + HasPlatformType: + active: true + IgnoredReturnValue: + active: true + restrictToConfig: true + returnValueAnnotations: + - 'CheckResult' + - '*.CheckResult' + - 'CheckReturnValue' + - '*.CheckReturnValue' + ignoreReturnValueAnnotations: + - 'CanIgnoreReturnValue' + - '*.CanIgnoreReturnValue' + returnValueTypes: + - 'kotlin.sequences.Sequence' + - 'kotlinx.coroutines.flow.*Flow' + - 'java.util.stream.*Stream' + ignoreFunctionCall: [] + ImplicitDefaultLocale: + active: true + ImplicitUnitReturnType: + active: false + allowExplicitReturnType: true + InvalidRange: + active: true + IteratorHasNextCallsNextMethod: + active: true + IteratorNotThrowingNoSuchElementException: + active: true + LateinitUsage: + active: false + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/androidUnitTest/**', '**/androidInstrumentedTest/**', '**/jsTest/**', '**/iosTest/**'] + ignoreOnClassesPattern: '' + MapGetWithNotNullAssertionOperator: + active: true + MissingPackageDeclaration: + active: false + excludes: ['**/*.kts'] + NullCheckOnMutableProperty: + active: false + NullableToStringCall: + active: false + PropertyUsedBeforeDeclaration: + active: false + UnconditionalJumpStatementInLoop: + active: false + UnnecessaryNotNullCheck: + active: false + UnnecessaryNotNullOperator: + active: true + UnnecessarySafeCall: + active: true + UnreachableCatchBlock: + active: true + UnreachableCode: + active: true + UnsafeCallOnNullableType: + active: true + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/androidUnitTest/**', '**/androidInstrumentedTest/**', '**/jsTest/**', '**/iosTest/**'] + UnsafeCast: + active: true + UnusedUnaryOperator: + active: true + UselessPostfixExpression: + active: true + WrongEqualsTypeParameter: + active: true + +style: + active: true + AlsoCouldBeApply: + active: false + BracesOnIfStatements: + active: false + singleLine: 'never' + multiLine: 'always' + BracesOnWhenStatements: + active: false + singleLine: 'necessary' + multiLine: 'consistent' + CanBeNonNullable: + active: false + CascadingCallWrapping: + active: false + includeElvis: true + ClassOrdering: + active: false + CollapsibleIfStatements: + active: false + DataClassContainsFunctions: + active: false + conversionFunctionPrefix: + - 'to' + allowOperators: false + DataClassShouldBeImmutable: + active: false + DestructuringDeclarationWithTooManyEntries: + active: true + maxDestructuringEntries: 3 + DoubleNegativeLambda: + active: false + negativeFunctions: + - reason: 'Use `takeIf` instead.' + value: 'takeUnless' + - reason: 'Use `all` instead.' + value: 'none' + negativeFunctionNameParts: + - 'not' + - 'non' + EqualsNullCall: + active: true + EqualsOnSignatureLine: + active: false + ExplicitCollectionElementAccessMethod: + active: false + ExplicitItLambdaParameter: + active: true + ExpressionBodySyntax: + active: false + includeLineWrapping: false + ForbiddenAnnotation: + active: false + annotations: + - reason: 'it is a java annotation. Use `Suppress` instead.' + value: 'java.lang.SuppressWarnings' + - reason: 'it is a java annotation. Use `kotlin.Deprecated` instead.' + value: 'java.lang.Deprecated' + - reason: 'it is a java annotation. Use `kotlin.annotation.MustBeDocumented` instead.' + value: 'java.lang.annotation.Documented' + - reason: 'it is a java annotation. Use `kotlin.annotation.Target` instead.' + value: 'java.lang.annotation.Target' + - reason: 'it is a java annotation. Use `kotlin.annotation.Retention` instead.' + value: 'java.lang.annotation.Retention' + - reason: 'it is a java annotation. Use `kotlin.annotation.Repeatable` instead.' + value: 'java.lang.annotation.Repeatable' + - reason: 'Kotlin does not support @Inherited annotation, see https://youtrack.jetbrains.com/issue/KT-22265' + value: 'java.lang.annotation.Inherited' + ForbiddenComment: + active: true + comments: + - reason: 'Forbidden FIXME todo marker in comment, please fix the problem.' + value: 'FIXME:' + - reason: 'Forbidden STOPSHIP todo marker in comment, please address the problem before shipping the code.' + value: 'STOPSHIP:' + - reason: 'Forbidden TODO todo marker in comment, please do the changes.' + value: 'TODO:' + allowedPatterns: '' + ForbiddenImport: + active: false + imports: [] + forbiddenPatterns: '' + ForbiddenMethodCall: + active: false + methods: + - reason: 'print does not allow you to configure the output stream. Use a logger instead.' + value: 'kotlin.io.print' + - reason: 'println does not allow you to configure the output stream. Use a logger instead.' + value: 'kotlin.io.println' + ForbiddenSuppress: + active: false + rules: [] + ForbiddenVoid: + active: true + ignoreOverridden: false + ignoreUsageInGenerics: false + FunctionOnlyReturningConstant: + active: true + ignoreOverridableFunction: true + ignoreActualFunction: true + excludedFunctions: [] + LoopWithTooManyJumpStatements: + active: true + maxJumpCount: 1 + MagicNumber: + active: true + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/androidUnitTest/**', '**/androidInstrumentedTest/**', '**/jsTest/**', '**/iosTest/**', '**/*.kts'] + ignoreNumbers: + - '-1' + - '0' + - '1' + - '2' + ignoreHashCodeFunction: true + ignorePropertyDeclaration: false + ignoreLocalVariableDeclaration: false + ignoreConstantDeclaration: true + ignoreCompanionObjectPropertyDeclaration: true + ignoreAnnotation: false + ignoreNamedArgument: true + ignoreEnums: false + ignoreRanges: false + ignoreExtensionFunctions: true + MandatoryBracesLoops: + active: false + MaxChainedCallsOnSameLine: + active: false + maxChainedCalls: 5 + MaxLineLength: + active: true + maxLineLength: 120 + excludePackageStatements: true + excludeImportStatements: true + excludeCommentStatements: false + excludeRawStrings: true + MayBeConst: + active: true + ModifierOrder: + active: true + MultilineLambdaItParameter: + active: false + MultilineRawStringIndentation: + active: false + indentSize: 4 + trimmingMethods: + - 'trimIndent' + - 'trimMargin' + NestedClassesVisibility: + active: true + NewLineAtEndOfFile: + active: true + NoTabs: + active: false + NullableBooleanCheck: + active: false + ObjectLiteralToLambda: + active: true + OptionalAbstractKeyword: + active: true + OptionalUnit: + active: false + PreferToOverPairSyntax: + active: false + ProtectedMemberInFinalClass: + active: true + RedundantExplicitType: + active: false + RedundantHigherOrderMapUsage: + active: true + RedundantVisibilityModifierRule: + active: false + ReturnCount: + active: true + max: 2 + excludedFunctions: + - 'equals' + excludeLabeled: false + excludeReturnFromLambda: true + excludeGuardClauses: false + SafeCast: + active: true + SerialVersionUIDInSerializableClass: + active: true + SpacingBetweenPackageAndImports: + active: false + StringShouldBeRawString: + active: false + maxEscapedCharacterCount: 2 + ignoredCharacters: [] + ThrowsCount: + active: true + max: 2 + excludeGuardClauses: false + TrailingWhitespace: + active: false + TrimMultilineRawString: + active: false + trimmingMethods: + - 'trimIndent' + - 'trimMargin' + UnderscoresInNumericLiterals: + active: false + acceptableLength: 4 + allowNonStandardGrouping: false + UnnecessaryAbstractClass: + active: true + UnnecessaryAnnotationUseSiteTarget: + active: false + UnnecessaryApply: + active: true + UnnecessaryBackticks: + active: false + UnnecessaryBracesAroundTrailingLambda: + active: false + UnnecessaryFilter: + active: true + UnnecessaryInheritance: + active: true + UnnecessaryInnerClass: + active: false + UnnecessaryLet: + active: false + UnnecessaryParentheses: + active: false + allowForUnclearPrecedence: false + UntilInsteadOfRangeTo: + active: false + UnusedImports: + active: false + UnusedParameter: + active: true + allowedNames: 'ignored|expected' + UnusedPrivateClass: + active: true + UnusedPrivateMember: + active: true + allowedNames: '' + UnusedPrivateProperty: + active: true + allowedNames: '_|ignored|expected|serialVersionUID' + UseAnyOrNoneInsteadOfFind: + active: true + UseArrayLiteralsInAnnotations: + active: true + UseCheckNotNull: + active: true + UseCheckOrError: + active: true + UseDataClass: + active: false + allowVars: false + UseEmptyCounterpart: + active: false + UseIfEmptyOrIfBlank: + active: false + UseIfInsteadOfWhen: + active: false + ignoreWhenContainingVariableDeclaration: false + UseIsNullOrEmpty: + active: true + UseLet: + active: false + UseOrEmpty: + active: true + UseRequire: + active: true + UseRequireNotNull: + active: true + UseSumOfInsteadOfFlatMapSize: + active: false + UselessCallOnNotNull: + active: true + UtilityClassWithPublicConstructor: + active: true + VarCouldBeVal: + active: true + ignoreLateinitVar: false + WildcardImport: + active: false + excludeImports: + - 'java.util.*' diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 1951e2c..e2b76e8 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -19,6 +19,8 @@ ksp = "1.9.22-1.0.17" kotlinPoet = "1.16.0" # https://mockk.io/ mockk = "1.13.10" +# https://detekt.dev/docs/intro +detekt = "1.23.3" [libraries] # simbot @@ -125,6 +127,7 @@ mockk = { module = "io.mockk:mockk", version.ref = "mockk" } [plugins] ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" } +detekt = { id = "io.gitlab.arturbosch.detekt", version.ref = "detekt" } [bundles] gradle-common = ["gradle-common-core", "gradle-common-multiplatform", "gradle-common-publication"] diff --git a/simbot-component-telegram-api/src/commonMain/kotlin/love/forte/simbot/telegram/api/ApiRequests.kt b/simbot-component-telegram-api/src/commonMain/kotlin/love/forte/simbot/telegram/api/ApiRequests.kt index 3bab952..6340eec 100644 --- a/simbot-component-telegram-api/src/commonMain/kotlin/love/forte/simbot/telegram/api/ApiRequests.kt +++ b/simbot-component-telegram-api/src/commonMain/kotlin/love/forte/simbot/telegram/api/ApiRequests.kt @@ -69,7 +69,7 @@ public suspend fun TelegramApi<*>.requestRaw( builder.method = HttpMethod.Post when (body) { is OutgoingContent -> { - + // nothing. } else -> { diff --git a/simbot-component-telegram-type/src/jvmTest/kotlin/gen2/TelegramTypeGenerator.kt b/simbot-component-telegram-type/src/jvmTest/kotlin/gen2/TelegramTypeGenerator.kt index c757e5b..2390b3e 100644 --- a/simbot-component-telegram-type/src/jvmTest/kotlin/gen2/TelegramTypeGenerator.kt +++ b/simbot-component-telegram-type/src/jvmTest/kotlin/gen2/TelegramTypeGenerator.kt @@ -242,10 +242,10 @@ class TelegramTypeGenerator { else -> { val array = arrayRegex.matchEntire(raw) if (array == null) { - return ClassName(DEF_PACKAGE, raw) + ClassName(DEF_PACKAGE, raw) } else { val arrayType = array.groupValues[1] - return LIST.parameterizedBy(resolveType(arrayType)) + LIST.parameterizedBy(resolveType(arrayType)) } } } @@ -256,7 +256,11 @@ class TelegramTypeGenerator { if (index == 0) { append(s) } else { - append(s.replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString() }) + append( + s.replaceFirstChar { + if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString() + } + ) } } } From 5616f431de9a8a0446b8dd3bac66e1d4fec1d7a6 Mon Sep 17 00:00:00 2001 From: ForteScarlet Date: Wed, 10 Apr 2024 02:12:07 +0800 Subject: [PATCH 05/16] =?UTF-8?q?detekt=20&=20ktlint=20=E8=A7=84=E5=88=99?= =?UTF-8?q?=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle.kts | 8 +- ...ram-multiplatform-maven-publish.gradle.kts | 57 ++- config/detekt/detekt.yml | 357 +++++++++++++++--- .../build.gradle.kts | 20 +- 4 files changed, 356 insertions(+), 86 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index ca5701d..7dcd129 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -65,6 +65,8 @@ idea { } } + + detekt { source.setFrom( "simbot-component-telegram-api", @@ -81,8 +83,12 @@ detekt { // https://detekt.dev/blog/2019/03/03/configure-detekt-on-root-project/ tasks.withType().configureEach { - exclude("**/resources/") + exclude("**/src/*/resources/") exclude("**/build/") exclude("**/*Test/kotlin/") exclude("**/*Test/java/") } + +dependencies { + detektPlugins("io.gitlab.arturbosch.detekt:detekt-formatting:${libs.versions.detekt.get()}") +} diff --git a/buildSrc/src/main/kotlin/simbot-telegram-multiplatform-maven-publish.gradle.kts b/buildSrc/src/main/kotlin/simbot-telegram-multiplatform-maven-publish.gradle.kts index 2b08893..418ce0b 100644 --- a/buildSrc/src/main/kotlin/simbot-telegram-multiplatform-maven-publish.gradle.kts +++ b/buildSrc/src/main/kotlin/simbot-telegram-multiplatform-maven-publish.gradle.kts @@ -25,7 +25,6 @@ plugins { `maven-publish` } - setup(P.ComponentTelegram) val p = project @@ -33,32 +32,32 @@ multiplatformConfigPublishing { project = P.ComponentTelegram isSnapshot = project.version.toString().contains("SNAPSHOT", true) - publishing { - publications.withType { - val dokkaJar = p.tasks.register("${name}DokkaJar", Jar::class) { - group = JavaBasePlugin.DOCUMENTATION_GROUP - description = "Assembles Kotlin docs with Dokka into a Javadoc jar" - archiveClassifier.set("javadoc") - from(tasks.named("dokkaHtml")) - - // Each archive name should be distinct, to avoid implicit dependency issues. - // We use the same format as the sources Jar tasks. - // https://youtrack.jetbrains.com/issue/KT-46466 - archiveBaseName.set("${archiveBaseName.get()}-${name}") - } - artifact(dokkaJar) - } - } - - // val jarJavadoc by tasks.registering(Jar::class) { - // group = "documentation" - // archiveClassifier.set("javadoc") - // if (!(isSnapshot || isSnapshot() || isSimbotLocal())) { - // archiveClassifier.set("javadoc") - // from(tasks.findByName("dokkaHtml")) + // publishing { + // publications.withType { + // val dokkaJar = p.tasks.register("${name}DokkaJar", Jar::class) { + // group = JavaBasePlugin.DOCUMENTATION_GROUP + // description = "Assembles Kotlin docs with Dokka into a Javadoc jar" + // archiveClassifier.set("javadoc") + // from(tasks.named("dokkaHtml")) + // + // // Each archive name should be distinct, to avoid implicit dependency issues. + // // We use the same format as the sources Jar tasks. + // // https://youtrack.jetbrains.com/issue/KT-46466 + // archiveBaseName.set("${archiveBaseName.get()}-${name}") + // } + // artifact(dokkaJar) // } // } + val jarJavadoc by tasks.registering(Jar::class) { + group = "documentation" + archiveClassifier.set("javadoc") + if (!(isSnapshot || isSnapshot() || isSimbotLocal())) { + archiveClassifier.set("javadoc") + from(tasks.findByName("dokkaHtml")) + } + } + // val dokkaJar = p.tasks.register("${publication.name}DokkaJar", Jar::class) { // group = JavaBasePlugin.DOCUMENTATION_GROUP @@ -72,7 +71,7 @@ multiplatformConfigPublishing { // archiveBaseName.set("${archiveBaseName.get()}-${publication.name}") // } - // artifact(dokkaJar) + artifact(jarJavadoc) releasesRepository = ReleaseRepository snapshotRepository = SnapshotRepository gpg = Gpg.ofSystemPropOrNull() @@ -86,10 +85,10 @@ multiplatformConfigPublishing { } // TODO see https://github.com/gradle-nexus/publish-plugin/issues/208#issuecomment-1465029831 -val signingTasks: TaskCollection = tasks.withType() -tasks.withType().configureEach { - mustRunAfter(signingTasks) -} +// val signingTasks: TaskCollection = tasks.withType() +// tasks.withType().configureEach { +// mustRunAfter(signingTasks) +// } show() diff --git a/config/detekt/detekt.yml b/config/detekt/detekt.yml index 8ad57cd..1d896c5 100644 --- a/config/detekt/detekt.yml +++ b/config/detekt/detekt.yml @@ -71,7 +71,7 @@ comments: OutdatedDocumentation: active: false matchTypeParameters: true - matchDeclarationsOrder: true + matchDeclarationsOrder: false allowParamOnConstructorProperties: false UndocumentedPublicClass: active: false @@ -91,7 +91,7 @@ comments: searchProtectedProperty: false complexity: - active: true + active: false # 暂时不管复杂度检测 CognitiveComplexMethod: active: false threshold: 15 @@ -247,7 +247,7 @@ exceptions: NotImplementedDeclaration: active: false ObjectExtendsThrowable: - active: false + active: true PrintStackTrace: active: true RethrowCaughtException: @@ -345,10 +345,10 @@ naming: active: false parameterPattern: '[a-z][A-Za-z0-9]*|_' MatchingDeclarationName: - active: true - mustBeFirst: true + active: false + mustBeFirst: false MemberNameEqualsClassName: - active: true + active: false ignoreOverridden: true NoNameShadowing: active: true @@ -384,7 +384,7 @@ performance: ArrayPrimitive: active: true CouldBeSequence: - active: false + active: true threshold: 3 ForEachOnRange: active: true @@ -476,11 +476,11 @@ potential-bugs: NullableToStringCall: active: false PropertyUsedBeforeDeclaration: - active: false + active: true UnconditionalJumpStatementInLoop: - active: false + active: true UnnecessaryNotNullCheck: - active: false + active: true UnnecessaryNotNullOperator: active: true UnnecessarySafeCall: @@ -533,7 +533,7 @@ style: active: true maxDestructuringEntries: 3 DoubleNegativeLambda: - active: false + active: true negativeFunctions: - reason: 'Use `takeIf` instead.' value: 'takeUnless' @@ -545,11 +545,11 @@ style: EqualsNullCall: active: true EqualsOnSignatureLine: - active: false + active: true ExplicitCollectionElementAccessMethod: - active: false - ExplicitItLambdaParameter: active: true + ExplicitItLambdaParameter: + active: false ExpressionBodySyntax: active: false includeLineWrapping: false @@ -571,7 +571,7 @@ style: - reason: 'Kotlin does not support @Inherited annotation, see https://youtrack.jetbrains.com/issue/KT-22265' value: 'java.lang.annotation.Inherited' ForbiddenComment: - active: true + active: false comments: - reason: 'Forbidden FIXME todo marker in comment, please fix the problem.' value: 'FIXME:' @@ -605,9 +605,9 @@ style: excludedFunctions: [] LoopWithTooManyJumpStatements: active: true - maxJumpCount: 1 + maxJumpCount: 3 MagicNumber: - active: true + active: false excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/androidUnitTest/**', '**/androidInstrumentedTest/**', '**/jsTest/**', '**/iosTest/**', '**/*.kts'] ignoreNumbers: - '-1' @@ -619,10 +619,10 @@ style: ignoreLocalVariableDeclaration: false ignoreConstantDeclaration: true ignoreCompanionObjectPropertyDeclaration: true - ignoreAnnotation: false + ignoreAnnotation: true ignoreNamedArgument: true - ignoreEnums: false - ignoreRanges: false + ignoreEnums: true + ignoreRanges: true ignoreExtensionFunctions: true MandatoryBracesLoops: active: false @@ -634,7 +634,7 @@ style: maxLineLength: 120 excludePackageStatements: true excludeImportStatements: true - excludeCommentStatements: false + excludeCommentStatements: true excludeRawStrings: true MayBeConst: active: true @@ -651,11 +651,11 @@ style: NestedClassesVisibility: active: true NewLineAtEndOfFile: - active: true - NoTabs: active: false + NoTabs: + active: true NullableBooleanCheck: - active: false + active: true ObjectLiteralToLambda: active: true OptionalAbstractKeyword: @@ -663,7 +663,7 @@ style: OptionalUnit: active: false PreferToOverPairSyntax: - active: false + active: true ProtectedMemberInFinalClass: active: true RedundantExplicitType: @@ -674,26 +674,26 @@ style: active: false ReturnCount: active: true - max: 2 + max: 3 excludedFunctions: - 'equals' - excludeLabeled: false + excludeLabeled: true excludeReturnFromLambda: true - excludeGuardClauses: false + excludeGuardClauses: true SafeCast: active: true SerialVersionUIDInSerializableClass: active: true SpacingBetweenPackageAndImports: - active: false + active: true StringShouldBeRawString: active: false maxEscapedCharacterCount: 2 ignoredCharacters: [] ThrowsCount: active: true - max: 2 - excludeGuardClauses: false + max: 3 + excludeGuardClauses: true TrailingWhitespace: active: false TrimMultilineRawString: @@ -706,9 +706,9 @@ style: acceptableLength: 4 allowNonStandardGrouping: false UnnecessaryAbstractClass: - active: true - UnnecessaryAnnotationUseSiteTarget: active: false + UnnecessaryAnnotationUseSiteTarget: + active: true UnnecessaryApply: active: true UnnecessaryBackticks: @@ -722,24 +722,24 @@ style: UnnecessaryInnerClass: active: false UnnecessaryLet: - active: false + active: true UnnecessaryParentheses: - active: false - allowForUnclearPrecedence: false + active: true + allowForUnclearPrecedence: true UntilInsteadOfRangeTo: active: false UnusedImports: - active: false - UnusedParameter: active: true + UnusedParameter: + active: false # 暂时不管未使用到的参数 allowedNames: 'ignored|expected' UnusedPrivateClass: - active: true + active: false # 暂时不管未使用到的私有类 UnusedPrivateMember: - active: true + active: false # 暂时不管未使用到的私有成员 allowedNames: '' UnusedPrivateProperty: - active: true + active: false # 暂时不管未使用到的私有属性 allowedNames: '_|ignored|expected|serialVersionUID' UseAnyOrNoneInsteadOfFind: active: true @@ -755,7 +755,7 @@ style: UseEmptyCounterpart: active: false UseIfEmptyOrIfBlank: - active: false + active: true UseIfInsteadOfWhen: active: false ignoreWhenContainingVariableDeclaration: false @@ -774,11 +774,280 @@ style: UselessCallOnNotNull: active: true UtilityClassWithPublicConstructor: - active: true + active: false VarCouldBeVal: active: true ignoreLateinitVar: false WildcardImport: - active: false + active: false # 也是还是挺有必要的? excludeImports: - 'java.util.*' + +formatting: + active: true + android: false + autoCorrect: true + AnnotationOnSeparateLine: + active: true + autoCorrect: true + indentSize: 4 + AnnotationSpacing: + active: true + autoCorrect: true + ArgumentListWrapping: + active: true + autoCorrect: true + indentSize: 4 + maxLineLength: 120 + BlockCommentInitialStarAlignment: + active: true + autoCorrect: true + ChainWrapping: + active: true + autoCorrect: true + indentSize: 4 + ClassName: + active: false + CommentSpacing: + active: true + autoCorrect: true + CommentWrapping: + active: true + autoCorrect: true + indentSize: 4 + ContextReceiverMapping: + active: false + autoCorrect: true + maxLineLength: 120 + indentSize: 4 + DiscouragedCommentLocation: + active: false + autoCorrect: true + EnumEntryNameCase: + active: true + autoCorrect: true + EnumWrapping: + active: false + autoCorrect: true + indentSize: 4 + Filename: + active: false + FinalNewline: + active: true + autoCorrect: true + insertFinalNewLine: true + FunKeywordSpacing: + active: true + autoCorrect: true + FunctionName: + active: false + FunctionReturnTypeSpacing: + active: true + autoCorrect: true + maxLineLength: 120 + FunctionSignature: + active: false + autoCorrect: false + forceMultilineWhenParameterCountGreaterOrEqualThan: 2147483647 + functionBodyExpressionWrapping: 'default' + maxLineLength: 120 + indentSize: 4 + FunctionStartOfBodySpacing: + active: true + autoCorrect: true + FunctionTypeReferenceSpacing: + active: true + autoCorrect: true + IfElseBracing: + active: false + autoCorrect: true + indentSize: 4 + IfElseWrapping: + active: false + autoCorrect: true + indentSize: 4 + ImportOrdering: + active: false + autoCorrect: true + layout: '*,java.**,javax.**,kotlin.**,^' + Indentation: + active: true + autoCorrect: true + indentSize: 4 + KdocWrapping: + active: true + autoCorrect: true + indentSize: 4 + MaximumLineLength: + active: true + maxLineLength: 120 + ignoreBackTickedIdentifier: false + ModifierListSpacing: + active: true + autoCorrect: true + ModifierOrdering: + active: true + autoCorrect: true + MultiLineIfElse: + active: true + autoCorrect: true + indentSize: 4 + MultilineExpressionWrapping: + active: false + autoCorrect: true + indentSize: 4 + NoBlankLineBeforeRbrace: + active: false + autoCorrect: true + NoBlankLineInList: + active: true + autoCorrect: false + NoBlankLinesInChainedMethodCalls: + active: true + autoCorrect: false + NoConsecutiveBlankLines: + active: false + autoCorrect: true + NoConsecutiveComments: + active: true + NoEmptyClassBody: + active: true + autoCorrect: true + NoEmptyFirstLineInClassBody: + active: false + autoCorrect: true + indentSize: 4 + NoEmptyFirstLineInMethodBlock: + active: true + autoCorrect: true + NoLineBreakAfterElse: + active: true + autoCorrect: true + NoLineBreakBeforeAssignment: + active: true + autoCorrect: true + NoMultipleSpaces: + active: true + autoCorrect: true + NoSemicolons: + active: true + autoCorrect: true + NoSingleLineBlockComment: + active: false + autoCorrect: true + indentSize: 4 + NoTrailingSpaces: + active: true + autoCorrect: true + NoUnitReturn: + active: false + autoCorrect: true + NoUnusedImports: + active: true + autoCorrect: true + NoWildcardImports: + active: false # 也许还是挺有用的 + packagesToUseImportOnDemandProperty: 'java.util.*,kotlinx.android.synthetic.**' + NullableTypeSpacing: + active: true + autoCorrect: true + PackageName: + active: true + autoCorrect: false + ParameterListSpacing: + active: false + autoCorrect: true + ParameterListWrapping: + active: false # 也许可以考虑? + autoCorrect: true + maxLineLength: 120 + indentSize: 4 + ParameterWrapping: + active: false + autoCorrect: true + indentSize: 4 + maxLineLength: 120 + PropertyName: + active: false + PropertyWrapping: + active: false + autoCorrect: true + indentSize: 4 + maxLineLength: 120 + SpacingAroundAngleBrackets: + active: true + autoCorrect: true + SpacingAroundColon: + active: true + autoCorrect: true + SpacingAroundComma: + active: true + autoCorrect: true + SpacingAroundCurly: + active: true + autoCorrect: true + SpacingAroundDot: + active: true + autoCorrect: true + SpacingAroundDoubleColon: + active: true + autoCorrect: true + SpacingAroundKeyword: + active: true + autoCorrect: true + SpacingAroundOperators: + active: true + autoCorrect: true + SpacingAroundParens: + active: true + autoCorrect: true + SpacingAroundRangeOperator: + active: true + autoCorrect: true + SpacingAroundUnaryOperator: + active: true + autoCorrect: true + SpacingBetweenDeclarationsWithAnnotations: + active: true + autoCorrect: true + SpacingBetweenDeclarationsWithComments: + active: true + autoCorrect: true + SpacingBetweenFunctionNameAndOpeningParenthesis: + active: true + autoCorrect: true + StringTemplate: + active: true + autoCorrect: true + StringTemplateIndent: + active: false + autoCorrect: true + indentSize: 4 + TrailingCommaOnCallSite: + active: false + autoCorrect: true + useTrailingCommaOnCallSite: true + TrailingCommaOnDeclarationSite: + active: false + autoCorrect: true + useTrailingCommaOnDeclarationSite: true + TryCatchFinallySpacing: + active: false + autoCorrect: true + indentSize: 4 + TypeArgumentListSpacing: + active: true + autoCorrect: true + indentSize: 4 + TypeParameterListSpacing: + active: true + autoCorrect: true + indentSize: 4 + UnnecessaryParenthesesBeforeTrailingLambda: + active: true + autoCorrect: true + Wrapping: + active: true + autoCorrect: true + indentSize: 4 + maxLineLength: 120 diff --git a/simbot-component-telegram-api/build.gradle.kts b/simbot-component-telegram-api/build.gradle.kts index d33021a..cca3f2a 100644 --- a/simbot-component-telegram-api/build.gradle.kts +++ b/simbot-component-telegram-api/build.gradle.kts @@ -35,7 +35,6 @@ setup(P.ComponentTelegram) useK2() configJavaCompileWithModule("simbot.component.telegram.api") -apply(plugin = "simbot-telegram-multiplatform-maven-publish") //configJsTestTasks() @@ -132,11 +131,11 @@ kotlin.sourceSets.commonMain { } // see https://github.com/google/ksp/issues/567#issuecomment-1510477456 -tasks.withType>().configureEach { - if (name != "kspCommonMainKotlinMetadata") { - dependsOn("kspCommonMainKotlinMetadata") - } -} +// tasks.withType>().configureEach { +// if (name != "kspCommonMainKotlinMetadata") { +// dependsOn("kspCommonMainKotlinMetadata") +// } +// } // // kotlin.sourceSets.commonMain { // kotlin.srcDir("build/generated/ksp/metadata/commonMain/kotlin") @@ -147,12 +146,9 @@ tasks.withType().configureEach { suppressGeneratedFiles.set(false) } } -// -// ksp { -// arg("qg.api.reader.enable", (!isCi).toString()) -// arg("qg.api.finder.api.output", rootDir.resolve("generated-docs/api-list.md").absolutePath) -// arg("qg.api.finder.event.output", rootDir.resolve("generated-docs/event-list.md").absolutePath) -// } + +apply(plugin = "simbot-telegram-multiplatform-maven-publish") + data class SupportListItem(val depth: Int, val name: String, val link: String, val mark: Boolean? = null) From fef7a1a95445e7b93dccdb2bc75045f2b27b9c19 Mon Sep 17 00:00:00 2001 From: ForteScarlet Date: Wed, 10 Apr 2024 02:23:02 +0800 Subject: [PATCH 06/16] =?UTF-8?q?detekt=20&=20ktlint=20(formatter)=20?= =?UTF-8?q?=E8=A7=84=E5=88=99=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...simbot-component-telegram [detekt].run.xml | 24 ++++++++++++++ build.gradle.kts | 11 +++++-- ...ram-multiplatform-maven-publish.gradle.kts | 10 ++++-- config/detekt/detekt.yml | 2 +- .../build.gradle.kts | 5 +-- .../forte/simbot/telegram/api/ApiRequests.kt | 7 ++-- .../forte/simbot/telegram/api/Telegram.kt | 4 +-- .../api/bot/GetMyShortDescriptionApi.kt | 3 +- .../forte/simbot/telegram/api/exceptions.kt | 4 ++- .../api/message/ReplyMarkupWrapper.kt | 12 ++++--- .../telegram/api/update/DeleteWebhookApi.kt | 7 ++-- .../telegram/api/update/SetWebhookApi.kt | 32 +++++++++++-------- .../build.gradle.kts | 2 +- .../component/telegram/core/TelegramUsage.kt | 2 +- .../telegram/core/actor/TelegramMember.kt | 2 +- .../SerializableTelegramBotConfiguration.kt | 12 +++---- .../telegram/core/bot/TelegramBotManager.kt | 11 +++++-- .../TelegramSingleMessageSourceReceiptImpl.kt | 2 +- .../build.gradle.kts | 4 +-- .../forte/simbot/telegram/stdlib/bot/Bot.kt | 2 +- .../telegram/stdlib/bot/internal/BotImpl.kt | 25 +++++++++++---- .../simbot/telegram/type/FormattingOptions.kt | 1 - .../type/inline/ChosenInlineResult.kt | 3 +- 23 files changed, 127 insertions(+), 60 deletions(-) create mode 100644 .run/runConfigurations/simbot-component-telegram [detekt].run.xml diff --git a/.run/runConfigurations/simbot-component-telegram [detekt].run.xml b/.run/runConfigurations/simbot-component-telegram [detekt].run.xml new file mode 100644 index 0000000..e74df74 --- /dev/null +++ b/.run/runConfigurations/simbot-component-telegram [detekt].run.xml @@ -0,0 +1,24 @@ + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index 7dcd129..227bd3c 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -19,6 +19,7 @@ import io.gitlab.arturbosch.detekt.Detekt import love.forte.gradle.common.core.project.setup import love.forte.gradle.common.core.repository.Repositories +import util.isCi plugins { idea @@ -66,6 +67,9 @@ idea { } +dependencies { + detektPlugins("io.gitlab.arturbosch.detekt:detekt-formatting:${libs.versions.detekt.get()}") +} detekt { source.setFrom( @@ -77,8 +81,12 @@ detekt { config.setFrom(rootDir.resolve("config/detekt/detekt.yml")) baseline = file("$projectDir/config/detekt/baseline.xml") + buildUponDefaultConfig = true parallel = true reportsDir = rootProject.layout.buildDirectory.dir("detekt/report").get().asFile + if (!isCi) { + autoCorrect = true + } } // https://detekt.dev/blog/2019/03/03/configure-detekt-on-root-project/ @@ -89,6 +97,3 @@ tasks.withType().configureEach { exclude("**/*Test/java/") } -dependencies { - detektPlugins("io.gitlab.arturbosch.detekt:detekt-formatting:${libs.versions.detekt.get()}") -} diff --git a/buildSrc/src/main/kotlin/simbot-telegram-multiplatform-maven-publish.gradle.kts b/buildSrc/src/main/kotlin/simbot-telegram-multiplatform-maven-publish.gradle.kts index 418ce0b..a3eda7c 100644 --- a/buildSrc/src/main/kotlin/simbot-telegram-multiplatform-maven-publish.gradle.kts +++ b/buildSrc/src/main/kotlin/simbot-telegram-multiplatform-maven-publish.gradle.kts @@ -93,7 +93,7 @@ multiplatformConfigPublishing { show() fun show() { - //// show project info + // // show project info logger.info( """ |======================================================= @@ -103,8 +103,12 @@ fun show() { |= project.description: {} |= os.name: {} |======================================================= - """.trimIndent(), - group, name, version, description, systemProp("os.name") + """.trimIndent(), + group, + name, + version, + description, + systemProp("os.name") ) } diff --git a/config/detekt/detekt.yml b/config/detekt/detekt.yml index 1d896c5..9dcfe73 100644 --- a/config/detekt/detekt.yml +++ b/config/detekt/detekt.yml @@ -685,7 +685,7 @@ style: SerialVersionUIDInSerializableClass: active: true SpacingBetweenPackageAndImports: - active: true + active: false # 开了的话,似乎多行也不行 StringShouldBeRawString: active: false maxEscapedCharacterCount: 2 diff --git a/simbot-component-telegram-api/build.gradle.kts b/simbot-component-telegram-api/build.gradle.kts index cca3f2a..a866722 100644 --- a/simbot-component-telegram-api/build.gradle.kts +++ b/simbot-component-telegram-api/build.gradle.kts @@ -36,7 +36,7 @@ setup(P.ComponentTelegram) useK2() configJavaCompileWithModule("simbot.component.telegram.api") -//configJsTestTasks() +// configJsTestTasks() kotlin { explicitApi() @@ -216,7 +216,8 @@ tasks.create("updateSupportListsDoc") { with(project.file("supports.md")) { toPath().writeText( - builder, Charsets.UTF_8, + builder, + Charsets.UTF_8, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.CREATE diff --git a/simbot-component-telegram-api/src/commonMain/kotlin/love/forte/simbot/telegram/api/ApiRequests.kt b/simbot-component-telegram-api/src/commonMain/kotlin/love/forte/simbot/telegram/api/ApiRequests.kt index 6340eec..9ad9127 100644 --- a/simbot-component-telegram-api/src/commonMain/kotlin/love/forte/simbot/telegram/api/ApiRequests.kt +++ b/simbot-component-telegram-api/src/commonMain/kotlin/love/forte/simbot/telegram/api/ApiRequests.kt @@ -48,8 +48,11 @@ public suspend fun TelegramApi<*>.requestRaw( ): HttpResponse { val builder = HttpRequestBuilder() builder.url { - if (server == null) takeFrom(Telegram.BaseServerUrl) - else takeFrom(server) + if (server == null) { + takeFrom(Telegram.BaseServerUrl) + } else { + takeFrom(server) + } appendEncodedPathSegments(token, this@requestRaw.name) } diff --git a/simbot-component-telegram-api/src/commonMain/kotlin/love/forte/simbot/telegram/api/Telegram.kt b/simbot-component-telegram-api/src/commonMain/kotlin/love/forte/simbot/telegram/api/Telegram.kt index 7ef6233..617ff2a 100644 --- a/simbot-component-telegram-api/src/commonMain/kotlin/love/forte/simbot/telegram/api/Telegram.kt +++ b/simbot-component-telegram-api/src/commonMain/kotlin/love/forte/simbot/telegram/api/Telegram.kt @@ -48,8 +48,8 @@ public object Telegram { * otherwise, return a new [Url]. */ @JvmStatic - public fun serverUrl(url: String): Url - = if (url == BASE_SERVER_VALUE) BaseServerUrl else Url(url) + public fun serverUrl(url: String): Url = + if (url == BASE_SERVER_VALUE) BaseServerUrl else Url(url) /** * A default [Json]. diff --git a/simbot-component-telegram-api/src/commonMain/kotlin/love/forte/simbot/telegram/api/bot/GetMyShortDescriptionApi.kt b/simbot-component-telegram-api/src/commonMain/kotlin/love/forte/simbot/telegram/api/bot/GetMyShortDescriptionApi.kt index f7d6af5..a3ef420 100644 --- a/simbot-component-telegram-api/src/commonMain/kotlin/love/forte/simbot/telegram/api/bot/GetMyShortDescriptionApi.kt +++ b/simbot-component-telegram-api/src/commonMain/kotlin/love/forte/simbot/telegram/api/bot/GetMyShortDescriptionApi.kt @@ -34,7 +34,8 @@ import kotlin.jvm.JvmStatic * * @author ForteScarlet */ -public class GetMyShortDescriptionApi private constructor(languageCode: String?) : SimpleBodyTelegramApi() { +public class GetMyShortDescriptionApi private constructor(languageCode: String?) : + SimpleBodyTelegramApi() { public companion object Factory { private const val NAME = "getMyShortDescription" private val SER = TelegramApiResult.serializer(BotShortDescription.serializer()) diff --git a/simbot-component-telegram-api/src/commonMain/kotlin/love/forte/simbot/telegram/api/exceptions.kt b/simbot-component-telegram-api/src/commonMain/kotlin/love/forte/simbot/telegram/api/exceptions.kt index 493f9a7..e567184 100644 --- a/simbot-component-telegram-api/src/commonMain/kotlin/love/forte/simbot/telegram/api/exceptions.kt +++ b/simbot-component-telegram-api/src/commonMain/kotlin/love/forte/simbot/telegram/api/exceptions.kt @@ -28,4 +28,6 @@ public open class TelegramApiResultNotOkException( ) : TelegramApiException(message, cause) -public class UnknownUpdatedFieldException(message: String? = "Unknown updated field") : IllegalArgumentException(message) +public class UnknownUpdatedFieldException(message: String? = "Unknown updated field") : IllegalArgumentException( + message +) diff --git a/simbot-component-telegram-api/src/commonMain/kotlin/love/forte/simbot/telegram/api/message/ReplyMarkupWrapper.kt b/simbot-component-telegram-api/src/commonMain/kotlin/love/forte/simbot/telegram/api/message/ReplyMarkupWrapper.kt index 9f37db4..5db4bb2 100644 --- a/simbot-component-telegram-api/src/commonMain/kotlin/love/forte/simbot/telegram/api/message/ReplyMarkupWrapper.kt +++ b/simbot-component-telegram-api/src/commonMain/kotlin/love/forte/simbot/telegram/api/message/ReplyMarkupWrapper.kt @@ -55,12 +55,15 @@ public sealed class ReplyMarkupWrapper { @JvmStatic @JvmName("valueOf") public fun InlineKeyboardMarkup.wrapper(): ReplyMarkupWrapper = InlineKeyboardMarkupWrapper(this) + @JvmStatic @JvmName("valueOf") public fun ReplyKeyboardMarkup.wrapper(): ReplyMarkupWrapper = ReplyKeyboardMarkupWrapper(this) + @JvmStatic @JvmName("valueOf") public fun ReplyKeyboardRemove.wrapper(): ReplyMarkupWrapper = ReplyKeyboardRemoveWrapper(this) + @JvmStatic @JvmName("valueOf") public fun ForceReply.wrapper(): ReplyMarkupWrapper = ForceReplyWrapper(this) @@ -68,13 +71,14 @@ public sealed class ReplyMarkupWrapper { } -private data class InlineKeyboardMarkupWrapper(override val value: InlineKeyboardMarkup): ReplyMarkupWrapper() -private data class ReplyKeyboardMarkupWrapper(override val value: ReplyKeyboardMarkup): ReplyMarkupWrapper() -private data class ReplyKeyboardRemoveWrapper(override val value: ReplyKeyboardRemove): ReplyMarkupWrapper() -private data class ForceReplyWrapper(override val value: ForceReply): ReplyMarkupWrapper() +private data class InlineKeyboardMarkupWrapper(override val value: InlineKeyboardMarkup) : ReplyMarkupWrapper() +private data class ReplyKeyboardMarkupWrapper(override val value: ReplyKeyboardMarkup) : ReplyMarkupWrapper() +private data class ReplyKeyboardRemoveWrapper(override val value: ReplyKeyboardRemove) : ReplyMarkupWrapper() +private data class ForceReplyWrapper(override val value: ForceReply) : ReplyMarkupWrapper() internal object ReplyMarkupWrapperSerializer : KSerializer { + @Suppress("ReturnCount") override fun deserialize(decoder: Decoder): ReplyMarkupWrapper { // deserialize unsupported, // decode to JsonObject. diff --git a/simbot-component-telegram-api/src/commonMain/kotlin/love/forte/simbot/telegram/api/update/DeleteWebhookApi.kt b/simbot-component-telegram-api/src/commonMain/kotlin/love/forte/simbot/telegram/api/update/DeleteWebhookApi.kt index b3bc7d4..bc65c75 100644 --- a/simbot-component-telegram-api/src/commonMain/kotlin/love/forte/simbot/telegram/api/update/DeleteWebhookApi.kt +++ b/simbot-component-telegram-api/src/commonMain/kotlin/love/forte/simbot/telegram/api/update/DeleteWebhookApi.kt @@ -40,8 +40,11 @@ public class DeleteWebhookApi private constructor(dropPendingUpdates: Boolean?) private val FALSE_INSTANCE = DeleteWebhookApi(false) private fun toJsonBodyString(dropPendingUpdates: Boolean?): String = - if (dropPendingUpdates == null) "{}" - else """{"drop_pending_updates":$dropPendingUpdates}""" + if (dropPendingUpdates == null) { + "{}" + } else { + """{"drop_pending_updates":$dropPendingUpdates}""" + } /** * Create an instance of [DeleteWebhookApi]. diff --git a/simbot-component-telegram-api/src/commonMain/kotlin/love/forte/simbot/telegram/api/update/SetWebhookApi.kt b/simbot-component-telegram-api/src/commonMain/kotlin/love/forte/simbot/telegram/api/update/SetWebhookApi.kt index 924e58a..7104f9d 100644 --- a/simbot-component-telegram-api/src/commonMain/kotlin/love/forte/simbot/telegram/api/update/SetWebhookApi.kt +++ b/simbot-component-telegram-api/src/commonMain/kotlin/love/forte/simbot/telegram/api/update/SetWebhookApi.kt @@ -56,20 +56,26 @@ public class SetWebhookApi private constructor(params: Params) : FormBodyTelegra public companion object Factory { private const val NAME = "setWebhook" private fun Params.toForm(): MultiPartFormDataContent { - return MultiPartFormDataContent(formData { - append("url", url) - ipAddress?.also { append("ip_address", it) } - maxConnections?.also { append("max_connections", it) } - allowedUpdates?.also { append("allowed_updates", it) } - dropPendingUpdates?.also { append("drop_pending_updates", it) } - secretToken?.also { append("secret_token", it) } + return MultiPartFormDataContent( + formData { + append("url", url) + ipAddress?.also { append("ip_address", it) } + maxConnections?.also { append("max_connections", it) } + allowedUpdates?.also { append("allowed_updates", it) } + dropPendingUpdates?.also { append("drop_pending_updates", it) } + secretToken?.also { append("secret_token", it) } - // upload file - certificate?.includeTo("certificate", headers { - append(HttpHeaders.ContentType, "image/png") - append(HttpHeaders.ContentDisposition, "filename=\"file\"") - }, this) - }) + // upload file + certificate?.includeTo( + "certificate", + headers { + append(HttpHeaders.ContentType, "image/png") + append(HttpHeaders.ContentDisposition, "filename=\"file\"") + }, + this + ) + } + ) } } diff --git a/simbot-component-telegram-core/build.gradle.kts b/simbot-component-telegram-core/build.gradle.kts index b7e3a2f..cfff715 100644 --- a/simbot-component-telegram-core/build.gradle.kts +++ b/simbot-component-telegram-core/build.gradle.kts @@ -35,7 +35,7 @@ useK2() configJavaCompileWithModule("simbot.component.telegram.core") apply(plugin = "simbot-telegram-multiplatform-maven-publish") -//configJsTestTasks() +// configJsTestTasks() kotlin { explicitApi() diff --git a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/TelegramUsage.kt b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/TelegramUsage.kt index 45ef0af..f1fc32c 100644 --- a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/TelegramUsage.kt +++ b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/TelegramUsage.kt @@ -58,7 +58,7 @@ import kotlin.jvm.JvmName * */ public fun C.useTelegram(block: ConfigurerFunction? = null) - where C : ComponentInstaller, C : PluginInstaller { + where C : ComponentInstaller, C : PluginInstaller { val builder = TelegramUsageBuilder().invokeBy(block) install(TelegramComponent) { builder.componentConfigurers.forEach { it.invokeWith(this) } diff --git a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/actor/TelegramMember.kt b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/actor/TelegramMember.kt index 7981e47..0e29455 100644 --- a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/actor/TelegramMember.kt +++ b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/actor/TelegramMember.kt @@ -87,7 +87,7 @@ public interface TelegramMember : TelegramUser, Member { } internal const val SEND_TO_MEMBER_IS_UNSUPPORTED = "Telegram bot cannot proactively send a message to a member " + - "because the private chat id is unknown." + "because the private chat id is unknown." internal fun sendToMemberIsUnsupported(): Nothing = throw UnsupportedOperationException(SEND_TO_MEMBER_IS_UNSUPPORTED) diff --git a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/bot/SerializableTelegramBotConfiguration.kt b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/bot/SerializableTelegramBotConfiguration.kt index 5f204cb..45528c2 100644 --- a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/bot/SerializableTelegramBotConfiguration.kt +++ b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/bot/SerializableTelegramBotConfiguration.kt @@ -96,14 +96,14 @@ public data class SerializableTelegramBotConfiguration( /* /** - * Ticket. - */ + * Ticket. + */ public val ticket: Ticket /** - * The server address used by the Bot. - * If [BotConfiguration.server] is `null`, - * [Telegram.BaseServerUrl] is returned. - */ + * The server address used by the Bot. + * If [BotConfiguration.server] is `null`, + * [Telegram.BaseServerUrl] is returned. + */ public val server: Url */ diff --git a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/bot/TelegramBotManager.kt b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/bot/TelegramBotManager.kt index 5fed0d3..59c98da 100644 --- a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/bot/TelegramBotManager.kt +++ b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/bot/TelegramBotManager.kt @@ -61,7 +61,7 @@ public interface TelegramBotManager : BotManager { if (configuration !is SerializableTelegramBotConfiguration) { throw UnsupportedBotConfigurationException( "Expect: love.forte.simbot.component.telegram.bot.SerializableTelegramBotConfiguration, " + - "but $configuration(${configuration::class})" + "but $configuration(${configuration::class})" ) } @@ -134,7 +134,10 @@ public interface TelegramBotManager : BotManager { configurer: ConfigurerFunction ): TelegramBotManager { val component = context.components.find { it is TelegramComponent } as? TelegramComponent - ?: throw NoSuchComponentException("TelegramComponent(id=${TelegramComponent.ID_VALUE}) not found in current context. Maybe you didn't install it in application?") + ?: throw NoSuchComponentException( + "TelegramComponent(id=${TelegramComponent.ID_VALUE}) not found in current context. " + + "Maybe you didn't install it in application?" + ) val configuration = TelegramBotManagerConfiguration().invokeBy(configurer) val coroutineContext = configuration.coroutineContext @@ -193,7 +196,9 @@ public interface TelegramBotManagerFactoryConfigurerProvider : * ``` * */ -public fun PluginInstaller.useTelegramBotManager(configurer: ConfigurerFunction? = null) { +public fun PluginInstaller.useTelegramBotManager( + configurer: ConfigurerFunction? = null +) { if (configurer == null) { install(TelegramBotManager) } else { diff --git a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/message/internal/TelegramSingleMessageSourceReceiptImpl.kt b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/message/internal/TelegramSingleMessageSourceReceiptImpl.kt index eece09f..d39110c 100644 --- a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/message/internal/TelegramSingleMessageSourceReceiptImpl.kt +++ b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/message/internal/TelegramSingleMessageSourceReceiptImpl.kt @@ -84,7 +84,7 @@ internal class TelegramSingleMessageIdReceiptImpl( override fun toString(): String = - "TelegramSingleMessageIdReceipt(id=${messageId})" + "TelegramSingleMessageIdReceipt(id=$messageId)" override fun equals(other: Any?): Boolean { if (this === other) return true diff --git a/simbot-component-telegram-stdlib/build.gradle.kts b/simbot-component-telegram-stdlib/build.gradle.kts index 01767af..bc691c1 100644 --- a/simbot-component-telegram-stdlib/build.gradle.kts +++ b/simbot-component-telegram-stdlib/build.gradle.kts @@ -35,7 +35,7 @@ useK2() configJavaCompileWithModule("simbot.component.telegram.stdlib") apply(plugin = "simbot-telegram-multiplatform-maven-publish") -//configJsTestTasks() +// configJsTestTasks() kotlin { explicitApi() @@ -124,7 +124,7 @@ kotlin.sourceSets.commonMain { // see https://github.com/google/ksp/issues/567#issuecomment-1510477456 tasks.withType>().configureEach { - if(name != "kspCommonMainKotlinMetadata") { + if (name != "kspCommonMainKotlinMetadata") { dependsOn("kspCommonMainKotlinMetadata") } } diff --git a/simbot-component-telegram-stdlib/src/commonMain/kotlin/love/forte/simbot/telegram/stdlib/bot/Bot.kt b/simbot-component-telegram-stdlib/src/commonMain/kotlin/love/forte/simbot/telegram/stdlib/bot/Bot.kt index 7133664..ac991f6 100644 --- a/simbot-component-telegram-stdlib/src/commonMain/kotlin/love/forte/simbot/telegram/stdlib/bot/Bot.kt +++ b/simbot-component-telegram-stdlib/src/commonMain/kotlin/love/forte/simbot/telegram/stdlib/bot/Bot.kt @@ -350,7 +350,7 @@ public enum class SubscribeSequence { * The normal sequence level. * Always executes asynchronously after [PRE]. */ - NORMAL; + NORMAL } /** diff --git a/simbot-component-telegram-stdlib/src/commonMain/kotlin/love/forte/simbot/telegram/stdlib/bot/internal/BotImpl.kt b/simbot-component-telegram-stdlib/src/commonMain/kotlin/love/forte/simbot/telegram/stdlib/bot/internal/BotImpl.kt index 7ff8b49..cf8b2e1 100644 --- a/simbot-component-telegram-stdlib/src/commonMain/kotlin/love/forte/simbot/telegram/stdlib/bot/internal/BotImpl.kt +++ b/simbot-component-telegram-stdlib/src/commonMain/kotlin/love/forte/simbot/telegram/stdlib/bot/internal/BotImpl.kt @@ -81,10 +81,12 @@ internal class BotImpl( val engine = configuration.apiClientEngine val engineFactory = configuration.apiClientEngineFactory - if (engine != null && engineFactory != null) { - throw IllegalArgumentException("`apiClientEngine` and `apiClientEngineFactory` can only have one that is not null.") + // 不能二者都有 + require(!(engine != null && engineFactory != null)) { + "`apiClientEngine` and `apiClientEngineFactory` can only have one that is not null." } + return when { engine == null && engineFactory == null -> HttpClient { apiClientConfigurer?.invokeWith(this) @@ -102,7 +104,7 @@ internal class BotImpl( } else -> - throw IllegalArgumentException() + throw IllegalArgumentException("`engine` and `engineFactory` only need one.") } } @@ -134,7 +136,7 @@ internal class BotImpl( override suspend fun pushUpdate(update: Update, raw: String?) { job.ensureActive() - val channel = eventChannel ?: throw IllegalStateException("Bot not started yet") + val channel = eventChannel ?: error("Bot not started yet") val event = update.resolveToEvent(raw) channel.send(event) @@ -238,13 +240,21 @@ internal class BotImpl( if (retry.isDelayMillisMultiplyByRetryTimes) { delayMillis { retryTimes -> (retry.delayMillis * retryTimes).also { millis -> - eventLogger.debug("LongPolling next retry delay millis {} in retry {}", millis, retryTimes) + eventLogger.debug( + "LongPolling next retry delay millis {} in retry {}", + millis, + retryTimes + ) } } } else { delayMillis { retryTimes -> retry.delayMillis.also { millis -> - eventLogger.debug("LongPolling next retry delay millis {} in retry {}", millis, retryTimes) + eventLogger.debug( + "LongPolling next retry delay millis {} in retry {}", + millis, + retryTimes + ) } } } @@ -319,7 +329,8 @@ internal class BotImpl( } emptyList() - }) { api -> + } + ) { api -> api.requestData(client, token, server) }.collect { update -> pushUpdate(update) diff --git a/simbot-component-telegram-type/src/commonMain/kotlin/love/forte/simbot/telegram/type/FormattingOptions.kt b/simbot-component-telegram-type/src/commonMain/kotlin/love/forte/simbot/telegram/type/FormattingOptions.kt index 7ffabbc..d805b11 100644 --- a/simbot-component-telegram-type/src/commonMain/kotlin/love/forte/simbot/telegram/type/FormattingOptions.kt +++ b/simbot-component-telegram-type/src/commonMain/kotlin/love/forte/simbot/telegram/type/FormattingOptions.kt @@ -61,5 +61,4 @@ public enum class FormattingOption(public val value: String) { * [Markdown style](https://core.telegram.org/bots/api#markdown-style) */ MARKDOWN(FORMATTING_OPTION_MARKDOWN_STYLE), - ; } diff --git a/simbot-component-telegram-type/src/commonMain/kotlin/love/forte/simbot/telegram/type/inline/ChosenInlineResult.kt b/simbot-component-telegram-type/src/commonMain/kotlin/love/forte/simbot/telegram/type/inline/ChosenInlineResult.kt index 0236892..765392a 100644 --- a/simbot-component-telegram-type/src/commonMain/kotlin/love/forte/simbot/telegram/type/inline/ChosenInlineResult.kt +++ b/simbot-component-telegram-type/src/commonMain/kotlin/love/forte/simbot/telegram/type/inline/ChosenInlineResult.kt @@ -54,5 +54,4 @@ public data class ChosenInlineResult( * The query that was used to obtain the result */ val query: String, - - ) +) From cf64de7492bc02b4f2c54116596b7e5d349f9111 Mon Sep 17 00:00:00 2001 From: ForteScarlet Date: Wed, 10 Apr 2024 02:36:06 +0800 Subject: [PATCH 07/16] test branch with detekt check --- .github/workflows/test-branch.yml | 35 +++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/.github/workflows/test-branch.yml b/.github/workflows/test-branch.yml index cc4bb9e..d545532 100644 --- a/.github/workflows/test-branch.yml +++ b/.github/workflows/test-branch.yml @@ -45,14 +45,41 @@ jobs: allTests --info --warning-mode all -# --build-cache -# -Porg.gradle.daemon=false -# -Porg.gradle.jvmargs="-Xmx4g -Xms2g -XX:MaxMetaspaceSize=1g -Dfile.encoding=UTF-8" + # --build-cache + # -Porg.gradle.daemon=false + # -Porg.gradle.jvmargs="-Xmx4g -Xms2g -XX:MaxMetaspaceSize=1g -Dfile.encoding=UTF-8" - name: Upload test reports uses: actions/upload-artifact@v4 if: ${{ always() }} with: - name: test-reports-${{ matrix.os }} + name: test-reports-${{ runner.os }} path: '**/build/reports/tests' retention-days: 7 + + detekt-check: + name: Detekt check + strategy: + matrix: + os: [ macos-latest, windows-latest, ubuntu-latest ] + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-java@v4 + with: + distribution: 'zulu' + java-version: 21 + cache: 'gradle' + + - name: Run All Tests + uses: gradle/actions/setup-gradle@v3 + with: + gradle-version: 8.5 + arguments: detekt + - name: Upload detekt reports + uses: actions/upload-artifact@v4 + if: ${{ always() }} + with: + name: test-reports-${{ runner.os }} + path: '**/build/detekt/report' + retention-days: 7 From 6c48b4eec034e3cf5dfafcd814a3eb1bc923751e Mon Sep 17 00:00:00 2001 From: ForteScarlet Date: Wed, 10 Apr 2024 02:51:23 +0800 Subject: [PATCH 08/16] =?UTF-8?q?=E5=B0=9D=E8=AF=95=E4=BF=AE=E5=A4=8DCI?= =?UTF-8?q?=E4=B8=AD=E6=97=A0=E6=B3=95=E6=89=93=E5=8C=85=E5=8F=91=E5=B8=83?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...ram-multiplatform-maven-publish.gradle.kts | 26 ++++++++++++++++--- .../build.gradle.kts | 7 ----- .../build.gradle.kts | 10 +++---- 3 files changed, 27 insertions(+), 16 deletions(-) diff --git a/buildSrc/src/main/kotlin/simbot-telegram-multiplatform-maven-publish.gradle.kts b/buildSrc/src/main/kotlin/simbot-telegram-multiplatform-maven-publish.gradle.kts index a3eda7c..41ba00f 100644 --- a/buildSrc/src/main/kotlin/simbot-telegram-multiplatform-maven-publish.gradle.kts +++ b/buildSrc/src/main/kotlin/simbot-telegram-multiplatform-maven-publish.gradle.kts @@ -85,10 +85,28 @@ multiplatformConfigPublishing { } // TODO see https://github.com/gradle-nexus/publish-plugin/issues/208#issuecomment-1465029831 -// val signingTasks: TaskCollection = tasks.withType() -// tasks.withType().configureEach { -// mustRunAfter(signingTasks) -// } +val signingTasks: TaskCollection = tasks.withType() +tasks.withType().configureEach { + mustRunAfter(signingTasks) +} +// TODO see https://github.com/gradle/gradle/issues/26132 +// Resolves issues with .asc task output of the sign task of native targets. +// See: https://github.com/gradle/gradle/issues/26132 +// And: https://youtrack.jetbrains.com/issue/KT-46466 +tasks.withType().configureEach { + val pubName = name.removePrefix("sign").removeSuffix("Publication") + + // These tasks only exist for native targets, hence findByName() to avoid trying to find them for other targets + + // Task ':linkDebugTest' uses this output of task ':signPublication' without declaring an explicit or implicit dependency + tasks.findByName("linkDebugTest$pubName")?.let { + mustRunAfter(it) + } + // Task ':compileTestKotlin' uses this output of task ':signPublication' without declaring an explicit or implicit dependency + tasks.findByName("compileTestKotlin$pubName")?.let { + mustRunAfter(it) + } +} show() diff --git a/simbot-component-telegram-core/build.gradle.kts b/simbot-component-telegram-core/build.gradle.kts index cfff715..5a33ecd 100644 --- a/simbot-component-telegram-core/build.gradle.kts +++ b/simbot-component-telegram-core/build.gradle.kts @@ -129,13 +129,6 @@ kotlin.sourceSets.commonMain { tasks.withType { kotlin.srcDir(destinationDirectory) } } -// see https://github.com/google/ksp/issues/567#issuecomment-1510477456 -tasks.withType>().configureEach { - if (name != "kspCommonMainKotlinMetadata") { - dependsOn("kspCommonMainKotlinMetadata") - } -} - tasks.withType().configureEach { dokkaSourceSets.configureEach { suppressGeneratedFiles.set(false) diff --git a/simbot-component-telegram-stdlib/build.gradle.kts b/simbot-component-telegram-stdlib/build.gradle.kts index bc691c1..dd194cb 100644 --- a/simbot-component-telegram-stdlib/build.gradle.kts +++ b/simbot-component-telegram-stdlib/build.gradle.kts @@ -123,11 +123,11 @@ kotlin.sourceSets.commonMain { } // see https://github.com/google/ksp/issues/567#issuecomment-1510477456 -tasks.withType>().configureEach { - if (name != "kspCommonMainKotlinMetadata") { - dependsOn("kspCommonMainKotlinMetadata") - } -} +// tasks.withType>().configureEach { +// if (name != "kspCommonMainKotlinMetadata") { +// dependsOn("kspCommonMainKotlinMetadata") +// } +// } // // kotlin.sourceSets.commonMain { // kotlin.srcDir("build/generated/ksp/metadata/commonMain/kotlin") From a6c6835b4f756a78added507d7d75b9bee78c47e Mon Sep 17 00:00:00 2001 From: ForteScarlet Date: Wed, 10 Apr 2024 02:53:33 +0800 Subject: [PATCH 09/16] =?UTF-8?q?=E5=A2=9E=E5=8A=A0detekt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/detekt/detekt.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/config/detekt/detekt.yml b/config/detekt/detekt.yml index 9dcfe73..e29fc6c 100644 --- a/config/detekt/detekt.yml +++ b/config/detekt/detekt.yml @@ -1,7 +1,8 @@ build: - maxIssues: 1145141919 # 先不限制最大问题 + maxIssues: 10000 # 先不限制最大问题 excludeCorrectable: false weights: + formatting: 10000 # 代码格式的问题,一般都有 autoCorrect, 需要尽可能不出错 # complexity: 2 # LongParameterList: 1 # style: 1 From 1a28d541c8eab5bce7ed3f398dd15baf1cd0decf Mon Sep 17 00:00:00 2001 From: ForteScarlet Date: Wed, 10 Apr 2024 03:02:04 +0800 Subject: [PATCH 10/16] =?UTF-8?q?=E5=A2=9E=E5=8A=A0detekt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/detekt/detekt.yml | 12 ++++++------ .../telegram/api/message/CopyMessageApi.kt | 4 +++- .../telegram/api/message/CopyMessagesApi.kt | 16 +++++++++------- .../telegram/api/message/ForwardMessageApi.kt | 1 + .../telegram/api/message/ForwardMessagesApi.kt | 1 + .../telegram/api/message/SendMessageApi.kt | 3 +-- .../simbot/telegram/api/update/GetUpdatesApi.kt | 4 +++- .../actor/internal/TelegramUserContactImpl.kt | 11 ++++++++--- .../core/bot/internal/TelegramBotImpl.kt | 2 +- .../telegram/core/component/TelegramComponent.kt | 4 +++- .../telegram/core/event/TelegramMessageEvent.kt | 6 ++++-- .../forte/simbot/telegram/type/InputMedia.kt | 1 + .../love/forte/simbot/telegram/type/game/Game.kt | 3 --- 13 files changed, 41 insertions(+), 27 deletions(-) diff --git a/config/detekt/detekt.yml b/config/detekt/detekt.yml index e29fc6c..f0091b7 100644 --- a/config/detekt/detekt.yml +++ b/config/detekt/detekt.yml @@ -3,10 +3,10 @@ build: excludeCorrectable: false weights: formatting: 10000 # 代码格式的问题,一般都有 autoCorrect, 需要尽可能不出错 - # complexity: 2 - # LongParameterList: 1 - # style: 1 - # comments: 1 + comments: 0 + complexity: 0 + LongParameterList: 0 + style: 0 config: validation: true @@ -730,7 +730,7 @@ style: UntilInsteadOfRangeTo: active: false UnusedImports: - active: true + active: false UnusedParameter: active: false # 暂时不管未使用到的参数 allowedNames: 'ignored|expected' @@ -901,7 +901,7 @@ formatting: active: false autoCorrect: true NoBlankLineInList: - active: true + active: false autoCorrect: false NoBlankLinesInChainedMethodCalls: active: true diff --git a/simbot-component-telegram-api/src/commonMain/kotlin/love/forte/simbot/telegram/api/message/CopyMessageApi.kt b/simbot-component-telegram-api/src/commonMain/kotlin/love/forte/simbot/telegram/api/message/CopyMessageApi.kt index b4eb991..f261eb4 100644 --- a/simbot-component-telegram-api/src/commonMain/kotlin/love/forte/simbot/telegram/api/message/CopyMessageApi.kt +++ b/simbot-component-telegram-api/src/commonMain/kotlin/love/forte/simbot/telegram/api/message/CopyMessageApi.kt @@ -140,7 +140,8 @@ public class CopyMessageApi private constructor(body: Body) : SimpleBodyTelegram */ @Suppress("MemberVisibilityCanBePrivate") public class Builder { - // Requires + //region Requires + /** * @see Body.chatId */ @@ -181,6 +182,7 @@ public class CopyMessageApi private constructor(body: Body) : SimpleBodyTelegram } public var messageId: Int? = null + //endregion // Optionals public var messageThreadId: Int? = null diff --git a/simbot-component-telegram-api/src/commonMain/kotlin/love/forte/simbot/telegram/api/message/CopyMessagesApi.kt b/simbot-component-telegram-api/src/commonMain/kotlin/love/forte/simbot/telegram/api/message/CopyMessagesApi.kt index 9c87597..fc1d2bf 100644 --- a/simbot-component-telegram-api/src/commonMain/kotlin/love/forte/simbot/telegram/api/message/CopyMessagesApi.kt +++ b/simbot-component-telegram-api/src/commonMain/kotlin/love/forte/simbot/telegram/api/message/CopyMessagesApi.kt @@ -55,13 +55,14 @@ public class CopyMessagesApi private constructor(body: Body) : SimpleBodyTelegra * Create a [CopyMessagesApi] based only on required. */ @JvmStatic - public fun create(chatId: ChatId, fromChatId: ChatId, messageIds: Collection): CopyMessagesApi = CopyMessagesApi( - Body( - chatId = chatId, - fromChatId = fromChatId, - messageIds = messageIds + public fun create(chatId: ChatId, fromChatId: ChatId, messageIds: Collection): CopyMessagesApi = + CopyMessagesApi( + Body( + chatId = chatId, + fromChatId = fromChatId, + messageIds = messageIds + ) ) - ) /** * Create a [Builder]. @@ -123,7 +124,8 @@ public class CopyMessagesApi private constructor(body: Body) : SimpleBodyTelegra */ @Suppress("MemberVisibilityCanBePrivate") public class Builder { - // Requires + // Region Requires + /** * @see Body.chatId */ diff --git a/simbot-component-telegram-api/src/commonMain/kotlin/love/forte/simbot/telegram/api/message/ForwardMessageApi.kt b/simbot-component-telegram-api/src/commonMain/kotlin/love/forte/simbot/telegram/api/message/ForwardMessageApi.kt index a5eafbd..65b94fb 100644 --- a/simbot-component-telegram-api/src/commonMain/kotlin/love/forte/simbot/telegram/api/message/ForwardMessageApi.kt +++ b/simbot-component-telegram-api/src/commonMain/kotlin/love/forte/simbot/telegram/api/message/ForwardMessageApi.kt @@ -119,6 +119,7 @@ public class ForwardMessageApi private constructor(body: Body) : SimpleBodyTeleg @Suppress("MemberVisibilityCanBePrivate") public class Builder { // Requires + /** * @see Body.chatId */ diff --git a/simbot-component-telegram-api/src/commonMain/kotlin/love/forte/simbot/telegram/api/message/ForwardMessagesApi.kt b/simbot-component-telegram-api/src/commonMain/kotlin/love/forte/simbot/telegram/api/message/ForwardMessagesApi.kt index a1406cf..3a2007d 100644 --- a/simbot-component-telegram-api/src/commonMain/kotlin/love/forte/simbot/telegram/api/message/ForwardMessagesApi.kt +++ b/simbot-component-telegram-api/src/commonMain/kotlin/love/forte/simbot/telegram/api/message/ForwardMessagesApi.kt @@ -123,6 +123,7 @@ public class ForwardMessagesApi private constructor(body: Body) : SimpleBodyTele @Suppress("MemberVisibilityCanBePrivate") public class Builder { // Requires + /** * @see Body.chatId */ diff --git a/simbot-component-telegram-api/src/commonMain/kotlin/love/forte/simbot/telegram/api/message/SendMessageApi.kt b/simbot-component-telegram-api/src/commonMain/kotlin/love/forte/simbot/telegram/api/message/SendMessageApi.kt index 1297874..5300157 100644 --- a/simbot-component-telegram-api/src/commonMain/kotlin/love/forte/simbot/telegram/api/message/SendMessageApi.kt +++ b/simbot-component-telegram-api/src/commonMain/kotlin/love/forte/simbot/telegram/api/message/SendMessageApi.kt @@ -126,7 +126,7 @@ public class SendMessageApi private constructor(body: Body) : SimpleBodyTelegram @SerialName("chat_id") public val chatId: ChatId, // Integer or String public val text: String, - + // Optionals @SerialName("message_thread_id") public val messageThreadId: Int? = null, @SerialName("parse_mode") @@ -140,7 +140,6 @@ public class SendMessageApi private constructor(body: Body) : SimpleBodyTelegram public val protectContent: Boolean? = null, @SerialName("reply_parameters") public val replyParameters: ReplyParameters? = null, - @SerialName("reply_markup") public val replyMarkup: ReplyMarkupWrapper? = null, ) diff --git a/simbot-component-telegram-api/src/commonMain/kotlin/love/forte/simbot/telegram/api/update/GetUpdatesApi.kt b/simbot-component-telegram-api/src/commonMain/kotlin/love/forte/simbot/telegram/api/update/GetUpdatesApi.kt index 006ff4e..e090bb5 100644 --- a/simbot-component-telegram-api/src/commonMain/kotlin/love/forte/simbot/telegram/api/update/GetUpdatesApi.kt +++ b/simbot-component-telegram-api/src/commonMain/kotlin/love/forte/simbot/telegram/api/update/GetUpdatesApi.kt @@ -151,7 +151,9 @@ public inline fun getUpdateFlow( eachLimit: Int? = null, allowedUpdates: Collection? = null, crossinline onEachResult: (List) -> List = { it }, - crossinline onError: (Throwable) -> List = { if (it is HttpRequestTimeoutException) emptyList() else throw it }, + crossinline onError: (Throwable) -> List = { + if (it is HttpRequestTimeoutException) emptyList() else throw it + }, crossinline requestor: suspend (GetUpdatesApi) -> List ): Flow { return flow { diff --git a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/actor/internal/TelegramUserContactImpl.kt b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/actor/internal/TelegramUserContactImpl.kt index 00aba3b..dda6935 100644 --- a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/actor/internal/TelegramUserContactImpl.kt +++ b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/actor/internal/TelegramUserContactImpl.kt @@ -54,9 +54,14 @@ internal class TelegramUserContactImpl( return sent.toTelegramMessageReceipt(bot) } - override fun toString(): String = buildString { - return "TelegramUserContact(id=${source.id}, firstName=${source.firstName} username=${source.username}, chat=Chat(id=${sourceChat.id}, type=${sourceChat.type} title=${sourceChat.title}))" - } + override fun toString(): String = + "TelegramUserContact(" + + "id=${source.id}, " + + "firstName=${source.firstName} " + + "username=${source.username}, " + + "chat=Chat(id=${sourceChat.id}, " + + "type=${sourceChat.type} " + + "title=${sourceChat.title}))" } internal fun User.toTelegramUserContact(bot: TelegramBotImpl, chat: Chat): TelegramUserContactImpl = diff --git a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/bot/internal/TelegramBotImpl.kt b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/bot/internal/TelegramBotImpl.kt index 4dd2b54..d8735ec 100644 --- a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/bot/internal/TelegramBotImpl.kt +++ b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/bot/internal/TelegramBotImpl.kt @@ -73,7 +73,7 @@ internal class TelegramBotImpl( private var _userInfo: User? = null override val userInfo: User - get() = _userInfo ?: throw IllegalStateException("`userInfo` has not been initialized yet.") + get() = _userInfo ?: error("`userInfo` has not been initialized yet.") override suspend fun queryUserInfo(): User { return GetMeApi.create().requestDataBy(source).also { diff --git a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/component/TelegramComponent.kt b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/component/TelegramComponent.kt index 12a5feb..519fbe8 100644 --- a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/component/TelegramComponent.kt +++ b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/component/TelegramComponent.kt @@ -122,7 +122,9 @@ public interface TelegramComponentFactoryConfigurerProvider : * ``` * */ -public fun ComponentInstaller.useTelegramComponent(configurer: ConfigurerFunction? = null) { +public fun ComponentInstaller.useTelegramComponent( + configurer: ConfigurerFunction? = null +) { if (configurer == null) { install(TelegramComponent) } else { diff --git a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/event/TelegramMessageEvent.kt b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/event/TelegramMessageEvent.kt index e0c5e1b..9db4fa8 100644 --- a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/event/TelegramMessageEvent.kt +++ b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/event/TelegramMessageEvent.kt @@ -76,7 +76,8 @@ public interface TelegramChatGroupMessageEvent : TelegramMessageEvent, ChatGroup get() = sourceContent.from!!.id.ID @STP - override suspend fun author(): love.forte.simbot.component.telegram.core.actor.TelegramMember // TODO chat group member? + override suspend fun author(): love.forte.simbot.component.telegram.core.actor.TelegramMember + // TODO chat group member? @ST override suspend fun reply(text: String): TelegramMessageReceipt @@ -109,7 +110,8 @@ public interface TelegramChannelMessageEvent : TelegramMessageEvent, ChatGroupMe get() = sourceContent.from!!.id.ID @STP - override suspend fun author(): love.forte.simbot.component.telegram.core.actor.TelegramMember // TODO chat group member? + override suspend fun author(): love.forte.simbot.component.telegram.core.actor.TelegramMember + // TODO chat group member? @ST override suspend fun reply(text: String): TelegramMessageReceipt diff --git a/simbot-component-telegram-type/src/commonMain/kotlin/love/forte/simbot/telegram/type/InputMedia.kt b/simbot-component-telegram-type/src/commonMain/kotlin/love/forte/simbot/telegram/type/InputMedia.kt index 957b138..37a13f7 100644 --- a/simbot-component-telegram-type/src/commonMain/kotlin/love/forte/simbot/telegram/type/InputMedia.kt +++ b/simbot-component-telegram-type/src/commonMain/kotlin/love/forte/simbot/telegram/type/InputMedia.kt @@ -83,6 +83,7 @@ public data class InputMediaAnimation( * type: `InputFile or String` */ public val thumbnail: String? = null, // TODO InputFile or String + /** * Optional. * Caption of the animation to be sent, 0-1024 characters after entities parsing diff --git a/simbot-component-telegram-type/src/commonMain/kotlin/love/forte/simbot/telegram/type/game/Game.kt b/simbot-component-telegram-type/src/commonMain/kotlin/love/forte/simbot/telegram/type/game/Game.kt index 10e7380..8b2f1ce 100644 --- a/simbot-component-telegram-type/src/commonMain/kotlin/love/forte/simbot/telegram/type/game/Game.kt +++ b/simbot-component-telegram-type/src/commonMain/kotlin/love/forte/simbot/telegram/type/game/Game.kt @@ -33,7 +33,6 @@ public data class Game( * Title of the game */ val title: String, - /** * Description of the game */ @@ -47,14 +46,12 @@ public data class Game( * Brief description of the game or high scores included in the game message. Can be automatically edited to include current high scores for the game when the bot calls setGameScore, or manually edited using editMessageText. 0-4096 characters. */ val text: String? = null, - /** * Optional. * Special entities that appear in text, such as usernames, URLs, bot commands, etc. */ @SerialName("text_entities") val textEntities: List? = null, - /** * Optional. * Animation that will be displayed in the game message in chats. From aa24d2d41fa25bbbbc4fbfc8d8355bfe0ffda462 Mon Sep 17 00:00:00 2001 From: ForteScarlet Date: Wed, 10 Apr 2024 03:20:30 +0800 Subject: [PATCH 11/16] =?UTF-8?q?=E9=83=A8=E5=88=86=E5=86=85=E5=AE=B9?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AbstractTelegramChatGroupActor.kt | 35 ++++++++++++++----- .../core/actor/internal/TelegramMemberImpl.kt | 9 +++-- .../TelegramChannelMessageEventImpl.kt | 6 ++-- 3 files changed, 37 insertions(+), 13 deletions(-) diff --git a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/actor/internal/AbstractTelegramChatGroupActor.kt b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/actor/internal/AbstractTelegramChatGroupActor.kt index 18878be..fd6722f 100644 --- a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/actor/internal/AbstractTelegramChatGroupActor.kt +++ b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/actor/internal/AbstractTelegramChatGroupActor.kt @@ -18,14 +18,23 @@ package love.forte.simbot.component.telegram.core.actor.internal import love.forte.simbot.common.collectable.Collectable +import love.forte.simbot.common.collectable.emptyCollectable import love.forte.simbot.common.id.ID +import love.forte.simbot.common.id.toInt import love.forte.simbot.component.telegram.core.actor.TelegramChatGroupActor +import love.forte.simbot.component.telegram.core.actor.TelegramMember import love.forte.simbot.component.telegram.core.bot.internal.TelegramBotImpl +import love.forte.simbot.component.telegram.core.bot.requestDataBy import love.forte.simbot.component.telegram.core.message.TelegramMessageReceipt +import love.forte.simbot.component.telegram.core.message.internal.toTelegramMessageReceipt import love.forte.simbot.definition.Role import love.forte.simbot.message.Message import love.forte.simbot.message.MessageContent -import love.forte.simbot.telegram.type.Chat +import love.forte.simbot.telegram.api.chat.GetChatMemberApi +import love.forte.simbot.telegram.api.chat.GetChatMemberCountApi +import love.forte.simbot.telegram.api.message.SendMessageApi +import love.forte.simbot.telegram.stdlib.bot.requestDataBy +import love.forte.simbot.telegram.type.* /** @@ -37,22 +46,32 @@ internal abstract class AbstractTelegramChatGroupActor : TelegramChatGroupActor abstract override val source: Chat override val roles: Collectable - get() = TODO("Not yet implemented") + get() = emptyCollectable() // TODO("Not yet implemented") - override suspend fun botAsMember(): love.forte.simbot.component.telegram.core.actor.TelegramMember { - TODO("Not yet implemented") + override suspend fun botAsMember(): TelegramMember { + return bot.queryUserInfo().toTelegramMember(bot) } - override suspend fun member(id: ID): love.forte.simbot.component.telegram.core.actor.TelegramMember? { - TODO("Not yet implemented") + override suspend fun member(id: ID): TelegramMember? { + val chatMember = GetChatMemberApi.create(ChatId(source.id), id.toInt()) + .requestDataBy(bot) + + return when (chatMember) { + is ChatMemberAdministrator -> chatMember.user.toTelegramMember(bot, chatMember) + is ChatMemberBanned -> chatMember.user.toTelegramMember(bot, chatMember) + is ChatMemberLeft -> chatMember.user.toTelegramMember(bot, chatMember) + is ChatMemberOwner -> chatMember.user.toTelegramMember(bot, chatMember) + is ChatMemberRestricted -> chatMember.user.toTelegramMember(bot, chatMember) + } } override suspend fun memberCount(): Int { - TODO("Not yet implemented") + return GetChatMemberCountApi.create(ChatId(source.id)).requestDataBy(bot) } override suspend fun send(text: String): TelegramMessageReceipt { - TODO("Not yet implemented") + val sent = SendMessageApi.create(ChatId(source.id), text).requestDataBy(bot.source) + return sent.toTelegramMessageReceipt(bot) } override suspend fun send(message: Message): TelegramMessageReceipt { diff --git a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/actor/internal/TelegramMemberImpl.kt b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/actor/internal/TelegramMemberImpl.kt index 8711052..e34fb44 100644 --- a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/actor/internal/TelegramMemberImpl.kt +++ b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/actor/internal/TelegramMemberImpl.kt @@ -17,7 +17,9 @@ package love.forte.simbot.component.telegram.core.actor.internal +import love.forte.simbot.component.telegram.core.actor.TelegramMember import love.forte.simbot.component.telegram.core.bot.internal.TelegramBotImpl +import love.forte.simbot.telegram.type.ChatMember import love.forte.simbot.telegram.type.User import kotlin.coroutines.CoroutineContext @@ -29,7 +31,8 @@ import kotlin.coroutines.CoroutineContext internal class TelegramMemberImpl( private val bot: TelegramBotImpl, override val source: User, -) : love.forte.simbot.component.telegram.core.actor.TelegramMember { + private val chatMember: ChatMember? +) : TelegramMember { override val coroutineContext: CoroutineContext = bot.subContext override fun toString(): String { @@ -55,5 +58,5 @@ internal class TelegramMemberImpl( } -internal fun User.toTelegramMember(bot: TelegramBotImpl): TelegramMemberImpl = - TelegramMemberImpl(bot, this) +internal fun User.toTelegramMember(bot: TelegramBotImpl, chatMember: ChatMember? = null): TelegramMemberImpl = + TelegramMemberImpl(bot, this, chatMember) diff --git a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/event/internal/TelegramChannelMessageEventImpl.kt b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/event/internal/TelegramChannelMessageEventImpl.kt index 2bedbc4..47dc4b0 100644 --- a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/event/internal/TelegramChannelMessageEventImpl.kt +++ b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/event/internal/TelegramChannelMessageEventImpl.kt @@ -17,6 +17,8 @@ package love.forte.simbot.component.telegram.core.event.internal +import love.forte.simbot.component.telegram.core.actor.TelegramChannel +import love.forte.simbot.component.telegram.core.actor.TelegramMember import love.forte.simbot.component.telegram.core.actor.internal.toTelegramChannel import love.forte.simbot.component.telegram.core.actor.internal.toTelegramMember import love.forte.simbot.component.telegram.core.bot.internal.TelegramBotImpl @@ -48,11 +50,11 @@ internal class TelegramChannelMessageEventImpl( override val messageContent: TelegramMessageContent = TelegramMessageContentImpl(bot, sourceContent) - override suspend fun content(): love.forte.simbot.component.telegram.core.actor.TelegramChannel { + override suspend fun content(): TelegramChannel { return sourceContent.chat.toTelegramChannel(bot) } - override suspend fun author(): love.forte.simbot.component.telegram.core.actor.TelegramMember { + override suspend fun author(): TelegramMember { // TODO from!!? check senderChat? return sourceContent.from!!.toTelegramMember(bot) } From 4d84b8fe1f3c9a75a29d2de67167fc05e339ec62 Mon Sep 17 00:00:00 2001 From: ForteScarlet Date: Wed, 10 Apr 2024 03:55:27 +0800 Subject: [PATCH 12/16] resolver? --- .../core/message/TelegramMessageResolver.kt | 31 ++++++++++++++++--- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/message/TelegramMessageResolver.kt b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/message/TelegramMessageResolver.kt index ec7f396..f333a5b 100644 --- a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/message/TelegramMessageResolver.kt +++ b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/message/TelegramMessageResolver.kt @@ -19,10 +19,9 @@ package love.forte.simbot.component.telegram.core.message -import love.forte.simbot.telegram.api.message.CopyMessageApi -import love.forte.simbot.telegram.api.message.ForwardMessageApi -import love.forte.simbot.telegram.api.message.buildCopyMessageApi -import love.forte.simbot.telegram.api.message.buildForwardMessageApi +import love.forte.simbot.message.Message +import love.forte.simbot.telegram.api.TelegramApi +import love.forte.simbot.telegram.api.message.* import love.forte.simbot.telegram.type.ChatId import kotlin.jvm.JvmName import love.forte.simbot.telegram.type.Message as StdlibMessage @@ -46,3 +45,27 @@ internal inline fun StdlibMessage.toForwardApi( } } +internal inline fun Message.resolve() { + TODO("Message.resolve") +} + + +internal class MessageResolver { + private val apiStacks = mutableListOf>() // TelegramApi? + var builder: SendMessageApi.Builder = SendMessageApi.builder() + private set + + fun newBuilder(): SendMessageApi.Builder { + apiStacks.add(builder.build()) + return SendMessageApi.builder().also { builder = it } + } + + inline fun checkOrNewBuilder(block: (SendMessageApi.Builder) -> Boolean): SendMessageApi.Builder { + val currentBuilder = builder + return if (block(currentBuilder)) { + currentBuilder + } else { + newBuilder() + } + } +} From b6129e28ecfee37173a779db4f13e8b61f834eae Mon Sep 17 00:00:00 2001 From: ForteScarlet Date: Wed, 10 Apr 2024 16:45:49 +0800 Subject: [PATCH 13/16] =?UTF-8?q?detekt=20=E9=85=8D=E7=BD=AE=E5=92=8C?= =?UTF-8?q?=E9=83=A8=E5=88=86=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .editorconfig | 2 +- .github/workflows/test-branch.yml | 20 ++- build.gradle.kts | 25 ++- config/detekt/detekt.yml | 16 +- .../ComponentEventProcessorProvider.kt | 14 +- .../IncludeMessageElementsProcessor.kt | 3 +- ...libProcessorExtensionsProcessorProvider.kt | 15 +- .../UpdateEventProcessorProvider.kt | 161 +++++++++++------- 8 files changed, 163 insertions(+), 93 deletions(-) diff --git a/.editorconfig b/.editorconfig index cb26fe6..dcbb430 100644 --- a/.editorconfig +++ b/.editorconfig @@ -6,7 +6,7 @@ indent_style = space insert_final_newline = true max_line_length = 120 tab_width = 4 -ij_continuation_indent_size = 8 +ij_continuation_indent_size = 4 ij_formatter_off_tag = @formatter:off ij_formatter_on_tag = @formatter:on ij_formatter_tags_enabled = true diff --git a/.github/workflows/test-branch.yml b/.github/workflows/test-branch.yml index d545532..de364c2 100644 --- a/.github/workflows/test-branch.yml +++ b/.github/workflows/test-branch.yml @@ -13,7 +13,7 @@ on: - 'gradle/**' concurrency: - group: ${{ github.workflow }}-${{ github.ref }} + group: '${{ github.workflow }}-${{ github.ref }}' cancel-in-progress: true env: @@ -59,10 +59,7 @@ jobs: detekt-check: name: Detekt check - strategy: - matrix: - os: [ macos-latest, windows-latest, ubuntu-latest ] - runs-on: ${{ matrix.os }} + runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-java@v4 @@ -80,6 +77,15 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ always() }} with: - name: test-reports-${{ runner.os }} - path: '**/build/detekt/report' + name: detekt-reports + path: 'build/reports/detekt' retention-days: 7 + + # https://detekt.dev/docs/introduction/reporting/#integration-with-github-code-scanning + # Make sure we always run this upload task, + # because the previous step may fail if there are findings. + - name: Upload SARIF to GitHub using the upload-sarif action + uses: github/codeql-action/upload-sarif@v2 + if: ${{ always() }} + with: + sarif_file: 'build/reports/detekt/detekt.sarif' diff --git a/build.gradle.kts b/build.gradle.kts index 227bd3c..11ea6f7 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -73,27 +73,42 @@ dependencies { detekt { source.setFrom( - "simbot-component-telegram-api", - "simbot-component-telegram-core", - "simbot-component-telegram-stdlib", - "simbot-component-telegram-type", + subprojects + // internal 处理器不管 + // .filter { "internal-processors" !in it.path } + .map { it.projectDir.absoluteFile } ) config.setFrom(rootDir.resolve("config/detekt/detekt.yml")) baseline = file("$projectDir/config/detekt/baseline.xml") buildUponDefaultConfig = true parallel = true - reportsDir = rootProject.layout.buildDirectory.dir("detekt/report").get().asFile + reportsDir = rootProject.layout.buildDirectory.dir("reports/detekt").get().asFile if (!isCi) { autoCorrect = true } + basePath = projectDir.absolutePath } // https://detekt.dev/blog/2019/03/03/configure-detekt-on-root-project/ tasks.withType().configureEach { + include("**/src/*Main/kotlin/**/*.kt") + include("**/src/*Main/kotlin/**/*.java") + include("**/src/*Main/java/**/*.kt") + include("**/src/*Main/java/**/*.java") + include("**/src/main/kotlin/**/*.kt") + include("**/src/main/kotlin/**/*.java") + include("**/src/main/java/**/*.kt") + include("**/src/main/java/**/*.java") + + // internal 处理器不管 + exclude("**/internal-processors/") exclude("**/src/*/resources/") exclude("**/build/") exclude("**/*Test/kotlin/") exclude("**/*Test/java/") + exclude("**/test/kotlin/") + exclude("**/test/java/") + exclude("**.kts") } diff --git a/config/detekt/detekt.yml b/config/detekt/detekt.yml index f0091b7..423cf62 100644 --- a/config/detekt/detekt.yml +++ b/config/detekt/detekt.yml @@ -1,12 +1,12 @@ build: maxIssues: 10000 # 先不限制最大问题 excludeCorrectable: false - weights: - formatting: 10000 # 代码格式的问题,一般都有 autoCorrect, 需要尽可能不出错 - comments: 0 - complexity: 0 - LongParameterList: 0 - style: 0 +# weights: +# formatting: 0 # 代码格式的问题 +# comments: 0 +# complexity: 0 +# LongParameterList: 0 +# style: 0 config: validation: true @@ -44,12 +44,12 @@ console-reports: output-reports: active: true - exclude: +# exclude: # - 'TxtOutputReport' # - 'XmlOutputReport' # - 'HtmlOutputReport' # - 'MdOutputReport' - - 'SarifOutputReport' +# - 'SarifOutputReport' comments: active: true diff --git a/internal-processors/component-events-processor/src/main/kotlin/telegram/internal/processors/componentevents/ComponentEventProcessorProvider.kt b/internal-processors/component-events-processor/src/main/kotlin/telegram/internal/processors/componentevents/ComponentEventProcessorProvider.kt index 25c9924..0920c45 100644 --- a/internal-processors/component-events-processor/src/main/kotlin/telegram/internal/processors/componentevents/ComponentEventProcessorProvider.kt +++ b/internal-processors/component-events-processor/src/main/kotlin/telegram/internal/processors/componentevents/ComponentEventProcessorProvider.kt @@ -85,7 +85,7 @@ private class ComponentEventProcessor(private val environment: SymbolProcessorEn **************************** 此文件内容是 **自动生成** 的 **************************** - """.trimIndent() + """.trimIndent() ) indent(" ") }.build() @@ -124,7 +124,11 @@ private class ComponentEventProcessor(private val environment: SymbolProcessorEn * ``` */ private fun generateEvents(optionalPropertiesWithNames: List>): List { - data class TypeBasedEventData(val property: KSPropertyDeclaration, val typeName: TypeName, val typeBuilder: TypeSpec.Builder) + data class TypeBasedEventData( + val property: KSPropertyDeclaration, + val typeName: TypeName, + val typeBuilder: TypeSpec.Builder + ) // val eventTypesWithTypeKey = mutableMapOf<>() val typeBasedEventTypes = optionalPropertiesWithNames.asSequence() .map { (property, _) -> @@ -140,7 +144,8 @@ private class ComponentEventProcessor(private val environment: SymbolProcessorEn PropertySpec.builder( name = TELEGRAM_EVENT_PROPERTY_SOURCE_CONTENT_NAME, type = typeName, - KModifier.OVERRIDE, KModifier.PUBLIC + KModifier.OVERRIDE, + KModifier.PUBLIC ) .addKdoc( "Source content with type [%T]\n\n", @@ -180,7 +185,8 @@ private class ComponentEventProcessor(private val environment: SymbolProcessorEn PropertySpec.builder( name = TELEGRAM_EVENT_PROPERTY_SOURCE_CONTENT_NAME, type = propertyTypeName, - KModifier.OVERRIDE, KModifier.PUBLIC + KModifier.OVERRIDE, + KModifier.PUBLIC ) .addKdoc( "Source content from [%M] with type [%T]\n\n", diff --git a/internal-processors/include-component-message-elements-processor/src/main/kotlin/telegram/internal/processors/includemessageelements/IncludeMessageElementsProcessor.kt b/internal-processors/include-component-message-elements-processor/src/main/kotlin/telegram/internal/processors/includemessageelements/IncludeMessageElementsProcessor.kt index e6fc8b9..595b520 100644 --- a/internal-processors/include-component-message-elements-processor/src/main/kotlin/telegram/internal/processors/includemessageelements/IncludeMessageElementsProcessor.kt +++ b/internal-processors/include-component-message-elements-processor/src/main/kotlin/telegram/internal/processors/includemessageelements/IncludeMessageElementsProcessor.kt @@ -97,7 +97,7 @@ private class IncludeMessageElementsProcessor(val environment: SymbolProcessorEn **************************** 此文件内容是 **自动生成** 的 **************************** - """.trimIndent() + """.trimIndent() ) addFunction(function) @@ -130,7 +130,6 @@ private class IncludeMessageElementsProcessor(val environment: SymbolProcessorEn *``` */ private fun generateIncludeFunction(impls: List): FunSpec { - // kotlinx.serialization.modules.subclass val memberName = MemberName("kotlinx.serialization.modules", "subclass") diff --git a/internal-processors/stdlib-processor-extensions-processor/src/main/kotlin/telegram/internal/processors/stdlibprocessor/StdlibProcessorExtensionsProcessorProvider.kt b/internal-processors/stdlib-processor-extensions-processor/src/main/kotlin/telegram/internal/processors/stdlibprocessor/StdlibProcessorExtensionsProcessorProvider.kt index 08e9702..30bbd15 100644 --- a/internal-processors/stdlib-processor-extensions-processor/src/main/kotlin/telegram/internal/processors/stdlibprocessor/StdlibProcessorExtensionsProcessorProvider.kt +++ b/internal-processors/stdlib-processor-extensions-processor/src/main/kotlin/telegram/internal/processors/stdlibprocessor/StdlibProcessorExtensionsProcessorProvider.kt @@ -102,7 +102,7 @@ private class UpdateEventProcessor(private val environment: SymbolProcessorEnvir **************************** 此文件内容是 **自动生成** 的 **************************** - """.trimIndent() + """.trimIndent() ) }.build() @@ -184,8 +184,11 @@ private class UpdateEventProcessor(private val environment: SymbolProcessorEnvir // subscribe(NAME, sequence, processor) .addStatement( "%M<%T>(%M, %L, %L)", - BotSubscribeExtensionMember, eventType, - nameMember, SEQUENCE_PARAM_NAME, PROCESSOR_PARAM_NAME + BotSubscribeExtensionMember, + eventType, + nameMember, + SEQUENCE_PARAM_NAME, + PROCESSOR_PARAM_NAME ) .build() ) @@ -203,8 +206,10 @@ private class UpdateEventProcessor(private val environment: SymbolProcessorEnvir @see %M @see %M - """.trimIndent(), - eventType, nameMember, propertyName, + """.trimIndent(), + eventType, + nameMember, + propertyName, BotSubscribeExtensionMember, MemberName(UpdateClassName, propertyName) ) diff --git a/internal-processors/update-events-processor/src/main/kotlin/telegram/internal/processors/updateevents/UpdateEventProcessorProvider.kt b/internal-processors/update-events-processor/src/main/kotlin/telegram/internal/processors/updateevents/UpdateEventProcessorProvider.kt index e474dab..ff00d86 100644 --- a/internal-processors/update-events-processor/src/main/kotlin/telegram/internal/processors/updateevents/UpdateEventProcessorProvider.kt +++ b/internal-processors/update-events-processor/src/main/kotlin/telegram/internal/processors/updateevents/UpdateEventProcessorProvider.kt @@ -152,7 +152,7 @@ private class UpdateEventProcessor(private val environment: SymbolProcessorEnvir **************************** 此文件内容是 **自动生成** 的 **************************** - """.trimIndent() + """.trimIndent() ) .addType(updateValuesObject) .addType(dividerClass) @@ -232,8 +232,9 @@ private class UpdateEventProcessor(private val environment: SymbolProcessorEnvir addKdoc( "Find the first optional property that is not null based on [%T], " + - "and use [block] to process the serialized name and value of this property." + - "\n\n", UpdateClassName + "and use [block] to process the serialized name and value of this property." + + "\n\n", + UpdateClassName ) addKdoc( "@throws %T If no optional properties that are not null are found in [%T]", @@ -257,7 +258,8 @@ private class UpdateEventProcessor(private val environment: SymbolProcessorEnvir addProperty( PropertySpec.builder( - constantName(name), STRING, + constantName(name), + STRING, KModifier.CONST ) .addKdoc("The serialized name constant of [%M]\n\n", member) @@ -287,7 +289,9 @@ private class UpdateEventProcessor(private val environment: SymbolProcessorEnvir All optional parameters' name in [%T] @see %T - """.trimIndent(), typeName, typeName + """.trimIndent(), + typeName, + typeName ) .jvmField() .build() @@ -308,25 +312,27 @@ private class UpdateEventProcessor(private val environment: SymbolProcessorEnvir addParameter(nameParam) returns(KClass::class.asTypeName().parameterizedBy(STAR)) - addCode(CodeBlock.builder().apply { - beginControlFlow("return when(${nameParam.name})") + addCode( + CodeBlock.builder().apply { + beginControlFlow("return when(${nameParam.name})") - for ((parameter, name) in optionalPropertiesWithNames) { - addStatement( - "%N -> %T::class", - constantName(name), - parameter.type.toTypeName().copy(nullable = false) - ) + for ((parameter, name) in optionalPropertiesWithNames) { + addStatement( + "%N -> %T::class", + constantName(name), + parameter.type.toTypeName().copy(nullable = false) + ) - } + } - addStatement( - "else -> throw %T(%P)", - IllegalArgumentExceptionClassName, - "Unknown name: \$${nameParam.name}" - ) - endControlFlow() - }.build()) + addStatement( + "else -> throw %T(%P)", + IllegalArgumentExceptionClassName, + "Unknown name: \$${nameParam.name}" + ) + endControlFlow() + }.build() + ) }.build() addFunction(getUpdateTypeFun) @@ -366,7 +372,7 @@ private class UpdateEventProcessor(private val environment: SymbolProcessorEnvir name: ClassName, suspend: Boolean, optionalPropertiesWithNames: List>, - ): TypeSpec { + ): TypeSpec { val tv = TypeVariableName("C") return TypeSpec.classBuilder(name).apply { addTypeVariable(tv) @@ -376,7 +382,14 @@ private class UpdateEventProcessor(private val environment: SymbolProcessorEnvir // visitFunctions for ((property, _) in optionalPropertiesWithNames) { - addFunction(updateDividerEventFun(suspend, tv, property.simpleName.asString(), property.type.resolve().toTypeName())) + addFunction( + updateDividerEventFun( + suspend, + tv, + property.simpleName.asString(), + property.type.resolve().toTypeName() + ) + ) } addFunction(updateDividerAcceptByUpdateFun(suspend, tv, optionalPropertiesWithNames)) @@ -412,12 +425,19 @@ private class UpdateEventProcessor(private val environment: SymbolProcessorEnvir addParameter(DIVIDER_CONTEXT_PARAM_NAME, tv) addCode( "onMismatchUpdateEvent(%L, %L, %L, %L)", - DIVIDER_NAME_PARAM_NAME, DIVIDER_VALUE_PARAM_NAME, DIVIDER_UPDATE_PARAM_NAME, DIVIDER_CONTEXT_PARAM_NAME + DIVIDER_NAME_PARAM_NAME, + DIVIDER_VALUE_PARAM_NAME, + DIVIDER_UPDATE_PARAM_NAME, + DIVIDER_CONTEXT_PARAM_NAME ) }.build() } - private fun updateDividerAcceptByUpdateFun(suspend: Boolean, tv: TypeVariableName, optionalPropertiesWithNames: List>): FunSpec { + private fun updateDividerAcceptByUpdateFun( + suspend: Boolean, + tv: TypeVariableName, + optionalPropertiesWithNames: List> + ): FunSpec { return FunSpec.builder("accept").apply { addModifiers(KModifier.PUBLIC, KModifier.FINAL) if (suspend) { @@ -426,28 +446,36 @@ private class UpdateEventProcessor(private val environment: SymbolProcessorEnvir addParameter(DIVIDER_UPDATE_PARAM_NAME, UpdateClassName) addParameter(DIVIDER_CONTEXT_PARAM_NAME, tv) - addCode(buildCodeBlock { - beginControlFlow("when") - - for ((property, name) in optionalPropertiesWithNames) { - val pname = property.simpleName.asString() - // update.xxx != null -> onXxx - add("%L.%L != null -> ", DIVIDER_UPDATE_PARAM_NAME, pname) - addStatement("%L(%M, %L.%L, %L, %L)", - pname.toOnFunName(), - MemberName(ClassName(UPDATE_PACKAGE, UPDATE_VALUES_CLASS_NAME), constantName(name)), - DIVIDER_UPDATE_PARAM_NAME, pname, - DIVIDER_UPDATE_PARAM_NAME, - DIVIDER_CONTEXT_PARAM_NAME - ) - } + addCode( + buildCodeBlock { + beginControlFlow("when") + + for ((property, name) in optionalPropertiesWithNames) { + val pname = property.simpleName.asString() + // update.xxx != null -> onXxx + add("%L.%L != null -> ", DIVIDER_UPDATE_PARAM_NAME, pname) + addStatement( + "%L(%M, %L.%L, %L, %L)", + pname.toOnFunName(), + MemberName(ClassName(UPDATE_PACKAGE, UPDATE_VALUES_CLASS_NAME), constantName(name)), + DIVIDER_UPDATE_PARAM_NAME, + pname, + DIVIDER_UPDATE_PARAM_NAME, + DIVIDER_CONTEXT_PARAM_NAME + ) + } - endControlFlow() - }) + endControlFlow() + } + ) }.build() } - private fun updateDividerAcceptByNameValueFun(suspend: Boolean, tv: TypeVariableName, optionalPropertiesWithNames: List>): FunSpec { + private fun updateDividerAcceptByNameValueFun( + suspend: Boolean, + tv: TypeVariableName, + optionalPropertiesWithNames: List> + ): FunSpec { return FunSpec.builder("accept").apply { addModifiers(KModifier.PUBLIC, KModifier.FINAL) if (suspend) { @@ -457,25 +485,36 @@ private class UpdateEventProcessor(private val environment: SymbolProcessorEnvir addParameter(DIVIDER_VALUE_PARAM_NAME, ANY) addParameter(DIVIDER_UPDATE_PARAM_NAME, UpdateClassName.copy(nullable = true)) addParameter(DIVIDER_CONTEXT_PARAM_NAME, tv) - addCode(buildCodeBlock { - beginControlFlow("when") - - for ((property, name) in optionalPropertiesWithNames) { - val pname = property.simpleName.asString() - // name == constant && value is xxx -> onXxx - add("%L == %M ", DIVIDER_NAME_PARAM_NAME, MemberName(ClassName(UPDATE_PACKAGE, UPDATE_VALUES_CLASS_NAME), constantName(name))) - add("&& %L is %T -> ", DIVIDER_VALUE_PARAM_NAME, property.type.toTypeName().copy(nullable = false)) - addStatement("%L(%L, %L, %L, %L)", - pname.toOnFunName(), - DIVIDER_NAME_PARAM_NAME, - DIVIDER_VALUE_PARAM_NAME, - DIVIDER_UPDATE_PARAM_NAME, - DIVIDER_CONTEXT_PARAM_NAME - ) - } + addCode( + buildCodeBlock { + beginControlFlow("when") + + for ((property, name) in optionalPropertiesWithNames) { + val pname = property.simpleName.asString() + // name == constant && value is xxx -> onXxx + add( + "%L == %M ", + DIVIDER_NAME_PARAM_NAME, + MemberName(ClassName(UPDATE_PACKAGE, UPDATE_VALUES_CLASS_NAME), constantName(name)) + ) + add( + "&& %L is %T -> ", + DIVIDER_VALUE_PARAM_NAME, + property.type.toTypeName().copy(nullable = false) + ) + addStatement( + "%L(%L, %L, %L, %L)", + pname.toOnFunName(), + DIVIDER_NAME_PARAM_NAME, + DIVIDER_VALUE_PARAM_NAME, + DIVIDER_UPDATE_PARAM_NAME, + DIVIDER_CONTEXT_PARAM_NAME + ) + } - endControlFlow() - }) + endControlFlow() + } + ) }.build() } From 5ba68b4cf828486663fd00a68484c0664d7136f9 Mon Sep 17 00:00:00 2001 From: ForteScarlet Date: Wed, 10 Apr 2024 22:20:55 +0800 Subject: [PATCH 14/16] =?UTF-8?q?=E6=B6=88=E6=81=AF=E4=BA=8B=E4=BB=B6?= =?UTF-8?q?=E7=9B=B8=E5=85=B3=E7=9A=84=E5=AE=9E=E7=8E=B0=E5=92=8C=E8=B0=83?= =?UTF-8?q?=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../telegram/api/message/SendMessageApi.kt | 11 +- .../core/actor/TelegramChatGroupActor.kt | 5 +- .../telegram/core/actor/TelegramMember.kt | 5 +- .../AbstractTelegramChatGroupActor.kt | 14 +- .../actor/internal/TelegramUserContactImpl.kt | 12 +- .../telegram/core/bot/TelegramBot.kt | 6 +- .../core/bot/internal/TelegramBotImpl.kt | 11 +- .../core/event/TelegramMessageEvent.kt | 39 +++- .../TelegramChannelMessageEventImpl.kt | 36 +-- .../TelegramChatGroupMessageEventImpl.kt | 26 ++- .../TelegramPrivateMessageEventImpl.kt | 27 ++- .../TelegramSuperGroupMessageEventImpl.kt | 92 ++++++++ .../core/message/TelegramMessageReceipt.kt | 2 + .../core/message/TelegramMessageResolver.kt | 220 ++++++++++++++++-- .../TelegramMessageResultApiElement.kt | 87 +++++++ .../internal/ReceivingMessageResolvers.kt | 62 +++++ .../SendingMessageStandardResolvers.kt} | 38 ++- .../internal/TelegramMessageContentImpl.kt | 8 +- .../TelegramSingleMessageSourceReceiptImpl.kt | 25 +- 19 files changed, 623 insertions(+), 103 deletions(-) create mode 100644 simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/event/internal/TelegramSuperGroupMessageEventImpl.kt create mode 100644 simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/message/TelegramMessageResultApiElement.kt create mode 100644 simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/message/internal/ReceivingMessageResolvers.kt rename simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/message/{TelegramMessageApiBodyElement.kt => internal/SendingMessageStandardResolvers.kt} (50%) diff --git a/simbot-component-telegram-api/src/commonMain/kotlin/love/forte/simbot/telegram/api/message/SendMessageApi.kt b/simbot-component-telegram-api/src/commonMain/kotlin/love/forte/simbot/telegram/api/message/SendMessageApi.kt index 5300157..5eb0a3d 100644 --- a/simbot-component-telegram-api/src/commonMain/kotlin/love/forte/simbot/telegram/api/message/SendMessageApi.kt +++ b/simbot-component-telegram-api/src/commonMain/kotlin/love/forte/simbot/telegram/api/message/SendMessageApi.kt @@ -173,7 +173,12 @@ public class SendMessageApi private constructor(body: Body) : SimpleBodyTelegram /** * @see Body.text */ - public var text: String? = null + public var text: StringBuilder? = null + + public fun text(append: CharSequence) { + val apd = text ?: StringBuilder().also { text = it } + apd.append(append) + } // Optional @@ -264,7 +269,7 @@ public class SendMessageApi private constructor(body: Body) : SimpleBodyTelegram return Body( chatId = chatId, - text = text, + text = text.toString(), messageThreadId = messageThreadId, parseMode = parseMode, entities = entities, @@ -301,6 +306,6 @@ public inline fun buildSendMessageApi( block: Builder.() -> Unit = {} ): SendMessageApi = buildSendMessageApi { this.chatId = chatId - this.text = text + this.text = StringBuilder(text) block() } diff --git a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/actor/TelegramChatGroupActor.kt b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/actor/TelegramChatGroupActor.kt index ab5d24e..90b1314 100644 --- a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/actor/TelegramChatGroupActor.kt +++ b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/actor/TelegramChatGroupActor.kt @@ -48,7 +48,7 @@ public interface TelegramChatAware { } /** - * A Telegram [Chat] representing a group ([Chat.type] == [ChatType.GROUP].value) + * A Telegram [Chat] representing a group ([Chat.type] == [ChatType.GROUP] or [ChatType.SUPERGROUP]) * or a channel ([Chat.type] == [ChatType.CHANNEL].value). * * @see TelegramChatGroup @@ -114,8 +114,7 @@ public interface TelegramChatGroupActor : TelegramChatAware, ChatGroup { /** - * - * A Telegram [Chat] representing a group ([Chat.type] == [ChatType.GROUP].value). + * A Telegram [Chat] representing a group ([Chat.type] == [ChatType.GROUP] or [ChatType.SUPERGROUP]). * * @author ForteScarlet */ diff --git a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/actor/TelegramMember.kt b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/actor/TelegramMember.kt index 0e29455..d34d7c6 100644 --- a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/actor/TelegramMember.kt +++ b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/actor/TelegramMember.kt @@ -86,8 +86,9 @@ public interface TelegramMember : TelegramUser, Member { sendToMemberIsUnsupported() } -internal const val SEND_TO_MEMBER_IS_UNSUPPORTED = "Telegram bot cannot proactively send a message to a member " + - "because the private chat id is unknown." +internal const val SEND_TO_MEMBER_IS_UNSUPPORTED = + "Telegram bot cannot proactively send a message to a member " + + "because the private chat id is unknown." internal fun sendToMemberIsUnsupported(): Nothing = throw UnsupportedOperationException(SEND_TO_MEMBER_IS_UNSUPPORTED) diff --git a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/actor/internal/AbstractTelegramChatGroupActor.kt b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/actor/internal/AbstractTelegramChatGroupActor.kt index fd6722f..74c4b34 100644 --- a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/actor/internal/AbstractTelegramChatGroupActor.kt +++ b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/actor/internal/AbstractTelegramChatGroupActor.kt @@ -18,7 +18,6 @@ package love.forte.simbot.component.telegram.core.actor.internal import love.forte.simbot.common.collectable.Collectable -import love.forte.simbot.common.collectable.emptyCollectable import love.forte.simbot.common.id.ID import love.forte.simbot.common.id.toInt import love.forte.simbot.component.telegram.core.actor.TelegramChatGroupActor @@ -26,14 +25,12 @@ import love.forte.simbot.component.telegram.core.actor.TelegramMember import love.forte.simbot.component.telegram.core.bot.internal.TelegramBotImpl import love.forte.simbot.component.telegram.core.bot.requestDataBy import love.forte.simbot.component.telegram.core.message.TelegramMessageReceipt -import love.forte.simbot.component.telegram.core.message.internal.toTelegramMessageReceipt +import love.forte.simbot.component.telegram.core.message.send import love.forte.simbot.definition.Role import love.forte.simbot.message.Message import love.forte.simbot.message.MessageContent import love.forte.simbot.telegram.api.chat.GetChatMemberApi import love.forte.simbot.telegram.api.chat.GetChatMemberCountApi -import love.forte.simbot.telegram.api.message.SendMessageApi -import love.forte.simbot.telegram.stdlib.bot.requestDataBy import love.forte.simbot.telegram.type.* @@ -46,7 +43,7 @@ internal abstract class AbstractTelegramChatGroupActor : TelegramChatGroupActor abstract override val source: Chat override val roles: Collectable - get() = emptyCollectable() // TODO("Not yet implemented") + get() = TODO("Not yet implemented") override suspend fun botAsMember(): TelegramMember { return bot.queryUserInfo().toTelegramMember(bot) @@ -70,15 +67,14 @@ internal abstract class AbstractTelegramChatGroupActor : TelegramChatGroupActor } override suspend fun send(text: String): TelegramMessageReceipt { - val sent = SendMessageApi.create(ChatId(source.id), text).requestDataBy(bot.source) - return sent.toTelegramMessageReceipt(bot) + return bot.send(text, source.id) } override suspend fun send(message: Message): TelegramMessageReceipt { - TODO("Not yet implemented") + return bot.send(message, source.id) } override suspend fun send(messageContent: MessageContent): TelegramMessageReceipt { - TODO("Not yet implemented") + return bot.send(messageContent, source.id) } } diff --git a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/actor/internal/TelegramUserContactImpl.kt b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/actor/internal/TelegramUserContactImpl.kt index dda6935..4ce44c8 100644 --- a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/actor/internal/TelegramUserContactImpl.kt +++ b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/actor/internal/TelegramUserContactImpl.kt @@ -19,13 +19,10 @@ package love.forte.simbot.component.telegram.core.actor.internal import love.forte.simbot.component.telegram.core.bot.internal.TelegramBotImpl import love.forte.simbot.component.telegram.core.message.TelegramMessageReceipt -import love.forte.simbot.component.telegram.core.message.internal.toTelegramMessageReceipt +import love.forte.simbot.component.telegram.core.message.send import love.forte.simbot.message.Message import love.forte.simbot.message.MessageContent -import love.forte.simbot.telegram.api.message.SendMessageApi -import love.forte.simbot.telegram.stdlib.bot.requestDataBy import love.forte.simbot.telegram.type.Chat -import love.forte.simbot.telegram.type.ChatId import love.forte.simbot.telegram.type.User import kotlin.coroutines.CoroutineContext @@ -42,16 +39,15 @@ internal class TelegramUserContactImpl( override val coroutineContext: CoroutineContext = bot.subContext override suspend fun send(messageContent: MessageContent): TelegramMessageReceipt { - TODO("Not yet implemented") + return bot.send(messageContent, sourceChat.id) } override suspend fun send(message: Message): TelegramMessageReceipt { - TODO("Not yet implemented") + return bot.send(message, sourceChat.id) } override suspend fun send(text: String): TelegramMessageReceipt { - val sent = SendMessageApi.create(ChatId(sourceChat.id), text).requestDataBy(bot.source) - return sent.toTelegramMessageReceipt(bot) + return bot.send(text, sourceChat.id) } override fun toString(): String = diff --git a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/bot/TelegramBot.kt b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/bot/TelegramBot.kt index 5cbe715..6468200 100644 --- a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/bot/TelegramBot.kt +++ b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/bot/TelegramBot.kt @@ -93,12 +93,12 @@ public interface TelegramBot : Bot { override val groupRelation: GroupRelation? - get() = null // TODO + get() = null // TODO? override val guildRelation: GuildRelation? - get() = null // TODO + get() = null // TODO? override val contactRelation: ContactRelation? - get() = null // TODO + get() = null // TODO? } diff --git a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/bot/internal/TelegramBotImpl.kt b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/bot/internal/TelegramBotImpl.kt index d8735ec..80f44a2 100644 --- a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/bot/internal/TelegramBotImpl.kt +++ b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/bot/internal/TelegramBotImpl.kt @@ -35,6 +35,7 @@ import love.forte.simbot.component.telegram.core.event.TelegramUnsupportedEvent import love.forte.simbot.component.telegram.core.event.internal.TelegramChannelMessageEventImpl import love.forte.simbot.component.telegram.core.event.internal.TelegramChatGroupMessageEventImpl import love.forte.simbot.component.telegram.core.event.internal.TelegramPrivateMessageEventImpl +import love.forte.simbot.component.telegram.core.event.internal.TelegramSuperGroupMessageEventImpl import love.forte.simbot.event.Event import love.forte.simbot.event.EventDispatcher import love.forte.simbot.event.onEachError @@ -170,8 +171,16 @@ internal fun subscribeInternalProcessor( } // supergroup? + ChatType.SUPERGROUP -> { + pushEvent( + TelegramSuperGroupMessageEventImpl( + bot = bot, + sourceEvent = context, + sourceContent = value + ) + ) + } - // TODO others else -> onMismatchUpdateEvent(name, value, update, context) } } diff --git a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/event/TelegramMessageEvent.kt b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/event/TelegramMessageEvent.kt index 9db4fa8..963cd8d 100644 --- a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/event/TelegramMessageEvent.kt +++ b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/event/TelegramMessageEvent.kt @@ -23,6 +23,7 @@ import love.forte.simbot.common.time.Timestamp import love.forte.simbot.component.telegram.core.actor.TelegramChannel import love.forte.simbot.component.telegram.core.actor.TelegramChatGroup import love.forte.simbot.component.telegram.core.actor.TelegramContact +import love.forte.simbot.component.telegram.core.actor.TelegramMember import love.forte.simbot.component.telegram.core.message.TelegramMessageContent import love.forte.simbot.component.telegram.core.message.TelegramMessageReceipt import love.forte.simbot.component.telegram.core.time.unixDateTimestamp @@ -76,7 +77,7 @@ public interface TelegramChatGroupMessageEvent : TelegramMessageEvent, ChatGroup get() = sourceContent.from!!.id.ID @STP - override suspend fun author(): love.forte.simbot.component.telegram.core.actor.TelegramMember + override suspend fun author(): TelegramMember // TODO chat group member? @ST @@ -89,6 +90,39 @@ public interface TelegramChatGroupMessageEvent : TelegramMessageEvent, ChatGroup override suspend fun reply(messageContent: MessageContent): TelegramMessageReceipt } +/** + * An event about [Message] from a [TelegramChatGroup] (chat.type == `"supergroup"`) + * + * @author ForteScarlet + */ +public interface TelegramSuperGroupMessageEvent : TelegramMessageEvent, ChatGroupMessageEvent { + override val messageContent: TelegramMessageContent + + /** + * The [TelegramChatGroup]. + */ + @STP + override suspend fun content(): TelegramChatGroup + + /** + * The [sender][Message.from]'s [id][User.id] + */ + override val authorId: ID + get() = sourceContent.from!!.id.ID + + @STP + override suspend fun author(): TelegramMember + + @ST + override suspend fun reply(text: String): TelegramMessageReceipt + + @ST + override suspend fun reply(message: love.forte.simbot.message.Message): TelegramMessageReceipt + + @ST + override suspend fun reply(messageContent: MessageContent): TelegramMessageReceipt +} + /** * An event about [Message] from a [TelegramChannel] (chat.type == `"channel"`) * @@ -110,8 +144,7 @@ public interface TelegramChannelMessageEvent : TelegramMessageEvent, ChatGroupMe get() = sourceContent.from!!.id.ID @STP - override suspend fun author(): love.forte.simbot.component.telegram.core.actor.TelegramMember - // TODO chat group member? + override suspend fun author(): TelegramMember @ST override suspend fun reply(text: String): TelegramMessageReceipt diff --git a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/event/internal/TelegramChannelMessageEventImpl.kt b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/event/internal/TelegramChannelMessageEventImpl.kt index 47dc4b0..c390151 100644 --- a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/event/internal/TelegramChannelMessageEventImpl.kt +++ b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/event/internal/TelegramChannelMessageEventImpl.kt @@ -22,17 +22,14 @@ import love.forte.simbot.component.telegram.core.actor.TelegramMember import love.forte.simbot.component.telegram.core.actor.internal.toTelegramChannel import love.forte.simbot.component.telegram.core.actor.internal.toTelegramMember import love.forte.simbot.component.telegram.core.bot.internal.TelegramBotImpl -import love.forte.simbot.component.telegram.core.bot.requestDataBy import love.forte.simbot.component.telegram.core.event.StdlibEvent import love.forte.simbot.component.telegram.core.event.TelegramChannelMessageEvent import love.forte.simbot.component.telegram.core.message.TelegramMessageContent import love.forte.simbot.component.telegram.core.message.TelegramMessageReceipt import love.forte.simbot.component.telegram.core.message.internal.TelegramMessageContentImpl -import love.forte.simbot.component.telegram.core.message.internal.toTelegramMessageReceipt -import love.forte.simbot.component.telegram.core.message.toCopyApi +import love.forte.simbot.component.telegram.core.message.send import love.forte.simbot.message.MessageContent -import love.forte.simbot.telegram.api.message.buildSendMessageApi -import love.forte.simbot.telegram.type.ChatId +import love.forte.simbot.telegram.api.message.SendMessageApi import love.forte.simbot.telegram.type.Message import love.forte.simbot.telegram.type.ReplyParameters @@ -55,28 +52,37 @@ internal class TelegramChannelMessageEventImpl( } override suspend fun author(): TelegramMember { - // TODO from!!? check senderChat? + // TODO check senderChat? return sourceContent.from!!.toTelegramMember(bot) } override suspend fun reply(text: String): TelegramMessageReceipt { - return buildSendMessageApi(ChatId(sourceContent.chat.id), text) { + return bot.send(text, sourceContent.chat.id) { replyParameters = ReplyParameters(sourceContent.messageId) - }.requestDataBy(bot).toTelegramMessageReceipt(bot) + } } override suspend fun reply(message: love.forte.simbot.message.Message): TelegramMessageReceipt { - TODO("reply(Message) Not yet implemented") + return bot.send(message, sourceContent.chat.id) { + SendMessageApi.builder().also { + it.replyParameters = ReplyParameters(messageId = sourceContent.messageId) + } + } } override suspend fun reply(messageContent: MessageContent): TelegramMessageReceipt { - if (messageContent is TelegramMessageContent) { - return messageContent.source.toCopyApi(ChatId(sourceContent.chat.id)) { + return bot.send( + messageContent, + sourceContent.chat.id, + copyApiBlock = { replyParameters = ReplyParameters(messageId = sourceContent.messageId) - }.requestDataBy(bot).toTelegramMessageReceipt(bot, sourceContent.chat.id) - } - - return reply(messageContent.messages) + }, + builderFactory = { + SendMessageApi.builder().also { + it.replyParameters = ReplyParameters(messageId = sourceContent.messageId) + } + } + ) } override fun toString(): String { diff --git a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/event/internal/TelegramChatGroupMessageEventImpl.kt b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/event/internal/TelegramChatGroupMessageEventImpl.kt index 81ed413..5c1629a 100644 --- a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/event/internal/TelegramChatGroupMessageEventImpl.kt +++ b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/event/internal/TelegramChatGroupMessageEventImpl.kt @@ -27,8 +27,9 @@ import love.forte.simbot.component.telegram.core.message.TelegramMessageContent import love.forte.simbot.component.telegram.core.message.TelegramMessageReceipt import love.forte.simbot.component.telegram.core.message.internal.TelegramMessageContentImpl import love.forte.simbot.component.telegram.core.message.internal.toTelegramMessageReceipt -import love.forte.simbot.component.telegram.core.message.toCopyApi +import love.forte.simbot.component.telegram.core.message.send import love.forte.simbot.message.MessageContent +import love.forte.simbot.telegram.api.message.SendMessageApi import love.forte.simbot.telegram.api.message.buildSendMessageApi import love.forte.simbot.telegram.type.ChatId import love.forte.simbot.telegram.type.Message @@ -63,17 +64,26 @@ internal class TelegramChatGroupMessageEventImpl( } override suspend fun reply(message: love.forte.simbot.message.Message): TelegramMessageReceipt { - TODO("reply(Message) Not yet implemented") + return bot.send(message, sourceContent.chat.id) { + SendMessageApi.builder().also { + it.replyParameters = ReplyParameters(messageId = sourceContent.messageId) + } + } } override suspend fun reply(messageContent: MessageContent): TelegramMessageReceipt { - if (messageContent is TelegramMessageContent) { - return messageContent.source.toCopyApi(ChatId(sourceContent.chat.id)) { + return bot.send( + messageContent, + sourceContent.chat.id, + copyApiBlock = { replyParameters = ReplyParameters(messageId = sourceContent.messageId) - }.requestDataBy(bot).toTelegramMessageReceipt(bot, sourceContent.chat.id) - } - - return reply(messageContent.messages) + }, + builderFactory = { + SendMessageApi.builder().also { + it.replyParameters = ReplyParameters(messageId = sourceContent.messageId) + } + } + ) } override fun toString(): String { diff --git a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/event/internal/TelegramPrivateMessageEventImpl.kt b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/event/internal/TelegramPrivateMessageEventImpl.kt index 5690d2b..4bd51bf 100644 --- a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/event/internal/TelegramPrivateMessageEventImpl.kt +++ b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/event/internal/TelegramPrivateMessageEventImpl.kt @@ -22,12 +22,12 @@ import love.forte.simbot.component.telegram.core.bot.internal.TelegramBotImpl import love.forte.simbot.component.telegram.core.bot.requestDataBy import love.forte.simbot.component.telegram.core.event.StdlibEvent import love.forte.simbot.component.telegram.core.event.TelegramPrivateMessageEvent -import love.forte.simbot.component.telegram.core.message.TelegramMessageContent import love.forte.simbot.component.telegram.core.message.TelegramMessageReceipt import love.forte.simbot.component.telegram.core.message.internal.TelegramMessageContentImpl import love.forte.simbot.component.telegram.core.message.internal.toTelegramMessageReceipt -import love.forte.simbot.component.telegram.core.message.toCopyApi +import love.forte.simbot.component.telegram.core.message.send import love.forte.simbot.message.MessageContent +import love.forte.simbot.telegram.api.message.SendMessageApi import love.forte.simbot.telegram.api.message.buildSendMessageApi import love.forte.simbot.telegram.type.ChatId import love.forte.simbot.telegram.type.Message @@ -57,17 +57,26 @@ internal class TelegramPrivateMessageEventImpl( } override suspend fun reply(message: love.forte.simbot.message.Message): TelegramMessageReceipt { - TODO("reply(Message) Not yet implemented") + return bot.send(message, sourceContent.chat.id) { + SendMessageApi.builder().also { + it.replyParameters = ReplyParameters(messageId = sourceContent.messageId) + } + } } override suspend fun reply(messageContent: MessageContent): TelegramMessageReceipt { - if (messageContent is TelegramMessageContent) { - return messageContent.source.toCopyApi(ChatId(sourceContent.chat.id)) { + return bot.send( + messageContent, + sourceContent.chat.id, + copyApiBlock = { replyParameters = ReplyParameters(messageId = sourceContent.messageId) - }.requestDataBy(bot).toTelegramMessageReceipt(bot, sourceContent.chat.id) - } - - return reply(messageContent.messages) + }, + builderFactory = { + SendMessageApi.builder().also { + it.replyParameters = ReplyParameters(messageId = sourceContent.messageId) + } + } + ) } override fun toString(): String { diff --git a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/event/internal/TelegramSuperGroupMessageEventImpl.kt b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/event/internal/TelegramSuperGroupMessageEventImpl.kt new file mode 100644 index 0000000..b33f016 --- /dev/null +++ b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/event/internal/TelegramSuperGroupMessageEventImpl.kt @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2024. ForteScarlet. + * + * This file is part of simbot-component-telegram. + * + * simbot-component-telegram is free software: you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Foundation, + * either version 3 of the License, or (at your option) any later version. + * + * simbot-component-telegram is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along with simbot-component-telegram. + * If not, see . + */ + +package love.forte.simbot.component.telegram.core.event.internal + +import love.forte.simbot.component.telegram.core.actor.internal.toTelegramChatGroup +import love.forte.simbot.component.telegram.core.actor.internal.toTelegramMember +import love.forte.simbot.component.telegram.core.bot.internal.TelegramBotImpl +import love.forte.simbot.component.telegram.core.bot.requestDataBy +import love.forte.simbot.component.telegram.core.event.StdlibEvent +import love.forte.simbot.component.telegram.core.event.TelegramChatGroupMessageEvent +import love.forte.simbot.component.telegram.core.message.TelegramMessageContent +import love.forte.simbot.component.telegram.core.message.TelegramMessageReceipt +import love.forte.simbot.component.telegram.core.message.internal.TelegramMessageContentImpl +import love.forte.simbot.component.telegram.core.message.internal.toTelegramMessageReceipt +import love.forte.simbot.component.telegram.core.message.send +import love.forte.simbot.message.MessageContent +import love.forte.simbot.telegram.api.message.SendMessageApi +import love.forte.simbot.telegram.api.message.buildSendMessageApi +import love.forte.simbot.telegram.type.ChatId +import love.forte.simbot.telegram.type.Message +import love.forte.simbot.telegram.type.ReplyParameters + + +/** + * + * @author ForteScarlet + */ +internal class TelegramSuperGroupMessageEventImpl( + override val bot: TelegramBotImpl, + override val sourceEvent: StdlibEvent, + // 记得确保 chat.type == SUPERGROUP + override val sourceContent: Message +) : TelegramChatGroupMessageEvent { + override val messageContent: TelegramMessageContent = TelegramMessageContentImpl(bot, sourceContent) + + override suspend fun content(): love.forte.simbot.component.telegram.core.actor.TelegramChatGroup { + return sourceContent.chat.toTelegramChatGroup(bot) + } + + override suspend fun author(): love.forte.simbot.component.telegram.core.actor.TelegramMember { + // TODO from!!? check senderChat? + return sourceContent.from!!.toTelegramMember(bot) + } + + override suspend fun reply(text: String): TelegramMessageReceipt { + return buildSendMessageApi(ChatId(sourceContent.chat.id), text) { + replyParameters = ReplyParameters(sourceContent.messageId) + }.requestDataBy(bot).toTelegramMessageReceipt(bot) + } + + override suspend fun reply(message: love.forte.simbot.message.Message): TelegramMessageReceipt { + return bot.send(message, sourceContent.chat.id) { + SendMessageApi.builder().also { + it.replyParameters = ReplyParameters(messageId = sourceContent.messageId) + } + } + } + + override suspend fun reply(messageContent: MessageContent): TelegramMessageReceipt { + return bot.send( + messageContent, + sourceContent.chat.id, + copyApiBlock = { + replyParameters = ReplyParameters(messageId = sourceContent.messageId) + }, + builderFactory = { + SendMessageApi.builder().also { + it.replyParameters = ReplyParameters(messageId = sourceContent.messageId) + } + } + ) + } + + override fun toString(): String { + return "TelegramSuperGroupMessageEvent(name=${sourceEvent.name})" + } +} diff --git a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/message/TelegramMessageReceipt.kt b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/message/TelegramMessageReceipt.kt index 49be819..6018343 100644 --- a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/message/TelegramMessageReceipt.kt +++ b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/message/TelegramMessageReceipt.kt @@ -19,6 +19,7 @@ package love.forte.simbot.component.telegram.core.message import love.forte.simbot.common.id.IntID import love.forte.simbot.common.id.IntID.Companion.ID +import love.forte.simbot.common.id.LongID import love.forte.simbot.message.AggregatedMessageReceipt import love.forte.simbot.message.MessageReceipt import love.forte.simbot.message.SingleMessageReceipt @@ -34,6 +35,7 @@ public interface TelegramMessageSourceAware { public abstract class TelegramSingleMessageReceipt : TelegramMessageReceipt, SingleMessageReceipt() { abstract override val id: IntID + public abstract val chatId: LongID } diff --git a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/message/TelegramMessageResolver.kt b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/message/TelegramMessageResolver.kt index f333a5b..660ff98 100644 --- a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/message/TelegramMessageResolver.kt +++ b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/message/TelegramMessageResolver.kt @@ -19,10 +19,16 @@ package love.forte.simbot.component.telegram.core.message -import love.forte.simbot.message.Message +import love.forte.simbot.component.telegram.core.bot.internal.TelegramBotImpl +import love.forte.simbot.component.telegram.core.bot.requestDataBy +import love.forte.simbot.component.telegram.core.message.internal.PlainTextResolver +import love.forte.simbot.component.telegram.core.message.internal.TelegramAggregatedMessageIdReceiptImpl +import love.forte.simbot.component.telegram.core.message.internal.toTelegramMessageReceipt +import love.forte.simbot.message.* import love.forte.simbot.telegram.api.TelegramApi import love.forte.simbot.telegram.api.message.* import love.forte.simbot.telegram.type.ChatId +import love.forte.simbot.telegram.type.MessageId import kotlin.jvm.JvmName import love.forte.simbot.telegram.type.Message as StdlibMessage @@ -45,27 +51,215 @@ internal inline fun StdlibMessage.toForwardApi( } } -internal inline fun Message.resolve() { - TODO("Message.resolve") +internal suspend inline fun TelegramBotImpl.send( + text: String, + chatId: Long, + block: SendMessageApi.Builder.() -> Unit = {} +): TelegramMessageReceipt { + return buildSendMessageApi(ChatId(chatId), text, block) + .requestDataBy(this) + .toTelegramMessageReceipt(this) } +internal suspend inline fun TelegramBotImpl.send( + messageContent: MessageContent, chatId: Long, + crossinline copyApiBlock: CopyMessageApi.Builder.() -> Unit = {}, + crossinline builderFactory: BuilderFactory = { SendMessageApi.builder() } +): TelegramMessageReceipt { + if (messageContent is TelegramMessageContent) { + return messageContent.source.toCopyApi(ChatId(chatId), copyApiBlock) + .requestDataBy(this) + .toTelegramMessageReceipt(this, chatId) + } + + return send(messageContent.messages, chatId) { builderFactory() } +} + +internal suspend fun TelegramBotImpl.send( + message: Message, + chatId: Long, + builderFactory: BuilderFactory = DefaultBuilderFactory +): TelegramMessageReceipt { + val funcList = message.resolve(builderFactory) + + fun toReceipt(result: Any): TelegramSingleMessageReceipt { + return when (result) { + is StdlibMessage -> result.toTelegramMessageReceipt(this) + is MessageId -> result.toTelegramMessageReceipt(this, chatId) + else -> error("Unexpected result type: $result") + } + } + + when { + funcList.isEmpty() -> error("Nothing to send, the message element list is empty.") + funcList.size == 1 -> { + val result = funcList.first()().requestDataBy(this) + return when (result) { + is StdlibMessage -> toReceipt(result) + is MessageId -> toReceipt(result) + else -> error("Unexpected result type: $result") + } + } + + else -> { + // 00 -> nothing, 不可能到这儿 + // 01 -> only Message + // 10 -> only MessageId + // 11 -> 混杂的 + var messageTypeMark = 0 + val resultList = funcList.map { + val result = it.invoke().requestDataBy(this) + when (result) { + is StdlibMessage -> messageTypeMark = messageTypeMark or MESSAGE_MARK + is MessageId -> messageTypeMark = messageTypeMark or MESSAGE_ID_MARK + } + result + } + + return when (messageTypeMark) { + // only Message + MESSAGE_MARK -> { + @Suppress("UNCHECKED_CAST") + val sourceList = resultList as List + return sourceList.toTelegramMessageReceipt(this, chatId) + } + // only MessageId + MESSAGE_ID_MARK -> { + @Suppress("UNCHECKED_CAST") + val idList = resultList as List + idList.toTelegramMessageReceipt(this, chatId) + } + + MESSAGE_ALL_MARK -> { + val messageIds = resultList.map { + when (it) { + is StdlibMessage -> it.messageId + is MessageId -> it.messageId + else -> error("Unexpected result type: $it") + } + } + + TelegramAggregatedMessageIdReceiptImpl(this, chatId, messageIds) + } + + else -> error("Unexpected mark value: $messageTypeMark") + } + } + } +} + +private const val MESSAGE_MARK = 0b01 +private const val MESSAGE_ID_MARK = 0b10 +private const val MESSAGE_ALL_MARK = MESSAGE_MARK or MESSAGE_ID_MARK + +internal suspend fun Message.resolve( + builderFactory: BuilderFactory = DefaultBuilderFactory +): List { + return when (val m = this) { + is Message.Element -> { + val context = SendingMessageResolverContext(builderFactory) + for (resolver in sendingResolvers) { + resolver.resolve(0, m, this, context) + } + + context.end() + } + + is Messages -> { + if (m.isEmpty()) { + return emptyList() + } + + val context = SendingMessageResolverContext(builderFactory) + m.forEachIndexed { index, element -> + for (resolver in sendingResolvers) { + resolver.resolve(index, element, this, context) + } + } + + context.end() + } + } +} + +internal fun interface SendingMessageResolver { + suspend fun resolve( + index: Int, + element: Message.Element, + source: Message, + context: SendingMessageResolverContext + ) +} + +private val sendingResolvers = listOf( + PlainTextResolver, + TelegramMessageResultApiElementSendingResolver, +) + +internal typealias BuilderFactory = () -> SendMessageApi.Builder + +internal val DefaultBuilderFactory: BuilderFactory = { SendMessageApi.builder() } + +internal typealias SendingMessageResolvedFunction = () -> TelegramApi<*> // * 只能是 Message 或 MessageId + +internal class SendingMessageResolverContext( + private val builderFactory: BuilderFactory, +) { + val apiStacks = mutableListOf() // TelegramApi? + private var _builder: SendMessageApi.Builder? = null + + fun addToStackMsg(api: () -> TelegramApi) { + apiStacks.add(api) + } + + fun addToStackMsgId(api: () -> TelegramApi) { + apiStacks.add(api) + } -internal class MessageResolver { - private val apiStacks = mutableListOf>() // TelegramApi? - var builder: SendMessageApi.Builder = SendMessageApi.builder() - private set + val builderOrNull: SendMessageApi.Builder? + get() = _builder + + /** + * 如果当前builder存在,记录并消除。 + */ + fun archiveCurrent() { + _builder?.also { b -> + apiStacks.add { b.build() } + _builder = null + } + } + + private val builderOrNew: SendMessageApi.Builder + get() = _builder ?: builderFactory().also { _builder = it } + + val builder: SendMessageApi.Builder + get() = builderOrNew fun newBuilder(): SendMessageApi.Builder { - apiStacks.add(builder.build()) - return SendMessageApi.builder().also { builder = it } + archiveCurrent() + return builderFactory().also { _builder = it } } - inline fun checkOrNewBuilder(block: (SendMessageApi.Builder) -> Boolean): SendMessageApi.Builder { - val currentBuilder = builder - return if (block(currentBuilder)) { - currentBuilder + inline fun builderOrNew(createNew: (SendMessageApi.Builder) -> Boolean): SendMessageApi.Builder { + val current = builderOrNew + return if (createNew(current)) { + newBuilder() } else { + current + } + } + + inline fun builderOrNullOrNew(createNew: (SendMessageApi.Builder?) -> Boolean): SendMessageApi.Builder? { + val current = builderOrNull + return if (createNew(builderOrNull)) { newBuilder() + } else { + current } } + + fun end(): List { + archiveCurrent() + return apiStacks + } } diff --git a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/message/TelegramMessageResultApiElement.kt b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/message/TelegramMessageResultApiElement.kt new file mode 100644 index 0000000..6629769 --- /dev/null +++ b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/message/TelegramMessageResultApiElement.kt @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2024. ForteScarlet. + * + * This file is part of simbot-component-telegram. + * + * simbot-component-telegram is free software: you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Foundation, + * either version 3 of the License, or (at your option) any later version. + * + * simbot-component-telegram is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along with simbot-component-telegram. + * If not, see . + */ + +package love.forte.simbot.component.telegram.core.message + +import love.forte.simbot.telegram.api.TelegramApi +import love.forte.simbot.telegram.api.message.CopyMessageApi +import love.forte.simbot.telegram.api.message.ForwardMessageApi +import love.forte.simbot.telegram.api.message.SendMessageApi +import love.forte.simbot.telegram.type.Message +import love.forte.simbot.telegram.type.MessageId +import kotlin.jvm.JvmStatic + + +/** + * A [TelegramMessageElement] implementation that provide a [TelegramApi] + * (witch the type of result is [Message] or [MessageId], + * e.g. [SendMessageApi], [ForwardMessageApi], [CopyMessageApi], etc.) directly. + * + * [TelegramMessageResultApiElement] is a [SendOnly] type, + * and it is also a 'malleable' best message element. + * + * Note: The [TelegramMessageResultApiElement] is NOT serializable. + * @author ForteScarlet + */ +@SendOnly +public sealed class TelegramMessageResultApiElement : TelegramMessageElement { + /** + * The result `*` is [Message] or [MessageId]. + */ + public abstract val api: TelegramApi<*> + + public companion object { + /** + * Create a [TelegramMessageResultApiElement] by [api]. + */ + @JvmStatic + public fun createByMessageApi(api: TelegramApi): TelegramMessageResultApiElement = + MessageResult(api) + + /** + * Create a [TelegramMessageResultApiElement] by [api]. + */ + @JvmStatic + public fun createByMessageIdApi(api: TelegramApi): TelegramMessageResultApiElement = + MessageIdResult(api) + } +} + +internal data class MessageResult(override val api: TelegramApi) : TelegramMessageResultApiElement() +internal data class MessageIdResult(override val api: TelegramApi) : TelegramMessageResultApiElement() + + +internal object TelegramMessageResultApiElementSendingResolver : SendingMessageResolver { + override suspend fun resolve( + index: Int, + element: love.forte.simbot.message.Message.Element, + source: love.forte.simbot.message.Message, + context: SendingMessageResolverContext + ) { + if (element is TelegramMessageResultApiElement) { + context.archiveCurrent() + when (element) { + is MessageIdResult -> { + context.addToStackMsgId { element.api } + } + is MessageResult -> { + context.addToStackMsg { element.api } + } + } + } + } +} diff --git a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/message/internal/ReceivingMessageResolvers.kt b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/message/internal/ReceivingMessageResolvers.kt new file mode 100644 index 0000000..609678c --- /dev/null +++ b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/message/internal/ReceivingMessageResolvers.kt @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2024. ForteScarlet. + * + * This file is part of simbot-component-telegram. + * + * simbot-component-telegram is free software: you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Foundation, + * either version 3 of the License, or (at your option) any later version. + * + * simbot-component-telegram is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along with simbot-component-telegram. + * If not, see . + */ + +package love.forte.simbot.component.telegram.core.message.internal + +import love.forte.simbot.component.telegram.core.message.StdlibMessage +import love.forte.simbot.message.Messages +import love.forte.simbot.message.MessagesBuilder + +/** + * + */ +internal fun StdlibMessage.toMessages(): Messages { + val builder = MessagesBuilder.create() + // TODO forwardOrigin: MessageOrigin? + // TODO replyToMessage: Message ..? + // TODO externalReply: ExternalReplyInfo ..? + // TODO quote: TextQuote + // TODO replyToStory: Story ..? + // TODO hasProtectedContent: Boolean ..? + + text?.also { builder.add(it) } + + // TODO entities ..? + + // TODO linkPreviewOptions: LinkPreviewOptions + // TODO animation: Animation + // TODO audio: Audio + // TODO document: Document + // TODO photo: List + // TODO sticker: Sticker + // TODO story: Story + // TODO video: Video + // TODO videoNote: VideoNote + // TODO voice: Voice + // TODO voice: Voice + // TODO - caption: String? = null, + // - captionEntities: List? = null, + + // TODO contact: Contact + // TODO dice: Dice + // TODO game: Game + // TODO poll: Poll + // TODO venue: Venue + // TODO location: Location + + return builder.build() +} diff --git a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/message/TelegramMessageApiBodyElement.kt b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/message/internal/SendingMessageStandardResolvers.kt similarity index 50% rename from simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/message/TelegramMessageApiBodyElement.kt rename to simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/message/internal/SendingMessageStandardResolvers.kt index c94aa5d..37ab565 100644 --- a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/message/TelegramMessageApiBodyElement.kt +++ b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/message/internal/SendingMessageStandardResolvers.kt @@ -15,25 +15,23 @@ * If not, see . */ -package love.forte.simbot.component.telegram.core.message +package love.forte.simbot.component.telegram.core.message.internal -import kotlinx.serialization.SerialName -import kotlinx.serialization.Serializable -import love.forte.simbot.telegram.api.message.SendMessageApi +import love.forte.simbot.component.telegram.core.message.SendingMessageResolver +import love.forte.simbot.component.telegram.core.message.SendingMessageResolverContext +import love.forte.simbot.message.Message +import love.forte.simbot.message.PlainText - -/** - * - * A [TelegramMessageElement] implementation that provide a [SendMessageApi.Body] directly. - * [body] is sent directly as a separate SendApi and is not affected by other elements. - * - * [TelegramMessageApiBodyElement] is a type used only when sending, and it is also a 'malleable' best message element. - * - * A [SendOnly] element, will not be received in event. - * - * @author ForteScarlet - */ -@SendOnly -@Serializable -@SerialName("telegram.m.message_api_body") -public data class TelegramMessageApiBodyElement(public val body: SendMessageApi.Body) : TelegramMessageElement +internal object PlainTextResolver : SendingMessageResolver { + override suspend fun resolve( + index: Int, + element: Message.Element, + source: Message, + context: SendingMessageResolverContext + ) { + if (element is PlainText) { + context.builder.text(element.text) + } + // TODO TelegramText? (can with parse mode option) + } +} diff --git a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/message/internal/TelegramMessageContentImpl.kt b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/message/internal/TelegramMessageContentImpl.kt index e3a8005..f98d2ca 100644 --- a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/message/internal/TelegramMessageContentImpl.kt +++ b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/message/internal/TelegramMessageContentImpl.kt @@ -25,7 +25,6 @@ import love.forte.simbot.component.telegram.core.bot.requestDataBy import love.forte.simbot.component.telegram.core.message.StdlibMessage import love.forte.simbot.component.telegram.core.message.TelegramMessageContent import love.forte.simbot.message.Messages -import love.forte.simbot.message.emptyMessages import love.forte.simbot.telegram.api.message.DeleteMessageApi import love.forte.simbot.telegram.type.ChatId @@ -39,11 +38,12 @@ internal class TelegramMessageContentImpl( override val source: StdlibMessage ) : TelegramMessageContent { - override val messages: Messages - get() = emptyMessages() // TODO("Not yet implemented") + override val messages: Messages by lazy { + source.toMessages() + } override val plainText: String? - get() = source.text // TODO entries? + get() = source.text override suspend fun delete(vararg options: DeleteOption) { kotlin.runCatching { diff --git a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/message/internal/TelegramSingleMessageSourceReceiptImpl.kt b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/message/internal/TelegramSingleMessageSourceReceiptImpl.kt index d39110c..0f7c2de 100644 --- a/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/message/internal/TelegramSingleMessageSourceReceiptImpl.kt +++ b/simbot-component-telegram-core/src/commonMain/kotlin/love/forte/simbot/component/telegram/core/message/internal/TelegramSingleMessageSourceReceiptImpl.kt @@ -21,6 +21,8 @@ import love.forte.simbot.ability.DeleteFailureException import love.forte.simbot.ability.DeleteOption import love.forte.simbot.common.id.IntID import love.forte.simbot.common.id.IntID.Companion.ID +import love.forte.simbot.common.id.LongID +import love.forte.simbot.common.id.LongID.Companion.ID import love.forte.simbot.component.telegram.core.bot.internal.TelegramBotImpl import love.forte.simbot.component.telegram.core.message.* import love.forte.simbot.telegram.api.message.DeleteMessageApi @@ -39,6 +41,8 @@ internal class TelegramSingleMessageSourceReceiptImpl( private val bot: TelegramBotImpl, override val message: Message ) : TelegramSingleMessageSourceReceipt() { + override val chatId: LongID + get() = message.chat.id.ID override suspend fun delete(vararg options: DeleteOption) { // TODO option ignore fail @@ -71,15 +75,18 @@ internal class TelegramSingleMessageSourceReceiptImpl( */ internal class TelegramSingleMessageIdReceiptImpl( private val bot: TelegramBotImpl, - private val chatId: Long, + private val chatIdValue: Long, private val messageId: Int ) : TelegramSingleMessageIdReceipt() { override val id: IntID get() = messageId.ID + override val chatId: LongID + get() = chatIdValue.ID + override suspend fun delete(vararg options: DeleteOption) { // TODO option ignore fail - DeleteMessageApi.create(ChatId(chatId), messageId).requestDataBy(bot.source) + DeleteMessageApi.create(ChatId(chatIdValue), messageId).requestDataBy(bot.source) } @@ -105,6 +112,19 @@ internal class TelegramSingleMessageIdReceiptImpl( } } +// internal class SimpleTelegramAggregatedMessageReceiptImpl( +// private val bot: TelegramBotImpl, +// private val chatId: Long, +// private val receipts: List, +// ) : TelegramAggregatedMessageReceipt() { +// override val ids: Collection +// get() = receipts.map { it.id } +// +// override fun get(index: Int): TelegramSingleMessageReceipt = receipts[index] +// +// override fun iterator(): Iterator = receipts.iterator() +// } + internal class TelegramAggregatedMessageIdReceiptImpl( private val bot: TelegramBotImpl, private val chatId: Long, @@ -178,6 +198,7 @@ internal fun MessageId.toTelegramMessageReceipt( ): TelegramSingleMessageIdReceiptImpl = TelegramSingleMessageIdReceiptImpl(bot, chatId, messageId) + /** * [this] must be >= 1 * (preferably >= 2). From 12ac8e0fc5b8ae08ac4cf68a64c2dfcbf254c6aa Mon Sep 17 00:00:00 2001 From: ForteScarlet Date: Thu, 11 Apr 2024 16:03:36 +0800 Subject: [PATCH 15/16] v0.0.1-dev1 --- .changelog/v0.0.1-dev1.md | 73 +++++++++++++++++++++ simbot-component-telegram-type/README.md | 4 +- simbot-component-telegram-type/README_CN.md | 2 + 3 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 .changelog/v0.0.1-dev1.md diff --git a/.changelog/v0.0.1-dev1.md b/.changelog/v0.0.1-dev1.md new file mode 100644 index 0000000..4bc727f --- /dev/null +++ b/.changelog/v0.0.1-dev1.md @@ -0,0 +1,73 @@ +> 对应核心版本: [**v4.0.0-beta3**](https://github.com/simple-robot/simpler-robot/releases/tag/v4.0.0-beta3) + + +> [!warning] +> **目前版本处于 `dev` 阶段,代表此版本是一个开发预览版,可能不稳定、可能随时发生更改、且不保证可用性。** + + +我们欢迎并期望着您的的[反馈](https://github.com/simple-robot/simbot-component-telegram/issues)或[协助](https://github.com/simple-robot/simbot-component-telegram/pulls), +感谢您的贡献与支持! + +也欢迎您为我们献上一颗 `star`,这是对我们最大的鼓励与认可! + +此版本在使用 `stdlib` 模块时,可以监听到所有的事件(因为Telegram所有的事件都在一个 `Update` 类型中,这还挺方便的): + +```Kotlin +val bot = BotFactory.create(TOKEN) { + coroutineContext = Dispatchers.IO + + // 可选地配置 engine,比如配置一个代理 + apiClientEngine = CIO.create { + proxy = ProxyBuilder.http("http://127.0.0.1:7790") + } + + // 配置 longPolling 的值即代表启用主动拉取事件的形式,*类似于*其他组件中那种 ws 接收事件的方式。 + // 不配置、配置为 `null` 则代表不启用。 + longPolling = LongPolling( + limit = 100, + timeout = 10.minutes.inWholeSeconds.toInt(), + allowedUpdates = setOf(UpdateValues.MESSAGE_NAME) + ) +} + +// 使用 `subscribe` 订阅所有事件、根据类型(以及名称)订阅事件 +bot.subscribe { event -> + println("Event: $event") +} + +// 使用 onXxx 根据某个具体事件的扩展来订阅事件,等同于订阅一个对应类型、名称的事件。 +// 比如此处,订阅事件类型为 `Message` 且事件名为 `"message"` 的事件。 +bot.onMessage { event, message -> + println("event: ${event}") + println("message: ${message}") +} + +// 启动并挂起bot +bot.start() +bot.join() +``` + +> [!note] +> 如果不配置 `longPolling`,也就是只使用 Telegram 的 webhook 的形式接收事件, +> 那么你需要自行启动一个 HTTP 服务,并将接收到的请求体的 JSON 字符串(或解析后的 `Update` 实体)提供给 bot。 +> ```Kotlin + +``` + + +核心组件模块(`core`模块)目前支持的事件: + +- `TelegramEvent` + - `TelegramMessageRelatedEvent` + - `TelegramMessageEvent` + - `TelegramChatGroupMessageEvent` + - `TelegramSuperGroupMessageEvent` + - `TelegramChannelMessageEvent` + - `TelegramPrivateMessageEvent` + - `TelegramUnsupportedEvent` (一个兜底用的事件类型,可以借助此类型来监听到所有 `stdlib` 模块中的所有尚未提供专属类型的事件类型。) + +目前: +- 发送/回复文本消息、直接借助API发送消息、直接转发消息 (`send/reply(MessageContent`)。 +- 接收消息内的纯文本内容 (`MessageContent.plainText`) +- **暂不支持**解析为 `Messages` (`MessageContent.messages`) + diff --git a/simbot-component-telegram-type/README.md b/simbot-component-telegram-type/README.md index 274bbd9..667b611 100644 --- a/simbot-component-telegram-type/README.md +++ b/simbot-component-telegram-type/README.md @@ -45,7 +45,7 @@ dependencies { ``` -## Notes +## Please note ### Compatibility Currently, most types in modules are defined using `data class`. These types are considered to be used for serialization. @@ -53,3 +53,5 @@ When officials modify/extend a type (such as adding fields), binary compatibilit (the parameters of the constructor have changed). This change usually increments the `minor` version number. + +(There are also plans to find a version to rewrite them into a more compatible form (such as the common class).) diff --git a/simbot-component-telegram-type/README_CN.md b/simbot-component-telegram-type/README_CN.md index 6fcbec7..86b5e1e 100644 --- a/simbot-component-telegram-type/README_CN.md +++ b/simbot-component-telegram-type/README_CN.md @@ -53,3 +53,5 @@ dependencies { 当官方对API做出修改时(例如增加字段),那么数据类的二进制兼容性可能无法被保证(因为构造函数的字段发生了变化)。 这种变更通常会递增 `minor` 版本号。 + +(也有计划找个版本将它们改写为兼容性更好的形式(比如普通的`class`)。) From c43ff110f5ed0173d7e58c4f6b1c0cf9fba356da Mon Sep 17 00:00:00 2001 From: ForteScarlet Date: Thu, 11 Apr 2024 16:10:49 +0800 Subject: [PATCH 16/16] v0.0.1-dev1 --- .github/workflows/publish-release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index 5791ea7..3986e4e 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -2,7 +2,7 @@ name: Publish Release on: push: tags: - - v*.**.** + - v** env: IS_CI: true