sync module, limited in updating watchlist / collection
hi @moogar0880 I don't know if this project is still alive. But recently I decided to refactor some it's code, as it's kinda limited compared to what the trakt api offers.
One example is the exposure of sync/collection and sync/watchlist. You'r only allowed to pass one TvShow, TVEpisode or Movie object to it. Where the trakt api offers a number of ways, where you can send multiple episodes, shows or movies to it. This brings some issues as for example. If you want to do batch updates of a number of episodes, you have to call the sync/ route for each episodes. Possibly resulting in rate limiting.
Now i'm able to work around this with the following code:
@post
def add_to_collection(media=None, media_type=None, media_objects=None):
"""Add a :class:`Movie`, :class:`TVShow`, or :class:`TVEpisode` to your
collection
The trakt api allows for adding or removing multiple media objects
through an array. If you want to make us if this.
Make sure to leave media empty, and pass the media_type
('movies', 'shows' or 'episodes')
and don't pass a value for `media`. Make sure to pass an array of
media objects to media_objects.
:param media: The :class:`TVShow` shows, :class:`TVEpisode` episodes,
or :class:`Movie` movies media object.
:param media_type: The :string: media type key
:param media_objects: The :class:`TVShow` shows, :class:`TVEpisode` episodes,
or :class:`Movie` movies media object.
"""
valid_type = ('movies', 'shows', 'episodes')
if media:
yield 'sync/collection', media.to_json()
if media_type and media_objects and isinstance(media_objects, list):
if media_type not in valid_type:
raise ValueError('media_type must be one of {}'.format(valid_type))
yield 'sync/collection', {
media_type: [media_object.to_json_singular()[media_type[:-1]]
for media_object in media_objects]
}
But then the next issue pops up. For updating episodes, currently it's sending the following object:
{
"episode": {
"ids": {
"trakt": [episode_trakt_id]
}
}
}
But we don't have this id available when sending the request. Now the way it's currently working, is that it will request the trakt id using the show-slug. And there are two issues i have with that.
- It's doing an extra request for each episode, while that's not really needed.
- It leaves room for error as i'm using slug and not and id (imdb, trakt, tvdb, etc)
@property
def ext(self):
return 'shows/{id}/seasons/{season}/episodes/{episode}'.format(
id=slugify(self.show), season=self.season, episode=self.number
)
So i'd prefer to use the forrmat of:
"title": "Mad Men",
"year": 2007,
"ids": {
"trakt": 4,
"slug": "mad-men",
"tvdb": 80337,
"imdb": "tt0804503",
"tmdb": 1104
},
"seasons": [
{
"number": 1,
"episodes": [
{
"number": 1,
"media_type": "bluray",
"resolution": "hd_1080p",
"audio": "dolby_digital_plus",
"audio_channels": "5.1"
},
{
"number": 2
}
]
}
But this does not fit into the current architecture of PyTrakt.
An alternative i've considered. Is adding a generec sync route, that just routes and passes along the request to the route that can handle these structures of standard media objects
i'm going with this for now. As I can't think of a solution where I don't have to rewrite large parts of the code.
@post
def add_to_watchlist(media):
"""Add a :class:`Movie`, :class:`TVShow`, or :class:`TVEpisode`
to your watchlist
"""
# Legacy support of using PyTrakt media objects.
if isinstance(media, (TVEpisode, TVSeason, TVShow, Movie)):
media_object = media.to_json()
else:
media_object = media
yield 'sync/watchlist', media_object
hey @p0psicles sorry about the lack of communication. I think I may have gotten overzealous when tuning my github notifications a couple months ago... but, to your questions:
I don't know if this project is still alive... it's kinda limited compared to what the trakt api offers.
It's definitely been a while since I've had the time or need to develop on this library. I'm certainly happy to review/merge PRs or provide feedback/input as needed but I don't think I'll have much in the way of time to start doing heavy development on this library, which it sounds like may be needed.
It's doing an extra request for each episode, while that's not really needed
Is the extra request you're referring to a request to get the trakt_id that PyTrakt is currently trying to send to update a collection? If so it sounds to me like maybe the sync API calls in PyTrakt should be updated to check if there's a way to send a resource being synchronized to trakt without additional API requests?
It comes down to requiring the TVShow().to_json() and TVEpisode().to_json() methods. I understand the initial idea behind it. But in practice it's really limiting the trakt sync api usage.
What would you think of the last code example I posted? In just allowing the user to send it's own dict struct?
I think allowing users to send their own arbitrary blobs of data should be fine. I'm not entirely sure that the class implementations should be flagged as "legacy", but the approach seems reasonable 👍
Ooh that's fine. I think I added the legacy comment more to show a user the old and new behavior. But I can remove the comment.
I did some more changes. I'll create one big PR. That you can give your feedback on. Then I can submit one PR per functional change.
Then we can take a look at the documentation. As I noticed it was lagging a bit behind. Is there a place where I can update it?
I did some more changes. I'll create one big PR. That you can give your feedback on. Then I can submit one PR per functional change.
Sounds good to me 👍
Then we can take a look at the documentation. As I noticed it was lagging a bit behind. Is there a place where I can update it?
All of the docs are automatically generated from the rst files in the docs/ directory, as well as the embedded docstrings on the classes/functions/etc, so you should be able to just update those as you go. Just taking a quick look at the docs directory it seems like nothing in there has changed in several years so I agree that those are very likely overdue for an update.