package utils import ( "archive/zip" "bytes" "encoding/json" "fmt" "io/ioutil" "os" "strconv" "strings" "time" "gitlab.com/uafrica/go-utils/struct_utils" ) // GetEnv is a helper function for getting environment variables with a default func GetEnv(name string, def string) (env string) { // If variable not set, provide default if env = os.Getenv(name); env == "" { env = def } return } // CorsHeaders returns a map to allow Cors func CorsHeaders() map[string]string { return map[string]string{ "Access-Control-Allow-Origin": "*", "Access-Control-Allow-Headers": "*", "Access-Control-Allow-Methods": "OPTIONS,GET,PUT,POST,DELETE,PATCH,HEAD", "Access-Control-Max-Age": "86400", "Access-Control-Allow-Credentials": "true", } } func CorsHeadersCached() map[string]string { return map[string]string{ "Access-Control-Allow-Origin": "*", "Access-Control-Allow-Headers": "*", "Access-Control-Allow-Methods": "OPTIONS,GET,PUT,POST,DELETE,PATCH,HEAD", "Access-Control-Max-Age": "86400", "Access-Control-Allow-Credentials": "true", } } func ZipData(fileName string, data []byte) ([]byte, error) { // Create zip buf := new(bytes.Buffer) // Create a new zip archive. zipWriter := zip.NewWriter(buf) header := &zip.FileHeader{ Name: fileName, Method: zip.Deflate, Modified: time.Now(), } // Write data file, err := zipWriter.CreateHeader(header) if err != nil { return nil, err } _, err = file.Write(data) if err != nil { return nil, err } // Close zip err = zipWriter.Close() if err != nil { return []byte(""), err } return buf.Bytes(), nil } func UnzipData(data []byte) (map[string][]byte, error) { // Create a new zip reader. zipReader, err := zip.NewReader(bytes.NewReader(data), int64(len(data))) if err != nil { return nil, err } // Read all the files from zip archive var fileData = make(map[string][]byte) for _, zipFile := range zipReader.File { unzippedData, err := readZipFile(zipFile) if err != nil { continue } fileData[zipFile.FileHeader.Name] = unzippedData } return fileData, nil } func readZipFile(zipFile *zip.File) ([]byte, error) { zipFileData, err := zipFile.Open() if err != nil { return nil, err } defer zipFileData.Close() return ioutil.ReadAll(zipFileData) } func DeepCopy(toValue interface{}, fromValue interface{}) (err error) { valueBytes, err := json.Marshal(fromValue) if err != nil { return err } err = struct_utils.UnmarshalJSON(valueBytes, toValue) if err != nil { return err } return nil } func UnwrapBool(b *bool) bool { if b == nil { return false } return *b } // MapStringInterfaceToMapStringString converts a generic value typed map to a map with string values func MapStringInterfaceToMapStringString(inputMap map[string]interface{}) map[string]string { query := make(map[string]string) for mapKey, mapVal := range inputMap { // Check if mapVal is a slice or a single value switch mapValTyped := mapVal.(type) { case []interface{}: // Slice - convert each element individually var mapValString []string // Loop through each element in the slice and check the type for _, sliceElem := range mapValTyped { switch sliceElemTyped := sliceElem.(type) { case string: // Enclose strings in escaped quotations mapValString = append(mapValString, fmt.Sprintf("\"%v\"", sliceElemTyped)) case float64: // Use FormatFloat for least amount of precision. mapValString = append(mapValString, strconv.FormatFloat(sliceElemTyped, 'f', -1, 64)) default: // Convert to string mapValString = append(mapValString, fmt.Sprintf("%v", sliceElemTyped)) } } // Join as a comma seperated array query[mapKey] = "[" + strings.Join(mapValString, ",") + "]" default: // Single value - convert to string query[mapKey] = fmt.Sprintf("%v", mapVal) } } return query } // MergeMaps If there are similar properties in the maps, the last one will be used as the value func MergeMaps(maps ...map[string]string) map[string]string { ret := map[string]string{} for _, mapV := range maps { for k, v := range mapV { ret[k] = v } } return ret }