Use TheMovieDB v3 api
This commit is contained in:
Executable
+157
@@ -0,0 +1,157 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
#-----------------------
|
||||
# Name: tmdb_request.py
|
||||
# Python Library
|
||||
# Author: Raymond Wagner
|
||||
# Purpose: Wrapped urllib2.Request class pre-configured for accessing the
|
||||
# TMDb v3 API
|
||||
#-----------------------
|
||||
|
||||
from tmdb_exceptions import *
|
||||
from locales import get_locale
|
||||
from cache import Cache
|
||||
|
||||
from urllib import urlencode
|
||||
import urllib2
|
||||
import json
|
||||
|
||||
DEBUG = False
|
||||
cache = Cache(filename='pytmdb3.cache')
|
||||
|
||||
#DEBUG = True
|
||||
#cache = Cache(engine='null')
|
||||
|
||||
def set_key(key):
|
||||
"""
|
||||
Specify the API key to use retrieving data from themoviedb.org. This
|
||||
key must be set before any calls will function.
|
||||
"""
|
||||
if len(key) != 32:
|
||||
raise TMDBKeyInvalid("Specified API key must be 128-bit hex")
|
||||
try:
|
||||
int(key, 16)
|
||||
except:
|
||||
raise TMDBKeyInvalid("Specified API key must be 128-bit hex")
|
||||
Request._api_key = key
|
||||
|
||||
def set_cache(engine=None, *args, **kwargs):
|
||||
"""Specify caching engine and properties."""
|
||||
cache.configure(engine, *args, **kwargs)
|
||||
|
||||
class Request( urllib2.Request ):
|
||||
_api_key = None
|
||||
_base_url = "http://api.themoviedb.org/3/"
|
||||
|
||||
@property
|
||||
def api_key(self):
|
||||
if self._api_key is None:
|
||||
raise TMDBKeyMissing("API key must be specified before "+\
|
||||
"requests can be made")
|
||||
return self._api_key
|
||||
|
||||
def __init__(self, url, **kwargs):
|
||||
"""Return a request object, using specified API path and arguments."""
|
||||
kwargs['api_key'] = self.api_key
|
||||
self._url = url.lstrip('/')
|
||||
self._kwargs = dict([(kwa,kwv) for kwa,kwv in kwargs.items()
|
||||
if kwv is not None])
|
||||
|
||||
locale = get_locale()
|
||||
kwargs = {}
|
||||
for k,v in self._kwargs.items():
|
||||
kwargs[k] = locale.encode(v)
|
||||
url = '{0}{1}?{2}'.format(self._base_url, self._url, urlencode(kwargs))
|
||||
|
||||
urllib2.Request.__init__(self, url)
|
||||
self.add_header('Accept', 'application/json')
|
||||
self.lifetime = 3600 # 1hr
|
||||
|
||||
def new(self, **kwargs):
|
||||
"""Create a new instance of the request, with tweaked arguments."""
|
||||
args = dict(self._kwargs)
|
||||
for k,v in kwargs.items():
|
||||
if v is None:
|
||||
if k in args:
|
||||
del args[k]
|
||||
else:
|
||||
args[k] = v
|
||||
obj = self.__class__(self._url, **args)
|
||||
obj.lifetime = self.lifetime
|
||||
return obj
|
||||
|
||||
def add_data(self, data):
|
||||
"""Provide data to be sent with POST."""
|
||||
urllib2.Request.add_data(self, urlencode(data))
|
||||
|
||||
def open(self):
|
||||
"""Open a file object to the specified URL."""
|
||||
try:
|
||||
if DEBUG:
|
||||
print 'loading '+self.get_full_url()
|
||||
if self.has_data():
|
||||
print ' '+self.get_data()
|
||||
return urllib2.urlopen(self)
|
||||
except urllib2.HTTPError, e:
|
||||
raise TMDBHTTPError(e)
|
||||
|
||||
def read(self):
|
||||
"""Return result from specified URL as a string."""
|
||||
return self.open().read()
|
||||
|
||||
@cache.cached(urllib2.Request.get_full_url)
|
||||
def readJSON(self):
|
||||
"""Parse result from specified URL as JSON data."""
|
||||
url = self.get_full_url()
|
||||
try:
|
||||
# catch HTTP error from open()
|
||||
data = json.load(self.open())
|
||||
except TMDBHTTPError, e:
|
||||
try:
|
||||
# try to load whatever was returned
|
||||
data = json.loads(e.response)
|
||||
except:
|
||||
# cannot parse json, just raise existing error
|
||||
raise e
|
||||
else:
|
||||
# response parsed, try to raise error from TMDB
|
||||
handle_status(data, url)
|
||||
# no error from TMDB, just raise existing error
|
||||
raise e
|
||||
handle_status(data, url)
|
||||
#if DEBUG:
|
||||
# import pprint
|
||||
# pprint.PrettyPrinter().pprint(data)
|
||||
return data
|
||||
|
||||
status_handlers = {
|
||||
1: None,
|
||||
2: TMDBRequestInvalid('Invalid service - This service does not exist.'),
|
||||
3: TMDBRequestError('Authentication Failed - You do not have '+\
|
||||
'permissions to access this service.'),
|
||||
4: TMDBRequestInvalid("Invalid format - This service doesn't exist "+\
|
||||
'in that format.'),
|
||||
5: TMDBRequestInvalid('Invalid parameters - Your request parameters '+\
|
||||
'are incorrect.'),
|
||||
6: TMDBRequestInvalid('Invalid id - The pre-requisite id is invalid '+\
|
||||
'or not found.'),
|
||||
7: TMDBKeyInvalid('Invalid API key - You must be granted a valid key.'),
|
||||
8: TMDBRequestError('Duplicate entry - The data you tried to submit '+\
|
||||
'already exists.'),
|
||||
9: TMDBOffline('This service is tempirarily offline. Try again later.'),
|
||||
10: TMDBKeyRevoked('Suspended API key - Access to your account has been '+\
|
||||
'suspended, contact TMDB.'),
|
||||
11: TMDBError('Internal error - Something went wrong. Contact TMDb.'),
|
||||
12: None,
|
||||
13: None,
|
||||
14: TMDBRequestError('Authentication Failed.'),
|
||||
15: TMDBError('Failed'),
|
||||
16: TMDBError('Device Denied'),
|
||||
17: TMDBError('Session Denied')}
|
||||
|
||||
def handle_status(data, query):
|
||||
status = status_handlers[data.get('status_code', 1)]
|
||||
if status is not None:
|
||||
status.tmdberrno = data['status_code']
|
||||
status.query = query
|
||||
raise status
|
||||
Reference in New Issue
Block a user