Skip to content

Commit

Permalink
Merge pull request #11189 from pymedusa/release/release-1.0.13
Browse files Browse the repository at this point in the history
Release/release 1.0.13
  • Loading branch information
medariox authored Mar 22, 2023
2 parents 671a443 + 05aaeab commit 6b37ad0
Show file tree
Hide file tree
Showing 20 changed files with 479 additions and 257 deletions.
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
## 1.0.13 (22-03-2023)

#### Improvements
- Replace trakt with pytrakt

#### Fixes
- Fix git subprocess call for Windows paths with spaces

-----

## 1.0.12 (03-03-2023)

#### New Features
Expand Down
6 changes: 3 additions & 3 deletions ext/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ ext | **`pytz`** | [2018.4](https://pypi.org/project/pytz/2018.4/) | `subliminal
ext | `PyYAML` | [5.4.1](https://pypi.org/project/PyYAML/5.4.1/) | `knowit` | Modules: `_yaml`, `yaml`
ext | `rarfile` | [3.1](https://pypi.org/project/rarfile/3.1/) | **`medusa`**, `subliminal` | File: `rarfile.py`
ext | **`rebulk`** | [3.1.0](https://pypi.org/project/rebulk/3.1.0/) | **`medusa`**, `guessit` | -
ext | **`requests`** | [2.28.2](https://pypi.org/project/requests/2.28.2/) | **`medusa`**, `adba`, `boto`, `CacheControl`, `cloudscraper`, `PyGithub`, `python-twitter`, `pytvmaze`, `requests-oauthlib`, `requests-toolbelt`, `rtorrent-python`, `simpleanidb`, `subliminal`, `tmdbsimple`, `trakt`, `tvdbapiv2` | -
ext | `requests-oauthlib` | [1.3.1](https://pypi.org/project/requests-oauthlib/1.3.1/) | **`medusa`**, `python-twitter`, `trakt` | Module: `requests_oauthlib`
ext | **`requests`** | [2.28.2](https://pypi.org/project/requests/2.28.2/) | **`medusa`**, `adba`, `boto`, `CacheControl`, `cloudscraper`, `PyGithub`, `python-twitter`, `pytvmaze`, `requests-oauthlib`, `requests-toolbelt`, `rtorrent-python`, `simpleanidb`, `subliminal`, `tmdbsimple`, `pytrakt`, `tvdbapiv2` | -
ext | `requests-oauthlib` | [1.3.1](https://pypi.org/project/requests-oauthlib/1.3.1/) | **`medusa`**, `python-twitter`, `pytrakt` | Module: `requests_oauthlib`
ext | `requests-toolbelt` | [0.9.1](https://pypi.org/project/requests-toolbelt/0.9.1/) | `cloudscraper` | Module: `requests_toolbelt`
ext | `sgmllib3k` | [1.0.0](https://pypi.org/project/sgmllib3k/1.0.0/) | `feedparser` | File: `sgmllib.py`
ext | `six` | [1.16.0](https://pypi.org/project/six/1.16.0/) | **`medusa`**, `adba`, `configobj`, `html5lib`, `imdbpie`, `knowit`, `PyGithub`, `subliminal`, `tvdbapiv2`, `validators` | File: `six.py`
Expand All @@ -60,7 +60,7 @@ ext | **`subliminal`** | [2.1.0](https://pypi.org/project/subliminal/2.1.0/) | *
ext | **`tmdbsimple`** | [2.8.0](https://pypi.org/project/tmdbsimple/2.8.0/) | **`medusa`** | -
ext | **`tornado`** | [6.1](https://pypi.org/project/tornado/6.1/) | **`medusa`**, `tornroutes` | -
ext | **`tornroutes`** | [0.5.1](https://pypi.org/project/tornroutes/0.5.1/) | **`medusa`** | -
ext | **`trakt`** | [3.4.0](https://pypi.org/project/trakt/3.4.0/) | **`medusa`** | -
ext | **`pytrakt`** | [3.4.20](https://pypi.org/project/pytrakt/3.4.20/) | **`medusa`** | -
ext | `trans` | [2.1.0](https://pypi.org/project/trans/2.1.0/) | `imdbpie` | File: `trans.py`
ext | `ttl-cache` | [1.6](https://pypi.org/project/ttl-cache/1.6/) | **`medusa`**, `adba` | File: `ttl_cache.py`
ext | **`tvdbapiv2`** | pymedusa/[d6d0e9d](https://github.com/pymedusa/tvdbv2/tree/d6d0e9d98071c2d646beb997b336edbb0e98dfb7) | **`medusa`** | -
Expand Down
6 changes: 3 additions & 3 deletions ext/trakt/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@
except ImportError:
pass

version_info = (3, 4, 0)
__author__ = 'Jon Nappi'
__version__ = '.'.join([str(i) for i in version_info])
from .__version__ import __version__

__author__ = 'Jon Nappi, Elan Ruusamäe'
1 change: 1 addition & 0 deletions ext/trakt/__version__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
__version__ = '3.4.20'
11 changes: 6 additions & 5 deletions ext/trakt/calendar.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
# -*- coding: utf-8 -*-
"""Interfaces to all of the Calendar objects offered by the Trakt.tv API"""
from pprint import pformat

from trakt.core import get
from trakt.movies import Movie
from trakt.tv import TVEpisode, TVShow
from trakt.utils import extract_ids, now, airs_date
from trakt.utils import airs_date, now

__author__ = 'Jon Nappi'
__all__ = ['Calendar', 'PremiereCalendar', 'MyPremiereCalendar',
'ShowCalendar', 'MyShowCalendar', 'SeasonCalendar',
'MySeasonCalendar', 'MovieCalendar', 'MyMovieCalendar']


class Calendar(object):
class Calendar:
"""Base :class:`Calendar` type serves as a foundation for other Calendar
types
"""
Expand All @@ -26,7 +27,7 @@ def __init__(self, date=None, days=7, extended=None):
:param days: Number of days for this :class:`Calendar`. Defaults to 7
days
"""
super(Calendar, self).__init__()
super().__init__()
self.date = date or now()
self.days = days
self._calendar = []
Expand Down Expand Up @@ -72,7 +73,6 @@ def _build(self, data):
first_aired = cal_item.get('first_aired')
season = episode.get('season')
ep_num = episode.get('number')
extract_ids(show_data)
show_data.update(show_data)
e_data = {
'airs_at': airs_date(first_aired),
Expand All @@ -81,7 +81,8 @@ def _build(self, data):
'show_data': TVShow(**show_data)
}
self._calendar.append(
TVEpisode(show_data['title'], season, ep_num, **e_data)
TVEpisode(show_data['title'], season, ep_num,
show_id=show_data['ids']['trakt'], **e_data)
)
self._calendar = sorted(self._calendar, key=lambda x: x.airs_at)

Expand Down
26 changes: 15 additions & 11 deletions ext/trakt/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,19 @@
import json
import logging
import os
from urllib.parse import urljoin

import requests
import sys
import time
from collections import namedtuple
from datetime import datetime, timedelta, timezone
from functools import wraps
from json import JSONDecodeError
from urllib.parse import urljoin

import requests
from requests_oauthlib import OAuth2Session
from datetime import datetime, timedelta, timezone

from trakt import errors
from trakt.errors import BadResponseException

__author__ = 'Jon Nappi'
__all__ = ['Airs', 'Alias', 'Comment', 'Genre', 'get', 'delete', 'post', 'put',
Expand Down Expand Up @@ -43,7 +46,7 @@
CONFIG_PATH = os.path.join(os.path.expanduser('~'), '.pytrakt.json')

#: Your personal Trakt.tv OAUTH Bearer Token
OAUTH_TOKEN = api_key = None
OAUTH_TOKEN = None

# OAuth token validity checked
OAUTH_TOKEN_VALID = None
Expand Down Expand Up @@ -441,7 +444,7 @@ def load_config():
APPLICATION_ID = config_data.get('APPLICATION_ID', None)


class Core(object):
class Core:
"""This class contains all of the functionality required for interfacing
with the Trakt.tv API
"""
Expand Down Expand Up @@ -476,9 +479,6 @@ def _bootstrap(self):
if (not OAUTH_TOKEN_VALID and OAUTH_EXPIRES_AT is not None
and OAUTH_REFRESH is not None):
_validate_token(self)
# For backwards compatibility with trakt<=2.3.0
if api_key is not None and OAUTH_TOKEN is None:
OAUTH_TOKEN = api_key

@staticmethod
def _get_first(f, *args, **kwargs):
Expand Down Expand Up @@ -516,7 +516,6 @@ def _handle_request(self, method, url, data=None):
self.logger.debug('%s: %s', method, url)
HEADERS['trakt-api-key'] = CLIENT_ID
HEADERS['Authorization'] = 'Bearer {0}'.format(OAUTH_TOKEN)
self.logger.debug('headers: %s', str(HEADERS))
self.logger.debug('method, url :: %s, %s', method, url)
if method == 'get': # GETs need to pass data as params, not body
response = session.request(method, url, headers=HEADERS,
Expand All @@ -529,7 +528,12 @@ def _handle_request(self, method, url, data=None):
raise self.error_map[response.status_code](response)
elif response.status_code == 204: # HTTP no content
return None
json_data = json.loads(response.content.decode('UTF-8', 'ignore'))

try:
json_data = json.loads(response.content.decode('UTF-8', 'ignore'))
except JSONDecodeError as e:
raise BadResponseException(response, f"Unable to parse JSON: {e}")

return json_data

def get(self, f):
Expand Down
31 changes: 31 additions & 0 deletions ext/trakt/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,13 @@

__author__ = 'Jon Nappi'
__all__ = [
# Base Exception
'TraktException',

# Errors for use by PyTrakt
'BadResponseException',

# Exceptions by HTTP status code
'BadRequestException',
'OAuthException',
'ForbiddenException',
Expand All @@ -17,6 +23,7 @@
'LockedUserAccountException',
'RateLimitException',
'TraktInternalException',
'TraktBadGateway',
'TraktUnavailable',
]

Expand All @@ -32,6 +39,16 @@ def __str__(self):
return self.message


class BadResponseException(TraktException):
"""TraktException type to be raised when json could not be decoded"""
http_code = -1
message = "Bad Response - Response could not be parsed"

def __init__(self, response=None, details=None):
super().__init__(response)
self.details = details


class BadRequestException(TraktException):
"""TraktException type to be raised when a 400 return code is received"""
http_code = 400
Expand Down Expand Up @@ -85,12 +102,26 @@ class RateLimitException(TraktException):
http_code = 429
message = 'Rate Limit Exceeded'

@property
def retry_after(self):
return int(self.response.headers.get("Retry-After", 1))


class TraktInternalException(TraktException):
"""TraktException type to be raised when a 500 error is raised"""
http_code = 500
message = 'Internal Server Error'

@property
def error_message(self):
return self.response.headers.get("x-error-message", None)


class TraktBadGateway(TraktException):
"""TraktException type to be raised when a 502 error is raised"""
http_code = 502
message = 'Trakt Unavailable - Bad Gateway'


class TraktUnavailable(TraktException):
"""TraktException type to be raised when a 503 error is raised"""
Expand Down
53 changes: 53 additions & 0 deletions ext/trakt/mixins.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# -*- coding: utf-8 -*-
"""Contains various MixIns"""

__author__ = 'Jon Nappi, Elan Ruusamäe'


class IdsMixin:
"""
Provides Mixin to translate "ids" array
to appropriate provider ids in base class.
This is replacement for extract_ids() utility method.
"""

__ids = ['imdb', 'slug', 'tmdb', 'trakt']

def __init__(self):
self._ids = {}

@property
def ids(self):
"""
Accessor to the trakt, imdb, and tmdb ids,
as well as the trakt.tv slug
"""
ids = {k: getattr(self, k, None) for k in self.__ids}
return {
'ids': ids
}

@ids.setter
def ids(self, value):
self._ids = value

@property
def imdb(self):
return self._ids.get('imdb', None)

@property
def tmdb(self):
return self._ids.get('tmdb', None)

@property
def trakt(self):
return self._ids.get('trakt', None)

@property
def tvdb(self):
return self._ids.get('tvdb', None)

@property
def tvrage(self):
return self._ids.get('tvrage', None)
Loading

0 comments on commit 6b37ad0

Please sign in to comment.