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

Source Code for Module lastfm.track

  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, Searchable, Sharable, Taggable 
  9  from lastfm.lazylist import lazylist 
 10  from lastfm.decorators import cached_property, top_property 
11 12 -class Track(LastfmBase, Cacheable, Sharable, Searchable, Taggable):
13 """A class representing a track."""
14 - def init(self, 15 api, 16 name = None, 17 mbid = None, 18 url = None, 19 duration = None, 20 streamable = None, 21 full_track = None, 22 artist = None, 23 album = None, 24 position = None, 25 image = None, 26 stats = None, 27 played_on = None, 28 loved_on = None, 29 wiki = None, 30 subject = None):
31 if not isinstance(api, Api): 32 raise InvalidParametersError("api reference must be supplied as an argument") 33 Taggable.init(self, api) 34 Sharable.init(self, api) 35 self._api = api 36 self._id = id 37 self._name = name 38 self._mbid = mbid 39 self._url = url 40 self._duration = duration 41 self._streamable = streamable 42 self._full_track = full_track 43 self._artist = artist 44 self._album = album 45 self._position = position 46 self._image = image 47 self._stats = stats and Stats( 48 subject = self, 49 match = stats.match, 50 playcount = stats.playcount, 51 rank = stats.rank, 52 listeners = stats.listeners, 53 ) 54 self._played_on = played_on 55 self._loved_on = loved_on 56 self._wiki = wiki and Wiki( 57 subject = self, 58 published = wiki.published, 59 summary = wiki.summary, 60 content = wiki.content 61 ) 62 self._subject = subject
63 64 @property
65 - def id(self):
66 """id of the track""" 67 return self._id
68 69 @property
70 - def name(self):
71 """name of the track""" 72 return self._name
73 74 @property
75 - def mbid(self):
76 """mbid of the track""" 77 return self._mbid
78 79 @property
80 - def url(self):
81 """url of the tracks's page""" 82 return self._url
83 84 @property
85 - def duration(self):
86 """duration of the tracks's page""" 87 return self._duration
88 89 @property
90 - def streamable(self):
91 """is the track streamable""" 92 if self._streamable is None: 93 self._fill_info() 94 return self._streamable
95 96 @property
97 - def full_track(self):
98 """is the full track streamable""" 99 if self._full_track is None: 100 self._fill_info() 101 return self._full_track
102 103 @property
104 - def artist(self):
105 """artist of the track""" 106 return self._artist
107 108 @property
109 - def album(self):
110 """artist of the track""" 111 if self._album is None: 112 self._fill_info() 113 return self._album
114 115 @property
116 - def position(self):
117 """position of the track""" 118 if self._position is None: 119 self._fill_info() 120 return self._position
121 122 @property
123 - def image(self):
124 """image of the track's album cover""" 125 return self._image
126 127 @property
128 - def stats(self):
129 """stats of the track""" 130 return self._stats
131 132 @property
133 - def played_on(self):
134 """datetime the track was last played""" 135 return self._played_on
136 137 @property
138 - def loved_on(self):
139 """datetime the track was marked 'loved'""" 140 return self._loved_on
141 142 @property
143 - def wiki(self):
144 """wiki of the track""" 145 if self._wiki == "na": 146 return None 147 if self._wiki is None: 148 self._fill_info() 149 return self._wiki
150 151 @cached_property
152 - def similar(self):
153 """tracks similar to this track""" 154 params = Track._check_params( 155 {'method': 'track.getSimilar'}, 156 self.artist.name, 157 self.name, 158 self.mbid 159 ) 160 data = self._api._fetch_data(params).find('similartracks') 161 return [ 162 Track( 163 self._api, 164 subject = self, 165 name = t.findtext('name'), 166 artist = Artist( 167 self._api, 168 subject = self, 169 name = t.findtext('artist/name'), 170 mbid = t.findtext('artist/mbid'), 171 url = t.findtext('artist/url') 172 ), 173 mbid = t.findtext('mbid'), 174 stats = Stats( 175 subject = t.findtext('name'), 176 match = float(t.findtext('match')) 177 ), 178 streamable = (t.findtext('streamable') == '1'), 179 full_track = (t.find('streamable').attrib['fulltrack'] == '1'), 180 image = dict([(i.get('size'), i.text) for i in t.findall('image')]), 181 ) 182 for t in data.findall('track') 183 ]
184 185 @top_property("similar")
186 - def most_similar(self):
187 """track most similar to this track""" 188 pass
189 190 @cached_property
191 - def top_fans(self):
192 """top fans of the track""" 193 params = Track._check_params( 194 {'method': 'track.getTopFans'}, 195 self.artist.name, 196 self.name, 197 self.mbid 198 ) 199 data = self._api._fetch_data(params).find('topfans') 200 return [ 201 User( 202 self._api, 203 subject = self, 204 name = u.findtext('name'), 205 url = u.findtext('url'), 206 image = dict([(i.get('size'), i.text) for i in u.findall('image')]), 207 stats = Stats( 208 subject = u.findtext('name'), 209 weight = int(u.findtext('weight')) 210 ) 211 ) 212 for u in data.findall('user') 213 ]
214 215 @top_property("top_fans")
216 - def top_fan(self):
217 """topmost fan of the track""" 218 pass
219 220 @cached_property
221 - def top_tags(self):
222 """top tags for the track""" 223 params = Track._check_params( 224 {'method': 'track.getTopTags'}, 225 self.artist.name, 226 self.name, 227 self.mbid 228 ) 229 data = self._api._fetch_data(params).find('toptags') 230 return [ 231 Tag( 232 self._api, 233 subject = self, 234 name = t.findtext('name'), 235 url = t.findtext('url'), 236 stats = Stats( 237 subject = t.findtext('name'), 238 count = int(t.findtext('count')), 239 ) 240 ) 241 for t in data.findall('tag') 242 ]
243 244 @top_property("top_tags")
245 - def top_tag(self):
246 """topmost tag for the track""" 247 pass
248
249 - def love(self):
250 params = self._default_params({'method': 'track.love'}) 251 self._api._post_data(params)
252
253 - def ban(self):
254 params = self._default_params({'method': 'track.ban'}) 255 self._api._post_data(params)
256 257 @staticmethod
258 - def get_info(api, 259 artist = None, 260 track = None, 261 mbid = None):
262 data = Track._fetch_data(api, artist, track, mbid) 263 t = Track( 264 api, 265 name = data.findtext('name'), 266 artist = Artist( 267 api, 268 name = data.findtext('artist/name'), 269 ), 270 ) 271 t._fill_info() 272 return t
273
274 - def _default_params(self, extra_params = {}):
275 if not (self.artist and self.name): 276 raise InvalidParametersError("artist and track have to be provided.") 277 params = {'artist': self.artist.name, 'track': self.name} 278 params.update(extra_params) 279 return params
280 281 @staticmethod
282 - def _search_yield_func(api, track):
283 return Track( 284 api, 285 name = track.findtext('name'), 286 artist = Artist( 287 api, 288 name=track.findtext('artist') 289 ), 290 url = track.findtext('url'), 291 stats = Stats( 292 subject=track.findtext('name'), 293 listeners=int(track.findtext('listeners')) 294 ), 295 streamable = (track.findtext('streamable') == '1'), 296 full_track = (track.find('streamable').attrib['fulltrack'] == '1'), 297 image = dict([(i.get('size'), i.text) for i in track.findall('image')]), 298 )
299 300 @staticmethod
301 - def _fetch_data(api, 302 artist = None, 303 track = None, 304 mbid = None):
305 params = Track._check_params({'method': 'track.getInfo'}, artist, track, mbid) 306 return api._fetch_data(params).find('track')
307
308 - def _fill_info(self):
309 data = Track._fetch_data(self._api, self.artist.name, self.name) 310 self._id = int(data.findtext('id')) 311 self._mbid = data.findtext('mbid') 312 self._url = data.findtext('url') 313 self._duration = int(data.findtext('duration')) 314 self._streamable = (data.findtext('streamable') == '1') 315 self._full_track = (data.find('streamable').attrib['fulltrack'] == '1') 316 317 self._image = dict([(i.get('size'), i.text) for i in data.findall('image')]) 318 self._stats = Stats( 319 subject = self, 320 listeners = int(data.findtext('listeners')), 321 playcount = int(data.findtext('playcount')), 322 ) 323 self._artist = Artist( 324 self._api, 325 name = data.findtext('artist/name'), 326 mbid = data.findtext('artist/mbid'), 327 url = data.findtext('artist/url') 328 ) 329 if data.find('album') is not None: 330 self._album = Album( 331 self._api, 332 artist = self._artist, 333 name = data.findtext('album/title'), 334 mbid = data.findtext('album/mbid'), 335 url = data.findtext('album/url'), 336 image = dict([(i.get('size'), i.text) for i in data.findall('album/image')]) 337 ) 338 self._position = data.find('album').attrib['position'].strip() \ 339 and int(data.find('album').attrib['position']) 340 if data.find('wiki') is not None: 341 self._wiki = Wiki( 342 self, 343 published = datetime(*(time.strptime( 344 data.findtext('wiki/published').strip(), 345 '%a, %d %b %Y %H:%M:%S +0000' 346 )[0:6])), 347 summary = data.findtext('wiki/summary'), 348 content = data.findtext('wiki/content') 349 ) 350 else: 351 self._wiki = 'na'
352 353 @staticmethod
354 - def _check_params(params, 355 artist = None, 356 track = None, 357 mbid = None):
358 if not ((artist and track) or mbid): 359 raise InvalidParametersError("either (artist and track) or mbid has to be given as argument.") 360 361 if artist and track: 362 params.update({'artist': artist, 'track': track}) 363 elif mbid: 364 params.update({'mbid': mbid}) 365 return params
366 367 @staticmethod
368 - def _hash_func(*args, **kwds):
369 try: 370 return hash("%s%s" % (kwds['name'], hash(kwds['artist']))) 371 except KeyError: 372 raise InvalidParametersError("name and artist have to be provided for hashing")
373
374 - def __hash__(self):
375 return self.__class__._hash_func(name = self.name, artist = self.artist)
376
377 - def __eq__(self, other):
378 if self.mbid and other.mbid: 379 return self.mbid == other.mbid 380 if self.url and other.url: 381 return self.url == other.url 382 if (self.name and self.artist) and (other.name and other.artist): 383 return (self.name == other.name) and (self.artist == other.artist) 384 return super(Track, self).__eq__(other)
385
386 - def __lt__(self, other):
387 return self.name < other.name
388
389 - def __repr__(self):
390 return "<lastfm.Track: '%s' by %s>" % (self.name, self.artist.name)
391 392 import time 393 from datetime import datetime 394 395 from lastfm.api import Api 396 from lastfm.artist import Artist 397 from lastfm.album import Album 398 from lastfm.error import InvalidParametersError 399 from lastfm.stats import Stats 400 from lastfm.tag import Tag 401 from lastfm.user import User 402 from lastfm.wiki import Wiki 403