Skip to content

Commit

Permalink
PEP8 code style updates.
Browse files Browse the repository at this point in the history
Modified from original commit.

Signed-off-by: Raymond Wagner <[email protected]>
  • Loading branch information
Richard O'Dwyer authored and wagnerrp committed Oct 6, 2013
1 parent abae25a commit 053778c
Show file tree
Hide file tree
Showing 14 changed files with 612 additions and 450 deletions.
5 changes: 3 additions & 2 deletions scripts/populate_locale.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@
import sys
import os


def sanitize(name):
name = ' '.join(name.split())
return name


fpath = os.path.join(os.getcwd(), __file__) if not __file__.startswith('/') else __file__
fpath = os.path.join(fpath.rsplit('/',2)[0], 'tmdb3/locales.py')
fpath = os.path.join(fpath.rsplit('/', 2)[0], 'tmdb3/locales.py')

fd = open(fpath, 'r')
while True:
Expand Down Expand Up @@ -52,4 +54,3 @@ def sanitize(name):
continue
name, _, alpha2 = [t.text if t.text else t.getchildren()[0].tail for t in row]
fd.write('Country("{0}", u"{1}")\n'.format(alpha2, sanitize(name).encode('utf8')))

1 change: 0 additions & 1 deletion scripts/pytmdb3.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,3 @@
namespace = globals().copy()
namespace.update(locals())
code.InteractiveConsole(namespace).interact(banner)

12 changes: 6 additions & 6 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
from distutils.core import setup

setup(
name='tmdb3',
version='0.6.16',
description='TheMovieDB.org APIv3 interface',
long_description="Object-oriented interface to TheMovieDB.org's v3 API.",
packages=['tmdb3']
)
name='tmdb3',
version='0.6.16',
description='TheMovieDB.org APIv3 interface',
long_description="Object-oriented interface to TheMovieDB.org's v3 API.",
packages=['tmdb3']
)
40 changes: 23 additions & 17 deletions tmdb3/cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,18 @@
import cache_null
import cache_file

class Cache( object ):

class Cache(object):
"""
This class implements a persistent cache, backed in a file specified in
the object creation. The file is protected for safe, concurrent access
by multiple instances using flock.
This cache uses JSON for speed and storage efficiency, so only simple
data types are supported.
Data is stored in a simple format {key:(expiretimestamp, data)}
This class implements a cache framework, allowing selecting of a
pluggable engine. The framework stores data in a key/value manner,
along with a lifetime, after which data will be expired and
pulled fresh next time it is requested from the cache.
This class defines a wrapper to be used with query functions. The
wrapper will automatically cache the inputs and outputs of the
wrapped function, pulling the output from local storage for
subsequent calls with those inputs.
"""
def __init__(self, engine=None, *args, **kwargs):
self._engine = None
Expand All @@ -40,7 +44,7 @@ def _import(self, data=None):
self._age = max(self._age, obj.creation)

def _expire(self):
for k,v in self._data.items():
for k, v in self._data.items():
if v.expired:
del self._data[k]

Expand Down Expand Up @@ -90,19 +94,22 @@ def __init__(self, cache, callback, func=None, inst=None):
self.__doc__ = func.__doc__

def __call__(self, *args, **kwargs):
if self.func is None: # decorator is waiting to be given a function
if self.func is None:
# decorator is waiting to be given a function
if len(kwargs) or (len(args) != 1):
raise TMDBCacheError('Cache.Cached decorator must be called '+\
'a single callable argument before it '+\
'be used.')
raise TMDBCacheError(
'Cache.Cached decorator must be called a single ' +
'callable argument before it be used.')
elif args[0] is None:
raise TMDBCacheError('Cache.Cached decorator called before '+\
'being given a function to wrap.')
raise TMDBCacheError(
'Cache.Cached decorator called before being given ' +
'a function to wrap.')
elif not callable(args[0]):
raise TMDBCacheError('Cache.Cached must be provided a '+\
'callable object.')
raise TMDBCacheError(
'Cache.Cached must be provided a callable object.')
return self.__class__(self.cache, self.callback, args[0])
elif self.inst.lifetime == 0:
# lifetime of zero means never cache
return self.func(*args, **kwargs)
else:
key = self.callback()
Expand All @@ -121,4 +128,3 @@ def __get__(self, inst, owner):
func = self.func.__get__(inst, owner)
callback = self.callback.__get__(inst, owner)
return self.__class__(self.cache, callback, func, inst)

30 changes: 21 additions & 9 deletions tmdb3/cache_engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,35 +10,46 @@
import time
from weakref import ref

class Engines( object ):

class Engines(object):
"""
Static collector for engines to register against.
"""
def __init__(self):
self._engines = {}

def register(self, engine):
self._engines[engine.__name__] = engine
self._engines[engine.name] = engine

def __getitem__(self, key):
return self._engines[key]

def __contains__(self, key):
return self._engines.__contains__(key)

Engines = Engines()

class CacheEngineType( type ):

class CacheEngineType(type):
"""
Cache Engine Metaclass that registers new engines against the cache
for named selection and use.
"""
def __init__(mcs, name, bases, attrs):
super(CacheEngineType, mcs).__init__(name, bases, attrs)
def __init__(cls, name, bases, attrs):
super(CacheEngineType, cls).__init__(name, bases, attrs)
if name != 'CacheEngine':
# skip base class
Engines.register(mcs)
Engines.register(cls)

class CacheEngine( object ):
__metaclass__ = CacheEngineType

class CacheEngine(object):
__metaclass__ = CacheEngineType
name = 'unspecified'

def __init__(self, parent):
self.parent = ref(parent)

def configure(self):
raise RuntimeError
def get(self, date):
Expand All @@ -48,7 +59,8 @@ def put(self, key, value, lifetime):
def expire(self, key):
raise RuntimeError

class CacheObject( object ):

class CacheObject(object):
"""
Cache object class, containing one stored record.
"""
Expand All @@ -64,7 +76,7 @@ def __len__(self):

@property
def expired(self):
return (self.remaining == 0)
return self.remaining == 0

@property
def remaining(self):
Expand Down
52 changes: 30 additions & 22 deletions tmdb3/cache_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,11 @@ def _donothing(*args, **kwargs):

try:
import fcntl
class Flock( object ):
class Flock(object):
"""
Context manager to flock file for the duration the object exists.
Referenced file will be automatically unflocked as the interpreter
exits the context.
Context manager to flock file for the duration the object
exists. Referenced file will be automatically unflocked as the
interpreter exits the context.
Supports an optional callback to process the error and optionally
suppress it.
"""
Expand All @@ -70,8 +70,10 @@ def __init__(self, fileobj, operation, callback=None):
self.fileobj = fileobj
self.operation = operation
self.callback = callback

def __enter__(self):
fcntl.flock(self.fileobj, self.operation)

def __exit__(self, exc_type, exc_value, exc_tb):
suppress = False
if callable(self.callback):
Expand Down Expand Up @@ -102,9 +104,11 @@ def __init__(self, fileobj, operation, callback=None):
self.fileobj = fileobj
self.operation = operation
self.callback = callback

def __enter__(self):
self.size = os.path.getsize(self.fileobj.name)
msvcrt.locking(self.fileobj.fileno(), self.operation, self.size)

def __exit__(self, exc_type, exc_value, exc_tb):
suppress = False
if callable(self.callback):
Expand All @@ -119,20 +123,20 @@ def parse_filename(filename):
if filename.startswith('~'):
# check for home directory
return os.path.expanduser(filename)
elif (ord(filename[0]) in (range(65,91)+range(99,123))) \
elif (ord(filename[0]) in (range(65, 91) + range(99, 123))) \
and (filename[1:3] == ':\\'):
# check for absolute drive path (e.g. C:\...)
return filename
elif (filename.count('\\') >= 3) and (filename.startswith('\\\\')):
# check for absolute UNC path (e.g. \\server\...)
return filename
# return path with temp directory prepended
return os.path.expandvars(os.path.join('%TEMP%',filename))
return os.path.expandvars(os.path.join('%TEMP%', filename))


class FileCacheObject( CacheObject ):
_struct = struct.Struct('dII') # double and two ints
# timestamp, lifetime, position
class FileCacheObject(CacheObject):
_struct = struct.Struct('dII') # double and two ints
# timestamp, lifetime, position

@classmethod
def fromFile(cls, fd):
Expand All @@ -151,7 +155,7 @@ def __init__(self, *args, **kwargs):
@property
def size(self):
if self._size is None:
self._buff.seek(0,2)
self._buff.seek(0, 2)
size = self._buff.tell()
if size == 0:
if (self._key is None) or (self._data is None):
Expand All @@ -160,8 +164,10 @@ def size(self):
self._size = self._buff.tell()
self._size = size
return self._size

@size.setter
def size(self, value): self._size = value
def size(self, value):
self._size = value

@property
def key(self):
Expand All @@ -171,16 +177,20 @@ def key(self):
except:
pass
return self._key

@key.setter
def key(self, value): self._key = value
def key(self, value):
self._key = value

@property
def data(self):
if self._data is None:
self._key, self._data = json.loads(self._buff.getvalue())
return self._data

@data.setter
def data(self, value): self._data = value
def data(self, value):
self._data = value

def load(self, fd):
fd.seek(self.position)
Expand All @@ -200,7 +210,7 @@ def dumpdata(self, fd):
class FileEngine( CacheEngine ):
"""Simple file-backed engine."""
name = 'file'
_struct = struct.Struct('HH') # two shorts for version and count
_struct = struct.Struct('HH') # two shorts for version and count
_version = 2

def __init__(self, parent):
Expand All @@ -220,7 +230,6 @@ def _init_cache(self):

if self.cachefile is None:
raise TMDBCacheError("No cache filename given.")

self.cachefile = parse_filename(self.cachefile)

try:
Expand Down Expand Up @@ -258,15 +267,15 @@ def get(self, date):
self._init_cache()
self._open('r+b')

with Flock(self.cachefd, Flock.LOCK_SH): # lock for shared access
with Flock(self.cachefd, Flock.LOCK_SH):
# return any new objects in the cache
return self._read(date)

def put(self, key, value, lifetime):
self._init_cache()
self._open('r+b')

with Flock(self.cachefd, Flock.LOCK_EX): # lock for exclusive access
with Flock(self.cachefd, Flock.LOCK_EX):
newobjs = self._read(self.age)
newobjs.append(FileCacheObject(key, value, lifetime))

Expand All @@ -284,7 +293,8 @@ def _open(self, mode='r+b'):
# already opened in requested mode, nothing to do
self.cachefd.seek(0)
return
except: pass # catch issue of no cachefile yet opened
except:
pass # catch issue of no cachefile yet opened
self.cachefd = io.open(self.cachefile, mode)

def _read(self, date):
Expand All @@ -311,7 +321,7 @@ def _read(self, date):
return []

# get end of file
self.cachefd.seek(0,2)
self.cachefd.seek(0, 2)
position = self.cachefd.tell()
newobjs = []
emptycount = 0
Expand Down Expand Up @@ -349,7 +359,7 @@ def _write(self, data):
data = data[-1]

# determine write position of data in cache
self.cachefd.seek(0,2)
self.cachefd.seek(0, 2)
end = self.cachefd.tell()
data.position = end

Expand Down Expand Up @@ -388,5 +398,3 @@ def _write(self, data):

def expire(self, key):
pass


18 changes: 13 additions & 5 deletions tmdb3/cache_null.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,19 @@

from cache_engine import CacheEngine

class NullEngine( CacheEngine ):

class NullEngine(CacheEngine):
"""Non-caching engine for debugging."""
name = 'null'
def configure(self): pass
def get(self, date): return []
def put(self, key, value, lifetime): return []
def expire(self, key): pass

def configure(self):
pass

def get(self, date):
return []

def put(self, key, value, lifetime):
return []

def expire(self, key):
pass
Loading

0 comments on commit 053778c

Please sign in to comment.