コード例 #1
0
ファイル: service.go プロジェクト: sarifsystems/sarif
func (s *Service) handleEventLast(msg sarif.Message) {
	filter := make(map[string]interface{})
	if err := msg.DecodePayload(&filter); err != nil {
		s.ReplyBadRequest(msg, err)
		return
	}

	s.Log("debug", "get last by filter:", filter)
	var events []Event
	err := s.Store.Scan("events", store.Scan{
		Reverse: true,
		Only:    "values",
		Filter:  filter,
		Limit:   1,
	}, &events)
	if err != nil {
		s.ReplyInternalError(msg, err)
	}
	if len(events) == 0 {
		s.Reply(msg, MessageEventNotFound)
		return
	}
	s.Log("debug", "last - found", events)

	reply := sarif.Message{Action: "event/found"}
	if err := reply.EncodePayload(events[0]); err != nil {
		s.ReplyInternalError(msg, err)
		return
	}
	reply.Text = events[0].String()

	s.Reply(msg, reply)
}
コード例 #2
0
ファイル: regular.go プロジェクト: sarifsystems/sarif
func (r *SentenceRule) Parse(s string) (sarif.Message, bool) {
	msg := sarif.Message{}
	match := r.Regexp.FindStringSubmatch(s)
	if match == nil {
		return msg, false
	}

	msg.Action = r.Action
	p := make(map[string]string)
	for i, field := range r.Regexp.SubexpNames() {
		if field == "" {
			continue
		}
		v := TrimQuotes(match[i])
		if field == "text" {
			msg.Text = strings.TrimSpace(msg.Text + " " + v)
			continue
		}
		if field == "_action" {
			msg.Action = strings.TrimSpace(msg.Action + "/" + v)
			continue
		}
		p[field] = v
	}
	if len(p) > 0 {
		msg.EncodePayload(p)
	}
	return msg, true
}
コード例 #3
0
ファイル: cmd_updown.go プロジェクト: sarifsystems/sarif
func (app *App) Up() {
	if flag.NArg() <= 1 {
		app.Log.Fatal("Please specify an action to send to.")
	}
	action := flag.Arg(1)

	in, err := ioutil.ReadAll(os.Stdin)
	if err != nil {
		app.Log.Fatal(err)
	}

	msg := sarif.Message{
		Action: action,
	}

	pl := ContentPayload{
		Content: content.PutData(in),
	}
	if strings.HasPrefix(pl.Content.Type, "text/") {
		msg.Text = string(in)
	}
	if err := msg.EncodePayload(pl); err != nil {
		app.Log.Fatal(err)
	}

	msg, ok := <-app.Client.Request(msg)
	if !ok {
		app.Log.Fatal("No reply received.")
	}
	fmt.Println(strings.TrimSpace(msg.Text))
}
コード例 #4
0
ファイル: conversation.go プロジェクト: sarifsystems/sarif
func (cv *Conversation) answer(a *schema.Action, text string) (sarif.Message, bool) {
	reply := sarif.Message{
		Action: a.Reply,
		Text:   text,
	}
	if text == ".cancel" || text == "cancel" || strings.HasPrefix(text, "cancel ") {
		return reply, false
	}

	t := a.SchemaType
	if t == "ConfirmAction" || t == "DeleteAction" || t == "CancelAction" {
		ctx := &natural.Context{Text: text, ExpectedReply: "affirmative"}
		r, err := cv.service.Parse(ctx)
		if err != nil || len(r.Intents) == 0 {
			return reply, false
		}
		if r.Intents[0].Type == "neg" {
			reply.Action = a.ReplyNegative
			return reply, reply.Action != ""
		}
	}

	if a.Payload != nil {
		reply.EncodePayload(a.Payload)
	}
	return reply, true
}
コード例 #5
0
ファイル: message_schema.go プロジェクト: sarifsystems/sarif
func (r *MessageSchema) Apply(vars []*Var) sarif.Message {
	msg := sarif.Message{}
	msg.Action = r.Action
	pl := make(map[string]string)
	sort.Sort(sort.Reverse(byWeight(vars)))

	for _, v := range vars {
		switch v.Name {
		case "_action":
			msg.Action = v.Value
		case "text":
			msg.Text = v.Value
		case "to":
			fallthrough
		case "that":
			if msg.Text == "" {
				msg.Text = v.Value
			}
		default:
			if _, ok := r.Fields[v.Name]; ok {
				pl[v.Name] = v.Value
			}
		}
	}
	if len(vars) > 0 {
		msg.EncodePayload(&pl)
	}
	return msg
}
コード例 #6
0
ファイル: util.go プロジェクト: sarifsystems/sarif
func tableToMessage(L *lua.LState, t *lua.LTable) sarif.Message {
	msg := sarif.Message{}
	msg.Version = tableGetString(t, "sarif")
	msg.Id = tableGetString(t, "id")
	msg.Action = tableGetString(t, "action")
	msg.Source = tableGetString(t, "src")
	msg.Destination = tableGetString(t, "dest")
	msg.CorrId = tableGetString(t, "corr")
	msg.Text = tableGetString(t, "text")

	p := luareflect.DecodeToBasic(t.RawGetH(lua.LString("p")))
	msg.EncodePayload(p)
	return msg
}
コード例 #7
0
ファイル: service.go プロジェクト: sarifsystems/sarif
func (s *Service) handleEventNew(msg sarif.Message) {
	isTargeted := msg.IsAction("event/new")

	var e Event
	e.Text = msg.Text
	e.Time = time.Now()
	e.Value = 1
	if s, v, ok := parseDataFromAction(msg.Action, "event/new"); ok {
		e.Action, e.Value = s, v
	}
	if err := msg.DecodePayload(&e); err != nil && isTargeted {
		s.ReplyBadRequest(msg, err)
		return
	}

	if err := msg.DecodePayload(&e.Meta); err != nil {
		s.ReplyBadRequest(msg, err)
		return
	}
	if e.Time.IsZero() {
		e.Time = time.Now()
	}

	if _, err := s.Store.Put(e.Key(), &e); err != nil {
		s.Log("err/internal", "could not store finished task: "+err.Error())
		return
	}

	if isTargeted {
		reply := sarif.Message{Action: "event/created"}
		if err := reply.EncodePayload(e); err != nil {
			s.ReplyInternalError(msg, err)
			return
		}
		reply.Text = "New event: " + e.String()
		s.Reply(msg, reply)
	}
}
コード例 #8
0
ファイル: service.go プロジェクト: sarifsystems/sarif
func (s *Service) handleGeofenceCreate(msg sarif.Message) {
	var g Geofence
	if err := msg.DecodePayload(&g); err != nil {
		s.ReplyBadRequest(msg, err)
		return
	}

	if g.Address != "" {
		geo, err := Geocode(g.Address)
		if err != nil {
			s.ReplyBadRequest(msg, err)
			return
		}
		if len(geo) == 0 {
			s.Publish(msg.Reply(MsgAddressNotFound))
			return
		}
		g.BoundingBox = BoundingBox(geo[0].BoundingBox)
	}
	if g.Name == "" {
		g.Name = sarif.GenerateId()
	}
	g.GeohashMin = EncodeGeohash(g.BoundingBox.LatMin, g.BoundingBox.LngMin, 12)
	g.GeohashMax = EncodeGeohash(g.BoundingBox.LatMax, g.BoundingBox.LngMax, 12)

	if _, err := s.Store.Put(g.Key(), &g); err != nil {
		s.ReplyInternalError(msg, err)
	}

	reply := sarif.Message{Action: "location/fence/created"}
	if err := reply.EncodePayload(g); err != nil {
		s.ReplyInternalError(msg, err)
		return
	}
	reply.Text = "Geofence '" + g.Name + "' created."
	s.Publish(reply)
}
コード例 #9
0
ファイル: parser.go プロジェクト: sarifsystems/sarif
func (p *Parser) InventMessageForMeaning(action string, m *Meaning) (sarif.Message, error) {
	msg := sarif.Message{}

	if action != "" {
		msg.Action += "/" + action
	}
	if m.Subject != "" {
		msg.Action += "/" + m.Subject
	}
	if m.Predicate != "" {
		msg.Action += "/" + m.Predicate
	}
	if m.Object != "" {
		msg.Action += "/" + m.Object
	}

	msg.Action = strings.Trim(msg.Action, "/")
	pl := make(map[string]string)
	for _, v := range m.Vars {
		pl[v.Name] = v.Value
	}
	msg.EncodePayload(pl)
	return msg, nil
}
コード例 #10
0
ファイル: web.go プロジェクト: sarifsystems/sarif
func (s *Server) handleRestPublish(w http.ResponseWriter, req *http.Request) {
	defer req.Body.Close()
	s.Client.Log("debug", "new REST request: "+req.URL.Path)

	// Parse form values.
	if err := req.ParseForm(); err != nil {
		s.Client.Log("warn", "REST bad request: "+err.Error())
		w.WriteHeader(400)
		fmt.Fprintln(w, "Bad request:", err)
		return
	}

	// Check authentication.
	name := s.checkAuthentication(req)
	if name == "" {
		w.WriteHeader(401)
		fmt.Fprintln(w, "Not authorized")
		s.Client.Log("info", "authentication failed for "+req.RemoteAddr)
		return
	}
	s.Client.Log("info", "authenticated "+req.RemoteAddr+" for "+name)
	client := s.getApiClientByName(name)

	// Create message from form values.
	msg := sarif.Message{
		Id:     sarif.GenerateId(),
		Source: name,
	}
	if strings.HasPrefix(req.URL.Path, REST_URL) {
		msg.Action = strings.TrimPrefix(req.URL.Path, REST_URL)
	}
	pl := make(map[string]interface{})
	for k, v := range req.Form {
		if k == "authtoken" {
			continue
		}
		if k == "_device" {
			msg.Destination = v[0]
		} else if k == "text" {
			msg.Text = strings.Join(v, "\n")
		} else if len(v) == 1 {
			pl[k] = parseValue(v[0])
		} else if k == "_device" {
			pl[k] = v
		}
	}
	_ = msg.EncodePayload(pl)

	if !s.clientIsAllowed(name, msg) {
		w.WriteHeader(401)
		fmt.Fprintf(w, "'%s' is not authorized to publish '%s'", name, msg.Action)
		s.Client.Log("warn", "REST '"+name+"' is not authorized to publish on "+msg.Action)
		return
	}

	// Publish message.
	if err := client.Publish(msg); err != nil {
		s.Client.Log("warn", "REST bad request: "+err.Error())
		w.WriteHeader(400)
		fmt.Fprintln(w, "Bad Request:", err)
		return
	}
	w.Write([]byte(msg.Id))
}
コード例 #11
0
ファイル: natural.go プロジェクト: sarifsystems/sarif
func ParseSimple(text string) (sarif.Message, bool) {
	msg := sarif.Message{}

	// Raw JSON message
	if strings.HasPrefix(text, "{") {
		if err := json.Unmarshal([]byte(text), &msg); err == nil {
			return msg, true
		}
	}

	if strings.HasPrefix(text, "sarif://") {
		if msg, err := sarif.ConvertURL(text); err == nil {
			return msg, true
		}
	}

	if strings.HasPrefix(text, ".") || strings.HasPrefix(text, "/") {
		text = strings.TrimLeft(text, "./ ")
		parts, _ := SplitQuoted(text, " ")
		if parts[0] == "" {
			return msg, false
		}
		msg.Action = parts[0]

		msg.Text = ""
		payload := make(map[string]interface{}, 0)
		for _, part := range parts[1:] {
			keyval, _ := SplitQuoted(part, "=")
			if len(keyval) == 1 {
				if msg.Text != "" {
					msg.Text += " "
				}
				msg.Text += TrimQuotes(keyval[0])
				continue
			}

			k := TrimQuotes(keyval[0])
			vtext := strings.Join(keyval[1:], "=")
			quoted := strings.ContainsAny(vtext, "\"`")
			vtext = TrimQuotes(vtext)
			var v interface{} = vtext
			if !quoted {
				v = ParseValue(vtext)
			}
			switch k {
			case "text":
				msg.Text = vtext
			case "device":
				fallthrough
			case "destination":
				msg.Destination = vtext
			default:
				payload[k] = v
			}
		}
		if len(payload) > 0 {
			msg.EncodePayload(payload)
		}
		return msg, true
	}

	return msg, false
}