Example #1
0
    def to_dict(self):
        """Dump progress to a dictionary.

        :return: Progress dictionary
        :rtype: :class:`~python:dict`
        """

        result = super(Progress, self).to_dict()

        label = LABELS['last_progress_change'][self.progress_type]
        result[label] = to_iso8601_datetime(self.last_progress_change)

        if self.progress_type == 'watched':
            result['reset_at'] = self.reset_at

        result['seasons'] = [
            season.to_dict()
            for season in self.seasons.values()
        ]

        if self.hidden_seasons:
            result['hidden_seasons'] = [
                popitems(season.to_dict(), ['number', 'ids'])
                for season in self.hidden_seasons.values()
            ]

        if self.next_episode:
            result['next_episode'] = popitems(self.next_episode.to_dict(), ['season', 'number', 'title', 'ids'])
            result['next_episode']['season'] = self.next_episode.keys[0][0]

        if self.last_episode:
            result['last_episode'] = popitems(self.last_episode.to_dict(), ['season', 'number', 'title', 'ids'])
            result['last_episode']['season'] = self.last_episode.keys[0][0]

        return result
Example #2
0
    def get(self,
            media=None,
            store=None,
            params=None,
            query=None,
            flat=False,
            **kwargs):
        if not params:
            params = []

        params.insert(0, media)

        # Request resource
        response = self.http.get(
            params=params,
            query=query,
            **popitems(kwargs, ['authenticated', 'validate_token']))

        # Parse response
        items = self.get_data(response, **kwargs)

        if isinstance(items, requests.Response):
            return items

        if type(items) is not list and not isinstance(items,
                                                      PaginationIterator):
            return None

        # Map items
        return SyncMapper.process(self.client,
                                  store,
                                  items,
                                  media=media,
                                  flat=flat,
                                  **self.flags)
Example #3
0
    def remove(self, items, **kwargs):
        response = self.http.post(
            'remove',
            data=items,
            **popitems(kwargs, ['authenticated', 'validate_token']))

        return self.get_data(response, **kwargs)
Example #4
0
    def get(self, media=None, store=None, params=None, query=None, flat=False, **kwargs):
        if not params:
            params = []

        params.insert(0, media)

        # Request resource
        response = self.http.get(
            params=params,
            query=query,
            **popitems(kwargs, [
                'authenticated',
                'validate_token'
            ])
        )

        # Parse response
        items = self.get_data(response, **kwargs)

        if isinstance(items, requests.Response):
            return items

        if type(items) is not list and not isinstance(items, PaginationIterator):
            return None

        # Map items
        return SyncMapper.process(
            self.client, store, items,
            media=media,
            flat=flat,
            **self.flags
        )
Example #5
0
    def likes(self, type=None, **kwargs):
        if type and type not in ['comments', 'lists']:
            raise ValueError('Unknown type specified: %r' % type)

        if kwargs.get('parse') is False:
            raise ValueError('Parse can\'t be disabled on this method')

        # Send request
        response = self.http.get(
            'likes',
            params=[type],
            **popitems(kwargs, ['authenticated', 'validate_token']))

        # Parse response
        items = self.get_data(response, **kwargs)

        if not items:
            return

        # Map items to comment/list objects
        for item in items:
            item_type = item.get('type')

            if item_type == 'comment':
                yield CommentMapper.comment(self.client, item)
            elif item_type == 'list':
                yield ListMapper.custom_list(self.client, item)
            else:
                log.warn('Unknown item returned, type: %r', item_type)
Example #6
0
    def delete(self, username, id, **kwargs):
        # Send request
        response = self.http.delete(
            '/users/%s/lists/%s' % (clean_username(username), id),
            **popitems(kwargs, ['authenticated', 'validate_token']))

        return 200 <= response.status_code < 300
Example #7
0
    def add(self, username, id, items, **kwargs):
        # Send request
        response = self.http.post(
            '/users/%s/lists/%s/items' % (clean_username(username), id),
            data=items,
            **popitems(kwargs, ['authenticated', 'validate_token']))

        # Parse response
        return self.get_data(response, **kwargs)
Example #8
0
    def get(self, id, **kwargs):
        response = self.http.get(str(id), query=dict(**popitems(kwargs, ['extended', 'limit'])))

        item = self.get_data(response, **kwargs)

        if isinstance(item, requests.Response):
            return item

        return SummaryMapper.show(self.client, item)
Example #9
0
    def get(self, **kwargs):
        response = self.http.get(
            **popitems(kwargs, [
                'authenticated',
                'validate_token'
            ])
        )

        return self.get_data(response, **kwargs)
Example #10
0
    def trending(self, **kwargs):
        response = self.http.get('trending', query=dict(**popitems(kwargs, ['extended', 'limit'])))

        items = self.get_data(response, **kwargs)

        if isinstance(items, requests.Response):
            return items

        return SummaryMapper.shows(self.client, items)
Example #11
0
    def trending(self, **kwargs):
        response = self.http.get(
            'trending', query=dict(**popitems(kwargs, ['extended', 'limit'])))

        items = self.get_data(response, **kwargs)

        if isinstance(items, requests.Response):
            return items

        return SummaryMapper.shows(self.client, items)
Example #12
0
    def get(self, id, **kwargs):
        response = self.http.get(
            str(id), query=dict(**popitems(kwargs, ['extended', 'limit'])))

        item = self.get_data(response, **kwargs)

        if isinstance(item, requests.Response):
            return item

        return SummaryMapper.show(self.client, item)
Example #13
0
    def add(self, items, **kwargs):
        response = self.http.post(
            data=items,
            **popitems(kwargs, [
                'authenticated',
                'validate_token'
            ])
        )

        return self.get_data(response, **kwargs)
Example #14
0
    def delete(self, playbackid, **kwargs):
        response = self.http.delete(
            path=str(playbackid),
            **popitems(kwargs, [
                'authenticated',
                'validate_token'
            ])
        )

        return 200 <= response.status_code < 300
Example #15
0
    def delete(self, username, id, **kwargs):
        # Send request
        response = self.http.delete(
            '/users/%s/lists/%s' % (clean_username(username), id),
            **popitems(kwargs, [
                'authenticated',
                'validate_token'
            ])
        )

        return 200 <= response.status_code < 300
Example #16
0
 def last_activities(self, **kwargs):
     return self.get_data(
         self.http.get(
             'last_activities',
             **popitems(kwargs, [
                 'authenticated',
                 'validate_token'
             ])
         ),
         **kwargs
     )
Example #17
0
    def get(self, start_date: date, days: int, **kwargs):
        params = ['{:%Y-%m-%d}'.format(start_date), days]

        response = self.http.get(
            params=params,
            **popitems(kwargs, ['authenticated', 'validate_token']))

        items = self.get_data(response, **kwargs)

        if isinstance(items, requests.Response):
            return items

        return SummaryMapper.shows(self.client, items)
Example #18
0
    def add(self, username, id, items, **kwargs):
        # Send request
        response = self.http.post(
            '/users/%s/lists/%s/items' % (clean_username(username), id),
            data=items,
            **popitems(kwargs, [
                'authenticated',
                'validate_token'
            ])
        )

        # Parse response
        return self.get_data(response, **kwargs)
    def to_dict(self):
        """Dump progress to a dictionary.

        :return: Progress dictionary
        :rtype: :class:`~python:dict`
        """

        result = super(Progress, self).to_dict()

        label = LABELS['last_progress_change'][self.progress_type]
        result[label] = to_iso8601_datetime(self.last_progress_change)

        if self.progress_type == 'watched':
            result['reset_at'] = self.reset_at

        result['seasons'] = [
            season.to_dict() for season in self.seasons.values()
        ]

        if self.hidden_seasons:
            result['hidden_seasons'] = [
                popitems(season.to_dict(), ['number', 'ids'])
                for season in self.hidden_seasons.values()
            ]

        if self.next_episode:
            result['next_episode'] = popitems(
                self.next_episode.to_dict(),
                ['season', 'number', 'title', 'ids'])
            result['next_episode']['season'] = self.next_episode.keys[0][0]

        if self.last_episode:
            result['last_episode'] = popitems(
                self.last_episode.to_dict(),
                ['season', 'number', 'title', 'ids'])
            result['last_episode']['season'] = self.last_episode.keys[0][0]

        return result
Example #20
0
    def update(self,
               username,
               id,
               name=None,
               description=None,
               privacy=None,
               display_numbers=None,
               allow_comments=None,
               return_type='object',
               **kwargs):
        data = {
            'name': name,
            'description': description,
            'privacy': privacy,
            'allow_comments': allow_comments,
            'display_numbers': display_numbers
        }

        # Remove attributes with `None` values
        for key in list(data.keys()):
            if data[key] is not None:
                continue

            del data[key]

        # Send request
        response = self.http.put(
            '/users/%s/lists/%s' % (clean_username(username), id),
            data=data,
            **popitems(kwargs, ['authenticated', 'validate_token']))

        # Parse response
        item = self.get_data(response, **kwargs)

        if isinstance(item, requests.Response):
            return item

        if not item:
            return None

        if return_type == 'data':
            return item

        if return_type == 'object':
            # Map item to list object
            return ListMapper.custom_list(self.client, item, username=username)

        raise ValueError('Unsupported value for "return_type": %r',
                         return_type)
Example #21
0
    def update(self, username, id, name=None, description=None, privacy=None, display_numbers=None,
               allow_comments=None, return_type='object', **kwargs):
        data = {
            'name': name,
            'description': description,

            'privacy': privacy,
            'allow_comments': allow_comments,
            'display_numbers': display_numbers
        }

        # Remove attributes with `None` values
        for key in list(data.keys()):
            if data[key] is not None:
                continue

            del data[key]

        # Send request
        response = self.http.put(
            '/users/%s/lists/%s' % (clean_username(username), id),
            data=data,
            **popitems(kwargs, [
                'authenticated',
                'validate_token'
            ])
        )

        # Parse response
        item = self.get_data(response, **kwargs)

        if isinstance(item, requests.Response):
            return item

        if not item:
            return None

        if return_type == 'data':
            return item

        if return_type == 'object':
            # Map item to list object
            return ListMapper.custom_list(
                self.client, item,
                username=username
            )

        raise ValueError("Unsupported value for \"return_type\": %r", return_type)
Example #22
0
    def progress(self, progress_type, id, hidden=False, specials=False, count_specials=True, **kwargs):
        query = {
            'hidden': hidden,
            'specials': specials,
            'count_specials': count_specials
        }

        response = self.http.get(str(id), [
            'progress', progress_type
        ], query=query, **popitems(kwargs, [
            'authenticated',
            'validate_token'
        ]))

        item = self.get_data(response, **kwargs)

        if isinstance(item, requests.Response):
            return item

        return ProgressMapper.progress(self.client, progress_type, item)
Example #23
0
    def likes(self, type=None, **kwargs):
        if type and type not in ['comments', 'lists']:
            raise ValueError('Unknown type specified: %r' % type)

        if kwargs.get('parse') is False:
            raise ValueError('Parse can\'t be disabled on this method')

        # Send request
        response = self.http.get(
            'likes',
            params=[type],
            **popitems(kwargs, [
                'authenticated',
                'validate_token'
            ])
        )

        # Parse response
        items = self.get_data(response, **kwargs)

        if not items:
            return

        # Map items to comment/list objects
        for item in items:
            item_type = item.get('type')

            if item_type == 'comment':
                yield CommentMapper.comment(
                    self.client, item
                )
            elif item_type == 'list':
                yield ListMapper.custom_list(
                    self.client, item
                )
            else:
                log.warn('Unknown item returned, type: %r', item_type)
Example #24
0
    def progress(self,
                 progress_type,
                 id,
                 hidden=False,
                 specials=False,
                 count_specials=True,
                 **kwargs):
        query = {
            'hidden': hidden,
            'specials': specials,
            'count_specials': count_specials
        }

        response = self.http.get(
            str(id), ['progress', progress_type],
            query=query,
            **popitems(kwargs, ['authenticated', 'validate_token']))

        item = self.get_data(response, **kwargs)

        if isinstance(item, requests.Response):
            return item

        return ProgressMapper.progress(self.client, progress_type, item)
Example #25
0
    def get(self, **kwargs):
        response = self.http.get(
            **popitems(kwargs, ['authenticated', 'validate_token']))

        return self.get_data(response, **kwargs)
Example #26
0
    def get(self,
            source,
            media,
            collection=None,
            start_date=None,
            days=None,
            query=None,
            years=None,
            genres=None,
            languages=None,
            countries=None,
            runtimes=None,
            ratings=None,
            certifications=None,
            networks=None,
            status=None,
            **kwargs):
        """Retrieve calendar items.

        The `all` calendar displays info for all shows airing during the specified period. The `my` calendar displays
        episodes for all shows that have been watched, collected, or watchlisted.

        :param source: Calendar source (`all` or `my`)
        :type source: str

        :param media: Media type (`dvd`, `movies` or `shows`)
        :type media: str

        :param collection: Collection type (`new`, `premieres`)
        :type collection: str or None

        :param start_date: Start date (defaults to today)
        :type start_date: datetime or None

        :param days: Number of days to display (defaults to `7`)
        :type days: int or None

        :param query: Search title or description.
        :type query: str or None

        :param years: Year or range of years (e.g. `2014`, or `2014-2016`)
        :type years: int or str or tuple or None

        :param genres: Genre slugs (e.g. `action`)
        :type genres: str or list of str or None

        :param languages: Language codes (e.g. `en`)
        :type languages: str or list of str or None

        :param countries: Country codes (e.g. `us`)
        :type countries: str or list of str or None

        :param runtimes: Runtime range in minutes (e.g. `30-90`)
        :type runtimes: str or tuple or None

        :param ratings: Rating range between `0` and `100` (e.g. `75-100`)
        :type ratings: str or tuple or None

        :param certifications: US Content Certification (e.g. `pg-13`, `tv-pg`)
        :type certifications: str or list of str or None

        :param networks: (TV) Network name (e.g. `HBO`)
        :type networks: str or list of str or None

        :param status: (TV) Show status (e.g. `returning series`, `in production`, ended`)
        :type status: str or list of str or None

        :return: Items
        :rtype: list of trakt.objects.video.Video
        """
        if source not in ['all', 'my']:
            raise ValueError('Unknown collection type: %s' % (source, ))

        if media not in ['dvd', 'movies', 'shows']:
            raise ValueError('Unknown media type: %s' % (media, ))

        # Default `start_date` to today when only `days` is provided
        if start_date is None and days:
            start_date = datetime.utcnow()

        # Request calendar collection
        response = self.http.get(
            '/calendars/%s/%s%s' % (source, media,
                                    ('/' + collection) if collection else ''),
            params=[
                start_date.strftime('%Y-%m-%d') if start_date else None, days
            ],
            query={
                'query': query,
                'years': years,
                'genres': genres,
                'languages': languages,
                'countries': countries,
                'runtimes': runtimes,
                'ratings': ratings,
                'certifications': certifications,

                # TV
                'networks': networks,
                'status': status
            },
            **popitems(kwargs, ['authenticated', 'validate_token']))

        # Parse response
        items = self.get_data(response, **kwargs)

        if isinstance(items, requests.Response):
            return items

        # Map items
        if media == 'shows':
            return SummaryMapper.episodes(self.client, items, parse_show=True)

        return SummaryMapper.movies(self.client, items)
Example #27
0
 def last_activities(self, **kwargs):
     return self.get_data(
         self.http.get(
             'last_activities',
             **popitems(kwargs, ['authenticated', 'validate_token'])),
         **kwargs)
Example #28
0
    def get(self, source, media, collection=None, start_date=None, days=None, query=None, years=None, genres=None,
            languages=None, countries=None, runtimes=None, ratings=None, certifications=None, networks=None,
            status=None, **kwargs):
        """Retrieve calendar items.

        The `all` calendar displays info for all shows airing during the specified period. The `my` calendar displays
        episodes for all shows that have been watched, collected, or watchlisted.

        :param source: Calendar source (`all` or `my`)
        :type source: str

        :param media: Media type (`dvd`, `movies` or `shows`)
        :type media: str

        :param collection: Collection type (`new`, `premieres`)
        :type collection: str or None

        :param start_date: Start date (defaults to today)
        :type start_date: datetime or None

        :param days: Number of days to display (defaults to `7`)
        :type days: int or None

        :param query: Search title or description.
        :type query: str or None

        :param years: Year or range of years (e.g. `2014`, or `2014-2016`)
        :type years: int or str or tuple or None

        :param genres: Genre slugs (e.g. `action`)
        :type genres: str or list of str or None

        :param languages: Language codes (e.g. `en`)
        :type languages: str or list of str or None

        :param countries: Country codes (e.g. `us`)
        :type countries: str or list of str or None

        :param runtimes: Runtime range in minutes (e.g. `30-90`)
        :type runtimes: str or tuple or None

        :param ratings: Rating range between `0` and `100` (e.g. `75-100`)
        :type ratings: str or tuple or None

        :param certifications: US Content Certification (e.g. `pg-13`, `tv-pg`)
        :type certifications: str or list of str or None

        :param networks: (TV) Network name (e.g. `HBO`)
        :type networks: str or list of str or None

        :param status: (TV) Show status (e.g. `returning series`, `in production`, ended`)
        :type status: str or list of str or None

        :return: Items
        :rtype: list of trakt.objects.video.Video
        """
        if source not in ['all', 'my']:
            raise ValueError('Unknown collection type: %s' % (source,))

        if media not in ['dvd', 'movies', 'shows']:
            raise ValueError('Unknown media type: %s' % (media,))

        # Default `start_date` to today when only `days` is provided
        if start_date is None and days:
            start_date = datetime.utcnow()

        # Request calendar collection
        response = self.http.get(
            '/calendars/%s/%s%s' % (
                source, media,
                ('/' + collection) if collection else ''
            ),
            params=[
                start_date.strftime('%Y-%m-%d') if start_date else None,
                days
            ],
            query={
                'query': query,
                'years': years,
                'genres': genres,

                'languages': languages,
                'countries': countries,
                'runtimes': runtimes,

                'ratings': ratings,
                'certifications': certifications,

                # TV
                'networks': networks,
                'status': status
            },
            **popitems(kwargs, [
                'authenticated',
                'validate_token'
            ])
        )

        # Parse response
        items = self.get_data(response, **kwargs)

        if isinstance(items, requests.Response):
            return items

        # Map items
        if media == 'shows':
            return SummaryMapper.episodes(
                self.client, items,
                parse_show=True
            )

        return SummaryMapper.movies(self.client, items)
Example #29
0
    def action(self, action, movie=None, show=None, episode=None, progress=0.0, **kwargs):
        """Perform scrobble action.

        :param action: Action to perform (either :code:`start`, :code:`pause` or :code:`stop`)
        :type action: :class:`~python:str`

        :param movie: Movie definition (or `None`)

            **Example:**

            .. code-block:: python

                {
                    'title': 'Guardians of the Galaxy',
                    'year': 2014,

                    'ids': {
                        'tmdb': 118340
                    }
                }

        :type movie: :class:`~python:dict`

        :param show: Show definition (or `None`)

            **Example:**

            .. code-block:: python

                {
                    'title': 'Breaking Bad',
                    'year': 2008,

                    'ids': {
                        'tvdb': 81189
                    }
                }


        :type show: :class:`~python:dict`

        :param episode: Episode definition (or `None`)

            **Example:**

            .. code-block:: python

                {
                    "season": 3,
                    "number": 11
                }

        :type episode: :class:`~python:dict`

        :param progress: Current movie/episode progress percentage
        :type progress: :class:`~python:float`

        :param kwargs: Extra request options
        :type kwargs: :class:`~python:dict`

        :return: Response (or `None`)

            **Example:**

            .. code-block:: python

                {
                    'action': 'start',
                    'progress': 1.25,

                    'sharing': {
                        'facebook': true,
                        'twitter': true,
                        'tumblr': false
                    },

                    'movie': {
                        'title': 'Guardians of the Galaxy',
                        'year': 2014,

                        'ids': {
                            'trakt': 28,
                            'slug': 'guardians-of-the-galaxy-2014',
                            'imdb': 'tt2015381',
                            'tmdb': 118340
                        }
                    }
                }

        :rtype: :class:`~python:dict`
        """
        if movie and (show or episode):
            raise ValueError('Only one media type should be provided')

        if not movie and not episode:
            raise ValueError('Missing media item')

        data = {
            'progress': progress,
            'app_version': kwargs.pop('app_version', self.client.version),
            'app_date': kwargs.pop('app_date', None)
        }

        if movie:
            # TODO validate
            data['movie'] = movie
        elif episode:
            if show:
                data['show'] = show

            # TODO validate
            data['episode'] = episode

        response = self.http.post(
            action,
            data=data,
            **popitems(kwargs, [
                'authenticated',
                'validate_token'
            ])
        )

        return self.get_data(response, **kwargs)
Example #30
0
    def delete(self, playbackid, **kwargs):
        response = self.http.delete(
            path=str(playbackid),
            **popitems(kwargs, ['authenticated', 'validate_token']))

        return 200 <= response.status_code < 300
Example #31
0
    def action(self,
               action,
               movie=None,
               show=None,
               episode=None,
               progress=0.0,
               **kwargs):
        """Perform scrobble action.

        :param action: Action to perform (either :code:`start`, :code:`pause` or :code:`stop`)
        :type action: :class:`~python:str`

        :param movie: Movie definition (or `None`)

            **Example:**

            .. code-block:: python

                {
                    'title': 'Guardians of the Galaxy',
                    'year': 2014,

                    'ids': {
                        'tmdb': 118340
                    }
                }

        :type movie: :class:`~python:dict`

        :param show: Show definition (or `None`)

            **Example:**

            .. code-block:: python

                {
                    'title': 'Breaking Bad',
                    'year': 2008,

                    'ids': {
                        'tvdb': 81189
                    }
                }


        :type show: :class:`~python:dict`

        :param episode: Episode definition (or `None`)

            **Example:**

            .. code-block:: python

                {
                    "season": 3,
                    "number": 11
                }

        :type episode: :class:`~python:dict`

        :param progress: Current movie/episode progress percentage
        :type progress: :class:`~python:float`

        :param kwargs: Extra request options
        :type kwargs: :class:`~python:dict`

        :return: Response (or `None`)

            **Example:**

            .. code-block:: python

                {
                    'action': 'start',
                    'progress': 1.25,

                    'sharing': {
                        'facebook': true,
                        'twitter': true,
                        'tumblr': false
                    },

                    'movie': {
                        'title': 'Guardians of the Galaxy',
                        'year': 2014,

                        'ids': {
                            'trakt': 28,
                            'slug': 'guardians-of-the-galaxy-2014',
                            'imdb': 'tt2015381',
                            'tmdb': 118340
                        }
                    }
                }

        :rtype: :class:`~python:dict`
        """
        if movie and (show or episode):
            raise ValueError('Only one media type should be provided')

        if not movie and not episode:
            raise ValueError('Missing media item')

        data = {
            'progress': progress,
            'app_version': kwargs.pop('app_version', self.client.version),
            'app_date': kwargs.pop('app_date', None)
        }

        if movie:
            # TODO validate
            data['movie'] = movie
        elif episode:
            if show:
                data['show'] = show

            # TODO validate
            data['episode'] = episode

        response = self.http.post(
            action,
            data=data,
            **popitems(kwargs, ['authenticated', 'validate_token']))

        return self.get_data(response, **kwargs)