/
task.go
136 lines (112 loc) · 3.18 KB
/
task.go
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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
package prago
import (
"fmt"
"runtime/debug"
"time"
)
func (app *App) postInitTaskManager() {
app.API("tasks/runtask").Method("POST").Permission(loggedPermission).Handler(func(request *Request) {
id := request.Request().FormValue("id")
csrf := request.Request().FormValue("csrf")
if request.csrfToken() != csrf {
panic("wrong token")
}
task := app.tasksMap[id]
if !request.Authorize(task.permission) {
panic("not authorized")
}
app.runTask(task, request.UserID(), request.Locale())
request.Redirect(task.dashboard.board.getURL())
})
sysadminBoard.Dashboard(unlocalized("Cache")).AddTask(unlocalized("Delete cache"), "sysadmin", func(ta *TaskActivity) error {
app.ClearCache()
return nil
})
}
type taskView struct {
ID string
Name string
CSRFToken string
}
func (t *Task) taskView(locale, csrfToken string) taskView {
return taskView{
ID: t.uuid,
Name: t.name(locale),
CSRFToken: csrfToken,
}
}
func (dashboard *Dashboard) getTasks(userData UserData, csrfToken string) (ret []taskView) {
for _, v := range dashboard.tasks {
if userData.Authorize(v.permission) {
ret = append(ret, v.taskView(userData.Locale(), csrfToken))
}
}
return ret
}
// Task represent some user task
type Task struct {
uuid string
name func(string) string
dashboard *Dashboard
permission Permission
handler func(*TaskActivity) error
lastStarted time.Time
}
// Task creates task
func (dashboard *Dashboard) AddTask(name func(string) string, permission Permission, handler func(*TaskActivity) error) {
if dashboard.board.app.tasksMap == nil {
dashboard.board.app.tasksMap = make(map[string]*Task)
}
if dashboard.board.app.validatePermission(permission) != nil {
panic("invalid permission")
}
task := &Task{
uuid: randomString(20),
name: name,
permission: sysadminPermission,
dashboard: dashboard,
handler: handler,
}
dashboard.tasks = append(dashboard.tasks, task)
dashboard.board.app.tasksMap[task.uuid] = task
}
func (app *App) runTask(t *Task, userID int64, locale string) {
var name string = t.name(locale)
var notification *Notification = app.Notification(name)
notification.preName = t.dashboard.name(locale)
activity := &TaskActivity{
task: t,
notification: notification,
}
t.lastStarted = time.Now()
notification.SetPrimaryAction("Ukončit", func() {
activity.stoppedByUser = true
})
notification.disableCancel = true
if userID > 0 {
notification.Push(userID)
}
progress := -1.0
notification.SetProgress(&progress)
go func() {
defer func() {
notification.primaryAction = nil
notification.secondaryAction = nil
activity.notification.disableCancel = false
activity.notification.progress = nil
if r := recover(); r != nil {
activity.notification.SetStyleFail()
if activity.stoppedByUser {
notification.SetDescription("Ukončeno uživatelem")
} else {
recoveryStr := fmt.Sprintf("%v, stack: %s", r, string(debug.Stack()))
notification.SetDescription(recoveryStr)
}
} else {
activity.notification.description = "Úspěšně dokončeno"
activity.notification.SetStyleSuccess()
}
}()
must(t.handler(activity))
}()
}