Package lastfm :: Module artist
[hide private]
[frames] | no frames]

Source Code for Module lastfm.artist

  1  #!/usr/bin/env python 
  2  """Module for calling Artist related last.fm web services API methods""" 
  3   
  4  __author__ = "Abhinav Sarkar <abhinav@abhinavsarkar.net>" 
  5  __version__ = "0.2" 
  6  __license__ = "GNU Lesser General Public License" 
  7   
  8  from lastfm.base import LastfmBase 
  9  from lastfm.mixins import Cacheable, Searchable, Sharable, Shoutable, Taggable 
 10  from lastfm.lazylist import lazylist 
 11  from lastfm.decorators import cached_property, top_property 
12 13 -class Artist(LastfmBase, Cacheable, Sharable, Shoutable, Searchable, Taggable):
14 """A class representing an artist."""
15 - def init(self, 16 api, 17 name = None, 18 mbid = None, 19 url = None, 20 image = None, 21 streamable = None, 22 stats = None, 23 similar = None, 24 top_tags = None, 25 bio = None, 26 subject = None):
27 """ 28 Create an Artist object by providing all the data related to it. 29 30 @param api: an instance of L{Api} 31 @type api: L{Api} 32 @param name: the artist name 33 @type name: L{str} 34 @param mbid: MBID of the artist 35 @type mbid: L{str} 36 @param url: URL of the artist on last.fm 37 @type url: L{str} 38 @param image: the images of the artist in various sizes 39 @type image: L{dict} 40 @param streamable: flag indicating if the artist is streamable from last.fm 41 @type streamable: L{bool} 42 @param stats: the artist statistics 43 @type stats: L{Stats} 44 @param similar: artists similar to the provided artist 45 @type similar: L{list} of L{Artist} 46 @param top_tags: top tags for the artist 47 @type top_tags: L{list} of L{Tag} 48 @param bio: biography of the artist 49 @type bio: L{Wiki} 50 @param subject: the subject to which this instance belongs to 51 @type subject: L{User} OR L{Artist} OR L{Tag} OR L{Track} OR L{WeeklyChart} 52 53 @raise InvalidParametersError: If an instance of L{Api} is not provided as the first 54 parameter then an Exception is raised. 55 """ 56 if not isinstance(api, Api): 57 raise InvalidParametersError("api reference must be supplied as an argument") 58 Sharable.init(self, api) 59 Shoutable.init(self, api) 60 Taggable.init(self, api) 61 62 self._api = api 63 self._name = name 64 self._mbid = mbid 65 self._url = url 66 self._image = image 67 self._streamable = streamable 68 self._stats = stats and Stats( 69 subject = self, 70 listeners = stats.listeners, 71 playcount = stats.playcount, 72 weight = stats.weight, 73 match = stats.match, 74 rank = stats.rank 75 ) 76 self._similar = similar 77 self._top_tags = top_tags 78 self._bio = bio and Wiki( 79 subject = self, 80 published = bio.published, 81 summary = bio.summary, 82 content = bio.content 83 ) 84 self._subject = subject
85 86 @property
87 - def name(self):
88 """ 89 name of the artist 90 @rtype: L{str} 91 """ 92 return self._name
93 94 @property
95 - def mbid(self):
96 """ 97 MBID of the artist 98 @rtype: L{str} 99 """ 100 if self._mbid is None: 101 self._fill_info() 102 return self._mbid
103 104 @property
105 - def url(self):
106 """ 107 url of the artist's page 108 @rtype: L{str} 109 """ 110 if self._url is None: 111 self._fill_info() 112 return self._url
113 114 @property
115 - def image(self):
116 """ 117 images of the artist 118 @rtype: L{dict} 119 """ 120 if self._image is None: 121 self._fill_info() 122 return self._image
123 124 @property
125 - def streamable(self):
126 """ 127 is the artist streamable on last.fm 128 @rtype: L{bool} 129 """ 130 if self._streamable is None: 131 self._fill_info() 132 return self._streamable
133 134 @property
135 - def stats(self):
136 """ 137 stats for the artist 138 @rtype: L{Stats} 139 """ 140 if self._stats is None: 141 self._fill_info() 142 return self._stats
143
144 - def get_similar(self, limit = None):
145 """ 146 Get the artists similar to this artist. 147 148 @param limit: the number of artists returned (optional) 149 @type limit: L{int} 150 151 @return: artists similar to this artist 152 @rtype: L{list} of L{Artist} 153 """ 154 params = self._default_params({'method': 'artist.getSimilar'}) 155 if limit is not None: 156 params.update({'limit': limit}) 157 data = self._api._fetch_data(params).find('similarartists') 158 self._similar = [ 159 Artist( 160 self._api, 161 subject = self, 162 name = a.findtext('name'), 163 mbid = a.findtext('mbid'), 164 stats = Stats( 165 subject = a.findtext('name'), 166 match = float(a.findtext('match')), 167 ), 168 url = 'http://' + a.findtext('url'), 169 image = {'large': a.findtext('image')} 170 ) 171 for a in data.findall('artist') 172 ] 173 return self._similar[:]
174 175 @property
176 - def similar(self):
177 """ 178 artists similar to this artist 179 @rtype: L{list} of L{Artist} 180 """ 181 if self._similar is None or len(self._similar) < 6: 182 return self.get_similar() 183 return self._similar[:]
184 185 @top_property("similar")
186 - def most_similar(self):
187 """ 188 artist most similar to this artist 189 @rtype: L{Artist} 190 """ 191 pass
192 193 @property
194 - def top_tags(self):
195 """ 196 top tags for the artist 197 @rtype: L{list} of L{Tag} 198 """ 199 if self._top_tags is None or len(self._top_tags) < 6: 200 params = self._default_params({'method': 'artist.getTopTags'}) 201 data = self._api._fetch_data(params).find('toptags') 202 self._top_tags = [ 203 Tag( 204 self._api, 205 subject = self, 206 name = t.findtext('name'), 207 url = t.findtext('url') 208 ) 209 for t in data.findall('tag') 210 ] 211 return self._top_tags[:]
212 213 @top_property("top_tags")
214 - def top_tag(self):
215 """ 216 top tag for the artist 217 @rtype: L{Tag} 218 """ 219 pass
220 221 @property
222 - def bio(self):
223 """ 224 biography of the artist 225 @rtype: L{Wiki} 226 """ 227 if self._bio is None: 228 self._fill_info() 229 return self._bio
230 231 @cached_property
232 - def events(self):
233 """ 234 events for the artist 235 @rtype: L{lazylist} of L{Event} 236 """ 237 params = self._default_params({'method': 'artist.getEvents'}) 238 data = self._api._fetch_data(params).find('events') 239 240 return [ 241 Event.create_from_data(self._api, e) 242 for e in data.findall('event') 243 ]
244 245 @cached_property
246 - def top_albums(self):
247 """ 248 top albums of the artist 249 @rtype: L{list} of L{Album} 250 """ 251 params = self._default_params({'method': 'artist.getTopAlbums'}) 252 data = self._api._fetch_data(params).find('topalbums') 253 254 return [ 255 Album( 256 self._api, 257 subject = self, 258 name = a.findtext('name'), 259 artist = self, 260 mbid = a.findtext('mbid'), 261 url = a.findtext('url'), 262 image = dict([(i.get('size'), i.text) for i in a.findall('image')]), 263 stats = Stats( 264 subject = a.findtext('name'), 265 playcount = int(a.findtext('playcount')), 266 rank = int(a.attrib['rank']) 267 ) 268 ) 269 for a in data.findall('album') 270 ]
271 272 @top_property("top_albums")
273 - def top_album(self):
274 """ 275 top album of the artist 276 @rtype: L{Album} 277 """ 278 pass
279 280 @cached_property
281 - def top_fans(self):
282 """ 283 top fans of the artist 284 @rtype: L{list} of L{User} 285 """ 286 params = self._default_params({'method': 'artist.getTopFans'}) 287 data = self._api._fetch_data(params).find('topfans') 288 return [ 289 User( 290 self._api, 291 subject = self, 292 name = u.findtext('name'), 293 url = u.findtext('url'), 294 image = dict([(i.get('size'), i.text) for i in u.findall('image')]), 295 stats = Stats( 296 subject = u.findtext('name'), 297 weight = int(u.findtext('weight')) 298 ) 299 ) 300 for u in data.findall('user') 301 ]
302 303 @top_property("top_fans")
304 - def top_fan(self):
305 """ 306 top fan of the artist 307 @rtype: L{User}""" 308 pass
309 310 @cached_property
311 - def top_tracks(self):
312 """ 313 top tracks of the artist 314 @rtype: L{list} of L{Track} 315 """ 316 params = self._default_params({'method': 'artist.getTopTracks'}) 317 data = self._api._fetch_data(params).find('toptracks') 318 return [ 319 Track( 320 self._api, 321 subject = self, 322 name = t.findtext('name'), 323 artist = self, 324 mbid = t.findtext('mbid'), 325 stats = Stats( 326 subject = t.findtext('name'), 327 playcount = int(t.findtext('playcount')), 328 rank = int(t.attrib['rank']) 329 ), 330 streamable = (t.findtext('streamable') == '1'), 331 full_track = (t.find('streamable').attrib['fulltrack'] == '1'), 332 image = dict([(i.get('size'), i.text) for i in t.findall('image')]), 333 ) 334 for t in data.findall('track') 335 ]
336 337 @top_property("top_tracks")
338 - def top_track(self):
339 """ 340 topmost track of the artist 341 @rtype: L{Track} 342 """ 343 pass
344 345 @staticmethod
346 - def get_info(api, artist = None, mbid = None):
347 """ 348 Get the data for the artist. 349 350 @param api: an instance of L{Api} 351 @type api: L{Api} 352 @param artist: the name of the artist 353 @type artist: L{str} 354 @param mbid: MBID of the artist 355 @type mbid: L{str} 356 357 @return: an Artist object corresponding the provided artist name 358 @rtype: L{Artist} 359 360 @raise lastfm.InvalidParametersError: Either artist or mbid parameter has to 361 be provided. Otherwise exception is raised. 362 363 @note: Use the L{Api.get_artist} method instead of using this method directly. 364 """ 365 data = Artist._fetch_data(api, artist, mbid) 366 367 a = Artist(api, name = data.findtext('name')) 368 a._fill_info() 369 return a
370
371 - def _default_params(self, extra_params = {}):
372 if not self.name: 373 raise InvalidParametersError("artist has to be provided.") 374 params = {'artist': self.name} 375 params.update(extra_params) 376 return params
377 378 @staticmethod
379 - def _fetch_data(api, 380 artist = None, 381 mbid = None):
382 params = {'method': 'artist.getInfo'} 383 if not (artist or mbid): 384 raise InvalidParametersError("either artist or mbid has to be given as argument.") 385 if artist: 386 params.update({'artist': artist}) 387 elif mbid: 388 params.update({'mbid': mbid}) 389 return api._fetch_data(params).find('artist')
390
391 - def _fill_info(self):
392 data = Artist._fetch_data(self._api, self.name) 393 self._name = data.findtext('name') 394 self._mbid = data.findtext('mbid') 395 self._url = data.findtext('url') 396 self._image = dict([(i.get('size'), i.text) for i in data.findall('image')]) 397 self._streamable = (data.findtext('streamable') == 1) 398 if not self._stats: 399 self._stats = Stats( 400 subject = self, 401 listeners = int(data.findtext('stats/listeners')), 402 playcount = int(data.findtext('stats/playcount')) 403 ) 404 self._similar = [ 405 Artist( 406 self._api, 407 subject = self, 408 name = a.findtext('name'), 409 url = a.findtext('url'), 410 image = dict([(i.get('size'), i.text) for i in a.findall('image')]) 411 ) 412 for a in data.findall('similar/artist') 413 ] 414 self._top_tags = [ 415 Tag( 416 self._api, 417 subject = self, 418 name = t.findtext('name'), 419 url = t.findtext('url') 420 ) 421 for t in data.findall('tags/tag') 422 ] 423 self._bio = Wiki( 424 self, 425 published = data.findtext('bio/published').strip() and 426 datetime(*(time.strptime( 427 data.findtext('bio/published').strip(), 428 '%a, %d %b %Y %H:%M:%S +0000' 429 )[0:6])), 430 summary = data.findtext('bio/summary'), 431 content = data.findtext('bio/content') 432 )
433 434 @staticmethod
435 - def _search_yield_func(api, artist):
436 return Artist( 437 api, 438 name = artist.findtext('name'), 439 mbid = artist.findtext('mbid'), 440 url = artist.findtext('url'), 441 image = dict([(i.get('size'), i.text) for i in artist.findall('image')]), 442 streamable = (artist.findtext('streamable') == '1'), 443 )
444 @staticmethod
445 - def _hash_func(*args, **kwds):
446 try: 447 return hash(kwds['name'].lower()) 448 except KeyError: 449 try: 450 return hash(args[1].lower()) 451 except IndexError: 452 raise InvalidParametersError("name has to be provided for hashing")
453
454 - def __hash__(self):
455 return self.__class__._hash_func(name = self.name)
456
457 - def __eq__(self, other):
458 if self.mbid and other.mbid: 459 return self.mbid == other.mbid 460 if self.url and other.url: 461 return self.url == other.url 462 return self.name == other.name
463
464 - def __lt__(self, other):
465 return self.name < other.name
466
467 - def __repr__(self):
468 return "<lastfm.Artist: %s>" % self._name
469 470 from datetime import datetime 471 import time 472 473 from lastfm.album import Album 474 from lastfm.api import Api 475 from lastfm.error import InvalidParametersError 476 from lastfm.event import Event 477 from lastfm.stats import Stats 478 from lastfm.tag import Tag 479 from lastfm.track import Track 480 from lastfm.user import User 481 from lastfm.wiki import Wiki 482