multi-client but one ntg search, nontrivial config.json change
parent
5a4bcecac7
commit
e546034c26
|
|
@ -1,6 +1,12 @@
|
||||||
package broker
|
package broker
|
||||||
|
|
||||||
import "local/truckstop/config"
|
import (
|
||||||
|
"local/truckstop/config"
|
||||||
|
|
||||||
|
"golang.org/x/time/rate"
|
||||||
|
)
|
||||||
|
|
||||||
|
var limiter = rate.NewLimiter(rate.Limit(0.3), 1)
|
||||||
|
|
||||||
type Broker interface {
|
type Broker interface {
|
||||||
Search([]config.State) ([]Job, error)
|
Search([]config.State) ([]Job, error)
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,8 @@ package broker
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"local/truckstop/config"
|
"local/truckstop/config"
|
||||||
|
"log"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -37,9 +39,10 @@ func (j JobLocation) String() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (j Job) FormatMultilineText() string {
|
func (j Job) FormatMultilineText() string {
|
||||||
|
foo := func(client string) string {
|
||||||
return fmt.Sprintf(
|
return fmt.Sprintf(
|
||||||
"--- %s: %s => %s ---\nPickup: %s\nDropoff: %s\nNotes: %d lbs, %d miles, %s",
|
"--- %s: %s => %s ---\nPickup: %s\nDropoff: %s\nNotes: %d lbs, %d miles, %s",
|
||||||
config.Get().Name,
|
client,
|
||||||
j.Pickup.State,
|
j.Pickup.State,
|
||||||
j.Dropoff.State,
|
j.Dropoff.State,
|
||||||
j.Pickup.String(),
|
j.Pickup.String(),
|
||||||
|
|
@ -48,4 +51,17 @@ func (j Job) FormatMultilineText() string {
|
||||||
j.Miles,
|
j.Miles,
|
||||||
j.Meta,
|
j.Meta,
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
out := ""
|
||||||
|
clients := config.Get().Clients
|
||||||
|
for k := range clients {
|
||||||
|
log.Printf("job multiline: %+v contains %s then use %v", clients[k].States, j.Pickup.State, k)
|
||||||
|
if strings.Contains(fmt.Sprint(clients[k].States), j.Pickup.State) {
|
||||||
|
if len(out) > 0 {
|
||||||
|
out += "\n\n"
|
||||||
|
}
|
||||||
|
out += foo(k)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out
|
||||||
}
|
}
|
||||||
|
|
|
||||||
22
config.json
22
config.json
|
|
@ -1,23 +1,33 @@
|
||||||
{
|
{
|
||||||
"Name": "pa",
|
|
||||||
"Interval": {
|
"Interval": {
|
||||||
"Input": "10s..30s",
|
"Input": "10s..30s",
|
||||||
"OK": "6h0m0s..6h0m0s",
|
"OK": "6h0m0s..6h0m0s",
|
||||||
"Error": "6h0m0s..6h0m0s"
|
"Error": "6h0m0s..6h0m0s"
|
||||||
},
|
},
|
||||||
|
"Clients": {
|
||||||
|
"pa": {
|
||||||
"States": [
|
"States": [
|
||||||
"FL",
|
"OH"
|
||||||
"GA",
|
|
||||||
"NC"
|
|
||||||
],
|
],
|
||||||
|
"IDs": {
|
||||||
|
"Matrix": "@belandbroc:matrix.org"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"caleb": {
|
||||||
|
"States": [
|
||||||
|
"OH"
|
||||||
|
],
|
||||||
|
"IDs": {
|
||||||
|
"Matrix": "@belandbroc:matrix.org"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"Storage": [
|
"Storage": [
|
||||||
"map"
|
"map"
|
||||||
],
|
],
|
||||||
"Client": "breellocaldev@gmail.com",
|
|
||||||
"Message": {
|
"Message": {
|
||||||
"Matrix": {
|
"Matrix": {
|
||||||
"ReceiveEnabled": true,
|
"ReceiveEnabled": true,
|
||||||
"Client": "@belandbroc:matrix.org",
|
|
||||||
"Mock": true,
|
"Mock": true,
|
||||||
"Homeserver": "https://matrix-client.matrix.org",
|
"Homeserver": "https://matrix-client.matrix.org",
|
||||||
"Username": "@breellocaldev:matrix.org",
|
"Username": "@breellocaldev:matrix.org",
|
||||||
|
|
|
||||||
|
|
@ -9,19 +9,21 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
Name string
|
|
||||||
Interval struct {
|
Interval struct {
|
||||||
Input Duration
|
Input Duration
|
||||||
OK Duration
|
OK Duration
|
||||||
Error Duration
|
Error Duration
|
||||||
}
|
}
|
||||||
|
Clients map[string]struct {
|
||||||
States []State
|
States []State
|
||||||
|
IDs struct {
|
||||||
|
Matrix string
|
||||||
|
}
|
||||||
|
}
|
||||||
Storage []string
|
Storage []string
|
||||||
Client string
|
|
||||||
Message struct {
|
Message struct {
|
||||||
Matrix struct {
|
Matrix struct {
|
||||||
ReceiveEnabled bool
|
ReceiveEnabled bool
|
||||||
Client string
|
|
||||||
Mock bool
|
Mock bool
|
||||||
Homeserver string
|
Homeserver string
|
||||||
Username string
|
Username string
|
||||||
|
|
@ -54,6 +56,21 @@ func configPath() string {
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func AllStates() []State {
|
||||||
|
c := Get()
|
||||||
|
statem := map[State]struct{}{}
|
||||||
|
for _, v := range c.Clients {
|
||||||
|
for _, state := range v.States {
|
||||||
|
statem[state] = struct{}{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
states := make([]State, 0, len(statem)+1)
|
||||||
|
for k := range statem {
|
||||||
|
states = append(states, k)
|
||||||
|
}
|
||||||
|
return states
|
||||||
|
}
|
||||||
|
|
||||||
func Refresh() error {
|
func Refresh() error {
|
||||||
b, err := ioutil.ReadFile(configPath())
|
b, err := ioutil.ReadFile(configPath())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
40
main.go
40
main.go
|
|
@ -49,39 +49,51 @@ func matrixrecv() error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
states := map[config.State]struct{}{}
|
states := map[string]map[config.State]struct{}{}
|
||||||
for _, msg := range messages {
|
for _, msg := range messages {
|
||||||
if len(states) > 0 {
|
if _, ok := states[msg.Sender]; ok {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
for _, state := range parseOutStates([]byte(msg)) {
|
states[msg.Sender] = map[config.State]struct{}{}
|
||||||
states[state] = struct{}{}
|
for _, state := range parseOutStates([]byte(msg.Content)) {
|
||||||
|
states[msg.Sender][state] = struct{}{}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
setNewStates(states)
|
setNewStates(states)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func setNewStates(states map[config.State]struct{}) {
|
func setNewStates(states map[string]map[config.State]struct{}) {
|
||||||
if len(states) == 0 {
|
if len(states) == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
conf := *config.Get()
|
||||||
|
changed := map[string][]config.State{}
|
||||||
|
for client, clientStates := range states {
|
||||||
newstates := []config.State{}
|
newstates := []config.State{}
|
||||||
for k := range states {
|
for k := range clientStates {
|
||||||
newstates = append(newstates, k)
|
newstates = append(newstates, k)
|
||||||
}
|
}
|
||||||
sort.Slice(newstates, func(i, j int) bool {
|
sort.Slice(newstates, func(i, j int) bool {
|
||||||
return newstates[i] < newstates[j]
|
return newstates[i] < newstates[j]
|
||||||
})
|
})
|
||||||
conf := *config.Get()
|
clientconf := conf.Clients[client]
|
||||||
if fmt.Sprint(newstates) == fmt.Sprint(conf.States) {
|
if fmt.Sprint(newstates) == fmt.Sprint(clientconf.States) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
clientconf.States = newstates
|
||||||
|
conf.Clients[client] = clientconf
|
||||||
|
changed[client] = newstates
|
||||||
|
}
|
||||||
|
if len(changed) == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
conf.States = newstates
|
|
||||||
log.Printf("updating config new states: %+v", conf)
|
log.Printf("updating config new states: %+v", conf)
|
||||||
config.Set(conf)
|
config.Set(conf)
|
||||||
if err := sendNewStates(conf.States); err != nil {
|
for client, states := range changed {
|
||||||
log.Printf("failed to send new states %+v: %v", conf.States, err)
|
if err := sendNewStates(client, states); err != nil {
|
||||||
|
log.Printf("failed to send new states %s/%+v: %v", client, states, err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -160,7 +172,7 @@ func once() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func getJobs() ([]broker.Job, error) {
|
func getJobs() ([]broker.Job, error) {
|
||||||
states := config.Get().States
|
states := config.AllStates()
|
||||||
ntg := broker.NewNTGVision()
|
ntg := broker.NewNTGVision()
|
||||||
if config.Get().Brokers.NTG.Mock {
|
if config.Get().Brokers.NTG.Mock {
|
||||||
ntg = ntg.WithMock()
|
ntg = ntg.WithMock()
|
||||||
|
|
@ -200,7 +212,7 @@ func sendJob(job broker.Job) error {
|
||||||
return sender.Send(job.FormatMultilineText())
|
return sender.Send(job.FormatMultilineText())
|
||||||
}
|
}
|
||||||
|
|
||||||
func sendNewStates(states []config.State) error {
|
func sendNewStates(client string, states []config.State) error {
|
||||||
sender := message.NewMatrix()
|
sender := message.NewMatrix()
|
||||||
return sender.Send(fmt.Sprintf("now searching for loads from: %+v", states))
|
return sender.Send(fmt.Sprintf("%s: now searching for loads from: %+v", client, states))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,6 @@ type Matrix struct {
|
||||||
username string
|
username string
|
||||||
token string
|
token string
|
||||||
room string
|
room string
|
||||||
client string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewMatrix() Matrix {
|
func NewMatrix() Matrix {
|
||||||
|
|
@ -24,7 +23,6 @@ func NewMatrix() Matrix {
|
||||||
token: conf.Token,
|
token: conf.Token,
|
||||||
room: conf.Room,
|
room: conf.Room,
|
||||||
mock: conf.Mock,
|
mock: conf.Mock,
|
||||||
client: conf.Client,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -32,32 +30,51 @@ func (m Matrix) getclient() (*gomatrix.Client, error) {
|
||||||
return gomatrix.NewClient(m.homeserver, m.username, m.token)
|
return gomatrix.NewClient(m.homeserver, m.username, m.token)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m Matrix) Receive() ([]string, error) {
|
func (m Matrix) Receive() ([]Message, error) {
|
||||||
if m.mock {
|
if m.mock {
|
||||||
log.Printf("matrix.Receive()")
|
log.Printf("matrix.Receive()")
|
||||||
return []string{"FL, GA, NC"}, nil
|
messages := make([]Message, 0)
|
||||||
|
for k := range config.Get().Clients {
|
||||||
|
messages = append(messages, Message{Sender: k, Content: "OH"})
|
||||||
|
}
|
||||||
|
return messages, nil
|
||||||
|
}
|
||||||
|
clients := config.Get().Clients
|
||||||
|
matrixIDs := map[string]struct{}{}
|
||||||
|
for k := range clients {
|
||||||
|
matrixIDs[clients[k].IDs.Matrix] = struct{}{}
|
||||||
|
}
|
||||||
|
if len(matrixIDs) == 0 {
|
||||||
|
return nil, nil
|
||||||
}
|
}
|
||||||
c, err := m.getclient()
|
c, err := m.getclient()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
messages := make([]string, 0)
|
messages := make([]Message, 0)
|
||||||
result, err := c.Messages(m.room, "", "", 'b', 50)
|
result, err := c.Messages(m.room, "", "", 'b', 50)
|
||||||
for _, event := range result.Chunk {
|
for _, event := range result.Chunk {
|
||||||
if event.Sender != m.client {
|
if _, ok := matrixIDs[event.Sender]; !ok {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
switch event.Type {
|
switch event.Type {
|
||||||
case "m.room.message":
|
case "m.room.message":
|
||||||
b, ok := event.Body()
|
b, ok := event.Body()
|
||||||
if ok {
|
if ok {
|
||||||
messages = append(messages, b)
|
messages = append(messages, Message{Sender: event.Sender, Content: b})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
for i := range messages {
|
||||||
|
for k, v := range config.Get().Clients {
|
||||||
|
if v.IDs.Matrix == messages[i].Sender {
|
||||||
|
messages[i].Sender = k
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return messages, nil
|
return messages, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,5 +2,10 @@ package message
|
||||||
|
|
||||||
type Sender interface {
|
type Sender interface {
|
||||||
Send(string) error
|
Send(string) error
|
||||||
Receive() ([]string, error)
|
Receive() ([]Message, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type Message struct {
|
||||||
|
Sender string
|
||||||
|
Content string
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,7 @@
|
||||||
todo:
|
todo:
|
||||||
- modify old items once no longer available
|
|
||||||
- many users -> 1 ntg query
|
|
||||||
- accept after date
|
- accept after date
|
||||||
- "caleb: my-usual-stuff" to alias
|
- modify old items once no longer available; drop stale jobs good candidate but requires new matrix interaction
|
||||||
|
- "caleb: commands: args"
|
||||||
- rate LIMIT
|
- rate LIMIT
|
||||||
- more than NTG
|
- more than NTG
|
||||||
- accept pause commands
|
- accept pause commands
|
||||||
|
|
@ -16,6 +15,8 @@ todo:
|
||||||
- accept states via element for one system
|
- accept states via element for one system
|
||||||
- set up copy for caleb, broc
|
- set up copy for caleb, broc
|
||||||
done:
|
done:
|
||||||
|
- many users -> 1 ntg query
|
||||||
|
- multi client
|
||||||
- rm email
|
- rm email
|
||||||
- send matrix msg on config change
|
- send matrix msg on config change
|
||||||
- setup pa on element
|
- setup pa on element
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue