Form support for transport Ad-Hoc commands with arguments
This commit is contained in:
parent
e3a5191905
commit
21dc5fa6c6
2
Makefile
2
Makefile
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
COMMIT := $(shell git rev-parse --short HEAD)
|
COMMIT := $(shell git rev-parse --short HEAD)
|
||||||
TD_COMMIT := "5bbfc1cf5dab94f82e02f3430ded7241d4653551"
|
TD_COMMIT := "5bbfc1cf5dab94f82e02f3430ded7241d4653551"
|
||||||
VERSION := "v1.9.1"
|
VERSION := "v1.10.0-dev"
|
||||||
MAKEOPTS := "-j4"
|
MAKEOPTS := "-j4"
|
||||||
|
|
||||||
all:
|
all:
|
||||||
|
|
|
@ -16,7 +16,7 @@ import (
|
||||||
goxmpp "gosrc.io/xmpp"
|
goxmpp "gosrc.io/xmpp"
|
||||||
)
|
)
|
||||||
|
|
||||||
var version string = "1.9.1"
|
var version string = "1.10.0-dev"
|
||||||
var commit string
|
var commit string
|
||||||
|
|
||||||
var sm *goxmpp.StreamManager
|
var sm *goxmpp.StreamManager
|
||||||
|
|
|
@ -107,9 +107,9 @@ var transportConfigurationOptions = map[string]configurationOption{
|
||||||
}
|
}
|
||||||
|
|
||||||
type command struct {
|
type command struct {
|
||||||
requiredArgs int
|
RequiredArgs int
|
||||||
arguments []string
|
Arguments []string
|
||||||
description string
|
Description string
|
||||||
}
|
}
|
||||||
type configurationOption struct {
|
type configurationOption struct {
|
||||||
arguments string
|
arguments string
|
||||||
|
@ -138,14 +138,21 @@ func GetCommands(typ CommandType) map[string]command {
|
||||||
return commandMap
|
return commandMap
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetCommand obtains one command
|
||||||
|
func GetCommand(typ CommandType, cmd string) (command, bool) {
|
||||||
|
commands := GetCommands(typ)
|
||||||
|
command, ok := commands[cmd]
|
||||||
|
return command, ok
|
||||||
|
}
|
||||||
|
|
||||||
// CommandToHelpString builds a text description of a command
|
// CommandToHelpString builds a text description of a command
|
||||||
func CommandToHelpString(name string, cmd command) string {
|
func CommandToHelpString(name string, cmd command) string {
|
||||||
var str strings.Builder
|
var str strings.Builder
|
||||||
|
|
||||||
str.WriteString("/")
|
str.WriteString("/")
|
||||||
str.WriteString(name)
|
str.WriteString(name)
|
||||||
for i, arg := range cmd.arguments {
|
for i, arg := range cmd.Arguments {
|
||||||
optional := i >= cmd.requiredArgs
|
optional := i >= cmd.RequiredArgs
|
||||||
str.WriteString(" ")
|
str.WriteString(" ")
|
||||||
if optional {
|
if optional {
|
||||||
str.WriteString("[")
|
str.WriteString("[")
|
||||||
|
@ -156,7 +163,7 @@ func CommandToHelpString(name string, cmd command) string {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
str.WriteString(" — ")
|
str.WriteString(" — ")
|
||||||
str.WriteString(cmd.description)
|
str.WriteString(cmd.Description)
|
||||||
|
|
||||||
return str.String()
|
return str.String()
|
||||||
}
|
}
|
||||||
|
@ -267,7 +274,7 @@ func (c *Client) ProcessTransportCommand(cmdline string, resource string) string
|
||||||
if !ok {
|
if !ok {
|
||||||
return "Unknown command"
|
return "Unknown command"
|
||||||
}
|
}
|
||||||
if len(args) < command.requiredArgs {
|
if len(args) < command.RequiredArgs {
|
||||||
return notEnoughArguments
|
return notEnoughArguments
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"io"
|
"io"
|
||||||
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
@ -701,22 +702,80 @@ func handleSetQueryCommand(s xmpp.Sender, iq *stanza.IQ, command *stanza.Command
|
||||||
|
|
||||||
log.Debugf("command: %#v", command)
|
log.Debugf("command: %#v", command)
|
||||||
|
|
||||||
if command.Action == "" || command.Action == stanza.CommandActionExecute {
|
|
||||||
_, ok := toToID(iq.To)
|
|
||||||
if !ok {
|
|
||||||
bare, resource, ok := gateway.SplitJID(iq.From)
|
bare, resource, ok := gateway.SplitJID(iq.From)
|
||||||
if !ok {
|
if !ok {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var cmdString string
|
||||||
|
if command.Action == "" || command.Action == stanza.CommandActionExecute {
|
||||||
|
_, ok := toToID(iq.To)
|
||||||
|
if !ok {
|
||||||
|
cmd, ok := telegram.GetCommand(telegram.CommandTypeTransport, command.Node)
|
||||||
|
if ok && cmd.RequiredArgs > 0 {
|
||||||
|
var fields []*stanza.Field
|
||||||
|
for i, arg := range cmd.Arguments {
|
||||||
|
fields = append(fields, &stanza.Field{
|
||||||
|
Var: strconv.FormatInt(int64(i), 10),
|
||||||
|
Label: arg,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
answer.Payload = &stanza.Command{
|
||||||
|
SessionId: command.Node,
|
||||||
|
Node: command.Node,
|
||||||
|
Status: stanza.CommandStatusExecuting,
|
||||||
|
CommandElement: &stanza.Form{
|
||||||
|
Title: command.Node,
|
||||||
|
Instructions: []string{cmd.Description},
|
||||||
|
Fields: fields,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cmdString = "/" + command.Node
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if command.Action == stanza.CommandActionComplete {
|
||||||
|
_, ok := toToID(iq.To)
|
||||||
|
if !ok {
|
||||||
|
form, ok := command.CommandElement.(*stanza.Form)
|
||||||
|
if ok {
|
||||||
|
// just for the case the client messed the order somehow
|
||||||
|
sort.Slice(form.Fields, func(i int, j int) bool {
|
||||||
|
iField := form.Fields[i]
|
||||||
|
jField := form.Fields[j]
|
||||||
|
if iField != nil && jField != nil {
|
||||||
|
ii, iErr := strconv.ParseInt(iField.Var, 10, 64)
|
||||||
|
ji, jErr := strconv.ParseInt(jField.Var, 10, 64)
|
||||||
|
return iErr == nil && jErr == nil && ii < ji
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
})
|
||||||
|
|
||||||
|
var cmd strings.Builder
|
||||||
|
cmd.WriteString("/")
|
||||||
|
cmd.WriteString(command.Node)
|
||||||
|
for _, field := range form.Fields {
|
||||||
|
cmd.WriteString(" ")
|
||||||
|
if len(field.ValuesList) > 0 {
|
||||||
|
cmd.WriteString(field.ValuesList[0])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cmdString = cmd.String()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if cmdString != "" {
|
||||||
session, ok := sessions[bare]
|
session, ok := sessions[bare]
|
||||||
if !ok {
|
if !ok {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
response := session.ProcessTransportCommand("/" + command.Node, resource)
|
response := session.ProcessTransportCommand(cmdString, resource)
|
||||||
|
|
||||||
answer.Payload = &stanza.Command{
|
answer.Payload = &stanza.Command{
|
||||||
|
SessionId: command.Node,
|
||||||
Node: command.Node,
|
Node: command.Node,
|
||||||
Status: stanza.CommandStatusCompleted,
|
Status: stanza.CommandStatusCompleted,
|
||||||
CommandElement: &stanza.Note{
|
CommandElement: &stanza.Note{
|
||||||
|
@ -724,10 +783,10 @@ func handleSetQueryCommand(s xmpp.Sender, iq *stanza.IQ, command *stanza.Command
|
||||||
Type: stanza.CommandNoteTypeInfo,
|
Type: stanza.CommandNoteTypeInfo,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debugf("command response: %#v", answer.Payload)
|
log.Debugf("command response: %#v", answer.Payload)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
func iqAnswerSetError(answer *stanza.IQ, payload *extensions.QueryRegister, code int) {
|
func iqAnswerSetError(answer *stanza.IQ, payload *extensions.QueryRegister, code int) {
|
||||||
answer.Type = stanza.IQTypeError
|
answer.Type = stanza.IQTypeError
|
||||||
|
|
Loading…
Reference in a new issue