created SafeList class for safe access and operations to some list type attributes. implemented some more auth methods in track.py

master
Abhinav Sarkar 2008-09-03 18:51:44 +00:00
parent fd7d7f1b12
commit 74f4803661
5 changed files with 146 additions and 31 deletions

View File

@ -298,22 +298,18 @@ class Api(object):
sign = False,
session = False,
no_cache = False):
params.update({'api_key': self.apiKey})
params['api_key'] = self.apiKey
if session:
params.update({'sk': self.sessionKey})
if self.sessionKey is not None:
params['sk'] = self.sessionKey
else:
raise LastfmAuthenticationFailedError("session key must be present to call this method")
if sign:
keys = params.keys()[:]
keys.sort()
sig = unicode()
for name in keys:
sig += (name + params[name])
sig += self.secret
hashed_sig = md5.new(sig).hexdigest()
params.update({'api_sig': hashed_sig})
params['api_sig'] = self._getApiSig(params)
xml = self._fetchUrl(Api.API_ROOT_URL, params, no_cache = self._no_cache or no_cache)
return self._checkXML(xml)
def _postUrl(self,
@ -328,19 +324,29 @@ class Api(object):
return url_data
def _postData(self, params):
params.update({'api_key': self.apiKey, 'sk': self.sessionKey})
params['api_key'] = self.apiKey
keys = params.keys()[:]
keys.sort()
sig = unicode()
for name in keys:
sig += (name + params[name])
sig += self.secret
hashed_sig = md5.new(sig).hexdigest()
params.update({'api_sig': hashed_sig})
if self.sessionKey is not None:
params['sk'] = self.sessionKey
else:
raise LastfmAuthenticationFailedError("session key must be present to call this method")
params['api_sig'] = self._getApiSig(params)
xml = self._postUrl(Api.API_ROOT_URL, params)
return self._checkXML(xml)
def _getApiSig(self, params):
if self.secret is not None:
keys = params.keys()[:]
keys.sort()
sig = unicode()
for name in keys:
sig += (name + params[name])
sig += self.secret
hashed_sig = md5.new(sig).hexdigest()
return hashed_sig
else:
raise LastfmAuthenticationFailedError("api secret must be present to call this method")
def _checkXML(self, xml):
data = None
@ -370,7 +376,7 @@ import urlparse
from album import Album
from artist import Artist
from error import errorMap, LastfmError, LastfmOperationFailedError, LastfmInvalidResourceError
from error import errorMap, LastfmError, LastfmOperationFailedError, LastfmInvalidResourceError, LastfmAuthenticationFailedError
from event import Event
from filecache import FileCache
from geo import Location, Country

View File

@ -104,14 +104,14 @@ class Artist(LastfmBase):
)
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:
return self.getSimilar()
return self.__similar
return self.__similar[:]
@LastfmBase.topProperty("similar")
def mostSimilar(self):
@ -136,7 +136,7 @@ class Artist(LastfmBase):
)
for t in data.findall('tag')
]
return self.__topTags
return self.__topTags[:]
@LastfmBase.topProperty("topTags")
def topTag(self):

View File

@ -74,7 +74,7 @@ class LastfmBase(object):
if cacheAttribute is None:
cacheAttribute = func(ob)
setattr(ob, attributeName, cacheAttribute)
return cacheAttribute
return copy.copy(cacheAttribute)
return property(fget = wrapper, doc = func.__doc__)
@ -90,4 +90,5 @@ class LastfmBase(object):
def __le__(self, other):
return not self.__gt__(other)
import sys
import sys
import copy

86
src/safelist.py Normal file
View File

@ -0,0 +1,86 @@
#!/usr/bin/env python
__author__ = "Abhinav Sarkar <abhinav@abhinavsarkar.net>"
__version__ = "0.2"
__license__ = "GNU Lesser General Public License"
import sys
class SafeList(object):
def __init__(self, lst, addFunc, removeFunc):
self._list = lst
self._addFunc = addFunc
self._removeFunc = removeFunc
def add(self, lst):
if not isinstance(lst, (list, tuple)):
lst = [lst]
self._addFunc(lst)
def remove(self, lst):
if not isinstance(lst, (list, tuple)):
lst = [lst]
for l in lst:
self._removeFunc(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.
"""
(start, end, step) = i.indices(len(self._list))
# Replace (0, -1, 1) with (0, 0, 1) (misfeature in .indices()).
if step == 1:
if end < start:
end = start
step = None
if i.step == None:
step = None
return (start, end, step)
def __getitem__(self, i):
if isinstance(i, slice):
(start, end, step) = self._tuple_from_slice(i)
if step == None:
indices = xrange(start, end)
else:
indices = xrange(start, end, step)
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))
if j is None:
j = len(self)
for k in xrange(i, j):
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):
ans = list(self._list)
ans.sort(cmpfunc)
self._list[:] = ans
else:
def sort(self, cmpfunc=None, key=None, reverse=False):
ans = list(self._list)
if reverse == True:
ans.sort(cmpfunc, key, reverse)
elif key != None:
ans.sort(cmpfunc, key)
else:
ans.sort(cmpfunc)
self._list[:] = ans
def __len__(self):
return len(self._list)
def __repr__(self):
return repr(self._list)

View File

@ -211,20 +211,22 @@ class Track(LastfmBase):
"""topmost tag for the track"""
pass
def getTags(self):
@LastfmBase.cachedProperty
def tags(self):
if self.__tags is None:
if not (self.artist and self.name):
raise LastfmInvalidParametersError("artist and track name have to be provided.")
params = {'method': 'track.getTags', 'artist': self.artist.name, 'track': self.name}
data = self.__api._fetchData(params, sign = True, session = True, no_cache = True).find('tags')
self.__tags = [
self.__tags = SafeList([
Tag(
self.__api,
name = t.findtext('name'),
url = t.findtext('url')
)
for t in data.findall('tag')
]
],
self.addTags, self.removeTag)
return self.__tags
def addTags(self, tags):
@ -267,6 +269,25 @@ class Track(LastfmBase):
def love(self):
params = {'method': 'track.love', 'artist': self.artist.name, 'track': self.name}
self.__api._postData(params)
def ban(self):
params = {'method': 'track.ban', 'artist': self.artist.name, 'track': self.name}
self.__api._postData(params)
def share(self, recipient, message = None):
params = {
'method': 'track.share',
'artist': self.artist.name,
'track': self.name
}
if message is not None:
params['message'] = message
for i in xrange(len(recipient)):
if isinstance(recipient[i], User):
recipient[i] = recipient[i].name
params['recipient'] = ",".join(recipient)
self.__api._postData(params)
@staticmethod
def search(api,
@ -343,6 +364,7 @@ class Track(LastfmBase):
from api import Api
from artist import Artist
from error import LastfmInvalidParametersError
from safelist import SafeList
from stats import Stats
from tag import Tag
from user import User
from user import User