created wiki module. added some new methods in Track class. some minor debugging.

This commit is contained in:
Abhinav Sarkar 2008-09-16 19:44:14 +00:00
parent 2b02a84b87
commit 7d25f64788
6 changed files with 178 additions and 80 deletions

View File

@ -169,7 +169,6 @@ class Album(LastfmBase):
name = data.findtext('artist'), name = data.findtext('artist'),
), ),
) )
if a.id is None:
a._fillInfo() a._fillInfo()
return a return a

View File

@ -144,15 +144,10 @@ class Api(object):
limit = None): limit = None):
return Tasteometer.compare(self, type1, type2, value1, value2, limit) 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): if isinstance(artist, Artist):
artist = artist.name artist = artist.name
result = Track.search(self, track, artist) return Track.getInfo(self, artist, track, mbid)
try:
result[0]
except IndexError:
raise LastfmInvalidResourceError("'%s' by %s: no such track found" % (track, artist))
return result[0]
def searchTrack(self, def searchTrack(self,
track, track,
@ -209,6 +204,8 @@ class Api(object):
def _GetOpener(self, url): def _GetOpener(self, url):
opener = self._urllib.build_opener() 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() opener.addheaders = self._request_headers.items()
return opener return opener
@ -233,7 +230,9 @@ class Api(object):
if parameters is None: if parameters is None:
return None return None
else: 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): def _ReadUrlData(self, opener, url, data = None):
now = datetime.now() now = datetime.now()

View File

@ -37,8 +37,8 @@ class Artist(LastfmBase):
) )
self.__similar = similar self.__similar = similar
self.__topTags = topTags self.__topTags = topTags
self.__bio = bio and Artist.Bio( self.__bio = bio and Wiki(
artist = self, subject = self,
published = bio.published, published = bio.published,
summary = bio.summary, summary = bio.summary,
content = bio.content content = bio.content
@ -324,7 +324,7 @@ class Artist(LastfmBase):
) )
for t in data.findall('tags/tag') for t in data.findall('tags/tag')
] ]
self.__bio = Artist.Bio( self.__bio = Wiki(
self, self,
published = datetime(*(time.strptime( published = datetime(*(time.strptime(
data.findtext('bio/published').strip(), data.findtext('bio/published').strip(),
@ -341,7 +341,6 @@ class Artist(LastfmBase):
data = Artist._fetchData(api, artist, mbid) data = Artist._fetchData(api, artist, mbid)
a = Artist(api, name = data.findtext('name')) a = Artist(api, name = data.findtext('name'))
if a.bio is None:
a._fillInfo() a._fillInfo()
return a return a
@ -371,41 +370,6 @@ class Artist(LastfmBase):
def __repr__(self): def __repr__(self):
return "<lastfm.Artist: %s>" % self.__name 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 from datetime import datetime
import time import time
@ -417,3 +381,4 @@ from stats import Stats
from tag import Tag from tag import Tag
from track import Track from track import Track
from user import User from user import User
from wiki import Wiki

View File

@ -74,7 +74,11 @@ class LastfmBase(object):
if cacheAttribute is None: if cacheAttribute is None:
cacheAttribute = func(ob) cacheAttribute = func(ob)
setattr(ob, attributeName, cacheAttribute) 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__) return property(fget = wrapper, doc = func.__doc__)
@ -92,3 +96,4 @@ class LastfmBase(object):
import sys import sys
import copy import copy
from error import LastfmError

View File

@ -14,23 +14,30 @@ class Track(LastfmBase):
name = None, name = None,
mbid = None, mbid = None,
url = None, url = None,
duration = None,
streamable = None, streamable = None,
fullTrack = None,
artist = None, artist = None,
album = None, album = None,
position = None,
image = None, image = None,
stats = None, stats = None,
fullTrack = None,
playedOn = None, playedOn = None,
lovedOn = None): lovedOn = None,
wiki = None):
if not isinstance(api, Api): if not isinstance(api, Api):
raise LastfmInvalidParametersError("api reference must be supplied as an argument") raise LastfmInvalidParametersError("api reference must be supplied as an argument")
self.__api = api self.__api = api
self.__id = id
self.__name = name self.__name = name
self.__mbid = mbid self.__mbid = mbid
self.__url = url self.__url = url
self.__duration = duration
self.__streamable = streamable self.__streamable = streamable
self.__fullTrack = fullTrack
self.__artist = artist self.__artist = artist
self.__album = album self.__album = album
self.__position = position
self.__image = image self.__image = image
self.__stats = stats and Stats( self.__stats = stats and Stats(
subject = self, subject = self,
@ -39,10 +46,19 @@ class Track(LastfmBase):
rank = stats.rank, rank = stats.rank,
listeners = stats.listeners, listeners = stats.listeners,
) )
self.__fullTrack = fullTrack
self.__playedOn = playedOn self.__playedOn = playedOn
self.__lovedOn = lovedOn 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 @property
def name(self): def name(self):
@ -59,11 +75,25 @@ class Track(LastfmBase):
"""url of the tracks's page""" """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
@property @property
def streamable(self): def streamable(self):
"""is the track streamable""" """is the track streamable"""
if self.__streamable is None:
self._fillInfo()
return self.__streamable return self.__streamable
@property
def fullTrack(self):
"""is the full track streamable"""
if self.__fullTrack is None:
self._fillInfo()
return self.__fullTrack
@property @property
def artist(self): def artist(self):
"""artist of the track""" """artist of the track"""
@ -72,8 +102,17 @@ class Track(LastfmBase):
@property @property
def album(self): def album(self):
"""artist of the track""" """artist of the track"""
if self.__album is None:
self._fillInfo()
return self.__album return self.__album
@property
def position(self):
"""position of the track"""
if self.__position is None:
self._fillInfo()
return self.__position
@property @property
def image(self): def image(self):
"""image of the track's album cover""" """image of the track's album cover"""
@ -84,11 +123,6 @@ class Track(LastfmBase):
"""stats of the track""" """stats of the track"""
return self.__stats return self.__stats
@property
def fullTrack(self):
"""is the full track streamable"""
return self.__fullTrack
@property @property
def playedOn(self): def playedOn(self):
"""datetime the track was last played""" """datetime the track was last played"""
@ -99,6 +133,15 @@ class Track(LastfmBase):
"""datetime the track was marked 'loved'""" """datetime the track was marked 'loved'"""
return self.__lovedOn 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, def __checkParams(self,
params, params,
artist = None, artist = None,
@ -213,12 +256,11 @@ class Track(LastfmBase):
@LastfmBase.cachedProperty @LastfmBase.cachedProperty
def tags(self): def tags(self):
if self.__tags is None:
if not (self.artist and self.name): if not (self.artist and self.name):
raise LastfmInvalidParametersError("artist and track name have to be provided.") raise LastfmInvalidParametersError("artist and track name have to be provided.")
params = {'method': 'track.getTags', 'artist': self.artist.name, 'track': self.name} 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') data = self.__api._fetchData(params, sign = True, session = True, no_cache = True).find('tags')
self.__tags = SafeList([ return SafeList([
Tag( Tag(
self.__api, self.__api,
name = t.findtext('name'), name = t.findtext('name'),
@ -227,7 +269,6 @@ class Track(LastfmBase):
for t in data.findall('tag') for t in data.findall('tag')
], ],
self.addTags, self.removeTag) self.addTags, self.removeTag)
return self.__tags
def addTags(self, tags): def addTags(self, tags):
while(len(tags) > 10): while(len(tags) > 10):
@ -336,6 +377,80 @@ class Track(LastfmBase):
yield t yield t
return gen() 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 @staticmethod
def hashFunc(*args, **kwds): def hashFunc(*args, **kwds):
try: try:
@ -361,10 +476,15 @@ class Track(LastfmBase):
def __repr__(self): def __repr__(self):
return "<lastfm.Track: '%s' by %s>" % (self.name, self.artist.name) return "<lastfm.Track: '%s' by %s>" % (self.name, self.artist.name)
import time
from datetime import datetime
from api import Api from api import Api
from artist import Artist from artist import Artist
from album import Album
from error import LastfmInvalidParametersError from error import LastfmInvalidParametersError
from safelist import SafeList from safelist import SafeList
from stats import Stats from stats import Stats
from tag import Tag from tag import Tag
from user import User from user import User
from wiki import Wiki

View File

@ -590,7 +590,10 @@ class User(LastfmBase):
for page in xrange(2, totalPages+1): for page in xrange(2, totalPages+1):
params.update({'page': page}) params.update({'page': page})
try:
data = self.__api._fetchData(params).find('albums') data = self.__api._fetchData(params).find('albums')
except LastfmError:
continue
for a in gen2(data): for a in gen2(data):
yield a yield a
return gen() return gen()
@ -633,7 +636,10 @@ class User(LastfmBase):
for page in xrange(2, totalPages+1): for page in xrange(2, totalPages+1):
params.update({'page': page}) params.update({'page': page})
try:
data = self.__api._fetchData(params).find('artists') data = self.__api._fetchData(params).find('artists')
except LastfmError:
continue
for a in gen2(data): for a in gen2(data):
yield a yield a
return gen() return gen()
@ -683,7 +689,11 @@ class User(LastfmBase):
for page in xrange(2, totalPages+1): for page in xrange(2, totalPages+1):
params.update({'page': page}) params.update({'page': page})
data = None
try:
data = self.__api._fetchData(params).find('tracks') data = self.__api._fetchData(params).find('tracks')
except LastfmError:
continue
for t in gen2(data): for t in gen2(data):
yield t yield t
return gen() return gen()