1
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
12 -class User(LastfmBase, Cacheable, Shoutable):
13 """A class representing an user."""
14 - def init(self,
15 api,
16 name = None,
17 real_name = None,
18 url = None,
19 image = None,
20 stats = None):
36
37 @property
39 """name of the user"""
40 return self._name
41
42 @property
44 """real name of the user"""
45 return self._real_name
46
47 @property
49 """url of the user's page"""
50 return self._url
51
52 @property
54 """image of the user"""
55 return self._image
56
57 @property
59 """stats for the user"""
60 return self._stats
61
62 @property
63 @LastfmBase.autheticate
65 """lang for the user"""
66 return self._language
67
68 @property
69 @LastfmBase.autheticate
71 """country for the user"""
72 return self._country
73
74 @property
75 @LastfmBase.autheticate
77 """age for the user"""
78 return self._age
79
80 @property
81 @LastfmBase.autheticate
83 """stats for the user"""
84 return self._gender
85
86 @property
87 @LastfmBase.autheticate
89 """is the user a subscriber"""
90 return self._subscriber
91
92 @property
100
101 @LastfmBase.cached_property
110
113 params = self._default_params({'method': 'user.getPastEvents'})
114 if limit is not None:
115 params.update({'limit': limit})
116
117 @lazylist
118 def gen(lst):
119 data = self._api._fetch_data(params).find('events')
120 total_pages = int(data.attrib['totalPages'])
121
122 @lazylist
123 def gen2(lst, data):
124 for e in data.findall('event'):
125 yield Event.create_from_data(self._api, e)
126
127 for e in gen2(data):
128 yield e
129
130 for page in xrange(2, total_pages+1):
131 params.update({'page': page})
132 data = self._api._fetch_data(params).find('events')
133 for e in gen2(data):
134 yield e
135 return gen()
136
137 @LastfmBase.cached_property
140
141 @LastfmBase.autheticate
143 params = {'method': 'user.getRecommendedEvents'}
144 if limit is not None:
145 params.update({'limit': limit})
146
147 @lazylist
148 def gen(lst):
149 data = self._api._fetch_data(params, sign = True, session = True).find('events')
150 total_pages = int(data.attrib['totalPages'])
151
152 @lazylist
153 def gen2(lst, data):
154 for e in data.findall('event'):
155 yield Event.create_from_data(self._api, e)
156
157 for e in gen2(data):
158 yield e
159
160 for page in xrange(2, total_pages+1):
161 params.update({'page': page})
162 data = self._api._fetch_data(params, sign = True, session = True).find('events')
163 for e in gen2(data):
164 yield e
165 return gen()
166
167 @LastfmBase.cached_property
170
173 params = self._default_params({'method': 'user.getFriends'})
174 if limit is not None:
175 params.update({'limit': limit})
176 data = self._api._fetch_data(params).find('friends')
177 return [
178 User(
179 self._api,
180 subject = self,
181 name = u.findtext('name'),
182 real_name = u.findtext('realname'),
183 image = dict([(i.get('size'), i.text) for i in u.findall('image')]),
184 url = u.findtext('url'),
185 )
186 for u in data.findall('user')
187 ]
188
189
190 @LastfmBase.cached_property
192 """friends of the user"""
193 return self.get_friends()
194
196 params = self._default_params({'method': 'user.getNeighbours'})
197 if limit is not None:
198 params.update({'limit': limit})
199 data = self._api._fetch_data(params).find('neighbours')
200 return [
201 User(
202 self._api,
203 subject = self,
204 name = u.findtext('name'),
205 real_name = u.findtext('realname'),
206 image = {'medium': u.findtext('image')},
207 url = u.findtext('url'),
208 stats = Stats(
209 subject = u.findtext('name'),
210 match = u.findtext('match') and float(u.findtext('match')),
211 ),
212 )
213 for u in data.findall('user')
214 ]
215
216 @LastfmBase.cached_property
220
221 @LastfmBase.top_property("neighbours")
223 """nearest neightbour of the user"""
224 pass
225
226 @LastfmBase.cached_property
228 """playlists of the user"""
229 params = self._default_params({'method': 'user.getPlaylists'})
230 data = self._api._fetch_data(params).find('playlists')
231 return [
232 User.Playlist(
233 self._api,
234 id = int(p.findtext('id')),
235 title = p.findtext('title'),
236 date = datetime(*(
237 time.strptime(
238 p.findtext('date').strip(),
239 '%Y-%m-%dT%H:%M:%S'
240 )[0:6])
241 ),
242 size = int(p.findtext('size')),
243 creator = self
244 )
245 for p in data.findall('playlist')
246 ]
247
248 @LastfmBase.autheticate
250 params = {'method': 'playlist.create',
251 'title': title}
252 if description is not None:
253 params['description'] = description
254 self._api._post_data(params)
255 self._playlists = None
256
257 @LastfmBase.cached_property
259 params = self._default_params({'method': 'user.getLovedTracks'})
260 data = self._api._fetch_data(params).find('lovedtracks')
261 return [
262 Track(
263 self._api,
264 subject = self,
265 name = t.findtext('name'),
266 artist = Artist(
267 self._api,
268 subject = self,
269 name = t.findtext('artist/name'),
270 mbid = t.findtext('artist/mbid'),
271 url = t.findtext('artist/url'),
272 ),
273 mbid = t.findtext('mbid'),
274 image = dict([(i.get('size'), i.text) for i in t.findall('image')]),
275 loved_on = datetime(*(
276 time.strptime(
277 t.findtext('date').strip(),
278 '%d %b %Y, %H:%M'
279 )[0:6])
280 )
281 )
282 for t in data.findall('track')
283 ]
284
286 params = self._default_params({'method': 'user.getRecentTracks'})
287 data = self._api._fetch_data(params, no_cache = True).find('recenttracks')
288 return [
289 Track(
290 self._api,
291 subject = self,
292 name = t.findtext('name'),
293 artist = Artist(
294 self._api,
295 subject = self,
296 name = t.findtext('artist'),
297 mbid = t.find('artist').attrib['mbid'],
298 ),
299 album = Album(
300 self._api,
301 subject = self,
302 name = t.findtext('album'),
303 artist = Artist(
304 self._api,
305 subject = self,
306 name = t.findtext('artist'),
307 mbid = t.find('artist').attrib['mbid'],
308 ),
309 mbid = t.find('album').attrib['mbid'],
310 ),
311 mbid = t.findtext('mbid'),
312 streamable = (t.findtext('streamable') == '1'),
313 url = t.findtext('url'),
314 image = dict([(i.get('size'), i.text) for i in t.findall('image')]),
315 played_on = datetime(*(
316 time.strptime(
317 t.findtext('date').strip(),
318 '%d %b %Y, %H:%M'
319 )[0:6])
320 )
321 )
322 for t in data.findall('track')
323 ]
324
325 @property
329
330 @LastfmBase.top_property("recent_tracks")
332 """most recent track played by the user"""
333 pass
334
336 params = self._default_params({'method': 'user.getTopAlbums'})
337 if period is not None:
338 params.update({'period': period})
339 data = self._api._fetch_data(params).find('topalbums')
340
341 return [
342 Album(
343 self._api,
344 subject = self,
345 name = a.findtext('name'),
346 artist = Artist(
347 self._api,
348 subject = self,
349 name = a.findtext('artist/name'),
350 mbid = a.findtext('artist/mbid'),
351 url = a.findtext('artist/url'),
352 ),
353 mbid = a.findtext('mbid'),
354 url = a.findtext('url'),
355 image = dict([(i.get('size'), i.text) for i in a.findall('image')]),
356 stats = Stats(
357 subject = a.findtext('name'),
358 playcount = int(a.findtext('playcount')),
359 rank = int(a.attrib['rank'])
360 )
361 )
362 for a in data.findall('album')
363 ]
364
365 @LastfmBase.cached_property
367 """overall top albums of the user"""
368 return self.get_top_albums()
369
370 @LastfmBase.top_property("top_albums")
372 """overall top most album of the user"""
373 pass
374
376 params = self._default_params({'method': 'user.getTopArtists'})
377 if period is not None:
378 params.update({'period': period})
379 data = self._api._fetch_data(params).find('topartists')
380
381 return [
382 Artist(
383 self._api,
384 subject = self,
385 name = a.findtext('name'),
386 mbid = a.findtext('mbid'),
387 stats = Stats(
388 subject = a.findtext('name'),
389 rank = a.attrib['rank'].strip() and int(a.attrib['rank']) or None,
390 playcount = a.findtext('playcount') and int(a.findtext('playcount')) or None
391 ),
392 url = a.findtext('url'),
393 streamable = (a.findtext('streamable') == "1"),
394 image = dict([(i.get('size'), i.text) for i in a.findall('image')]),
395 )
396 for a in data.findall('artist')
397 ]
398
399 @LastfmBase.cached_property
403
404 @LastfmBase.top_property("top_artists")
406 """top artist of the user"""
407 pass
408
409 @LastfmBase.cached_property
410 @LastfmBase.autheticate
412 params = {'method': 'user.getRecommendedArtists'}
413
414 @lazylist
415 def gen(lst):
416 data = self._api._fetch_data(params, sign = True, session = True).find('recommendations')
417 total_pages = int(data.attrib['totalPages'])
418
419 @lazylist
420 def gen2(lst, data):
421 for a in data.findall('artist'):
422 yield Artist(
423 self._api,
424 name = a.findtext('name'),
425 mbid = a.findtext('mbid'),
426 url = a.findtext('url'),
427 streamable = (a.findtext('streamable') == "1"),
428 image = dict([(i.get('size'), i.text) for i in a.findall('image')]),
429 )
430
431 for a in gen2(data):
432 yield a
433
434 for page in xrange(2, total_pages+1):
435 params.update({'page': page})
436 data = self._api._fetch_data(params, sign = True, session = True).find('recommendations')
437 for a in gen2(data):
438 yield a
439 return gen()
440
442 params = self._default_params({'method': 'user.getTopTracks'})
443 if period is not None:
444 params.update({'period': period})
445 data = self._api._fetch_data(params).find('toptracks')
446 return [
447 Track(
448 self._api,
449 subject = self,
450 name = t.findtext('name'),
451 artist = Artist(
452 self._api,
453 subject = self,
454 name = t.findtext('artist/name'),
455 mbid = t.findtext('artist/mbid'),
456 url = t.findtext('artist/url'),
457 ),
458 mbid = t.findtext('mbid'),
459 stats = Stats(
460 subject = t.findtext('name'),
461 rank = t.attrib['rank'].strip() and int(t.attrib['rank']) or None,
462 playcount = t.findtext('playcount') and int(t.findtext('playcount')) or None
463 ),
464 streamable = (t.findtext('streamable') == '1'),
465 full_track = (t.find('streamable').attrib['fulltrack'] == '1'),
466 image = dict([(i.get('size'), i.text) for i in t.findall('image')]),
467 )
468 for t in data.findall('track')
469 ]
470
471 @LastfmBase.cached_property
475
476 @LastfmBase.top_property("top_tracks")
480
499
500 @LastfmBase.cached_property
504
505 @LastfmBase.top_property("top_tags")
507 """top tag of the user"""
508 pass
509
510 @LastfmBase.cached_property
518
526
527 @LastfmBase.cached_property
530
531 @LastfmBase.cached_property
542 return gen()
543
551
552 @LastfmBase.cached_property
555
556 @LastfmBase.cached_property
567 return gen()
568
576
577 @LastfmBase.cached_property
580
581 @LastfmBase.cached_property
592 return gen()
593
599
600 @LastfmBase.cached_property
603
604 @LastfmBase.cached_property
615 return gen()
616
617 - def compare(self, other, limit = None):
624 @property
627
628 @staticmethod
638
639 @staticmethod
654
656 if not self.name:
657 raise InvalidParametersError("user has to be provided.")
658 params = {'user': self.name}
659 params.update(extra_params)
660 return params
661
662 @staticmethod
664 try:
665 return hash(kwds['name'])
666 except KeyError:
667 raise InvalidParametersError("name has to be provided for hashing")
668
671
674
677
679 return "<lastfm.User: %s>" % self.name
680
681 - class Playlist(lastfm.playlist.Playlist):
682 """A class representing a playlist belonging to the user."""
683 - def init(self, api, id, title, date, size, creator):
690
691 @property
694
695 @property
698
699 @property
702
703 @property
706
707 @property
710
711 @property
714
715 @LastfmBase.autheticate
731
732 @staticmethod
734 try:
735 return hash(kwds['id'])
736 except KeyError:
737 raise InvalidParametersError("id has to be provided for hashing")
738
741
743 return "<lastfm.User.Playlist: %s>" % self.title
744
746 """A class representing the music library of the user."""
748 self._api = api
749 self._user = user
750
751 @property
754
757 params = self._default_params({'method': 'library.getAlbums'})
758 if limit is not None:
759 params.update({'limit': limit})
760
761 @lazylist
762 def gen(lst):
763 data = self._api._fetch_data(params).find('albums')
764 total_pages = int(data.attrib['totalPages'])
765
766 @lazylist
767 def gen2(lst, data):
768 for a in data.findall('album'):
769 yield Album(
770 self._api,
771 subject = self,
772 name = a.findtext('name'),
773 artist = Artist(
774 self._api,
775 subject = self,
776 name = a.findtext('artist/name'),
777 mbid = a.findtext('artist/mbid'),
778 url = a.findtext('artist/url'),
779 ),
780 mbid = a.findtext('mbid'),
781 url = a.findtext('url'),
782 image = dict([(i.get('size'), i.text) for i in a.findall('image')]),
783 stats = Stats(
784 subject = a.findtext('name'),
785 playcount = int(a.findtext('playcount')),
786 )
787 )
788
789
790 for a in gen2(data):
791 yield a
792
793 for page in xrange(2, total_pages+1):
794 params.update({'page': page})
795 try:
796 data = self._api._fetch_data(params).find('albums')
797 except LastfmError:
798 continue
799 for a in gen2(data):
800 yield a
801 return gen()
802
803 @LastfmBase.cached_property
806
807 @LastfmBase.autheticate
824
827 params = self._default_params({'method': 'library.getArtists'})
828 if limit is not None:
829 params.update({'limit': limit})
830
831 @lazylist
832 def gen(lst):
833 data = self._api._fetch_data(params).find('artists')
834 total_pages = int(data.attrib['totalPages'])
835
836 @lazylist
837 def gen2(lst, data):
838 for a in data.findall('artist'):
839 yield Artist(
840 self._api,
841 subject = self,
842 name = a.findtext('name'),
843 mbid = a.findtext('mbid'),
844 stats = Stats(
845 subject = a.findtext('name'),
846 playcount = a.findtext('playcount') and int(a.findtext('playcount')) or None,
847 tagcount = a.findtext('tagcount') and int(a.findtext('tagcount')) or None
848 ),
849 url = a.findtext('url'),
850 streamable = (a.findtext('streamable') == "1"),
851 image = dict([(i.get('size'), i.text) for i in a.findall('image')]),
852 )
853
854 for a in gen2(data):
855 yield a
856
857 for page in xrange(2, total_pages+1):
858 params.update({'page': page})
859 try:
860 data = self._api._fetch_data(params).find('artists')
861 except LastfmError:
862 continue
863 for a in gen2(data):
864 yield a
865 return gen()
866
867 @LastfmBase.cached_property
870
871 @LastfmBase.autheticate
873 params = {'method': 'library.addArtist'}
874 if isinstance(artist, Artist):
875 params['artist'] = artist.name
876 else:
877 params['artist'] = artist
878 self._api._post_data(params)
879 self._artists = None
880
883 params = self._default_params({'method': 'library.getTracks'})
884 if limit is not None:
885 params.update({'limit': limit})
886
887 @lazylist
888 def gen(lst):
889 data = self._api._fetch_data(params).find('tracks')
890 total_pages = int(data.attrib['totalPages'])
891
892 @lazylist
893 def gen2(lst, data):
894 for t in data.findall('track'):
895 yield Track(
896 self._api,
897 subject = self,
898 name = t.findtext('name'),
899 artist = Artist(
900 self._api,
901 subject = self,
902 name = t.findtext('artist/name'),
903 mbid = t.findtext('artist/mbid'),
904 url = t.findtext('artist/url'),
905 ),
906 mbid = t.findtext('mbid'),
907 stats = Stats(
908 subject = t.findtext('name'),
909 playcount = t.findtext('playcount') and int(t.findtext('playcount')) or None,
910 tagcount = t.findtext('tagcount') and int(t.findtext('tagcount')) or None
911 ),
912 streamable = (t.findtext('streamable') == '1'),
913 full_track = (t.find('streamable').attrib['fulltrack'] == '1'),
914 image = dict([(i.get('size'), i.text) for i in t.findall('image')]),
915 )
916
917 for t in gen2(data):
918 yield t
919
920 for page in xrange(2, total_pages+1):
921 params.update({'page': page})
922 data = None
923 try:
924 data = self._api._fetch_data(params).find('tracks')
925 except LastfmError:
926 continue
927 for t in gen2(data):
928 yield t
929 return gen()
930
931 @LastfmBase.cached_property
934
935 @LastfmBase.autheticate
951
958
959 @staticmethod
961 try:
962 return hash(kwds['user'])
963 except KeyError:
964 raise InvalidParametersError("user has to be provided for hashing")
965
968
970 return "<lastfm.User.Library: for user '%s'>" % self.user.name
971
972 from datetime import datetime
973 import time
974
975 from lastfm.api import Api
976 from lastfm.artist import Artist
977 from lastfm.album import Album
978 from lastfm.error import LastfmError, InvalidParametersError, AuthenticationFailedError
979 from lastfm.event import Event
980 from lastfm.geo import Country
981 from lastfm.stats import Stats
982 from lastfm.tag import Tag
983 from lastfm.tasteometer import Tasteometer
984 from lastfm.track import Track
985 from lastfm.weeklychart import WeeklyChart, WeeklyAlbumChart, WeeklyArtistChart, WeeklyTrackChart, WeeklyTagChart
986