created SafeList class for safe access and operations to some list type attributes. implemented some more auth methods in track.py
This commit is contained in:
parent
fd7d7f1b12
commit
74f4803661
50
src/api.py
50
src/api.py
@ -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
|
||||
|
@ -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):
|
||||
|
@ -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
86
src/safelist.py
Normal 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)
|
30
src/track.py
30
src/track.py
@ -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
|
Loading…
Reference in New Issue
Block a user