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

Source Code for Module lastfm.user

  1  #!/usr/bin/env python 
  2   
  3  __author__ = "Abhinav Sarkar <abhinav@abhinavsarkar.net>" 
  4  __version__ = "0.2" 
  5  __license__ = "GNU Lesser General Public License" 
  6   
  7  from lastfm.base import LastfmBase 
  8  from lastfm.mixins import Cacheable, Shoutable 
  9  from lastfm.lazylist import lazylist 
 10  import lastfm.playlist 
 11  from lastfm.decorators import cached_property, top_property, authenticate 
12 13 -class User(LastfmBase, Cacheable, Shoutable):
14 """A class representing an user."""
15 - def init(self, 16 api, 17 name = None, 18 real_name = None, 19 url = None, 20 image = None, 21 stats = None, 22 **kwargs):
23 if not isinstance(api, Api): 24 raise InvalidParametersError("api reference must be supplied as an argument") 25 Shoutable.init(self, api) 26 self._api = api 27 self._name = name 28 self._real_name = real_name 29 self._url = url 30 self._image = image 31 self._stats = stats and Stats( 32 subject = self, 33 match = stats.match, 34 weight = stats.weight, 35 playcount = stats.playcount 36 ) 37 self._library = User.Library(api, self)
38 39 @property
40 - def name(self):
41 """name of the user""" 42 return self._name
43 44 @property
45 - def real_name(self):
46 """real name of the user""" 47 return self._real_name
48 49 @property
50 - def url(self):
51 """url of the user's page""" 52 return self._url
53 54 @property
55 - def image(self):
56 """image of the user""" 57 return self._image
58 59 @property
60 - def stats(self):
61 """stats for the user""" 62 return self._stats
63 64 @property 65 @authenticate
66 - def language(self):
67 """lang for the user""" 68 return self._language
69 70 @property 71 @authenticate
72 - def country(self):
73 """country for the user""" 74 return self._country
75 76 @property 77 @authenticate
78 - def age(self):
79 """age for the user""" 80 return self._age
81 82 @property 83 @authenticate
84 - def gender(self):
85 """stats for the user""" 86 return self._gender
87 88 @property 89 @authenticate
90 - def subscriber(self):
91 """is the user a subscriber""" 92 return self._subscriber
93 94 @property
95 - def authenticated(self):
96 """is the user authenticated""" 97 try: 98 auth_user = self._api.get_authenticated_user() 99 return auth_user == self 100 except AuthenticationFailedError: 101 return False
102 103 @cached_property
104 - def events(self):
105 params = self._default_params({'method': 'user.getEvents'}) 106 data = self._api._fetch_data(params).find('events') 107 108 return [ 109 Event.create_from_data(self._api, e) 110 for e in data.findall('event') 111 ]
112
113 - def get_past_events(self, 114 limit = None):
115 params = self._default_params({'method': 'user.getPastEvents'}) 116 if limit is not None: 117 params.update({'limit': limit}) 118 119 @lazylist 120 def gen(lst): 121 data = self._api._fetch_data(params).find('events') 122 total_pages = int(data.attrib['totalPages']) 123 124 @lazylist 125 def gen2(lst, data): 126 for e in data.findall('event'): 127 yield Event.create_from_data(self._api, e)
128 129 for e in gen2(data): 130 yield e 131 132 for page in xrange(2, total_pages+1): 133 params.update({'page': page}) 134 data = self._api._fetch_data(params).find('events') 135 for e in gen2(data): 136 yield e
137 return gen() 138 139 @cached_property
140 - def past_events(self):
141 return self.get_past_events()
142 143 @authenticate 158 159 for e in gen2(data): 160 yield e 161 162 for page in xrange(2, total_pages+1): 163 params.update({'page': page}) 164 data = self._api._fetch_data(params, sign = True, session = True).find('events') 165 for e in gen2(data): 166 yield e 167 return gen() 168 169 @cached_property
170 - def recommended_events(self):
171 return self.get_recommended_events()
172
173 - def get_friends(self, 174 limit = None):
175 params = self._default_params({'method': 'user.getFriends'}) 176 if limit is not None: 177 params.update({'limit': limit}) 178 data = self._api._fetch_data(params).find('friends') 179 return [ 180 User( 181 self._api, 182 subject = self, 183 name = u.findtext('name'), 184 real_name = u.findtext('realname'), 185 image = dict([(i.get('size'), i.text) for i in u.findall('image')]), 186 url = u.findtext('url'), 187 ) 188 for u in data.findall('user') 189 ]
190 191 192 @cached_property
193 - def friends(self):
194 """friends of the user""" 195 return self.get_friends()
196
197 - def get_neighbours(self, limit = None):
198 params = self._default_params({'method': 'user.getNeighbours'}) 199 if limit is not None: 200 params.update({'limit': limit}) 201 data = self._api._fetch_data(params).find('neighbours') 202 return [ 203 User( 204 self._api, 205 subject = self, 206 name = u.findtext('name'), 207 real_name = u.findtext('realname'), 208 image = {'medium': u.findtext('image')}, 209 url = u.findtext('url'), 210 stats = Stats( 211 subject = u.findtext('name'), 212 match = u.findtext('match') and float(u.findtext('match')), 213 ), 214 ) 215 for u in data.findall('user') 216 ]
217 218 @cached_property
219 - def neighbours(self):
220 """neighbours of the user""" 221 return self.get_neighbours()
222 223 @top_property("neighbours")
224 - def nearest_neighbour(self):
225 """nearest neightbour of the user""" 226 pass
227 228 @cached_property
229 - def playlists(self):
230 """playlists of the user""" 231 params = self._default_params({'method': 'user.getPlaylists'}) 232 data = self._api._fetch_data(params).find('playlists') 233 return [ 234 User.Playlist( 235 self._api, 236 id = int(p.findtext('id')), 237 title = p.findtext('title'), 238 date = datetime(*( 239 time.strptime( 240 p.findtext('date').strip(), 241 '%Y-%m-%dT%H:%M:%S' 242 )[0:6]) 243 ), 244 size = int(p.findtext('size')), 245 creator = self 246 ) 247 for p in data.findall('playlist') 248 ]
249 250 @authenticate
251 - def create_playlist(self, title, description = None):
252 params = {'method': 'playlist.create', 253 'title': title} 254 if description is not None: 255 params['description'] = description 256 self._api._post_data(params) 257 self._playlists = None
258 259 @cached_property
260 - def loved_tracks(self):
261 params = self._default_params({'method': 'user.getLovedTracks'}) 262 data = self._api._fetch_data(params).find('lovedtracks') 263 return [ 264 Track( 265 self._api, 266 subject = self, 267 name = t.findtext('name'), 268 artist = Artist( 269 self._api, 270 subject = self, 271 name = t.findtext('artist/name'), 272 mbid = t.findtext('artist/mbid'), 273 url = t.findtext('artist/url'), 274 ), 275 mbid = t.findtext('mbid'), 276 image = dict([(i.get('size'), i.text) for i in t.findall('image')]), 277 loved_on = datetime(*( 278 time.strptime( 279 t.findtext('date').strip(), 280 '%d %b %Y, %H:%M' 281 )[0:6]) 282 ) 283 ) 284 for t in data.findall('track') 285 ]
286
287 - def get_recent_tracks(self, limit = None):
288 params = self._default_params({'method': 'user.getRecentTracks'}) 289 data = self._api._fetch_data(params, no_cache = True).find('recenttracks') 290 return [ 291 Track( 292 self._api, 293 subject = self, 294 name = t.findtext('name'), 295 artist = Artist( 296 self._api, 297 subject = self, 298 name = t.findtext('artist'), 299 mbid = t.find('artist').attrib['mbid'], 300 ), 301 album = Album( 302 self._api, 303 subject = self, 304 name = t.findtext('album'), 305 artist = Artist( 306 self._api, 307 subject = self, 308 name = t.findtext('artist'), 309 mbid = t.find('artist').attrib['mbid'], 310 ), 311 mbid = t.find('album').attrib['mbid'], 312 ), 313 mbid = t.findtext('mbid'), 314 streamable = (t.findtext('streamable') == '1'), 315 url = t.findtext('url'), 316 image = dict([(i.get('size'), i.text) for i in t.findall('image')]), 317 played_on = datetime(*( 318 time.strptime( 319 t.findtext('date').strip(), 320 '%d %b %Y, %H:%M' 321 )[0:6]) 322 ) 323 ) 324 for t in data.findall('track') 325 ]
326 327 @property
328 - def recent_tracks(self):
329 """recent tracks played by the user""" 330 return self.get_recent_tracks()
331 332 @top_property("recent_tracks")
333 - def most_recent_track(self):
334 """most recent track played by the user""" 335 pass
336
337 - def get_top_albums(self, period = None):
338 params = self._default_params({'method': 'user.getTopAlbums'}) 339 if period is not None: 340 params.update({'period': period}) 341 data = self._api._fetch_data(params).find('topalbums') 342 343 return [ 344 Album( 345 self._api, 346 subject = self, 347 name = a.findtext('name'), 348 artist = Artist( 349 self._api, 350 subject = self, 351 name = a.findtext('artist/name'), 352 mbid = a.findtext('artist/mbid'), 353 url = a.findtext('artist/url'), 354 ), 355 mbid = a.findtext('mbid'), 356 url = a.findtext('url'), 357 image = dict([(i.get('size'), i.text) for i in a.findall('image')]), 358 stats = Stats( 359 subject = a.findtext('name'), 360 playcount = int(a.findtext('playcount')), 361 rank = int(a.attrib['rank']) 362 ) 363 ) 364 for a in data.findall('album') 365 ]
366 367 @cached_property
368 - def top_albums(self):
369 """overall top albums of the user""" 370 return self.get_top_albums()
371 372 @top_property("top_albums")
373 - def top_album(self):
374 """overall top most album of the user""" 375 pass
376
377 - def get_top_artists(self, period = None):
378 params = self._default_params({'method': 'user.getTopArtists'}) 379 if period is not None: 380 params.update({'period': period}) 381 data = self._api._fetch_data(params).find('topartists') 382 383 return [ 384 Artist( 385 self._api, 386 subject = self, 387 name = a.findtext('name'), 388 mbid = a.findtext('mbid'), 389 stats = Stats( 390 subject = a.findtext('name'), 391 rank = a.attrib['rank'].strip() and int(a.attrib['rank']) or None, 392 playcount = a.findtext('playcount') and int(a.findtext('playcount')) or None 393 ), 394 url = a.findtext('url'), 395 streamable = (a.findtext('streamable') == "1"), 396 image = dict([(i.get('size'), i.text) for i in a.findall('image')]), 397 ) 398 for a in data.findall('artist') 399 ]
400 401 @cached_property
402 - def top_artists(self):
403 """top artists of the user""" 404 return self.get_top_artists()
405 406 @top_property("top_artists")
407 - def top_artist(self):
408 """top artist of the user""" 409 pass
410 411 @cached_property 412 @authenticate
413 - def recommended_artists(self):
414 params = {'method': 'user.getRecommendedArtists'} 415 416 @lazylist 417 def gen(lst): 418 data = self._api._fetch_data(params, sign = True, session = True).find('recommendations') 419 total_pages = int(data.attrib['totalPages']) 420 421 @lazylist 422 def gen2(lst, data): 423 for a in data.findall('artist'): 424 yield Artist( 425 self._api, 426 name = a.findtext('name'), 427 mbid = a.findtext('mbid'), 428 url = a.findtext('url'), 429 streamable = (a.findtext('streamable') == "1"), 430 image = dict([(i.get('size'), i.text) for i in a.findall('image')]), 431 )
432 433 for a in gen2(data): 434 yield a 435 436 for page in xrange(2, total_pages+1): 437 params.update({'page': page}) 438 data = self._api._fetch_data(params, sign = True, session = True).find('recommendations') 439 for a in gen2(data): 440 yield a 441 return gen() 442
443 - def get_top_tracks(self, period = None):
444 params = self._default_params({'method': 'user.getTopTracks'}) 445 if period is not None: 446 params.update({'period': period}) 447 data = self._api._fetch_data(params).find('toptracks') 448 return [ 449 Track( 450 self._api, 451 subject = self, 452 name = t.findtext('name'), 453 artist = Artist( 454 self._api, 455 subject = self, 456 name = t.findtext('artist/name'), 457 mbid = t.findtext('artist/mbid'), 458 url = t.findtext('artist/url'), 459 ), 460 mbid = t.findtext('mbid'), 461 stats = Stats( 462 subject = t.findtext('name'), 463 rank = t.attrib['rank'].strip() and int(t.attrib['rank']) or None, 464 playcount = t.findtext('playcount') and int(t.findtext('playcount')) or None 465 ), 466 streamable = (t.findtext('streamable') == '1'), 467 full_track = (t.find('streamable').attrib['fulltrack'] == '1'), 468 image = dict([(i.get('size'), i.text) for i in t.findall('image')]), 469 ) 470 for t in data.findall('track') 471 ]
472 473 @cached_property
474 - def top_tracks(self):
475 """top tracks of the user""" 476 return self.get_top_tracks()
477 478 @top_property("top_tracks")
479 - def top_track(self):
480 """top track of the user""" 481 return (len(self.top_tracks) and self.top_tracks[0] or None)
482
483 - def get_top_tags(self, limit = None):
484 params = self._default_params({'method': 'user.getTopTags'}) 485 if limit is not None: 486 params.update({'limit': limit}) 487 data = self._api._fetch_data(params).find('toptags') 488 return [ 489 Tag( 490 self._api, 491 subject = self, 492 name = t.findtext('name'), 493 url = t.findtext('url'), 494 stats = Stats( 495 subject = t.findtext('name'), 496 count = int(t.findtext('count')) 497 ) 498 ) 499 for t in data.findall('tag') 500 ]
501 502 @cached_property
503 - def top_tags(self):
504 """top tags of the user""" 505 return self.get_top_tags()
506 507 @top_property("top_tags")
508 - def top_tag(self):
509 """top tag of the user""" 510 pass
511 512 @cached_property
513 - def weekly_chart_list(self):
514 params = self._default_params({'method': 'user.getWeeklyChartList'}) 515 data = self._api._fetch_data(params).find('weeklychartlist') 516 return [ 517 WeeklyChart.create_from_data(self._api, self, c) 518 for c in data.findall('chart') 519 ]
520
521 - def get_weekly_album_chart(self, 522 start = None, 523 end = None):
524 params = self._default_params({'method': 'user.getWeeklyAlbumChart'}) 525 params = WeeklyChart._check_weekly_chart_params(params, start, end) 526 data = self._api._fetch_data(params).find('weeklyalbumchart') 527 return WeeklyAlbumChart.create_from_data(self._api, self, data)
528 529 @cached_property
530 - def recent_weekly_album_chart(self):
531 return self.get_weekly_album_chart()
532 533 @cached_property
534 - def weekly_album_chart_list(self):
535 wcl = list(self.weekly_chart_list) 536 wcl.reverse() 537 @lazylist 538 def gen(lst): 539 for wc in wcl: 540 try: 541 yield self.get_weekly_album_chart(wc.start, wc.end) 542 except LastfmError: 543 pass
544 return gen() 545
546 - def get_weekly_artist_chart(self, 547 start = None, 548 end = None):
549 params = self._default_params({'method': 'user.getWeeklyArtistChart'}) 550 params = WeeklyChart._check_weekly_chart_params(params, start, end) 551 data = self._api._fetch_data(params).find('weeklyartistchart') 552 return WeeklyArtistChart.create_from_data(self._api, self, data)
553 554 @cached_property
555 - def recent_weekly_artist_chart(self):
556 return self.get_weekly_artist_chart()
557 558 @cached_property
559 - def weekly_artist_chart_list(self):
560 wcl = list(self.weekly_chart_list) 561 wcl.reverse() 562 @lazylist 563 def gen(lst): 564 for wc in wcl: 565 try: 566 yield self.get_weekly_artist_chart(wc.start, wc.end) 567 except LastfmError: 568 pass
569 return gen() 570
571 - def get_weekly_track_chart(self, 572 start = None, 573 end = None):
574 params = self._default_params({'method': 'user.getWeeklyTrackChart'}) 575 params = WeeklyChart._check_weekly_chart_params(params, start, end) 576 data = self._api._fetch_data(params).find('weeklytrackchart') 577 return WeeklyTrackChart.create_from_data(self._api, self, data)
578 579 @cached_property
580 - def recent_weekly_track_chart(self):
581 return self.get_weekly_track_chart()
582 583 @cached_property
584 - def weekly_track_chart_list(self):
585 wcl = list(self.weekly_chart_list) 586 wcl.reverse() 587 @lazylist 588 def gen(lst): 589 for wc in wcl: 590 try: 591 yield self.get_weekly_track_chart(wc.start, wc.end) 592 except LastfmError: 593 pass
594 return gen() 595
596 - def get_weekly_tag_chart(self, 597 start = None, 598 end = None):
599 WeeklyChart._check_weekly_chart_params({}, start, end) 600 return WeeklyTagChart.create_from_data(self._api, self, start, end)
601 602 @cached_property
603 - def recent_weekly_tag_chart(self):
604 return self.get_weekly_tag_chart()
605 606 @cached_property
607 - def weekly_tag_chart_list(self):
608 wcl = list(self.weekly_chart_list) 609 wcl.reverse() 610 @lazylist 611 def gen(lst): 612 for wc in wcl: 613 try: 614 yield self.get_weekly_tag_chart(wc.start, wc.end) 615 except LastfmError: 616 pass
617 return gen() 618
619 - def compare(self, other, limit = None):
620 if isinstance(other, User): 621 other = other.name 622 return Tasteometer.compare(self._api, 623 'user', 'user', 624 self.name, other, 625 limit)
626 @property
627 - def library(self):
628 return self._library
629 630 @staticmethod
631 - def get_info(api, name):
632 user = User(api, name = name) 633 friends = user.friends 634 if len(friends) == 0: 635 return user 636 else: 637 f = friends[0] 638 user = [a for a in f.friends if a.name == user.name][0] 639 return user
640 641 @staticmethod
642 - def get_authenticated_user(api):
643 data = api._fetch_data({'method': 'user.getInfo'}, sign = True, session = True).find('user') 644 user = User( 645 api, 646 name = data.findtext('name'), 647 url = data.findtext('url'), 648 ) 649 user._language = data.findtext('lang') 650 user._country = Country(api, name = Country.ISO_CODES[data.findtext('country')]) 651 user._age = int(data.findtext('age')) 652 user._gender = data.findtext('gender') 653 user._subscriber = (data.findtext('subscriber') == "1") 654 user._stats = Stats(subject = user, playcount = data.findtext('playcount')) 655 return user
656
657 - def _default_params(self, extra_params = {}):
658 if not self.name: 659 raise InvalidParametersError("user has to be provided.") 660 params = {'user': self.name} 661 params.update(extra_params) 662 return params
663 664 @staticmethod
665 - def _hash_func(*args, **kwds):
666 try: 667 return hash(kwds['name']) 668 except KeyError: 669 raise InvalidParametersError("name has to be provided for hashing")
670
671 - def __hash__(self):
672 return self.__class__._hash_func(name = self.name)
673
674 - def __eq__(self, other):
675 return self.name == other.name
676
677 - def __lt__(self, other):
678 return self.name < other.name
679
680 - def __repr__(self):
681 return "<lastfm.User: %s>" % self.name
682
683 - class Playlist(lastfm.playlist.Playlist):
684 """A class representing a playlist belonging to the user."""
685 - def init(self, api, id, title, date, size, creator):
686 super(User.Playlist, self).init(api, "lastfm://playlist/%s" % id) 687 self._id = id 688 self._title = title 689 self._date = date 690 self._size = size 691 self._creator = creator
692 693 @property
694 - def id(self):
695 return self._id
696 697 @property
698 - def title(self):
699 return self._title
700 701 @property
702 - def date(self):
703 return self._date
704 705 @property
706 - def size(self):
707 return self._size
708 709 @property
710 - def creator(self):
711 return self._creator
712 713 @property
714 - def user(self):
715 return self._creator
716 717 @authenticate
718 - def add_track(self, track, artist = None):
719 params = {'method': 'playlist.addTrack', 'playlistID': self.id} 720 if isinstance(track, Track): 721 params['artist'] = track.artist.name 722 params['track'] = track.name 723 else: 724 if artist is None: 725 track = self._api.search_track(track)[0] 726 params['artist'] = track.artist.name 727 params['track'] = track.name 728 else: 729 params['artist'] = isinstance(artist, Artist) and artist.name or artist 730 params['track'] = track 731 self._api._post_data(params) 732 self._data = None
733 734 @staticmethod
735 - def _hash_func(*args, **kwds):
736 try: 737 return hash(kwds['id']) 738 except KeyError: 739 raise InvalidParametersError("id has to be provided for hashing")
740
741 - def __hash__(self):
742 return self.__class__._hash_func(id = self.id)
743
744 - def __repr__(self):
745 return "<lastfm.User.Playlist: %s>" % self.title
746
747 - class Library(object):
748 """A class representing the music library of the user."""
749 - def __init__(self, api, user):
750 self._api = api 751 self._user = user
752 753 @property
754 - def user(self):
755 return self._user
756
757 - def get_albums(self, 758 limit = None):
759 params = self._default_params({'method': 'library.getAlbums'}) 760 if limit is not None: 761 params.update({'limit': limit}) 762 763 @lazylist 764 def gen(lst): 765 data = self._api._fetch_data(params).find('albums') 766 total_pages = int(data.attrib['totalPages']) 767 768 @lazylist 769 def gen2(lst, data): 770 for a in data.findall('album'): 771 yield Album( 772 self._api, 773 subject = self, 774 name = a.findtext('name'), 775 artist = Artist( 776 self._api, 777 subject = self, 778 name = a.findtext('artist/name'), 779 mbid = a.findtext('artist/mbid'), 780 url = a.findtext('artist/url'), 781 ), 782 mbid = a.findtext('mbid'), 783 url = a.findtext('url'), 784 image = dict([(i.get('size'), i.text) for i in a.findall('image')]), 785 stats = Stats( 786 subject = a.findtext('name'), 787 playcount = int(a.findtext('playcount')), 788 ) 789 )
790 791 792 for a in gen2(data): 793 yield a 794 795 for page in xrange(2, total_pages+1): 796 params.update({'page': page}) 797 try: 798 data = self._api._fetch_data(params).find('albums') 799 except LastfmError: 800 continue 801 for a in gen2(data): 802 yield a
803 return gen() 804 805 @cached_property
806 - def albums(self):
807 return self.get_albums()
808 809 @authenticate
810 - def add_album(self, album, artist = None):
811 params = {'method': 'library.addAlbum'} 812 if isinstance(album, Album): 813 params['artist'] = album.artist.name 814 params['album'] = album.name 815 else: 816 if artist is None: 817 album = self._api.search_album(album)[0] 818 params['artist'] = album.artist.name 819 params['album'] = album.name 820 else: 821 params['artist'] = isinstance(artist, Artist) and artist.name or artist 822 params['album'] = album 823 824 self._api._post_data(params) 825 self._albums = None
826
827 - def get_artists(self, 828 limit = None):
829 params = self._default_params({'method': 'library.getArtists'}) 830 if limit is not None: 831 params.update({'limit': limit}) 832 833 @lazylist 834 def gen(lst): 835 data = self._api._fetch_data(params).find('artists') 836 total_pages = int(data.attrib['totalPages']) 837 838 @lazylist 839 def gen2(lst, data): 840 for a in data.findall('artist'): 841 yield Artist( 842 self._api, 843 subject = self, 844 name = a.findtext('name'), 845 mbid = a.findtext('mbid'), 846 stats = Stats( 847 subject = a.findtext('name'), 848 playcount = a.findtext('playcount') and int(a.findtext('playcount')) or None, 849 tagcount = a.findtext('tagcount') and int(a.findtext('tagcount')) or None 850 ), 851 url = a.findtext('url'), 852 streamable = (a.findtext('streamable') == "1"), 853 image = dict([(i.get('size'), i.text) for i in a.findall('image')]), 854 )
855 856 for a in gen2(data): 857 yield a 858 859 for page in xrange(2, total_pages+1): 860 params.update({'page': page}) 861 try: 862 data = self._api._fetch_data(params).find('artists') 863 except LastfmError: 864 continue 865 for a in gen2(data): 866 yield a 867 return gen() 868 869 @cached_property
870 - def artists(self):
871 return self.get_artists()
872 873 @authenticate
874 - def add_artist(self, artist):
875 params = {'method': 'library.addArtist'} 876 if isinstance(artist, Artist): 877 params['artist'] = artist.name 878 else: 879 params['artist'] = artist 880 self._api._post_data(params) 881 self._artists = None
882
883 - def get_tracks(self, 884 limit = None):
885 params = self._default_params({'method': 'library.getTracks'}) 886 if limit is not None: 887 params.update({'limit': limit}) 888 889 @lazylist 890 def gen(lst): 891 data = self._api._fetch_data(params).find('tracks') 892 total_pages = int(data.attrib['totalPages']) 893 894 @lazylist 895 def gen2(lst, data): 896 for t in data.findall('track'): 897 yield Track( 898 self._api, 899 subject = self, 900 name = t.findtext('name'), 901 artist = Artist( 902 self._api, 903 subject = self, 904 name = t.findtext('artist/name'), 905 mbid = t.findtext('artist/mbid'), 906 url = t.findtext('artist/url'), 907 ), 908 mbid = t.findtext('mbid'), 909 stats = Stats( 910 subject = t.findtext('name'), 911 playcount = t.findtext('playcount') and int(t.findtext('playcount')) or None, 912 tagcount = t.findtext('tagcount') and int(t.findtext('tagcount')) or None 913 ), 914 streamable = (t.findtext('streamable') == '1'), 915 full_track = (t.find('streamable').attrib['fulltrack'] == '1'), 916 image = dict([(i.get('size'), i.text) for i in t.findall('image')]), 917 )
918 919 for t in gen2(data): 920 yield t 921 922 for page in xrange(2, total_pages+1): 923 params.update({'page': page}) 924 data = None 925 try: 926 data = self._api._fetch_data(params).find('tracks') 927 except LastfmError: 928 continue 929 for t in gen2(data): 930 yield t 931 return gen() 932 933 @cached_property
934 - def tracks(self):
935 return self.get_tracks()
936 937 @authenticate
938 - def add_track(self, track, artist = None):
939 params = {'method': 'library.addTrack'} 940 if isinstance(track, Track): 941 params['artist'] = track.artist.name 942 params['track'] = track.name 943 else: 944 if artist is None: 945 track = self._api.search_track(track)[0] 946 params['artist'] = track.artist.name 947 params['track'] = track.name 948 else: 949 params['artist'] = isinstance(artist, Artist) and artist.name or artist 950 params['track'] = track 951 self._api._post_data(params) 952 self._tracks = None
953
954 - def _default_params(self, extra_params = {}):
955 if not self.user.name: 956 raise InvalidParametersError("user has to be provided.") 957 params = {'user': self.user.name} 958 params.update(extra_params) 959 return params
960 961 @staticmethod
962 - def _hash_func(*args, **kwds):
963 try: 964 return hash(kwds['user']) 965 except KeyError: 966 raise InvalidParametersError("user has to be provided for hashing")
967
968 - def __hash__(self):
969 return self.__class__._hash_func(user = self.user)
970
971 - def __repr__(self):
972 return "<lastfm.User.Library: for user '%s'>" % self.user.name
973 974 from datetime import datetime 975 import time 976 977 from lastfm.api import Api 978 from lastfm.artist import Artist 979 from lastfm.album import Album 980 from lastfm.error import LastfmError, InvalidParametersError, AuthenticationFailedError 981 from lastfm.event import Event 982 from lastfm.geo import Country 983 from lastfm.stats import Stats 984 from lastfm.tag import Tag 985 from lastfm.tasteometer import Tasteometer 986 from lastfm.track import Track 987 from lastfm.weeklychart import WeeklyChart, WeeklyAlbumChart, WeeklyArtistChart, WeeklyTrackChart, WeeklyTagChart 988