mirror of
https://github.com/black-ant/Ant-Browser.git
synced 2026-07-14 18:48:55 +08:00
151 lines
3.9 KiB
Go
151 lines
3.9 KiB
Go
package automation
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"sort"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/google/uuid"
|
|
)
|
|
|
|
type ScriptRunRecord struct {
|
|
ID string `json:"id"`
|
|
ScriptID string `json:"scriptId"`
|
|
ScriptName string `json:"scriptName"`
|
|
ScriptType string `json:"scriptType"`
|
|
Status string `json:"status"`
|
|
Summary string `json:"summary"`
|
|
Error string `json:"error"`
|
|
ResultText string `json:"resultText"`
|
|
LogText string `json:"logText"`
|
|
StartedAt string `json:"startedAt"`
|
|
FinishedAt string `json:"finishedAt"`
|
|
DurationMs int64 `json:"durationMs"`
|
|
}
|
|
|
|
type ScriptRunRequest struct {
|
|
ScriptID string `json:"scriptId"`
|
|
SelectorText string `json:"selectorText"`
|
|
TargetMode string `json:"targetMode,omitempty"`
|
|
TargetInput any `json:"targetInput,omitempty"`
|
|
ParamsText string `json:"paramsText"`
|
|
UseScriptSelector bool `json:"useScriptSelector"`
|
|
UseScriptParams bool `json:"useScriptParams"`
|
|
TimeoutMs int `json:"timeoutMs,omitempty"`
|
|
}
|
|
|
|
type ScriptRunStore struct {
|
|
rootDir string
|
|
}
|
|
|
|
func NewScriptRunStore(rootDir string) *ScriptRunStore {
|
|
return &ScriptRunStore{
|
|
rootDir: filepath.Clean(strings.TrimSpace(rootDir)),
|
|
}
|
|
}
|
|
|
|
func (s *ScriptRunStore) Save(input ScriptRunRecord) (ScriptRunRecord, error) {
|
|
record := normalizeScriptRunRecord(input)
|
|
if err := os.MkdirAll(s.rootDir, 0o755); err != nil {
|
|
return ScriptRunRecord{}, fmt.Errorf("create automation run dir failed: %w", err)
|
|
}
|
|
|
|
data, err := json.MarshalIndent(record, "", " ")
|
|
if err != nil {
|
|
return ScriptRunRecord{}, fmt.Errorf("marshal automation run record failed: %w", err)
|
|
}
|
|
|
|
if err := writeFileAtomic(filepath.Join(s.rootDir, record.ID+".json"), data, 0o644); err != nil {
|
|
return ScriptRunRecord{}, fmt.Errorf("write automation run record failed: %w", err)
|
|
}
|
|
return record, nil
|
|
}
|
|
|
|
func (s *ScriptRunStore) List(limit int) ([]ScriptRunRecord, error) {
|
|
if limit <= 0 {
|
|
limit = 20
|
|
}
|
|
if limit > 200 {
|
|
limit = 200
|
|
}
|
|
|
|
if err := os.MkdirAll(s.rootDir, 0o755); err != nil {
|
|
return nil, fmt.Errorf("create automation run dir failed: %w", err)
|
|
}
|
|
|
|
entries, err := os.ReadDir(s.rootDir)
|
|
if err != nil {
|
|
if os.IsNotExist(err) {
|
|
return []ScriptRunRecord{}, nil
|
|
}
|
|
return nil, fmt.Errorf("read automation run dir failed: %w", err)
|
|
}
|
|
|
|
items := make([]ScriptRunRecord, 0, len(entries))
|
|
for _, entry := range entries {
|
|
if entry.IsDir() || !strings.HasSuffix(strings.ToLower(entry.Name()), ".json") {
|
|
continue
|
|
}
|
|
data, err := os.ReadFile(filepath.Join(s.rootDir, entry.Name()))
|
|
if err != nil {
|
|
continue
|
|
}
|
|
var record ScriptRunRecord
|
|
if err := json.Unmarshal(data, &record); err != nil {
|
|
continue
|
|
}
|
|
items = append(items, normalizeScriptRunRecord(record))
|
|
}
|
|
|
|
sort.Slice(items, func(i, j int) bool {
|
|
return parseRFC3339OrZero(items[i].StartedAt).After(parseRFC3339OrZero(items[j].StartedAt))
|
|
})
|
|
|
|
if len(items) > limit {
|
|
items = items[:limit]
|
|
}
|
|
return items, nil
|
|
}
|
|
|
|
func normalizeScriptRunRecord(input ScriptRunRecord) ScriptRunRecord {
|
|
now := time.Now().Format(time.RFC3339)
|
|
|
|
id := strings.TrimSpace(input.ID)
|
|
if id == "" {
|
|
id = uuid.NewString()
|
|
}
|
|
|
|
status := strings.TrimSpace(input.Status)
|
|
switch status {
|
|
case "success", "failed", "running":
|
|
default:
|
|
status = "failed"
|
|
}
|
|
|
|
startedAt := firstNonEmpty(input.StartedAt, now)
|
|
finishedAt := firstNonEmpty(input.FinishedAt, startedAt)
|
|
durationMs := input.DurationMs
|
|
if durationMs < 0 {
|
|
durationMs = 0
|
|
}
|
|
|
|
return ScriptRunRecord{
|
|
ID: id,
|
|
ScriptID: strings.TrimSpace(input.ScriptID),
|
|
ScriptName: strings.TrimSpace(input.ScriptName),
|
|
ScriptType: strings.TrimSpace(input.ScriptType),
|
|
Status: status,
|
|
Summary: strings.TrimSpace(input.Summary),
|
|
Error: strings.TrimSpace(input.Error),
|
|
ResultText: strings.TrimSpace(input.ResultText),
|
|
LogText: strings.TrimSpace(input.LogText),
|
|
StartedAt: startedAt,
|
|
FinishedAt: finishedAt,
|
|
DurationMs: durationMs,
|
|
}
|
|
}
|