golift.io/starr@v1.0.0/readarr/bookfile.go (about)

     1  package readarr
     2  
     3  import (
     4  	"bytes"
     5  	"context"
     6  	"encoding/json"
     7  	"fmt"
     8  	"net/url"
     9  	"path"
    10  	"time"
    11  
    12  	"golift.io/starr"
    13  )
    14  
    15  const bpBookFile = APIver + "/bookfile"
    16  
    17  // BookFile represents the data from the bookfile endpoint.
    18  type BookFile struct {
    19  	AuthorID            int64          `json:"authorId"`
    20  	BookID              int64          `json:"bookId"`
    21  	Path                string         `json:"path"`
    22  	Size                int            `json:"size,omitempty"`
    23  	DateAdded           time.Time      `json:"dateAdded,omitempty"`
    24  	Quality             *starr.Quality `json:"quality"`
    25  	QualityWeight       int            `json:"qualityWeight,omitempty"`
    26  	QualityCutoffNotMet bool           `json:"qualityCutoffNotMet"`
    27  	ID                  int64          `json:"id"`
    28  	AudioTags           *AudioTags     `json:"audioTags,omitempty"`
    29  }
    30  
    31  /* I've never seen audio tags in the wild. */
    32  
    33  // AudioTags are part of a bookfile.
    34  type AudioTags struct {
    35  	Title          string          `json:"title"`
    36  	CleanTitle     string          `json:"cleanTitle"`
    37  	Authors        []string        `json:"authors"`
    38  	AuthorTitle    string          `json:"authorTitle"`
    39  	BookTitle      string          `json:"bookTitle"`
    40  	SeriesTitle    string          `json:"seriesTitle"`
    41  	SeriesIndex    string          `json:"seriesIndex"`
    42  	ISBN           string          `json:"isbn"`
    43  	ASIN           string          `json:"asin"`
    44  	GoodreadsID    string          `json:"goodreadsId"`
    45  	AuthorMBID     string          `json:"authorMBId"`
    46  	BookMBID       string          `json:"bookMBId"`
    47  	ReleaseMBID    string          `json:"releaseMBId"`
    48  	RecordingMBID  string          `json:"recordingMBId"`
    49  	TrackMBID      string          `json:"trackMBId"`
    50  	DiscNumber     int             `json:"discNumber"`
    51  	DiscCount      int             `json:"discCount"`
    52  	Country        *AudioCountry   `json:"country"`
    53  	Year           int             `json:"year"`
    54  	Publisher      string          `json:"publisher"`
    55  	Label          string          `json:"label"`
    56  	Source         string          `json:"source"`
    57  	CatalogNumber  string          `json:"catalogNumber"`
    58  	Disambiguation string          `json:"disambiguation"`
    59  	Duration       *starr.TimeSpan `json:"duration"`
    60  	Quality        *starr.Quality  `json:"quality"`
    61  	MediaInfo      *AudioMediaInfo `json:"mediaInfo"`
    62  	TrackNumbers   []int           `json:"trackNumbers"`
    63  	Language       string          `json:"language"`
    64  	ReleaseGroup   string          `json:"releaseGroup"`
    65  	ReleaseHash    string          `json:"releaseHash"`
    66  }
    67  
    68  // AudioMediaInfo is part of AudioTags.
    69  type AudioMediaInfo struct {
    70  	AudioFormat     string `json:"audioFormat"`
    71  	AudioBitrate    int    `json:"audioBitrate"`
    72  	AudioChannels   int    `json:"audioChannels"`
    73  	AudioBits       int    `json:"audioBits"`
    74  	AudioSampleRate int    `json:"audioSampleRate"`
    75  }
    76  
    77  // AudioCountry is part of AudioTags.
    78  type AudioCountry struct {
    79  	TwoLetterCode string `json:"twoLetterCode"`
    80  	Name          string `json:"name"`
    81  }
    82  
    83  // GetBookFilesForAuthor returns the book files for an author.
    84  func (r *Readarr) GetBookFilesForAuthor(authorID int64) ([]*BookFile, error) {
    85  	return r.GetBookFilesForAuthorContext(context.Background(), authorID)
    86  }
    87  
    88  // GetBookFilesForAuthorContext returns the book files for an author.
    89  func (r *Readarr) GetBookFilesForAuthorContext(ctx context.Context, authorID int64) ([]*BookFile, error) {
    90  	var output []*BookFile
    91  
    92  	req := starr.Request{URI: bpBookFile, Query: make(url.Values)}
    93  	req.Query.Add("authorId", fmt.Sprint(authorID))
    94  
    95  	if err := r.GetInto(ctx, req, &output); err != nil {
    96  		return nil, fmt.Errorf("api.Get(%s): %w", &req, err)
    97  	}
    98  
    99  	return output, nil
   100  }
   101  
   102  // GetBookFilesForBook returns the book files for a book or books.
   103  func (r *Readarr) GetBookFilesForBook(bookID ...int64) ([]*BookFile, error) {
   104  	return r.GetBookFilesForBookContext(context.Background(), bookID...)
   105  }
   106  
   107  // GetBookFilesForBookContext returns the book files for a book or books.
   108  func (r *Readarr) GetBookFilesForBookContext(ctx context.Context, bookID ...int64) ([]*BookFile, error) {
   109  	var output []*BookFile
   110  
   111  	req := starr.Request{URI: bpBookFile, Query: make(url.Values)}
   112  
   113  	for _, id := range bookID {
   114  		req.Query.Add("bookId", fmt.Sprint(id))
   115  	}
   116  
   117  	if err := r.GetInto(ctx, req, &output); err != nil {
   118  		return nil, fmt.Errorf("api.Get(%s): %w", &req, err)
   119  	}
   120  
   121  	return output, nil
   122  }
   123  
   124  // GetBookFiles returns the requested book files by ID.
   125  func (r *Readarr) GetBookFiles(bookFileIDs []int64) ([]*BookFile, error) {
   126  	return r.GetBookFilesContext(context.Background(), bookFileIDs)
   127  }
   128  
   129  // GetBookFilesContext returns the requested book files by their IDs.
   130  func (r *Readarr) GetBookFilesContext(ctx context.Context, bookFileIDs []int64) ([]*BookFile, error) {
   131  	var output []*BookFile
   132  
   133  	if len(bookFileIDs) == 0 {
   134  		return output, nil
   135  	}
   136  
   137  	req := starr.Request{URI: bpBookFile, Query: make(url.Values)}
   138  
   139  	for _, fileID := range bookFileIDs {
   140  		req.Query.Add("bookFileIds", fmt.Sprint(fileID))
   141  	}
   142  
   143  	if err := r.GetInto(ctx, req, &output); err != nil {
   144  		return nil, fmt.Errorf("api.Get(%s): %w", &req, err)
   145  	}
   146  
   147  	return output, nil
   148  }
   149  
   150  // UpdateBookFile updates a book file.
   151  func (r *Readarr) UpdateBookFile(bookFile *BookFile) (*BookFile, error) {
   152  	return r.UpdateBookFileContext(context.Background(), bookFile)
   153  }
   154  
   155  // UpdateBookFileContext updates a book file.
   156  func (r *Readarr) UpdateBookFileContext(ctx context.Context, bookFile *BookFile) (*BookFile, error) {
   157  	var output BookFile
   158  
   159  	var body bytes.Buffer
   160  	if err := json.NewEncoder(&body).Encode(bookFile); err != nil {
   161  		return nil, fmt.Errorf("json.Marshal(%s): %w", bpBookFile, err)
   162  	}
   163  
   164  	req := starr.Request{URI: path.Join(bpBookFile, fmt.Sprint(bookFile.ID)), Body: &body}
   165  	if err := r.PutInto(ctx, req, &output); err != nil {
   166  		return nil, fmt.Errorf("api.Put(%s): %w", &req, err)
   167  	}
   168  
   169  	return &output, nil
   170  }
   171  
   172  // DeleteBookFile deletes a book file.
   173  func (r *Readarr) DeleteBookFile(bookFileID int64) error {
   174  	return r.DeleteBookFileContext(context.Background(), bookFileID)
   175  }
   176  
   177  // DeleteBookFileContext deletes a book file.
   178  func (r *Readarr) DeleteBookFileContext(ctx context.Context, bookFileID int64) error {
   179  	req := starr.Request{URI: path.Join(bpBookFile, fmt.Sprint(bookFileID))}
   180  	if err := r.DeleteAny(ctx, req); err != nil {
   181  		return fmt.Errorf("api.Delete(%s): %w", &req, err)
   182  	}
   183  
   184  	return nil
   185  }
   186  
   187  // DeleteBookFiles bulk deletes book files by their IDs.
   188  func (r *Readarr) DeleteBookFiles(bookFileIDs []int64) error {
   189  	return r.DeleteBookFilesContext(context.Background(), bookFileIDs)
   190  }
   191  
   192  // DeleteBookFilesContext bulk deletes book files by their IDs.
   193  func (r *Readarr) DeleteBookFilesContext(ctx context.Context, bookFileIDs []int64) error {
   194  	postData := struct {
   195  		T []int64 `json:"bookFileIds"`
   196  	}{bookFileIDs}
   197  
   198  	var body bytes.Buffer
   199  	if err := json.NewEncoder(&body).Encode(&postData); err != nil {
   200  		return fmt.Errorf("json.Marshal(%s): %w", bpBookFile, err)
   201  	}
   202  
   203  	req := starr.Request{URI: path.Join(bpBookFile, "bulk"), Body: &body}
   204  	if err := r.DeleteAny(ctx, req); err != nil {
   205  		return fmt.Errorf("api.Delete(%s): %w", &req, err)
   206  	}
   207  
   208  	return nil
   209  }