Task Engine

/app/controller/clib/task.go (3.9 KB)

  1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
package clib

import (
"fmt"
"net/http"

"github.com/pkg/errors"

"{{{ .Package }}}/app"
"{{{ .Package }}}/app/controller"
"{{{ .Package }}}/app/controller/cutil"
"{{{ .Package }}}/app/lib/task"
"{{{ .Package }}}/app/lib/websocket"
"{{{ .Package }}}/app/util"
"{{{ .Package }}}/views/vtask"
)

const taskIcon = "gift"

func TaskList(w http.ResponseWriter, r *http.Request) {
controller.Act("task.list", w, r, func(as *app.State, ps *cutil.PageState) (string, error) {
tasks := as.Services.Task.RegisteredTasks
ps.SetTitleAndData("Tasks", tasks)
ps.DefaultNavIcon = taskIcon
return controller.Render(r, as, &vtask.List{Tasks: tasks}, ps, taskBC(nil)...)
})
}

func TaskDetail(w http.ResponseWriter, r *http.Request) {
controller.Act("task.list", w, r, func(as *app.State, ps *cutil.PageState) (string, error) {
key, err := cutil.PathString(r, "key", false)
if err != nil {
return "", err
}
t := as.Services.Task.RegisteredTasks.Get(key)
if t == nil {
return "", errors.Errorf("no task found with key [%s]", key)
}
ps.SetTitleAndData(t.TitleSafe(), t)
ps.DefaultNavIcon = taskIcon
return controller.Render(r, as, &vtask.Detail{Task: t}, ps, taskBC(t)...)
})
}

func TaskRun(w http.ResponseWriter, r *http.Request) {
controller.Act("task.run", w, r, func(as *app.State, ps *cutil.PageState) (string, error) {
key, err := cutil.PathString(r, "key", false)
if err != nil {
return "", err
}
t := as.Services.Task.RegisteredTasks.Get(key)
if t == nil {
return "", errors.Errorf("unable to find task [%s]", key)
}
args := cutil.QueryArgsMap(r.URL)
page := &vtask.Detail{Task: t, Args: args}
if args.GetBoolOpt("async") {
delete(args, "async")
page.SocketURL = t.WebPath() + "/start" + "?" + args.ToQueryString()
ps.SetTitleAndData(t.TitleSafe(), t)
} else {
ret := t.Run(ps.Context, args, ps.Logger)
page.Result = ret
ps.SetTitleAndData(t.TitleSafe(), ret)
}
return controller.Render(r, as, page, ps, taskBC(t, "Run**play")...)
})
}

func TaskStart(w http.ResponseWriter, r *http.Request) {
controller.Act("task.start", w, r, func(as *app.State, ps *cutil.PageState) (string, error) {
key, err := cutil.PathString(r, "key", false)
if err != nil {
return "", err
}
t := as.Services.Task.RegisteredTasks.Get(key)
if t == nil {
return "", errors.Errorf("unable to find task [%s]", key)
}
args := cutil.QueryArgsMap(r.URL)

ch := fmt.Sprintf("%s-%d", t.Key, util.RandomInt(1000))
id, err := as.Services.Socket.Upgrade(ps.Context, w, r, ch{{{ if .HasUser }}}, ps.User{{{ end }}}, ps.Profile{{{ if .HasAccount }}}, ps.Accounts{{{ end }}}, websocket.EchoHandler, ps.Logger)
if err != nil {
ps.Logger.Warnf("unable to upgrade connection to WebSocket: %s", err.Error())
return "", err
}

fn := as.Services.Socket.Terminal(ch, ps.Logger)
go func() {
res := t.Run(ps.Context, args, ps.Logger, fn)
html := vtask.ResultSummary(as, res, ps)
x := util.ValueMap{"result": res, "html": html}
_ = as.Services.Socket.WriteMessage(id, websocket.NewMessage(nil, ch, "complete", x), ps.Logger)
_ = as.Services.Socket.WriteCloseRequest(id, ps.Logger)
}()

return "", as.Services.Socket.ReadLoop(ps.Context, id, ps.Logger)
})
}

func TaskRemove(w http.ResponseWriter, r *http.Request) {
controller.Act("task.remove", w, r, func(as *app.State, ps *cutil.PageState) (string, error) {
key, err := cutil.PathString(r, "key", false)
if err != nil {
return "", err
}
as.Services.Task.RemoveTask(key)
if err != nil {
return "", errors.Wrap(err, "unable to remove task")
}
return controller.ReturnToReferrer("removed task ["+key+"]", "/admin/task", ps)
})
}

func taskBC(t *task.Task, extra ...string) []string {
ret := []string{"admin", "Tasks||/admin/task**task"}
if t != nil {
ret = append(ret, t.TitleSafe()+"||"+t.WebPath()+"**"+t.IconSafe())
}
return append(ret, extra...)
}