@@ -43,6 +43,50 @@ type CollectionMovie struct {
4343 CollectedAt string `json:"collected_at"`
4444}
4545
46+ // ShowIDs represents the various IDs associated with a show
47+ type ShowIDs struct {
48+ Trakt int `json:"trakt"`
49+ TMDB int `json:"tmdb"`
50+ IMDB string `json:"imdb"`
51+ Slug string `json:"slug"`
52+ TVDB int `json:"tvdb"`
53+ }
54+
55+ // ShowInfo represents the basic show information
56+ type ShowInfo struct {
57+ Title string `json:"title"`
58+ Year int `json:"year"`
59+ IDs ShowIDs `json:"ids"`
60+ }
61+
62+ // EpisodeIDs represents the various IDs associated with an episode
63+ type EpisodeIDs struct {
64+ Trakt int `json:"trakt"`
65+ TMDB int `json:"tmdb"`
66+ TVDB int `json:"tvdb"`
67+ }
68+
69+ // EpisodeInfo represents the basic episode information
70+ type EpisodeInfo struct {
71+ Season int `json:"season"`
72+ Number int `json:"number"`
73+ Title string `json:"title"`
74+ IDs EpisodeIDs `json:"ids"`
75+ }
76+
77+ // WatchedShow represents a watched show with its metadata
78+ type WatchedShow struct {
79+ Show ShowInfo `json:"show"`
80+ Seasons []ShowSeason `json:"seasons"`
81+ LastWatchedAt string `json:"last_watched_at"`
82+ }
83+
84+ // ShowSeason represents a season of a show
85+ type ShowSeason struct {
86+ Number int `json:"number"`
87+ Episodes []EpisodeInfo `json:"episodes"`
88+ }
89+
4690// Client represents a Trakt API client
4791type Client struct {
4892 config * config.Config
@@ -213,4 +257,67 @@ func (c *Client) GetCollectionMovies() ([]CollectionMovie, error) {
213257 "count" : len (movies ),
214258 })
215259 return movies , nil
260+ }
261+
262+ // GetWatchedShows retrieves the list of watched shows from Trakt
263+ func (c * Client ) GetWatchedShows () ([]WatchedShow , error ) {
264+ req , err := http .NewRequest ("GET" , c .config .Trakt .APIBaseURL + "/sync/watched/shows" , nil )
265+ if err != nil {
266+ c .logger .Error ("errors.api_request_failed" , map [string ]interface {}{
267+ "error" : err .Error (),
268+ })
269+ return nil , fmt .Errorf ("failed to create request: %w" , err )
270+ }
271+
272+ // Add required headers
273+ req .Header .Set ("Content-Type" , "application/json" )
274+ req .Header .Set ("trakt-api-version" , "2" )
275+ req .Header .Set ("trakt-api-key" , c .config .Trakt .ClientID )
276+ req .Header .Set ("Authorization" , "Bearer " + c .config .Trakt .AccessToken )
277+
278+ resp , err := c .makeRequest (req )
279+ if err != nil {
280+ c .logger .Error ("errors.api_request_failed" , map [string ]interface {}{
281+ "error" : err .Error (),
282+ })
283+ return nil , fmt .Errorf ("failed to execute request: %w" , err )
284+ }
285+ defer resp .Body .Close ()
286+
287+ // Handle rate limiting
288+ if limit := resp .Header .Get ("X-Ratelimit-Remaining" ); limit != "" {
289+ remaining , _ := strconv .Atoi (limit )
290+ if remaining < 100 {
291+ c .logger .Warn ("api.rate_limit_warning" , map [string ]interface {}{
292+ "remaining" : remaining ,
293+ })
294+ }
295+ }
296+
297+ // Check response status
298+ if resp .StatusCode != http .StatusOK {
299+ var errorResp map [string ]string
300+ if err := json .NewDecoder (resp .Body ).Decode (& errorResp ); err != nil {
301+ errorResp = map [string ]string {"error" : "unknown error" }
302+ }
303+ c .logger .Error ("errors.api_request_failed" , map [string ]interface {}{
304+ "status" : resp .StatusCode ,
305+ "error" : errorResp ["error" ],
306+ })
307+ return nil , fmt .Errorf ("API request failed with status %d: %s" , resp .StatusCode , errorResp ["error" ])
308+ }
309+
310+ // Parse response
311+ var shows []WatchedShow
312+ if err := json .NewDecoder (resp .Body ).Decode (& shows ); err != nil {
313+ c .logger .Error ("errors.api_response_parse_failed" , map [string ]interface {}{
314+ "error" : err .Error (),
315+ })
316+ return nil , fmt .Errorf ("failed to parse response: %w" , err )
317+ }
318+
319+ c .logger .Info ("api.watched_shows_fetched" , map [string ]interface {}{
320+ "count" : len (shows ),
321+ })
322+ return shows , nil
216323}
0 commit comments