github.com/arduino/arduino-cloud-cli@v0.0.0-20240517070944-e7a449561083/internal/template/extract.go (about)

     1  // This file is part of arduino-cloud-cli.
     2  //
     3  // Copyright (C) 2021 ARDUINO SA (http://www.arduino.cc/)
     4  //
     5  // This program is free software: you can redistribute it and/or modify
     6  // it under the terms of the GNU Affero General Public License as published
     7  // by the Free Software Foundation, either version 3 of the License, or
     8  // (at your option) any later version.
     9  //
    10  // This program is distributed in the hope that it will be useful,
    11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13  // GNU Affero General Public License for more details.
    14  //
    15  // You should have received a copy of the GNU Affero General Public License
    16  // along with this program.  If not, see <https://www.gnu.org/licenses/>.
    17  
    18  package template
    19  
    20  import (
    21  	"encoding/json"
    22  	"errors"
    23  	"fmt"
    24  	"io/ioutil"
    25  	"os"
    26  
    27  	iotclient "github.com/arduino/iot-client-go"
    28  	"gopkg.in/yaml.v3"
    29  )
    30  
    31  // FromThing extracts a template of type map[string]interface{} from a thing.
    32  func FromThing(thing *iotclient.ArduinoThing) map[string]interface{} {
    33  	template := make(map[string]interface{})
    34  	template["name"] = thing.Name
    35  	template["timezone"] = thing.Timezone
    36  
    37  	// Extract template from thing structure
    38  	var props []map[string]interface{}
    39  	for _, p := range thing.Properties {
    40  		prop := make(map[string]interface{})
    41  		prop["name"] = p.Name
    42  		prop["permission"] = p.Permission
    43  		prop["type"] = p.Type
    44  		prop["update_parameter"] = p.UpdateParameter
    45  		prop["update_strategy"] = p.UpdateStrategy
    46  		prop["variable_name"] = p.VariableName
    47  		props = append(props, prop)
    48  	}
    49  	template["variables"] = props
    50  
    51  	return template
    52  }
    53  
    54  // FromDashboard extracts a template of type map[string]interface{} from a dashboard.
    55  func FromDashboard(dashboard *iotclient.ArduinoDashboardv2) map[string]interface{} {
    56  	template := make(map[string]interface{})
    57  	template["name"] = dashboard.Name
    58  
    59  	// Extract template from dashboard structure
    60  	var widgets []map[string]interface{}
    61  	for _, w := range dashboard.Widgets {
    62  		widget := make(map[string]interface{})
    63  		widget["type"] = w.Type
    64  		widget["name"] = w.Name
    65  		widget["width"] = w.Width
    66  		widget["height"] = w.Height
    67  		widget["x"] = w.X
    68  		widget["y"] = w.Y
    69  
    70  		if w.WidthMobile != 0 && w.HeightMobile != 0 {
    71  			widget["width_mobile"] = w.WidthMobile
    72  			widget["height_mobile"] = w.HeightMobile
    73  			widget["x_mobile"] = w.XMobile
    74  			widget["y_mobile"] = w.YMobile
    75  		}
    76  
    77  		var vars []map[string]interface{}
    78  		for _, v := range w.Variables {
    79  			variable := make(map[string]interface{})
    80  			variable["thing_id"] = v.ThingName
    81  			variable["variable_id"] = v.VariableName
    82  			vars = append(vars, variable)
    83  		}
    84  		if len(vars) > 0 {
    85  			widget["variables"] = vars
    86  		}
    87  
    88  		filterWidgetOptions(w.Options)
    89  		if len(w.Options) > 0 {
    90  			widget["options"] = w.Options
    91  		}
    92  		widgets = append(widgets, widget)
    93  	}
    94  	if len(widgets) > 0 {
    95  		template["widgets"] = widgets
    96  	}
    97  	return template
    98  }
    99  
   100  // ToFile takes a generic template and saves it into a file,
   101  // in the specified format (yaml or json).
   102  func ToFile(template map[string]interface{}, outfile string, format string) error {
   103  	var file []byte
   104  	var err error
   105  
   106  	if format == "json" {
   107  		file, err = json.MarshalIndent(template, "", "    ")
   108  		if err != nil {
   109  			return fmt.Errorf("%s: %w", "template marshal failure: ", err)
   110  		}
   111  
   112  	} else if format == "yaml" {
   113  		file, err = yaml.Marshal(template)
   114  		if err != nil {
   115  			return fmt.Errorf("%s: %w", "template marshal failure: ", err)
   116  		}
   117  
   118  	} else {
   119  		return errors.New("format is not valid: only 'json' and 'yaml' are supported")
   120  	}
   121  
   122  	err = ioutil.WriteFile(outfile, file, os.FileMode(0644))
   123  	if err != nil {
   124  		return fmt.Errorf("%s: %w", "cannot write outfile: ", err)
   125  	}
   126  
   127  	return nil
   128  }