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
16 changes: 8 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@

**Go library to interact with APIs in all the Starr apps.**

- [Lidarr](https://lidarr.audio) ([over 80 methods](https://pkg.go.dev/golift.io/starr@main/lidarr))
- [Prowlarr](https://prowlarr.com) ([over 20 methods](https://pkg.go.dev/golift.io/starr@main/prowlarr))
- [Radarr](https://radarr.video) ([over 100 methods](https://pkg.go.dev/golift.io/starr@main/radarr))
- [Readarr](https://readarr.com) ([over 70 methods](https://pkg.go.dev/golift.io/starr@main/readarr))
- [Sonarr](https://sonarr.tv) ([over 120 methods](https://pkg.go.dev/golift.io/starr@main/sonarr))
- [Lidarr](https://lidarr.audio) ([view Go ref](https://pkg.go.dev/golift.io/starr@main/lidarr))
- [Prowlarr](https://prowlarr.com) ([view Go ref](https://pkg.go.dev/golift.io/starr@main/prowlarr))
- [Radarr](https://radarr.video) ([view Go ref](https://pkg.go.dev/golift.io/starr@main/radarr))
- [Readarr](https://readarr.com) ([view Go ref](https://pkg.go.dev/golift.io/starr@main/readarr))
- [Sonarr](https://sonarr.tv) ([view Go ref](https://pkg.go.dev/golift.io/starr@main/sonarr))

### Webhooks & Scripts

Expand All @@ -25,9 +25,9 @@

## One 🌟 To Rule Them All

This library is slowly updated as new methods are needed or requested. If you have
specific needs this library doesn't currently meet, but should or could, please
[let us know](https://github.com/golift/starr/issues/new)!
Pretty much all the API methods are available. Plus Connections: Webhooks and Custom Scripts.
If you have specific needs this library doesn't currently meet,
but should or could, please [let us know](https://github.com/golift/starr/issues/new)!

This library is currently in use by:

Expand Down
75 changes: 75 additions & 0 deletions lidarr/album.go
Original file line number Diff line number Diff line change
Expand Up @@ -241,3 +241,78 @@ func (l *Lidarr) DeleteAlbumContext(ctx context.Context, albumID int64, deleteFi

return nil
}

const bpAlbumStudio = APIver + "/albumstudio"

// AlbumsMonitoredInput is the body for PUT /album/monitor.
type AlbumsMonitoredInput struct {
AlbumIDs []int64 `json:"albumIds"`
Monitored bool `json:"monitored"`
}

// MonitoringOptions configures album studio monitoring.
type MonitoringOptions struct {
Monitor string `json:"monitor,omitempty"`
AlbumsToMonitor []string `json:"albumsToMonitor,omitempty"`
Monitored bool `json:"monitored,omitempty"`
}

// AlbumStudioArtist is one artist block for album studio.
type AlbumStudioArtist struct {
ID int64 `json:"id"`
Monitored bool `json:"monitored,omitempty"`
Albums []*Album `json:"albums,omitempty"`
}

// AlbumStudioInput is the body for POST /albumstudio.
type AlbumStudioInput struct {
Artist []*AlbumStudioArtist `json:"artist,omitempty"`
MonitoringOptions *MonitoringOptions `json:"monitoringOptions,omitempty"`
MonitorNewItems string `json:"monitorNewItems,omitempty"`
}

// MonitorAlbums sets monitored state for the given album IDs.
func (l *Lidarr) MonitorAlbums(albumIDs []int64, monitored bool) ([]*Album, error) {
return l.MonitorAlbumsContext(context.Background(), albumIDs, monitored)
}

// MonitorAlbumsContext sets monitored state for the given album IDs.
func (l *Lidarr) MonitorAlbumsContext(ctx context.Context, albumIDs []int64, monitored bool) ([]*Album, error) {
in := AlbumsMonitoredInput{AlbumIDs: albumIDs, Monitored: monitored}

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

var output []*Album

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

return output, nil
}

// AlbumStudio triggers album studio actions (monitoring) for artists/albums.
func (l *Lidarr) AlbumStudio(in *AlbumStudioInput) error {
return l.AlbumStudioContext(context.Background(), in)
}

// AlbumStudioContext triggers album studio actions (monitoring) for artists/albums.
func (l *Lidarr) AlbumStudioContext(ctx context.Context, in *AlbumStudioInput) error {
var body bytes.Buffer
if err := json.NewEncoder(&body).Encode(in); err != nil {
return fmt.Errorf("json.Marshal(%s): %w", bpAlbumStudio, err)
}

var output any

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

return nil
}
92 changes: 92 additions & 0 deletions lidarr/artist.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,21 @@ import (

const bpArtist = APIver + "/artist"

// ArtistEditorInput is the request body for PUT and DELETE /artist/editor.
type ArtistEditorInput struct {
ArtistIDs []int `json:"artistIds,omitempty"`
Monitored *bool `json:"monitored,omitempty"`
MonitorNewItems string `json:"monitorNewItems,omitempty"`
QualityProfileID *int `json:"qualityProfileId,omitempty"`
MetadataProfileID *int `json:"metadataProfileId,omitempty"`
RootFolderPath string `json:"rootFolderPath,omitempty"`
Tags []int `json:"tags,omitempty"`
ApplyTags starr.ApplyTags `json:"applyTags,omitempty"`
MoveFiles bool `json:"moveFiles,omitempty"`
DeleteFiles bool `json:"deleteFiles,omitempty"`
AddImportListExclusion bool `json:"addImportListExclusion,omitempty"`
}

// Artist represents the /api/v1/artist endpoint, and it's part of an Album.
type Artist struct {
ID int64 `json:"id"`
Expand Down Expand Up @@ -159,3 +174,80 @@ func (l *Lidarr) DeleteArtistContext(ctx context.Context, artistID int64, delete

return nil
}

// LookupArtist searches for artists matching the specified search term.
func (l *Lidarr) LookupArtist(term string) ([]*Artist, error) {
return l.LookupArtistContext(context.Background(), term)
}

// LookupArtistContext searches for artists matching the specified search term.
func (l *Lidarr) LookupArtistContext(ctx context.Context, term string) ([]*Artist, error) {
var output []*Artist

if term == "" {
return output, nil
}

req := starr.Request{
URI: path.Join(bpArtist, "lookup"),
Query: make(url.Values),
}
req.Query.Set("term", term)

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

return output, nil
}

// EditArtists applies bulk edits to artists.
func (l *Lidarr) EditArtists(in *ArtistEditorInput) ([]*Artist, error) {
return l.EditArtistsContext(context.Background(), in)
}

// EditArtistsContext applies bulk edits to artists.
func (l *Lidarr) EditArtistsContext(ctx context.Context, in *ArtistEditorInput) ([]*Artist, error) {
var body bytes.Buffer
if err := json.NewEncoder(&body).Encode(in); err != nil {
return nil, fmt.Errorf("json.Marshal(%s): %w", path.Join(bpArtist, "editor"), err)
}

var output []*Artist

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

return output, nil
}

// DeleteArtists applies bulk deletes to artists.
func (l *Lidarr) DeleteArtists(in *ArtistEditorInput) ([]*Artist, error) {
return l.DeleteArtistsContext(context.Background(), in)
}

// DeleteArtistsContext applies bulk deletes to artists.
func (l *Lidarr) DeleteArtistsContext(ctx context.Context, in *ArtistEditorInput) ([]*Artist, error) {
var body bytes.Buffer
if err := json.NewEncoder(&body).Encode(in); err != nil {
return nil, fmt.Errorf("json.Marshal(%s): %w", path.Join(bpArtist, "editor"), err)
}

req := starr.Request{URI: starr.SetAPIPath(path.Join(bpArtist, "editor")), Body: &body}

resp, err := l.Delete(ctx, req)
if err != nil {
return nil, fmt.Errorf("api.Delete(%s): %w", &req, err)
}
defer resp.Body.Close()

var output []*Artist

if err := json.NewDecoder(resp.Body).Decode(&output); err != nil {
return nil, fmt.Errorf("decoding response from %s: %w", &req, err)
}

return output, nil
}
130 changes: 130 additions & 0 deletions lidarr/autotagging.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
package lidarr

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

"golift.io/starr"
"golift.io/starr/starrshared"
)

const bpAutoTagging = APIver + "/autotagging"

// AutoTagging is the /api/v1/autotagging resource.
type AutoTagging = starrshared.AutoTagging

// AutoTaggingSpecification is one rule inside an AutoTagging definition.
type AutoTaggingSpecification = starrshared.AutoTaggingSpecification

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

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

req := starr.Request{URI: bpAutoTagging}
if err := l.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 (l *Lidarr) GetAutoTagging(id int) (*AutoTagging, error) {
return l.GetAutoTaggingContext(context.Background(), id)
}

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

req := starr.Request{URI: path.Join(bpAutoTagging, starr.Str(id))}
if err := l.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 (l *Lidarr) GetAutoTaggingSchema() ([]*AutoTaggingSpecification, error) {
return l.GetAutoTaggingSchemaContext(context.Background())
}

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

req := starr.Request{URI: path.Join(bpAutoTagging, "schema")}
if err := l.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 (l *Lidarr) AddAutoTagging(in *AutoTagging) (*AutoTagging, error) {
return l.AddAutoTaggingContext(context.Background(), in)
}

// AddAutoTaggingContext creates an auto tagging configuration.
func (l *Lidarr) 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 := l.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 (l *Lidarr) UpdateAutoTagging(in *AutoTagging) (*AutoTagging, error) {
return l.UpdateAutoTaggingContext(context.Background(), in)
}

// UpdateAutoTaggingContext updates an auto tagging configuration.
func (l *Lidarr) 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 := l.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 (l *Lidarr) DeleteAutoTagging(id int) error {
return l.DeleteAutoTaggingContext(context.Background(), id)
}

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

return nil
}
Loading
Loading