mirror of
https://gitcode.com/JianFeeeee/homeagent-sdk.git
synced 2026-09-21 17:38:03 +00:00
feat(qq): download task tracking with qq_get_download_tasks, sync re-added
This commit is contained in:
@ -17,7 +17,7 @@ import (
|
|||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"gitcode.com/JianFeeeee/homeagent-sdk/sdk"
|
"gitcode.com/JianFeeeee/homeagent-sdk/sdk"
|
||||||
@ -74,6 +74,15 @@ func rconPacket(id, typ int32, body string) []byte {
|
|||||||
return pkt
|
return pkt
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type DownloadTask struct {
|
||||||
|
FileID string `json:"file_id"`
|
||||||
|
Filename string `json:"filename"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
Path string `json:"path,omitempty"`
|
||||||
|
Error string `json:"error,omitempty"`
|
||||||
|
CreatedAt string `json:"created_at"`
|
||||||
|
}
|
||||||
|
|
||||||
type Plugin struct {
|
type Plugin struct {
|
||||||
name string
|
name string
|
||||||
sdk *sdk.PluginSDK
|
sdk *sdk.PluginSDK
|
||||||
@ -91,6 +100,8 @@ type Plugin struct {
|
|||||||
groupAllowFrom map[int64]struct{}
|
groupAllowFrom map[int64]struct{}
|
||||||
srv *http.Server
|
srv *http.Server
|
||||||
agentfsDir string
|
agentfsDir string
|
||||||
|
downloadMu sync.Mutex
|
||||||
|
downloadTasks []*DownloadTask
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Plugin) Name() string { return p.name }
|
func (p *Plugin) Name() string { return p.name }
|
||||||
@ -273,6 +284,10 @@ type 枚举: text(文字)/ voice(语音转文字后发送)/ image(图
|
|||||||
}, "required": []string{"file_id"},
|
}, "required": []string{"file_id"},
|
||||||
}, p.handleDownloadFile)
|
}, p.handleDownloadFile)
|
||||||
|
|
||||||
|
p.regTool(s, tp+"get_download_tasks", "查看所有下载任务及状态(running/done/failed),包含文件名、保存路径、错误信息等", map[string]interface{}{
|
||||||
|
"type": "object", "properties": map[string]interface{}{},
|
||||||
|
}, p.handleGetDownloadTasks)
|
||||||
|
|
||||||
p.regTool(s, tp+"upload_group_file", "上传文件到QQ群(通过base64编码发送,同时出现在群消息和群文件柜)", map[string]interface{}{
|
p.regTool(s, tp+"upload_group_file", "上传文件到QQ群(通过base64编码发送,同时出现在群消息和群文件柜)", map[string]interface{}{
|
||||||
"type": "object", "properties": map[string]interface{}{
|
"type": "object", "properties": map[string]interface{}{
|
||||||
"group_id": map[string]interface{}{"type": "integer", "description": "目标群号"},
|
"group_id": map[string]interface{}{"type": "integer", "description": "目标群号"},
|
||||||
@ -1478,6 +1493,25 @@ func (p *Plugin) handleGetGroupFiles(args map[string]interface{}) (interface{},
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *Plugin) addDownloadTask(fileID, filename string) *DownloadTask {
|
||||||
|
p.downloadMu.Lock()
|
||||||
|
defer p.downloadMu.Unlock()
|
||||||
|
t := &DownloadTask{FileID: fileID, Filename: filename, Status: "running", CreatedAt: time.Now().Format("15:04:05")}
|
||||||
|
p.downloadTasks = append(p.downloadTasks, t)
|
||||||
|
if len(p.downloadTasks) > 100 {
|
||||||
|
p.downloadTasks = p.downloadTasks[len(p.downloadTasks)-100:]
|
||||||
|
}
|
||||||
|
return t
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Plugin) updateDownloadTask(t *DownloadTask, status, path, errMsg string) {
|
||||||
|
p.downloadMu.Lock()
|
||||||
|
defer p.downloadMu.Unlock()
|
||||||
|
t.Status = status
|
||||||
|
t.Path = path
|
||||||
|
t.Error = errMsg
|
||||||
|
}
|
||||||
|
|
||||||
func (p *Plugin) handleDownloadFile(args map[string]interface{}) (interface{}, error) {
|
func (p *Plugin) handleDownloadFile(args map[string]interface{}) (interface{}, error) {
|
||||||
fileID, _ := args["file_id"].(string)
|
fileID, _ := args["file_id"].(string)
|
||||||
if fileID == "" {
|
if fileID == "" {
|
||||||
@ -1488,41 +1522,53 @@ func (p *Plugin) handleDownloadFile(args map[string]interface{}) (interface{}, e
|
|||||||
groupID, _ := convInt64(args["group_id"])
|
groupID, _ := convInt64(args["group_id"])
|
||||||
userID, _ := convInt64(args["user_id"])
|
userID, _ := convInt64(args["user_id"])
|
||||||
|
|
||||||
dispName := filename
|
task := p.addDownloadTask(fileID, filename)
|
||||||
if dispName == "" {
|
|
||||||
dispName = fileID
|
|
||||||
if len(dispName) > 16 {
|
|
||||||
dispName = dispName[:16] + "…"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
go func() {
|
go func(t *DownloadTask, fid, fname, furl string, gid, uid int64) {
|
||||||
savePath := ""
|
savePath := ""
|
||||||
if fileURL != "" {
|
errMsg := ""
|
||||||
savePath = p.downloadURL(fileURL, filename)
|
if furl != "" {
|
||||||
|
savePath = p.downloadURL(furl, fname)
|
||||||
}
|
}
|
||||||
if savePath == "" && groupID > 0 {
|
if savePath == "" && gid > 0 {
|
||||||
savePath = p.downloadGroupFile(groupID, fileID, filename)
|
savePath = p.downloadGroupFile(gid, fid, fname)
|
||||||
}
|
}
|
||||||
if savePath == "" && userID > 0 {
|
if savePath == "" && uid > 0 {
|
||||||
savePath = p.downloadPrivateFile(userID, fileID, filename)
|
savePath = p.downloadPrivateFile(uid, fid, fname)
|
||||||
}
|
}
|
||||||
if savePath == "" {
|
if savePath == "" {
|
||||||
savePath = p.downloadFromNapCat(fileID, filename)
|
savePath = p.downloadFromNapCat(fid, fname)
|
||||||
}
|
}
|
||||||
if savePath != "" {
|
if savePath != "" {
|
||||||
|
p.updateDownloadTask(t, "done", savePath, "")
|
||||||
log.Printf("[qq] 文件下载完成: %s", savePath)
|
log.Printf("[qq] 文件下载完成: %s", savePath)
|
||||||
if p.sdk != nil {
|
if p.sdk != nil {
|
||||||
p.sdk.InjectInterruptText(p.name, p.name,
|
p.sdk.InjectInterruptText(p.name, p.name,
|
||||||
fmt.Sprintf("文件下载完成: %s,保存在 %s", filepath.Base(savePath), savePath))
|
fmt.Sprintf("文件下载完成: %s,保存在 %s", filepath.Base(savePath), savePath))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log.Printf("[qq] 文件下载失败: %s", fileID)
|
errMsg = "下载失败,文件可能已过期"
|
||||||
|
p.updateDownloadTask(t, "failed", "", errMsg)
|
||||||
|
log.Printf("[qq] 文件下载失败: %s", fid)
|
||||||
}
|
}
|
||||||
}()
|
}(task, fileID, filename, fileURL, groupID, userID)
|
||||||
|
|
||||||
return map[string]interface{}{"status": "started", "file_id": fileID, "filename": dispName,
|
return map[string]interface{}{
|
||||||
"hint": "下载已后台启动,完成后会推送通知。若长时间未收到完成通知表示文件已过期无法下载,需让发送者重新发送"}, nil
|
"status": "started", "file_id": fileID, "filename": filename,
|
||||||
|
"hint": "下载已后台启动。使用 qq_get_download_tasks 查看进度。"}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Plugin) handleGetDownloadTasks(args map[string]interface{}) (interface{}, error) {
|
||||||
|
p.downloadMu.Lock()
|
||||||
|
defer p.downloadMu.Unlock()
|
||||||
|
// 返回最近 50 条
|
||||||
|
tasks := p.downloadTasks
|
||||||
|
if len(tasks) > 50 {
|
||||||
|
tasks = tasks[len(tasks)-50:]
|
||||||
|
}
|
||||||
|
return map[string]interface{}{
|
||||||
|
"tasks": tasks, "total": len(p.downloadTasks),
|
||||||
|
"hint": "status 为 running 表示下载中,done 已完成,failed 已失败。用 qq_download_file 重新下载失败的任务。"}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Plugin) handleUploadGroupFile(args map[string]interface{}) (interface{}, error) {
|
func (p *Plugin) handleUploadGroupFile(args map[string]interface{}) (interface{}, error) {
|
||||||
@ -2037,6 +2083,7 @@ func NewPlugin(name string, config map[string]interface{}) (sdk.Plugin, error) {
|
|||||||
name: name,
|
name: name,
|
||||||
allowFrom: make(map[int64]struct{}),
|
allowFrom: make(map[int64]struct{}),
|
||||||
groupAllowFrom: make(map[int64]struct{}),
|
groupAllowFrom: make(map[int64]struct{}),
|
||||||
|
downloadTasks: make([]*DownloadTask, 0),
|
||||||
dmPolicy: "open",
|
dmPolicy: "open",
|
||||||
groupPolicy: "open",
|
groupPolicy: "open",
|
||||||
}, nil
|
}, nil
|
||||||
|
|||||||
Reference in New Issue
Block a user