@@ -19,7 +19,7 @@ import (
1919 "context"
2020 "encoding/json"
2121 "fmt"
22- "io/ioutil "
22+ "io"
2323 "net/http"
2424 "regexp"
2525 "sort"
@@ -32,6 +32,7 @@ import (
3232 "github.com/arduino/arduino-cli/arduino/discovery"
3333 "github.com/arduino/arduino-cli/arduino/httpclient"
3434 "github.com/arduino/arduino-cli/commands"
35+ "github.com/arduino/arduino-cli/inventory"
3536 rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1"
3637 "github.com/pkg/errors"
3738 "github.com/sirupsen/logrus"
@@ -59,52 +60,74 @@ func apiByVidPid(vid, pid string) ([]*rpc.BoardListItem, error) {
5960 return nil , errors .Errorf (tr ("Invalid pid value: '%s'" ), pid )
6061 }
6162
62- url := fmt .Sprintf ("%s/%s/%s" , vidPidURL , vid , pid )
63- retVal := []* rpc.BoardListItem {}
64- req , _ := http .NewRequest ("GET" , url , nil )
65- req .Header .Set ("Content-Type" , "application/json" )
63+ var resp []byte
64+ cacheKey := fmt .Sprintf ("cache.builder-api.v3/boards/byvid/pid/%s/%s" , vid , pid )
65+ if cachedResp := inventory .Store .GetString (cacheKey + ".data" ); cachedResp != "" {
66+ ts := inventory .Store .GetInt64 (cacheKey + ".ts" )
67+ if time .Now ().Unix ()- ts < 24 * 60 * 60 { // 24 hr timeout
68+ if cachedResp == "ErrNotFound" {
69+ return nil , ErrNotFound
70+ }
71+ resp = []byte (cachedResp )
72+ }
73+ }
6674
67- // TODO: use proxy if set
75+ if resp == nil {
76+ url := fmt .Sprintf ("%s/%s/%s" , vidPidURL , vid , pid )
77+ req , _ := http .NewRequest ("GET" , url , nil )
78+ req .Header .Set ("Content-Type" , "application/json" )
6879
69- httpClient , err := httpclient . New ()
80+ // TODO: use proxy if set
7081
71- if err != nil {
72- return nil , errors .Wrap (err , tr ("failed to initialize http client" ))
73- }
82+ httpClient , err := httpclient .New ()
7483
75- if res , err := httpClient .Do (req ); err == nil {
84+ if err != nil {
85+ return nil , errors .Wrap (err , tr ("failed to initialize http client" ))
86+ }
87+
88+ res , err := httpClient .Do (req )
89+ if err != nil {
90+ return nil , errors .Wrap (err , tr ("error querying Arduino Cloud Api" ))
91+ }
7692 if res .StatusCode >= 400 {
7793 if res .StatusCode == 404 {
94+ inventory .Store .Set (cacheKey + ".data" , "ErrNotFound" )
95+ inventory .Store .Set (cacheKey + ".ts" , time .Now ().Unix ())
96+ inventory .WriteStore ()
7897 return nil , ErrNotFound
7998 }
8099 return nil , errors .Errorf (tr ("the server responded with status %s" ), res .Status )
81100 }
82101
83- body , _ := ioutil .ReadAll (res .Body )
84- res .Body .Close ()
85-
86- var dat map [string ]interface {}
87- err = json .Unmarshal (body , & dat )
102+ resp , err = io .ReadAll (res .Body )
88103 if err != nil {
89- return nil , errors .Wrap (err , tr ("error processing response from server" ))
104+ return nil , err
105+ }
106+ if err := res .Body .Close (); err != nil {
107+ return nil , err
90108 }
91109
92- name , nameFound := dat ["name" ].(string )
93- fqbn , fbqnFound := dat ["fqbn" ].(string )
110+ inventory .Store .Set (cacheKey + ".data" , string (resp ))
111+ inventory .Store .Set (cacheKey + ".ts" , time .Now ().Unix ())
112+ inventory .WriteStore ()
113+ }
94114
95- if ! nameFound || ! fbqnFound {
96- return nil , errors .New (tr ("wrong format in server response" ))
97- }
115+ var dat map [string ]interface {}
116+ if err := json .Unmarshal (resp , & dat ); err != nil {
117+ return nil , errors .Wrap (err , tr ("error processing response from server" ))
118+ }
119+ name , nameFound := dat ["name" ].(string )
120+ fqbn , fbqnFound := dat ["fqbn" ].(string )
121+ if ! nameFound || ! fbqnFound {
122+ return nil , errors .New (tr ("wrong format in server response" ))
123+ }
98124
99- retVal = append (retVal , & rpc.BoardListItem {
125+ return []* rpc.BoardListItem {
126+ {
100127 Name : name ,
101128 Fqbn : fqbn ,
102- })
103- } else {
104- return nil , errors .Wrap (err , tr ("error querying Arduino Cloud Api" ))
105- }
106-
107- return retVal , nil
129+ },
130+ }, nil
108131}
109132
110133func identifyViaCloudAPI (port * discovery.Port ) ([]* rpc.BoardListItem , error ) {
0 commit comments