44 "bytes"
55 "encoding/json"
66 "errors"
7+ "fmt"
78 "io"
89 "net/http"
910 "os"
@@ -16,42 +17,43 @@ import (
1617 "github.com/AlexxIT/SmartScaleConnect/pkg/fitbit"
1718)
1819
19- var cache = map [string ][]* core.Weight {}
20+ func GetWeights (from any ) ([]* core.Weight , error ) {
21+ switch from .(type ) {
22+ case string :
23+ return getWeights (from .(string ))
2024
21- func GetWeights (config string ) ([]* core.Weight , error ) {
22- if weights , ok := cache [config ]; ok {
23- return weights , nil
24- }
25-
26- weights , err := getWeights (config )
27- if err != nil {
28- return nil , err
29- }
30-
31- cache [config ] = weights
32-
33- return weights , nil
34- }
25+ case map [string ]any :
26+ data , err := json .Marshal (from )
27+ if err != nil {
28+ return nil , err
29+ }
3530
36- func getWeights (config string ) ([]* core.Weight , error ) {
37- switch config [0 ] {
38- case '{' :
39- var weight core.Weight
40- if err := json .Unmarshal ([]byte (config ), & weight ); err != nil {
31+ var weight * core.Weight
32+ if err = json .Unmarshal (data , & weight ); err != nil {
4133 return nil , err
4234 }
4335 if weight .Date .IsZero () {
4436 weight .Date = time .Now ()
4537 }
46- return []* core.Weight {& weight }, nil
47- case '[' :
38+ return []* core.Weight {weight }, nil
39+
40+ case []any :
41+ data , err := json .Marshal (from )
42+ if err != nil {
43+ return nil , err
44+ }
45+
4846 var weights []* core.Weight
49- if err : = json .Unmarshal ([] byte ( config ) , & weights ); err != nil {
47+ if err = json .Unmarshal (data , & weights ); err != nil {
5048 return nil , err
5149 }
5250 return weights , nil
5351 }
5452
53+ return nil , fmt .Errorf ("wrong from format: %v" , from )
54+ }
55+
56+ func getWeights (config string ) ([]* core.Weight , error ) {
5557 switch fields := strings .Fields (config ); fields [0 ] {
5658 case "csv" :
5759 rd , err := openFile (fields [1 ])
@@ -105,24 +107,7 @@ func getWeights(config string) ([]*core.Weight, error) {
105107func SetWeights (config string , src []* core.Weight ) error {
106108 switch fields := strings .Fields (config ); fields [0 ] {
107109 case "csv" , "json" :
108- if strings .Contains (fields [1 ], "://" ) {
109- return postFile (config , src )
110- }
111-
112- // important read file before os.Create
113- dst := appendFile (config , src )
114-
115- f , err := os .Create (fields [1 ])
116- if err != nil {
117- return err
118- }
119- defer f .Close ()
120-
121- if fields [0 ] == "csv" {
122- return csv .Write (f , dst )
123- } else {
124- return json .NewEncoder (f ).Encode (dst )
125- }
110+ return writeFile (config , src )
126111
127112 case "garmin" , "zepp/xiaomi" :
128113 return appendAccount (config , src )
@@ -151,10 +136,38 @@ func openFile(path string) (io.ReadCloser, error) {
151136 }
152137}
153138
154- func appendFile (config string , src []* core.Weight ) []* core.Weight {
139+ func writeFile (config string , src []* core.Weight ) error {
140+ fields := strings .Fields (config )
141+ format := fields [0 ]
142+ filename := fields [1 ]
143+
144+ if strings .Contains (filename , "://" ) {
145+ return postFile (format , filename , src )
146+ }
147+
148+ if filename == "stdout" {
149+ return writeToStdout (format , src )
150+ }
151+
152+ // important read file before os.Create
155153 // empty dst file is OK
156154 dst , _ := GetWeights (config )
155+ dst = appendFile (dst , src )
157156
157+ f , err := os .Create (filename )
158+ if err != nil {
159+ return err
160+ }
161+ defer f .Close ()
162+
163+ if format == "csv" {
164+ return csv .Write (f , dst )
165+ } else {
166+ return json .NewEncoder (f ).Encode (dst )
167+ }
168+ }
169+
170+ func appendFile (dst , src []* core.Weight ) []* core.Weight {
158171 for _ , s := range src {
159172 i := slices .IndexFunc (dst , func (d * core.Weight ) bool {
160173 return s .Date .Unix () == d .Date .Unix ()
@@ -236,7 +249,7 @@ func appendAccount(config string, src []*core.Weight) error {
236249 return client .AddWeights (add )
237250}
238251
239- func postFile ( config string , src []* core.Weight ) ( err error ) {
252+ func prepareFile ( src []* core.Weight ) [] * core. Weight {
240253 // skip zero weights
241254 dst := make ([]* core.Weight , 0 , len (src ))
242255 for _ , weight := range src {
@@ -250,19 +263,23 @@ func postFile(config string, src []*core.Weight) (err error) {
250263 return a .Date .Compare (b .Date )
251264 })
252265
266+ return dst
267+ }
268+
269+ func postFile (format , url string , src []* core.Weight ) (err error ) {
253270 body := bytes .NewBuffer (nil )
271+ dst := prepareFile (src )
254272
255- switch fields := strings .Fields (config ); fields [0 ] {
256- case "csv" :
273+ if format == "csv" {
257274 if err = csv .Write (body , dst ); err != nil {
258275 return err
259276 }
260- _ , err = http .Post (fields [ 1 ] , "text/csv" , body )
261- case "json" :
277+ _ , err = http .Post (url , "text/csv" , body )
278+ } else {
262279 if err = json .NewEncoder (body ).Encode (dst ); err != nil {
263280 return err
264281 }
265- _ , err = http .Post (fields [ 1 ] , "application/json" , body )
282+ _ , err = http .Post (url , "application/json" , body )
266283 }
267284
268285 return
@@ -296,3 +313,13 @@ func postLatest(config string, src []*core.Weight) error {
296313
297314 return nil
298315}
316+
317+ func writeToStdout (format string , src []* core.Weight ) error {
318+ dst := prepareFile (src )
319+
320+ if format == "csv" {
321+ return csv .Write (os .Stdout , dst )
322+ } else {
323+ return json .NewEncoder (os .Stdout ).Encode (dst )
324+ }
325+ }
0 commit comments