Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ linters:
- noinlineerr
- wsl
settings:
gosec:
excludes:
- G117
wsl_v5:
allow-first-in-block: true
allow-whole-block: false
Expand Down
15 changes: 11 additions & 4 deletions http.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ type Request struct {
Body io.Reader // Used in PUT, POST, DELETE. Not for GET.
Query url.Values // GET parameters work for any request type.
URI string // Required: path portion of the URL.
// Headers are optional extra HTTP headers merged after defaults (overrides Content-Type, Accept, etc.).
Headers http.Header
}

// ReqError is returned when a Starr app returns an invalid status code.
Expand Down Expand Up @@ -64,7 +66,7 @@ func (c *Config) req(ctx context.Context, method string, req Request) (*http.Res
return nil, fmt.Errorf("http.NewRequestWithContext(%s): %w", req.URI, err)
}

c.SetHeaders(httpReq)
c.SetHeaders(httpReq, req.Headers)

if req.Query != nil {
httpReq.URL.RawQuery = req.Query.Encode()
Expand Down Expand Up @@ -131,8 +133,9 @@ func closeResp(resp *http.Response) {
}
}

// SetHeaders sets all our request headers based on method and other data.
func (c *Config) SetHeaders(req *http.Request) {
// SetHeaders sets default request headers, merges localReq.Headers (which override defaults),
// then forces application/x-www-form-urlencoded for native login POSTs.
func (c *Config) SetHeaders(req *http.Request, headers http.Header) {
// This app allows http auth, in addition to api key (nginx proxy).
if auth := c.HTTPUser + ":" + c.HTTPPass; auth != ":" {
req.Header.Set("Authorization", "Basic "+base64.StdEncoding.EncodeToString([]byte(auth)))
Expand All @@ -142,9 +145,13 @@ func (c *Config) SetHeaders(req *http.Request) {
req.Header.Set("Content-Type", "application/json")
}

for key, vals := range headers {
req.Header[http.CanonicalHeaderKey(key)] = vals
}

if req.Method == http.MethodPost && strings.HasSuffix(req.URL.RequestURI(), "/login") {
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
} else {
} else if req.Header.Get("Accept") == "" {
req.Header.Set("Accept", "application/json")
}

Expand Down
143 changes: 143 additions & 0 deletions sonarr/autotagging.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
package sonarr

import (
"bytes"
"context"
"encoding/json"
"fmt"
"path"

"golift.io/starr"
)

const bpAutoTagging = APIver + "/autotagging"

// AutoTagging is the /api/v3/autotagging resource.
type AutoTagging struct {
ID int `json:"id,omitempty"`
Name string `json:"name,omitempty"`
RemoveTagsAutomatically bool `json:"removeTagsAutomatically"`
Tags []int `json:"tags,omitempty"`
Specifications []*AutoTaggingSpecification `json:"specifications,omitempty"`
}

// AutoTaggingSpecification is one rule inside an AutoTagging definition.
type AutoTaggingSpecification struct {
ID int `json:"id,omitempty"`
Name string `json:"name,omitempty"`
Implementation string `json:"implementation,omitempty"`
ImplementationName string `json:"implementationName,omitempty"`
Negate bool `json:"negate"`
Required bool `json:"required"`
Fields []*starr.FieldInput `json:"fields,omitempty"`
}

// GetAutoTaggings returns all auto tagging configurations.
func (s *Sonarr) GetAutoTaggings() ([]*AutoTagging, error) {
return s.GetAutoTaggingsContext(context.Background())
}

// GetAutoTaggingsContext returns all auto tagging configurations.
func (s *Sonarr) GetAutoTaggingsContext(ctx context.Context) ([]*AutoTagging, error) {
var output []*AutoTagging

req := starr.Request{URI: bpAutoTagging}
if err := s.GetInto(ctx, req, &output); err != nil {
return nil, fmt.Errorf("api.Get(%s): %w", &req, err)
}

return output, nil
}

// GetAutoTagging returns a single auto tagging configuration.
func (s *Sonarr) GetAutoTagging(id int) (*AutoTagging, error) {
return s.GetAutoTaggingContext(context.Background(), id)
}

// GetAutoTaggingContext returns a single auto tagging configuration.
func (s *Sonarr) GetAutoTaggingContext(ctx context.Context, id int) (*AutoTagging, error) {
var output AutoTagging

req := starr.Request{URI: path.Join(bpAutoTagging, starr.Str(id))}
if err := s.GetInto(ctx, req, &output); err != nil {
return nil, fmt.Errorf("api.Get(%s): %w", &req, err)
}

return &output, nil
}

// GetAutoTaggingSchema returns the specification schema templates for auto tagging.
func (s *Sonarr) GetAutoTaggingSchema() ([]*AutoTaggingSpecification, error) {
return s.GetAutoTaggingSchemaContext(context.Background())
}

// GetAutoTaggingSchemaContext returns the specification schema templates for auto tagging.
func (s *Sonarr) GetAutoTaggingSchemaContext(ctx context.Context) ([]*AutoTaggingSpecification, error) {
var output []*AutoTaggingSpecification

req := starr.Request{URI: path.Join(bpAutoTagging, "schema")}
if err := s.GetInto(ctx, req, &output); err != nil {
return nil, fmt.Errorf("api.Get(%s): %w", &req, err)
}

return output, nil
}

// AddAutoTagging creates an auto tagging configuration.
func (s *Sonarr) AddAutoTagging(in *AutoTagging) (*AutoTagging, error) {
return s.AddAutoTaggingContext(context.Background(), in)
}

// AddAutoTaggingContext creates an auto tagging configuration.
func (s *Sonarr) AddAutoTaggingContext(ctx context.Context, in *AutoTagging) (*AutoTagging, error) {
var output AutoTagging

var body bytes.Buffer
if err := json.NewEncoder(&body).Encode(in); err != nil {
return nil, fmt.Errorf("json.Marshal(%s): %w", bpAutoTagging, err)
}

req := starr.Request{URI: bpAutoTagging, Body: &body}
if err := s.PostInto(ctx, req, &output); err != nil {
return nil, fmt.Errorf("api.Post(%s): %w", &req, err)
}

return &output, nil
}

// UpdateAutoTagging updates an auto tagging configuration.
func (s *Sonarr) UpdateAutoTagging(in *AutoTagging) (*AutoTagging, error) {
return s.UpdateAutoTaggingContext(context.Background(), in)
}

// UpdateAutoTaggingContext updates an auto tagging configuration.
func (s *Sonarr) UpdateAutoTaggingContext(ctx context.Context, input *AutoTagging) (*AutoTagging, error) {
var output AutoTagging

var body bytes.Buffer
if err := json.NewEncoder(&body).Encode(input); err != nil {
return nil, fmt.Errorf("json.Marshal(%s): %w", bpAutoTagging, err)
}

req := starr.Request{URI: path.Join(bpAutoTagging, starr.Str(input.ID)), Body: &body}
if err := s.PutInto(ctx, req, &output); err != nil {
return nil, fmt.Errorf("api.Put(%s): %w", &req, err)
}

return &output, nil
}

// DeleteAutoTagging deletes an auto tagging configuration.
func (s *Sonarr) DeleteAutoTagging(id int) error {
return s.DeleteAutoTaggingContext(context.Background(), id)
}

// DeleteAutoTaggingContext deletes an auto tagging configuration.
func (s *Sonarr) DeleteAutoTaggingContext(ctx context.Context, id int) error {
req := starr.Request{URI: path.Join(bpAutoTagging, starr.Str(id))}
if err := s.DeleteAny(ctx, req); err != nil {
return fmt.Errorf("api.Delete(%s): %w", &req, err)
}

return nil
}
Loading
Loading