diff --git a/convert.go b/convert.go new file mode 100644 index 0000000..bb28a04 --- /dev/null +++ b/convert.go @@ -0,0 +1,57 @@ +package main + +import ( + "errors" + "os" + "strconv" +) + +func getEnvFallback(key string, fallback ...string) (string, error) { + // Check for function fallback signature + length := len(fallback) + if length > 1 { + return "", errors.New("Invalid signature: Too many fallback values provided!") + } + + // Try to get environment variable + value, exists := os.LookupEnv(key) + if exists { + return value, nil + } + + // Try using fallback value instead + if length == 1 { + return fallback[0], nil + } else if length == 0 { + // No fallback value provided + return "", errors.New("Panic: No fallback value provided!") + } + + // Could not get environment variable + return "", errors.New("Could not get environment variable: " + key) +} + +func convertFallback(input string, fallback ...int) (int, error) { + // Check for function fallback signature + length := len(fallback) + if length > 1 { + return 0, errors.New("Invalid signature: Too many fallback values provided!") + } + + // Try to convert input to int + value, err := strconv.Atoi(input) + if err == nil { + return value, nil + } + + // Try using fallback value instead + if length == 1 { + return fallback[0], nil + } else if length == 0 { + // No fallback value provided + return 0, errors.New("Panic: No fallback value provided!") + } + + // Could not convert input + return 0, err +} diff --git a/main.go b/main.go index b1ae262..0650be8 100644 --- a/main.go +++ b/main.go @@ -1,182 +1,12 @@ package main import ( - "bytes" - "encoding/json" - "errors" - "fmt" "log" - "mime/multipart" - "os" - "strconv" "github.com/go-resty/resty/v2" "github.com/joho/godotenv" ) -type Response struct { - Success bool `json:"success"` -} - -type Endpoint string - -const ( - RECTANGLE Endpoint = "rectangle" - UPDATE Endpoint = "update" - COLOR Endpoint = "color" -) - -type Update struct { - Endpoint Endpoint `json:"endpoint"` -} - -type Color struct { - R uint8 `json:"r"` - G uint8 `json:"g"` - B uint8 `json:"b"` - Endpoint Endpoint `json:"endpoint"` -} - -type Rectangle struct { - X int `json:"x"` - Y int `json:"y"` - W uint `json:"w"` - H uint `json:"h"` - Endpoint Endpoint `json:"endpoint"` -} - -func getEnvFallback(key string, fallback ...string) (string, error) { - // Check for function fallback signature - length := len(fallback) - if length > 1 { - return "", errors.New("Invalid signature: Too many fallback values provided!") - } - - // Try to get environment variable - value, exists := os.LookupEnv(key) - if exists { - return value, nil - } - - // Try using fallback value instead - if length == 1 { - return fallback[0], nil - } else if length == 0 { - // No fallback value provided - return "", errors.New("Panic: No fallback value provided!") - } - - // Could not get environment variable - return "", errors.New("Could not get environment variable: " + key) -} - -func convertFallback(input string, fallback ...int) (int, error) { - // Check for function fallback signature - length := len(fallback) - if length > 1 { - return 0, errors.New("Invalid signature: Too many fallback values provided!") - } - - // Try to convert input to int - value, err := strconv.Atoi(input) - if err == nil { - return value, nil - } - - // Try using fallback value instead - if length == 1 { - return fallback[0], nil - } else if length == 0 { - // No fallback value provided - return 0, errors.New("Panic: No fallback value provided!") - } - - // Could not convert input - return 0, err -} - -func loadMatrixData() (string, int, int) { - // Remote server info - API_SERVER_IP, _ := getEnvFallback("API_SERVER_IP", "localhost") - API_SERVER_PORT, _ := getEnvFallback("API_SERVER_PORT", "8080") - - // LED panel info - PUBLIC_LED_WIDTH, _ := convertFallback(os.Getenv("PUBLIC_LED_WIDTH"), 64) - PUBLIC_LED_HEIGHT, _ := convertFallback(os.Getenv("PUBLIC_LED_HEIGHT"), 64) - - // Matrix arrangement info - PUBLIC_LED_CHAIN, _ := convertFallback(os.Getenv("PUBLIC_LED_CHAIN"), 1) - PUBLIC_LED_PARALLEL, _ := convertFallback(os.Getenv("PUBLIC_LED_PARALLEL"), 1) - - // Prepare remote server url - url := fmt.Sprintf("http://%s:%s", API_SERVER_IP, API_SERVER_PORT) - - // Calculate combined resolution - width := PUBLIC_LED_WIDTH * PUBLIC_LED_CHAIN - height := PUBLIC_LED_HEIGHT * PUBLIC_LED_PARALLEL - - return url, width, height -} - -func createInsructions(marshal []byte) (*bytes.Buffer, string) { - // Create a new form data object - body := &bytes.Buffer{} - writer := multipart.NewWriter(body) - - // Add the "instructions" key with the value of marshal - part, err := writer.CreateFormField("instructions") - if err != nil { - log.Fatal(err) - return nil, "" - } - part.Write(marshal) - - // Close the multipart writer - writer.Close() - - return body, writer.FormDataContentType() -} - -func sendRequest(client *resty.Client, url string, ins []interface{}) { - // Manually marshal instructions - marshal, err := json.Marshal(ins) - if err != nil { - log.Fatal(err) - return - } - - // Create instructions form data - req, content := createInsructions(marshal) - if req == nil { - return - } - - // Build and send request - res, err := client.R(). - SetHeader("Content-Type", content). - SetBody(req.Bytes()). - Post(fmt.Sprintf("%s/instructions", url)) - - // Error handling - if err != nil { - log.Fatal(err) - return - } - - // Unmarshal response - var data Response - err = json.Unmarshal(res.Body(), &data) - if err != nil { - log.Fatal(err) - return - } - - // Print response - if !data.Success { - log.Fatal(errors.New("Remote server responded unsuccessfully!")) - } -} - func main() { // Load .env file if it exists err := godotenv.Load(".env") @@ -194,6 +24,13 @@ func main() { // Initialize custom matrix data col := Color{R: 255, G: 0, B: 255, Endpoint: COLOR} rct := Rectangle{X: 0, Y: 0, W: 10, H: 10, Endpoint: RECTANGLE} + + // Send request to remote server + sendRequest(client, url, []interface{}{col, rct}) + + // Initialize custom matrix data + col = Color{R: 255, G: 255, B: 0, Endpoint: COLOR} + rct = Rectangle{X: 15, Y: 15, W: 15, H: 15, Endpoint: RECTANGLE} upd := Update{Endpoint: UPDATE} // Send request to remote server diff --git a/matrix.go b/matrix.go new file mode 100644 index 0000000..e97523a --- /dev/null +++ b/matrix.go @@ -0,0 +1,29 @@ +package main + +import ( + "fmt" + "os" +) + +func loadMatrixData() (string, int, int) { + // Remote server info + API_SERVER_IP, _ := getEnvFallback("API_SERVER_IP", "localhost") + API_SERVER_PORT, _ := getEnvFallback("API_SERVER_PORT", "8080") + + // LED panel info + PUBLIC_LED_WIDTH, _ := convertFallback(os.Getenv("PUBLIC_LED_WIDTH"), 64) + PUBLIC_LED_HEIGHT, _ := convertFallback(os.Getenv("PUBLIC_LED_HEIGHT"), 64) + + // Matrix arrangement info + PUBLIC_LED_CHAIN, _ := convertFallback(os.Getenv("PUBLIC_LED_CHAIN"), 1) + PUBLIC_LED_PARALLEL, _ := convertFallback(os.Getenv("PUBLIC_LED_PARALLEL"), 1) + + // Prepare remote server url + url := fmt.Sprintf("http://%s:%s", API_SERVER_IP, API_SERVER_PORT) + + // Calculate combined resolution + width := PUBLIC_LED_WIDTH * PUBLIC_LED_CHAIN + height := PUBLIC_LED_HEIGHT * PUBLIC_LED_PARALLEL + + return url, width, height +} diff --git a/request.go b/request.go new file mode 100644 index 0000000..f80239f --- /dev/null +++ b/request.go @@ -0,0 +1,71 @@ +package main + +import ( + "bytes" + "encoding/json" + "errors" + "fmt" + "log" + "mime/multipart" + + "github.com/go-resty/resty/v2" +) + +func createInsructions(marshal []byte) (*bytes.Buffer, string) { + // Create a new form data object + body := &bytes.Buffer{} + writer := multipart.NewWriter(body) + + // Add the "instructions" key with the value of marshal + part, err := writer.CreateFormField("instructions") + if err != nil { + log.Fatal(err) + return nil, "" + } + part.Write(marshal) + + // Close the multipart writer + writer.Close() + + return body, writer.FormDataContentType() +} + +func sendRequest(client *resty.Client, url string, ins []interface{}) { + // Manually marshal instructions + marshal, err := json.Marshal(ins) + if err != nil { + log.Fatal(err) + return + } + + // Create instructions form data + req, content := createInsructions(marshal) + if req == nil { + return + } + + // Build and send request + res, err := client.R(). + SetHeader("Content-Type", content). + SetBody(req.Bytes()). + Post(fmt.Sprintf("%s/instructions", url)) + + // Error handling + if err != nil { + log.Fatal(err) + return + } + + // Unmarshal response + var data Response + err = json.Unmarshal(res.Body(), &data) + if err != nil { + log.Fatal(err) + return + } + + // Print response + if !data.Success { + log.Fatal(errors.New("Remote server responded unsuccessfully!")) + } +} diff --git a/types.go b/types.go new file mode 100644 index 0000000..c8d4224 --- /dev/null +++ b/types.go @@ -0,0 +1,32 @@ +package main + +type Response struct { + Success bool `json:"success"` +} + +type Endpoint string + +const ( + RECTANGLE Endpoint = "rectangle" + UPDATE Endpoint = "update" + COLOR Endpoint = "color" +) + +type Update struct { + Endpoint Endpoint `json:"endpoint"` +} + +type Color struct { + R uint8 `json:"r"` + G uint8 `json:"g"` + B uint8 `json:"b"` + Endpoint Endpoint `json:"endpoint"` +} + +type Rectangle struct { + X int `json:"x"` + Y int `json:"y"` + W uint `json:"w"` + H uint `json:"h"` + Endpoint Endpoint `json:"endpoint"` +}