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 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
62 - def id(self):
63 """id of the track""" 64 return self._id
65 66 @property
67 - def name(self):
68 """name of the track""" 69 return self._name
70 71 @property
72 - def mbid(self):
73 """mbid of the track""" 74 return self._mbid
75 76 @property
77 - def url(self):
78 """url of the tracks's page""" 79 return self._url
80 81 @property
82 - def duration(self):
83 """duration of the tracks's page""" 84 return self._duration
85 86 @property
87 - def streamable(self):
88 """is the track streamable""" 89 if self._streamable is None: 90 self._fill_info() 91 return self._streamable
92 93 @property
94 - def full_track(self):
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
101 - def artist(self):
102 """artist of the track""" 103 return self._artist
104 105 @property
106 - def album(self):
107 """artist of the track""" 108 if self._album is None: 109 self._fill_info() 110 return self._album
111 112 @property
113 - def position(self):
114 """position of the track""" 115 if self._position is None: 116 self._fill_info() 117 return self._position
118 119 @property
120 - def image(self):
121 """image of the track's album cover""" 122 return self._image
123 124 @property
125 - def stats(self):
126 """stats of the track""" 127 return self._stats
128 129 @property
130 - def played_on(self):
131 """datetime the track was last played""" 132 return self._played_on
133 134 @property
135 - def loved_on(self):
136 """datetime the track was marked 'loved'""" 137 return self._loved_on
138 139 @property
140 - def wiki(self):
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
149 - def similar(self):
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")
183 - def most_similar(self):
184 """track most similar to this track""" 185 pass
186 187 @LastfmBase.cached_property
188 - def top_fans(self):
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")
213 - def top_fan(self):
214 """topmost fan of the track""" 215 pass
216 217 @LastfmBase.cached_property
218 - def top_tags(self):
219 """top tags for the track""" 220 params = Track._check_params( 221 {'method': 'track.getTopTags'}, 222 self.artist.name, 223 self.name, 224 self.mbid 225 ) 226 data = self._api._fetch_data(params).find('toptags') 227 return [ 228 Tag( 229 self._api, 230 subject = self, 231 name = t.findtext('name'), 232 url = t.findtext('url'), 233 stats = Stats( 234 subject = t.findtext('name'), 235 count = int(t.findtext('count')), 236 ) 237 ) 238 for t in data.findall('tag') 239 ]
240 241 @LastfmBase.top_property("top_tags")
242 - def top_tag(self):
243 """topmost tag for the track""" 244 pass
245
246 - def love(self):
247 params = self._default_params({'method': 'track.love'}) 248 self._api._post_data(params)
249
250 - def ban(self):
251 params = self._default_params({'method': 'track.ban'}) 252 self._api._post_data(params)
253 254 @staticmethod
255 - def get_info(api, 256 artist = None, 257 track = None, 258 mbid = None):
259 data = Track._fetch_data(api, artist, track, mbid) 260 t = Track( 261 api, 262 name = data.findtext('name'), 263 artist = Artist( 264 api, 265 name = data.findtext('artist/name'), 266 ), 267 ) 268 t._fill_info() 269 return t
270
271 - def _default_params(self, extra_params = {}):
272 if not (self.artist and self.name): 273 raise InvalidParametersError("artist and track have to be provided.") 274 params = {'artist': self.artist.name, 'track': self.name} 275 params.update(extra_params) 276 return params
277 278 @staticmethod
279 - def _search_yield_func(api, track):
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):
302 params = Track._check_params({'method': 'track.getInfo'}, artist, track, mbid) 303 return api._fetch_data(params).find('track')
304
305 - def _fill_info(self):
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):
355 if not ((artist and track) or mbid): 356 raise InvalidParametersError("either (artist and track) or mbid has to be given as argument.") 357 358 if artist and track: 359 params.update({'artist': artist, 'track': track}) 360 elif mbid: 361 params.update({'mbid': mbid}) 362 return params
363 364 @staticmethod
365 - def _hash_func(*args, **kwds):
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
371 - def __hash__(self):
372 return self.__class__._hash_func(name = self.name, artist = self.artist)
373
374 - def __eq__(self, other):
375 if self.mbid and other.mbid: 376 return self.mbid == other.mbid 377 if self.url and other.url: 378 return self.url == other.url 379 if (self.name and self.artist) and (other.name and other.artist): 380 return (self.name == other.name) and (self.artist == other.artist) 381 return super(Track, self).__eq__(other)
382
383 - def __lt__(self, other):
384 return self.name < other.name
385
386 - def __repr__(self):
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