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
96
97 @LastfmBase.cached_property
106
109 params = self._default_params({'method': 'user.getPastEvents'})
110 if limit is not None:
111 params.update({'limit': limit})
112
113 @lazylist
114 def gen(lst):
115 data = self._api._fetch_data(params).find('events')
116 total_pages = int(data.attrib['totalPages'])
117
118 @lazylist
119 def gen2(lst, data):
120 for e in data.findall('event'):
121 yield Event.create_from_data(self._api, e)
122
123 for e in gen2(data):
124 yield e
125
126 for page in xrange(2, total_pages+1):
127 params.update({'page': page})
128 data = self._api._fetch_data(params).find('events')
129 for e in gen2(data):
130 yield e
131 return gen()
132
133 @LastfmBase.cached_property
136
137 @LastfmBase.autheticate
139 params = {'method': 'user.getRecommendedEvents'}
140 if limit is not None:
141 params.update({'limit': limit})
142
143 @lazylist
144 def gen(lst):
145 data = self._api._fetch_data(params, sign = True, session = True).find('events')
146 total_pages = int(data.attrib['totalPages'])
147
148 @lazylist
149 def gen2(lst, data):
150 for e in data.findall('event'):
151 yield Event.create_from_data(self._api, e)
152
153 for e in gen2(data):
154 yield e
155
156 for page in xrange(2, total_pages+1):
157 params.update({'page': page})
158 data = self._api._fetch_data(params, sign = True, session = True).find('events')
159 for e in gen2(data):
160 yield e
161 return gen()
162
163 @LastfmBase.cached_property
166
169 params = self._default_params({'method': 'user.getFriends'})
170 if limit is not None:
171 params.update({'limit': limit})
172 data = self._api._fetch_data(params).find('friends')
173 return [
174 User(
175 self._api,
176 subject = self,
177 name = u.findtext('name'),
178 image = dict([(i.get('size'), i.text) for i in u.findall('image')]),
179 url = u.findtext('url'),
180 )
181 for u in data.findall('user')
182 ]
183
184
185 @LastfmBase.cached_property
187 """friends of the user"""
188 return self.get_friends()
189
191 params = self._default_params({'method': 'user.getNeighbours'})
192 if limit is not None:
193 params.update({'limit': limit})
194 data = self._api._fetch_data(params).find('neighbours')
195 return [
196 User(
197 self._api,
198 subject = self,
199 name = u.findtext('name'),
200 image = {'medium': u.findtext('image')},
201 url = u.findtext('url'),
202 stats = Stats(
203 subject = u.findtext('name'),
204 match = u.findtext('match') and float(u.findtext('match')),
205 ),
206 )
207 for u in data.findall('user')
208 ]
209
210 @LastfmBase.cached_property
214
215 @LastfmBase.top_property("neighbours")
217 """nearest neightbour of the user"""
218 pass
219
220 @LastfmBase.cached_property
222 """playlists of the user"""
223 params = self._default_params({'method': 'user.getPlaylists'})
224 data = self._api._fetch_data(params).find('playlists')
225 return [
226 User.Playlist(
227 self._api,
228 id = int(p.findtext('id')),
229 title = p.findtext('title'),
230 date = datetime(*(
231 time.strptime(
232 p.findtext('date').strip(),
233 '%Y-%m-%dT%H:%M:%S'
234 )[0:6])
235 ),
236 size = int(p.findtext('size')),
237 creator = self
238 )
239 for p in data.findall('playlist')
240 ]
241
242 @LastfmBase.autheticate
244 params = {'method': 'playlist.create',
245 'title': title}
246 if description is not None:
247 params['description'] = description
248 self._api._post_data(params)
249 self._playlists = None
250
251 @LastfmBase.cached_property
253 params = self._default_params({'method': 'user.getLovedTracks'})
254 data = self._api._fetch_data(params).find('lovedtracks')
255 return [
256 Track(
257 self._api,
258 subject = self,
259 name = t.findtext('name'),
260 artist = Artist(
261 self._api,
262 subject = self,
263 name = t.findtext('artist/name'),
264 mbid = t.findtext('artist/mbid'),
265 url = t.findtext('artist/url'),
266 ),
267 mbid = t.findtext('mbid'),
268 image = dict([(i.get('size'), i.text) for i in t.findall('image')]),
269 loved_on = datetime(*(
270 time.strptime(
271 t.findtext('date').strip(),
272 '%d %b %Y, %H:%M'
273 )[0:6])
274 )
275 )
276 for t in data.findall('track')
277 ]
278
280 params = self._default_params({'method': 'user.getRecentTracks'})
281 data = self._api._fetch_data(params, no_cache = True).find('recenttracks')
282 return [
283 Track(
284 self._api,
285 subject = self,
286 name = t.findtext('name'),
287 artist = Artist(
288 self._api,
289 subject = self,
290 name = t.findtext('artist'),
291 mbid = t.find('artist').attrib['mbid'],
292 ),
293 album = Album(
294 self._api,
295 subject = self,
296 name = t.findtext('album'),
297 artist = Artist(
298 self._api,
299 subject = self,
300 name = t.findtext('artist'),
301 mbid = t.find('artist').attrib['mbid'],
302 ),
303 mbid = t.find('album').attrib['mbid'],
304 ),
305 mbid = t.findtext('mbid'),
306 streamable = (t.findtext('streamable') == '1'),
307 url = t.findtext('url'),
308 image = dict([(i.get('size'), i.text) for i in t.findall('image')]),
309 played_on = datetime(*(
310 time.strptime(
311 t.findtext('date').strip(),
312 '%d %b %Y, %H:%M'
313 )[0:6])
314 )
315 )
316 for t in data.findall('track')
317 ]
318
319 @property
323
324 @LastfmBase.top_property("recent_tracks")
326 """most recent track played by the user"""
327 pass
328
330 params = self._default_params({'method': 'user.getTopAlbums'})
331 if period is not None:
332 params.update({'period': period})
333 data = self._api._fetch_data(params).find('topalbums')
334
335 return [
336 Album(
337 self._api,
338 subject = self,
339 name = a.findtext('name'),
340 artist = Artist(
341 self._api,
342 subject = self,
343 name = a.findtext('artist/name'),
344 mbid = a.findtext('artist/mbid'),
345 url = a.findtext('artist/url'),
346 ),
347 mbid = a.findtext('mbid'),
348 url = a.findtext('url'),
349 image = dict([(i.get('size'), i.text) for i in a.findall('image')]),
350 stats = Stats(
351 subject = a.findtext('name'),
352 playcount = int(a.findtext('playcount')),
353 rank = int(a.attrib['rank'])
354 )
355 )
356 for a in data.findall('album')
357 ]
358
359 @LastfmBase.cached_property
361 """overall top albums of the user"""
362 return self.get_top_albums()
363
364 @LastfmBase.top_property("top_albums")
366 """overall top most album of the user"""
367 pass
368
370 params = self._default_params({'method': 'user.getTopArtists'})
371 if period is not None:
372 params.update({'period': period})
373 data = self._api._fetch_data(params).find('topartists')
374
375 return [
376 Artist(
377 self._api,
378 subject = self,
379 name = a.findtext('name'),
380 mbid = a.findtext('mbid'),
381 stats = Stats(
382 subject = a.findtext('name'),
383 rank = a.attrib['rank'].strip() and int(a.attrib['rank']) or None,
384 playcount = a.findtext('playcount') and int(a.findtext('playcount')) or None
385 ),
386 url = a.findtext('url'),
387 streamable = (a.findtext('streamable') == "1"),
388 image = dict([(i.get('size'), i.text) for i in a.findall('image')]),
389 )
390 for a in data.findall('artist')
391 ]
392
393 @LastfmBase.cached_property
397
398 @LastfmBase.top_property("top_artists")
400 """top artist of the user"""
401 pass
402
403 @LastfmBase.cached_property
404 @LastfmBase.autheticate
406 params = {'method': 'user.getRecommendedArtists'}
407
408 @lazylist
409 def gen(lst):
410 data = self._api._fetch_data(params, sign = True, session = True).find('recommendations')
411 total_pages = int(data.attrib['totalPages'])
412
413 @lazylist
414 def gen2(lst, data):
415 for a in data.findall('artist'):
416 yield Artist(
417 self._api,
418 name = a.findtext('name'),
419 mbid = a.findtext('mbid'),
420 url = a.findtext('url'),
421 streamable = (a.findtext('streamable') == "1"),
422 image = dict([(i.get('size'), i.text) for i in a.findall('image')]),
423 )
424
425 for a in gen2(data):
426 yield a
427
428 for page in xrange(2, total_pages+1):
429 params.update({'page': page})
430 data = self._api._fetch_data(params, sign = True, session = True).find('recommendations')
431 for a in gen2(data):
432 yield a
433 return gen()
434
436 params = self._default_params({'method': 'user.getTopTracks'})
437 if period is not None:
438 params.update({'period': period})
439 data = self._api._fetch_data(params).find('toptracks')
440 return [
441 Track(
442 self._api,
443 subject = self,
444 name = t.findtext('name'),
445 artist = Artist(
446 self._api,
447 subject = self,
448 name = t.findtext('artist/name'),
449 mbid = t.findtext('artist/mbid'),
450 url = t.findtext('artist/url'),
451 ),
452 mbid = t.findtext('mbid'),
453 stats = Stats(
454 subject = t.findtext('name'),
455 rank = t.attrib['rank'].strip() and int(t.attrib['rank']) or None,
456 playcount = t.findtext('playcount') and int(t.findtext('playcount')) or None
457 ),
458 streamable = (t.findtext('streamable') == '1'),
459 full_track = (t.find('streamable').attrib['fulltrack'] == '1'),
460 image = dict([(i.get('size'), i.text) for i in t.findall('image')]),
461 )
462 for t in data.findall('track')
463 ]
464
465 @LastfmBase.cached_property
469
470 @LastfmBase.top_property("top_tracks")
474
493
494 @LastfmBase.cached_property
498
499 @LastfmBase.top_property("top_tags")
501 """top tag of the user"""
502 pass
503
504 @LastfmBase.cached_property
512
520
521 @LastfmBase.cached_property
524
525 @LastfmBase.cached_property
536 return gen()
537
545
546 @LastfmBase.cached_property
549
550 @LastfmBase.cached_property
561 return gen()
562
570
571 @LastfmBase.cached_property
574
575 @LastfmBase.cached_property
586 return gen()
587
593
594 @LastfmBase.cached_property
597
598 @LastfmBase.cached_property
609 return gen()
610
611 - def compare(self, other, limit = None):
616 @property
619
620
621 @staticmethod
636
638 if not self.name:
639 raise InvalidParametersError("user has to be provided.")
640 params = {'user': self.name}
641 params.update(extra_params)
642 return params
643
644 @staticmethod
646 try:
647 return hash(kwds['name'])
648 except KeyError:
649 raise InvalidParametersError("name has to be provided for hashing")
650
653
656
659
661 return "<lastfm.User: %s>" % self.name
662
663 - class Playlist(lastfm.playlist.Playlist):
664 """A class representing a playlist belonging to the user."""
665 - def init(self, api, id, title, date, size, creator):
672
673 @property
676
677 @property
680
681 @property
684
685 @property
688
689 @property
692
693 @property
696
697 @LastfmBase.autheticate
713
714 @staticmethod
716 try:
717 return hash(kwds['id'])
718 except KeyError:
719 raise InvalidParametersError("id has to be provided for hashing")
720
723
725 return "<lastfm.User.Playlist: %s>" % self.title
726
728 """A class representing the music library of the user."""
730 self._api = api
731 self._user = user
732
733 @property
736
739 params = self._default_params({'method': 'library.getAlbums'})
740 if limit is not None:
741 params.update({'limit': limit})
742
743 @lazylist
744 def gen(lst):
745 data = self._api._fetch_data(params).find('albums')
746 total_pages = int(data.attrib['totalPages'])
747
748 @lazylist
749 def gen2(lst, data):
750 for a in data.findall('album'):
751 yield Album(
752 self._api,
753 subject = self,
754 name = a.findtext('name'),
755 artist = Artist(
756 self._api,
757 subject = self,
758 name = a.findtext('artist/name'),
759 mbid = a.findtext('artist/mbid'),
760 url = a.findtext('artist/url'),
761 ),
762 mbid = a.findtext('mbid'),
763 url = a.findtext('url'),
764 image = dict([(i.get('size'), i.text) for i in a.findall('image')]),
765 stats = Stats(
766 subject = a.findtext('name'),
767 playcount = int(a.findtext('playcount')),
768 )
769 )
770
771
772 for a in gen2(data):
773 yield a
774
775 for page in xrange(2, total_pages+1):
776 params.update({'page': page})
777 try:
778 data = self._api._fetch_data(params).find('albums')
779 except LastfmError:
780 continue
781 for a in gen2(data):
782 yield a
783 return gen()
784
785 @LastfmBase.cached_property
788
789 @LastfmBase.autheticate
806
809 params = self._default_params({'method': 'library.getArtists'})
810 if limit is not None:
811 params.update({'limit': limit})
812
813 @lazylist
814 def gen(lst):
815 data = self._api._fetch_data(params).find('artists')
816 total_pages = int(data.attrib['totalPages'])
817
818 @lazylist
819 def gen2(lst, data):
820 for a in data.findall('artist'):
821 yield Artist(
822 self._api,
823 subject = self,
824 name = a.findtext('name'),
825 mbid = a.findtext('mbid'),
826 stats = Stats(
827 subject = a.findtext('name'),
828 playcount = a.findtext('playcount') and int(a.findtext('playcount')) or None,
829 tagcount = a.findtext('tagcount') and int(a.findtext('tagcount')) or None
830 ),
831 url = a.findtext('url'),
832 streamable = (a.findtext('streamable') == "1"),
833 image = dict([(i.get('size'), i.text) for i in a.findall('image')]),
834 )
835
836 for a in gen2(data):
837 yield a
838
839 for page in xrange(2, total_pages+1):
840 params.update({'page': page})
841 try:
842 data = self._api._fetch_data(params).find('artists')
843 except LastfmError:
844 continue
845 for a in gen2(data):
846 yield a
847 return gen()
848
849 @LastfmBase.cached_property
852
853 @LastfmBase.autheticate
855 params = {'method': 'library.addArtist'}
856 if isinstance(artist, Artist):
857 params['artist'] = artist.name
858 else:
859 params['artist'] = artist
860 self._api._post_data(params)
861 self._artists = None
862
865 params = self._default_params({'method': 'library.getTracks'})
866 if limit is not None:
867 params.update({'limit': limit})
868
869 @lazylist
870 def gen(lst):
871 data = self._api._fetch_data(params).find('tracks')
872 total_pages = int(data.attrib['totalPages'])
873
874 @lazylist
875 def gen2(lst, data):
876 for t in data.findall('track'):
877 yield Track(
878 self._api,
879 subject = self,
880 name = t.findtext('name'),
881 artist = Artist(
882 self._api,
883 subject = self,
884 name = t.findtext('artist/name'),
885 mbid = t.findtext('artist/mbid'),
886 url = t.findtext('artist/url'),
887 ),
888 mbid = t.findtext('mbid'),
889 stats = Stats(
890 subject = t.findtext('name'),
891 playcount = t.findtext('playcount') and int(t.findtext('playcount')) or None,
892 tagcount = t.findtext('tagcount') and int(t.findtext('tagcount')) or None
893 ),
894 streamable = (t.findtext('streamable') == '1'),
895 full_track = (t.find('streamable').attrib['fulltrack'] == '1'),
896 image = dict([(i.get('size'), i.text) for i in t.findall('image')]),
897 )
898
899 for t in gen2(data):
900 yield t
901
902 for page in xrange(2, total_pages+1):
903 params.update({'page': page})
904 data = None
905 try:
906 data = self._api._fetch_data(params).find('tracks')
907 except LastfmError:
908 continue
909 for t in gen2(data):
910 yield t
911 return gen()
912
913 @LastfmBase.cached_property
916
917 @LastfmBase.autheticate
933
940
941 @staticmethod
943 try:
944 return hash(kwds['user'])
945 except KeyError:
946 raise InvalidParametersError("user has to be provided for hashing")
947
950
952 return "<lastfm.User.Library: for user '%s'>" % self.user.name
953
954 from datetime import datetime
955 import time
956
957 from lastfm.api import Api
958 from lastfm.artist import Artist
959 from lastfm.album import Album
960 from lastfm.error import LastfmError, InvalidParametersError
961 from lastfm.event import Event
962 from lastfm.geo import Country
963 from lastfm.stats import Stats
964 from lastfm.tag import Tag
965 from lastfm.tasteometer import Tasteometer
966 from lastfm.track import Track
967 from lastfm.weeklychart import WeeklyChart, WeeklyAlbumChart, WeeklyArtistChart, WeeklyTrackChart, WeeklyTagChart
968