-
Notifications
You must be signed in to change notification settings - Fork 20
/
environment.go
110 lines (90 loc) · 3.24 KB
/
environment.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
package runs
import (
"regexp"
"strings"
"time"
"github.com/nyaruka/goflow/assets"
"github.com/nyaruka/goflow/flows"
"github.com/nyaruka/goflow/utils"
"github.com/pkg/errors"
)
type runEnvironment struct {
utils.Environment
run *flowRun
}
// creates a run environment based on the given run
func newRunEnvironment(base utils.Environment, run *flowRun) flows.RunEnvironment {
return &runEnvironment{base, run}
}
func (e *runEnvironment) Timezone() *time.Location {
contact := e.run.Contact()
// if run has a contact with a timezone, that overrides the enviroment's timezone
if contact != nil && contact.Timezone() != nil {
return contact.Timezone()
}
return e.run.Session().Environment().Timezone()
}
func (e *runEnvironment) Locations() (assets.LocationHierarchy, error) {
sessionAssets := e.run.Session().Assets()
hierarchies := sessionAssets.Locations().Hierarchies()
if len(hierarchies) > 0 {
// in the future we might support more than one hiearchy per session,
// but for now we only use the first one
return hierarchies[0], nil
}
return nil, nil
}
// FindLocations returns locations with the matching name (case-insensitive), level and parent (optional)
func (e *runEnvironment) FindLocations(name string, level utils.LocationLevel, parent *utils.Location) ([]*utils.Location, error) {
locations, err := e.Locations()
if err != nil {
return nil, err
}
if locations == nil {
return nil, errors.Errorf("can't find locations in environment which is not location enabled")
}
return locations.FindByName(name, level, parent), nil
}
// FindLocationsFuzzy returns matching locations like FindLocations but attempts the following strategies
// to find locations:
// 1. Exact match
// 2. Match with punctuation removed
// 3. Split input into words and try to match each word
// 4. Try to match pairs of words
func (e *runEnvironment) FindLocationsFuzzy(text string, level utils.LocationLevel, parent *utils.Location) ([]*utils.Location, error) {
// try matching name exactly
if locations, err := e.FindLocations(text, level, parent); len(locations) > 0 || err != nil {
return locations, err
}
// try with punctuation removed
stripped := strings.TrimSpace(regexp.MustCompile(`\W+`).ReplaceAllString(text, ""))
if locations, err := e.FindLocations(stripped, level, parent); len(locations) > 0 || err != nil {
return locations, err
}
// try on each tokenized word
words := regexp.MustCompile(`\W+`).Split(text, -1)
for _, word := range words {
if locations, err := e.FindLocations(word, level, parent); len(locations) > 0 || err != nil {
return locations, err
}
}
// try with each pair of words
for w := 0; w < len(words)-1; w++ {
wordPair := strings.Join(words[w:w+2], " ")
if locations, err := e.FindLocations(wordPair, level, parent); len(locations) > 0 || err != nil {
return locations, err
}
}
return []*utils.Location{}, nil
}
func (e *runEnvironment) LookupLocation(path flows.LocationPath) (*utils.Location, error) {
locations, err := e.Locations()
if err != nil {
return nil, err
}
if locations == nil {
return nil, errors.Errorf("can't lookup locations in environment which is not location enabled")
}
return locations.FindByPath(path.String()), nil
}
var _ flows.RunEnvironment = (*runEnvironment)(nil)