diff --git a/internal/module/db-sqlite.go b/internal/module/db-sqlite.go index db83186..0a9ddeb 100644 --- a/internal/module/db-sqlite.go +++ b/internal/module/db-sqlite.go @@ -14,17 +14,6 @@ import ( _ "modernc.org/sqlite" ) -type DbSqlite struct { - config config.ModuleConfig - Dsn string - ctx context.Context - inputHandler common.InputHandler - db *sql.DB - logger *slog.Logger - dbMu sync.Mutex - cancel context.CancelFunc -} - func init() { RegisterModule(ModuleRegistration{ Type: "db.sqlite", @@ -53,6 +42,17 @@ func init() { }) } +type DbSqlite struct { + config config.ModuleConfig + Dsn string + ctx context.Context + inputHandler common.InputHandler + db *sql.DB + logger *slog.Logger + dbMu sync.Mutex + cancel context.CancelFunc +} + func (dbs *DbSqlite) Id() string { return dbs.config.Id } diff --git a/internal/module/http-server.go b/internal/module/http-server.go index 25917e5..96de1d8 100644 --- a/internal/module/http-server.go +++ b/internal/module/http-server.go @@ -16,6 +16,34 @@ import ( "github.com/jwetzell/showbridge-go/internal/processor" ) +func init() { + RegisterModule(ModuleRegistration{ + Type: "http.server", + Title: "HTTP Server", + ParamsSchema: &jsonschema.Schema{ + Type: "object", + Properties: map[string]*jsonschema.Schema{ + "port": { + Title: "Port", + Type: "integer", + Minimum: jsonschema.Ptr[float64](1024), + Maximum: jsonschema.Ptr[float64](65535), + }, + }, + Required: []string{"port"}, + AdditionalProperties: &jsonschema.Schema{Not: &jsonschema.Schema{}}, + }, + New: func(config config.ModuleConfig) (common.Module, error) { + params := config.Params + portNum, err := params.GetInt("port") + if err != nil { + return nil, fmt.Errorf("http.server port error: %w", err) + } + return &HTTPServer{Port: uint16(portNum), config: config, logger: CreateLogger(config)}, nil + }, + }) +} + type HTTPServer struct { config config.ModuleConfig Port uint16 @@ -55,34 +83,6 @@ func (hsrw *HTTPServerResponseWriter) Write(data []byte) (int, error) { return hsrw.ResponseWriter.Write(data) } -func init() { - RegisterModule(ModuleRegistration{ - Type: "http.server", - Title: "HTTP Server", - ParamsSchema: &jsonschema.Schema{ - Type: "object", - Properties: map[string]*jsonschema.Schema{ - "port": { - Title: "Port", - Type: "integer", - Minimum: jsonschema.Ptr[float64](1024), - Maximum: jsonschema.Ptr[float64](65535), - }, - }, - Required: []string{"port"}, - AdditionalProperties: &jsonschema.Schema{Not: &jsonschema.Schema{}}, - }, - New: func(config config.ModuleConfig) (common.Module, error) { - params := config.Params - portNum, err := params.GetInt("port") - if err != nil { - return nil, fmt.Errorf("http.server port error: %w", err) - } - return &HTTPServer{Port: uint16(portNum), config: config, logger: CreateLogger(config)}, nil - }, - }) -} - func (hs *HTTPServer) Id() string { return hs.config.Id } diff --git a/internal/module/midi-input.go b/internal/module/midi-input.go index 55a440f..3e21d9e 100644 --- a/internal/module/midi-input.go +++ b/internal/module/midi-input.go @@ -14,16 +14,6 @@ import ( _ "gitlab.com/gomidi/midi/v2/drivers/rtmididrv" ) -type MIDIInput struct { - config config.ModuleConfig - ctx context.Context - inputHandler common.InputHandler - Port string - logger *slog.Logger - cancel context.CancelFunc - stop func() -} - func init() { RegisterModule(ModuleRegistration{ Type: "midi.input", @@ -51,6 +41,16 @@ func init() { }) } +type MIDIInput struct { + config config.ModuleConfig + ctx context.Context + inputHandler common.InputHandler + Port string + logger *slog.Logger + cancel context.CancelFunc + stop func() +} + func (mi *MIDIInput) Id() string { return mi.config.Id } diff --git a/internal/module/midi-output.go b/internal/module/midi-output.go index 5c60a42..8df6dac 100644 --- a/internal/module/midi-output.go +++ b/internal/module/midi-output.go @@ -16,17 +16,6 @@ import ( _ "gitlab.com/gomidi/midi/v2/drivers/rtmididrv" ) -type MIDIOutput struct { - config config.ModuleConfig - ctx context.Context - inputHandler common.InputHandler - Port string - sendFunc func(midi.Message) error - logger *slog.Logger - cancel context.CancelFunc - sendFuncMu sync.Mutex -} - func init() { RegisterModule(ModuleRegistration{ Type: "midi.output", @@ -55,6 +44,17 @@ func init() { }) } +type MIDIOutput struct { + config config.ModuleConfig + ctx context.Context + inputHandler common.InputHandler + Port string + sendFunc func(midi.Message) error + logger *slog.Logger + cancel context.CancelFunc + sendFuncMu sync.Mutex +} + func (mo *MIDIOutput) Id() string { return mo.config.Id } diff --git a/internal/module/mqtt-client.go b/internal/module/mqtt-client.go index 5fb9f69..eb6146e 100644 --- a/internal/module/mqtt-client.go +++ b/internal/module/mqtt-client.go @@ -14,21 +14,6 @@ import ( "github.com/jwetzell/showbridge-go/internal/config" ) -type MQTTClient struct { - config config.ModuleConfig - ctx context.Context - inputHandler common.InputHandler - Broker string - ClientID string - Topic string - QoS byte - Retained bool - client mqtt.Client - logger *slog.Logger - cancel context.CancelFunc - clientMu sync.Mutex -} - func init() { RegisterModule(ModuleRegistration{ Type: "mqtt.client", @@ -109,6 +94,21 @@ func init() { }) } +type MQTTClient struct { + config config.ModuleConfig + ctx context.Context + inputHandler common.InputHandler + Broker string + ClientID string + Topic string + QoS byte + Retained bool + client mqtt.Client + logger *slog.Logger + cancel context.CancelFunc + clientMu sync.Mutex +} + func (mc *MQTTClient) Id() string { return mc.config.Id } diff --git a/internal/module/nats-client.go b/internal/module/nats-client.go index 8f82dbf..7b46b34 100644 --- a/internal/module/nats-client.go +++ b/internal/module/nats-client.go @@ -12,20 +12,6 @@ import ( "github.com/nats-io/nats.go" ) -type NATSClient struct { - config config.ModuleConfig - ctx context.Context - inputHandler common.InputHandler - URL string - Subject string - client *nats.Conn - logger *slog.Logger - cancel context.CancelFunc - sub *nats.Subscription - subMu sync.Mutex - clientMu sync.Mutex -} - func init() { RegisterModule(ModuleRegistration{ Type: "nats.client", @@ -63,6 +49,20 @@ func init() { }) } +type NATSClient struct { + config config.ModuleConfig + ctx context.Context + inputHandler common.InputHandler + URL string + Subject string + client *nats.Conn + logger *slog.Logger + cancel context.CancelFunc + sub *nats.Subscription + subMu sync.Mutex + clientMu sync.Mutex +} + func (nc *NATSClient) Id() string { return nc.config.Id } diff --git a/internal/module/nats-server.go b/internal/module/nats-server.go index 2a16f94..5aca505 100644 --- a/internal/module/nats-server.go +++ b/internal/module/nats-server.go @@ -16,18 +16,6 @@ import ( "github.com/nats-io/nats-server/v2/server" ) -type NATSServer struct { - config config.ModuleConfig - ctx context.Context - Ip string - Port int - inputHandler common.InputHandler - server *server.Server - logger *slog.Logger - cancel context.CancelFunc - serverMu sync.Mutex -} - func init() { RegisterModule(ModuleRegistration{ Type: "nats.server", @@ -80,6 +68,18 @@ func init() { }) } +type NATSServer struct { + config config.ModuleConfig + ctx context.Context + Ip string + Port int + inputHandler common.InputHandler + server *server.Server + logger *slog.Logger + cancel context.CancelFunc + serverMu sync.Mutex +} + func (ns *NATSServer) Id() string { return ns.config.Id } diff --git a/internal/module/psn-client.go b/internal/module/psn-client.go index 86a9ef7..abfe009 100644 --- a/internal/module/psn-client.go +++ b/internal/module/psn-client.go @@ -12,6 +12,16 @@ import ( "github.com/jwetzell/showbridge-go/internal/config" ) +func init() { + RegisterModule(ModuleRegistration{ + Type: "psn.client", + Title: "PosiStageNet Client", + New: func(config config.ModuleConfig) (common.Module, error) { + return &PSNClient{config: config, decoder: psn.NewDecoder(), logger: CreateLogger(config)}, nil + }, + }) +} + type PSNClient struct { config config.ModuleConfig conn *net.UDPConn @@ -23,16 +33,6 @@ type PSNClient struct { connMu sync.Mutex } -func init() { - RegisterModule(ModuleRegistration{ - Type: "psn.client", - Title: "PosiStageNet Client", - New: func(config config.ModuleConfig) (common.Module, error) { - return &PSNClient{config: config, decoder: psn.NewDecoder(), logger: CreateLogger(config)}, nil - }, - }) -} - func (pc *PSNClient) Id() string { return pc.config.Id } diff --git a/internal/module/redis-client.go b/internal/module/redis-client.go index 5b5f7a4..556b1d0 100644 --- a/internal/module/redis-client.go +++ b/internal/module/redis-client.go @@ -13,18 +13,6 @@ import ( "github.com/redis/go-redis/v9" ) -type RedisClient struct { - config config.ModuleConfig - ctx context.Context - inputHandler common.InputHandler - Host string - Port uint16 - client *redis.Client - logger *slog.Logger - cancel context.CancelFunc - clientMu sync.Mutex -} - func init() { RegisterModule(ModuleRegistration{ Type: "redis.client", @@ -62,6 +50,18 @@ func init() { }) } +type RedisClient struct { + config config.ModuleConfig + ctx context.Context + inputHandler common.InputHandler + Host string + Port uint16 + client *redis.Client + logger *slog.Logger + cancel context.CancelFunc + clientMu sync.Mutex +} + func (rc *RedisClient) Id() string { return rc.config.Id } diff --git a/internal/module/serial-client.go b/internal/module/serial-client.go index e18e611..6910e32 100644 --- a/internal/module/serial-client.go +++ b/internal/module/serial-client.go @@ -17,19 +17,6 @@ import ( "go.bug.st/serial" ) -type SerialClient struct { - config config.ModuleConfig - ctx context.Context - inputHandler common.InputHandler - Port string - Framer framer.Framer - Mode *serial.Mode - port serial.Port - logger *slog.Logger - cancel context.CancelFunc - portMu sync.Mutex -} - func init() { RegisterModule(ModuleRegistration{ Type: "serial.client", @@ -86,6 +73,19 @@ func init() { }) } +type SerialClient struct { + config config.ModuleConfig + ctx context.Context + inputHandler common.InputHandler + Port string + Framer framer.Framer + Mode *serial.Mode + port serial.Port + logger *slog.Logger + cancel context.CancelFunc + portMu sync.Mutex +} + func (sc *SerialClient) Id() string { return sc.config.Id } diff --git a/internal/module/sip-call-server.go b/internal/module/sip-call-server.go index d86ddea..9ea8146 100644 --- a/internal/module/sip-call-server.go +++ b/internal/module/sip-call-server.go @@ -21,31 +21,6 @@ import ( "github.com/jwetzell/showbridge-go/internal/processor" ) -type SIPCallServer struct { - config config.ModuleConfig - ctx context.Context - inputHandler common.InputHandler - IP string - Port int - Transport string - UserAgent string - logger *slog.Logger - cancel context.CancelFunc - ua *sipgo.UserAgent - uaMu sync.Mutex -} - -type SIPCallMessage struct { - To string -} - -type SIPCall struct { - inDialog *diago.DialogServerSession - lock sync.Mutex -} - -type sipCallContextKey string - func init() { RegisterModule(ModuleRegistration{ Type: "sip.call.server", @@ -124,6 +99,31 @@ func init() { }) } +type SIPCallServer struct { + config config.ModuleConfig + ctx context.Context + inputHandler common.InputHandler + IP string + Port int + Transport string + UserAgent string + logger *slog.Logger + cancel context.CancelFunc + ua *sipgo.UserAgent + uaMu sync.Mutex +} + +type SIPCallMessage struct { + To string +} + +type SIPCall struct { + inDialog *diago.DialogServerSession + lock sync.Mutex +} + +type sipCallContextKey string + func (scs *SIPCallServer) Id() string { return scs.config.Id } diff --git a/internal/module/sip-dtmf-server.go b/internal/module/sip-dtmf-server.go index 5036c2f..f4f84df 100644 --- a/internal/module/sip-dtmf-server.go +++ b/internal/module/sip-dtmf-server.go @@ -22,31 +22,6 @@ import ( "github.com/jwetzell/showbridge-go/internal/processor" ) -type SIPDTMFServer struct { - config config.ModuleConfig - ctx context.Context - inputHandler common.InputHandler - IP string - Port int - Transport string - UserAgent string - Separator string - logger *slog.Logger - cancel context.CancelFunc - ua *sipgo.UserAgent - uaMu sync.Mutex -} - -type SIPDTMFMessage struct { - To string - Digits string -} - -type SIPDTMFCall struct { - inDialog *diago.DialogServerSession - lock sync.Mutex -} - func init() { RegisterModule(ModuleRegistration{ Type: "sip.dtmf.server", @@ -144,6 +119,31 @@ func init() { }) } +type SIPDTMFServer struct { + config config.ModuleConfig + ctx context.Context + inputHandler common.InputHandler + IP string + Port int + Transport string + UserAgent string + Separator string + logger *slog.Logger + cancel context.CancelFunc + ua *sipgo.UserAgent + uaMu sync.Mutex +} + +type SIPDTMFMessage struct { + To string + Digits string +} + +type SIPDTMFCall struct { + inDialog *diago.DialogServerSession + lock sync.Mutex +} + func (sds *SIPDTMFServer) Id() string { return sds.config.Id } diff --git a/internal/module/tcp-client.go b/internal/module/tcp-client.go index a41a799..8f63d8b 100644 --- a/internal/module/tcp-client.go +++ b/internal/module/tcp-client.go @@ -15,18 +15,6 @@ import ( "github.com/jwetzell/showbridge-go/internal/framer" ) -type TCPClient struct { - config config.ModuleConfig - framer framer.Framer - conn *net.TCPConn - ctx context.Context - inputHandler common.InputHandler - Addr *net.TCPAddr - logger *slog.Logger - cancel context.CancelFunc - connMu sync.Mutex -} - func init() { RegisterModule(ModuleRegistration{ Type: "net.tcp.client", @@ -85,6 +73,18 @@ func init() { }) } +type TCPClient struct { + config config.ModuleConfig + framer framer.Framer + conn *net.TCPConn + ctx context.Context + inputHandler common.InputHandler + Addr *net.TCPAddr + logger *slog.Logger + cancel context.CancelFunc + connMu sync.Mutex +} + func (tc *TCPClient) Id() string { return tc.config.Id } diff --git a/internal/module/tcp-server.go b/internal/module/tcp-server.go index 88f5cd1..1974db6 100644 --- a/internal/module/tcp-server.go +++ b/internal/module/tcp-server.go @@ -19,21 +19,6 @@ import ( "github.com/jwetzell/showbridge-go/internal/framer" ) -type TCPServer struct { - config config.ModuleConfig - Addr *net.TCPAddr - Framer framer.Framer - ctx context.Context - inputHandler common.InputHandler - wg sync.WaitGroup - connections []*net.TCPConn - connectionsMu sync.RWMutex - logger *slog.Logger - cancel context.CancelFunc - listener *net.TCPListener - listenerMu sync.Mutex -} - func init() { RegisterModule(ModuleRegistration{ Type: "net.tcp.server", @@ -97,6 +82,21 @@ func init() { }) } +type TCPServer struct { + config config.ModuleConfig + Addr *net.TCPAddr + Framer framer.Framer + ctx context.Context + inputHandler common.InputHandler + wg sync.WaitGroup + connections []*net.TCPConn + connectionsMu sync.RWMutex + logger *slog.Logger + cancel context.CancelFunc + listener *net.TCPListener + listenerMu sync.Mutex +} + func (ts *TCPServer) Id() string { return ts.config.Id } diff --git a/internal/module/time-interval.go b/internal/module/time-interval.go index 0bf1204..df29d0a 100644 --- a/internal/module/time-interval.go +++ b/internal/module/time-interval.go @@ -11,16 +11,6 @@ import ( "github.com/jwetzell/showbridge-go/internal/config" ) -type TimeInterval struct { - config config.ModuleConfig - Duration uint32 - ctx context.Context - inputHandler common.InputHandler - ticker *time.Ticker - logger *slog.Logger - cancel context.CancelFunc -} - func init() { RegisterModule(ModuleRegistration{ Type: "time.interval", @@ -49,6 +39,16 @@ func init() { }) } +type TimeInterval struct { + config config.ModuleConfig + Duration uint32 + ctx context.Context + inputHandler common.InputHandler + ticker *time.Ticker + logger *slog.Logger + cancel context.CancelFunc +} + func (i *TimeInterval) Id() string { return i.config.Id } diff --git a/internal/module/time-timer.go b/internal/module/time-timer.go index d466621..1be771b 100644 --- a/internal/module/time-timer.go +++ b/internal/module/time-timer.go @@ -11,16 +11,6 @@ import ( "github.com/jwetzell/showbridge-go/internal/config" ) -type TimeTimer struct { - config config.ModuleConfig - Duration uint32 - ctx context.Context - inputHandler common.InputHandler - timer *time.Timer - logger *slog.Logger - cancel context.CancelFunc -} - func init() { RegisterModule(ModuleRegistration{ Type: "time.timer", @@ -50,6 +40,16 @@ func init() { }) } +type TimeTimer struct { + config config.ModuleConfig + Duration uint32 + ctx context.Context + inputHandler common.InputHandler + timer *time.Timer + logger *slog.Logger + cancel context.CancelFunc +} + func (t *TimeTimer) Id() string { return t.config.Id } diff --git a/internal/module/udp-client.go b/internal/module/udp-client.go index b8471b3..d0b66c7 100644 --- a/internal/module/udp-client.go +++ b/internal/module/udp-client.go @@ -13,18 +13,6 @@ import ( "github.com/jwetzell/showbridge-go/internal/config" ) -type UDPClient struct { - config config.ModuleConfig - Addr *net.UDPAddr - Port uint16 - conn *net.UDPConn - ctx context.Context - inputHandler common.InputHandler - logger *slog.Logger - cancel context.CancelFunc - connMu sync.Mutex -} - func init() { RegisterModule(ModuleRegistration{ Type: "net.udp.client", @@ -67,6 +55,18 @@ func init() { }) } +type UDPClient struct { + config config.ModuleConfig + Addr *net.UDPAddr + Port uint16 + conn *net.UDPConn + ctx context.Context + inputHandler common.InputHandler + logger *slog.Logger + cancel context.CancelFunc + connMu sync.Mutex +} + func (uc *UDPClient) Id() string { return uc.config.Id } diff --git a/internal/module/udp-multicast.go b/internal/module/udp-multicast.go index 4177aab..89103d4 100644 --- a/internal/module/udp-multicast.go +++ b/internal/module/udp-multicast.go @@ -14,17 +14,6 @@ import ( "github.com/jwetzell/showbridge-go/internal/config" ) -type UDPMulticast struct { - config config.ModuleConfig - conn *net.UDPConn - ctx context.Context - inputHandler common.InputHandler - Addr *net.UDPAddr - logger *slog.Logger - cancel context.CancelFunc - connMu sync.Mutex -} - func init() { RegisterModule(ModuleRegistration{ Type: "net.udp.multicast", @@ -67,6 +56,17 @@ func init() { }) } +type UDPMulticast struct { + config config.ModuleConfig + conn *net.UDPConn + ctx context.Context + inputHandler common.InputHandler + Addr *net.UDPAddr + logger *slog.Logger + cancel context.CancelFunc + connMu sync.Mutex +} + func (um *UDPMulticast) Id() string { return um.config.Id } diff --git a/internal/module/udp-server.go b/internal/module/udp-server.go index fbb3650..486adb0 100644 --- a/internal/module/udp-server.go +++ b/internal/module/udp-server.go @@ -15,18 +15,6 @@ import ( "github.com/jwetzell/showbridge-go/internal/config" ) -type UDPServer struct { - Addr *net.UDPAddr - BufferSize int - config config.ModuleConfig - ctx context.Context - inputHandler common.InputHandler - logger *slog.Logger - cancel context.CancelFunc - listener *net.UDPConn - listenerMu sync.Mutex -} - func init() { RegisterModule(ModuleRegistration{ Type: "net.udp.server", @@ -90,6 +78,18 @@ func init() { }) } +type UDPServer struct { + Addr *net.UDPAddr + BufferSize int + config config.ModuleConfig + ctx context.Context + inputHandler common.InputHandler + logger *slog.Logger + cancel context.CancelFunc + listener *net.UDPConn + listenerMu sync.Mutex +} + func (us *UDPServer) Id() string { return us.config.Id } diff --git a/internal/module/websocket-client.go b/internal/module/websocket-client.go index bd3586e..917534d 100644 --- a/internal/module/websocket-client.go +++ b/internal/module/websocket-client.go @@ -16,17 +16,6 @@ import ( "github.com/jwetzell/showbridge-go/internal/config" ) -type WebSocketClient struct { - config config.ModuleConfig - URL url.URL - ctx context.Context - conn *websocket.Conn - inputHandler common.InputHandler - logger *slog.Logger - cancel context.CancelFunc - connMu sync.Mutex -} - func init() { RegisterModule(ModuleRegistration{ Type: "websocket.client", @@ -63,6 +52,17 @@ func init() { }) } +type WebSocketClient struct { + config config.ModuleConfig + URL url.URL + ctx context.Context + conn *websocket.Conn + inputHandler common.InputHandler + logger *slog.Logger + cancel context.CancelFunc + connMu sync.Mutex +} + func (wc *WebSocketClient) Id() string { return wc.config.Id } diff --git a/internal/processor/artnet-packet-decode.go b/internal/processor/artnet-packet-decode.go index 692f422..85c0917 100644 --- a/internal/processor/artnet-packet-decode.go +++ b/internal/processor/artnet-packet-decode.go @@ -9,6 +9,16 @@ import ( "github.com/jwetzell/showbridge-go/internal/config" ) +func init() { + RegisterProcessor(ProcessorRegistration{ + Type: "artnet.packet.decode", + Title: "Decode ArtNet Packet", + New: func(config config.ProcessorConfig) (Processor, error) { + return &ArtNetPacketDecode{config: config}, nil + }, + }) +} + type ArtNetPacketDecode struct { config config.ProcessorConfig } @@ -36,14 +46,4 @@ func (apd *ArtNetPacketDecode) Process(ctx context.Context, wrappedPayload commo func (apd *ArtNetPacketDecode) Type() string { return apd.config.Type -} - -func init() { - RegisterProcessor(ProcessorRegistration{ - Type: "artnet.packet.decode", - Title: "Decode ArtNet Packet", - New: func(config config.ProcessorConfig) (Processor, error) { - return &ArtNetPacketDecode{config: config}, nil - }, - }) -} +} \ No newline at end of file diff --git a/internal/processor/artnet-packet-encode.go b/internal/processor/artnet-packet-encode.go index 1a22ce7..a8cbaf1 100644 --- a/internal/processor/artnet-packet-encode.go +++ b/internal/processor/artnet-packet-encode.go @@ -9,6 +9,16 @@ import ( "github.com/jwetzell/showbridge-go/internal/config" ) +func init() { + RegisterProcessor(ProcessorRegistration{ + Type: "artnet.packet.encode", + Title: "Encode ArtNet Packet", + New: func(config config.ProcessorConfig) (Processor, error) { + return &ArtNetPacketEncode{config: config}, nil + }, + }) +} + type ArtNetPacketEncode struct { config config.ProcessorConfig } @@ -36,13 +46,3 @@ func (ape *ArtNetPacketEncode) Process(ctx context.Context, wrappedPayload commo func (ape *ArtNetPacketEncode) Type() string { return ape.config.Type } - -func init() { - RegisterProcessor(ProcessorRegistration{ - Type: "artnet.packet.encode", - Title: "Encode ArtNet Packet", - New: func(config config.ProcessorConfig) (Processor, error) { - return &ArtNetPacketEncode{config: config}, nil - }, - }) -} diff --git a/internal/processor/db-query.go b/internal/processor/db-query.go index a2b62c8..9c0360a 100644 --- a/internal/processor/db-query.go +++ b/internal/processor/db-query.go @@ -13,6 +13,51 @@ import ( "github.com/jwetzell/showbridge-go/internal/config" ) +func init() { + RegisterProcessor(ProcessorRegistration{ + Type: "db.query", + Title: "Query Database", + ParamsSchema: &jsonschema.Schema{ + Type: "object", + Properties: map[string]*jsonschema.Schema{ + "module": { + Title: "Module ID", + Type: "string", + Description: "ID of the database module to query", + }, + "query": { + Title: "Query", + Type: "string", + Description: "SQL query to execute", + }, + }, + Required: []string{"module", "query"}, + AdditionalProperties: &jsonschema.Schema{Not: &jsonschema.Schema{}}, + }, + New: func(config config.ProcessorConfig) (Processor, error) { + + params := config.Params + + moduleIdString, err := params.GetString("module") + if err != nil { + return nil, fmt.Errorf("db.query module error: %w", err) + } + + queryString, err := params.GetString("query") + if err != nil { + return nil, fmt.Errorf("db.query query error: %w", err) + } + + queryTemplate, err := template.New("query").Parse(queryString) + + if err != nil { + return nil, err + } + return &DbQuery{config: config, ModuleId: moduleIdString, Query: queryTemplate, logger: slog.Default().With("component", "processor", "type", config.Type)}, nil + }, + }) +} + type DbQuery struct { config config.ProcessorConfig ModuleId string @@ -101,48 +146,3 @@ func (dq *DbQuery) Process(ctx context.Context, wrappedPayload common.WrappedPay func (dq *DbQuery) Type() string { return dq.config.Type } - -func init() { - RegisterProcessor(ProcessorRegistration{ - Type: "db.query", - Title: "Query Database", - ParamsSchema: &jsonschema.Schema{ - Type: "object", - Properties: map[string]*jsonschema.Schema{ - "module": { - Title: "Module ID", - Type: "string", - Description: "ID of the database module to query", - }, - "query": { - Title: "Query", - Type: "string", - Description: "SQL query to execute", - }, - }, - Required: []string{"module", "query"}, - AdditionalProperties: &jsonschema.Schema{Not: &jsonschema.Schema{}}, - }, - New: func(config config.ProcessorConfig) (Processor, error) { - - params := config.Params - - moduleIdString, err := params.GetString("module") - if err != nil { - return nil, fmt.Errorf("db.query module error: %w", err) - } - - queryString, err := params.GetString("query") - if err != nil { - return nil, fmt.Errorf("db.query query error: %w", err) - } - - queryTemplate, err := template.New("query").Parse(queryString) - - if err != nil { - return nil, err - } - return &DbQuery{config: config, ModuleId: moduleIdString, Query: queryTemplate, logger: slog.Default().With("component", "processor", "type", config.Type)}, nil - }, - }) -} diff --git a/internal/processor/debug-log.go b/internal/processor/debug-log.go index 6672ff5..6895e11 100644 --- a/internal/processor/debug-log.go +++ b/internal/processor/debug-log.go @@ -9,13 +9,22 @@ import ( "github.com/jwetzell/showbridge-go/internal/config" ) -// TODO(jwetzell): maybe make a more useful logging processor +func init() { + RegisterProcessor(ProcessorRegistration{ + Type: "debug.log", + Title: "Debug Log", + New: func(config config.ProcessorConfig) (Processor, error) { + return &DebugLog{config: config, logger: slog.Default().With("component", "processor", "type", config.Type)}, nil + }, + }) +} type DebugLog struct { config config.ProcessorConfig logger *slog.Logger } +// TODO(jwetzell): maybe make a more useful logging processor func (dl *DebugLog) Process(ctx context.Context, wrappedPayload common.WrappedPayload) (common.WrappedPayload, error) { payload := wrappedPayload.Payload payloadString := fmt.Sprintf("%+v", payload) @@ -28,12 +37,3 @@ func (dl *DebugLog) Type() string { return dl.config.Type } -func init() { - RegisterProcessor(ProcessorRegistration{ - Type: "debug.log", - Title: "Debug Log", - New: func(config config.ProcessorConfig) (Processor, error) { - return &DebugLog{config: config, logger: slog.Default().With("component", "processor", "type", config.Type)}, nil - }, - }) -} diff --git a/internal/processor/filter-change.go b/internal/processor/filter-change.go index 9843ce3..24367c1 100644 --- a/internal/processor/filter-change.go +++ b/internal/processor/filter-change.go @@ -8,6 +8,16 @@ import ( "github.com/jwetzell/showbridge-go/internal/config" ) +func init() { + RegisterProcessor(ProcessorRegistration{ + Type: "filter.change", + Title: "Filter On Change", + New: func(config config.ProcessorConfig) (Processor, error) { + return &FilterChange{config: config}, nil + }, + }) +} + type FilterChange struct { config config.ProcessorConfig previous any @@ -28,13 +38,3 @@ func (fc *FilterChange) Process(ctx context.Context, wrappedPayload common.Wrapp func (fc *FilterChange) Type() string { return fc.config.Type } - -func init() { - RegisterProcessor(ProcessorRegistration{ - Type: "filter.change", - Title: "Filter On Change", - New: func(config config.ProcessorConfig) (Processor, error) { - return &FilterChange{config: config}, nil - }, - }) -} diff --git a/internal/processor/filter-expr.go b/internal/processor/filter-expr.go index d88169d..5240db3 100644 --- a/internal/processor/filter-expr.go +++ b/internal/processor/filter-expr.go @@ -11,6 +11,39 @@ import ( "github.com/jwetzell/showbridge-go/internal/config" ) +func init() { + RegisterProcessor(ProcessorRegistration{ + Type: "filter.expr", + Title: "Filter by Expr expression", + ParamsSchema: &jsonschema.Schema{ + Type: "object", + Properties: map[string]*jsonschema.Schema{ + "expression": { + Title: "Expression", + Type: "string", + }, + }, + Required: []string{"expression"}, + AdditionalProperties: &jsonschema.Schema{Not: &jsonschema.Schema{}}, + }, + New: func(config config.ProcessorConfig) (Processor, error) { + params := config.Params + + expressionString, err := params.GetString("expression") + if err != nil { + return nil, fmt.Errorf("filter.expr expression error: %w", err) + } + + program, err := expr.Compile(expressionString) + if err != nil { + return nil, err + } + + return &FilterExpr{config: config, Program: program}, nil + }, + }) +} + // NOTE(jwetzell): see language definition https://expr-lang.org/docs/language-definition type FilterExpr struct { config config.ProcessorConfig @@ -45,36 +78,3 @@ func (fe *FilterExpr) Process(ctx context.Context, wrappedPayload common.Wrapped func (fe *FilterExpr) Type() string { return fe.config.Type } - -func init() { - RegisterProcessor(ProcessorRegistration{ - Type: "filter.expr", - Title: "Filter by Expr expression", - ParamsSchema: &jsonschema.Schema{ - Type: "object", - Properties: map[string]*jsonschema.Schema{ - "expression": { - Title: "Expression", - Type: "string", - }, - }, - Required: []string{"expression"}, - AdditionalProperties: &jsonschema.Schema{Not: &jsonschema.Schema{}}, - }, - New: func(config config.ProcessorConfig) (Processor, error) { - params := config.Params - - expressionString, err := params.GetString("expression") - if err != nil { - return nil, fmt.Errorf("filter.expr expression error: %w", err) - } - - program, err := expr.Compile(expressionString) - if err != nil { - return nil, err - } - - return &FilterExpr{config: config, Program: program}, nil - }, - }) -} diff --git a/internal/processor/filter-regex.go b/internal/processor/filter-regex.go index c138c69..461d263 100644 --- a/internal/processor/filter-regex.go +++ b/internal/processor/filter-regex.go @@ -11,33 +11,6 @@ import ( "github.com/jwetzell/showbridge-go/internal/config" ) -type FilterRegex struct { - config config.ProcessorConfig - Pattern *regexp.Regexp -} - -func (fr *FilterRegex) Process(ctx context.Context, wrappedPayload common.WrappedPayload) (common.WrappedPayload, error) { - payload := wrappedPayload.Payload - payloadString, ok := common.GetAnyAs[string](payload) - - if !ok { - wrappedPayload.End = true - return wrappedPayload, errors.New("filter.regex processor only accepts a string") - } - - if !fr.Pattern.MatchString(payloadString) { - wrappedPayload.End = true - return wrappedPayload, nil - } - - wrappedPayload.Payload = payloadString - return wrappedPayload, nil -} - -func (fr *FilterRegex) Type() string { - return fr.config.Type -} - func init() { RegisterProcessor(ProcessorRegistration{ Type: "filter.regex", @@ -71,3 +44,30 @@ func init() { }, }) } + +type FilterRegex struct { + config config.ProcessorConfig + Pattern *regexp.Regexp +} + +func (fr *FilterRegex) Process(ctx context.Context, wrappedPayload common.WrappedPayload) (common.WrappedPayload, error) { + payload := wrappedPayload.Payload + payloadString, ok := common.GetAnyAs[string](payload) + + if !ok { + wrappedPayload.End = true + return wrappedPayload, errors.New("filter.regex processor only accepts a string") + } + + if !fr.Pattern.MatchString(payloadString) { + wrappedPayload.End = true + return wrappedPayload, nil + } + + wrappedPayload.Payload = payloadString + return wrappedPayload, nil +} + +func (fr *FilterRegex) Type() string { + return fr.config.Type +} diff --git a/internal/processor/float-parse.go b/internal/processor/float-parse.go index 6166c9c..d185d93 100644 --- a/internal/processor/float-parse.go +++ b/internal/processor/float-parse.go @@ -12,33 +12,6 @@ import ( "github.com/jwetzell/showbridge-go/internal/config" ) -type FloatParse struct { - BitSize int - config config.ProcessorConfig -} - -func (fp *FloatParse) Process(ctx context.Context, wrappedPayload common.WrappedPayload) (common.WrappedPayload, error) { - payload := wrappedPayload.Payload - payloadString, ok := common.GetAnyAs[string](payload) - - if !ok { - wrappedPayload.End = true - return wrappedPayload, errors.New("float.parse processor only accepts a string") - } - - payloadFloat, err := strconv.ParseFloat(payloadString, fp.BitSize) - if err != nil { - wrappedPayload.End = true - return wrappedPayload, err - } - wrappedPayload.Payload = payloadFloat - return wrappedPayload, nil -} - -func (fp *FloatParse) Type() string { - return fp.config.Type -} - func init() { RegisterProcessor(ProcessorRegistration{ Type: "float.parse", @@ -70,3 +43,30 @@ func init() { }, }) } + +type FloatParse struct { + BitSize int + config config.ProcessorConfig +} + +func (fp *FloatParse) Process(ctx context.Context, wrappedPayload common.WrappedPayload) (common.WrappedPayload, error) { + payload := wrappedPayload.Payload + payloadString, ok := common.GetAnyAs[string](payload) + + if !ok { + wrappedPayload.End = true + return wrappedPayload, errors.New("float.parse processor only accepts a string") + } + + payloadFloat, err := strconv.ParseFloat(payloadString, fp.BitSize) + if err != nil { + wrappedPayload.End = true + return wrappedPayload, err + } + wrappedPayload.Payload = payloadFloat + return wrappedPayload, nil +} + +func (fp *FloatParse) Type() string { + return fp.config.Type +} diff --git a/internal/processor/float-random.go b/internal/processor/float-random.go index 5bfe283..1b41e99 100644 --- a/internal/processor/float-random.go +++ b/internal/processor/float-random.go @@ -12,32 +12,6 @@ import ( "github.com/jwetzell/showbridge-go/internal/config" ) -type FloatRandom struct { - BitSize int - Min float64 - Max float64 - config config.ProcessorConfig -} - -func (fr *FloatRandom) Process(ctx context.Context, wrappedPayload common.WrappedPayload) (common.WrappedPayload, error) { - if fr.BitSize == 32 { - payloadFloat := rand.Float32()*(float32(fr.Max)-float32(fr.Min)) + float32(fr.Min) - wrappedPayload.Payload = payloadFloat - return wrappedPayload, nil - } - if fr.BitSize == 64 { - payloadFloat := rand.Float64()*(fr.Max-fr.Min) + fr.Min - wrappedPayload.Payload = payloadFloat - return wrappedPayload, nil - } - wrappedPayload.End = true - return wrappedPayload, errors.New("float.random bitSize error: must be 32 or 64") -} - -func (fr *FloatRandom) Type() string { - return fr.config.Type -} - func init() { RegisterProcessor(ProcessorRegistration{ Type: "float.random", @@ -97,3 +71,29 @@ func init() { }, }) } + +type FloatRandom struct { + BitSize int + Min float64 + Max float64 + config config.ProcessorConfig +} + +func (fr *FloatRandom) Process(ctx context.Context, wrappedPayload common.WrappedPayload) (common.WrappedPayload, error) { + if fr.BitSize == 32 { + payloadFloat := rand.Float32()*(float32(fr.Max)-float32(fr.Min)) + float32(fr.Min) + wrappedPayload.Payload = payloadFloat + return wrappedPayload, nil + } + if fr.BitSize == 64 { + payloadFloat := rand.Float64()*(fr.Max-fr.Min) + fr.Min + wrappedPayload.Payload = payloadFloat + return wrappedPayload, nil + } + wrappedPayload.End = true + return wrappedPayload, errors.New("float.random bitSize error: must be 32 or 64") +} + +func (fr *FloatRandom) Type() string { + return fr.config.Type +} diff --git a/internal/processor/free-d-create.go b/internal/processor/free-d-create.go index b29233b..6b455e1 100644 --- a/internal/processor/free-d-create.go +++ b/internal/processor/free-d-create.go @@ -13,6 +13,181 @@ import ( "github.com/jwetzell/showbridge-go/internal/config" ) +func init() { + RegisterProcessor(ProcessorRegistration{ + Type: "freed.create", + Title: "Create FreeD", + ParamsSchema: &jsonschema.Schema{ + Type: "object", + Properties: map[string]*jsonschema.Schema{ + "id": { + Title: "Camera ID", + Type: "string", + }, + "pan": { + Title: "Pan", + Type: "string", + }, + "tilt": { + Title: "Tilt", + Type: "string", + }, + "roll": { + Title: "Roll", + Type: "string", + }, + "posX": { + Title: "Position X", + Type: "string", + }, + "posY": { + Title: "Position Y", + Type: "string", + }, + "posZ": { + Title: "Position Z", + Type: "string", + }, + "zoom": { + Title: "Zoom", + Type: "string", + }, + "focus": { + Title: "Focus", + Type: "string", + }, + }, + Required: []string{ + "id", + "pan", + "tilt", + "roll", + "posX", + "posY", + "posZ", + "zoom", + "focus", + }, + AdditionalProperties: &jsonschema.Schema{Not: &jsonschema.Schema{}}, + }, + New: func(config config.ProcessorConfig) (Processor, error) { + + // TODO(jwetzell): make some params optional + params := config.Params + idString, err := params.GetString("id") + if err != nil { + return nil, fmt.Errorf("freed.create id error: %w", err) + } + + idTemplate, err := template.New("id").Parse(idString) + + if err != nil { + return nil, err + } + + panString, err := params.GetString("pan") + if err != nil { + return nil, fmt.Errorf("freed.create pan error: %w", err) + } + + panTemplate, err := template.New("pan").Parse(panString) + + if err != nil { + return nil, err + } + + tiltString, err := params.GetString("tilt") + if err != nil { + return nil, fmt.Errorf("freed.create tilt error: %w", err) + } + + tiltTemplate, err := template.New("tilt").Parse(tiltString) + + if err != nil { + return nil, err + } + + rollString, err := params.GetString("roll") + if err != nil { + return nil, fmt.Errorf("freed.create roll error: %w", err) + } + + rollTemplate, err := template.New("roll").Parse(rollString) + + if err != nil { + return nil, err + } + + posXString, err := params.GetString("posX") + if err != nil { + return nil, fmt.Errorf("freed.create posX error: %w", err) + } + + posXTemplate, err := template.New("posX").Parse(posXString) + + if err != nil { + return nil, err + } + + posYString, err := params.GetString("posY") + if err != nil { + return nil, fmt.Errorf("freed.create posY error: %w", err) + } + + posYTemplate, err := template.New("posY").Parse(posYString) + + if err != nil { + return nil, err + } + + posZString, err := params.GetString("posZ") + if err != nil { + return nil, fmt.Errorf("freed.create posZ error: %w", err) + } + + posZTemplate, err := template.New("posZ").Parse(posZString) + + if err != nil { + return nil, err + } + + zoomString, err := params.GetString("zoom") + if err != nil { + return nil, fmt.Errorf("freed.create zoom error: %w", err) + } + + zoomTemplate, err := template.New("zoom").Parse(zoomString) + + if err != nil { + return nil, err + } + + focusString, err := params.GetString("focus") + if err != nil { + return nil, fmt.Errorf("freed.create focus error: %w", err) + } + + focusTemplate, err := template.New("focus").Parse(focusString) + if err != nil { + return nil, err + } + + return &FreeDCreate{ + config: config, + Id: idTemplate, + Pan: panTemplate, + Tilt: tiltTemplate, + Roll: rollTemplate, + PosX: posXTemplate, + PosY: posYTemplate, + PosZ: posZTemplate, + Zoom: zoomTemplate, + Focus: focusTemplate, + }, nil + }, + }) +} + type FreeDCreate struct { config config.ProcessorConfig Id *template.Template @@ -203,178 +378,3 @@ func (fc *FreeDCreate) Process(ctx context.Context, wrappedPayload common.Wrappe func (fc *FreeDCreate) Type() string { return fc.config.Type } - -func init() { - RegisterProcessor(ProcessorRegistration{ - Type: "freed.create", - Title: "Create FreeD", - ParamsSchema: &jsonschema.Schema{ - Type: "object", - Properties: map[string]*jsonschema.Schema{ - "id": { - Title: "Camera ID", - Type: "string", - }, - "pan": { - Title: "Pan", - Type: "string", - }, - "tilt": { - Title: "Tilt", - Type: "string", - }, - "roll": { - Title: "Roll", - Type: "string", - }, - "posX": { - Title: "Position X", - Type: "string", - }, - "posY": { - Title: "Position Y", - Type: "string", - }, - "posZ": { - Title: "Position Z", - Type: "string", - }, - "zoom": { - Title: "Zoom", - Type: "string", - }, - "focus": { - Title: "Focus", - Type: "string", - }, - }, - Required: []string{ - "id", - "pan", - "tilt", - "roll", - "posX", - "posY", - "posZ", - "zoom", - "focus", - }, - AdditionalProperties: &jsonschema.Schema{Not: &jsonschema.Schema{}}, - }, - New: func(config config.ProcessorConfig) (Processor, error) { - - // TODO(jwetzell): make some params optional - params := config.Params - idString, err := params.GetString("id") - if err != nil { - return nil, fmt.Errorf("freed.create id error: %w", err) - } - - idTemplate, err := template.New("id").Parse(idString) - - if err != nil { - return nil, err - } - - panString, err := params.GetString("pan") - if err != nil { - return nil, fmt.Errorf("freed.create pan error: %w", err) - } - - panTemplate, err := template.New("pan").Parse(panString) - - if err != nil { - return nil, err - } - - tiltString, err := params.GetString("tilt") - if err != nil { - return nil, fmt.Errorf("freed.create tilt error: %w", err) - } - - tiltTemplate, err := template.New("tilt").Parse(tiltString) - - if err != nil { - return nil, err - } - - rollString, err := params.GetString("roll") - if err != nil { - return nil, fmt.Errorf("freed.create roll error: %w", err) - } - - rollTemplate, err := template.New("roll").Parse(rollString) - - if err != nil { - return nil, err - } - - posXString, err := params.GetString("posX") - if err != nil { - return nil, fmt.Errorf("freed.create posX error: %w", err) - } - - posXTemplate, err := template.New("posX").Parse(posXString) - - if err != nil { - return nil, err - } - - posYString, err := params.GetString("posY") - if err != nil { - return nil, fmt.Errorf("freed.create posY error: %w", err) - } - - posYTemplate, err := template.New("posY").Parse(posYString) - - if err != nil { - return nil, err - } - - posZString, err := params.GetString("posZ") - if err != nil { - return nil, fmt.Errorf("freed.create posZ error: %w", err) - } - - posZTemplate, err := template.New("posZ").Parse(posZString) - - if err != nil { - return nil, err - } - - zoomString, err := params.GetString("zoom") - if err != nil { - return nil, fmt.Errorf("freed.create zoom error: %w", err) - } - - zoomTemplate, err := template.New("zoom").Parse(zoomString) - - if err != nil { - return nil, err - } - - focusString, err := params.GetString("focus") - if err != nil { - return nil, fmt.Errorf("freed.create focus error: %w", err) - } - - focusTemplate, err := template.New("focus").Parse(focusString) - if err != nil { - return nil, err - } - - return &FreeDCreate{ - config: config, - Id: idTemplate, - Pan: panTemplate, - Tilt: tiltTemplate, - Roll: rollTemplate, - PosX: posXTemplate, - PosY: posYTemplate, - PosZ: posZTemplate, - Zoom: zoomTemplate, - Focus: focusTemplate, - }, nil - }, - }) -} diff --git a/internal/processor/free-d-decode.go b/internal/processor/free-d-decode.go index 92d4b15..be23147 100644 --- a/internal/processor/free-d-decode.go +++ b/internal/processor/free-d-decode.go @@ -9,10 +9,20 @@ import ( "github.com/jwetzell/showbridge-go/internal/config" ) +func init() { + RegisterProcessor(ProcessorRegistration{ + Type: "freed.decode", + Title: "Decode FreeD", + New: func(config config.ProcessorConfig) (Processor, error) { + return &FreeDDecode{config: config}, nil + }, + }) +} + type FreeDDecode struct { config config.ProcessorConfig } - + func (fd *FreeDDecode) Process(ctx context.Context, wrappedPayload common.WrappedPayload) (common.WrappedPayload, error) { payload := wrappedPayload.Payload payloadBytes, ok := common.GetAnyAsByteSlice(payload) @@ -34,13 +44,3 @@ func (fd *FreeDDecode) Process(ctx context.Context, wrappedPayload common.Wrappe func (fd *FreeDDecode) Type() string { return fd.config.Type } - -func init() { - RegisterProcessor(ProcessorRegistration{ - Type: "freed.decode", - Title: "Decode FreeD", - New: func(config config.ProcessorConfig) (Processor, error) { - return &FreeDDecode{config: config}, nil - }, - }) -} diff --git a/internal/processor/free-d-encode.go b/internal/processor/free-d-encode.go index a0ae34f..6ea6309 100644 --- a/internal/processor/free-d-encode.go +++ b/internal/processor/free-d-encode.go @@ -9,6 +9,16 @@ import ( "github.com/jwetzell/showbridge-go/internal/config" ) +func init() { + RegisterProcessor(ProcessorRegistration{ + Type: "freed.encode", + Title: "Encode FreeD", + New: func(config config.ProcessorConfig) (Processor, error) { + return &FreeDEncode{config: config}, nil + }, + }) +} + type FreeDEncode struct { config config.ProcessorConfig } @@ -31,13 +41,3 @@ func (fe *FreeDEncode) Process(ctx context.Context, wrappedPayload common.Wrappe func (fe *FreeDEncode) Type() string { return fe.config.Type } - -func init() { - RegisterProcessor(ProcessorRegistration{ - Type: "freed.encode", - Title: "Encode FreeD", - New: func(config config.ProcessorConfig) (Processor, error) { - return &FreeDEncode{config: config}, nil - }, - }) -} diff --git a/internal/processor/http-request-do.go b/internal/processor/http-request-do.go index 67a6f77..99dcc31 100644 --- a/internal/processor/http-request-do.go +++ b/internal/processor/http-request-do.go @@ -14,6 +14,53 @@ import ( "github.com/jwetzell/showbridge-go/internal/config" ) +func init() { + RegisterProcessor(ProcessorRegistration{ + Type: "http.request.do", + Title: "Do HTTP Request", + ParamsSchema: &jsonschema.Schema{ + Type: "object", + Properties: map[string]*jsonschema.Schema{ + "method": { + Title: "HTTP Method", + Type: "string", + Enum: []any{"GET", "POST", "PUT", "PATCH", "DELETE"}, + }, + "url": { + Title: "URL", + Type: "string", + }, + }, + Required: []string{"method", "url"}, + AdditionalProperties: &jsonschema.Schema{Not: &jsonschema.Schema{}}, + }, + New: func(config config.ProcessorConfig) (Processor, error) { + params := config.Params + + methodString, err := params.GetString("method") + if err != nil { + return nil, fmt.Errorf("http.request.do method error: %w", err) + } + + urlString, err := params.GetString("url") + if err != nil { + return nil, fmt.Errorf("http.request.do url error: %w", err) + } + + urlTemplate, err := template.New("url").Parse(urlString) + + if err != nil { + return nil, err + } + client := &http.Client{ + Timeout: 10 * time.Second, + } + + return &HTTPRequestDo{config: config, URL: urlTemplate, Method: methodString, client: client}, nil + }, + }) +} + type HTTPRequestDo struct { config config.ProcessorConfig client *http.Client @@ -68,50 +115,3 @@ func (hrd *HTTPRequestDo) Process(ctx context.Context, wrappedPayload common.Wra func (hrd *HTTPRequestDo) Type() string { return hrd.config.Type } - -func init() { - RegisterProcessor(ProcessorRegistration{ - Type: "http.request.do", - Title: "Do HTTP Request", - ParamsSchema: &jsonschema.Schema{ - Type: "object", - Properties: map[string]*jsonschema.Schema{ - "method": { - Title: "HTTP Method", - Type: "string", - Enum: []any{"GET", "POST", "PUT", "PATCH", "DELETE"}, - }, - "url": { - Title: "URL", - Type: "string", - }, - }, - Required: []string{"method", "url"}, - AdditionalProperties: &jsonschema.Schema{Not: &jsonschema.Schema{}}, - }, - New: func(config config.ProcessorConfig) (Processor, error) { - params := config.Params - - methodString, err := params.GetString("method") - if err != nil { - return nil, fmt.Errorf("http.request.do method error: %w", err) - } - - urlString, err := params.GetString("url") - if err != nil { - return nil, fmt.Errorf("http.request.do url error: %w", err) - } - - urlTemplate, err := template.New("url").Parse(urlString) - - if err != nil { - return nil, err - } - client := &http.Client{ - Timeout: 10 * time.Second, - } - - return &HTTPRequestDo{config: config, URL: urlTemplate, Method: methodString, client: client}, nil - }, - }) -} diff --git a/internal/processor/http-response-create.go b/internal/processor/http-response-create.go index e965291..d3ceae9 100644 --- a/internal/processor/http-response-create.go +++ b/internal/processor/http-response-create.go @@ -11,38 +11,6 @@ import ( "github.com/jwetzell/showbridge-go/internal/config" ) -type HTTPResponseCreate struct { - Status int - BodyTmpl *template.Template - config config.ProcessorConfig -} - -type HTTPResponse struct { - Status int - Body []byte -} - -func (hrc *HTTPResponseCreate) Process(ctx context.Context, wrappedPayload common.WrappedPayload) (common.WrappedPayload, error) { - templateData := wrappedPayload - - var bodyBuffer bytes.Buffer - err := hrc.BodyTmpl.Execute(&bodyBuffer, templateData) - - if err != nil { - wrappedPayload.End = true - return wrappedPayload, err - } - wrappedPayload.Payload = HTTPResponse{ - Status: hrc.Status, - Body: bodyBuffer.Bytes(), - } - return wrappedPayload, nil -} - -func (hrc *HTTPResponseCreate) Type() string { - return hrc.config.Type -} - func init() { RegisterProcessor(ProcessorRegistration{ Type: "http.response.create", @@ -86,3 +54,35 @@ func init() { }, }) } + +type HTTPResponseCreate struct { + Status int + BodyTmpl *template.Template + config config.ProcessorConfig +} + +type HTTPResponse struct { + Status int + Body []byte +} + +func (hrc *HTTPResponseCreate) Process(ctx context.Context, wrappedPayload common.WrappedPayload) (common.WrappedPayload, error) { + templateData := wrappedPayload + + var bodyBuffer bytes.Buffer + err := hrc.BodyTmpl.Execute(&bodyBuffer, templateData) + + if err != nil { + wrappedPayload.End = true + return wrappedPayload, err + } + wrappedPayload.Payload = HTTPResponse{ + Status: hrc.Status, + Body: bodyBuffer.Bytes(), + } + return wrappedPayload, nil +} + +func (hrc *HTTPResponseCreate) Type() string { + return hrc.config.Type +} diff --git a/internal/processor/int-parse.go b/internal/processor/int-parse.go index b6c578e..f81a5a6 100644 --- a/internal/processor/int-parse.go +++ b/internal/processor/int-parse.go @@ -12,34 +12,6 @@ import ( "github.com/jwetzell/showbridge-go/internal/config" ) -type IntParse struct { - Base int - BitSize int - config config.ProcessorConfig -} - -func (ip *IntParse) Process(ctx context.Context, wrappedPayload common.WrappedPayload) (common.WrappedPayload, error) { - payload := wrappedPayload.Payload - payloadString, ok := common.GetAnyAs[string](payload) - - if !ok { - wrappedPayload.End = true - return wrappedPayload, errors.New("int.parse processor only accepts a string") - } - - payloadInt, err := strconv.ParseInt(payloadString, ip.Base, ip.BitSize) - if err != nil { - wrappedPayload.End = true - return wrappedPayload, err - } - wrappedPayload.Payload = payloadInt - return wrappedPayload, nil -} - -func (ip *IntParse) Type() string { - return ip.config.Type -} - func init() { RegisterProcessor(ProcessorRegistration{ Type: "int.parse", @@ -86,3 +58,31 @@ func init() { }, }) } + +type IntParse struct { + Base int + BitSize int + config config.ProcessorConfig +} + +func (ip *IntParse) Process(ctx context.Context, wrappedPayload common.WrappedPayload) (common.WrappedPayload, error) { + payload := wrappedPayload.Payload + payloadString, ok := common.GetAnyAs[string](payload) + + if !ok { + wrappedPayload.End = true + return wrappedPayload, errors.New("int.parse processor only accepts a string") + } + + payloadInt, err := strconv.ParseInt(payloadString, ip.Base, ip.BitSize) + if err != nil { + wrappedPayload.End = true + return wrappedPayload, err + } + wrappedPayload.Payload = payloadInt + return wrappedPayload, nil +} + +func (ip *IntParse) Type() string { + return ip.config.Type +} diff --git a/internal/processor/int-random.go b/internal/processor/int-random.go index 0f0ace3..3f96712 100644 --- a/internal/processor/int-random.go +++ b/internal/processor/int-random.go @@ -11,22 +11,6 @@ import ( "github.com/jwetzell/showbridge-go/internal/config" ) -type IntRandom struct { - Min int - Max int - config config.ProcessorConfig -} - -func (ir *IntRandom) Process(ctx context.Context, wrappedPayload common.WrappedPayload) (common.WrappedPayload, error) { - payloadInt := rand.IntN(ir.Max-ir.Min+1) + ir.Min - wrappedPayload.Payload = payloadInt - return wrappedPayload, nil -} - -func (ir *IntRandom) Type() string { - return ir.config.Type -} - func init() { RegisterProcessor(ProcessorRegistration{ Type: "int.random", @@ -67,3 +51,19 @@ func init() { }, }) } + +type IntRandom struct { + Min int + Max int + config config.ProcessorConfig +} + +func (ir *IntRandom) Process(ctx context.Context, wrappedPayload common.WrappedPayload) (common.WrappedPayload, error) { + payloadInt := rand.IntN(ir.Max-ir.Min+1) + ir.Min + wrappedPayload.Payload = payloadInt + return wrappedPayload, nil +} + +func (ir *IntRandom) Type() string { + return ir.config.Type +} diff --git a/internal/processor/int-scale.go b/internal/processor/int-scale.go index 09a99ce..996f5fb 100644 --- a/internal/processor/int-scale.go +++ b/internal/processor/int-scale.go @@ -10,31 +10,6 @@ import ( "github.com/jwetzell/showbridge-go/internal/config" ) -type IntScale struct { - OutMin int - OutMax int - InMin int - InMax int - config config.ProcessorConfig -} - -func (is *IntScale) Process(ctx context.Context, wrappedPayload common.WrappedPayload) (common.WrappedPayload, error) { - payload := wrappedPayload.Payload - payloadInt, ok := common.GetAnyAs[int](payload) - if !ok { - wrappedPayload.End = true - return wrappedPayload, errors.New("int.scale can only process an int") - } - - payloadInt = (payloadInt-is.InMin)*(is.OutMax-is.OutMin)/(is.InMax-is.InMin) + is.OutMin - wrappedPayload.Payload = payloadInt - return wrappedPayload, nil -} - -func (is *IntScale) Type() string { - return is.config.Type -} - func init() { RegisterProcessor(ProcessorRegistration{ Type: "int.scale", @@ -97,3 +72,28 @@ func init() { }, }) } + +type IntScale struct { + OutMin int + OutMax int + InMin int + InMax int + config config.ProcessorConfig +} + +func (is *IntScale) Process(ctx context.Context, wrappedPayload common.WrappedPayload) (common.WrappedPayload, error) { + payload := wrappedPayload.Payload + payloadInt, ok := common.GetAnyAs[int](payload) + if !ok { + wrappedPayload.End = true + return wrappedPayload, errors.New("int.scale can only process an int") + } + + payloadInt = (payloadInt-is.InMin)*(is.OutMax-is.OutMin)/(is.InMax-is.InMin) + is.OutMin + wrappedPayload.Payload = payloadInt + return wrappedPayload, nil +} + +func (is *IntScale) Type() string { + return is.config.Type +} diff --git a/internal/processor/json-decode.go b/internal/processor/json-decode.go index 30c7c46..9fe492b 100644 --- a/internal/processor/json-decode.go +++ b/internal/processor/json-decode.go @@ -9,6 +9,16 @@ import ( "github.com/jwetzell/showbridge-go/internal/config" ) +func init() { + RegisterProcessor(ProcessorRegistration{ + Type: "json.decode", + Title: "Decode JSON", + New: func(config config.ProcessorConfig) (Processor, error) { + return &JsonDecode{config: config}, nil + }, + }) +} + type JsonDecode struct { config config.ProcessorConfig } @@ -43,13 +53,3 @@ func (jd *JsonDecode) Process(ctx context.Context, wrappedPayload common.Wrapped func (jd *JsonDecode) Type() string { return jd.config.Type } - -func init() { - RegisterProcessor(ProcessorRegistration{ - Type: "json.decode", - Title: "Decode JSON", - New: func(config config.ProcessorConfig) (Processor, error) { - return &JsonDecode{config: config}, nil - }, - }) -} diff --git a/internal/processor/json-encode.go b/internal/processor/json-encode.go index 56e001d..b7c1ac8 100644 --- a/internal/processor/json-encode.go +++ b/internal/processor/json-encode.go @@ -9,6 +9,16 @@ import ( "github.com/jwetzell/showbridge-go/internal/config" ) +func init() { + RegisterProcessor(ProcessorRegistration{ + Type: "json.encode", + Title: "Encode JSON", + New: func(config config.ProcessorConfig) (Processor, error) { + return &JsonEncode{config: config}, nil + }, + }) +} + type JsonEncode struct { config config.ProcessorConfig } @@ -35,13 +45,3 @@ func (je *JsonEncode) Process(ctx context.Context, wrappedPayload common.Wrapped func (je *JsonEncode) Type() string { return je.config.Type } - -func init() { - RegisterProcessor(ProcessorRegistration{ - Type: "json.encode", - Title: "Encode JSON", - New: func(config config.ProcessorConfig) (Processor, error) { - return &JsonEncode{config: config}, nil - }, - }) -} diff --git a/internal/processor/kv-get.go b/internal/processor/kv-get.go index 0d6790b..bc270fd 100644 --- a/internal/processor/kv-get.go +++ b/internal/processor/kv-get.go @@ -11,6 +11,43 @@ import ( "github.com/jwetzell/showbridge-go/internal/config" ) +func init() { + RegisterProcessor(ProcessorRegistration{ + Type: "kv.get", + Title: "Get Key", + ParamsSchema: &jsonschema.Schema{ + Type: "object", + Properties: map[string]*jsonschema.Schema{ + "module": { + Title: "Module ID", + Type: "string", + }, + "key": { + Title: "Key", + Type: "string", + }, + }, + Required: []string{"module", "key"}, + AdditionalProperties: &jsonschema.Schema{Not: &jsonschema.Schema{}}, + }, + New: func(config config.ProcessorConfig) (Processor, error) { + + params := config.Params + + moduleIdString, err := params.GetString("module") + if err != nil { + return nil, fmt.Errorf("kv.get module error: %w", err) + } + + keyString, err := params.GetString("key") + if err != nil { + return nil, fmt.Errorf("kv.get key error: %w", err) + } + return &KVGet{config: config, ModuleId: moduleIdString, Key: keyString, logger: slog.Default().With("component", "processor", "type", config.Type)}, nil + }, + }) +} + type KVGet struct { config config.ProcessorConfig ModuleId string @@ -53,40 +90,3 @@ func (kvg *KVGet) Process(ctx context.Context, wrappedPayload common.WrappedPayl func (kvg *KVGet) Type() string { return kvg.config.Type } - -func init() { - RegisterProcessor(ProcessorRegistration{ - Type: "kv.get", - Title: "Get Key", - ParamsSchema: &jsonschema.Schema{ - Type: "object", - Properties: map[string]*jsonschema.Schema{ - "module": { - Title: "Module ID", - Type: "string", - }, - "key": { - Title: "Key", - Type: "string", - }, - }, - Required: []string{"module", "key"}, - AdditionalProperties: &jsonschema.Schema{Not: &jsonschema.Schema{}}, - }, - New: func(config config.ProcessorConfig) (Processor, error) { - - params := config.Params - - moduleIdString, err := params.GetString("module") - if err != nil { - return nil, fmt.Errorf("kv.get module error: %w", err) - } - - keyString, err := params.GetString("key") - if err != nil { - return nil, fmt.Errorf("kv.get key error: %w", err) - } - return &KVGet{config: config, ModuleId: moduleIdString, Key: keyString, logger: slog.Default().With("component", "processor", "type", config.Type)}, nil - }, - }) -} diff --git a/internal/processor/kv-set.go b/internal/processor/kv-set.go index 376b4e1..ce14979 100644 --- a/internal/processor/kv-set.go +++ b/internal/processor/kv-set.go @@ -11,6 +11,44 @@ import ( "github.com/jwetzell/showbridge-go/internal/config" ) +func init() { + RegisterProcessor(ProcessorRegistration{ + Type: "kv.set", + Title: "Set Key", + ParamsSchema: &jsonschema.Schema{ + Type: "object", + Properties: map[string]*jsonschema.Schema{ + "module": { + Title: "Module ID", + Type: "string", + }, + "key": { + Title: "Key", + Type: "string", + }, + }, + Required: []string{"module", "key"}, + AdditionalProperties: &jsonschema.Schema{Not: &jsonschema.Schema{}}, + }, + New: func(config config.ProcessorConfig) (Processor, error) { + + params := config.Params + + moduleIdString, err := params.GetString("module") + if err != nil { + return nil, fmt.Errorf("kv.set module error: %w", err) + } + + keyString, err := params.GetString("key") + if err != nil { + return nil, fmt.Errorf("kv.set key error: %w", err) + } + + return &KVSet{config: config, ModuleId: moduleIdString, Key: keyString, logger: slog.Default().With("component", "processor", "type", config.Type)}, nil + }, + }) +} + type KVSet struct { config config.ProcessorConfig ModuleId string @@ -52,41 +90,3 @@ func (kvs *KVSet) Process(ctx context.Context, wrappedPayload common.WrappedPayl func (kvs *KVSet) Type() string { return kvs.config.Type } - -func init() { - RegisterProcessor(ProcessorRegistration{ - Type: "kv.set", - Title: "Set Key", - ParamsSchema: &jsonschema.Schema{ - Type: "object", - Properties: map[string]*jsonschema.Schema{ - "module": { - Title: "Module ID", - Type: "string", - }, - "key": { - Title: "Key", - Type: "string", - }, - }, - Required: []string{"module", "key"}, - AdditionalProperties: &jsonschema.Schema{Not: &jsonschema.Schema{}}, - }, - New: func(config config.ProcessorConfig) (Processor, error) { - - params := config.Params - - moduleIdString, err := params.GetString("module") - if err != nil { - return nil, fmt.Errorf("kv.set module error: %w", err) - } - - keyString, err := params.GetString("key") - if err != nil { - return nil, fmt.Errorf("kv.set key error: %w", err) - } - - return &KVSet{config: config, ModuleId: moduleIdString, Key: keyString, logger: slog.Default().With("component", "processor", "type", config.Type)}, nil - }, - }) -} diff --git a/internal/processor/midi-control_change-create.go b/internal/processor/midi-control_change-create.go index 729347d..ab47808 100644 --- a/internal/processor/midi-control_change-create.go +++ b/internal/processor/midi-control_change-create.go @@ -15,70 +15,6 @@ import ( "gitlab.com/gomidi/midi/v2" ) -type MIDIControlChangeCreate struct { - config config.ProcessorConfig - Channel *template.Template - Control *template.Template - Value *template.Template -} - -func (mccc *MIDIControlChangeCreate) Process(ctx context.Context, wrappedPayload common.WrappedPayload) (common.WrappedPayload, error) { - templateData := wrappedPayload - - var channelBuffer bytes.Buffer - err := mccc.Channel.Execute(&channelBuffer, templateData) - - if err != nil { - wrappedPayload.End = true - return wrappedPayload, err - } - - channelValue, err := strconv.ParseUint(channelBuffer.String(), 10, 8) - - if err != nil { - wrappedPayload.End = true - return wrappedPayload, err - } - - var controlBuffer bytes.Buffer - err = mccc.Control.Execute(&controlBuffer, templateData) - - if err != nil { - wrappedPayload.End = true - return wrappedPayload, err - } - - controlValue, err := strconv.ParseUint(controlBuffer.String(), 10, 8) - - if err != nil { - wrappedPayload.End = true - return wrappedPayload, err - } - - var valueBuffer bytes.Buffer - err = mccc.Value.Execute(&valueBuffer, templateData) - - if err != nil { - wrappedPayload.End = true - return wrappedPayload, err - } - - valueValue, err := strconv.ParseUint(valueBuffer.String(), 10, 8) - - if err != nil { - wrappedPayload.End = true - return wrappedPayload, err - } - - payloadMessage := midi.ControlChange(uint8(channelValue), uint8(controlValue), uint8(valueValue)) - wrappedPayload.Payload = payloadMessage - return wrappedPayload, nil -} - -func (mccc *MIDIControlChangeCreate) Type() string { - return mccc.config.Type -} - func init() { RegisterProcessor(ProcessorRegistration{ Type: "midi.control_change.create", @@ -147,3 +83,67 @@ func init() { }, }) } + +type MIDIControlChangeCreate struct { + config config.ProcessorConfig + Channel *template.Template + Control *template.Template + Value *template.Template +} + +func (mccc *MIDIControlChangeCreate) Process(ctx context.Context, wrappedPayload common.WrappedPayload) (common.WrappedPayload, error) { + templateData := wrappedPayload + + var channelBuffer bytes.Buffer + err := mccc.Channel.Execute(&channelBuffer, templateData) + + if err != nil { + wrappedPayload.End = true + return wrappedPayload, err + } + + channelValue, err := strconv.ParseUint(channelBuffer.String(), 10, 8) + + if err != nil { + wrappedPayload.End = true + return wrappedPayload, err + } + + var controlBuffer bytes.Buffer + err = mccc.Control.Execute(&controlBuffer, templateData) + + if err != nil { + wrappedPayload.End = true + return wrappedPayload, err + } + + controlValue, err := strconv.ParseUint(controlBuffer.String(), 10, 8) + + if err != nil { + wrappedPayload.End = true + return wrappedPayload, err + } + + var valueBuffer bytes.Buffer + err = mccc.Value.Execute(&valueBuffer, templateData) + + if err != nil { + wrappedPayload.End = true + return wrappedPayload, err + } + + valueValue, err := strconv.ParseUint(valueBuffer.String(), 10, 8) + + if err != nil { + wrappedPayload.End = true + return wrappedPayload, err + } + + payloadMessage := midi.ControlChange(uint8(channelValue), uint8(controlValue), uint8(valueValue)) + wrappedPayload.Payload = payloadMessage + return wrappedPayload, nil +} + +func (mccc *MIDIControlChangeCreate) Type() string { + return mccc.config.Type +} diff --git a/internal/processor/midi-message-decode.go b/internal/processor/midi-message-decode.go index a0f87be..6b56a40 100644 --- a/internal/processor/midi-message-decode.go +++ b/internal/processor/midi-message-decode.go @@ -11,6 +11,16 @@ import ( "gitlab.com/gomidi/midi/v2" ) +func init() { + RegisterProcessor(ProcessorRegistration{ + Type: "midi.message.decode", + Title: "Decode MIDI Message", + New: func(config config.ProcessorConfig) (Processor, error) { + return &MIDIMessageDecode{config: config}, nil + }, + }) +} + type MIDIMessageDecode struct { config config.ProcessorConfig } @@ -33,13 +43,3 @@ func (mmd *MIDIMessageDecode) Process(ctx context.Context, wrappedPayload common func (mmd *MIDIMessageDecode) Type() string { return mmd.config.Type } - -func init() { - RegisterProcessor(ProcessorRegistration{ - Type: "midi.message.decode", - Title: "Decode MIDI Message", - New: func(config config.ProcessorConfig) (Processor, error) { - return &MIDIMessageDecode{config: config}, nil - }, - }) -} diff --git a/internal/processor/midi-message-encode.go b/internal/processor/midi-message-encode.go index 3dea40a..99b1433 100644 --- a/internal/processor/midi-message-encode.go +++ b/internal/processor/midi-message-encode.go @@ -11,6 +11,16 @@ import ( "gitlab.com/gomidi/midi/v2" ) +func init() { + RegisterProcessor(ProcessorRegistration{ + Type: "midi.message.encode", + Title: "Encode MIDI Message", + New: func(config config.ProcessorConfig) (Processor, error) { + return &MIDIMessageEncode{config: config}, nil + }, + }) +} + type MIDIMessageEncode struct { config config.ProcessorConfig } @@ -31,13 +41,3 @@ func (mme *MIDIMessageEncode) Process(ctx context.Context, wrappedPayload common func (mme *MIDIMessageEncode) Type() string { return mme.config.Type } - -func init() { - RegisterProcessor(ProcessorRegistration{ - Type: "midi.message.encode", - Title: "Encode MIDI Message", - New: func(config config.ProcessorConfig) (Processor, error) { - return &MIDIMessageEncode{config: config}, nil - }, - }) -} diff --git a/internal/processor/midi-message-unpack.go b/internal/processor/midi-message-unpack.go index 0087303..a16c869 100644 --- a/internal/processor/midi-message-unpack.go +++ b/internal/processor/midi-message-unpack.go @@ -12,6 +12,16 @@ import ( "gitlab.com/gomidi/midi/v2" ) +func init() { + RegisterProcessor(ProcessorRegistration{ + Type: "midi.message.unpack", + Title: "Unpack MIDI Message", + New: func(config config.ProcessorConfig) (Processor, error) { + return &MIDIMessageUnpack{config: config}, nil + }, + }) +} + type MIDIMessageUnpack struct { config config.ProcessorConfig } @@ -89,13 +99,3 @@ func (mmu *MIDIMessageUnpack) Process(ctx context.Context, wrappedPayload common func (mmu *MIDIMessageUnpack) Type() string { return mmu.config.Type } - -func init() { - RegisterProcessor(ProcessorRegistration{ - Type: "midi.message.unpack", - Title: "Unpack MIDI Message", - New: func(config config.ProcessorConfig) (Processor, error) { - return &MIDIMessageUnpack{config: config}, nil - }, - }) -} diff --git a/internal/processor/midi-note_off-create.go b/internal/processor/midi-note_off-create.go index 6d7a8d3..ae85d0a 100644 --- a/internal/processor/midi-note_off-create.go +++ b/internal/processor/midi-note_off-create.go @@ -15,70 +15,6 @@ import ( "gitlab.com/gomidi/midi/v2" ) -type MIDINoteOffCreate struct { - config config.ProcessorConfig - Channel *template.Template - Note *template.Template - Velocity *template.Template -} - -func (mnoc *MIDINoteOffCreate) Process(ctx context.Context, wrappedPayload common.WrappedPayload) (common.WrappedPayload, error) { - templateData := wrappedPayload - - var channelBuffer bytes.Buffer - err := mnoc.Channel.Execute(&channelBuffer, templateData) - - if err != nil { - wrappedPayload.End = true - return wrappedPayload, err - } - - channelValue, err := strconv.ParseUint(channelBuffer.String(), 10, 8) - - if err != nil { - wrappedPayload.End = true - return wrappedPayload, err - } - - var noteBuffer bytes.Buffer - err = mnoc.Note.Execute(¬eBuffer, templateData) - - if err != nil { - wrappedPayload.End = true - return wrappedPayload, err - } - - noteValue, err := strconv.ParseUint(noteBuffer.String(), 10, 8) - - if err != nil { - wrappedPayload.End = true - return wrappedPayload, err - } - - var velocityBuffer bytes.Buffer - err = mnoc.Velocity.Execute(&velocityBuffer, templateData) - - if err != nil { - wrappedPayload.End = true - return wrappedPayload, err - } - - velocityValue, err := strconv.ParseUint(velocityBuffer.String(), 10, 8) - - if err != nil { - wrappedPayload.End = true - return wrappedPayload, err - } - - payloadMessage := midi.NoteOffVelocity(uint8(channelValue), uint8(noteValue), uint8(velocityValue)) - wrappedPayload.Payload = payloadMessage - return wrappedPayload, nil -} - -func (mnoc *MIDINoteOffCreate) Type() string { - return mnoc.config.Type -} - func init() { RegisterProcessor(ProcessorRegistration{ Type: "midi.note_off.create", @@ -146,3 +82,67 @@ func init() { }, }) } + +type MIDINoteOffCreate struct { + config config.ProcessorConfig + Channel *template.Template + Note *template.Template + Velocity *template.Template +} + +func (mnoc *MIDINoteOffCreate) Process(ctx context.Context, wrappedPayload common.WrappedPayload) (common.WrappedPayload, error) { + templateData := wrappedPayload + + var channelBuffer bytes.Buffer + err := mnoc.Channel.Execute(&channelBuffer, templateData) + + if err != nil { + wrappedPayload.End = true + return wrappedPayload, err + } + + channelValue, err := strconv.ParseUint(channelBuffer.String(), 10, 8) + + if err != nil { + wrappedPayload.End = true + return wrappedPayload, err + } + + var noteBuffer bytes.Buffer + err = mnoc.Note.Execute(¬eBuffer, templateData) + + if err != nil { + wrappedPayload.End = true + return wrappedPayload, err + } + + noteValue, err := strconv.ParseUint(noteBuffer.String(), 10, 8) + + if err != nil { + wrappedPayload.End = true + return wrappedPayload, err + } + + var velocityBuffer bytes.Buffer + err = mnoc.Velocity.Execute(&velocityBuffer, templateData) + + if err != nil { + wrappedPayload.End = true + return wrappedPayload, err + } + + velocityValue, err := strconv.ParseUint(velocityBuffer.String(), 10, 8) + + if err != nil { + wrappedPayload.End = true + return wrappedPayload, err + } + + payloadMessage := midi.NoteOffVelocity(uint8(channelValue), uint8(noteValue), uint8(velocityValue)) + wrappedPayload.Payload = payloadMessage + return wrappedPayload, nil +} + +func (mnoc *MIDINoteOffCreate) Type() string { + return mnoc.config.Type +} diff --git a/internal/processor/midi-note_on-create.go b/internal/processor/midi-note_on-create.go index 9b62a23..c19cd0f 100644 --- a/internal/processor/midi-note_on-create.go +++ b/internal/processor/midi-note_on-create.go @@ -15,69 +15,6 @@ import ( "gitlab.com/gomidi/midi/v2" ) -type MIDINoteOnCreate struct { - config config.ProcessorConfig - Channel *template.Template - Note *template.Template - Velocity *template.Template -} - -func (mnoc *MIDINoteOnCreate) Process(ctx context.Context, wrappedPayload common.WrappedPayload) (common.WrappedPayload, error) { - templateData := wrappedPayload - - var channelBuffer bytes.Buffer - err := mnoc.Channel.Execute(&channelBuffer, templateData) - - if err != nil { - wrappedPayload.End = true - return wrappedPayload, err - } - - channelValue, err := strconv.ParseUint(channelBuffer.String(), 10, 8) - - if err != nil { - wrappedPayload.End = true - return wrappedPayload, err - } - - var noteBuffer bytes.Buffer - err = mnoc.Note.Execute(¬eBuffer, templateData) - - if err != nil { - wrappedPayload.End = true - return wrappedPayload, err - } - - noteValue, err := strconv.ParseUint(noteBuffer.String(), 10, 8) - - if err != nil { - wrappedPayload.End = true - return wrappedPayload, err - } - - var velocityBuffer bytes.Buffer - err = mnoc.Velocity.Execute(&velocityBuffer, templateData) - - if err != nil { - wrappedPayload.End = true - return wrappedPayload, err - } - - velocityValue, err := strconv.ParseUint(velocityBuffer.String(), 10, 8) - if err != nil { - wrappedPayload.End = true - return wrappedPayload, err - } - - payloadMessage := midi.NoteOn(uint8(channelValue), uint8(noteValue), uint8(velocityValue)) - wrappedPayload.Payload = payloadMessage - return wrappedPayload, nil -} - -func (mnoc *MIDINoteOnCreate) Type() string { - return mnoc.config.Type -} - func init() { RegisterProcessor(ProcessorRegistration{ Type: "midi.note_on.create", @@ -145,3 +82,66 @@ func init() { }, }) } + +type MIDINoteOnCreate struct { + config config.ProcessorConfig + Channel *template.Template + Note *template.Template + Velocity *template.Template +} + +func (mnoc *MIDINoteOnCreate) Process(ctx context.Context, wrappedPayload common.WrappedPayload) (common.WrappedPayload, error) { + templateData := wrappedPayload + + var channelBuffer bytes.Buffer + err := mnoc.Channel.Execute(&channelBuffer, templateData) + + if err != nil { + wrappedPayload.End = true + return wrappedPayload, err + } + + channelValue, err := strconv.ParseUint(channelBuffer.String(), 10, 8) + + if err != nil { + wrappedPayload.End = true + return wrappedPayload, err + } + + var noteBuffer bytes.Buffer + err = mnoc.Note.Execute(¬eBuffer, templateData) + + if err != nil { + wrappedPayload.End = true + return wrappedPayload, err + } + + noteValue, err := strconv.ParseUint(noteBuffer.String(), 10, 8) + + if err != nil { + wrappedPayload.End = true + return wrappedPayload, err + } + + var velocityBuffer bytes.Buffer + err = mnoc.Velocity.Execute(&velocityBuffer, templateData) + + if err != nil { + wrappedPayload.End = true + return wrappedPayload, err + } + + velocityValue, err := strconv.ParseUint(velocityBuffer.String(), 10, 8) + if err != nil { + wrappedPayload.End = true + return wrappedPayload, err + } + + payloadMessage := midi.NoteOn(uint8(channelValue), uint8(noteValue), uint8(velocityValue)) + wrappedPayload.Payload = payloadMessage + return wrappedPayload, nil +} + +func (mnoc *MIDINoteOnCreate) Type() string { + return mnoc.config.Type +} diff --git a/internal/processor/midi-program_change-create.go b/internal/processor/midi-program_change-create.go index 2e54c61..c49a851 100644 --- a/internal/processor/midi-program_change-create.go +++ b/internal/processor/midi-program_change-create.go @@ -15,54 +15,6 @@ import ( "gitlab.com/gomidi/midi/v2" ) -type MIDIProgramChangeCreate struct { - config config.ProcessorConfig - Channel *template.Template - Program *template.Template -} - -func (mpcc *MIDIProgramChangeCreate) Process(ctx context.Context, wrappedPayload common.WrappedPayload) (common.WrappedPayload, error) { - templateData := wrappedPayload - - var channelBuffer bytes.Buffer - err := mpcc.Channel.Execute(&channelBuffer, templateData) - - if err != nil { - wrappedPayload.End = true - return wrappedPayload, err - } - - channelValue, err := strconv.ParseUint(channelBuffer.String(), 10, 8) - - if err != nil { - wrappedPayload.End = true - return wrappedPayload, err - } - - var programBuffer bytes.Buffer - err = mpcc.Program.Execute(&programBuffer, templateData) - - if err != nil { - wrappedPayload.End = true - return wrappedPayload, err - } - - programValue, err := strconv.ParseUint(programBuffer.String(), 10, 8) - - if err != nil { - wrappedPayload.End = true - return wrappedPayload, err - } - - payloadMessage := midi.ProgramChange(uint8(channelValue), uint8(programValue)) - wrappedPayload.Payload = payloadMessage - return wrappedPayload, nil -} - -func (mpcc *MIDIProgramChangeCreate) Type() string { - return mpcc.config.Type -} - func init() { RegisterProcessor(ProcessorRegistration{ Type: "midi.program_change.create", @@ -114,3 +66,51 @@ func init() { }, }) } + +type MIDIProgramChangeCreate struct { + config config.ProcessorConfig + Channel *template.Template + Program *template.Template +} + +func (mpcc *MIDIProgramChangeCreate) Process(ctx context.Context, wrappedPayload common.WrappedPayload) (common.WrappedPayload, error) { + templateData := wrappedPayload + + var channelBuffer bytes.Buffer + err := mpcc.Channel.Execute(&channelBuffer, templateData) + + if err != nil { + wrappedPayload.End = true + return wrappedPayload, err + } + + channelValue, err := strconv.ParseUint(channelBuffer.String(), 10, 8) + + if err != nil { + wrappedPayload.End = true + return wrappedPayload, err + } + + var programBuffer bytes.Buffer + err = mpcc.Program.Execute(&programBuffer, templateData) + + if err != nil { + wrappedPayload.End = true + return wrappedPayload, err + } + + programValue, err := strconv.ParseUint(programBuffer.String(), 10, 8) + + if err != nil { + wrappedPayload.End = true + return wrappedPayload, err + } + + payloadMessage := midi.ProgramChange(uint8(channelValue), uint8(programValue)) + wrappedPayload.Payload = payloadMessage + return wrappedPayload, nil +} + +func (mpcc *MIDIProgramChangeCreate) Type() string { + return mpcc.config.Type +} diff --git a/internal/processor/module-output.go b/internal/processor/module-output.go index 13fecd3..a4491ac 100644 --- a/internal/processor/module-output.go +++ b/internal/processor/module-output.go @@ -11,6 +11,37 @@ import ( "github.com/jwetzell/showbridge-go/internal/config" ) +func init() { + RegisterProcessor(ProcessorRegistration{ + Type: "module.output", + Title: "Module Output", + ParamsSchema: &jsonschema.Schema{ + Type: "object", + Properties: map[string]*jsonschema.Schema{ + "module": { + Title: "Module ID", + Type: "string", + Description: "ID of module to send output to", + }, + }, + Required: []string{"module"}, + AdditionalProperties: &jsonschema.Schema{Not: &jsonschema.Schema{}}, + }, + New: func(config config.ProcessorConfig) (Processor, error) { + + params := config.Params + + moduleId, err := params.GetString("module") + + if err != nil { + return nil, fmt.Errorf("module.output module error: %w", err) + } + + return &ModuleOutput{config: config, ModuleId: moduleId, logger: slog.Default().With("component", "processor", "type", config.Type)}, nil + }, + }) +} + type ModuleOutput struct { config config.ProcessorConfig ModuleId string @@ -53,34 +84,3 @@ func (mo *ModuleOutput) Process(ctx context.Context, wrappedPayload common.Wrapp func (mo *ModuleOutput) Type() string { return mo.config.Type } - -func init() { - RegisterProcessor(ProcessorRegistration{ - Type: "module.output", - Title: "Module Output", - ParamsSchema: &jsonschema.Schema{ - Type: "object", - Properties: map[string]*jsonschema.Schema{ - "module": { - Title: "Module ID", - Type: "string", - Description: "ID of module to send output to", - }, - }, - Required: []string{"module"}, - AdditionalProperties: &jsonschema.Schema{Not: &jsonschema.Schema{}}, - }, - New: func(config config.ProcessorConfig) (Processor, error) { - - params := config.Params - - moduleId, err := params.GetString("module") - - if err != nil { - return nil, fmt.Errorf("module.output module error: %w", err) - } - - return &ModuleOutput{config: config, ModuleId: moduleId, logger: slog.Default().With("component", "processor", "type", config.Type)}, nil - }, - }) -} diff --git a/internal/processor/osc-message-create.go b/internal/processor/osc-message-create.go index b199a67..3820220 100644 --- a/internal/processor/osc-message-create.go +++ b/internal/processor/osc-message-create.go @@ -15,76 +15,6 @@ import ( "github.com/jwetzell/showbridge-go/internal/config" ) -type OSCMessageCreate struct { - config config.ProcessorConfig - Address *template.Template - Args []*template.Template - Types string -} - -func (omc *OSCMessageCreate) Process(ctx context.Context, wrappedPayload common.WrappedPayload) (common.WrappedPayload, error) { - - templateData := wrappedPayload - - var addressBuffer bytes.Buffer - err := omc.Address.Execute(&addressBuffer, templateData) - - if err != nil { - wrappedPayload.End = true - return wrappedPayload, err - } - - addressString := addressBuffer.String() - - if len(addressString) == 0 { - wrappedPayload.End = true - return wrappedPayload, errors.New("osc.message.create address must not be empty") - } - - if addressString[0] != '/' { - wrappedPayload.End = true - return wrappedPayload, errors.New("osc.message.create address must start with '/'") - } - - payloadMessage := &osc.OSCMessage{ - Address: addressString, - } - - args := []osc.OSCArg{} - - for argIndex, argTemplate := range omc.Args { - var argBuffer bytes.Buffer - err := argTemplate.Execute(&argBuffer, templateData) - - if err != nil { - wrappedPayload.End = true - return wrappedPayload, err - } - - argString := argBuffer.String() - - typedArg, err := argToTypedArg(argString, omc.Types[argIndex]) - - if err != nil { - wrappedPayload.End = true - return wrappedPayload, err - } - - args = append(args, typedArg) - } - - if len(args) > 0 { - payloadMessage.Args = args - } - - wrappedPayload.Payload = payloadMessage - return wrappedPayload, nil -} - -func (omc *OSCMessageCreate) Type() string { - return omc.config.Type -} - func init() { RegisterProcessor(ProcessorRegistration{ Type: "osc.message.create", @@ -158,6 +88,76 @@ func init() { }) } +type OSCMessageCreate struct { + config config.ProcessorConfig + Address *template.Template + Args []*template.Template + Types string +} + +func (omc *OSCMessageCreate) Process(ctx context.Context, wrappedPayload common.WrappedPayload) (common.WrappedPayload, error) { + + templateData := wrappedPayload + + var addressBuffer bytes.Buffer + err := omc.Address.Execute(&addressBuffer, templateData) + + if err != nil { + wrappedPayload.End = true + return wrappedPayload, err + } + + addressString := addressBuffer.String() + + if len(addressString) == 0 { + wrappedPayload.End = true + return wrappedPayload, errors.New("osc.message.create address must not be empty") + } + + if addressString[0] != '/' { + wrappedPayload.End = true + return wrappedPayload, errors.New("osc.message.create address must start with '/'") + } + + payloadMessage := &osc.OSCMessage{ + Address: addressString, + } + + args := []osc.OSCArg{} + + for argIndex, argTemplate := range omc.Args { + var argBuffer bytes.Buffer + err := argTemplate.Execute(&argBuffer, templateData) + + if err != nil { + wrappedPayload.End = true + return wrappedPayload, err + } + + argString := argBuffer.String() + + typedArg, err := argToTypedArg(argString, omc.Types[argIndex]) + + if err != nil { + wrappedPayload.End = true + return wrappedPayload, err + } + + args = append(args, typedArg) + } + + if len(args) > 0 { + payloadMessage.Args = args + } + + wrappedPayload.Payload = payloadMessage + return wrappedPayload, nil +} + +func (omc *OSCMessageCreate) Type() string { + return omc.config.Type +} + func argToTypedArg(rawArg string, oscType byte) (osc.OSCArg, error) { switch oscType { diff --git a/internal/processor/osc-message-decode.go b/internal/processor/osc-message-decode.go index 3469444..3a40989 100644 --- a/internal/processor/osc-message-decode.go +++ b/internal/processor/osc-message-decode.go @@ -10,6 +10,16 @@ import ( "github.com/jwetzell/showbridge-go/internal/config" ) +func init() { + RegisterProcessor(ProcessorRegistration{ + Type: "osc.message.decode", + Title: "Decode OSC Message", + New: func(config config.ProcessorConfig) (Processor, error) { + return &OSCMessageDecode{config: config}, nil + }, + }) +} + type OSCMessageDecode struct { config config.ProcessorConfig } @@ -45,13 +55,3 @@ func (omd *OSCMessageDecode) Process(ctx context.Context, wrappedPayload common. func (omd *OSCMessageDecode) Type() string { return omd.config.Type } - -func init() { - RegisterProcessor(ProcessorRegistration{ - Type: "osc.message.decode", - Title: "Decode OSC Message", - New: func(config config.ProcessorConfig) (Processor, error) { - return &OSCMessageDecode{config: config}, nil - }, - }) -} diff --git a/internal/processor/osc-message-encode.go b/internal/processor/osc-message-encode.go index ef41141..74ec952 100644 --- a/internal/processor/osc-message-encode.go +++ b/internal/processor/osc-message-encode.go @@ -14,6 +14,16 @@ type OSCMessageEncode struct { config config.ProcessorConfig } +func init() { + RegisterProcessor(ProcessorRegistration{ + Type: "osc.message.encode", + Title: "Encode OSC Message", + New: func(config config.ProcessorConfig) (Processor, error) { + return &OSCMessageEncode{config: config}, nil + }, + }) +} + func (ome *OSCMessageEncode) Process(ctx context.Context, wrappedPayload common.WrappedPayload) (common.WrappedPayload, error) { payload := wrappedPayload.Payload payloadMessage, ok := common.GetAnyAs[*osc.OSCMessage](payload) @@ -35,13 +45,3 @@ func (ome *OSCMessageEncode) Process(ctx context.Context, wrappedPayload common. func (ome *OSCMessageEncode) Type() string { return ome.config.Type } - -func init() { - RegisterProcessor(ProcessorRegistration{ - Type: "osc.message.encode", - Title: "Encode OSC Message", - New: func(config config.ProcessorConfig) (Processor, error) { - return &OSCMessageEncode{config: config}, nil - }, - }) -} diff --git a/internal/processor/pubsub-publish.go b/internal/processor/pubsub-publish.go index b9c7a4e..34965e9 100644 --- a/internal/processor/pubsub-publish.go +++ b/internal/processor/pubsub-publish.go @@ -13,6 +13,51 @@ import ( "github.com/jwetzell/showbridge-go/internal/config" ) +func init() { + RegisterProcessor(ProcessorRegistration{ + Type: "pubsub.publish", + Title: "Publish to Pub/Sub Topic", + ParamsSchema: &jsonschema.Schema{ + Type: "object", + Properties: map[string]*jsonschema.Schema{ + "module": { + Title: "Module ID", + Type: "string", + Description: "ID of the module to publish to", + }, + "topic": { + Title: "Topic", + Type: "string", + Description: "Topic to publish to", + }, + }, + Required: []string{"module", "topic"}, + AdditionalProperties: &jsonschema.Schema{Not: &jsonschema.Schema{}}, + }, + New: func(config config.ProcessorConfig) (Processor, error) { + + params := config.Params + + moduleIdString, err := params.GetString("module") + if err != nil { + return nil, fmt.Errorf("pubsub.publish module error: %w", err) + } + + topicString, err := params.GetString("topic") + if err != nil { + return nil, fmt.Errorf("pubsub.publish topic error: %w", err) + } + + topicTemplate, err := template.New("topic").Parse(topicString) + + if err != nil { + return nil, err + } + return &PubSubPublish{config: config, ModuleId: moduleIdString, Topic: topicTemplate, logger: slog.Default().With("component", "processor", "type", config.Type)}, nil + }, + }) +} + type PubSubPublish struct { config config.ProcessorConfig ModuleId string @@ -62,48 +107,3 @@ func (psp *PubSubPublish) Process(ctx context.Context, wrappedPayload common.Wra func (psp *PubSubPublish) Type() string { return psp.config.Type } - -func init() { - RegisterProcessor(ProcessorRegistration{ - Type: "pubsub.publish", - Title: "Publish to Pub/Sub Topic", - ParamsSchema: &jsonschema.Schema{ - Type: "object", - Properties: map[string]*jsonschema.Schema{ - "module": { - Title: "Module ID", - Type: "string", - Description: "ID of the module to publish to", - }, - "topic": { - Title: "Topic", - Type: "string", - Description: "Topic to publish to", - }, - }, - Required: []string{"module", "topic"}, - AdditionalProperties: &jsonschema.Schema{Not: &jsonschema.Schema{}}, - }, - New: func(config config.ProcessorConfig) (Processor, error) { - - params := config.Params - - moduleIdString, err := params.GetString("module") - if err != nil { - return nil, fmt.Errorf("pubsub.publish module error: %w", err) - } - - topicString, err := params.GetString("topic") - if err != nil { - return nil, fmt.Errorf("pubsub.publish topic error: %w", err) - } - - topicTemplate, err := template.New("topic").Parse(topicString) - - if err != nil { - return nil, err - } - return &PubSubPublish{config: config, ModuleId: moduleIdString, Topic: topicTemplate, logger: slog.Default().With("component", "processor", "type", config.Type)}, nil - }, - }) -} diff --git a/internal/processor/router-input.go b/internal/processor/router-input.go index f8af748..ea402cf 100644 --- a/internal/processor/router-input.go +++ b/internal/processor/router-input.go @@ -11,36 +11,6 @@ import ( "github.com/jwetzell/showbridge-go/internal/config" ) -type RouterInput struct { - config config.ProcessorConfig - SourceId string - logger *slog.Logger -} - -func (ri *RouterInput) Process(ctx context.Context, wrappedPayload common.WrappedPayload) (common.WrappedPayload, error) { - - payload := wrappedPayload.Payload - if wrappedPayload.InputHandler == nil { - wrappedPayload.End = true - return wrappedPayload, errors.New("router.input no input handler found") - } - - _, err := wrappedPayload.InputHandler(ctx, ri.SourceId, payload) - - if err != nil { - wrappedPayload.End = true - return wrappedPayload, errors.New("router.input failed to send input") - } - - wrappedPayload.Payload = payload - - return wrappedPayload, nil -} - -func (ri *RouterInput) Type() string { - return ri.config.Type -} - func init() { RegisterProcessor(ProcessorRegistration{ Type: "router.input", @@ -71,3 +41,33 @@ func init() { }, }) } + +type RouterInput struct { + config config.ProcessorConfig + SourceId string + logger *slog.Logger +} + +func (ri *RouterInput) Process(ctx context.Context, wrappedPayload common.WrappedPayload) (common.WrappedPayload, error) { + + payload := wrappedPayload.Payload + if wrappedPayload.InputHandler == nil { + wrappedPayload.End = true + return wrappedPayload, errors.New("router.input no input handler found") + } + + _, err := wrappedPayload.InputHandler(ctx, ri.SourceId, payload) + + if err != nil { + wrappedPayload.End = true + return wrappedPayload, errors.New("router.input failed to send input") + } + + wrappedPayload.Payload = payload + + return wrappedPayload, nil +} + +func (ri *RouterInput) Type() string { + return ri.config.Type +} diff --git a/internal/processor/script-expr.go b/internal/processor/script-expr.go index 00d03f7..c3b15dc 100644 --- a/internal/processor/script-expr.go +++ b/internal/processor/script-expr.go @@ -17,24 +17,6 @@ type ScriptExpr struct { Program *vm.Program } -func (se *ScriptExpr) Process(ctx context.Context, wrappedPayload common.WrappedPayload) (common.WrappedPayload, error) { - - exprEnv := wrappedPayload - - output, err := expr.Run(se.Program, exprEnv) - if err != nil { - wrappedPayload.End = true - return wrappedPayload, err - } - - wrappedPayload.Payload = output - return wrappedPayload, nil -} - -func (se *ScriptExpr) Type() string { - return se.config.Type -} - func init() { RegisterProcessor(ProcessorRegistration{ Type: "script.expr", @@ -67,3 +49,21 @@ func init() { }, }) } + +func (se *ScriptExpr) Process(ctx context.Context, wrappedPayload common.WrappedPayload) (common.WrappedPayload, error) { + + exprEnv := wrappedPayload + + output, err := expr.Run(se.Program, exprEnv) + if err != nil { + wrappedPayload.End = true + return wrappedPayload, err + } + + wrappedPayload.Payload = output + return wrappedPayload, nil +} + +func (se *ScriptExpr) Type() string { + return se.config.Type +} diff --git a/internal/processor/script-js.go b/internal/processor/script-js.go index 719a97d..4cdb5bb 100644 --- a/internal/processor/script-js.go +++ b/internal/processor/script-js.go @@ -10,6 +10,50 @@ import ( "modernc.org/quickjs" ) +func init() { + RegisterProcessor(ProcessorRegistration{ + Type: "script.js", + Title: "Run JavaScript", + ParamsSchema: &jsonschema.Schema{ + Type: "object", + Properties: map[string]*jsonschema.Schema{ + "program": { + Title: "Program", + Type: "string", + }, + }, + Required: []string{"program"}, + AdditionalProperties: &jsonschema.Schema{Not: &jsonschema.Schema{}}, + }, + New: func(config config.ProcessorConfig) (Processor, error) { + params := config.Params + + programString, err := params.GetString("program") + if err != nil { + return nil, fmt.Errorf("script.js program error: %w", err) + } + + vm, err := quickjs.NewVM() + + if err != nil { + return nil, err + } + + payloadAtom, err := vm.NewAtom("payload") + if err != nil { + return nil, err + } + + senderAtom, err := vm.NewAtom("sender") + if err != nil { + return nil, err + } + + return &ScriptJS{config: config, Program: programString, vm: vm, payloadAtom: payloadAtom, senderAtom: senderAtom}, nil + }, + }) +} + type ScriptJS struct { config config.ProcessorConfig vm *quickjs.VM @@ -93,47 +137,3 @@ func (sj *ScriptJS) Process(ctx context.Context, wrappedPayload common.WrappedPa func (sj *ScriptJS) Type() string { return sj.config.Type } - -func init() { - RegisterProcessor(ProcessorRegistration{ - Type: "script.js", - Title: "Run JavaScript", - ParamsSchema: &jsonschema.Schema{ - Type: "object", - Properties: map[string]*jsonschema.Schema{ - "program": { - Title: "Program", - Type: "string", - }, - }, - Required: []string{"program"}, - AdditionalProperties: &jsonschema.Schema{Not: &jsonschema.Schema{}}, - }, - New: func(config config.ProcessorConfig) (Processor, error) { - params := config.Params - - programString, err := params.GetString("program") - if err != nil { - return nil, fmt.Errorf("script.js program error: %w", err) - } - - vm, err := quickjs.NewVM() - - if err != nil { - return nil, err - } - - payloadAtom, err := vm.NewAtom("payload") - if err != nil { - return nil, err - } - - senderAtom, err := vm.NewAtom("sender") - if err != nil { - return nil, err - } - - return &ScriptJS{config: config, Program: programString, vm: vm, payloadAtom: payloadAtom, senderAtom: senderAtom}, nil - }, - }) -} diff --git a/internal/processor/script-wasm.go b/internal/processor/script-wasm.go index 3954197..04929ba 100644 --- a/internal/processor/script-wasm.go +++ b/internal/processor/script-wasm.go @@ -12,37 +12,6 @@ import ( "github.com/jwetzell/showbridge-go/internal/config" ) -type ScriptWASM struct { - config config.ProcessorConfig - Program *extism.Plugin - Function string -} - -func (sw *ScriptWASM) Process(ctx context.Context, wrappedPayload common.WrappedPayload) (common.WrappedPayload, error) { - - payload := wrappedPayload.Payload - payloadBytes, ok := common.GetAnyAsByteSlice(payload) - - if !ok { - wrappedPayload.End = true - return wrappedPayload, fmt.Errorf("script.wasm can only process a byte array") - } - - _, output, err := sw.Program.Call(sw.Function, payloadBytes) - - if err != nil { - wrappedPayload.End = true - return wrappedPayload, err - } - wrappedPayload.Payload = output - - return wrappedPayload, nil -} - -func (sw *ScriptWASM) Type() string { - return sw.config.Type -} - func init() { RegisterProcessor(ProcessorRegistration{ Type: "script.wasm", @@ -120,3 +89,34 @@ func init() { }, }) } + +type ScriptWASM struct { + config config.ProcessorConfig + Program *extism.Plugin + Function string +} + +func (sw *ScriptWASM) Process(ctx context.Context, wrappedPayload common.WrappedPayload) (common.WrappedPayload, error) { + + payload := wrappedPayload.Payload + payloadBytes, ok := common.GetAnyAsByteSlice(payload) + + if !ok { + wrappedPayload.End = true + return wrappedPayload, fmt.Errorf("script.wasm can only process a byte array") + } + + _, output, err := sw.Program.Call(sw.Function, payloadBytes) + + if err != nil { + wrappedPayload.End = true + return wrappedPayload, err + } + wrappedPayload.Payload = output + + return wrappedPayload, nil +} + +func (sw *ScriptWASM) Type() string { + return sw.config.Type +} diff --git a/internal/processor/sip-response-audio-create.go b/internal/processor/sip-response-audio-create.go index e2265ea..26b4f9b 100644 --- a/internal/processor/sip-response-audio-create.go +++ b/internal/processor/sip-response-audio-create.go @@ -11,45 +11,6 @@ import ( "github.com/jwetzell/showbridge-go/internal/config" ) -type SipResponseAudioCreate struct { - config config.ProcessorConfig - PreWait int - PostWait int - AudioFile *template.Template -} - -type SipAudioFileResponse struct { - PreWait int - PostWait int - AudioFile string -} - -func (srac *SipResponseAudioCreate) Process(ctx context.Context, wrappedPayload common.WrappedPayload) (common.WrappedPayload, error) { - - templateData := wrappedPayload - - var audioFileBuffer bytes.Buffer - err := srac.AudioFile.Execute(&audioFileBuffer, templateData) - - if err != nil { - wrappedPayload.End = true - return wrappedPayload, err - } - - audioFileString := audioFileBuffer.String() - - wrappedPayload.Payload = SipAudioFileResponse{ - PreWait: srac.PreWait, - PostWait: srac.PostWait, - AudioFile: audioFileString, - } - return wrappedPayload, nil -} - -func (srac *SipResponseAudioCreate) Type() string { - return srac.config.Type -} - func init() { RegisterProcessor(ProcessorRegistration{ Type: "sip.response.audio.create", @@ -99,3 +60,42 @@ func init() { }, }) } + +type SipResponseAudioCreate struct { + config config.ProcessorConfig + PreWait int + PostWait int + AudioFile *template.Template +} + +type SipAudioFileResponse struct { + PreWait int + PostWait int + AudioFile string +} + +func (srac *SipResponseAudioCreate) Process(ctx context.Context, wrappedPayload common.WrappedPayload) (common.WrappedPayload, error) { + + templateData := wrappedPayload + + var audioFileBuffer bytes.Buffer + err := srac.AudioFile.Execute(&audioFileBuffer, templateData) + + if err != nil { + wrappedPayload.End = true + return wrappedPayload, err + } + + audioFileString := audioFileBuffer.String() + + wrappedPayload.Payload = SipAudioFileResponse{ + PreWait: srac.PreWait, + PostWait: srac.PostWait, + AudioFile: audioFileString, + } + return wrappedPayload, nil +} + +func (srac *SipResponseAudioCreate) Type() string { + return srac.config.Type +} diff --git a/internal/processor/sip-response-dtmf-create.go b/internal/processor/sip-response-dtmf-create.go index 9c372d8..2bb0fdc 100644 --- a/internal/processor/sip-response-dtmf-create.go +++ b/internal/processor/sip-response-dtmf-create.go @@ -13,53 +13,6 @@ import ( "github.com/jwetzell/showbridge-go/internal/config" ) -type SipResponseDTMFCreate struct { - config config.ProcessorConfig - PreWait int - PostWait int - Digits *template.Template - validDTMF *regexp.Regexp -} - -type SipDTMFResponse struct { - PreWait int - PostWait int - Digits string -} - -var validDTMFRegex = regexp.MustCompile(`^[0-9*#A-Da-d]+$`) - -func (srdc *SipResponseDTMFCreate) Process(ctx context.Context, wrappedPayload common.WrappedPayload) (common.WrappedPayload, error) { - - templateData := wrappedPayload - - var digitsBuffer bytes.Buffer - err := srdc.Digits.Execute(&digitsBuffer, templateData) - - if err != nil { - wrappedPayload.End = true - return wrappedPayload, err - } - - digitsString := digitsBuffer.String() - - if !srdc.validDTMF.MatchString(digitsString) { - wrappedPayload.End = true - return wrappedPayload, errors.New("sip.response.dtmf.create result of digits template contains invalid characters") - } - - wrappedPayload.Payload = SipDTMFResponse{ - PreWait: srdc.PreWait, - PostWait: srdc.PostWait, - Digits: digitsString, - } - return wrappedPayload, nil -} - -func (srdc *SipResponseDTMFCreate) Type() string { - return srdc.config.Type -} - func init() { RegisterProcessor(ProcessorRegistration{ Type: "sip.response.dtmf.create", @@ -109,3 +62,50 @@ func init() { }, }) } + +type SipResponseDTMFCreate struct { + config config.ProcessorConfig + PreWait int + PostWait int + Digits *template.Template + validDTMF *regexp.Regexp +} + +type SipDTMFResponse struct { + PreWait int + PostWait int + Digits string +} + +var validDTMFRegex = regexp.MustCompile(`^[0-9*#A-Da-d]+$`) + +func (srdc *SipResponseDTMFCreate) Process(ctx context.Context, wrappedPayload common.WrappedPayload) (common.WrappedPayload, error) { + + templateData := wrappedPayload + + var digitsBuffer bytes.Buffer + err := srdc.Digits.Execute(&digitsBuffer, templateData) + + if err != nil { + wrappedPayload.End = true + return wrappedPayload, err + } + + digitsString := digitsBuffer.String() + + if !srdc.validDTMF.MatchString(digitsString) { + wrappedPayload.End = true + return wrappedPayload, errors.New("sip.response.dtmf.create result of digits template contains invalid characters") + } + + wrappedPayload.Payload = SipDTMFResponse{ + PreWait: srdc.PreWait, + PostWait: srdc.PostWait, + Digits: digitsString, + } + return wrappedPayload, nil +} + +func (srdc *SipResponseDTMFCreate) Type() string { + return srdc.config.Type +} diff --git a/internal/processor/string-create.go b/internal/processor/string-create.go index ed05f63..db54134 100644 --- a/internal/processor/string-create.go +++ b/internal/processor/string-create.go @@ -11,31 +11,6 @@ import ( "github.com/jwetzell/showbridge-go/internal/config" ) -type StringCreate struct { - config config.ProcessorConfig - Template *template.Template -} - -func (sc *StringCreate) Process(ctx context.Context, wrappedPayload common.WrappedPayload) (common.WrappedPayload, error) { - templateData := wrappedPayload - - var templateBuffer bytes.Buffer - err := sc.Template.Execute(&templateBuffer, templateData) - - if err != nil { - wrappedPayload.End = true - return wrappedPayload, err - } - - wrappedPayload.Payload = templateBuffer.String() - - return wrappedPayload, nil -} - -func (sc *StringCreate) Type() string { - return sc.config.Type -} - func init() { RegisterProcessor(ProcessorRegistration{ Type: "string.create", @@ -67,3 +42,28 @@ func init() { }, }) } + +type StringCreate struct { + config config.ProcessorConfig + Template *template.Template +} + +func (sc *StringCreate) Process(ctx context.Context, wrappedPayload common.WrappedPayload) (common.WrappedPayload, error) { + templateData := wrappedPayload + + var templateBuffer bytes.Buffer + err := sc.Template.Execute(&templateBuffer, templateData) + + if err != nil { + wrappedPayload.End = true + return wrappedPayload, err + } + + wrappedPayload.Payload = templateBuffer.String() + + return wrappedPayload, nil +} + +func (sc *StringCreate) Type() string { + return sc.config.Type +} diff --git a/internal/processor/string-decode.go b/internal/processor/string-decode.go index 029a309..2cf6bd0 100644 --- a/internal/processor/string-decode.go +++ b/internal/processor/string-decode.go @@ -8,6 +8,16 @@ import ( "github.com/jwetzell/showbridge-go/internal/config" ) +func init() { + RegisterProcessor(ProcessorRegistration{ + Type: "string.decode", + Title: "Decode String", + New: func(config config.ProcessorConfig) (Processor, error) { + return &StringDecode{config: config}, nil + }, + }) +} + type StringDecode struct { config config.ProcessorConfig } @@ -30,13 +40,3 @@ func (sd *StringDecode) Process(ctx context.Context, wrappedPayload common.Wrapp func (sd *StringDecode) Type() string { return sd.config.Type } - -func init() { - RegisterProcessor(ProcessorRegistration{ - Type: "string.decode", - Title: "Decode String", - New: func(config config.ProcessorConfig) (Processor, error) { - return &StringDecode{config: config}, nil - }, - }) -} diff --git a/internal/processor/string-encode.go b/internal/processor/string-encode.go index 622e656..6d76885 100644 --- a/internal/processor/string-encode.go +++ b/internal/processor/string-encode.go @@ -8,6 +8,16 @@ import ( "github.com/jwetzell/showbridge-go/internal/config" ) +func init() { + RegisterProcessor(ProcessorRegistration{ + Type: "string.encode", + Title: "Encode String", + New: func(config config.ProcessorConfig) (Processor, error) { + return &StringEncode{config: config}, nil + }, + }) +} + type StringEncode struct { config config.ProcessorConfig } @@ -29,13 +39,3 @@ func (se *StringEncode) Process(ctx context.Context, wrappedPayload common.Wrapp func (se *StringEncode) Type() string { return se.config.Type } - -func init() { - RegisterProcessor(ProcessorRegistration{ - Type: "string.encode", - Title: "Encode String", - New: func(config config.ProcessorConfig) (Processor, error) { - return &StringEncode{config: config}, nil - }, - }) -} diff --git a/internal/processor/string-split.go b/internal/processor/string-split.go index dd3a180..8d683fc 100644 --- a/internal/processor/string-split.go +++ b/internal/processor/string-split.go @@ -11,29 +11,6 @@ import ( "github.com/jwetzell/showbridge-go/internal/config" ) -type StringSplit struct { - config config.ProcessorConfig - Separator string -} - -func (ss *StringSplit) Process(ctx context.Context, wrappedPayload common.WrappedPayload) (common.WrappedPayload, error) { - payload := wrappedPayload.Payload - payloadString, ok := common.GetAnyAs[string](payload) - - if !ok { - wrappedPayload.End = true - return wrappedPayload, errors.New("string.split only accepts a string") - } - - wrappedPayload.Payload = strings.Split(payloadString, ss.Separator) - - return wrappedPayload, nil -} - -func (ss *StringSplit) Type() string { - return ss.config.Type -} - func init() { RegisterProcessor(ProcessorRegistration{ Type: "string.split", @@ -61,3 +38,26 @@ func init() { }, }) } + +type StringSplit struct { + config config.ProcessorConfig + Separator string +} + +func (ss *StringSplit) Process(ctx context.Context, wrappedPayload common.WrappedPayload) (common.WrappedPayload, error) { + payload := wrappedPayload.Payload + payloadString, ok := common.GetAnyAs[string](payload) + + if !ok { + wrappedPayload.End = true + return wrappedPayload, errors.New("string.split only accepts a string") + } + + wrappedPayload.Payload = strings.Split(payloadString, ss.Separator) + + return wrappedPayload, nil +} + +func (ss *StringSplit) Type() string { + return ss.config.Type +} diff --git a/internal/processor/struct-field-get.go b/internal/processor/struct-field-get.go index 8c0c578..fc7b807 100644 --- a/internal/processor/struct-field-get.go +++ b/internal/processor/struct-field-get.go @@ -11,6 +11,33 @@ import ( "github.com/jwetzell/showbridge-go/internal/config" ) +func init() { + RegisterProcessor(ProcessorRegistration{ + Type: "struct.field.get", + Title: "Get Struct Field", + ParamsSchema: &jsonschema.Schema{ + Type: "object", + Properties: map[string]*jsonschema.Schema{ + "name": { + Title: "Field Name", + Type: "string", + }, + }, + Required: []string{"name"}, + AdditionalProperties: &jsonschema.Schema{Not: &jsonschema.Schema{}}, + }, + New: func(config config.ProcessorConfig) (Processor, error) { + params := config.Params + nameString, err := params.GetString("name") + if err != nil { + return nil, fmt.Errorf("struct.field.get name error: %w", err) + } + + return &StructFieldGet{config: config, Name: nameString}, nil + }, + }) +} + type StructFieldGet struct { config config.ProcessorConfig Name string @@ -42,30 +69,3 @@ func (sfg *StructFieldGet) Process(ctx context.Context, wrappedPayload common.Wr func (sfg *StructFieldGet) Type() string { return sfg.config.Type } - -func init() { - RegisterProcessor(ProcessorRegistration{ - Type: "struct.field.get", - Title: "Get Struct Field", - ParamsSchema: &jsonschema.Schema{ - Type: "object", - Properties: map[string]*jsonschema.Schema{ - "name": { - Title: "Field Name", - Type: "string", - }, - }, - Required: []string{"name"}, - AdditionalProperties: &jsonschema.Schema{Not: &jsonschema.Schema{}}, - }, - New: func(config config.ProcessorConfig) (Processor, error) { - params := config.Params - nameString, err := params.GetString("name") - if err != nil { - return nil, fmt.Errorf("struct.field.get name error: %w", err) - } - - return &StructFieldGet{config: config, Name: nameString}, nil - }, - }) -} diff --git a/internal/processor/struct-method-get.go b/internal/processor/struct-method-get.go index c770ee1..2e530cd 100644 --- a/internal/processor/struct-method-get.go +++ b/internal/processor/struct-method-get.go @@ -11,6 +11,33 @@ import ( "github.com/jwetzell/showbridge-go/internal/config" ) +func init() { + RegisterProcessor(ProcessorRegistration{ + Type: "struct.method.get", + Title: "Get Struct Method", + ParamsSchema: &jsonschema.Schema{ + Type: "object", + Properties: map[string]*jsonschema.Schema{ + "name": { + Title: "Method Name", + Type: "string", + }, + }, + Required: []string{"name"}, + AdditionalProperties: &jsonschema.Schema{Not: &jsonschema.Schema{}}, + }, + New: func(config config.ProcessorConfig) (Processor, error) { + params := config.Params + nameString, err := params.GetString("name") + if err != nil { + return nil, fmt.Errorf("struct.method.get name error: %w", err) + } + + return &StructMethodGet{config: config, Name: nameString}, nil + }, + }) +} + type StructMethodGet struct { config config.ProcessorConfig Name string @@ -61,30 +88,3 @@ func (smg *StructMethodGet) Process(ctx context.Context, wrappedPayload common.W func (smg *StructMethodGet) Type() string { return smg.config.Type } - -func init() { - RegisterProcessor(ProcessorRegistration{ - Type: "struct.method.get", - Title: "Get Struct Method", - ParamsSchema: &jsonschema.Schema{ - Type: "object", - Properties: map[string]*jsonschema.Schema{ - "name": { - Title: "Method Name", - Type: "string", - }, - }, - Required: []string{"name"}, - AdditionalProperties: &jsonschema.Schema{Not: &jsonschema.Schema{}}, - }, - New: func(config config.ProcessorConfig) (Processor, error) { - params := config.Params - nameString, err := params.GetString("name") - if err != nil { - return nil, fmt.Errorf("struct.method.get name error: %w", err) - } - - return &StructMethodGet{config: config, Name: nameString}, nil - }, - }) -} diff --git a/internal/processor/time-sleep.go b/internal/processor/time-sleep.go index 6458348..fcccd07 100644 --- a/internal/processor/time-sleep.go +++ b/internal/processor/time-sleep.go @@ -10,20 +10,6 @@ import ( "github.com/jwetzell/showbridge-go/internal/config" ) -type TimeSleep struct { - config config.ProcessorConfig - Duration time.Duration -} - -func (ts *TimeSleep) Process(ctx context.Context, wrappedPayload common.WrappedPayload) (common.WrappedPayload, error) { - time.Sleep(ts.Duration) - return wrappedPayload, nil -} - -func (ts *TimeSleep) Type() string { - return ts.config.Type -} - func init() { RegisterProcessor(ProcessorRegistration{ Type: "time.sleep", @@ -52,3 +38,17 @@ func init() { }, }) } + +type TimeSleep struct { + config config.ProcessorConfig + Duration time.Duration +} + +func (ts *TimeSleep) Process(ctx context.Context, wrappedPayload common.WrappedPayload) (common.WrappedPayload, error) { + time.Sleep(ts.Duration) + return wrappedPayload, nil +} + +func (ts *TimeSleep) Type() string { + return ts.config.Type +} diff --git a/router_test.go b/router_test.go index 223b76d..6829582 100644 --- a/router_test.go +++ b/router_test.go @@ -14,6 +14,15 @@ import ( "github.com/jwetzell/showbridge-go/internal/module" ) +func init() { + module.RegisterModule(module.ModuleRegistration{ + Type: "mock.counter", + New: func(config config.ModuleConfig) (common.Module, error) { + return &MockCounterModule{config: config, logger: slog.Default()}, nil + }, + }) +} + type MockCounterModule struct { config config.ModuleConfig ctx context.Context @@ -58,15 +67,6 @@ func (mcm *MockCounterModule) Stop() { } } -func init() { - module.RegisterModule(module.ModuleRegistration{ - Type: "mock.counter", - New: func(config config.ModuleConfig) (common.Module, error) { - return &MockCounterModule{config: config, logger: slog.Default()}, nil - }, - }) -} - func TestNewRouter(t *testing.T) { routerConfig := config.Config{ Modules: []config.ModuleConfig{