feat(service): 添加 JM 下载功能
All checks were successful
Sakura-Miki-build / Automatic-Packaging (push) Successful in 2m27s
All checks were successful
Sakura-Miki-build / Automatic-Packaging (push) Successful in 2m27s
- 新增 DownloadUtil 工具类,用于处理 JMComic 下载任务 - 添加 JmDownloadService 服务类,实现 /JmDownload 命令的处理 - 更新 .gitea/workflows/build-test.yaml,重命名为 package.yaml 并调整工作流名称- 修改 MFAGenerateService、RandomPhotoService 和 ExampleService,优化命令前缀和参数处理 - 新增 JsonUtil 工具类,用于解析 JSON 数据 - 更新 AlistUtil 依赖版本至 1.0.1-spring
This commit is contained in:
parent
4bc526d48c
commit
4f37aace85
@ -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 ./
|
BIN
lib/AlistUtil-1.0.1-spring.jar
Normal file
BIN
lib/AlistUtil-1.0.1-spring.jar
Normal file
Binary file not shown.
2
pom.xml
2
pom.xml
@ -136,7 +136,7 @@
|
||||
<dependency>
|
||||
<groupId>io.github.1530624156</groupId>
|
||||
<artifactId>AlistUtil</artifactId>
|
||||
<version>1.0.0-spring</version>
|
||||
<version>1.0.1-spring</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.squareup.okhttp3</groupId>
|
||||
|
@ -27,7 +27,7 @@ class ExampleService : Service<MessageV2Event> {
|
||||
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
|
||||
}
|
||||
}
|
||||
|
@ -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<MessageV2Event>{
|
||||
|
||||
@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查看")
|
||||
}
|
||||
}
|
@ -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<Int>("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<String>("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<Int>("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)
|
||||
}
|
||||
}
|
@ -31,7 +31,7 @@ class MFAGenerateService : Service<FriendMessageEvent> {
|
||||
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<FriendMessageEvent> {
|
||||
*/
|
||||
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(
|
||||
|
@ -31,7 +31,7 @@ class RandomPhotoService : Service<MessageV2Event> {
|
||||
*/
|
||||
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"
|
||||
}
|
||||
|
||||
/**
|
||||
|
13
src/main/kotlin/info/alinadace/sakuramiki/util/JsonUtil.kt
Normal file
13
src/main/kotlin/info/alinadace/sakuramiki/util/JsonUtil.kt
Normal file
@ -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))
|
||||
}
|
Loading…
Reference in New Issue
Block a user