From 6d527a19b3560bdf7887ee3ff38bb17aa82bc7bd Mon Sep 17 00:00:00 2001 From: Glyn Owen Hanmer <1295698+glynternet@users.noreply.github.com> Date: Mon, 11 Jun 2018 22:57:02 +0200 Subject: [PATCH] oscli metro command --- cmd/oscli/cmd/generate.go | 25 +++++-------- cmd/oscli/cmd/metro.go | 78 +++++++++++++++++++++++++++++++++++++++ cmd/oscli/cmd/root.go | 26 ++++++++++++- cmd/oscli/main.go | 3 +- 4 files changed, 115 insertions(+), 17 deletions(-) create mode 100644 cmd/oscli/cmd/metro.go diff --git a/cmd/oscli/cmd/generate.go b/cmd/oscli/cmd/generate.go index eb0180f..9686021 100644 --- a/cmd/oscli/cmd/generate.go +++ b/cmd/oscli/cmd/generate.go @@ -3,7 +3,6 @@ package cmd import ( "fmt" "log" - "net" "github.com/glynternet/oscli/internal" "github.com/glynternet/oscli/models" @@ -21,33 +20,24 @@ const ( ) var cmdOSCGen = &cobra.Command{ - Use: "generate", + Use: "generate [ADDRESS] [MESSAGE]...", Short: "generate a stream of osc messages", Long: `generate a stream of osc messages Generate an osc signal with values ranging from 0 to 1 as a sin wave. The messages will be sent to the given address.`, + Args: cobra.MinimumNArgs(2), RunE: func(cmd *cobra.Command, args []string) error { - if len(args) == 0 { - return errors.New("arguments required to form OSC message") - } msgAddr, err := internal.CleanAddress(args[0]) if err != nil { return errors.Wrap(err, "parsing OSC message address") } - host, err := internal.GetRemoteHost( - viper.GetBool(keyLocal), - viper.GetString(keyRemoteHost), - ) + host, err := initRemoteHost() if err != nil { - log.Fatal(errors.Wrap(err, "getting remote host")) + return errors.Wrap(err, "initialising host") } - _, err = net.LookupHost(host) - if err != nil { - log.Fatal(errors.Wrapf(err, "looking up %s host %s", keyRemoteHost, host)) - } client := osc.NewClient( host, viper.GetInt(keyRemotePort), @@ -61,7 +51,11 @@ The messages will be sent to the given address.`, var staticArgs []interface{} if len(args) > 0 { for _, arg := range args[1:] { - staticArgs = append(staticArgs, arg) + a, err := osc2.Parse(arg) + if err != nil { + return errors.Wrapf(err, "parsing arg '%s' as value", arg) + } + staticArgs = append(staticArgs, a) } } @@ -75,6 +69,7 @@ The messages will be sent to the given address.`, err := client.Send(msg) if err != nil { log.Print(errors.Wrap(err, "sending message to client")) + continue } log.Printf("Message (%+v) sent to client at %s:%d", msg, client.IP(), client.Port()) } diff --git a/cmd/oscli/cmd/metro.go b/cmd/oscli/cmd/metro.go new file mode 100644 index 0000000..5badb26 --- /dev/null +++ b/cmd/oscli/cmd/metro.go @@ -0,0 +1,78 @@ +package cmd + +import ( + "fmt" + "log" + + "github.com/glynternet/oscli/internal" + osc2 "github.com/glynternet/oscli/pkg/osc" + "github.com/glynternet/oscli/pkg/wave" + "github.com/hypebeast/go-osc/osc" + "github.com/pkg/errors" + "github.com/spf13/cobra" + "github.com/spf13/viper" +) + +var cmdMetro = &cobra.Command{ + Use: "metro [ADDRESS] [MESSAGE]...", + Short: "generate a ticker of the same OSC message", + Args: cobra.MinimumNArgs(2), + RunE: func(cmd *cobra.Command, args []string) error { + msgAddr, err := internal.CleanAddress(args[0]) + if err != nil { + return errors.Wrap(err, "parsing OSC message address") + } + + host, err := initRemoteHost() + if err != nil { + return errors.Wrap(err, "initialising host") + } + + client := osc.NewClient( + host, + viper.GetInt(keyRemotePort), + ) + + msgFreq := viper.GetFloat64(keyMsgFrequency) + if msgFreq <= 0 { + log.Fatal(fmt.Errorf("%s must be positive, received %f", keyMsgFrequency, msgFreq)) + } + + var staticArgs []interface{} + if len(args) > 0 { + for _, arg := range args[1:] { + a, err := osc2.Parse(arg) + if err != nil { + return errors.Wrapf(err, "parsing arg '%s' as value", arg) + } + staticArgs = append(staticArgs, a) + } + } + + genFn := func() *osc.Message { + return osc.NewMessage(msgAddr, staticArgs...) + } + + // TODO: the second argument to this could be a ticker or something? + msgCh := osc2.Generate(genFn, wave.Frequency(msgFreq).Period()) + for { + select { + case msg := <-msgCh: + err := client.Send(msg) + if err != nil { + log.Print(errors.Wrap(err, "sending message to client")) + continue + } + log.Printf("Message (%+v) sent to client at %s:%d", msg, client.IP(), client.Port()) + } + } + }, +} + +func init() { + rootCmd.AddCommand(cmdMetro) + err := viper.BindPFlags(cmdMetro.Flags()) + if err != nil { + log.Fatal(err) + } +} diff --git a/cmd/oscli/cmd/root.go b/cmd/oscli/cmd/root.go index 3210d8c..436093f 100644 --- a/cmd/oscli/cmd/root.go +++ b/cmd/oscli/cmd/root.go @@ -2,8 +2,10 @@ package cmd import ( "log" + "net" "strings" + "github.com/glynternet/oscli/internal" "github.com/pkg/errors" "github.com/spf13/cobra" "github.com/spf13/viper" @@ -15,7 +17,7 @@ func Execute() error { } const ( - appName = "osc" + appName = "oscli" keyListenHost = "listen-host" usageListenHost = "host address to listen on" @@ -43,6 +45,9 @@ func init() { rootCmd.PersistentFlags().Uint(keyListenPort, 9000, usageListenPort) rootCmd.PersistentFlags().StringP(keyRemoteHost, "r", "", usageRemoteHost) rootCmd.PersistentFlags().Uint(keyRemotePort, 9000, usageRemotePort) + + rootCmd.PersistentFlags().Float64P(keyMsgFrequency, "m", 25, "frequency to send messages at") + err := viper.BindPFlags(rootCmd.PersistentFlags()) if err != nil { log.Fatal(errors.Wrap(err, "binding PFlags")) @@ -54,3 +59,22 @@ func initConfig() { viper.AutomaticEnv() // read in environment variables that match viper.SetEnvKeyReplacer(strings.NewReplacer("-", "_")) } + +func initRemoteHost() (string, error) { + host, err := internal.GetRemoteHost( + viper.GetBool(keyLocal), + viper.GetString(keyRemoteHost), + ) + if err != nil { + return "", errors.Wrap(err, "getting remote host") + } + + return host, errors.Wrap(verifyHost(host), "verifying host") +} + +// verifyHost checks that the given string can be resolved through the current +// DNS/networking state +func verifyHost(host string) error { + _, err := net.LookupHost(host) + return errors.Wrapf(err, "looking up %s host %s", keyRemoteHost, host) +} diff --git a/cmd/oscli/main.go b/cmd/oscli/main.go index 7507ce8..9a40853 100644 --- a/cmd/oscli/main.go +++ b/cmd/oscli/main.go @@ -17,7 +17,7 @@ func main() { } const ( - appName = "osc" + appName = "oscli" keyListenHost = "listen-host" usageListenHost = "host address to listen on" @@ -40,6 +40,7 @@ var rootCmd = &cobra.Command{ } func init() { + cobra.OnInitialize(initConfig) rootCmd.PersistentFlags().BoolP(keyLocal, "l", false, usageLocal) rootCmd.PersistentFlags().String(keyListenHost, "", usageListenHost) rootCmd.PersistentFlags().Uint(keyListenPort, 9000, usageListenPort)