created wiki module. added some new methods in Track class. some minor debugging.
This commit is contained in:
parent
2b02a84b87
commit
7d25f64788
|
@ -169,8 +169,7 @@ class Album(LastfmBase):
|
|||
name = data.findtext('artist'),
|
||||
),
|
||||
)
|
||||
if a.id is None:
|
||||
a._fillInfo()
|
||||
a._fillInfo()
|
||||
return a
|
||||
|
||||
@staticmethod
|
||||
|
|
15
src/api.py
15
src/api.py
|
@ -144,15 +144,10 @@ class Api(object):
|
|||
limit = None):
|
||||
return Tasteometer.compare(self, type1, type2, value1, value2, limit)
|
||||
|
||||
def getTrack(self, track, artist):
|
||||
def getTrack(self, track, artist = None, mbid = None):
|
||||
if isinstance(artist, Artist):
|
||||
artist = artist.name
|
||||
result = Track.search(self, track, artist)
|
||||
try:
|
||||
result[0]
|
||||
except IndexError:
|
||||
raise LastfmInvalidResourceError("'%s' by %s: no such track found" % (track, artist))
|
||||
return result[0]
|
||||
return Track.getInfo(self, artist, track, mbid)
|
||||
|
||||
def searchTrack(self,
|
||||
track,
|
||||
|
@ -209,6 +204,8 @@ class Api(object):
|
|||
|
||||
def _GetOpener(self, url):
|
||||
opener = self._urllib.build_opener()
|
||||
if self._urllib._opener is not None:
|
||||
opener = self._urllib.build_opener(*self._urllib._opener.handlers)
|
||||
opener.addheaders = self._request_headers.items()
|
||||
return opener
|
||||
|
||||
|
@ -233,7 +230,9 @@ class Api(object):
|
|||
if parameters is None:
|
||||
return None
|
||||
else:
|
||||
return urllib.urlencode(dict([(k, self._Encode(v)) for k, v in parameters.items() if v is not None]))
|
||||
keys = parameters.keys()
|
||||
keys.sort()
|
||||
return urllib.urlencode([(k, self._Encode(parameters[k])) for k in keys if parameters[k] is not None])
|
||||
|
||||
def _ReadUrlData(self, opener, url, data = None):
|
||||
now = datetime.now()
|
||||
|
|
|
@ -37,8 +37,8 @@ class Artist(LastfmBase):
|
|||
)
|
||||
self.__similar = similar
|
||||
self.__topTags = topTags
|
||||
self.__bio = bio and Artist.Bio(
|
||||
artist = self,
|
||||
self.__bio = bio and Wiki(
|
||||
subject = self,
|
||||
published = bio.published,
|
||||
summary = bio.summary,
|
||||
content = bio.content
|
||||
|
@ -324,7 +324,7 @@ class Artist(LastfmBase):
|
|||
)
|
||||
for t in data.findall('tags/tag')
|
||||
]
|
||||
self.__bio = Artist.Bio(
|
||||
self.__bio = Wiki(
|
||||
self,
|
||||
published = datetime(*(time.strptime(
|
||||
data.findtext('bio/published').strip(),
|
||||
|
@ -341,8 +341,7 @@ class Artist(LastfmBase):
|
|||
data = Artist._fetchData(api, artist, mbid)
|
||||
|
||||
a = Artist(api, name = data.findtext('name'))
|
||||
if a.bio is None:
|
||||
a._fillInfo()
|
||||
a._fillInfo()
|
||||
return a
|
||||
|
||||
@staticmethod
|
||||
|
@ -371,41 +370,6 @@ class Artist(LastfmBase):
|
|||
def __repr__(self):
|
||||
return "<lastfm.Artist: %s>" % self.__name
|
||||
|
||||
class Bio(object):
|
||||
"""A class representing the biography of an artist."""
|
||||
def __init__(self,
|
||||
artist,
|
||||
published = None,
|
||||
summary = None,
|
||||
content = None):
|
||||
self.__artist = artist
|
||||
self.__published = published
|
||||
self.__summary = summary
|
||||
self.__content = content
|
||||
|
||||
@property
|
||||
def artist(self):
|
||||
"""artist for which the biography is"""
|
||||
return self.__artist
|
||||
|
||||
@property
|
||||
def published(self):
|
||||
"""publication time of the biography"""
|
||||
return self.__published
|
||||
|
||||
@property
|
||||
def summary(self):
|
||||
"""summary of the biography"""
|
||||
return self.__summary
|
||||
|
||||
@property
|
||||
def content(self):
|
||||
"""content of the biography"""
|
||||
return self.__content
|
||||
|
||||
def __repr__(self):
|
||||
return "<lastfm.artist.Bio: for artist '%s'>" % self.__artist.name
|
||||
|
||||
from datetime import datetime
|
||||
import time
|
||||
|
||||
|
@ -417,3 +381,4 @@ from stats import Stats
|
|||
from tag import Tag
|
||||
from track import Track
|
||||
from user import User
|
||||
from wiki import Wiki
|
||||
|
|
|
@ -74,7 +74,11 @@ class LastfmBase(object):
|
|||
if cacheAttribute is None:
|
||||
cacheAttribute = func(ob)
|
||||
setattr(ob, attributeName, cacheAttribute)
|
||||
return copy.copy(cacheAttribute)
|
||||
try:
|
||||
cp = copy.copy(cacheAttribute)
|
||||
return cp
|
||||
except LastfmError:
|
||||
return cacheAttribute
|
||||
|
||||
return property(fget = wrapper, doc = func.__doc__)
|
||||
|
||||
|
@ -92,3 +96,4 @@ class LastfmBase(object):
|
|||
|
||||
import sys
|
||||
import copy
|
||||
from error import LastfmError
|
168
src/track.py
168
src/track.py
|
@ -14,23 +14,30 @@ class Track(LastfmBase):
|
|||
name = None,
|
||||
mbid = None,
|
||||
url = None,
|
||||
duration = None,
|
||||
streamable = None,
|
||||
fullTrack = None,
|
||||
artist = None,
|
||||
album = None,
|
||||
position = None,
|
||||
image = None,
|
||||
stats = None,
|
||||
fullTrack = None,
|
||||
playedOn = None,
|
||||
lovedOn = None):
|
||||
lovedOn = None,
|
||||
wiki = None):
|
||||
if not isinstance(api, Api):
|
||||
raise LastfmInvalidParametersError("api reference must be supplied as an argument")
|
||||
self.__api = api
|
||||
self.__id = id
|
||||
self.__name = name
|
||||
self.__mbid = mbid
|
||||
self.__url = url
|
||||
self.__duration = duration
|
||||
self.__streamable = streamable
|
||||
self.__fullTrack = fullTrack
|
||||
self.__artist = artist
|
||||
self.__album = album
|
||||
self.__position = position
|
||||
self.__image = image
|
||||
self.__stats = stats and Stats(
|
||||
subject = self,
|
||||
|
@ -39,10 +46,19 @@ class Track(LastfmBase):
|
|||
rank = stats.rank,
|
||||
listeners = stats.listeners,
|
||||
)
|
||||
self.__fullTrack = fullTrack
|
||||
self.__playedOn = playedOn
|
||||
self.__lovedOn = lovedOn
|
||||
self.__tags = None
|
||||
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
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
|
@ -59,11 +75,25 @@ class Track(LastfmBase):
|
|||
"""url of the tracks's page"""
|
||||
return self.__url
|
||||
|
||||
@property
|
||||
def duration(self):
|
||||
"""duration of the tracks's page"""
|
||||
return self.__duration
|
||||
|
||||
@property
|
||||
def streamable(self):
|
||||
"""is the track streamable"""
|
||||
if self.__streamable is None:
|
||||
self._fillInfo()
|
||||
return self.__streamable
|
||||
|
||||
@property
|
||||
def fullTrack(self):
|
||||
"""is the full track streamable"""
|
||||
if self.__fullTrack is None:
|
||||
self._fillInfo()
|
||||
return self.__fullTrack
|
||||
|
||||
@property
|
||||
def artist(self):
|
||||
"""artist of the track"""
|
||||
|
@ -72,8 +102,17 @@ class Track(LastfmBase):
|
|||
@property
|
||||
def album(self):
|
||||
"""artist of the track"""
|
||||
if self.__album is None:
|
||||
self._fillInfo()
|
||||
return self.__album
|
||||
|
||||
@property
|
||||
def position(self):
|
||||
"""position of the track"""
|
||||
if self.__position is None:
|
||||
self._fillInfo()
|
||||
return self.__position
|
||||
|
||||
@property
|
||||
def image(self):
|
||||
"""image of the track's album cover"""
|
||||
|
@ -84,11 +123,6 @@ class Track(LastfmBase):
|
|||
"""stats of the track"""
|
||||
return self.__stats
|
||||
|
||||
@property
|
||||
def fullTrack(self):
|
||||
"""is the full track streamable"""
|
||||
return self.__fullTrack
|
||||
|
||||
@property
|
||||
def playedOn(self):
|
||||
"""datetime the track was last played"""
|
||||
|
@ -99,6 +133,15 @@ class Track(LastfmBase):
|
|||
"""datetime the track was marked 'loved'"""
|
||||
return self.__lovedOn
|
||||
|
||||
@property
|
||||
def wiki(self):
|
||||
"""wiki of the track"""
|
||||
if self.__wiki == "na":
|
||||
return None
|
||||
if self.__wiki is None:
|
||||
self._fillInfo()
|
||||
return self.__wiki
|
||||
|
||||
def __checkParams(self,
|
||||
params,
|
||||
artist = None,
|
||||
|
@ -213,21 +256,19 @@ class Track(LastfmBase):
|
|||
|
||||
@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 = 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
|
||||
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')
|
||||
return SafeList([
|
||||
Tag(
|
||||
self.__api,
|
||||
name = t.findtext('name'),
|
||||
url = t.findtext('url')
|
||||
)
|
||||
for t in data.findall('tag')
|
||||
],
|
||||
self.addTags, self.removeTag)
|
||||
|
||||
def addTags(self, tags):
|
||||
while(len(tags) > 10):
|
||||
|
@ -336,6 +377,80 @@ class Track(LastfmBase):
|
|||
yield t
|
||||
return gen()
|
||||
|
||||
@staticmethod
|
||||
def _fetchData(api,
|
||||
artist = None,
|
||||
track = None,
|
||||
mbid = None):
|
||||
params = {'method': 'track.getInfo'}
|
||||
if not ((artist and track) or mbid):
|
||||
raise LastfmInvalidParametersError("either (artist and track) or mbid has to be given as argument.")
|
||||
if artist and track:
|
||||
params.update({'artist': artist, 'track': track})
|
||||
elif mbid:
|
||||
params.update({'mbid': mbid})
|
||||
return api._fetchData(params).find('track')
|
||||
|
||||
def _fillInfo(self):
|
||||
data = Track._fetchData(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.__fullTrack = (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 getInfo(api,
|
||||
artist = None,
|
||||
track = None,
|
||||
mbid = None):
|
||||
data = Track._fetchData(api, artist, track, mbid)
|
||||
t = Track(
|
||||
api,
|
||||
name = data.findtext('name'),
|
||||
artist = Artist(
|
||||
api,
|
||||
name = data.findtext('artist/name'),
|
||||
),
|
||||
)
|
||||
t._fillInfo()
|
||||
return t
|
||||
|
||||
@staticmethod
|
||||
def hashFunc(*args, **kwds):
|
||||
try:
|
||||
|
@ -361,10 +476,15 @@ class Track(LastfmBase):
|
|||
def __repr__(self):
|
||||
return "<lastfm.Track: '%s' by %s>" % (self.name, self.artist.name)
|
||||
|
||||
import time
|
||||
from datetime import datetime
|
||||
|
||||
from api import Api
|
||||
from artist import Artist
|
||||
from album import Album
|
||||
from error import LastfmInvalidParametersError
|
||||
from safelist import SafeList
|
||||
from stats import Stats
|
||||
from tag import Tag
|
||||
from user import User
|
||||
from wiki import Wiki
|
16
src/user.py
16
src/user.py
|
@ -590,7 +590,10 @@ class User(LastfmBase):
|
|||
|
||||
for page in xrange(2, totalPages+1):
|
||||
params.update({'page': page})
|
||||
data = self.__api._fetchData(params).find('albums')
|
||||
try:
|
||||
data = self.__api._fetchData(params).find('albums')
|
||||
except LastfmError:
|
||||
continue
|
||||
for a in gen2(data):
|
||||
yield a
|
||||
return gen()
|
||||
|
@ -633,7 +636,10 @@ class User(LastfmBase):
|
|||
|
||||
for page in xrange(2, totalPages+1):
|
||||
params.update({'page': page})
|
||||
data = self.__api._fetchData(params).find('artists')
|
||||
try:
|
||||
data = self.__api._fetchData(params).find('artists')
|
||||
except LastfmError:
|
||||
continue
|
||||
for a in gen2(data):
|
||||
yield a
|
||||
return gen()
|
||||
|
@ -683,7 +689,11 @@ class User(LastfmBase):
|
|||
|
||||
for page in xrange(2, totalPages+1):
|
||||
params.update({'page': page})
|
||||
data = self.__api._fetchData(params).find('tracks')
|
||||
data = None
|
||||
try:
|
||||
data = self.__api._fetchData(params).find('tracks')
|
||||
except LastfmError:
|
||||
continue
|
||||
for t in gen2(data):
|
||||
yield t
|
||||
return gen()
|
||||
|
|
Loading…
Reference in New Issue