diff --git a/.gitea/workflows/build-test.yaml b/.gitea/workflows/package.yaml similarity index 77% rename from .gitea/workflows/build-test.yaml rename to .gitea/workflows/package.yaml index e80886e..80dfe27 100644 --- a/.gitea/workflows/build-test.yaml +++ b/.gitea/workflows/package.yaml @@ -1,11 +1,11 @@ name: Sakura-Miki-build -run-name: ${{ gitea.actor }} is testing out Gitea Actions 🚀 +run-name: Automatic-Packaging 📦 on: [ push ] env: BARE_REPO_DIR: https://git.alina-dace.info/Dace/Sakura-Miki.git CLONED_REPO_DIR: ./ jobs: - Explore-Gitea-Actions: + Automatic-Packaging: runs-on: ubuntu-latest steps: - name: Checkout Git Repo @@ -18,7 +18,7 @@ jobs: distribution: 'temurin' cache: maven - run: chmod +x ./mvnw - - run: ./mvnw install:install-file -Dfile=./lib/AlistUtil-1.0.0-spring.jar -Dpackaging=jar -DgroupId=io.github.1530624156 -DartifactId=AlistUtil -Dversion=1.0.0-spring + - run: ./mvnw install:install-file -Dfile=./lib/AlistUtil-1.0.1-spring.jar -Dpackaging=jar -DgroupId=io.github.1530624156 -DartifactId=AlistUtil -Dversion=1.0.1-spring - name: build run: ./mvnw clean package -DskipTests=true -P prod - run: docker build -t sakura-miki:latest ./ diff --git a/lib/AlistUtil-1.0.1-spring.jar b/lib/AlistUtil-1.0.1-spring.jar new file mode 100644 index 0000000..811c958 Binary files /dev/null and b/lib/AlistUtil-1.0.1-spring.jar differ diff --git a/pom.xml b/pom.xml index 3b7b8f4..cf6a8f7 100644 --- a/pom.xml +++ b/pom.xml @@ -136,7 +136,7 @@ io.github.1530624156 AlistUtil - 1.0.0-spring + 1.0.1-spring com.squareup.okhttp3 diff --git a/src/main/kotlin/info/alinadace/sakuramiki/service/ExampleService.kt b/src/main/kotlin/info/alinadace/sakuramiki/service/ExampleService.kt index 962593d..6c77389 100644 --- a/src/main/kotlin/info/alinadace/sakuramiki/service/ExampleService.kt +++ b/src/main/kotlin/info/alinadace/sakuramiki/service/ExampleService.kt @@ -27,7 +27,7 @@ class ExampleService : Service { override fun entrance(event: MessageV2Event): Boolean { val chain = event.message if (chain.size == 1 && chain[0] is PlainText && event.sender.id == botConfig.admin) { - if (chain[0].toString() == "测试") { + if (chain[0].toString().trim() == "测试") { return true } } diff --git a/src/main/kotlin/info/alinadace/sakuramiki/service/jm/JmDownloadService.kt b/src/main/kotlin/info/alinadace/sakuramiki/service/jm/JmDownloadService.kt new file mode 100644 index 0000000..9420a07 --- /dev/null +++ b/src/main/kotlin/info/alinadace/sakuramiki/service/jm/JmDownloadService.kt @@ -0,0 +1,49 @@ +package info.alinadace.sakuramiki.service.jm + +import info.alinadace.sakuramiki.annotation.BotFunction +import info.alinadace.sakuramiki.configuration.BotConfig +import info.alinadace.sakuramiki.service.Service +import info.alinadace.sakuramiki.service.jm.util.DownloadUtil +import io.github.kloping.qqbot.api.v2.FriendMessageEvent +import io.github.kloping.qqbot.api.v2.GroupMessageEvent +import io.github.kloping.qqbot.api.v2.MessageV2Event +import io.github.kloping.qqbot.entities.ex.PlainText +import jakarta.annotation.Resource + +/** + * @author Kane + * @since 2025/3/24 15:36 + */ +@BotFunction(FriendMessageEvent::class, GroupMessageEvent::class) +class JmDownloadService: Service{ + + @Resource + lateinit var botConfig: BotConfig + + @Resource + lateinit var downloadUtil: DownloadUtil + + /** + * 服务入口 + */ + override fun entrance(event: MessageV2Event): Boolean { + val chain = event.message + if (chain.size == 1 && chain[0] is PlainText && event.sender.id == botConfig.admin) { + if (chain[0].toString().trim().startsWith("/JmDownload")) { + return true + } + } + return false + } + + /** + * 服务行为 + */ + override fun active(event: MessageV2Event) { + val chain = event.message + val code = chain[0].toString().trim().split(" ")[1] + event.send("任务已添加") + downloadUtil.start(code) + event.send("任务已完成,请前往Alist查看") + } +} diff --git a/src/main/kotlin/info/alinadace/sakuramiki/service/jm/util/DownloadUtil.kt b/src/main/kotlin/info/alinadace/sakuramiki/service/jm/util/DownloadUtil.kt new file mode 100644 index 0000000..3020de6 --- /dev/null +++ b/src/main/kotlin/info/alinadace/sakuramiki/service/jm/util/DownloadUtil.kt @@ -0,0 +1,85 @@ +package info.alinadace.sakuramiki.service.jm.util + +import cn.hutool.core.lang.UUID +import com.mavis.service.AlistService +import info.alinadace.sakuramiki.util.okHttpClient +import info.alinadace.sakuramiki.util.parse +import jakarta.annotation.Resource +import okhttp3.OkHttpClient +import okhttp3.Request +import okhttp3.RequestBody +import okhttp3.RequestBody.Companion.toRequestBody +import okhttp3.Response +import org.springframework.stereotype.Service + +/** + * @author Kane + * @since 2025/3/24 15:38 + */ +@Service +class DownloadUtil { + companion object { + private const val DIR = "/AliDrive/JMComic" + private const val OWNER = "Grand-cocoa" + private const val REPO = "JMComic-Crawler-Python" + private const val WORKFLOW_ID = "151600689" + private const val BASE = "https://api.github.com" + private const val CREATE = "${BASE}/repos/${OWNER}/${REPO}/actions/workflows/${WORKFLOW_ID}/dispatches" + private const val LIST = "${BASE}/repos/${OWNER}/${REPO}/actions/workflows/${WORKFLOW_ID}/runs" + private const val GET = "${BASE}/repos/${OWNER}/${REPO}/actions/runs/%d" + private const val ARTIFACTS = "${BASE}/repos/${OWNER}/${REPO}/actions/runs/%d/artifacts" + private const val DOWNLOAD = "${BASE}/repos/${OWNER}/${REPO}/actions/artifacts/%d/zip" + private const val APIKEY = "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" + + private const val CREATE_BODY = """{"inputs": {"JM_ALBUM_IDS": "%s","JM_PHOTO_IDS": ""},"ref": "master"}""" + + private fun OkHttpClient.newCall(url: String, method: String, body: RequestBody? = null): Response { + return this.newCall(Request.Builder() + .url(url) + .method(method, body) +// .addHeader("Content-Type", "application/json") + .addHeader("Authorization", "Bearer $APIKEY") + .addHeader("User-Agent", "Apifox/1.0.0 (https://apifox.com)") + .addHeader("Accept", "*/*") + .addHeader("Host", "api.github.com") + .addHeader("Connection", "keep-alive") + .build()).execute() + } + } + + @Resource + lateinit var alistService: AlistService + + fun start(id: String){ + val createBody = CREATE_BODY.format(id).toRequestBody() +// Request.Builder().post(createBody).addHeader() + val create = okHttpClient.newCall(CREATE, "POST", createBody) + if (create.code != 200) return + Thread.sleep(3000) + val list = okHttpClient.newCall(LIST, "GET") + if (list.code != 200) return + val listBody = parse(list.body?.string()!!) + val jobId = listBody.getByPath("workflow_runs[0].id") + var status = false + for (i in 0..10){ + Thread.sleep(10000) + val get = okHttpClient.newCall(GET.format(jobId), "GET") + if (get.code != 200) return + val getBody = parse(get.body?.string()!!) + if (getBody.getByPath("conclusion") == "success"){ + status = true + break + } + } + if (!status) return + val artifacts = okHttpClient.newCall(ARTIFACTS.format(jobId), "GET") + if (artifacts.code != 200) return + val artifactsBody = parse(artifacts.body?.string()!!) + val artifactId = artifactsBody.getByPath("artifacts[0].id") + val download = okHttpClient.newCall(DOWNLOAD.format(artifactId), "GET") + if (download.code != 200) return + val blob = download.body?.bytes() + val fastUUID = UUID.fastUUID().toString(true) + alistService.uploadFile(blob, DIR, fastUUID) + } +} diff --git a/src/main/kotlin/info/alinadace/sakuramiki/service/mfa/MFAGenerateService.kt b/src/main/kotlin/info/alinadace/sakuramiki/service/mfa/MFAGenerateService.kt index 65a3545..a194ebe 100644 --- a/src/main/kotlin/info/alinadace/sakuramiki/service/mfa/MFAGenerateService.kt +++ b/src/main/kotlin/info/alinadace/sakuramiki/service/mfa/MFAGenerateService.kt @@ -31,7 +31,7 @@ class MFAGenerateService : Service { if (message.size != 1 && message.size != 2) { return false } - if (message[0] is PlainText && message[0].toString().startsWith("mfa")){ + if (message[0] is PlainText && message[0].toString().startsWith("/mfa")){ if (message.size == 1){ val split = message[0].toString().split(" ") return split.size <= 2 @@ -45,7 +45,7 @@ class MFAGenerateService : Service { */ override fun active(event: FriendMessageEvent) { val message = event.message - if (message[0] is PlainText && message[0].toString().startsWith("mfa")){ + if (message[0] is PlainText && message[0].toString().startsWith("/mfa")){ val command = message[0].toString().split(" ") if (command.size == 1){ val mfa = mapper.selectOne( diff --git a/src/main/kotlin/info/alinadace/sakuramiki/service/randomphoto/RandomPhotoService.kt b/src/main/kotlin/info/alinadace/sakuramiki/service/randomphoto/RandomPhotoService.kt index b7fbc17..6112c6c 100644 --- a/src/main/kotlin/info/alinadace/sakuramiki/service/randomphoto/RandomPhotoService.kt +++ b/src/main/kotlin/info/alinadace/sakuramiki/service/randomphoto/RandomPhotoService.kt @@ -31,7 +31,7 @@ class RandomPhotoService : Service { */ override fun entrance(event: MessageV2Event): Boolean { val chain = event.message - return chain.size == 1 && chain[0] is PlainText && chain[0].toString() == "#photo" + return chain.size == 1 && chain[0] is PlainText && chain[0].toString().trim() == "/photo" } /** diff --git a/src/main/kotlin/info/alinadace/sakuramiki/util/JsonUtil.kt b/src/main/kotlin/info/alinadace/sakuramiki/util/JsonUtil.kt new file mode 100644 index 0000000..a3b3f66 --- /dev/null +++ b/src/main/kotlin/info/alinadace/sakuramiki/util/JsonUtil.kt @@ -0,0 +1,13 @@ +package info.alinadace.sakuramiki.util + +import cn.hutool.core.lang.Dict +import com.fasterxml.jackson.databind.ObjectMapper + +/** + * @author Kane + * @since 2025/3/24 16:10 + */ +private val OBJECT_MAPPER = ObjectMapper() +fun parse(json: String): Dict { + return OBJECT_MAPPER.readValue(json, OBJECT_MAPPER.typeFactory.constructType(Dict::class.java)) +}