Skip to content

Commit 8914651

Browse files
committed
Merge branch 'trakt-watched-pagination'
2 parents efa4f6a + fac9c04 commit 8914651

10 files changed

Lines changed: 598 additions & 38 deletions

File tree

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
# Changelog
22

3+
## Next release
4+
5+
* Address upcoming [Trakt pagination requirements](https://github.com/trakt/trakt-api/discussions/775) for watched methods:
6+
* Add paginated variants of `Sync.watchedMovies()`, `Sync.watchedShows()`, `Users.watchedMovies()` and
7+
`Users.watchedShows()` with required `page` and `limit` parameters. The original methods are deprecated.
8+
* Add `min` variants of watched methods: `Users.watchedMoviesMin()`, `Users.watchedShowsMin()`, `Sync.watchedMoviesMin()` and `Sync.watchedShowsMin()`
9+
* Add episode variant of watched methods: `Sync.watchedEpisodes()` and `Sync.watchedEpisodesMin()`
10+
311
## 6.18.0 - 2026-03-06
412

513
* Watchlist endpoints require pagination: deprecate the variants that don't accept page and limit parameters.
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
* Copyright © 2026 Uwe Trottmann <uwe@uwetrottmann.com>
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.uwetrottmann.trakt5.entities;
18+
19+
20+
import org.threeten.bp.OffsetDateTime;
21+
22+
public class WatchedEpisode {
23+
24+
public Integer plays;
25+
/**
26+
* Warning: Trakt only stores and returns minute-precision timestamps for watched_at. So seconds and
27+
* nanoseconds will always be zero.
28+
*/
29+
public OffsetDateTime last_watched_at;
30+
public OffsetDateTime last_updated_at;
31+
32+
public Episode episode;
33+
34+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/*
2+
* Copyright © 2026 Uwe Trottmann <uwe@uwetrottmann.com>
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.uwetrottmann.trakt5.enums;
18+
19+
/**
20+
* Extended info options for the watched movies endpoint.
21+
*/
22+
public class ExtendedMoviesWatched implements TraktEnum {
23+
24+
/**
25+
* Return movie details, like overview and rating.
26+
*
27+
* @deprecated Starting 2026-05-30, this will be the default. See the
28+
* <a href="https://github.com/trakt/trakt-api/discussions/775">Upcoming API Changes: Watched Endpoints Pagination &
29+
* Extended Defaults</a> discussion for details and updates.
30+
*/
31+
@Deprecated
32+
public static final ExtendedMoviesWatched FULL = new ExtendedMoviesWatched("full");
33+
34+
private final String value;
35+
36+
private ExtendedMoviesWatched(String value) {
37+
this.value = value;
38+
}
39+
40+
@Override
41+
public String toString() {
42+
return value;
43+
}
44+
}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/*
2+
* Copyright © 2026 Uwe Trottmann <uwe@uwetrottmann.com>
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.uwetrottmann.trakt5.enums;
18+
19+
import java.util.Arrays;
20+
import java.util.stream.Collectors;
21+
22+
/**
23+
* Extended info options for the watched shows endpoint. Use {@link #of(ExtendedShowsWatched...)}
24+
* to combine multiple values into a comma-separated parameter.
25+
*/
26+
public class ExtendedShowsWatched implements TraktEnum {
27+
28+
/**
29+
* Return show details, like overview and rating.
30+
*
31+
* @deprecated Starting 2026-05-30, this will be the default. See the
32+
* <a href="https://github.com/trakt/trakt-api/discussions/775">Upcoming API Changes: Watched Endpoints Pagination &
33+
* Extended Defaults</a> discussion for details and updates.
34+
*/
35+
@Deprecated
36+
public static final ExtendedShowsWatched FULL = new ExtendedShowsWatched("full");
37+
38+
/**
39+
* Exclude watched info for seasons and episodes.
40+
*
41+
* @deprecated Starting 2026-05-30, this will be the default. See the
42+
* <a href="https://github.com/trakt/trakt-api/discussions/775">Upcoming API Changes: Watched Endpoints Pagination &
43+
* Extended Defaults</a> discussion for details and updates.
44+
*/
45+
@Deprecated
46+
public static final ExtendedShowsWatched NOSEASONS = new ExtendedShowsWatched("noseasons");
47+
48+
/**
49+
* Include season progress information.
50+
* <p>
51+
* Note: until 2026-05-30 this is the default and won't have any effect. See the
52+
* <a href="https://github.com/trakt/trakt-api/discussions/775">Upcoming API Changes: Watched Endpoints Pagination &
53+
* Extended Defaults</a> discussion for details and updates.
54+
*/
55+
public static final ExtendedShowsWatched PROGRESS = new ExtendedShowsWatched("progress");
56+
57+
/**
58+
* Combine multiple extended values into a single comma-separated parameter.
59+
* <p>
60+
* Example: {@code ExtendedShowsWatched.of(FULL, NOSEASONS)} produces {@code "full,noseasons"}.
61+
*/
62+
public static ExtendedShowsWatched of(ExtendedShowsWatched... values) {
63+
if (values == null || values.length == 0) {
64+
throw new IllegalArgumentException("At least one value is required.");
65+
}
66+
return new ExtendedShowsWatched(
67+
Arrays.stream(values).map(ExtendedShowsWatched::toString).collect(Collectors.joining(","))
68+
);
69+
}
70+
71+
private final String value;
72+
73+
private ExtendedShowsWatched(String value) {
74+
this.value = value;
75+
}
76+
77+
@Override
78+
public String toString() {
79+
return value;
80+
}
81+
}

src/main/java/com/uwetrottmann/trakt5/enums/TraktEnum.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,12 @@
1616

1717
package com.uwetrottmann.trakt5.enums;
1818

19+
/**
20+
* Warning: GSON does not use {@link #toString()} to serialize enums, but the key value.
21+
* Use @SerializedName for these enums (or register both serializer and deserializer in TraktV2Helper).
22+
*/
1923
public interface TraktEnum {
2024

21-
// Note: GSON does not use .toString() to serialize enums, but the key value.
22-
// Use @SerializedName for these enums (or register both serializer and deserializer in TraktV2Helper).
23-
2425
/**
2526
* Return the value to be used by retrofit when building a request.
2627
*/

src/main/java/com/uwetrottmann/trakt5/services/Sync.java

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,12 @@
2929
import com.uwetrottmann.trakt5.entities.SyncItems;
3030
import com.uwetrottmann.trakt5.entities.SyncResponse;
3131
import com.uwetrottmann.trakt5.entities.UserSlug;
32+
import com.uwetrottmann.trakt5.entities.WatchedEpisode;
3233
import com.uwetrottmann.trakt5.entities.WatchlistedEpisode;
3334
import com.uwetrottmann.trakt5.entities.WatchlistedSeason;
3435
import com.uwetrottmann.trakt5.enums.Extended;
36+
import com.uwetrottmann.trakt5.enums.ExtendedMoviesWatched;
37+
import com.uwetrottmann.trakt5.enums.ExtendedShowsWatched;
3538
import com.uwetrottmann.trakt5.enums.HistoryType;
3639
import com.uwetrottmann.trakt5.enums.PlaybackType;
3740
import com.uwetrottmann.trakt5.enums.RatingsFilter;
@@ -46,6 +49,7 @@
4649

4750
import javax.annotation.Nonnull;
4851
import java.util.List;
52+
import java.util.Map;
4953

5054
public interface Sync {
5155

@@ -139,12 +143,38 @@ Call<SyncResponse> deleteItemsFromCollection(
139143
* <b>OAuth {@link TraktV2#accessToken(String) access token} required</b>
140144
* <p>
141145
* Returns all movies a user has watched.
146+
*
147+
* @deprecated Use {@link #watchedMovies(int, int, ExtendedMoviesWatched)} instead.
142148
*/
149+
@Deprecated
143150
@GET("sync/watched/movies")
144151
Call<List<BaseMovie>> watchedMovies(
145152
@Query(value = "extended", encoded = true) Extended extended
146153
);
147154

155+
/**
156+
* <b>OAuth {@link TraktV2#accessToken(String) access token} required</b>
157+
* <p>
158+
* Like {@link Users#watchedMovies(UserSlug, int, int, ExtendedMoviesWatched)}.
159+
*/
160+
@GET("sync/watched/movies")
161+
Call<List<BaseMovie>> watchedMovies(
162+
@Query("page") int page,
163+
@Query("limit") int limit,
164+
@Query(value = "extended", encoded = true) ExtendedMoviesWatched extended
165+
);
166+
167+
/**
168+
* <b>OAuth {@link TraktV2#accessToken(String) access token} required</b>
169+
* <p>
170+
* Like {@link Users#watchedMoviesMin(UserSlug, int, int)}.
171+
*/
172+
@GET("sync/watched/movies?extended=min")
173+
Call<Map<String, List<OffsetDateTime>>> watchedMoviesMin(
174+
@Query("page") int page,
175+
@Query("limit") int limit
176+
);
177+
148178
/**
149179
* <b>OAuth {@link TraktV2#accessToken(String) access token} required</b>
150180
* <p>
@@ -243,12 +273,74 @@ Call<Void> removePlayback(
243273
* <b>OAuth {@link TraktV2#accessToken(String) access token} required</b>
244274
* <p>
245275
* Returns all shows a user has watched.
276+
*
277+
* @deprecated Use {@link #watchedShows(int, int, ExtendedShowsWatched)} instead.
246278
*/
279+
@Deprecated
247280
@GET("sync/watched/shows")
248281
Call<List<BaseShow>> watchedShows(
249282
@Query(value = "extended", encoded = true) Extended extended
250283
);
251284

285+
/**
286+
* <b>OAuth {@link TraktV2#accessToken(String) access token} required</b>
287+
* <p>
288+
* Like {@link Users#watchedShows(UserSlug, int, int, ExtendedShowsWatched)}.
289+
*/
290+
@GET("sync/watched/shows")
291+
Call<List<BaseShow>> watchedShows(
292+
@Query("page") int page,
293+
@Query("limit") int limit,
294+
@Query(value = "extended", encoded = true) ExtendedShowsWatched extended
295+
);
296+
297+
/**
298+
* <b>OAuth {@link TraktV2#accessToken(String) access token} required</b>
299+
* <p>
300+
* Like {@link Users#watchedShowsMin(UserSlug, int, int)}.
301+
*/
302+
@GET("sync/watched/shows?extended=min")
303+
Call<Map<String, Map<String, Map<String, List<OffsetDateTime>>>>> watchedShowsMin(
304+
@Query("page") int page,
305+
@Query("limit") int limit
306+
);
307+
308+
/**
309+
* <b>OAuth {@link TraktV2#accessToken(String) access token} required</b>
310+
* <p>
311+
* Returns all episodes a user has watched.
312+
*
313+
* @param page Number of page of results to be returned.
314+
* @param limit Number of results to return per page.
315+
*/
316+
@GET("sync/watched/episodes")
317+
Call<List<WatchedEpisode>> watchedEpisodes(
318+
@Query("page") int page,
319+
@Query("limit") int limit
320+
);
321+
322+
/**
323+
* <b>OAuth {@link TraktV2#accessToken(String) access token} required</b>
324+
* <p>
325+
* Returns episode Trakt IDs mapped to a list of watched at timestamps.
326+
* <p>
327+
* An example for an equivalent JSON for a single episode with three watched at timestamps:
328+
* <pre>
329+
* {
330+
* "73482": [
331+
* "2015-02-10T09:04:00.000Z",
332+
* "2015-02-10T15:42:00.000Z",
333+
* "2015-02-24T05:51:00.000Z"
334+
* ]
335+
* }
336+
* </pre>
337+
*/
338+
@GET("sync/watched/episodes?extended=min")
339+
Call<Map<String, List<OffsetDateTime>>> watchedEpisodesMin(
340+
@Query("page") int page,
341+
@Query("limit") int limit
342+
);
343+
252344
/**
253345
* <b>OAuth {@link TraktV2#accessToken(String) access token} required</b>
254346
* <p>

0 commit comments

Comments
 (0)