-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmessages.go
executable file
·138 lines (128 loc) · 3.36 KB
/
messages.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
137
138
package bot
import (
"bufio"
"fmt"
"log"
"os"
"strings"
"time"
"unicode/utf8"
)
// Message holds the config, words, directions, User, Email, and Time
type Message struct {
config *Config
words []string
directions Directions
User string
Email string
Time time.Time
}
// NewMesssage sets up a new message with a given config
func NewMessage(c *Config) *Message {
return &Message{config: c}
}
// AddProfile adds the user, email, time to the Message
func (m *Message) AddProfile(user, email string, date time.Time) {
m.User = user
m.Email = email
m.Time = date
}
func (m *Message) String() string {
return strings.Join(m.words, " ")
}
// AddWord adds a new parsed word to the message
func (m *Message) AddWord(word string) {
m.words = append(m.words, word)
}
// Scan goes over the entire message to add words
func (m *Message) Scan(scanner *bufio.Scanner) error {
scanner.Split(bufio.ScanWords)
for scanner.Scan() {
m.AddWord(scanner.Text())
}
// fmt.Println("Scan")
// fmt.Printf("words: %#v\n", m.words)
if err := scanner.Err(); err != nil && err.Error() != "atEOD" {
return err
}
return nil
}
// ScanWords is used to split the text into words
func (m *Message) ScanWords(data []byte, atEOF bool) (advance int, token []byte, err error) {
start := 0
for width := 0; start < len(data); start += width {
var r rune
r, width = utf8.DecodeRune(data[start:])
if !isSpace(r) {
fmt.Println("no space")
break
}
}
for width, i := 0, start; i < len(data); i += width {
var r rune
r, width = utf8.DecodeRune(data[i:])
if isSpace(r) {
fmt.Println("found a space")
return i + width, data[start:i], nil
}
}
if atEOF && len(data) == 0 {
return 0, nil, fmt.Errorf("%s", "empty")
}
if atEOF && len(data) > start {
fmt.Println("atEOF")
return len(data), data[start:], nil
}
fmt.Println("want more data")
return len(data), data[start:], nil
}
// Process initializes the Action, adds the user, email, time to the env
// gets the options, calls the intro target, and finally streams the target
// results to the messenger
func (m *Message) Process(bot Messenger, directions Directions) error {
directions, err := m.processDirections(directions)
if err != nil {
return err
}
env := append(os.Environ(), []string{
"user=" + m.User,
"email=" + m.Email,
"time=" + m.Time.Format(time.RFC3339),
}...)
for _, direction := range directions {
for _, a := range direction.Actions {
var ops Options
a.Init(m.config, bot)
if ops, err = a.GetOptions(m.String()); err != nil {
log.Println("Error: make options:", err.Error())
}
env = append(env, "target="+direction.Target)
result := a.Make(NewTarget("intro", ops, env))
if result.Status == 0 {
if err = bot.Respond([]*Result{result}); err != nil {
log.Println("Error: make intro:", err.Error())
}
}
a.MakeStream(NewTarget(direction.Target, ops, env))
}
}
return nil
}
func (m *Message) processDirections(directions Directions) (Directions, error) {
if len(m.words) < 1 {
return nil, fmt.Errorf("%s", "No words found")
}
for _, direction := range directions {
for _, text := range direction.Words {
var word = m.words[0]
if word == m.config.ID {
word = m.words[1]
}
if strings.Title(text) == strings.Title(word) {
direction.Target = text
m.directions = append(m.directions, direction)
}
}
}
return m.directions, nil
}