refactored object caching behaviour out from base.py to cacheable.py and renamed registry.py to objectcache.py
parent
237b32c6c1
commit
26415e75bc
|
@ -7,13 +7,12 @@ __license__ = "GNU Lesser General Public License"
|
|||
from album import Album
|
||||
from api import Api
|
||||
from artist import Artist
|
||||
from base import LastfmBase
|
||||
from error import LastfmError
|
||||
from event import Event
|
||||
from geo import Location, Country
|
||||
from group import Group
|
||||
from playlist import Playlist
|
||||
from registry import Registry
|
||||
from objectcache import ObjectCache
|
||||
from tag import Tag
|
||||
from tasteometer import Tasteometer
|
||||
from track import Track
|
||||
|
@ -21,4 +20,4 @@ from user import User
|
|||
|
||||
__all__ = ['LastfmError', 'Api', 'Album', 'Artist', 'Event',
|
||||
'Location', 'Country', 'Group', 'Playlist', 'Tag',
|
||||
'Tasteometer', 'Track', 'User', 'Registry']
|
||||
'Tasteometer', 'Track', 'User', 'ObjectCache']
|
|
@ -6,8 +6,9 @@ __license__ = "GNU Lesser General Public License"
|
|||
|
||||
from base import LastfmBase
|
||||
from taggable import Taggable
|
||||
from cacheable import Cacheable
|
||||
|
||||
class Album(Taggable, LastfmBase):
|
||||
class Album(LastfmBase, Cacheable, Taggable):
|
||||
"""A class representing an album."""
|
||||
def init(self,
|
||||
api,
|
||||
|
|
|
@ -5,12 +5,13 @@ __version__ = "0.2"
|
|||
__license__ = "GNU Lesser General Public License"
|
||||
|
||||
from base import LastfmBase
|
||||
from cacheable import Cacheable
|
||||
from taggable import Taggable
|
||||
from sharable import Sharable
|
||||
from searchable import Searchable
|
||||
from lazylist import lazylist
|
||||
|
||||
class Artist(LastfmBase, Taggable, Sharable, Searchable):
|
||||
class Artist(LastfmBase, Cacheable, Sharable, Searchable, Taggable):
|
||||
"""A class representing an artist."""
|
||||
def init(self,
|
||||
api,
|
||||
|
|
46
src/base.py
46
src/base.py
|
@ -4,55 +4,9 @@ __author__ = "Abhinav Sarkar <abhinav@abhinavsarkar.net>"
|
|||
__version__ = "0.2"
|
||||
__license__ = "GNU Lesser General Public License"
|
||||
|
||||
try:
|
||||
from threading import Lock
|
||||
except ImportError:
|
||||
from dummy_threading import Lock
|
||||
|
||||
class LastfmBase(object):
|
||||
"""Base class for all the classes in this package"""
|
||||
|
||||
registry = {}
|
||||
_lock = Lock()
|
||||
|
||||
def __new__(cls, *args, **kwds):
|
||||
subject = None
|
||||
if 'subject' in kwds and not cls.__name__.startswith('Weekly'):
|
||||
subject = kwds['subject']
|
||||
del kwds['subject']
|
||||
|
||||
if 'bypass_registry' in kwds:
|
||||
del kwds['bypass_registry']
|
||||
inst = object.__new__(cls)
|
||||
inst.init(*args, **kwds)
|
||||
return inst
|
||||
|
||||
key = cls._hash_func(*args, **kwds)
|
||||
if subject is not None:
|
||||
key = (hash(subject), key)
|
||||
|
||||
LastfmBase._lock.acquire()
|
||||
try:
|
||||
inst, already_registered = LastfmBase.register(object.__new__(cls), key)
|
||||
if not already_registered:
|
||||
inst.init(*args, **kwds)
|
||||
finally:
|
||||
LastfmBase._lock.release()
|
||||
return inst
|
||||
|
||||
@staticmethod
|
||||
def register(ob, key):
|
||||
if not ob.__class__ in LastfmBase.registry:
|
||||
LastfmBase.registry[ob.__class__] = {}
|
||||
if key in LastfmBase.registry[ob.__class__]:
|
||||
ob = LastfmBase.registry[ob.__class__][key]
|
||||
#print "already registered: %s" % repr(ob)
|
||||
return (ob, True)
|
||||
else:
|
||||
#print "not already registered: %s" % ob.__class__
|
||||
LastfmBase.registry[ob.__class__][key] = ob
|
||||
return (ob, False)
|
||||
|
||||
@staticmethod
|
||||
def top_property(list_property_name):
|
||||
def decorator(func):
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "Abhinav Sarkar <abhinav@abhinavsarkar.net>"
|
||||
__version__ = "0.2"
|
||||
__license__ = "GNU Lesser General Public License"
|
||||
|
||||
try:
|
||||
from threading import Lock
|
||||
except ImportError:
|
||||
from dummy_threading import Lock
|
||||
|
||||
class Cacheable(object):
|
||||
registry = {}
|
||||
_lock = Lock()
|
||||
|
||||
def __new__(cls, *args, **kwds):
|
||||
subject = None
|
||||
if 'subject' in kwds and not cls.__name__.startswith('Weekly'):
|
||||
subject = kwds['subject']
|
||||
del kwds['subject']
|
||||
|
||||
if 'bypass_registry' in kwds:
|
||||
del kwds['bypass_registry']
|
||||
inst = object.__new__(cls)
|
||||
inst.init(*args, **kwds)
|
||||
return inst
|
||||
|
||||
key = cls._hash_func(*args, **kwds)
|
||||
if subject is not None:
|
||||
key = (hash(subject), key)
|
||||
|
||||
Cacheable._lock.acquire()
|
||||
try:
|
||||
inst, already_registered = Cacheable.register(object.__new__(cls), key)
|
||||
if not already_registered:
|
||||
inst.init(*args, **kwds)
|
||||
finally:
|
||||
Cacheable._lock.release()
|
||||
return inst
|
||||
|
||||
@staticmethod
|
||||
def register(ob, key):
|
||||
if not ob.__class__ in Cacheable.registry:
|
||||
Cacheable.registry[ob.__class__] = {}
|
||||
if key in Cacheable.registry[ob.__class__]:
|
||||
ob = Cacheable.registry[ob.__class__][key]
|
||||
#print "already registered: %s" % repr(ob)
|
||||
return (ob, True)
|
||||
else:
|
||||
#print "not already registered: %s" % ob.__class__
|
||||
Cacheable.registry[ob.__class__][key] = ob
|
||||
return (ob, False)
|
|
@ -5,9 +5,10 @@ __version__ = "0.2"
|
|||
__license__ = "GNU Lesser General Public License"
|
||||
|
||||
from base import LastfmBase
|
||||
from cacheable import Cacheable
|
||||
from sharable import Sharable
|
||||
|
||||
class Event(LastfmBase, Sharable):
|
||||
class Event(LastfmBase, Cacheable, Sharable):
|
||||
"""A class representing an event."""
|
||||
STATUS_ATTENDING = 0
|
||||
STATUS_MAYBE = 1
|
||||
|
|
|
@ -5,6 +5,7 @@ __version__ = "0.2"
|
|||
__license__ = "GNU Lesser General Public License"
|
||||
|
||||
from base import LastfmBase
|
||||
from cacheable import Cacheable
|
||||
from lazylist import lazylist
|
||||
|
||||
class Geo(object):
|
||||
|
@ -93,7 +94,7 @@ class Geo(object):
|
|||
for t in data.findall('track')
|
||||
]
|
||||
|
||||
class Venue(LastfmBase):
|
||||
class Venue(LastfmBase, Cacheable):
|
||||
"""A class representing a venue of an event"""
|
||||
def init(self,
|
||||
name = None,
|
||||
|
@ -137,7 +138,7 @@ class Venue(LastfmBase):
|
|||
def __repr__(self):
|
||||
return "<lastfm.geo.Venue: %s, %s>" % (self.name, self.location.city)
|
||||
|
||||
class Location(LastfmBase):
|
||||
class Location(LastfmBase, Cacheable):
|
||||
"""A class representing a location of an event"""
|
||||
XMLNS = "http://www.w3.org/2003/01/geo/wgs84_pos#"
|
||||
|
||||
|
@ -254,7 +255,7 @@ class Location(LastfmBase):
|
|||
else:
|
||||
return "<lastfm.geo.Location: %s>" % self.city
|
||||
|
||||
class Country(LastfmBase):
|
||||
class Country(LastfmBase, Cacheable):
|
||||
"""A class representing a country."""
|
||||
def init(self,
|
||||
api,
|
||||
|
|
|
@ -5,9 +5,10 @@ __version__ = "0.2"
|
|||
__license__ = "GNU Lesser General Public License"
|
||||
|
||||
from base import LastfmBase
|
||||
from cacheable import Cacheable
|
||||
from lazylist import lazylist
|
||||
|
||||
class Group(LastfmBase):
|
||||
class Group(LastfmBase, Cacheable):
|
||||
"""A class representing a group on last.fm."""
|
||||
def init(self,
|
||||
api,
|
||||
|
|
|
@ -6,7 +6,7 @@ __license__ = "GNU Lesser General Public License"
|
|||
|
||||
from album import Album
|
||||
from artist import Artist
|
||||
from base import LastfmBase
|
||||
from cacheable import Cacheable
|
||||
from error import InvalidParametersError
|
||||
from event import Event
|
||||
from geo import Location, Country
|
||||
|
@ -17,21 +17,21 @@ from track import Track
|
|||
from user import User
|
||||
from weeklychart import WeeklyAlbumChart, WeeklyArtistChart, WeeklyTrackChart
|
||||
|
||||
class Registry(object):
|
||||
class ObjectCache(object):
|
||||
"""The registry to contain all the entities"""
|
||||
keys = [c.__name__ for c in [Album, Artist, Event, Location, Country, Group,
|
||||
Playlist, Tag, Track, User, WeeklyAlbumChart, WeeklyArtistChart, WeeklyTrackChart]]
|
||||
|
||||
def __getitem__(self, name):
|
||||
if name not in Registry.keys:
|
||||
if name not in ObjectCache.keys:
|
||||
raise InvalidParametersError("Key does not correspond to a valid class")
|
||||
else:
|
||||
try:
|
||||
vals = LastfmBase.registry[eval(name)].values()
|
||||
vals = Cacheable.registry[eval(name)].values()
|
||||
vals.sort()
|
||||
return vals
|
||||
except KeyError:
|
||||
return []
|
||||
|
||||
def __repr__(self):
|
||||
return "<lastfm.Registry>"
|
||||
return "<lastfm.ObjectCache>"
|
|
@ -5,8 +5,9 @@ __version__ = "0.2"
|
|||
__license__ = "GNU Lesser General Public License"
|
||||
|
||||
from base import LastfmBase
|
||||
from cacheable import Cacheable
|
||||
|
||||
class Playlist(LastfmBase):
|
||||
class Playlist(LastfmBase, Cacheable):
|
||||
"""A class representing an XPSF playlist."""
|
||||
def init(self, api, url):
|
||||
self._api = api
|
||||
|
|
|
@ -6,9 +6,10 @@ __license__ = "GNU Lesser General Public License"
|
|||
|
||||
from base import LastfmBase
|
||||
from searchable import Searchable
|
||||
from cacheable import Cacheable
|
||||
from lazylist import lazylist
|
||||
|
||||
class Tag(LastfmBase, Searchable):
|
||||
class Tag(LastfmBase, Cacheable, Searchable):
|
||||
""""A class representing a tag."""
|
||||
def init(self,
|
||||
api,
|
||||
|
|
|
@ -5,12 +5,13 @@ __version__ = "0.2"
|
|||
__license__ = "GNU Lesser General Public License"
|
||||
|
||||
from base import LastfmBase
|
||||
from cacheable import Cacheable
|
||||
from taggable import Taggable
|
||||
from sharable import Sharable
|
||||
from searchable import Searchable
|
||||
from lazylist import lazylist
|
||||
|
||||
class Track(LastfmBase, Taggable, Sharable, Searchable):
|
||||
class Track(LastfmBase, Cacheable, Sharable, Searchable, Taggable):
|
||||
"""A class representing a track."""
|
||||
def init(self,
|
||||
api,
|
||||
|
|
|
@ -5,10 +5,11 @@ __version__ = "0.2"
|
|||
__license__ = "GNU Lesser General Public License"
|
||||
|
||||
from base import LastfmBase
|
||||
from cacheable import Cacheable
|
||||
from lazylist import lazylist
|
||||
import playlist
|
||||
|
||||
class User(LastfmBase):
|
||||
class User(LastfmBase, Cacheable):
|
||||
"""A class representing an user."""
|
||||
def init(self,
|
||||
api,
|
||||
|
|
|
@ -5,8 +5,9 @@ __version__ = "0.2"
|
|||
__license__ = "GNU Lesser General Public License"
|
||||
|
||||
from base import LastfmBase
|
||||
from cacheable import Cacheable
|
||||
|
||||
class WeeklyChart(LastfmBase):
|
||||
class WeeklyChart(LastfmBase, Cacheable):
|
||||
"""A class for representing the weekly charts"""
|
||||
|
||||
def init(self, subject, start, end,
|
||||
|
|
Loading…
Reference in New Issue