package arr import ( "context" "encoding/json" "fmt" "net/http" "strconv" ) // Update reads /, lets mutate change the raw JSON object and PUTs it // back. Working on raw fields keeps everything the client does not model // (Radarr and Sonarr replace the whole resource on PUT). func (c *Client) Update(ctx context.Context, path string, id int, mutate func(obj map[string]json.RawMessage) error) error { p := path + "/" + strconv.Itoa(id) var obj map[string]json.RawMessage if err := c.Do(ctx, http.MethodGet, p, nil, nil, &obj); err != nil { return err } if err := mutate(obj); err != nil { return err } return c.Do(ctx, http.MethodPut, p, nil, obj, nil) } // SetBool sets a boolean field of a raw object. func SetBool(obj map[string]json.RawMessage, key string, v bool) { obj[key], _ = json.Marshal(v) } // Command posts a command ("MoviesSearch", "SeasonSearch", ...) to /command. func (c *Client) Command(ctx context.Context, body map[string]any) error { return c.Do(ctx, http.MethodPost, "command", nil, body, nil) } // SetSeasonMonitored flips one season in a raw series object. func SetSeasonMonitored(obj map[string]json.RawMessage, season int, monitored bool) error { var seasons []map[string]json.RawMessage if err := json.Unmarshal(obj["seasons"], &seasons); err != nil { return fmt.Errorf("decoding seasons: %w", err) } found := false for _, s := range seasons { var n int if json.Unmarshal(s["seasonNumber"], &n) == nil && n == season { SetBool(s, "monitored", monitored) found = true } } if !found { return fmt.Errorf("season %d not found", season) } obj["seasons"], _ = json.Marshal(seasons) return nil }