-
Notifications
You must be signed in to change notification settings - Fork 5
[Feature] added get_history function #2 #92
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
added get_history function
Considering coderabbit return on my first PR, I changed TVShow to TVEpisode as get_history returns episodes, not shows. I edited it instead of approving coderabbit proposition beacause it added unecessary (IMO) stuff.
WalkthroughAdded a new function get_history in trakt/sync.py (decorated with @get) to retrieve sync/history with optional type, id, and time-range filters. It constructs the URI with path segments and query parameters, invokes the API, and maps results to Movie or TVEpisode objects. Query param assembly uses separate ?start_at and ?end_at fragments. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant C as Client
participant S as Sync.get_history()
participant A as Trakt API (sync/history)
participant M as Mapper (Movie/TVEpisode)
C->>S: get_history(list_type?, id?, start_at?, end_at?)
Note right of S: Build URI: /sync/history[/type[/id]]<br/>Append start_at/end_at as query params
S->>A: GET /sync/history...
A-->>S: JSON history entries
S->>M: Map each entry by type
M-->>S: [Movie | TVEpisode, ...]
S-->>C: Return list
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
✨ Finishing Touches
🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Nitpick comments (2)
trakt/sync.py (2)
533-533: Prefer not shadowing built-in idRename the parameter and its usages for clarity.
Apply this diff:
-def get_history(list_type=None, id=None, start_at=None, end_at=None): +def get_history(list_type=None, item_id=None, start_at=None, end_at=None): @@ - if id: - uri += '/{}'.format(id) + if item_id: + uri += '/{}'.format(item_id)Also applies to: 551-553
533-541: Optional: enforce timezone-aware datetimesIf callers pass naive datetimes, timestamp() will serialize them as-is. Consider normalizing to UTC or documenting the expectation.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (1)
trakt/sync.py(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
trakt/sync.py (4)
trakt/core.py (1)
get(144-147)trakt/utils.py (1)
timestamp(47-50)trakt/movies.py (1)
Movie(93-387)trakt/tv.py (1)
TVEpisode(723-970)
🔇 Additional comments (1)
trakt/sync.py (1)
547-553: Confirm: is item id valid without specifying type?Trakt’s docs typically show the form /sync/history/{type}/{id}. If type is required when passing an id, we should guard against item_id without list_type.
Apply this (if confirmed):
uri = 'sync/history' if list_type: uri += '/{}'.format(list_type) - if item_id: + if item_id: + if not list_type: + raise ValueError("When specifying an id, list_type must be 'movies' or 'episodes'.") uri += '/{}'.format(item_id)Would you like me to check the latest Trakt spec and adjust accordingly?
| 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) | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
| 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).
| elif 'episode' in d: | ||
| from trakt.tv import TVEpisode | ||
|
|
||
| results.append(TVEpisode(**d.pop('episode'))) | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
| 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.
Considering coderabbit return on previous commit, I changed TVShow to TVEpisode as get_history returns episodes, not shows. I edited it instead of approving coderabbit proposition beacause it added unecessary (IMO) stuff.
It resulted in 2 differents PR, I don't know if I could have done it differently I'm no github pro !