98 lines
1.9 KiB
Go
Executable File
98 lines
1.9 KiB
Go
Executable File
package api
|
|
|
|
import (
|
|
"encoding/csv"
|
|
"fmt"
|
|
"net/http"
|
|
"sort"
|
|
"strconv"
|
|
|
|
"github.com/gorilla/mux"
|
|
"github.com/rs/zerolog/log"
|
|
)
|
|
|
|
type FlatMaps []map[string]any
|
|
|
|
func (maps FlatMaps) GetHeaders() (res []string) {
|
|
keys := map[string]bool{}
|
|
for _, m := range maps {
|
|
for k, _ := range m {
|
|
if _, ok := keys[k]; !ok {
|
|
keys[k] = true
|
|
res = append(res, k)
|
|
}
|
|
}
|
|
}
|
|
sort.Strings(res)
|
|
return
|
|
}
|
|
|
|
func (maps FlatMaps) GetValues() (res [][]string) {
|
|
headers := maps.GetHeaders()
|
|
for _, m := range maps {
|
|
line := []string{}
|
|
for _, k := range headers {
|
|
if v, ok := m[k]; ok && v != nil {
|
|
line = append(line, fmt.Sprint(v))
|
|
} else {
|
|
line = append(line, "")
|
|
}
|
|
}
|
|
res = append(res, line)
|
|
}
|
|
return
|
|
}
|
|
|
|
func (h APIHandler) CacheExport(w http.ResponseWriter, r *http.Request) {
|
|
vars := mux.Vars(r)
|
|
cacheid := vars["cacheid"]
|
|
|
|
d, err := h.cache.Get(cacheid)
|
|
if err != nil {
|
|
log.Error().Err(err).Msg("Error getting cache")
|
|
w.WriteHeader(http.StatusNotFound)
|
|
return
|
|
}
|
|
|
|
if data, ok := d.([]any); ok {
|
|
|
|
flatmaps := FlatMaps{}
|
|
|
|
for _, v := range data {
|
|
fm := map[string]any{}
|
|
flatten("", v.(map[string]any), fm)
|
|
flatmaps = append(flatmaps, fm)
|
|
}
|
|
|
|
w.Header().Set("Content-Type", "text/csv")
|
|
w.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=export-%s.csv", cacheid))
|
|
c := csv.NewWriter(w)
|
|
c.Write(flatmaps.GetHeaders())
|
|
c.WriteAll(flatmaps.GetValues())
|
|
return
|
|
|
|
}
|
|
|
|
w.WriteHeader(http.StatusNotFound)
|
|
|
|
}
|
|
|
|
func flatten(prefix string, src map[string]any, dest map[string]any) {
|
|
if len(prefix) > 0 {
|
|
prefix += "."
|
|
}
|
|
for k, v := range src {
|
|
switch child := v.(type) {
|
|
case map[string]any:
|
|
flatten(prefix+k, child, dest)
|
|
case []any:
|
|
for i := 0; i < len(child); i++ {
|
|
dest[prefix+k+"."+strconv.Itoa(i)] = child[i]
|
|
}
|
|
default:
|
|
// log.Trace().Str("key", prefix+k).Any("value", v).Msg("")
|
|
dest[prefix+k] = v
|
|
}
|
|
}
|
|
}
|