Skip to content

Commit 415a548

Browse files
committed
Initial commit
0 parents  commit 415a548

File tree

14 files changed

+1359
-0
lines changed

14 files changed

+1359
-0
lines changed

LICENSE.txt

Whitespace-only changes.

addon.xml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2+
<addon id="script.module.tvdbsimple" name="tvdbsimple" version="1.0.4" provider-name="phate89">
3+
<requires>
4+
<import addon="xbmc.python" version="3.0.0"/>
5+
<import addon="script.module.requests" version="2.9.1"/>
6+
</requires>
7+
<extension point="xbmc.python.module" library="lib" />
8+
<extension point="xbmc.addon.metadata">
9+
<summary lang="en">tvdbsimple module</summary>
10+
<description lang="en">Helper module for thetvdb site access</description>
11+
<platform>all</platform>
12+
<license>GPLv3</license>
13+
<source>https://github.com/phate89/tvdbsimple</source>
14+
</extension>
15+
</addon>

changelog.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
1.0.0
2+
- Initial release
3+
4+

icon.png

13.5 KB
Loading

lib/__init__.py

Whitespace-only changes.

lib/tvdbsimple/__init__.py

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# -*- coding: utf-8 -*-
2+
3+
"""
4+
`tvdbsimple` is a wrapper, written in Python, for TheTVDb.com
5+
API v2. By calling the functions available in `tvdbsimple` you can simplify
6+
your code and easily access a vast amount of tv and cast data. To find
7+
out more about TheTVDb API, check out the [official api page](https://api.thetvdb.com/swagger/)
8+
9+
Features
10+
--------
11+
12+
- Full API implementation. Supports Search, Series, Episode, Updated, User and Languages methods.
13+
- Updated with the latest JSON API.
14+
- Fully tested with automated tests and travis.ci.
15+
- Supports Python 2.7, 3.3, 3.4, 3.5, 3.6.
16+
- Easy to access data using Python class attributes.
17+
- Easy to experiment with `tvdbsimple` functions inside the Python interpreter.
18+
19+
Installation
20+
------------
21+
22+
`tvdbsimple` is available on the [Python Package Index](https://pypi.python.org/pypi/tvdbsimple).
23+
24+
You can install `tvdbsimple` using one of the following techniques:
25+
26+
- Use pip: `pip install tvdbsimple`
27+
- Download the .zip or .tar.gz file from PyPI and install it yourself
28+
- Download the [source from Github](http://github.com/phate89/tvdbsimple) and install it yourself
29+
30+
If you install it yourself, also install [requests](http://www.python-requests.org/en/latest).
31+
32+
API Key
33+
-------
34+
You will need an API key to TheTVDb to access the API. To obtain a key, follow these steps:
35+
36+
1) Register for and verify an [account](http://thetvdb.com/?tab=register).
37+
2) [Log into](http://thetvdb.com/?tab=login) your account.
38+
3) [Go to this page](http://thetvdb.com/?tab=apiregister) and fill your details to generate a new API key.
39+
40+
Examples
41+
--------
42+
All the functions are fully documented here but you can find several use examples in the [examples page](https://github.com/phate89/tvdbsimple/blob/master/EXAMPLES.rst).
43+
44+
License
45+
-------
46+
The module is distributed with a GPLv3 license, see [LICENSE](https://www.gnu.org/licenses/gpl-3.0.en.html) for more details
47+
48+
copyright (c) 2017 by phate89.
49+
"""
50+
51+
__title__ = 'tvdbsimple'
52+
__version__ = '1.0.4'
53+
__author__ = 'phate89'
54+
__copyright__ = 'Copyright © 2017 phate89'
55+
__license__ = 'GPLv3'
56+
57+
from .base import APIKeyError
58+
from .keys import keys
59+
from .search import Search
60+
from .series import Series, Series_Episodes, Series_Images
61+
from .languages import Languages
62+
from .episode import Episode
63+
from .updates import Updates
64+
from .user import User, User_Ratings
65+
66+
KEYS=keys()
67+
"""
68+
Contains `API_KEY` and `API_TOKEN`.
69+
70+
To use the module you have to set at least the `API_KEY` value (THETVDb api key).
71+
You can also provide an `API_TOKEN` if you already have a valid one stored. If the
72+
valid token doesn't work anymore the module will try to retrieve a new one
73+
using the `API_KEY` variable
74+
"""

lib/tvdbsimple/base.py

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
# -*- coding: utf-8 -*-
2+
3+
"""
4+
This module implements the base class of tvdbsimple.
5+
6+
Handle automatically login, token creation and response basic stripping.
7+
8+
[See Authentication API section](https://api.thetvdb.com/swagger#!/Authentication)
9+
"""
10+
11+
import json
12+
import requests
13+
14+
15+
class AuthenticationError(Exception):
16+
"""
17+
Authentication exception class for authentication errors
18+
"""
19+
pass
20+
21+
class APIKeyError(Exception):
22+
"""
23+
Missing API key exception class in case of missing api
24+
"""
25+
pass
26+
27+
class TVDB(object):
28+
"""
29+
Basic Authentication class for API key, login and token automatic handling functionality.
30+
31+
[See Authentication API section](https://api.thetvdb.com/swagger#!/Authentication)
32+
"""
33+
_headers = {'Content-Type': 'application/json',
34+
'Accept': 'application/json',
35+
'Connection': 'close'}
36+
_BASE_PATH = ''
37+
_URLS = {}
38+
_BASE_URI = 'https://api.thetvdb.com'
39+
40+
def __init__(self, id=0, user=None, key=None):
41+
"""
42+
Initialize the base class.
43+
44+
You can provide `id` that is the item id used for url creation. You can also
45+
provide `user`, that is the username for login.
46+
You can also provide `key`, that is the userkey needed to
47+
authenticate with the user, you can find it in the
48+
[account info](http://thetvdb.com/?tab=userinfo) under account identifier.,
49+
the language id you want to use to retrieve the info.
50+
"""
51+
self._ID = id
52+
self.USER = user
53+
"""Stores username if available"""
54+
self.USER_KEY = key
55+
"""Stores user-key if available"""
56+
57+
def _get_path(self, key):
58+
return self._BASE_PATH + self._URLS[key]
59+
60+
def _get_id_path(self, key):
61+
return self._get_path(key).format(id=self._ID)
62+
63+
def _get_complete_url(self, path):
64+
return '{base_uri}/{path}'.format(base_uri=self._BASE_URI, path=path)
65+
66+
def _set_language(self, language):
67+
if language:
68+
self._headers['Accept-Language'] = language
69+
70+
def refresh_token(self):
71+
"""
72+
Refresh the current token set in the module.
73+
74+
Returns the new obtained valid token for the API.
75+
"""
76+
self._set_token_header()
77+
78+
response = requests.request(
79+
'GET', self._get_complete_url('refresh_token'),
80+
headers=self._headers)
81+
82+
response.raise_for_status()
83+
jsn = response.json()
84+
if 'token' in jsn:
85+
from . import KEYS
86+
KEYS.API_TOKEN = jsn['token']
87+
return KEYS.API_TOKEN
88+
return ''
89+
90+
def _set_token_header(self, forceNew=False):
91+
self._headers['Authorization'] = 'Bearer ' + self.get_token(forceNew)
92+
93+
def get_token(self, forceNew=False):
94+
"""
95+
Get the existing token or creates it if it doesn't exist.
96+
Returns the API token.
97+
98+
If `forceNew` is true the function will do a new login to retrieve the token.
99+
"""
100+
from . import KEYS
101+
if not KEYS.API_TOKEN or forceNew:
102+
if not KEYS.API_KEY:
103+
raise APIKeyError
104+
105+
if hasattr(self,"USER") and hasattr(self,"USER_KEY"):
106+
data = {"apikey": KEYS.API_KEY, "username": self.USER, "userkey": self.USER_KEY}
107+
else:
108+
data={"apikey": KEYS.API_KEY}
109+
110+
response = requests.request(
111+
'POST', self._get_complete_url('login'),
112+
data=json.dumps(data),
113+
headers=self._headers)
114+
if response.status_code == 200:
115+
KEYS.API_TOKEN = response.json()['token']
116+
else:
117+
error = "Unknown error while authenticating. Check your api key or your user/userkey"
118+
try:
119+
error = response.json()['error']
120+
except:
121+
pass
122+
raise AuthenticationError(error)
123+
return KEYS.API_TOKEN
124+
125+
def _request(self, method, path, params=None, payload=None, forceNewToken=False, cleanJson = True):
126+
self._set_token_header(forceNewToken)
127+
128+
url = self._get_complete_url(path)
129+
130+
response = requests.request(
131+
method, url, params=params,
132+
data=json.dumps(payload) if payload else payload,
133+
headers=self._headers)
134+
135+
if response.status_code == 200:
136+
response.encoding = 'utf-8'
137+
jsn = response.json()
138+
if cleanJson and 'data' in jsn:
139+
return jsn['data']
140+
return jsn
141+
elif not forceNewToken:
142+
return self._request(method=method, path=path, params=params, payload=payload, forceNewToken=True)
143+
try:
144+
raise Exception(response.json()['error'])
145+
except:
146+
response.raise_for_status()
147+
148+
def _GET(self, path, params=None, cleanJson = True):
149+
return self._request('GET', path, params=params, cleanJson=cleanJson)
150+
151+
def _POST(self, path, params=None, payload=None, cleanJson = True):
152+
return self._request('POST', path, params=params, payload=payload, cleanJson=cleanJson)
153+
154+
def _DELETE(self, path, params=None, payload=None, cleanJson = True):
155+
return self._request('DELETE', path, params=params, payload=payload, cleanJson=cleanJson)
156+
157+
def _PUT(self, path, params=None, payload=None, cleanJson = True):
158+
return self._request('PUT', path, params=params, payload=payload, cleanJson=cleanJson)
159+
160+
def _set_attrs_to_values(self, response={}):
161+
"""
162+
Set attributes to dictionary values.
163+
164+
- e.g.
165+
>>> import tvdbsimple as tvdb
166+
>>> show = tmdb.Tv(10332)
167+
>>> response = show.info()
168+
>>> show.title # instead of response['title']
169+
"""
170+
if isinstance(response, dict):
171+
for key in response:
172+
setattr(self, key, response[key])

lib/tvdbsimple/episode.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# -*- coding: utf-8 -*-
2+
3+
"""
4+
This module implements the Episode functionality of TheTVDb API.
5+
Allows to retrieve episode detailed info.
6+
7+
See [Episodes API section](https://api.thetvdb.com/swagger#!/Episodes)
8+
"""
9+
10+
from .base import TVDB
11+
12+
class Episode(TVDB):
13+
"""
14+
Episode class to retrieve detailed info about an episode.
15+
Requires the episode id.
16+
"""
17+
_BASE_PATH = 'episodes'
18+
_URLS = {
19+
'info': '/{id}'
20+
}
21+
22+
def __init__(self, id, language=''):
23+
"""
24+
Initialize the episode class.
25+
26+
`id` is the TheTVDb episode id. You can also provide `language`,
27+
the language id you want to use to retrieve the info.
28+
"""
29+
super(Episode, self).__init__(id)
30+
self._set_language(language)
31+
32+
def info(self, language=''):
33+
"""
34+
Get the episode information of the episode and set its values to the local attributes.
35+
36+
You can set `language` with the language id to retrieve info in that specific language.
37+
38+
It returns a dictionary with all the episode info.
39+
40+
For example
41+
42+
#!python
43+
>>> import tvdbsimple as tvdb
44+
>>> tvdb.KEYS.API_KEY = 'YOUR_API_KEY'
45+
>>> ep = tvdb.Episode(5330530)
46+
>>> ep.imdbId
47+
'tt4701544'
48+
49+
"""
50+
path = self._get_id_path('info')
51+
52+
self._set_language(language)
53+
response = self._GET(path)
54+
self._set_attrs_to_values(response)
55+
return response

lib/tvdbsimple/keys.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# -*- coding: utf-8 -*-
2+
3+
"""
4+
This module implements the keys class of tvdbsimple.
5+
"""
6+
7+
import os
8+
class keys():
9+
"""
10+
The class is needed to hold the api key value and the token value.
11+
"""
12+
API_KEY = os.environ.get('TVDB_API_KEY', None)
13+
"""
14+
It's the TheTVDb api key needed for the api access. The developer must fill it.
15+
"""
16+
API_TOKEN = os.environ.get('TVDB_API_TOKEN', None)
17+
"""
18+
Contains the TheTVDb token used for authenticating api requests. The developer might provide a valid one.
19+
20+
If a request fails the module will get a new token automatically upating it.
21+
"""

0 commit comments

Comments
 (0)