-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathbot.go
103 lines (95 loc) · 2.38 KB
/
bot.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
package main
import (
"fmt"
"log"
"time"
)
// collection ids to be processed by the bot
var botCollIDs = make(chan string, 100)
func botColl(id string) {
coll, err := db.ReadColl(id)
if err != nil {
log.Printf("bot: error reading %s: %v", id, err)
}
if err := db.Bot(coll); err != nil {
log.Printf("bot: error: %s: %v", coll.ID, err)
}
}
func bot() {
fmt.Println("running bot")
// get pre-transition states where actor is Bot, so we don't have to try each state
for _, from := range db.CollFSM.From(Bot) {
collIDs, err := db.ReadColls(CollState(from))
if err != nil {
log.Printf("bot: error reading %s collections: %v", from, err)
continue
}
for _, collID := range collIDs {
botColl(collID)
}
}
}
// Bot runs some automatic transitions.
// In order to avoid loops, it must be triggered by the ui only.
func (db *DB) Bot(coll *Collection) error {
// if actions can be done subsequently, it's useful to put them in that order
if err := db.BotArchive(coll); err != nil {
return err
}
if err := db.BotDelete(coll); err != nil {
return err
}
if err := db.BotFinalize(coll); err != nil {
return err
}
// TODO process unfetched tasks
return nil
}
func (db *DB) BotArchive(coll *Collection) error {
if !coll.BotCan("archive") {
return nil
}
since, err := coll.LatestEventSince()
if err != nil {
return err
}
if since > 2*7*24*time.Hour && coll.Due() == 0 { // more than two weeks and we're even
coll.ClientInput = ClientInput{} // clear data
if err := db.UpdateCollAndTasks(coll); err != nil {
return err
}
log.Printf("archiving %s", coll.ID)
return db.UpdateCollState(Bot, coll, Archived, 0, "")
}
return nil
}
func (db *DB) BotDelete(coll *Collection) error {
if !coll.BotCan("delete") {
return nil
}
since, err := coll.LatestEventSince()
if err != nil {
return err
}
if since > 2*7*24*time.Hour { // more than two weeks
log.Printf("deleting %s (%s)", coll.ID, coll.State)
return db.Delete(Bot, coll)
}
return nil
}
func (db *DB) BotFinalize(coll *Collection) error {
if !coll.BotCan("finalize") {
return nil
}
if coll.Due() > 0 {
return nil
}
for _, task := range coll.Tasks {
if task.State != Fetched && task.State != Reshipped {
// any task is neither fetched nor reshipped
return nil
}
}
log.Printf("finalizing %s", coll.ID)
return db.UpdateCollState(Bot, coll, Finalized, 0, "Bestellauftrag ist abgeschlossen")
}