more changes for PEP8 compliance

master
Abhinav Sarkar 2008-12-30 13:51:04 +00:00
parent c6bd6ec95f
commit 21f591a450
20 changed files with 937 additions and 915 deletions

View File

@ -23,76 +23,76 @@ class Album(Taggable, LastfmBase):
if not isinstance(api, Api):
raise InvalidParametersError("api reference must be supplied as an argument")
Taggable.init(self, api)
self.__api = api
self.__name = name
self.__artist = artist
self.__id = id
self.__mbid = mbid
self.__url = url
self.__release_date = release_date
self.__image = image
self.__stats = stats and Stats(
self._api = api
self._name = name
self._artist = artist
self._id = id
self._mbid = mbid
self._url = url
self._release_date = release_date
self._image = image
self._stats = stats and Stats(
subject = self,
listeners = stats.listeners,
playcount = stats.playcount,
match = stats.match,
rank = stats.rank
)
self.__top_tags = top_tags
self._top_tags = top_tags
@property
def name(self):
"""name of the album"""
return self.__name
return self._name
@property
def artist(self):
"""artist of the album"""
return self.__artist
return self._artist
@property
def id(self):
"""id of the album"""
if self.__id is None:
if self._id is None:
self._fill_info()
return self.__id
return self._id
@property
def mbid(self):
"""mbid of the album"""
if self.__mbid is None:
if self._mbid is None:
self._fill_info()
return self.__mbid
return self._mbid
@property
def url(self):
"""url of the album's page"""
if self.__url is None:
if self._url is None:
self._fill_info()
return self.__url
return self._url
@property
def release_date(self):
"""release date of the album"""
if self.__release_date is None:
if self._release_date is None:
self._fill_info()
return self.__release_date
return self._release_date
@property
def image(self):
"""cover images of the album"""
if self.__image is None:
if self._image is None:
self._fill_info()
return self.__image
return self._image
@property
def stats(self):
"""stats related to the album"""
if self.__stats is None:
if self._stats is None:
self._fill_info()
return self.__stats
return self._stats
@LastfmBase.cachedProperty
@LastfmBase.cached_property
def top_tags(self):
"""top tags for the album"""
params = {'method': 'album.getInfo'}
@ -100,10 +100,10 @@ class Album(Taggable, LastfmBase):
params.update({'artist': self.artist.name, 'album': self.name})
elif self.mbid:
params.update({'mbid': self.mbid})
data = self.__api._fetch_data(params).find('album')
data = self._api._fetch_data(params).find('album')
return [
Tag(
self.__api,
self._api,
subject = self,
name = t.findtext('name'),
url = t.findtext('url')
@ -111,60 +111,15 @@ class Album(Taggable, LastfmBase):
for t in data.findall('toptags/tag')
]
@LastfmBase.topProperty("top_tags")
@LastfmBase.top_property("top_tags")
def top_tag(self):
"""top tag for the album"""
pass
@LastfmBase.cachedProperty
@LastfmBase.cached_property
def playlist(self):
return Playlist.fetch(self.__api, "lastfm://playlist/album/%s" % self.id)
return Playlist.fetch(self._api, "lastfm://playlist/album/%s" % self.id)
def _default_params(self, extra_params = None):
if not (self.artist and self.name):
raise InvalidParametersError("artist and album have to be provided.")
params = {'artist': self.artist.name, 'album': self.name}
if extra_params is not None:
params.update(extra_params)
return params
@staticmethod
def _fetch_data(api,
artist = None,
album = None,
mbid = None):
params = {'method': 'album.getInfo'}
if not ((artist and album) or mbid):
raise InvalidParametersError("either (artist and album) or mbid has to be given as argument.")
if artist and album:
params.update({'artist': artist, 'album': album})
elif mbid:
params.update({'mbid': mbid})
return api._fetch_data(params).find('album')
def _fill_info(self):
data = Album._fetch_data(self.__api, self.artist.name, self.name)
self.__id = int(data.findtext('id'))
self.__mbid = data.findtext('mbid')
self.__url = data.findtext('url')
self.__release_date = data.findtext('releasedate') and data.findtext('releasedate').strip() and \
datetime(*(time.strptime(data.findtext('releasedate').strip(), '%d %b %Y, 00:00')[0:6]))
self.__image = dict([(i.get('size'), i.text) for i in data.findall('image')])
self.__stats = Stats(
subject = self,
listeners = int(data.findtext('listeners')),
playcount = int(data.findtext('playcount')),
)
self.__top_tags = [
Tag(
self.__api,
subject = self,
name = t.findtext('name'),
url = t.findtext('url')
)
for t in data.findall('toptags/tag')
]
@staticmethod
def get_info(api,
artist = None,
@ -182,15 +137,59 @@ class Album(Taggable, LastfmBase):
a._fill_info()
return a
def _default_params(self, extra_params = {}):
if not (self.artist and self.name):
raise InvalidParametersError("artist and album have to be provided.")
params = {'artist': self.artist.name, 'album': self.name}
params.update(extra_params)
return params
@staticmethod
def hash_func(*args, **kwds):
def _fetch_data(api,
artist = None,
album = None,
mbid = None):
params = {'method': 'album.getInfo'}
if not ((artist and album) or mbid):
raise InvalidParametersError("either (artist and album) or mbid has to be given as argument.")
if artist and album:
params.update({'artist': artist, 'album': album})
elif mbid:
params.update({'mbid': mbid})
return api._fetch_data(params).find('album')
def _fill_info(self):
data = Album._fetch_data(self._api, self.artist.name, self.name)
self._id = int(data.findtext('id'))
self._mbid = data.findtext('mbid')
self._url = data.findtext('url')
self._release_date = data.findtext('releasedate') and data.findtext('releasedate').strip() and \
datetime(*(time.strptime(data.findtext('releasedate').strip(), '%d %b %Y, 00:00')[0:6]))
self._image = dict([(i.get('size'), i.text) for i in data.findall('image')])
self._stats = Stats(
subject = self,
listeners = int(data.findtext('listeners')),
playcount = int(data.findtext('playcount')),
)
self._top_tags = [
Tag(
self._api,
subject = self,
name = t.findtext('name'),
url = t.findtext('url')
)
for t in data.findall('toptags/tag')
]
@staticmethod
def _hash_func(*args, **kwds):
try:
return hash("%s%s" % (kwds['name'], hash(kwds['artist'])))
except KeyError:
raise InvalidParametersError("name and artist have to be provided for hashing")
def __hash__(self):
return self.__class__.hash_func(name = self.name, artist = self.artist)
return self.__class__._hash_func(name = self.name, artist = self.artist)
def __eq__(self, other):
if self.id and other.id:

View File

@ -22,9 +22,9 @@ class Api(object):
request_headers=None,
no_cache = False,
debug = False):
self.__api_key = api_key
self.__secret = secret
self.__session_key = session_key
self._api_key = api_key
self._secret = secret
self._session_key = session_key
self._cache = FileCache()
self._urllib = urllib2
self._cache_timeout = Api.DEFAULT_CACHE_TIMEOUT
@ -37,36 +37,36 @@ class Api(object):
@property
def api_key(self):
return self.__api_key
return self._api_key
@property
def secret(self):
return self.__secret
return self._secret
@property
def session_key(self):
return self.__session_key
return self._session_key
def set_session_key(self):
params = {'method': 'auth.getSession', 'token': self.auth_token}
self.__session_key = self._fetch_data(params, sign = True).findtext('session/key')
self.__auth_token = None
@LastfmBase.cachedProperty
self._session_key = self._fetch_data(params, sign = True).findtext('session/key')
self._auth_token = None
@LastfmBase.cached_property
def auth_token(self):
params = {'method': 'auth.getToken'}
return self._fetch_data(params, sign = True).findtext('token')
@LastfmBase.cachedProperty
@LastfmBase.cached_property
def auth_url(self):
return "http://www.last.fm/api/auth/?api_key=%s&token=%s" % (self.api_key, self.auth_token)
def set_cache(self, cache):
'''Override the default cache. Set to None to prevent caching.
Args:
cache: an instance that supports the same API as the audioscrobblerws.FileCache
cache: an instance that supports the same API as the lastfm.FileCache
'''
self._cache = cache
@ -124,7 +124,7 @@ class Api(object):
def get_group(self, name):
return Group(self, name = name)
def fetch_playlist(self, url):
def get_playlist(self, url):
return Playlist.fetch(self, url)
def get_tag(self, name):
@ -165,7 +165,7 @@ class Api(object):
except Error, e:
raise e
return user
def get_authenticated_user(self):
if self.session_key is not None:
return User.get_authenticated_user(self)
@ -238,7 +238,7 @@ class Api(object):
keys = parameters.keys()
keys.sort()
return urllib.urlencode([(k, self._encode(parameters[k])) for k in keys if parameters[k] is not None])
def _read_url_data(self, opener, url, data = None):
now = datetime.now()
delta = now - self._last_fetch_time
@ -247,8 +247,8 @@ class Api(object):
time.sleep(Api.FETCH_INTERVAL - delta)
url_data = opener.open(url, data).read()
self._last_fetch_time = datetime.now()
return url_data
return url_data
def _fetch_url(self,
url,
parameters = None,
@ -303,19 +303,19 @@ class Api(object):
session = False,
no_cache = False):
params['api_key'] = self.api_key
if session:
if self.session_key is not None:
params['sk'] = self.session_key
else:
raise AuthenticationFailedError("session key must be present to call this method")
if sign:
params['api_sig'] = self._get_api_sig(params)
xml = self._fetch_url(Api.API_ROOT_URL, params, no_cache = self._no_cache or no_cache)
return self._check_XML(xml)
return self._check_xml(xml)
def _post_url(self,
url,
parameters):
@ -326,24 +326,24 @@ class Api(object):
opener = self._get_opener(url)
url_data = self._read_url_data(opener, url, data)
return url_data
def _post_data(self, params):
params['api_key'] = self.api_key
if self.session_key is not None:
params['sk'] = self.session_key
else:
raise AuthenticationFailedError("session key must be present to call this method")
params['api_sig'] = self._get_api_sig(params)
params['api_sig'] = self._get_api_sig(params)
xml = self._post_url(Api.API_ROOT_URL, params)
return self._check_XML(xml)
return self._check_xml(xml)
def _get_api_sig(self, params):
if self.secret is not None:
keys = params.keys()[:]
keys.sort()
sig = unicode()
sig = unicode()
for name in keys:
sig += ("%s%s" % (name, params[name]))
sig += self.secret
@ -352,7 +352,7 @@ class Api(object):
else:
raise AuthenticationFailedError("api secret must be present to call this method")
def _check_XML(self, xml):
def _check_xml(self, xml):
data = None
try:
data = ElementTree.XML(xml)
@ -361,18 +361,18 @@ class Api(object):
if data.get('status') != "ok":
code = int(data.find("error").get('code'))
message = data.findtext('error')
if code in errorMap.keys():
raise errorMap[code](message, code)
if code in error_map.keys():
raise error_map[code](message, code)
else:
raise Error(message, code)
return data
def __repr__(self):
return "<lastfm.Api: %s>" % self.__api_key
return "<lastfm.Api: %s>" % self._api_key
from datetime import datetime
import md5
import platform
import sys
import time
import urllib
import urllib2
@ -380,7 +380,7 @@ import urlparse
from album import Album
from artist import Artist
from error import errorMap, Error, OperationFailedError, AuthenticationFailedError
from error import error_map, Error, OperationFailedError, AuthenticationFailedError
from event import Event
from filecache import FileCache
from geo import Location, Country
@ -391,8 +391,7 @@ from tasteometer import Tasteometer
from track import Track
from user import User
python_version = platform.python_version_tuple()
if python_version[0] == 2 and python_version[1] >= 5:
if sys.version_info >= (2, 5):
import xml.etree.cElementTree as ElementTree
else:
try:

View File

@ -27,22 +27,22 @@ class Artist(LastfmBase, Taggable, Sharable, Searchable):
raise InvalidParametersError("api reference must be supplied as an argument")
Taggable.init(self, api)
Sharable.init(self, api)
self.__api = api
self.__name = name
self.__mbid = mbid
self.__url = url
self.__image = image
self.__streamable = streamable
self.__stats = stats and Stats(
self._api = api
self._name = name
self._mbid = mbid
self._url = url
self._image = image
self._streamable = streamable
self._stats = stats and Stats(
subject = self,
listeners = stats.listeners,
playcount = stats.playcount,
match = stats.match,
rank = stats.rank
)
self.__similar = similar
self.__top_tags = top_tags
self.__bio = bio and Wiki(
self._similar = similar
self._top_tags = top_tags
self._bio = bio and Wiki(
subject = self,
published = bio.published,
summary = bio.summary,
@ -52,59 +52,51 @@ class Artist(LastfmBase, Taggable, Sharable, Searchable):
@property
def name(self):
"""name of the artist"""
return self.__name
return self._name
@property
def mbid(self):
"""mbid of the artist"""
if self.__mbid is None:
if self._mbid is None:
self._fill_info()
return self.__mbid
return self._mbid
@property
def url(self):
"""url of the artist's page"""
if self.__url is None:
if self._url is None:
self._fill_info()
return self.__url
return self._url
@property
def image(self):
"""images of the artist"""
if self.__image is None:
if self._image is None:
self._fill_info()
return self.__image
return self._image
@property
def streamable(self):
"""is the artist streamable"""
if self.__streamable is None:
if self._streamable is None:
self._fill_info()
return self.__streamable
return self._streamable
@property
def stats(self):
"""stats for the artist"""
if self.__stats is None:
if self._stats is None:
self._fill_info()
return self.__stats
return self._stats
def _default_params(self, extraParams = None):
if not self.name:
raise InvalidParametersError("artist has to be provided.")
params = {'artist': self.name}
if extraParams is not None:
params.update(extraParams)
return params
def get_similar(self, limit = None):
params = self._default_params({'method': 'artist.getSimilar'})
if limit is not None:
params.update({'limit': limit})
data = self.__api._fetch_data(params).find('similarartists')
self.__similar = [
data = self._api._fetch_data(params).find('similarartists')
self._similar = [
Artist(
self.__api,
self._api,
subject = self,
name = a.findtext('name'),
mbid = a.findtext('mbid'),
@ -117,16 +109,16 @@ class Artist(LastfmBase, Taggable, Sharable, Searchable):
)
for a in data.findall('artist')
]
return self.__similar[:]
return self._similar[:]
@property
def similar(self):
"""artists similar to this artist"""
if self.__similar is None or len(self.__similar) < 6:
if self._similar is None or len(self._similar) < 6:
return self.get_similar()
return self.__similar[:]
return self._similar[:]
@LastfmBase.topProperty("similar")
@LastfmBase.top_property("similar")
def most_similar(self):
"""artist most similar to this artist"""
pass
@ -134,21 +126,21 @@ class Artist(LastfmBase, Taggable, Sharable, Searchable):
@property
def top_tags(self):
"""top tags for the artist"""
if self.__top_tags is None or len(self.__top_tags) < 6:
if self._top_tags is None or len(self._top_tags) < 6:
params = self._default_params({'method': 'artist.getTopTags'})
data = self.__api._fetch_data(params).find('toptags')
self.__top_tags = [
data = self._api._fetch_data(params).find('toptags')
self._top_tags = [
Tag(
self.__api,
self._api,
subject = self,
name = t.findtext('name'),
url = t.findtext('url')
)
for t in data.findall('tag')
]
return self.__top_tags[:]
return self._top_tags[:]
@LastfmBase.topProperty("top_tags")
@LastfmBase.top_property("top_tags")
def top_tag(self):
"""top tag for the artist"""
pass
@ -156,30 +148,30 @@ class Artist(LastfmBase, Taggable, Sharable, Searchable):
@property
def bio(self):
"""biography of the artist"""
if self.__bio is None:
if self._bio is None:
self._fill_info()
return self.__bio
return self._bio
@LastfmBase.cachedProperty
@LastfmBase.cached_property
def events(self):
"""events for the artist"""
params = self._default_params({'method': 'artist.getEvents'})
data = self.__api._fetch_data(params).find('events')
data = self._api._fetch_data(params).find('events')
return [
Event.create_from_data(self.__api, e)
Event.create_from_data(self._api, e)
for e in data.findall('event')
]
@LastfmBase.cachedProperty
@LastfmBase.cached_property
def top_albums(self):
"""top albums of the artist"""
params = self._default_params({'method': 'artist.getTopAlbums'})
data = self.__api._fetch_data(params).find('topalbums')
data = self._api._fetch_data(params).find('topalbums')
return [
Album(
self.__api,
self._api,
subject = self,
name = a.findtext('name'),
artist = self,
@ -195,19 +187,19 @@ class Artist(LastfmBase, Taggable, Sharable, Searchable):
for a in data.findall('album')
]
@LastfmBase.topProperty("top_albums")
@LastfmBase.top_property("top_albums")
def top_album(self):
"""top album of the artist"""
pass
@LastfmBase.cachedProperty
@LastfmBase.cached_property
def top_fans(self):
"""top fans of the artist"""
params = self._default_params({'method': 'artist.getTopFans'})
data = self.__api._fetch_data(params).find('topfans')
data = self._api._fetch_data(params).find('topfans')
return [
User(
self.__api,
self._api,
subject = self,
name = u.findtext('name'),
url = u.findtext('url'),
@ -219,20 +211,20 @@ class Artist(LastfmBase, Taggable, Sharable, Searchable):
)
for u in data.findall('user')
]
@LastfmBase.topProperty("top_fans")
@LastfmBase.top_property("top_fans")
def top_fan(self):
"""top fan of the artist"""
pass
@LastfmBase.cachedProperty
@LastfmBase.cached_property
def top_tracks(self):
"""top tracks of the artist"""
params = self._default_params({'method': 'artist.getTopTracks'})
data = self.__api._fetch_data(params).find('toptracks')
data = self._api._fetch_data(params).find('toptracks')
return [
Track(
self.__api,
self._api,
subject = self,
name = t.findtext('name'),
artist = self,
@ -243,17 +235,88 @@ class Artist(LastfmBase, Taggable, Sharable, Searchable):
rank = int(t.attrib['rank'])
),
streamable = (t.findtext('streamable') == '1'),
fullTrack = (t.find('streamable').attrib['fulltrack'] == '1'),
full_track = (t.find('streamable').attrib['fulltrack'] == '1'),
image = dict([(i.get('size'), i.text) for i in t.findall('image')]),
)
for t in data.findall('track')
]
@LastfmBase.topProperty("top_tracks")
@LastfmBase.top_property("top_tracks")
def top_track(self):
"""topmost fan of the artist"""
pass
@staticmethod
def get_info(api,
artist = None,
mbid = None):
data = Artist._fetch_data(api, artist, mbid)
a = Artist(api, name = data.findtext('name'))
a._fill_info()
return a
def _default_params(self, extra_params = {}):
if not self.name:
raise InvalidParametersError("artist has to be provided.")
params = {'artist': self.name}
params.update(extra_params)
return params
@staticmethod
def _fetch_data(api,
artist = None,
mbid = None):
params = {'method': 'artist.getInfo'}
if not (artist or mbid):
raise InvalidParametersError("either artist or mbid has to be given as argument.")
if artist:
params.update({'artist': artist})
elif mbid:
params.update({'mbid': mbid})
return api._fetch_data(params).find('artist')
def _fill_info(self):
data = Artist._fetch_data(self._api, self.name)
self._name = data.findtext('name')
self._mbid = data.findtext('mbid')
self._url = data.findtext('url')
self._image = dict([(i.get('size'), i.text) for i in data.findall('image')])
self._streamable = (data.findtext('streamable') == 1)
self._stats = Stats(
subject = self,
listeners = int(data.findtext('stats/listeners')),
playcount = int(data.findtext('stats/playcount'))
)
self._similar = [
Artist(
self._api,
subject = self,
name = a.findtext('name'),
url = a.findtext('url'),
image = dict([(i.get('size'), i.text) for i in a.findall('image')])
)
for a in data.findall('similar/artist')
]
self._top_tags = [
Tag(
self._api,
subject = self,
name = t.findtext('name'),
url = t.findtext('url')
)
for t in data.findall('tags/tag')
]
self._bio = Wiki(
self,
published = datetime(*(time.strptime(
data.findtext('bio/published').strip(),
'%a, %d %b %Y %H:%M:%S +0000'
)[0:6])),
summary = data.findtext('bio/summary'),
content = data.findtext('bio/content')
)
@staticmethod
def _search_yield_func(api, artist):
return Artist(
@ -265,71 +328,7 @@ class Artist(LastfmBase, Taggable, Sharable, Searchable):
streamable = (artist.findtext('streamable') == '1'),
)
@staticmethod
def _fetch_data(api,
artist = None,
mbid = None):
params = {'method': 'artist.get_info'}
if not (artist or mbid):
raise InvalidParametersError("either artist or mbid has to be given as argument.")
if artist:
params.update({'artist': artist})
elif mbid:
params.update({'mbid': mbid})
return api._fetch_data(params).find('artist')
def _fill_info(self):
data = Artist._fetch_data(self.__api, self.name)
self.__name = data.findtext('name')
self.__mbid = data.findtext('mbid')
self.__url = data.findtext('url')
self.__image = dict([(i.get('size'), i.text) for i in data.findall('image')])
self.__streamable = (data.findtext('streamable') == 1)
self.__stats = Stats(
subject = self,
listeners = int(data.findtext('stats/listeners')),
playcount = int(data.findtext('stats/playcount'))
)
self.__similar = [
Artist(
self.__api,
subject = self,
name = a.findtext('name'),
url = a.findtext('url'),
image = dict([(i.get('size'), i.text) for i in a.findall('image')])
)
for a in data.findall('similar/artist')
]
self.__top_tags = [
Tag(
self.__api,
subject = self,
name = t.findtext('name'),
url = t.findtext('url')
)
for t in data.findall('tags/tag')
]
self.__bio = Wiki(
self,
published = datetime(*(time.strptime(
data.findtext('bio/published').strip(),
'%a, %d %b %Y %H:%M:%S +0000'
)[0:6])),
summary = data.findtext('bio/summary'),
content = data.findtext('bio/content')
)
@staticmethod
def get_info(api,
artist = None,
mbid = None):
data = Artist._fetch_data(api, artist, mbid)
a = Artist(api, name = data.findtext('name'))
a._fill_info()
return a
@staticmethod
def hash_func(*args, **kwds):
def _hash_func(*args, **kwds):
try:
return hash(kwds['name'].lower())
except KeyError:
@ -339,7 +338,7 @@ class Artist(LastfmBase, Taggable, Sharable, Searchable):
raise InvalidParametersError("name has to be provided for hashing")
def __hash__(self):
return self.__class__.hash_func(name = self.name)
return self.__class__._hash_func(name = self.name)
def __eq__(self, other):
if self.mbid and other.mbid:
@ -352,7 +351,7 @@ class Artist(LastfmBase, Taggable, Sharable, Searchable):
return self.name < other.name
def __repr__(self):
return "<lastfm.Artist: %s>" % self.__name
return "<lastfm.Artist: %s>" % self._name
from datetime import datetime
import time

View File

@ -20,21 +20,21 @@ class LastfmBase(object):
if 'subject' in kwds and not cls.__name__.startswith('Weekly'):
subject = kwds['subject']
del kwds['subject']
if 'bypassRegistry' in kwds:
del kwds['bypassRegistry']
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)
key = cls._hash_func(*args, **kwds)
if subject is not None:
key = (hash(subject), key)
LastfmBase._lock.acquire()
try:
inst, alreadyRegistered = LastfmBase.register(object.__new__(cls), key)
if not alreadyRegistered:
inst, already_registered = LastfmBase.register(object.__new__(cls), key)
if not already_registered:
inst.init(*args, **kwds)
finally:
LastfmBase._lock.release()
@ -52,34 +52,32 @@ class LastfmBase(object):
#print "not already registered: %s" % ob.__class__
LastfmBase.registry[ob.__class__][key] = ob
return (ob, False)
@staticmethod
def topProperty(listPropertyName):
@staticmethod
def top_property(list_property_name):
def decorator(func):
def wrapper(ob):
topList = getattr(ob, listPropertyName)
return (len(topList) and topList[0] or None)
top_list = getattr(ob, list_property_name)
return (len(top_list) and top_list[0] or None)
return property(fget = wrapper, doc = func.__doc__)
return decorator
@staticmethod
def cachedProperty(func):
frame = sys._getframe(1)
classname = frame.f_code.co_name
funcName = func.func_code.co_name
attributeName = "_%s__%s" % (classname, funcName)
def cached_property(func):
func_name = func.func_code.co_name
attribute_name = "_%s" % func_name
def wrapper(ob):
cacheAttribute = getattr(ob, attributeName, None)
if cacheAttribute is None:
cacheAttribute = func(ob)
setattr(ob, attributeName, cacheAttribute)
cache_attribute = getattr(ob, attribute_name, None)
if cache_attribute is None:
cache_attribute = func(ob)
setattr(ob, attribute_name, cache_attribute)
try:
cp = copy.copy(cacheAttribute)
cp = copy.copy(cache_attribute)
return cp
except Error:
return cacheAttribute
return cache_attribute
return property(fget = wrapper, doc = func.__doc__)
def __gt__(self, other):
@ -94,6 +92,5 @@ class LastfmBase(object):
def __le__(self, other):
return not self.__gt__(other)
import sys
import copy
from error import Error
from error import Error

View File

@ -10,16 +10,16 @@ class BaseError(Exception):
message = None,
code = None):
super(BaseError, self).__init__()
self.__code = code
self.__message = message
self._code = code
self._message = message
@property
def code(self):
return self.__code
return self._code
@property
def message(self):
return self.__message
return self._message
def __str__(self):
return "%s" % self.message
@ -65,7 +65,7 @@ class TokenNotAuthorizedError(BaseError):#14
class TokenExpiredError(BaseError):#15
pass
errorMap = {
error_map = {
1: Error,
2: InvalidServiceError,
3: InvalidMethodError,

View File

@ -12,7 +12,7 @@ class Event(LastfmBase, Sharable):
STATUS_ATTENDING = 0
STATUS_MAYBE = 1
STATUS_NOT = 2
def init(self,
api,
id = None,
@ -29,91 +29,83 @@ class Event(LastfmBase, Sharable):
if not isinstance(api, Api):
raise InvalidParametersError("api reference must be supplied as an argument")
Sharable.init(self, api)
self.__api = api
self.__id = id
self.__title = title
self.__artists = artists
self.__headliner = headliner
self.__venue = venue
self.__start_date = start_date
self.__description = description
self.__image = image
self.__url = url
self.__stats = stats and Stats(
self._api = api
self._id = id
self._title = title
self._artists = artists
self._headliner = headliner
self._venue = venue
self._start_date = start_date
self._description = description
self._image = image
self._url = url
self._stats = stats and Stats(
subject = self,
attendance = stats.attendance,
reviews = stats.reviews
)
self.__tag = tag
self._tag = tag
@property
def id(self):
"""id of the event"""
return self.__id
return self._id
@property
def title(self):
"""title of the event"""
return self.__title
return self._title
@property
def artists(self):
"""artists performing in the event"""
return self.__artists
return self._artists
@property
def headliner(self):
"""headliner artist of the event"""
return self.__headliner
return self._headliner
@property
def venue(self):
"""venue of the event"""
return self.__venue
return self._venue
@property
def start_date(self):
"""start date of the event"""
return self.__start_date
return self._start_date
@property
def description(self):
"""description of the event"""
return self.__description
return self._description
@property
def image(self):
"""poster of the event"""
return self.__image
return self._image
@property
def url(self):
"""url of the event's page"""
return self.__url
return self._url
@property
def stats(self):
"""stats of the event"""
return self.__stats
return self._stats
@property
def tag(self):
"""tags for the event"""
return self.__tag
return self._tag
def attend(self, status = STATUS_ATTENDING):
if status not in [Event.STATUS_ATTENDING, Event.STATUS_MAYBE, Event.STATUS_NOT]:
InvalidParametersError("status has to be 0, 1 or 2")
params = self._default_params({'method': 'event.attend', 'status': status})
self.__api._post_data(params)
def _default_params(self, extra_params = None):
if not self.id:
raise InvalidParametersError("id has to be provided.")
params = {'event': self.id}
if extra_params is not None:
params.update(extra_params)
return params
self._api._post_data(params)
@staticmethod
def get_info(api, event):
@ -171,7 +163,7 @@ class Event(LastfmBase, Sharable):
name = data.findtext('venue/location/country')
),
street = data.findtext('venue/location/street'),
postalCode = data.findtext('venue/location/postalcode'),
postal_code = data.findtext('venue/location/postalcode'),
latitude = float(data.findtext(
'venue/location/{%s}point/{%s}lat' % ((Location.XMLNS,)*2)
)),
@ -194,15 +186,22 @@ class Event(LastfmBase, Sharable):
tag = data.findtext('tag')
)
def _default_params(self, extra_params = []):
if not self.id:
raise InvalidParametersError("id has to be provided.")
params = {'event': self.id}
params.update(extra_params)
return params
@staticmethod
def hash_func(*args, **kwds):
def _hash_func(*args, **kwds):
try:
return hash(kwds['id'])
except KeyError:
raise InvalidParametersError("id has to be provided for hashing")
def __hash__(self):
return Event.hash_func(id = self.id)
return Event._hash_func(id = self.id)
def __eq__(self, other):
return self.id == other.id

View File

@ -18,28 +18,28 @@ class Geo(object):
params = {'method': 'geo.getEvents', 'location': location}
if distance is not None:
params.update({'distance': distance})
if latitude is not None and longitude is not None:
params.update({'latitude': latitude, 'longitude': longitude})
@lazylist
def gen(lst):
data = api._fetch_data(params).find('events')
totalPages = int(data.attrib['totalpages'])
total_pages = int(data.attrib['totalpages'])
@lazylist
def gen2(lst, data):
for e in data.findall('event'):
yield Event.create_from_data(api, e)
for e in gen2(data):
yield e
for page in xrange(2, totalPages+1):
for page in xrange(2, total_pages+1):
params.update({'page': page})
data = api._fetch_data(params).find('events')
for e in gen2(data):
yield e
yield e
return gen()
@staticmethod
@ -67,7 +67,7 @@ class Geo(object):
params = {'method': 'geo.getTopTracks', 'country': country}
if location is not None:
params.update({'location': location})
data = api._fetch_data(params).find('toptracks')
return [
Track(
@ -86,7 +86,7 @@ class Geo(object):
playcount = int(t.findtext('playcount'))
),
streamable = (t.findtext('streamable') == '1'),
fullTrack = (t.find('streamable').attrib['fulltrack'] == '1'),
full_track = (t.find('streamable').attrib['fulltrack'] == '1'),
url = 'http://' + t.findtext('url'),
image = {'large': t.findtext('image')}
)
@ -99,34 +99,34 @@ class Venue(LastfmBase):
name = None,
location = None,
url = None):
self.__name = name
self.__location = location
self.__url = url
self._name = name
self._location = location
self._url = url
@property
def name(self):
"""name of the venue"""
return self.__name
return self._name
@property
def location(self):
"""location of the event"""
return self.__location
return self._location
@property
def url(self):
"""url of the event's page"""
return self.__url
return self._url
@staticmethod
def hash_func(*args, **kwds):
def _hash_func(*args, **kwds):
try:
return hash(kwds['url'])
except KeyError:
raise InvalidParametersError("url has to be provided for hashing")
def __hash__(self):
return self.__class__.hash_func(url = self.url)
return self.__class__._hash_func(url = self.url)
def __eq__(self, other):
return self.url == other.url
@ -152,77 +152,77 @@ class Location(LastfmBase):
timezone = None):
if not isinstance(api, Api):
raise InvalidParametersError("api reference must be supplied as an argument")
self.__api = api
self.__city = city
self.__country = country
self.__street = street
self.__postalCode = postal_code
self.__latitude = latitude
self.__longitude = longitude
self.__timezone = timezone
self._api = api
self._city = city
self._country = country
self._street = street
self._postal_code = postal_code
self._latitude = latitude
self._longitude = longitude
self._timezone = timezone
@property
def city(self):
"""city in which the location is situated"""
return self.__city
return self._city
@property
def country(self):
"""country in which the location is situated"""
return self.__country
return self._country
@property
def street(self):
"""street in which the location is situated"""
return self.__street
return self._street
@property
def postalCode(self):
def postal_code(self):
"""postal code of the location"""
return self.__postalCode
return self._postal_code
@property
def latitude(self):
"""latitude of the location"""
return self.__latitude
return self._latitude
@property
def longitude(self):
"""longitude of the location"""
return self.__longitude
return self._longitude
@property
def timezone(self):
"""timezone in which the location is situated"""
return self.__timezone
@LastfmBase.cachedProperty
return self._timezone
@LastfmBase.cached_property
def top_tracks(self):
"""top tracks of the location"""
if self.country is None or self.city is None:
raise InvalidParametersError("country and city of this location are required for calling this method")
return Geo.get_top_tracks(self.__api, self.country.name, self.city)
@LastfmBase.topProperty("top_tracks")
return Geo.get_top_tracks(self._api, self.country.name, self.city)
@LastfmBase.top_property("top_tracks")
def top_track(self):
"""top track of the location"""
pass
def get_events(self,
distance = None):
return Geo.get_events(self.__api,
return Geo.get_events(self._api,
self.city,
self.latitude,
self.longitude,
distance)
@LastfmBase.cachedProperty
@LastfmBase.cached_property
def events(self):
"""events taking place at/around the location"""
return self.get_events()
@staticmethod
def hash_func(*args, **kwds):
def _hash_func(*args, **kwds):
try:
return hash("latlong%s%s" % (kwds['latitude'], kwds['longitude']))
except KeyError:
@ -233,11 +233,11 @@ class Location(LastfmBase):
def __hash__(self):
if not self.city:
return self.__class__.hash_func(
return self.__class__._hash_func(
latitude = self.latitude,
longitude = self.longitude)
else:
return self.__class__.hash_func(name = self.city)
return self.__class__._hash_func(name = self.city)
def __eq__(self, other):
return self.latitude == other.latitude and self.longitude == other.longitude
@ -261,51 +261,51 @@ class Country(LastfmBase):
name = None):
if not isinstance(api, Api):
raise InvalidParametersError("api reference must be supplied as an argument")
self.__api = api
self.__name = name
self._api = api
self._name = name
@property
def name(self):
"""name of the country"""
return self.__name
return self._name
@LastfmBase.cachedProperty
@LastfmBase.cached_property
def top_artists(self):
"""top artists of the country"""
return Geo.get_top_artists(self.__api, self.name)
@LastfmBase.topProperty("top_artists")
return Geo.get_top_artists(self._api, self.name)
@LastfmBase.top_property("top_artists")
def top_artist(self):
"""top artist of the country"""
pass
def get_top_tracks(self, location = None):
return Geo.get_top_tracks(self.__api, self.name, location)
@LastfmBase.cachedProperty
return Geo.get_top_tracks(self._api, self.name, location)
@LastfmBase.cached_property
def top_tracks(self):
"""top tracks of the country"""
return self.get_top_tracks()
@LastfmBase.topProperty("top_tracks")
@LastfmBase.top_property("top_tracks")
def top_track(self):
"""top track of the country"""
pass
@LastfmBase.cachedProperty
@LastfmBase.cached_property
def events(self):
"""events taking place at/around the location"""
return Geo.get_events(self.__api, self.name)
return Geo.get_events(self._api, self.name)
@staticmethod
def hash_func(*args, **kwds):
def _hash_func(*args, **kwds):
try:
return hash(kwds['name'])
except KeyError:
raise InvalidParametersError("name has to be provided for hashing")
def __hash__(self):
return self.__class__.hash_func(name = self.name)
return self.__class__._hash_func(name = self.name)
def __eq__(self, other):
return self.name == other.name

View File

@ -14,35 +14,35 @@ class Group(LastfmBase):
name = None):
if not isinstance(api, Api):
raise InvalidParametersError("api reference must be supplied as an argument")
self.__api = api
self.__name = name
self._api = api
self._name = name
@property
def name(self):
return self.__name
return self._name
@LastfmBase.cachedProperty
@LastfmBase.cached_property
def weekly_chart_list(self):
params = {'method': 'group.getWeeklyChartList', 'group': self.name}
data = self.__api._fetch_data(params).find('weeklychartlist')
params = self._default_params({'method': 'group.getWeeklyChartList'})
data = self._api._fetch_data(params).find('weeklychartlist')
return [
WeeklyChart.create_from_data(self.__api, self, c)
WeeklyChart.create_from_data(self._api, self, c)
for c in data.findall('chart')
]
def get_weekly_album_chart(self,
start = None,
end = None):
params = {'method': 'group.getWeeklyAlbumChart', 'group': self.name}
params = self._default_params({'method': 'group.getWeeklyAlbumChart'})
params = WeeklyChart._check_weekly_chart_params(params, start, end)
data = self.__api._fetch_data(params).find('weeklyalbumchart')
return WeeklyAlbumChart.create_from_data(self.__api, self, data)
data = self._api._fetch_data(params).find('weeklyalbumchart')
return WeeklyAlbumChart.create_from_data(self._api, self, data)
@LastfmBase.cachedProperty
@LastfmBase.cached_property
def recent_weekly_album_chart(self):
return self.get_weekly_album_chart()
@LastfmBase.cachedProperty
@LastfmBase.cached_property
def weekly_album_chart_list(self):
wcl = list(self.weekly_chart_list)
wcl.reverse()
@ -55,16 +55,16 @@ class Group(LastfmBase):
def get_weekly_artist_chart(self,
start = None,
end = None):
params = {'method': 'group.getWeeklyArtistChart', 'group': self.name}
params = self._default_params({'method': 'group.getWeeklyArtistChart'})
params = WeeklyChart._check_weekly_chart_params(params, start, end)
data = self.__api._fetch_data(params).find('weeklyartistchart')
return WeeklyArtistChart.create_from_data(self.__api, self, data)
data = self._api._fetch_data(params).find('weeklyartistchart')
return WeeklyArtistChart.create_from_data(self._api, self, data)
@LastfmBase.cachedProperty
@LastfmBase.cached_property
def recent_weekly_artist_chart(self):
return self.get_weekly_artist_chart()
@LastfmBase.cachedProperty
@LastfmBase.cached_property
def weekly_artist_chart_list(self):
wcl = list(self.weekly_chart_list)
wcl.reverse()
@ -77,16 +77,16 @@ class Group(LastfmBase):
def get_weekly_track_chart(self,
start = None,
end = None):
params = {'method': 'group.getWeeklyTrackChart', 'group': self.name}
params = self._default_params({'method': 'group.getWeeklyTrackChart'})
params = WeeklyChart._check_weekly_chart_params(params, start, end)
data = self.__api._fetch_data(params).find('weeklytrackchart')
return WeeklyTrackChart.create_from_data(self.__api, self, data)
data = self._api._fetch_data(params).find('weeklytrackchart')
return WeeklyTrackChart.create_from_data(self._api, self, data)
@LastfmBase.cachedProperty
@LastfmBase.cached_property
def recent_weekly_track_chart(self):
return self.get_weekly_track_chart()
@LastfmBase.cachedProperty
@LastfmBase.cached_property
def weekly_track_chart_list(self):
wcl = list(self.weekly_chart_list)
wcl.reverse()
@ -96,15 +96,22 @@ class Group(LastfmBase):
yield self.get_weekly_track_chart(wc.start, wc.end)
return gen()
def _default_params(self, extra_params = {}):
if not self.name:
raise InvalidParametersError("group has to be provided.")
params = {'group': self.name}
params.update(extra_params)
return params
@staticmethod
def hash_func(*args, **kwds):
def _hash_func(*args, **kwds):
try:
return hash(kwds['name'])
except KeyError:
raise InvalidParametersError("name has to be provided for hashing")
def __hash__(self):
return self.__class__.hash_func(name = self.name)
return self.__class__._hash_func(name = self.name)
def __eq__(self, other):
return self.name == other.name

View File

@ -9,36 +9,36 @@ from base import LastfmBase
class Playlist(LastfmBase):
"""A class representing an XPSF playlist."""
def init(self, api, url):
self.__api = api
self.__data = None
self.__url = url
self._api = api
self._data = None
self._url = url
@LastfmBase.cachedProperty
@LastfmBase.cached_property
def data(self):
"""playlist's data"""
params = {'method': 'playlist.fetch', 'playlistURL': self.__url}
params = {'method': 'playlist.fetch', 'playlistURL': self._url}
tmp = StringIO.StringIO()
ElementTree.ElementTree(self.__api._fetch_data(params)[0]).write(tmp)
ElementTree.ElementTree(self._api._fetch_data(params)[0]).write(tmp)
return tmp.getvalue()
@property
def url(self):
"""url of the playlist"""
return self.__url
return self._url
@staticmethod
def fetch(api, url):
return Playlist(api, url = url)
@staticmethod
def hash_func(*args, **kwds):
def _hash_func(*args, **kwds):
try:
return hash(kwds['url'])
except KeyError:
raise InvalidParametersError("url has to be provided for hashing")
def __hash__(self):
return self.__class__.hash_func(url = self.url)
return self.__class__._hash_func(url = self.url)
def __eq__(self, other):
return self.url == other.url
@ -50,11 +50,10 @@ class Playlist(LastfmBase):
return "<lastfm.Playlist: %s>" % self.url
import StringIO
import platform
import sys
from error import InvalidParametersError
python_version = platform.python_version_tuple()
if python_version[0] == 2 and python_version[1] >= 5:
if sys.version_info >= (2, 5):
import xml.etree.cElementTree as ElementTree
else:
try:

View File

@ -6,26 +6,26 @@ __license__ = "GNU Lesser General Public License"
import sys
class SafeList(object):
def __init__(self, lst, addFunc, removeFunc):
def __init__(self, lst, add_func, remove_func):
self._list = lst
self._addFunc = addFunc
self._removeFunc = removeFunc
self._add_func = add_func
self._remove_func = remove_func
def add(self, lst):
if not isinstance(lst, (list, tuple)):
lst = [lst]
self._addFunc(lst)
self._add_func(lst)
def remove(self, lst):
if not isinstance(lst, (list, tuple)):
lst = [lst]
for l in lst:
self._removeFunc(l)
self._remove_func(l)
def __iter__(self):
for i in xrange(len(self._list)):
yield self._list[i]
def _tuple_from_slice(self, i):
"""
Get (start, end, step) tuple from slice object.
@ -40,7 +40,7 @@ class SafeList(object):
step = None
return (start, end, step)
def __getitem__(self, i):
if isinstance(i, slice):
(start, end, step) = self._tuple_from_slice(i)
@ -51,7 +51,7 @@ class SafeList(object):
return [self._list[i] for i in indices]
else:
return self._list[i]
def index(self, x, i=0, j=None):
if i != 0 or j is not None:
(i, j, ignore) = self._tuple_from_slice(slice(i, j))
@ -61,10 +61,10 @@ class SafeList(object):
if self._list[k] == x:
return k
raise ValueError('index(x): x not in list')
# Define sort() as appropriate for the Python version.
if sys.version_info[:3] < (2, 4, 0):
def sort(self, cmpfunc=None):
def sort(self, cmpfunc=None):
ans = list(self._list)
ans.sort(cmpfunc)
self._list[:] = ans
@ -78,9 +78,9 @@ class SafeList(object):
else:
ans.sort(cmpfunc)
self._list[:] = ans
def __len__(self):
return len(self._list)
def __repr__(self):
return repr(self._list)
return repr(self._list)

View File

@ -24,28 +24,28 @@ class Searchable(object):
if limit:
params.update({'limit': limit})
@lazylist
def gen(lst):
data = api._fetch_data(params).find('results')
totalPages = int(data.findtext("{%s}totalResults" % Api.SEARCH_XMLNS))/ \
total_pages = int(data.findtext("{%s}totalResults" % Api.SEARCH_XMLNS))/ \
int(data.findtext("{%s}itemsPerPage" % Api.SEARCH_XMLNS)) + 1
@lazylist
def gen2(lst, data):
for a in data.findall('%smatches/%s'%(cls_name, cls_name)):
yield cls._search_yield_func(api, a)
for a in gen2(data):
yield a
for page in xrange(2, totalPages+1):
for page in xrange(2, total_pages+1):
params.update({'page': page})
data = api._fetch_data(params).find('results')
for a in gen2(data):
yield a
return gen()
@staticmethod
def _search_yield_func(api, search_term):
pass
pass

View File

@ -6,7 +6,7 @@ __license__ = "GNU Lesser General Public License"
class Sharable(object):
def init(self, api):
self.__api = api
self._api = api
def share(self, recipient, message = None):
from user import User
@ -21,4 +21,7 @@ class Sharable(object):
if isinstance(recipient[i], User):
recipient[i] = recipient[i].name
params['recipient'] = ",".join(recipient)
self.__api._post_data(params)
self._api._post_data(params)
def _default_params(self, extra_params = {}):
return extra_params

View File

@ -17,67 +17,67 @@ class Stats(object):
weight = None,
attendance = None,
reviews = None,):
self.__subject = subject
self.__listeners = listeners
self.__playcount = playcount
self.__tagcount = tagcount
self.__count = count
self.__match = match
self.__rank = rank
self.__weight = weight
self.__attendance = attendance
self.__reviews = reviews
self._subject = subject
self._listeners = listeners
self._playcount = playcount
self._tagcount = tagcount
self._count = count
self._match = match
self._rank = rank
self._weight = weight
self._attendance = attendance
self._reviews = reviews
@property
def subject(self):
"""subject of the stats"""
return self.__subject
return self._subject
@property
def rank(self):
"""rank of the subject"""
return self.__rank
return self._rank
@property
def listeners(self):
"""number of listeners of the subject"""
return self.__listeners
return self._listeners
@property
def playcount(self):
"""playcount of the subject"""
return self.__playcount
return self._playcount
@property
def tagcount(self):
"""tagcount of the subject"""
return self.__tagcount
return self._tagcount
@property
def count(self):
"""count of the subject"""
return self.__count
return self._count
@property
def match(self):
"""match of the subject"""
return self.__match
return self._match
@property
def weight(self):
"""weight of the subject"""
return self.__weight
return self._weight
@property
def attendance(self):
"""attendance of the subject"""
return self.__attendance
return self._attendance
@property
def reviews(self):
"""reviews of the subject"""
return self.__reviews
return self._reviews
def __repr__(self):
return "<lastfm.Stats: for '%s'>" % self.__subject.name
return "<lastfm.Stats: for '%s'>" % self._subject.name

View File

@ -18,42 +18,42 @@ class Tag(LastfmBase, Searchable):
stats = None):
if not isinstance(api, Api):
raise InvalidParametersError("api reference must be supplied as an argument")
self.__api = api
self.__name = name
self.__url = url
self.__streamable = streamable
self.__stats = stats and Stats(
self._api = api
self._name = name
self._url = url
self._streamable = streamable
self._stats = stats and Stats(
subject = self,
count = stats.count
)
@property
def name(self):
"""name of the tag"""
return self.__name
return self._name
@property
def url(self):
"""url of the tag's page"""
return self.__url
return self._url
@property
def streamable(self):
"""is the tag streamable"""
return self.__streamable
return self._streamable
@property
def stats(self):
return self.__stats
@LastfmBase.cachedProperty
return self._stats
@LastfmBase.cached_property
def similar(self):
"""tags similar to this tag"""
params = {'method': 'tag.getSimilar', 'tag': self.name}
data = self.__api._fetch_data(params).find('similartags')
params = self._default_params({'method': 'tag.getSimilar'})
data = self._api._fetch_data(params).find('similartags')
return [
Tag(
self.__api,
self._api,
subject = self,
name = t.findtext('name'),
url = t.findtext('url'),
@ -61,24 +61,24 @@ class Tag(LastfmBase, Searchable):
)
for t in data.findall('tag')
]
@LastfmBase.topProperty("similar")
@LastfmBase.top_property("similar")
def most_similar(self):
"""most similar tag to this tag"""
pass
@LastfmBase.cachedProperty
@LastfmBase.cached_property
def top_albums(self):
"""top albums for the tag"""
params = {'method': 'tag.getTopAlbums', 'tag': self.name}
data = self.__api._fetch_data(params).find('topalbums')
params = self._default_params({'method': 'tag.getTopAlbums'})
data = self._api._fetch_data(params).find('topalbums')
return [
Album(
self.__api,
self._api,
subject = self,
name = a.findtext('name'),
artist = Artist(
self.__api,
self._api,
subject = self,
name = a.findtext('artist/name'),
mbid = a.findtext('artist/mbid'),
@ -96,19 +96,19 @@ class Tag(LastfmBase, Searchable):
for a in data.findall('album')
]
@LastfmBase.topProperty("top_albums")
@LastfmBase.top_property("top_albums")
def top_album(self):
"""top album for the tag"""
pass
@LastfmBase.cachedProperty
@LastfmBase.cached_property
def top_artists(self):
"""top artists for the tag"""
params = {'method': 'tag.getTopArtists', 'tag': self.name}
data = self.__api._fetch_data(params).find('topartists')
params = self._default_params({'method': 'tag.getTopArtists'})
data = self._api._fetch_data(params).find('topartists')
return [
Artist(
self.__api,
self._api,
subject = self,
name = a.findtext('name'),
mbid = a.findtext('mbid'),
@ -124,23 +124,23 @@ class Tag(LastfmBase, Searchable):
for a in data.findall('artist')
]
@LastfmBase.topProperty("top_artists")
@LastfmBase.top_property("top_artists")
def top_artist(self):
"""top artist for the tag"""
pass
@LastfmBase.cachedProperty
@LastfmBase.cached_property
def top_tracks(self):
"""top tracks for the tag"""
params = {'method': 'tag.getTopTracks', 'tag': self.name}
data = self.__api._fetch_data(params).find('toptracks')
params = self._default_params({'method': 'tag.getTopTracks'})
data = self._api._fetch_data(params).find('toptracks')
return [
Track(
self.__api,
self._api,
subject = self,
name = t.findtext('name'),
artist = Artist(
self.__api,
self._api,
subject = self,
name = t.findtext('artist/name'),
mbid = t.findtext('artist/mbid'),
@ -153,22 +153,22 @@ class Tag(LastfmBase, Searchable):
tagcount = t.findtext('tagcount') and int(t.findtext('tagcount')) or None
),
streamable = (t.findtext('streamable') == '1'),
fullTrack = (t.find('streamable').attrib['fulltrack'] == '1'),
full_track = (t.find('streamable').attrib['fulltrack'] == '1'),
image = dict([(i.get('size'), i.text) for i in t.findall('image')]),
)
for t in data.findall('track')
]
@LastfmBase.topProperty("top_tracks")
@LastfmBase.top_property("top_tracks")
def top_track(self):
"""top track for the tag"""
pass
@LastfmBase.cachedProperty
@LastfmBase.cached_property
def playlist(self):
return Playlist.fetch(self.__api,
return Playlist.fetch(self._api,
"lastfm://playlist/tag/%s/freetracks" % self.name)
@staticmethod
def get_top_tags(api):
params = {'method': 'tag.getTopTags'}
@ -185,7 +185,14 @@ class Tag(LastfmBase, Searchable):
)
for t in data.findall('tag')
]
def _default_params(self, extra_params = {}):
if not self.name:
raise InvalidParametersError("tag has to be provided.")
params = {'tag': self.name}
params.update(extra_params)
return params
@staticmethod
def _search_yield_func(api, tag):
return Tag(
@ -197,23 +204,23 @@ class Tag(LastfmBase, Searchable):
count = int(tag.findtext('count')),
)
)
@staticmethod
def hash_func(*args, **kwds):
def _hash_func(*args, **kwds):
try:
return hash(kwds['name'])
except KeyError:
raise InvalidParametersError("name has to be provided for hashing")
def __hash__(self):
return self.__class__.hash_func(name = self.name)
return self.__class__._hash_func(name = self.name)
def __eq__(self, other):
return self.name == other.name
def __lt__(self, other):
return self.name < other.name
def __repr__(self):
return "<lastfm.Tag: %s>" % self.name
@ -223,4 +230,4 @@ from artist import Artist
from error import InvalidParametersError
from playlist import Playlist
from stats import Stats
from track import Track
from track import Track

View File

@ -9,16 +9,16 @@ from safelist import SafeList
class Taggable(object):
def init(self, api):
self.__api = api
self._api = api
@LastfmBase.cachedProperty
@LastfmBase.cached_property
def tags(self):
from tag import Tag
params = self._default_params({'method': '%s.getTags' % self.__class__.__name__.lower()})
data = self.__api._fetch_data(params, sign = True, session = True, no_cache = True).find('tags')
data = self._api._fetch_data(params, sign = True, session = True, no_cache = True).find('tags')
return SafeList([
Tag(
self.__api,
self._api,
name = t.findtext('name'),
url = t.findtext('url')
)
@ -46,8 +46,8 @@ class Taggable(object):
'method': '%s.addTags' % self.__class__.__name__.lower(),
'tags': ",".join(tagnames)
})
self.__api._post_data(params)
self.__tags = None
self._api._post_data(params)
self._tags = None
def remove_tag(self, tag):
from tag import Tag
@ -58,8 +58,8 @@ class Taggable(object):
'method': '%s.removeTag' % self.__class__.__name__.lower(),
'tag': tag
})
self.__api._post_data(params)
self.__tags = None
self._api._post_data(params)
self._tags = None
def _default_params(self, extra_params):
pass
def _default_params(self, extra_params = {}):
return extra_params

View File

@ -10,24 +10,24 @@ class Tasteometer(object):
score = None,
matches = None,
artists = None):
self.__score = score
self.__matches = matches
self.__artists = artists
self._score = score
self._matches = matches
self._artists = artists
@property
def score(self):
"""score of the comparison"""
return self.__score
return self._score
@property
def matches(self):
"""matches for the comparison"""
return self.__matches
return self._matches
@property
def artists(self):
"""artists for the comparison"""
return self.__artists
return self._artists
@staticmethod
def compare(api,

View File

@ -32,130 +32,122 @@ class Track(LastfmBase, Taggable, Sharable, Searchable):
raise InvalidParametersError("api reference must be supplied as an argument")
Taggable.init(self, api)
Sharable.init(self, api)
self.__api = api
self.__id = id
self.__name = name
self.__mbid = mbid
self.__url = url
self.__duration = duration
self.__streamable = streamable
self.__full_track = full_track
self.__artist = artist
self.__album = album
self.__position = position
self.__image = image
self.__stats = stats and Stats(
self._api = api
self._id = id
self._name = name
self._mbid = mbid
self._url = url
self._duration = duration
self._streamable = streamable
self._full_track = full_track
self._artist = artist
self._album = album
self._position = position
self._image = image
self._stats = stats and Stats(
subject = self,
match = stats.match,
playcount = stats.playcount,
rank = stats.rank,
listeners = stats.listeners,
)
self.__played_on = played_on
self.__loved_on = loved_on
self.__wiki = wiki and Wiki(
self._played_on = played_on
self._loved_on = loved_on
self._wiki = wiki and Wiki(
subject = self,
published = wiki.published,
summary = wiki.summary,
content = wiki.content
)
@property
def id(self):
"""id of the track"""
return self.__id
return self._id
@property
def name(self):
"""name of the track"""
return self.__name
return self._name
@property
def mbid(self):
"""mbid of the track"""
return self.__mbid
return self._mbid
@property
def url(self):
"""url of the tracks's page"""
return self.__url
return self._url
@property
def duration(self):
"""duration of the tracks's page"""
return self.__duration
return self._duration
@property
def streamable(self):
"""is the track streamable"""
if self.__streamable is None:
if self._streamable is None:
self._fill_info()
return self.__streamable
return self._streamable
@property
def full_track(self):
"""is the full track streamable"""
if self.__full_track is None:
if self._full_track is None:
self._fill_info()
return self.__full_track
return self._full_track
@property
def artist(self):
"""artist of the track"""
return self.__artist
return self._artist
@property
def album(self):
"""artist of the track"""
if self.__album is None:
if self._album is None:
self._fill_info()
return self.__album
return self._album
@property
def position(self):
"""position of the track"""
if self.__position is None:
if self._position is None:
self._fill_info()
return self.__position
return self._position
@property
def image(self):
"""image of the track's album cover"""
return self.__image
return self._image
@property
def stats(self):
"""stats of the track"""
return self.__stats
return self._stats
@property
def playedOn(self):
def played_on(self):
"""datetime the track was last played"""
return self.__played_on
return self._played_on
@property
def lovedOn(self):
def loved_on(self):
"""datetime the track was marked 'loved'"""
return self.__loved_on
return self._loved_on
@property
def wiki(self):
"""wiki of the track"""
if self.__wiki == "na":
if self._wiki == "na":
return None
if self.__wiki is None:
if self._wiki is None:
self._fill_info()
return self.__wiki
def _default_params(self, extra_params = None):
if not (self.artist and self.name):
raise InvalidParametersError("artist and track have to be provided.")
params = {'artist': self.artist.name, 'track': self.name}
if extra_params is not None:
params.update(extra_params)
return params
return self._wiki
@LastfmBase.cachedProperty
@LastfmBase.cached_property
def similar(self):
"""tracks similar to this track"""
params = Track._check_params(
@ -164,14 +156,14 @@ class Track(LastfmBase, Taggable, Sharable, Searchable):
self.name,
self.mbid
)
data = self.__api._fetch_data(params).find('similartracks')
data = self._api._fetch_data(params).find('similartracks')
return [
Track(
self.__api,
self._api,
subject = self,
name = t.findtext('name'),
artist = Artist(
self.__api,
self._api,
subject = self,
name = t.findtext('artist/name'),
mbid = t.findtext('artist/mbid'),
@ -183,18 +175,18 @@ class Track(LastfmBase, Taggable, Sharable, Searchable):
match = float(t.findtext('match'))
),
streamable = (t.findtext('streamable') == '1'),
fullTrack = (t.find('streamable').attrib['fulltrack'] == '1'),
full_track = (t.find('streamable').attrib['fulltrack'] == '1'),
image = dict([(i.get('size'), i.text) for i in t.findall('image')]),
)
for t in data.findall('track')
]
@LastfmBase.topProperty("similar")
@LastfmBase.top_property("similar")
def most_similar(self):
"""track most similar to this track"""
pass
@LastfmBase.cachedProperty
@LastfmBase.cached_property
def top_fans(self):
"""top fans of the track"""
params = Track._check_params(
@ -203,10 +195,10 @@ class Track(LastfmBase, Taggable, Sharable, Searchable):
self.name,
self.mbid
)
data = self.__api._fetch_data(params).find('topfans')
data = self._api._fetch_data(params).find('topfans')
return [
User(
self.__api,
self._api,
subject = self,
name = u.findtext('name'),
url = u.findtext('url'),
@ -219,12 +211,12 @@ class Track(LastfmBase, Taggable, Sharable, Searchable):
for u in data.findall('user')
]
@LastfmBase.topProperty("top_fans")
@LastfmBase.top_property("top_fans")
def top_fan(self):
"""topmost fan of the track"""
pass
@LastfmBase.cachedProperty
@LastfmBase.cached_property
def top_tags(self):
"""top tags for the track"""
params = Track._check_params(
@ -233,10 +225,10 @@ class Track(LastfmBase, Taggable, Sharable, Searchable):
self.name,
self.mbid
)
data = self.__api._fetch_data(params).find('toptags')
data = self._api._fetch_data(params).find('toptags')
return [
Tag(
self.__api,
self._api,
subject = self,
name = t.findtext('name'),
url = t.findtext('url'),
@ -248,89 +240,19 @@ class Track(LastfmBase, Taggable, Sharable, Searchable):
for t in data.findall('tag')
]
@LastfmBase.topProperty("top_tags")
@LastfmBase.top_property("top_tags")
def top_tag(self):
"""topmost tag for the track"""
pass
def love(self):
params = self._default_params({'method': 'track.love'})
self.__api._post_data(params)
self._api._post_data(params)
def ban(self):
params = self._default_params({'method': 'track.ban'})
self.__api._post_data(params)
self._api._post_data(params)
@staticmethod
def _search_yield_func(api, track):
return Track(
api,
name = track.findtext('name'),
artist = Artist(
api,
name=track.findtext('artist')
),
url = track.findtext('url'),
stats = Stats(
subject=track.findtext('name'),
listeners=int(track.findtext('listeners'))
),
streamable = (track.findtext('streamable') == '1'),
fullTrack = (track.find('streamable').attrib['fulltrack'] == '1'),
image = dict([(i.get('size'), i.text) for i in track.findall('image')]),
)
@staticmethod
def _fetch_data(api,
artist = None,
track = None,
mbid = None):
params = Track._check_params({'method': 'track.getInfo'}, artist, track, mbid)
return api._fetch_data(params).find('track')
def _fill_info(self):
data = Track._fetch_data(self.__api, self.artist.name, self.name)
self.__id = int(data.findtext('id'))
self.__mbid = data.findtext('mbid')
self.__url = data.findtext('url')
self.__duration = int(data.findtext('duration'))
self.__streamable = (data.findtext('streamable') == '1'),
self.__full_track = (data.find('streamable').attrib['fulltrack'] == '1'),
self.__image = dict([(i.get('size'), i.text) for i in data.findall('image')])
self.__stats = Stats(
subject = self,
listeners = int(data.findtext('listeners')),
playcount = int(data.findtext('playcount')),
)
self.__artist = Artist(
self.__api,
name = data.findtext('artist/name'),
mbid = data.findtext('artist/mbid'),
url = data.findtext('artist/url')
)
self.__album = Album(
self.__api,
artist = self.__artist,
name = data.findtext('album/title'),
mbid = data.findtext('album/mbid'),
url = data.findtext('album/url'),
image = dict([(i.get('size'), i.text) for i in data.findall('album/image')])
)
self.__position = int(data.find('album').attrib['position'])
if data.find('wiki') is not None:
self.__wiki = Wiki(
self,
published = datetime(*(time.strptime(
data.findtext('wiki/published').strip(),
'%a, %d %b %Y %H:%M:%S +0000'
)[0:6])),
summary = data.findtext('wiki/summary'),
content = data.findtext('wiki/content')
)
else:
self.__wiki = 'na'
@staticmethod
def get_info(api,
artist = None,
@ -348,6 +270,83 @@ class Track(LastfmBase, Taggable, Sharable, Searchable):
t._fill_info()
return t
def _default_params(self, extra_params = {}):
if not (self.artist and self.name):
raise InvalidParametersError("artist and track have to be provided.")
params = {'artist': self.artist.name, 'track': self.name}
params.update(extra_params)
return params
@staticmethod
def _search_yield_func(api, track):
return Track(
api,
name = track.findtext('name'),
artist = Artist(
api,
name=track.findtext('artist')
),
url = track.findtext('url'),
stats = Stats(
subject=track.findtext('name'),
listeners=int(track.findtext('listeners'))
),
streamable = (track.findtext('streamable') == '1'),
full_track = (track.find('streamable').attrib['fulltrack'] == '1'),
image = dict([(i.get('size'), i.text) for i in track.findall('image')]),
)
@staticmethod
def _fetch_data(api,
artist = None,
track = None,
mbid = None):
params = Track._check_params({'method': 'track.getInfo'}, artist, track, mbid)
return api._fetch_data(params).find('track')
def _fill_info(self):
data = Track._fetch_data(self._api, self.artist.name, self.name)
self._id = int(data.findtext('id'))
self._mbid = data.findtext('mbid')
self._url = data.findtext('url')
self._duration = int(data.findtext('duration'))
self._streamable = (data.findtext('streamable') == '1'),
self._full_track = (data.find('streamable').attrib['fulltrack'] == '1'),
self._image = dict([(i.get('size'), i.text) for i in data.findall('image')])
self._stats = Stats(
subject = self,
listeners = int(data.findtext('listeners')),
playcount = int(data.findtext('playcount')),
)
self._artist = Artist(
self._api,
name = data.findtext('artist/name'),
mbid = data.findtext('artist/mbid'),
url = data.findtext('artist/url')
)
self._album = Album(
self._api,
artist = self._artist,
name = data.findtext('album/title'),
mbid = data.findtext('album/mbid'),
url = data.findtext('album/url'),
image = dict([(i.get('size'), i.text) for i in data.findall('album/image')])
)
self._position = int(data.find('album').attrib['position'])
if data.find('wiki') is not None:
self._wiki = Wiki(
self,
published = datetime(*(time.strptime(
data.findtext('wiki/published').strip(),
'%a, %d %b %Y %H:%M:%S +0000'
)[0:6])),
summary = data.findtext('wiki/summary'),
content = data.findtext('wiki/content')
)
else:
self._wiki = 'na'
@staticmethod
def _check_params(params,
artist = None,
@ -363,14 +362,14 @@ class Track(LastfmBase, Taggable, Sharable, Searchable):
return params
@staticmethod
def hash_func(*args, **kwds):
def _hash_func(*args, **kwds):
try:
return hash("%s%s" % (kwds['name'], hash(kwds['artist'])))
except KeyError:
raise InvalidParametersError("name and artist have to be provided for hashing")
def __hash__(self):
return self.__class__.hash_func(name = self.name, artist = self.artist)
return self.__class__._hash_func(name = self.name, artist = self.artist)
def __eq__(self, other):
if self.mbid and other.mbid:
@ -397,4 +396,4 @@ from error import InvalidParametersError
from stats import Stats
from tag import Tag
from user import User
from wiki import Wiki
from wiki import Wiki

View File

@ -23,117 +23,117 @@ class User(LastfmBase):
subscriber = None):
if not isinstance(api, Api):
raise InvalidParametersError("api reference must be supplied as an argument")
self.__api = api
self.__name = name
self.__url = url
self.__image = image
self.__stats = stats and Stats(
self._api = api
self._name = name
self._url = url
self._image = image
self._stats = stats and Stats(
subject = self,
match = stats.match,
weight = stats.weight,
playcount = stats.playcount
)
self.__library = User.Library(api, self)
self.__language = language
self.__country = country
self.__age = age
self.__gender = gender
self.__subscriber = subscriber
self._library = User.Library(api, self)
self._language = language
self._country = country
self._age = age
self._gender = gender
self._subscriber = subscriber
@property
def name(self):
"""name of the user"""
return self.__name
return self._name
@property
def url(self):
"""url of the user's page"""
return self.__url
return self._url
@property
def image(self):
"""image of the user"""
return self.__image
return self._image
@property
def stats(self):
"""stats for the user"""
return self.__stats
return self._stats
@property
def language(self):
"""lang for the user"""
return self.__language
return self._language
@property
def country(self):
"""country for the user"""
return self.__country
return self._country
@property
def age(self):
"""age for the user"""
return self.__age
return self._age
@property
def gender(self):
"""stats for the user"""
return self.__gender
return self._gender
@property
def subscriber(self):
"""is the user a subscriber"""
return self.__subscriber
return self._subscriber
@LastfmBase.cachedProperty
@LastfmBase.cached_property
def events(self):
params = {'method': 'user.getEvents', 'user': self.name}
data = self.__api._fetch_data(params).find('events')
params = self._default_params({'method': 'user.getEvents'})
data = self._api._fetch_data(params).find('events')
return [
Event.create_from_data(self.__api, e)
Event.create_from_data(self._api, e)
for e in data.findall('event')
]
def get_past_events(self,
limit = None):
params = {'method': 'user.getPastEvents', 'user': self.name}
params = self._default_params({'method': 'user.getPastEvents'})
if limit is not None:
params.update({'limit': limit})
@lazylist
def gen(lst):
data = self.__api._fetch_data(params).find('events')
totalPages = int(data.attrib['totalPages'])
data = self._api._fetch_data(params).find('events')
total_pages = int(data.attrib['totalPages'])
@lazylist
def gen2(lst, data):
for e in data.findall('event'):
yield Event.create_from_data(self.__api, e)
yield Event.create_from_data(self._api, e)
for e in gen2(data):
yield e
for page in xrange(2, totalPages+1):
for page in xrange(2, total_pages+1):
params.update({'page': page})
data = self.__api._fetch_data(params).find('events')
data = self._api._fetch_data(params).find('events')
for e in gen2(data):
yield e
yield e
return gen()
@LastfmBase.cachedProperty
@LastfmBase.cached_property
def past_events(self):
return self.get_past_events()
def get_friends(self,
limit = None):
params = {'method': 'user.getFriends', 'user': self.name}
params = self._default_params({'method': 'user.getFriends'})
if limit is not None:
params.update({'limit': limit})
data = self.__api._fetch_data(params).find('friends')
data = self._api._fetch_data(params).find('friends')
return [
User(
self.__api,
self._api,
subject = self,
name = u.findtext('name'),
image = dict([(i.get('size'), i.text) for i in u.findall('image')]),
@ -143,19 +143,19 @@ class User(LastfmBase):
]
@LastfmBase.cachedProperty
@LastfmBase.cached_property
def friends(self):
"""friends of the user"""
return self.get_friends()
def get_neighbours(self, limit = None):
params = {'method': 'user.getNeighbours', 'user': self.name}
params = self._default_params({'method': 'user.getNeighbours'})
if limit is not None:
params.update({'limit': limit})
data = self.__api._fetch_data(params).find('neighbours')
data = self._api._fetch_data(params).find('neighbours')
return [
User(
self.__api,
self._api,
subject = self,
name = u.findtext('name'),
image = {'medium': u.findtext('image')},
@ -168,24 +168,24 @@ class User(LastfmBase):
for u in data.findall('user')
]
@LastfmBase.cachedProperty
@LastfmBase.cached_property
def neighbours(self):
"""neighbours of the user"""
return self.get_neighbours()
@LastfmBase.topProperty("neighbours")
@LastfmBase.top_property("neighbours")
def nearest_neighbour(self):
"""nearest neightbour of the user"""
pass
@LastfmBase.cachedProperty
@LastfmBase.cached_property
def playlists(self):
"""playlists of the user"""
params = {'method': 'user.getPlaylists', 'user': self.name}
data = self.__api._fetch_data(params).find('playlists')
params = self._default_params({'method': 'user.getPlaylists'})
data = self._api._fetch_data(params).find('playlists')
return [
User.Playlist(
self.__api,
self._api,
id = int(p.findtext('id')),
title = p.findtext('title'),
date = datetime(*(
@ -200,17 +200,17 @@ class User(LastfmBase):
for p in data.findall('playlist')
]
@LastfmBase.cachedProperty
@LastfmBase.cached_property
def loved_tracks(self):
params = {'method': 'user.getLovedTracks', 'user': self.name}
data = self.__api._fetch_data(params).find('lovedtracks')
params = self._default_params({'method': 'user.getLovedTracks'})
data = self._api._fetch_data(params).find('lovedtracks')
return [
Track(
self.__api,
self._api,
subject = self,
name = t.findtext('name'),
artist = Artist(
self.__api,
self._api,
subject = self,
name = t.findtext('artist/name'),
mbid = t.findtext('artist/mbid'),
@ -218,7 +218,7 @@ class User(LastfmBase):
),
mbid = t.findtext('mbid'),
image = dict([(i.get('size'), i.text) for i in t.findall('image')]),
lovedOn = datetime(*(
loved_on = datetime(*(
time.strptime(
t.findtext('date').strip(),
'%d %b %Y, %H:%M'
@ -227,27 +227,27 @@ class User(LastfmBase):
)
for t in data.findall('track')
]
def get_recent_tracks(self, limit = None):
params = {'method': 'user.getRecentTracks', 'user': self.name}
data = self.__api._fetch_data(params, no_cache = True).find('recenttracks')
params = self._default_params({'method': 'user.getRecentTracks'})
data = self._api._fetch_data(params, no_cache = True).find('recenttracks')
return [
Track(
self.__api,
self._api,
subject = self,
name = t.findtext('name'),
artist = Artist(
self.__api,
self._api,
subject = self,
name = t.findtext('artist'),
mbid = t.find('artist').attrib['mbid'],
),
album = Album(
self.__api,
self._api,
subject = self,
name = t.findtext('album'),
artist = Artist(
self.__api,
self._api,
subject = self,
name = t.findtext('artist'),
mbid = t.find('artist').attrib['mbid'],
@ -258,7 +258,7 @@ class User(LastfmBase):
streamable = (t.findtext('streamable') == '1'),
url = t.findtext('url'),
image = dict([(i.get('size'), i.text) for i in t.findall('image')]),
playedOn = datetime(*(
played_on = datetime(*(
time.strptime(
t.findtext('date').strip(),
'%d %b %Y, %H:%M'
@ -273,24 +273,24 @@ class User(LastfmBase):
"""recent tracks played by the user"""
return self.get_recent_tracks()
@LastfmBase.topProperty("recent_tracks")
@LastfmBase.top_property("recent_tracks")
def most_recent_track(self):
"""most recent track played by the user"""
pass
def get_top_albums(self, period = None):
params = {'method': 'user.getTopAlbums', 'user': self.name}
params = self._default_params({'method': 'user.getTopAlbums'})
if period is not None:
params.update({'period': period})
data = self.__api._fetch_data(params).find('topalbums')
data = self._api._fetch_data(params).find('topalbums')
return [
Album(
self.__api,
self._api,
subject = self,
name = a.findtext('name'),
artist = Artist(
self.__api,
self._api,
subject = self,
name = a.findtext('artist/name'),
mbid = a.findtext('artist/mbid'),
@ -308,25 +308,25 @@ class User(LastfmBase):
for a in data.findall('album')
]
@LastfmBase.cachedProperty
@LastfmBase.cached_property
def top_albums(self):
"""overall top albums of the user"""
return self.get_top_albums()
@LastfmBase.topProperty("top_albums")
@LastfmBase.top_property("top_albums")
def top_album(self):
"""overall top most album of the user"""
pass
def get_top_artists(self, period = None):
params = {'method': 'user.getTopArtists', 'user': self.name}
params = self._default_params({'method': 'user.getTopArtists'})
if period is not None:
params.update({'period': period})
data = self.__api._fetch_data(params).find('topartists')
data = self._api._fetch_data(params).find('topartists')
return [
Artist(
self.__api,
self._api,
subject = self,
name = a.findtext('name'),
mbid = a.findtext('mbid'),
@ -342,28 +342,28 @@ class User(LastfmBase):
for a in data.findall('artist')
]
@LastfmBase.cachedProperty
@LastfmBase.cached_property
def top_artists(self):
"""top artists of the user"""
return self.get_top_artists()
@LastfmBase.topProperty("top_artists")
@LastfmBase.top_property("top_artists")
def top_artist(self):
"""top artist of the user"""
pass
def get_top_tracks(self, period = None):
params = {'method': 'user.getTopTracks', 'user': self.name}
params = self._default_params({'method': 'user.getTopTracks'})
if period is not None:
params.update({'period': period})
data = self.__api._fetch_data(params).find('toptracks')
data = self._api._fetch_data(params).find('toptracks')
return [
Track(
self.__api,
self._api,
subject = self,
name = t.findtext('name'),
artist = Artist(
self.__api,
self._api,
subject = self,
name = t.findtext('artist/name'),
mbid = t.findtext('artist/mbid'),
@ -376,30 +376,30 @@ class User(LastfmBase):
playcount = t.findtext('playcount') and int(t.findtext('playcount')) or None
),
streamable = (t.findtext('streamable') == '1'),
fullTrack = (t.find('streamable').attrib['fulltrack'] == '1'),
full_track = (t.find('streamable').attrib['fulltrack'] == '1'),
image = dict([(i.get('size'), i.text) for i in t.findall('image')]),
)
for t in data.findall('track')
]
@LastfmBase.cachedProperty
@LastfmBase.cached_property
def top_tracks(self):
"""top tracks of the user"""
return self.get_top_tracks()
@LastfmBase.topProperty("top_tracks")
@LastfmBase.top_property("top_tracks")
def top_track(self):
"""top track of the user"""
return (len(self.top_tracks) and self.top_tracks[0] or None)
def get_top_tags(self, limit = None):
params = {'method': 'user.getTopTags', 'user': self.name}
params = self._default_params({'method': 'user.getTopTags'})
if limit is not None:
params.update({'limit': limit})
data = self.__api._fetch_data(params).find('toptags')
data = self._api._fetch_data(params).find('toptags')
return [
Tag(
self.__api,
self._api,
subject = self,
name = t.findtext('name'),
url = t.findtext('url'),
@ -407,42 +407,42 @@ class User(LastfmBase):
subject = t.findtext('name'),
count = int(t.findtext('count'))
)
)
)
for t in data.findall('tag')
]
@LastfmBase.cachedProperty
@LastfmBase.cached_property
def top_tags(self):
"""top tags of the user"""
return self.get_top_tags()
@LastfmBase.topProperty("top_tags")
@LastfmBase.top_property("top_tags")
def top_tag(self):
"""top tag of the user"""
pass
@LastfmBase.cachedProperty
@LastfmBase.cached_property
def weekly_chart_list(self):
params = {'method': 'user.getWeeklyChartList', 'user': self.name}
data = self.__api._fetch_data(params).find('weeklychartlist')
params = self._default_params({'method': 'user.getWeeklyChartList'})
data = self._api._fetch_data(params).find('weeklychartlist')
return [
WeeklyChart.create_from_data(self.__api, self, c)
WeeklyChart.create_from_data(self._api, self, c)
for c in data.findall('chart')
]
def get_weekly_album_chart(self,
start = None,
end = None):
params = {'method': 'user.getWeeklyAlbumChart', 'user': self.name}
params = WeeklyChart._check_weekly_chart_params(params, start, end)
data = self.__api._fetch_data(params).find('weeklyalbumchart')
return WeeklyAlbumChart.create_from_data(self.__api, self, data)
params = self._default_params({'method': 'user.getWeeklyAlbumChart'})
params = WeeklyChart._check_weekly_chart_params(params, start, end)
data = self._api._fetch_data(params).find('weeklyalbumchart')
return WeeklyAlbumChart.create_from_data(self._api, self, data)
@LastfmBase.cachedProperty
@LastfmBase.cached_property
def recent_weekly_album_chart(self):
return self.get_weekly_album_chart()
@LastfmBase.cachedProperty
@LastfmBase.cached_property
def weekly_album_chart_list(self):
wcl = list(self.weekly_chart_list)
wcl.reverse()
@ -458,16 +458,16 @@ class User(LastfmBase):
def get_weekly_artist_chart(self,
start = None,
end = None):
params = {'method': 'user.getWeeklyArtistChart', 'user': self.name}
params = self._default_params({'method': 'user.getWeeklyArtistChart'})
params = WeeklyChart._check_weekly_chart_params(params, start, end)
data = self.__api._fetch_data(params).find('weeklyartistchart')
return WeeklyArtistChart.create_from_data(self.__api, self, data)
data = self._api._fetch_data(params).find('weeklyartistchart')
return WeeklyArtistChart.create_from_data(self._api, self, data)
@LastfmBase.cachedProperty
@LastfmBase.cached_property
def recent_weekly_artist_chart(self):
return self.get_weekly_artist_chart()
@LastfmBase.cachedProperty
@LastfmBase.cached_property
def weekly_artist_chart_list(self):
wcl = list(self.weekly_chart_list)
wcl.reverse()
@ -483,16 +483,16 @@ class User(LastfmBase):
def get_weekly_track_chart(self,
start = None,
end = None):
params = {'method': 'user.getWeeklyTrackChart', 'user': self.name}
params = self._default_params({'method': 'user.getWeeklyTrackChart'})
params = WeeklyChart._check_weekly_chart_params(params, start, end)
data = self.__api._fetch_data(params).find('weeklytrackchart')
return WeeklyTrackChart.create_from_data(self.__api, self, data)
data = self._api._fetch_data(params).find('weeklytrackchart')
return WeeklyTrackChart.create_from_data(self._api, self, data)
@LastfmBase.cachedProperty
@LastfmBase.cached_property
def recent_weekly_track_chart(self):
return self.get_weekly_track_chart()
@LastfmBase.cachedProperty
@LastfmBase.cached_property
def weekly_track_chart_list(self):
wcl = list(self.weekly_chart_list)
wcl.reverse()
@ -504,16 +504,16 @@ class User(LastfmBase):
except Error:
pass
return gen()
def compare(self, other, limit = None):
return Tasteometer.compare(self.__api,
return Tasteometer.compare(self._api,
'user', 'user',
self.name, other.name,
limit)
@property
def library(self):
return self.__library
return self._library
@staticmethod
def get_authenticated_user(api):
data = api._fetch_data({'method': 'user.getInfo'}, sign = True, session = True).find('user')
@ -532,15 +532,22 @@ class User(LastfmBase):
)
)
def _default_params(self, extra_params = {}):
if not self.name:
raise InvalidParametersError("user has to be provided.")
params = {'user': self.name}
params.update(extra_params)
return params
@staticmethod
def hash_func(*args, **kwds):
def _hash_func(*args, **kwds):
try:
return hash(kwds['name'])
except KeyError:
raise InvalidParametersError("name has to be provided for hashing")
def __hash__(self):
return self.__class__.hash_func(name = self.name)
return self.__class__._hash_func(name = self.name)
def __eq__(self, other):
return self.name == other.name
@ -550,89 +557,89 @@ class User(LastfmBase):
def __repr__(self):
return "<lastfm.User: %s>" % self.name
class Playlist(playlist.Playlist):
"""A class representing a playlist belonging to the user."""
def init(self, api, id, title, date, size, creator):
super(User.Playlist, self).init(api, "lastfm://playlist/%s" % id)
self.__id = id
self.__title = title
self.__date = date
self.__size = size
self.__creator = creator
self._id = id
self._title = title
self._date = date
self._size = size
self._creator = creator
@property
def id(self):
return self.__id
return self._id
@property
def title(self):
return self.__title
return self._title
@property
def date(self):
return self.__date
return self._date
@property
def size(self):
return self.__size
return self._size
@property
def creator(self):
return self.__creator
def addTrack(self, track):
return self._creator
def add_track(self, track):
params = {'method': 'playlist.addTrack', 'playlistID': self.id}
if not isinstance(track, Track):
track = self.__api.search_track(track)[0]
track = self._api.search_track(track)[0]
params['artist'] = track.artist.name
params['track'] = track.name
self.__api._post_data(params)
self._api._post_data(params)
@staticmethod
def hash_func(*args, **kwds):
def _hash_func(*args, **kwds):
try:
return hash(kwds['id'])
except KeyError:
raise InvalidParametersError("id has to be provided for hashing")
def __hash__(self):
return self.__class__.hash_func(id = self.id)
return self.__class__._hash_func(id = self.id)
def __repr__(self):
return "<lastfm.User.Playlist: %s>" % self.title
class Library(object):
"""A class representing the music library of the user."""
def __init__(self, api, user):
self.__api = api
self.__user = user
self._api = api
self._user = user
@property
def user(self):
return self.__user
return self._user
def get_albums(self,
limit = None):
params = {'method': 'library.getAlbums', 'user': self.user.name}
params = self._default_params({'method': 'library.getAlbums'})
if limit is not None:
params.update({'limit': limit})
@lazylist
def gen(lst):
data = self.__api._fetch_data(params).find('albums')
data = self._api._fetch_data(params).find('albums')
total_pages = int(data.attrib['totalPages'])
@lazylist
def gen2(lst, data):
for a in data.findall('album'):
yield Album(
self.__api,
self._api,
subject = self,
name = a.findtext('name'),
artist = Artist(
self.__api,
self._api,
subject = self,
name = a.findtext('artist/name'),
mbid = a.findtext('artist/mbid'),
@ -646,41 +653,41 @@ class User(LastfmBase):
playcount = int(a.findtext('playcount')),
)
)
for a in gen2(data):
yield a
for page in xrange(2, total_pages+1):
params.update({'page': page})
try:
data = self.__api._fetch_data(params).find('albums')
data = self._api._fetch_data(params).find('albums')
except Error:
continue
for a in gen2(data):
yield a
yield a
return gen()
@LastfmBase.cachedProperty
@LastfmBase.cached_property
def albums(self):
return self.get_albums()
def get_artists(self,
limit = None):
params = {'method': 'library.getArtists', 'user': self.user.name}
params = self._default_params({'method': 'library.getArtists'})
if limit is not None:
params.update({'limit': limit})
@lazylist
def gen(lst):
data = self.__api._fetch_data(params).find('artists')
data = self._api._fetch_data(params).find('artists')
total_pages = int(data.attrib['totalPages'])
@lazylist
def gen2(lst, data):
for a in data.findall('artist'):
yield Artist(
self.__api,
self._api,
subject = self,
name = a.findtext('name'),
mbid = a.findtext('mbid'),
@ -692,45 +699,45 @@ class User(LastfmBase):
url = a.findtext('url'),
streamable = (a.findtext('streamable') == "1"),
image = dict([(i.get('size'), i.text) for i in a.findall('image')]),
)
)
for a in gen2(data):
yield a
for page in xrange(2, total_pages+1):
params.update({'page': page})
try:
data = self.__api._fetch_data(params).find('artists')
data = self._api._fetch_data(params).find('artists')
except Error:
continue
for a in gen2(data):
yield a
yield a
return gen()
@LastfmBase.cachedProperty
@LastfmBase.cached_property
def artists(self):
return self.get_artists()
def get_tracks(self,
limit = None):
params = {'method': 'library.getTracks', 'user': self.user.name}
params = self._default_params({'method': 'library.getTracks'})
if limit is not None:
params.update({'limit': limit})
@lazylist
def gen(lst):
data = self.__api._fetch_data(params).find('tracks')
totalPages = int(data.attrib['totalPages'])
data = self._api._fetch_data(params).find('tracks')
total_pages = int(data.attrib['totalPages'])
@lazylist
def gen2(lst, data):
for t in data.findall('track'):
yield Track(
self.__api,
self._api,
subject = self,
name = t.findtext('name'),
artist = Artist(
self.__api,
self._api,
subject = self,
name = t.findtext('artist/name'),
mbid = t.findtext('artist/mbid'),
@ -743,38 +750,45 @@ class User(LastfmBase):
tagcount = t.findtext('tagcount') and int(t.findtext('tagcount')) or None
),
streamable = (t.findtext('streamable') == '1'),
fullTrack = (t.find('streamable').attrib['fulltrack'] == '1'),
full_track = (t.find('streamable').attrib['fulltrack'] == '1'),
image = dict([(i.get('size'), i.text) for i in t.findall('image')]),
)
)
for t in gen2(data):
yield t
for page in xrange(2, totalPages+1):
for page in xrange(2, total_pages+1):
params.update({'page': page})
data = None
try:
data = self.__api._fetch_data(params).find('tracks')
data = self._api._fetch_data(params).find('tracks')
except Error:
continue
for t in gen2(data):
yield t
yield t
return gen()
@LastfmBase.cachedProperty
@LastfmBase.cached_property
def tracks(self):
return self.get_tracks()
def _default_params(self, extra_params = {}):
if not self.user.name:
raise InvalidParametersError("user has to be provided.")
params = {'user': self.user.name}
params.update(extra_params)
return params
@staticmethod
def hash_func(*args, **kwds):
def _hash_func(*args, **kwds):
try:
return hash(kwds['user'])
except KeyError:
raise InvalidParametersError("user has to be provided for hashing")
def __hash__(self):
return self.__class__.hash_func(user = self.user)
return self.__class__._hash_func(user = self.user)
def __repr__(self):
return "<lastfm.User.Library: for user '%s'>" % self.user.name
@ -791,4 +805,4 @@ from stats import Stats
from tag import Tag
from tasteometer import Tasteometer
from track import Track
from weeklychart import WeeklyChart, WeeklyAlbumChart, WeeklyArtistChart, WeeklyTrackChart
from weeklychart import WeeklyChart, WeeklyAlbumChart, WeeklyArtistChart, WeeklyTrackChart

View File

@ -11,26 +11,26 @@ class WeeklyChart(LastfmBase):
def init(self, subject, start, end,
stats = None):
self.__subject = subject
self.__start = start
self.__end = end
self.__stats = stats
self._subject = subject
self._start = start
self._end = end
self._stats = stats
@property
def subject(self):
return self.__subject
return self._subject
@property
def start(self):
return self.__start
return self._start
@property
def end(self):
return self.__end
return self._end
@property
def stats(self):
return self.__stats
return self._stats
@staticmethod
def create_from_data(api, subject, data):
@ -56,7 +56,7 @@ class WeeklyChart(LastfmBase):
return params
@staticmethod
def hash_func(*args, **kwds):
def _hash_func(*args, **kwds):
try:
return hash("%s%s%s%s" % (
kwds['subject'].__class__.__name__,
@ -68,7 +68,7 @@ class WeeklyChart(LastfmBase):
raise InvalidParametersError("subject, start and end have to be provided for hashing")
def __hash__(self):
return self.__class__.hash_func(
return self.__class__._hash_func(
subject = self.subject,
start = self.start,
end = self.end
@ -102,11 +102,11 @@ class WeeklyAlbumChart(WeeklyChart):
"""A class for representing the weekly album charts"""
def init(self, subject, start, end, stats, albums):
super(WeeklyAlbumChart, self).init(subject, start, end, stats)
self.__albums = albums
self._albums = albums
@property
def albums(self):
return self.__albums
return self._albums
@staticmethod
def create_from_data(api, subject, data):
@ -156,11 +156,11 @@ class WeeklyArtistChart(WeeklyChart):
"""A class for representing the weekly artist charts"""
def init(self, subject, start, end, stats, artists):
super(WeeklyArtistChart, self).init(subject, start, end, stats)
self.__artists = artists
self._artists = artists
@property
def artists(self):
return self.__artists
return self._artists
@staticmethod
def create_from_data(api, subject, data):
@ -204,11 +204,11 @@ class WeeklyTrackChart(WeeklyChart):
"""A class for representing the weekly track charts"""
def init(self, subject, start, end, tracks, stats):
super(WeeklyTrackChart, self).init(subject, start, end, stats)
self.__tracks = tracks
self._tracks = tracks
@property
def tracks(self):
return self.__tracks
return self._tracks
@staticmethod
def create_from_data(api, subject, data):

View File

@ -11,30 +11,30 @@ class Wiki(object):
published = None,
summary = None,
content = None):
self.__subject = subject
self.__published = published
self.__summary = summary
self.__content = content
self._subject = subject
self._published = published
self._summary = summary
self._content = content
@property
def subject(self):
"""artist for which the biography is"""
return self.__subject
return self._subject
@property
def published(self):
"""publication time of the biography"""
return self.__published
return self._published
@property
def summary(self):
"""summary of the biography"""
return self.__summary
return self._summary
@property
def content(self):
"""content of the biography"""
return self.__content
return self._content
def __repr__(self):
return "<lastfm.Wiki: for %s '%s'>" % (self.subject.__class__.__name__, self.subject.name)