Skip to content
Open
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
48 changes: 48 additions & 0 deletions trakt/sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -528,6 +528,54 @@ def get_collection(list_type=None, extended=None):
results.append(TVShow(**d.pop('show')))

yield results

@get
def get_history(list_type=None, id=None, start_at=None, end_at=None):
"""Returns movies and episodes that a user has watched, sorted by most recent.

:param list_type: Optional Filter by a specific type.
Possible values: movies or episodes.
:param id: Optional Trakt ID for a specific item.
:param start_at : Optional, A `datetime.datetime` object or `str`, Filter by watched date starting at.
:param end_at : Optional, A `datetime.datetime` object or `str`, Filter by watched date ending at.
"""
valid_type = ('movies', 'episodes')

if list_type and list_type not in valid_type:
raise ValueError('list_type must be one of {}'.format(valid_type))

uri = 'sync/history'
if list_type:
uri += '/{}'.format(list_type)

if id:
uri += '/{}'.format(id)

if not isinstance(start_at, str):
start_at = timestamp(start_at)
if start_at:
uri += '?start_at={start_at}'.format(start_at=start_at)

if not isinstance(end_at, str):
end_at = timestamp(end_at)
if end_at:
uri += '?end_at={end_at}'.format(end_at=end_at)

Comment on lines +554 to +563
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Bug: None handling and malformed query string for start_at/end_at

  • start_at/end_at are timestamped even when None -> crashes.
  • Second query param incorrectly uses ? instead of &.

Apply this diff:

-    if not isinstance(start_at, str):
-        start_at = timestamp(start_at)
-    if start_at:
-        uri += '?start_at={start_at}'.format(start_at=start_at)
-               
-    if not isinstance(end_at, str):
-        end_at = timestamp(end_at)
-    if end_at:
-        uri += '?end_at={end_at}'.format(end_at=end_at)
+    params = []
+    if start_at:
+        if not isinstance(start_at, str):
+            start_at = timestamp(start_at)
+        params.append(f"start_at={start_at}")
+    if end_at:
+        if not isinstance(end_at, str):
+            end_at = timestamp(end_at)
+        params.append(f"end_at={end_at}")
+    if params:
+        uri += "?" + "&".join(params)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if not isinstance(start_at, str):
start_at = timestamp(start_at)
if start_at:
uri += '?start_at={start_at}'.format(start_at=start_at)
if not isinstance(end_at, str):
end_at = timestamp(end_at)
if end_at:
uri += '?end_at={end_at}'.format(end_at=end_at)
params = []
if start_at:
if not isinstance(start_at, str):
start_at = timestamp(start_at)
params.append(f"start_at={start_at}")
if end_at:
if not isinstance(end_at, str):
end_at = timestamp(end_at)
params.append(f"end_at={end_at}")
if params:
uri += "?" + "&".join(params)
🤖 Prompt for AI Agents
In trakt/sync.py around lines 554-563, the code timestamps start_at/end_at even
when they are None (causing crashes) and appends the second query param with '?'
instead of '&', producing a malformed query string; fix by only calling
timestamp(...) if the value is not None, build the query string safely by
collecting params into a list (e.g., params = [] then if start_at is not None:
params.append(f"start_at={timestamp(start_at) if not isinstance(start_at, str)
else start_at}") and similarly for end_at) and then append them to uri as '?' +
'&'.join(params) only if params is non-empty (avoiding multiple '?' and skipping
None values).


data = yield uri
results = []
for d in data:
if 'movie' in d:
from trakt.movies import Movie

results.append(Movie(**d.pop('movie')))
elif 'episode' in d:
from trakt.tv import TVEpisode

results.append(TVEpisode(**d.pop('episode')))

Comment on lines +572 to +576
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Bug: TVEpisode constructed without required show context

TVEpisode requires show context; constructing with only episode dict will raise or produce an invalid object. Follow the existing pattern used elsewhere in this module.

Apply this diff:

-        elif 'episode' in d:
-            from trakt.tv import TVEpisode
-
-            results.append(TVEpisode(**d.pop('episode')))
+        elif 'episode' in d:
+            from trakt.tv import TVEpisode
+            show = d.pop('show')
+            ep = d.pop('episode')
+            results.append(
+                TVEpisode(
+                    show.get('title', None),
+                    show_id=show['ids'].get('trakt'),
+                    **ep
+                )
+            )
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
elif 'episode' in d:
from trakt.tv import TVEpisode
results.append(TVEpisode(**d.pop('episode')))
elif 'episode' in d:
from trakt.tv import TVEpisode
show = d.pop('show')
ep = d.pop('episode')
results.append(
TVEpisode(
show.get('title', None),
show_id=show['ids'].get('trakt'),
**ep
)
)
🤖 Prompt for AI Agents
In trakt/sync.py around lines 572-576, the code constructs TVEpisode with only
the episode dict which lacks required show context; instead, pop the episode
dict and the associated show dict (as done elsewhere), construct a TVShow object
from the show dict, then construct the TVEpisode passing the episode fields plus
show=that TVShow instance; also add/import TVShow at the top if not already
imported so the episode has proper show context.

yield results



@post
Expand Down