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, Searchable, Sharable, Taggable
9 from lastfm.lazylist import lazylist
10
11 -class Track(LastfmBase, Cacheable, Sharable, Searchable, Taggable):
12 """A class representing a track."""
13 - def init(self,
14 api,
15 name = None,
16 mbid = None,
17 url = None,
18 duration = None,
19 streamable = None,
20 full_track = None,
21 artist = None,
22 album = None,
23 position = None,
24 image = None,
25 stats = None,
26 played_on = None,
27 loved_on = None,
28 wiki = None):
29 if not isinstance(api, Api):
30 raise InvalidParametersError("api reference must be supplied as an argument")
31 Taggable.init(self, api)
32 Sharable.init(self, api)
33 self._api = api
34 self._id = id
35 self._name = name
36 self._mbid = mbid
37 self._url = url
38 self._duration = duration
39 self._streamable = streamable
40 self._full_track = full_track
41 self._artist = artist
42 self._album = album
43 self._position = position
44 self._image = image
45 self._stats = stats and Stats(
46 subject = self,
47 match = stats.match,
48 playcount = stats.playcount,
49 rank = stats.rank,
50 listeners = stats.listeners,
51 )
52 self._played_on = played_on
53 self._loved_on = loved_on
54 self._wiki = wiki and Wiki(
55 subject = self,
56 published = wiki.published,
57 summary = wiki.summary,
58 content = wiki.content
59 )
60
61 @property
63 """id of the track"""
64 return self._id
65
66 @property
68 """name of the track"""
69 return self._name
70
71 @property
73 """mbid of the track"""
74 return self._mbid
75
76 @property
78 """url of the tracks's page"""
79 return self._url
80
81 @property
83 """duration of the tracks's page"""
84 return self._duration
85
86 @property
88 """is the track streamable"""
89 if self._streamable is None:
90 self._fill_info()
91 return self._streamable
92
93 @property
95 """is the full track streamable"""
96 if self._full_track is None:
97 self._fill_info()
98 return self._full_track
99
100 @property
102 """artist of the track"""
103 return self._artist
104
105 @property
107 """artist of the track"""
108 if self._album is None:
109 self._fill_info()
110 return self._album
111
112 @property
114 """position of the track"""
115 if self._position is None:
116 self._fill_info()
117 return self._position
118
119 @property
121 """image of the track's album cover"""
122 return self._image
123
124 @property
126 """stats of the track"""
127 return self._stats
128
129 @property
131 """datetime the track was last played"""
132 return self._played_on
133
134 @property
136 """datetime the track was marked 'loved'"""
137 return self._loved_on
138
139 @property
141 """wiki of the track"""
142 if self._wiki == "na":
143 return None
144 if self._wiki is None:
145 self._fill_info()
146 return self._wiki
147
148 @LastfmBase.cached_property
150 """tracks similar to this track"""
151 params = Track._check_params(
152 {'method': 'track.getSimilar'},
153 self.artist.name,
154 self.name,
155 self.mbid
156 )
157 data = self._api._fetch_data(params).find('similartracks')
158 return [
159 Track(
160 self._api,
161 subject = self,
162 name = t.findtext('name'),
163 artist = Artist(
164 self._api,
165 subject = self,
166 name = t.findtext('artist/name'),
167 mbid = t.findtext('artist/mbid'),
168 url = t.findtext('artist/url')
169 ),
170 mbid = t.findtext('mbid'),
171 stats = Stats(
172 subject = t.findtext('name'),
173 match = float(t.findtext('match'))
174 ),
175 streamable = (t.findtext('streamable') == '1'),
176 full_track = (t.find('streamable').attrib['fulltrack'] == '1'),
177 image = dict([(i.get('size'), i.text) for i in t.findall('image')]),
178 )
179 for t in data.findall('track')
180 ]
181
182 @LastfmBase.top_property("similar")
184 """track most similar to this track"""
185 pass
186
187 @LastfmBase.cached_property
189 """top fans of the track"""
190 params = Track._check_params(
191 {'method': 'track.getTopFans'},
192 self.artist.name,
193 self.name,
194 self.mbid
195 )
196 data = self._api._fetch_data(params).find('topfans')
197 return [
198 User(
199 self._api,
200 subject = self,
201 name = u.findtext('name'),
202 url = u.findtext('url'),
203 image = dict([(i.get('size'), i.text) for i in u.findall('image')]),
204 stats = Stats(
205 subject = u.findtext('name'),
206 weight = int(u.findtext('weight'))
207 )
208 )
209 for u in data.findall('user')
210 ]
211
212 @LastfmBase.top_property("top_fans")
214 """topmost fan of the track"""
215 pass
216
217 @LastfmBase.cached_property
240
241 @LastfmBase.top_property("top_tags")
243 """topmost tag for the track"""
244 pass
245
249
253
254 @staticmethod
255 - def get_info(api,
256 artist = None,
257 track = None,
258 mbid = None):
270
277
278 @staticmethod
280 return Track(
281 api,
282 name = track.findtext('name'),
283 artist = Artist(
284 api,
285 name=track.findtext('artist')
286 ),
287 url = track.findtext('url'),
288 stats = Stats(
289 subject=track.findtext('name'),
290 listeners=int(track.findtext('listeners'))
291 ),
292 streamable = (track.findtext('streamable') == '1'),
293 full_track = (track.find('streamable').attrib['fulltrack'] == '1'),
294 image = dict([(i.get('size'), i.text) for i in track.findall('image')]),
295 )
296
297 @staticmethod
298 - def _fetch_data(api,
299 artist = None,
300 track = None,
301 mbid = None):
304
306 data = Track._fetch_data(self._api, self.artist.name, self.name)
307 self._id = int(data.findtext('id'))
308 self._mbid = data.findtext('mbid')
309 self._url = data.findtext('url')
310 self._duration = int(data.findtext('duration'))
311 self._streamable = (data.findtext('streamable') == '1')
312 self._full_track = (data.find('streamable').attrib['fulltrack'] == '1')
313
314 self._image = dict([(i.get('size'), i.text) for i in data.findall('image')])
315 self._stats = Stats(
316 subject = self,
317 listeners = int(data.findtext('listeners')),
318 playcount = int(data.findtext('playcount')),
319 )
320 self._artist = Artist(
321 self._api,
322 name = data.findtext('artist/name'),
323 mbid = data.findtext('artist/mbid'),
324 url = data.findtext('artist/url')
325 )
326 if data.find('album') is not None:
327 self._album = Album(
328 self._api,
329 artist = self._artist,
330 name = data.findtext('album/title'),
331 mbid = data.findtext('album/mbid'),
332 url = data.findtext('album/url'),
333 image = dict([(i.get('size'), i.text) for i in data.findall('album/image')])
334 )
335 self._position = data.find('album').attrib['position'].strip() \
336 and int(data.find('album').attrib['position'])
337 if data.find('wiki') is not None:
338 self._wiki = Wiki(
339 self,
340 published = datetime(*(time.strptime(
341 data.findtext('wiki/published').strip(),
342 '%a, %d %b %Y %H:%M:%S +0000'
343 )[0:6])),
344 summary = data.findtext('wiki/summary'),
345 content = data.findtext('wiki/content')
346 )
347 else:
348 self._wiki = 'na'
349
350 @staticmethod
351 - def _check_params(params,
352 artist = None,
353 track = None,
354 mbid = None):
363
364 @staticmethod
366 try:
367 return hash("%s%s" % (kwds['name'], hash(kwds['artist'])))
368 except KeyError:
369 raise InvalidParametersError("name and artist have to be provided for hashing")
370
373
382
385
387 return "<lastfm.Track: '%s' by %s>" % (self.name, self.artist.name)
388
389 import time
390 from datetime import datetime
391
392 from lastfm.api import Api
393 from lastfm.artist import Artist
394 from lastfm.album import Album
395 from lastfm.error import InvalidParametersError
396 from lastfm.stats import Stats
397 from lastfm.tag import Tag
398 from lastfm.user import User
399 from lastfm.wiki import Wiki
400