Skip to content

Commit 98d795a

Browse files
Merge pull request #31 from open-olive/SIDE-1060-disambiguation-card-type-frame
Side 1060 disambiguation card type frame
2 parents 9b32611 + 26c46c5 commit 98d795a

20 files changed

+1704
-267
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
build/
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2020 Olive
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
REPO := github.com/open-olive/loop-development-kit/ldk/go/examples/whisper-disambiguation
2+
PKG := examplego
3+
4+
GIT_COMMIT := $(shell git rev-list -1 HEAD)
5+
GIT_BRANCH := $(if $(shell echo $$BRANCH_NAME),$(shell echo $$BRANCH_NAME),$(shell git rev-parse --abbrev-ref HEAD))
6+
VERSION := $(if $(shell echo $$VERSION),$(shell echo $$VERSION),"0.0.0-localdev-unset")
7+
GOPATH := $(shell go env GOPATH)
8+
9+
install:
10+
# The following command is needed to allow go get to clone from private bitbucket repos
11+
@ git config --global url."[email protected]:".insteadOf "https://bitbucket.org/"
12+
go mod download
13+
go mod tidy
14+
15+
assets:
16+
@ echo "Compiling assets"
17+
@ go get github.com/go-bindata/go-bindata/...
18+
@ $(GOPATH)/bin/go-bindata -o bind/assets.go -pkg bind assets/...
19+
@ go mod tidy
20+
21+
build/darwin-amd64/plugin:
22+
go build \
23+
-ldflags "-X ${REPO}/loop.GitBranch=${GIT_BRANCH} -X ${REPO}/loop.GitCommit=${GIT_COMMIT} -X ${REPO}/loop.Version=${VERSION}" \
24+
-o build/darwin-amd64/plugin ./
25+
26+
build/windows-amd64/plugin:
27+
GOOS=windows go build \
28+
-ldflags "-X ${REPO}/loop.GitBranch=${GIT_BRANCH} -X ${REPO}/loop.GitCommit=${GIT_COMMIT} -X ${REPO}/loop.Version=${VERSION}" \
29+
-o build/windows-amd64/plugin.exe ./
30+
31+
clean:
32+
rm -rf ./build
33+
34+
build: clean build/darwin-amd64/plugin build/windows-amd64/plugin
35+
36+
# TODO: remove before merging to master
37+
deploy-local: build
38+
cp build/darwin-amd64/plugin ~/Library/Application\ Support/Olive\ Helps\ local/loops/123/plugin
39+
40+
test:
41+
go test -v ./...
42+
43+
test-race:
44+
go test -v -race ./...
45+
46+
bench:
47+
go test -v -bench=. ./...
48+
49+
golangci:
50+
go get github.com/golangci/golangci-lint/cmd/[email protected]
51+
go mod tidy
52+
golangci-lint run
53+
54+
.PHONY: install assets build clean lint test test-race bench golangci
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
module github.com/open-olive/loop-development-kit/ldk/go/examples/whisper-disambiguation
2+
3+
go 1.14
4+
5+
replace github.com/open-olive/loop-development-kit/ldk/go => ../..
6+
7+
require (
8+
github.com/google/go-cmp v0.5.2
9+
github.com/hashicorp/yamux v0.0.0-20200609203250-aecfd211c9ce // indirect
10+
github.com/mitchellh/go-testing-interface v1.14.1 // indirect
11+
github.com/oklog/run v1.1.0 // indirect
12+
github.com/open-olive/loop-development-kit/ldk/go v1.3.1
13+
)

ldk/go/examples/whisper-disambiguation/go.sum

Lines changed: 209 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
package loop
2+
3+
import (
4+
"context"
5+
"encoding/json"
6+
"time"
7+
8+
ldk "github.com/open-olive/loop-development-kit/ldk/go"
9+
)
10+
11+
type recall struct {
12+
Address1 string `json:"address_1"`
13+
Address2 string `json:"address_2"`
14+
Codes string `json:"code_info"`
15+
Country string `json:"country"`
16+
City string `json:"city"`
17+
Classification string `json:"classification"`
18+
Date string `json:"recall_initiation_date"`
19+
Description string `json:"product_description"`
20+
Distribution string `json:"distribution_pattern"`
21+
Firm string `json:"recalling_firm"`
22+
ID string `json:"recall_number"`
23+
Quantity string `json:"product_quantity"`
24+
Reason string `json:"reason_for_recall"`
25+
RecallType string `json:"voluntary_mandated"`
26+
State string `json:"state"`
27+
Type string `json:"product_type"`
28+
Zip string `json:"postal_code"`
29+
}
30+
31+
type apiResponse struct {
32+
Meta interface{} `json:"meta"`
33+
Results []recall `json:"results"`
34+
}
35+
36+
// Serve allows Olive Helps to have access the loop
37+
func Serve() error {
38+
l := ldk.NewLogger("example-whisper-disambiguation")
39+
loop, err := NewLoop(l)
40+
if err != nil {
41+
return err
42+
}
43+
ldk.ServeLoopPlugin(l, loop)
44+
return nil
45+
}
46+
47+
// Loop is a structure for generating SideKick whispers
48+
type Loop struct {
49+
ctx context.Context
50+
cancel context.CancelFunc
51+
52+
sidekick ldk.Sidekick
53+
logger *ldk.Logger
54+
}
55+
56+
// NewLoop returns a pointer to a loop
57+
func NewLoop(logger *ldk.Logger) (*Loop, error) {
58+
return &Loop{
59+
logger: logger,
60+
}, nil
61+
}
62+
63+
// LoopStart is called by the host when the plugin is started to provide access to the host process
64+
func (c *Loop) LoopStart(sidekick ldk.Sidekick) error {
65+
c.logger.Info("Starting example whisper disambiguation loop")
66+
c.ctx, c.cancel = context.WithCancel(context.Background())
67+
68+
c.sidekick = sidekick
69+
70+
now := time.Now()
71+
72+
response, err := sidekick.Network().HTTPRequest(c.ctx, &ldk.HTTPRequest{
73+
URL: "https://api.fda.gov/food/enforcement.json?search=report_date:[" + now.AddDate(0, -3, 0).Format("20060102") + "+TO+" + now.Format("20060102") + "]&limit=10",
74+
Method: "GET",
75+
Body: nil,
76+
})
77+
if err != nil {
78+
c.logger.Error("received error from callback", err)
79+
return err
80+
}
81+
82+
if response.ResponseCode == 200 {
83+
var data apiResponse
84+
85+
if err := json.Unmarshal(response.Data, &data); err != nil {
86+
c.logger.Error("Error unmarshaling response payload", err)
87+
return err
88+
}
89+
90+
elements := make(map[string]ldk.WhisperContentDisambiguationElement)
91+
92+
for index := range data.Results {
93+
item := data.Results[index]
94+
elements[item.ID] = &ldk.WhisperContentDisambiguationElementOption{
95+
Label: "😝" + item.Firm + " (" + item.Date + ")",
96+
Order: uint32(index) + 1,
97+
OnChange: func(key string) {
98+
go func() {
99+
err := c.sidekick.Whisper().List(c.ctx, &ldk.WhisperContentList{
100+
Label: item.Firm + " Recall",
101+
Elements: map[string]ldk.WhisperContentListElement{
102+
"topMessage": &ldk.WhisperContentListElementMessage{
103+
Style: ldk.WhisperContentListElementStyleNone,
104+
Body: item.Description,
105+
Align: ldk.WhisperContentListElementAlignLeft,
106+
Order: 0,
107+
},
108+
"sectionDivider": &ldk.WhisperContentListElementDivider{
109+
Order: 1,
110+
},
111+
"reason": &ldk.WhisperContentListElementPair{
112+
Label: "Reason",
113+
Order: 2,
114+
Value: item.Reason,
115+
},
116+
"distribution": &ldk.WhisperContentListElementPair{
117+
Label: "Distribution",
118+
Order: 3,
119+
Value: item.Distribution,
120+
},
121+
"quantity": &ldk.WhisperContentListElementPair{
122+
Label: "Quantity",
123+
Order: 4,
124+
Value: item.Quantity,
125+
},
126+
"codes": &ldk.WhisperContentListElementPair{
127+
Extra: true,
128+
Label: "Codes",
129+
Order: 5,
130+
Value: item.Codes,
131+
},
132+
"id": &ldk.WhisperContentListElementPair{
133+
Extra: true,
134+
Label: "Recall number",
135+
Order: 6,
136+
Value: item.ID,
137+
},
138+
"date": &ldk.WhisperContentListElementPair{
139+
Extra: true,
140+
Label: "Date initiated",
141+
Order: 7,
142+
Value: item.Date,
143+
},
144+
"recallType": &ldk.WhisperContentListElementPair{
145+
Extra: true,
146+
Label: "Recall type",
147+
Order: 8,
148+
Value: item.RecallType,
149+
},
150+
"type": &ldk.WhisperContentListElementPair{
151+
Extra: true,
152+
Label: "Product type",
153+
Order: 9,
154+
Value: item.Type,
155+
},
156+
"classification": &ldk.WhisperContentListElementPair{
157+
Extra: true,
158+
Label: "Classification",
159+
Order: 10,
160+
Value: item.Classification,
161+
},
162+
"address": &ldk.WhisperContentListElementPair{
163+
Extra: true,
164+
Label: "Company address",
165+
Order: 11,
166+
Value: item.Address1 + " " + item.Address2 + " " + item.City + ", " + item.State + " " + item.Zip + " " + item.Country,
167+
},
168+
},
169+
})
170+
if err != nil {
171+
c.logger.Error("failed to emit whisper", "error", err)
172+
}
173+
}()
174+
},
175+
}
176+
}
177+
178+
elements["header1"] = &ldk.WhisperContentDisambiguationElementText{
179+
Body: "# Text header\n## Text subheader",
180+
Order: 0,
181+
}
182+
elements["header2"] = &ldk.WhisperContentDisambiguationElementText{
183+
Body: "# Text header",
184+
Order: 6,
185+
}
186+
187+
go func() {
188+
_, err := c.sidekick.Whisper().Disambiguation(c.ctx, &ldk.WhisperContentDisambiguation{
189+
Label: "Latest FDA Food Recalls",
190+
Elements: elements,
191+
})
192+
if err != nil {
193+
c.logger.Error("failed to emit whisper", "error", err)
194+
}
195+
}()
196+
197+
return nil
198+
}
199+
200+
c.logger.Error("received response code of", response.ResponseCode)
201+
return nil
202+
}
203+
204+
// LoopStop is called by the host when the plugin is stopped
205+
func (c *Loop) LoopStop() error {
206+
c.logger.Info("controller LoopStop called")
207+
c.cancel()
208+
209+
return nil
210+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package main
2+
3+
import (
4+
loop "github.com/open-olive/loop-development-kit/ldk/go/examples/whisper-disambiguation/loop"
5+
)
6+
7+
func main() {
8+
if err := loop.Serve(); err != nil {
9+
panic(err)
10+
}
11+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"author": "Olive",
3+
"created": "2020-06-22T00:00:00Z",
4+
"dependencies": [],
5+
"description": "This is an example loop written in Go.",
6+
"id": "9e9eeb9c-fa4d-471a-8778-088bdb077f97",
7+
"name": "Example Disambiguation Whisper Go",
8+
"organization": "OliveAI",
9+
"specification": "1",
10+
"updated": "2020-07-23T00:00:00Z",
11+
"version": "1.1.0"
12+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# Sidekick Loop Example in Go
2+
3+
This is a very simple loop to use as a starting point. This loop watches for text events and emits a whisper every time it receives an event.
4+
5+
## Developers
6+
7+
### Install
8+
9+
Ensure Go is installed and working ([Instructions](https://golang.org/doc/install)). Go v1.14 or higher is recommended.
10+
11+
This project uses [Go Modules](https://blog.golang.org/using-go-modules). You should clone it outside of your gopath. For example, your home directory.
12+
13+
To install dependencies, run the following command:
14+
15+
```shell
16+
make install
17+
```
18+
19+
### Build
20+
21+
Build will compile an executable and output it to the `/build` directory.
22+
23+
Run the following command to build:
24+
25+
```shell
26+
make build
27+
```
28+
29+
### Deploy
30+
31+
Deploying will first build, then copy the built files to the correct location for Sidekick to use them. You do not need to run the build command first, deploying will do it automatically.
32+
33+
This is useful for testing with Sidekick.
34+
35+
Run the following command to deploy:
36+
37+
```shell
38+
make deploy
39+
```
40+
41+
### Quality
42+
43+
The project uses a collection of tools to ensure code standards are maintained.
44+
45+
Run the following command to execute the quality checking tools:
46+
47+
```shell
48+
make quality
49+
```
50+
51+
### Test
52+
53+
This project has a test to ensure the loop text matching is working as expected.
54+
55+
Run the following command to execute tests:
56+
57+
```shell
58+
make test
59+
```

0 commit comments

Comments
 (0)