github.com/nvkalinin/business-calendar@v1.0.2-0.20220515154925-e7df8a3d0c34/cmd/sync.go (about) 1 package cmd 2 3 import ( 4 "encoding/json" 5 "io" 6 "net/http" 7 "net/url" 8 "strconv" 9 "strings" 10 "time" 11 12 "github.com/nvkalinin/business-calendar/log" 13 ) 14 15 type Sync struct { 16 ServerUrl string `long:"server-url" short:"s" env:"SERVER_URL" value-name:"str" default:"http://localhost" description:"URL сервера с REST API календаря."` 17 AdminPasswd string `long:"passwd" short:"p" env:"WEB_ADMIN_PASSWD" value-name:"str" description:"Пароль пользователя admin."` 18 Timeout time.Duration `long:"timeout" short:"t" env:"TIMEOUT" value-name:"duration" default:"60s" description:"Макс. время выполнения запроса."` 19 Years []int `long:"year" short:"y" env:"YEAR" value-name:"int" required:"true" description:"Год, за который нужно синхронизировать календарь. Можно указывать несколько раз."` 20 } 21 22 func (s *Sync) Execute(args []string) error { 23 ystr := make([]string, len(s.Years)) 24 for i, y := range s.Years { 25 ystr[i] = strconv.Itoa(y) 26 } 27 28 params := url.Values{"y": ystr} 29 body := strings.NewReader(params.Encode()) 30 31 url := makeUrl(s.ServerUrl, "/api/admin/sync") 32 req, err := http.NewRequest(http.MethodPost, url, body) 33 if err != nil { 34 log.Fatalf("[ERROR] cannot make request: %v", err) 35 } 36 req.Header.Set("Content-Type", "application/x-www-form-urlencoded") 37 req.SetBasicAuth("admin", s.AdminPasswd) 38 log.Printf("[DEBUG] sync request: URL=%s, %#v", url, req) 39 40 client := &http.Client{ 41 Timeout: s.Timeout, 42 } 43 resp, err := client.Do(req) 44 if err != nil { 45 log.Fatalf("[ERROR] cannot make request: %v", err) 46 } 47 defer func() { 48 if err := resp.Body.Close(); err != nil { 49 log.Printf("[WARN] cannot close response: %v", err) 50 } 51 }() 52 log.Printf("[DEBUG] sync response: %#v", resp) 53 54 respBody, err := io.ReadAll(resp.Body) 55 if err != nil { 56 log.Fatalf("[ERROR] cannot read response: %v", err) 57 } 58 log.Printf("[DEBUG] sync resp body: %v", respBody) 59 60 if resp.StatusCode != 200 { 61 err := readJsonError(respBody) 62 log.Fatalf("[ERROR] sync error (status %d): %v", resp.StatusCode, err) 63 } 64 65 res := map[int]string{} 66 if err := json.Unmarshal(respBody, &res); err != nil { 67 log.Fatalf("[ERROR] cannot parse response (status %d): %v", resp.StatusCode, err) 68 } 69 70 for y, syncRes := range res { 71 if syncRes == "ok" { 72 log.Printf("[INFO] year %d: ok", y) 73 } else { 74 log.Printf("[ERROR] year %d: %s", y, syncRes) 75 } 76 } 77 return nil 78 }