Skip to content
Browse files

Add basic session handling and passthrough.

  • Loading branch information...
1 parent 5004545 commit 3debcd531d8ed454b8ed9f4b61da6e03690ce13c @wagnerrp wagnerrp committed Apr 14, 2012
Showing with 162 additions and 0 deletions.
  1. +23 −0 tmdb3/tmdb_api.py
  2. +130 −0 tmdb3/tmdb_auth.py
  3. +9 −0 tmdb3/util.py
View
23 tmdb3/tmdb_api.py
@@ -47,6 +47,7 @@
from util import Datapoint, Datalist, Datadict, Element
from pager import PagedRequest
from locales import get_locale, set_locale
+from tmdb_auth import get_session, set_session
from tmdb_exceptions import *
import json
@@ -62,6 +63,28 @@ def _populate(self):
return Request('configuration')
Configuration = Configuration()
+class Account( Element ):
+ session = Datapoint('session', initarg=1, default=None)
+
+ def _populate_account(self):
+ if self.session is None:
+ self.session = get_session()
+ return Request('account', session_id=self.session.sessionid)
+
+ id = Datapoint('id', poller=_populate_account)
+ adult = Datapoint('include_adult', poller=_populate_account)
+ country = Datapoint('iso_3166_1', poller=_populate_account)
+ language = Datapoint('iso_639_1', poller=_populate_account)
+ name = Datapoint('name', poller=_populate_account)
+ username = Datapoint('username', poller=_populate_account)
+
+ @property
+ def locale(self):
+ return get_locale(self.language, self.country)
+
+ def __repr__(self):
+ return "<{0} {1.name}>".format(self.__class__.__name__, self)
+
def searchMovie(query, locale=None, adult=False):
return MovieSearchResult(
Request('search/movie', query=query, include_adult=adult),
View
130 tmdb3/tmdb_auth.py
@@ -0,0 +1,130 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#-----------------------
+# Name: tmdb_auth.py
+# Python Library
+# Author: Raymond Wagner
+# Purpose: Provide authentication and session services for
+# calls against the TMDB v3 API
+#-----------------------
+
+from datetime import datetime as _pydatetime, \
+ tzinfo as _pytzinfo
+import re
+class datetime( _pydatetime ):
+ """Customized datetime class with ISO format parsing."""
+ _reiso = re.compile('(?P<year>[0-9]{4})'
+ '-(?P<month>[0-9]{1,2})'
+ '-(?P<day>[0-9]{1,2})'
+ '.'
+ '(?P<hour>[0-9]{2})'
+ ':(?P<min>[0-9]{2})'
+ '(:(?P<sec>[0-9]{2}))?'
+ '(?P<tz>Z|'
+ '(?P<tzdirec>[-+])'
+ '(?P<tzhour>[0-9]{1,2})'
+ '(:)?'
+ '(?P<tzmin>[0-9]{2})?'
+ ')?')
+
+ class _tzinfo( _pytzinfo):
+ def __init__(self, direc='+', hr=0, min=0):
+ if direc == '-':
+ hr = -1*int(hr)
+ self._offset = timedelta(hours=int(hr), minutes=int(min))
+ def utcoffset(self, dt): return self._offset
+ def tzname(self, dt): return ''
+ def dst(self, dt): return timedelta(0)
+
+ @classmethod
+ def fromIso(cls, isotime, sep='T'):
+ match = cls._reiso.match(isotime)
+ if match is None:
+ raise TypeError("time data '%s' does not match ISO 8601 format" \
+ % isotime)
+
+ dt = [int(a) for a in match.groups()[:5]]
+ if match.group('sec') is not None:
+ dt.append(int(match.group('sec')))
+ else:
+ dt.append(0)
+ if match.group('tz'):
+ if match.group('tz') == 'Z':
+ tz = cls._tzinfo()
+ elif match.group('tzmin'):
+ tz = cls._tzinfo(*match.group('tzdirec','tzhour','tzmin'))
+ else:
+ tz = cls._tzinfo(*match.group('tzdirec','tzhour'))
+ dt.append(0)
+ dt.append(tz)
+ return cls(*dt)
+
+from request import Request
+
+syssession = None
+
+def set_session(sessionid):
+ global syssession
+ syssession = Session(sessionid)
+
+def get_session(sessionid=None):
+ global syssession
+ if sessionid:
+ return Session(sessionid)
+ elif syssession is not None:
+ return syssession
+ else:
+ return Session.new()
+
+class Session( object ):
+
+ @classmethod
+ def new(cls):
+ return cls(None)
+
+ def __init__(self, sessionid):
+ self.sessionid = sessionid
+
+ @property
+ def sessionid(self):
+ if self._sessionid is None:
+ if self._authtoken is None:
+ raise RuntimeError("No Auth Token to produce Session for")
+ # TODO: check authtokenexpiration against current time
+ req = Request('authentication/session/new', \
+ request_token=self._authtoken)
+ req.lifetime = 0
+ dat = req.readJSON()
+ if not dat['success']:
+ raise RuntimeError("Session generation failed")
+ self._sessionid = dat['session_id']
+ return self._sessionid
+
+ @sessionid.setter
+ def sessionid(self, value):
+ self._sessionid = value
+ self._authtoken = None
+ self._authtokenexpiration = None
+ if value is None:
+ self.authenticated = False
+ else:
+ self.authenticated = True
+
+ @property
+ def authtoken(self):
+ if self.authenticated:
+ raise RuntimeError("Session is already authenticated")
+ if self._authtoken is None:
+ req = Request('authentication/token/new')
+ req.lifetime = 0
+ dat = req.readJSON()
+ if not dat['success']:
+ raise RuntimeError("Auth Token request failed")
+ self._authtoken = dat['request_token']
+ self._authtokenexpiration = datetime.fromIso(dat['expires_at'])
+ return self._authtoken
+
+ @property
+ def callbackurl(self):
+ return "http://www.themoviedb.org/authenticate/"+self._authtoken
+
View
9 tmdb3/util.py
@@ -8,6 +8,7 @@
from copy import copy
from locales import get_locale
+from tmdb_auth import get_session
class Poller( object ):
"""
@@ -130,6 +131,7 @@ def __set__(self, inst, value):
value = self.default
if isinstance(value, Element):
value._locale = inst._locale
+ value._session = inst._session
inst._data[self.field] = value
def sethandler(self, handler):
@@ -179,6 +181,7 @@ def __set__(self, inst, value):
val = self.handler(val)
if isinstance(val, Element):
val._locale = inst._locale
+ val._session = inst._session
data.append(val)
if self.sort:
if self.sort is True:
@@ -232,6 +235,7 @@ def __set__(self, inst, value):
val = self.handler(val)
if isinstance(val, Element):
val._locale = inst._locale
+ val._session = inst._session
data[self.getkey(val)] = val
inst._data[self.field] = data
@@ -313,6 +317,11 @@ def __call__(cls, *args, **kwargs):
else:
obj._locale = get_locale()
+ if 'session' in kwargs:
+ obj._session = kwargs['session']
+ else:
+ obj._session = get_session()
+
obj._data = {}
if 'raw' in kwargs:
# if 'raw' keyword is supplied, create populate object manually

0 comments on commit 3debcd5

Please sign in to comment.
Something went wrong with that request. Please try again.