golift.io/starr@v1.0.0/readarr/author.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 bpAuthor = APIver + "/author" 16 17 // Author is the /api/v1/author endpoint. 18 type Author struct { 19 ID int64 `json:"id"` 20 Status string `json:"status,omitempty"` 21 AuthorName string `json:"authorName,omitempty"` 22 ForeignAuthorID string `json:"foreignAuthorId,omitempty"` 23 TitleSlug string `json:"titleSlug,omitempty"` 24 Overview string `json:"overview,omitempty"` 25 Links []*starr.Link `json:"links,omitempty"` 26 Images []*starr.Image `json:"images,omitempty"` 27 Path string `json:"path,omitempty"` 28 QualityProfileID int `json:"qualityProfileId,omitempty"` 29 MetadataProfileID int `json:"metadataProfileId,omitempty"` 30 Genres []string `json:"genres,omitempty"` 31 CleanName string `json:"cleanName,omitempty"` 32 SortName string `json:"sortName,omitempty"` 33 Tags []int `json:"tags,omitempty"` 34 Added time.Time `json:"added,omitempty"` 35 Ratings *starr.Ratings `json:"ratings,omitempty"` 36 Statistics *Statistics `json:"statistics,omitempty"` 37 LastBook *AuthorBook `json:"lastBook,omitempty"` 38 NextBook *AuthorBook `json:"nextBook,omitempty"` 39 Ended bool `json:"ended,omitempty"` 40 Monitored bool `json:"monitored"` 41 AuthorMetadataID int64 `json:"authorMetadataId"` 42 AuthorNameLastFirst string `json:"authorNameLastFirst"` 43 MonitorNewItems string `json:"monitorNewItems"` 44 SortNameLastFirst string `json:"sortNameLastFirst"` 45 } 46 47 // AuthorBook is part of an Author, and is very different from a normal Book type. 48 type AuthorBook struct { 49 ID int64 `json:"id"` 50 AuthorMetadataID int `json:"authorMetadataId"` 51 ForeignBookID string `json:"foreignBookId"` 52 TitleSlug string `json:"titleSlug"` 53 Title string `json:"title"` 54 ReleaseDate time.Time `json:"releaseDate"` 55 Links []*starr.Link `json:"links"` 56 Genres []string `json:"genres"` 57 Ratings *starr.Ratings `json:"ratings"` 58 CleanTitle string `json:"cleanTitle"` 59 Monitored bool `json:"monitored"` 60 AnyEditionOk bool `json:"anyEditionOk"` 61 LastInfoSync time.Time `json:"lastInfoSync"` 62 Added time.Time `json:"added"` 63 AddOptions *AddBookOptions `json:"addOptions"` 64 AuthorMetadata *starr.IsLoaded `json:"authorMetadata"` 65 Author *starr.IsLoaded `json:"author"` 66 Editions *starr.IsLoaded `json:"editions"` 67 BookFiles *starr.IsLoaded `json:"bookFiles"` 68 SeriesLinks *starr.IsLoaded `json:"seriesLinks"` 69 } 70 71 // Statistics for a Book, or maybe an author. 72 type Statistics struct { 73 BookCount int `json:"bookCount"` 74 BookFileCount int `json:"bookFileCount"` 75 TotalBookCount int `json:"totalBookCount"` 76 SizeOnDisk int `json:"sizeOnDisk"` 77 PercentOfBooks float64 `json:"percentOfBooks"` 78 AvailableBookCount int `json:"availableBookCount"` 79 } 80 81 // GetAuthorByID returns an author. 82 func (r *Readarr) GetAuthorByID(authorID int64) (*Author, error) { 83 return r.GetAuthorByIDContext(context.Background(), authorID) 84 } 85 86 // GetAuthorByIDContext returns an author. 87 func (r *Readarr) GetAuthorByIDContext(ctx context.Context, authorID int64) (*Author, error) { 88 var output Author 89 90 req := starr.Request{URI: path.Join(bpAuthor, fmt.Sprint(authorID))} 91 if err := r.GetInto(ctx, req, &output); err != nil { 92 return nil, fmt.Errorf("api.Get(%s): %w", &req, err) 93 } 94 95 return &output, nil 96 } 97 98 // UpdateAuthor updates an author in place. 99 func (r *Readarr) UpdateAuthor(author *Author, moveFiles bool) (*Author, error) { 100 return r.UpdateAuthorContext(context.Background(), author, moveFiles) 101 } 102 103 // UpdateAuthorContext updates an author in place. 104 func (r *Readarr) UpdateAuthorContext(ctx context.Context, author *Author, moveFiles bool) (*Author, error) { 105 var body bytes.Buffer 106 if err := json.NewEncoder(&body).Encode(author); err != nil { 107 return nil, fmt.Errorf("json.Marshal(%s): %w", bpAuthor, err) 108 } 109 110 var output Author 111 112 req := starr.Request{ 113 URI: path.Join(bpAuthor, fmt.Sprint(author.ID)), 114 Query: make(url.Values), 115 Body: &body, 116 } 117 req.Query.Add("moveFiles", fmt.Sprint(moveFiles)) 118 119 if err := r.PutInto(ctx, req, &output); err != nil { 120 return nil, fmt.Errorf("api.Put(%s): %w", &req, err) 121 } 122 123 return &output, nil 124 } 125 126 // DeleteAuthor removes an Author from the database. 127 // Setting deleteFiles true will delete all content for the Author. 128 func (r *Readarr) DeleteAuthor(authorID int64, deleteFiles, addImportExclusion bool) error { 129 return r.DeleteAuthorContext(context.Background(), authorID, deleteFiles, addImportExclusion) 130 } 131 132 // DeleteAuthorContext removes na Author from the database. 133 // Setting deleteFiles true will delete all content for the Author. 134 func (r *Readarr) DeleteAuthorContext(ctx context.Context, authorID int64, deleteFiles, addImportExclusion bool) error { 135 req := starr.Request{URI: path.Join(bpAuthor, fmt.Sprint(authorID)), Query: make(url.Values)} 136 req.Query.Set("deleteFiles", fmt.Sprint(deleteFiles)) 137 req.Query.Set("addImportListExclusion", fmt.Sprint(addImportExclusion)) 138 139 if err := r.DeleteAny(ctx, req); err != nil { 140 return fmt.Errorf("api.Delete(%s): %w", &req, err) 141 } 142 143 return nil 144 }