python-lastfm/lastfm/tag.py

241 lines
8.8 KiB
Python

#!/usr/bin/env python
__author__ = "Abhinav Sarkar <abhinav@abhinavsarkar.net>"
__version__ = "0.2"
__license__ = "GNU Lesser General Public License"
__package__ = "lastfm"
from lastfm.base import LastfmBase
from lastfm.mixins import (
Cacheable, Searchable, ArtistChartable)
from lastfm.decorators import cached_property, top_property
class Tag(LastfmBase, Cacheable, Searchable, ArtistChartable):
"""A class representing a tag."""
def init(self,
api,
name = None,
url = None,
streamable = None,
stats = None,
**kwargs):
if not isinstance(api, Api):
raise InvalidParametersError("api reference must be supplied as an argument")
ArtistChartable.init(self, api)
self._api = api
self._name = name
self._url = url
self._streamable = streamable
self._stats = stats and Stats(
subject = self,
count = stats.count,
rank = stats.rank
)
@property
def name(self):
"""name of the tag"""
return self._name
@property
def url(self):
"""url of the tag's page"""
return self._url
@property
def streamable(self):
"""is the tag streamable"""
return self._streamable
@property
def stats(self):
return self._stats
@cached_property
def similar(self):
"""tags similar to this tag"""
params = self._default_params({'method': 'tag.getSimilar'})
data = self._api._fetch_data(params).find('similartags')
return [
Tag(
self._api,
subject = self,
name = t.findtext('name'),
url = t.findtext('url'),
streamable = (t.findtext('streamable') == "1"),
)
for t in data.findall('tag')
]
@top_property("similar")
def most_similar(self):
"""most similar tag to this tag"""
pass
@cached_property
def top_albums(self):
"""top albums for the tag"""
params = self._default_params({'method': 'tag.getTopAlbums'})
data = self._api._fetch_data(params).find('topalbums')
return [
Album(
self._api,
subject = self,
name = a.findtext('name'),
artist = Artist(
self._api,
subject = self,
name = a.findtext('artist/name'),
mbid = a.findtext('artist/mbid'),
url = a.findtext('artist/url'),
),
mbid = a.findtext('mbid'),
url = a.findtext('url'),
image = dict([(i.get('size'), i.text) for i in a.findall('image')]),
stats = Stats(
subject = a.findtext('name'),
tagcount = a.findtext('tagcount') and int(a.findtext('tagcount')) or None,
rank = a.attrib['rank'].strip() and int(a.attrib['rank']) or None
)
)
for a in data.findall('album')
]
@top_property("top_albums")
def top_album(self):
"""top album for the tag"""
pass
@cached_property
def top_artists(self):
"""top artists for the tag"""
params = self._default_params({'method': 'tag.getTopArtists'})
data = self._api._fetch_data(params).find('topartists')
return [
Artist(
self._api,
subject = self,
name = a.findtext('name'),
mbid = a.findtext('mbid'),
stats = Stats(
subject = a.findtext('name'),
rank = a.attrib['rank'].strip() and int(a.attrib['rank']) or None,
tagcount = a.findtext('tagcount') and int(a.findtext('tagcount')) or None
),
url = a.findtext('url'),
streamable = (a.findtext('streamable') == "1"),
image = dict([(i.get('size'), i.text) for i in a.findall('image')]),
)
for a in data.findall('artist')
]
@top_property("top_artists")
def top_artist(self):
"""top artist for the tag"""
pass
@cached_property
def top_tracks(self):
"""top tracks for the tag"""
params = self._default_params({'method': 'tag.getTopTracks'})
data = self._api._fetch_data(params).find('toptracks')
return [
Track(
self._api,
subject = self,
name = t.findtext('name'),
artist = Artist(
self._api,
subject = self,
name = t.findtext('artist/name'),
mbid = t.findtext('artist/mbid'),
url = t.findtext('artist/url'),
),
mbid = t.findtext('mbid'),
stats = Stats(
subject = t.findtext('name'),
rank = t.attrib['rank'].strip() and int(t.attrib['rank']) or None,
tagcount = t.findtext('tagcount') and int(t.findtext('tagcount')) or None
),
streamable = (t.findtext('streamable') == '1'),
full_track = (t.find('streamable').attrib['fulltrack'] == '1'),
image = dict([(i.get('size'), i.text) for i in t.findall('image')]),
)
for t in data.findall('track')
]
@top_property("top_tracks")
def top_track(self):
"""top track for the tag"""
pass
@cached_property
def playlist(self):
return Playlist.fetch(self._api,
"lastfm://playlist/tag/%s/freetracks" % self.name)
@staticmethod
def get_top_tags(api):
params = {'method': 'tag.getTopTags'}
data = api._fetch_data(params).find('toptags')
return [
Tag(
api,
name = t.findtext('name'),
url = t.findtext('url'),
stats = Stats(
subject = t.findtext('name'),
count = int(t.findtext('count')),
)
)
for t in data.findall('tag')
]
def _default_params(self, extra_params = None):
if not self.name:
raise InvalidParametersError("tag has to be provided.")
params = {'tag': self.name}
if extra_params is not None:
params.update(extra_params)
return params
@staticmethod
def _search_yield_func(api, tag):
return Tag(
api,
name = tag.findtext('name'),
url = tag.findtext('url'),
stats = Stats(
subject = tag.findtext('name'),
count = int(tag.findtext('count')),
)
)
@staticmethod
def _hash_func(*args, **kwds):
try:
return hash(kwds['name'])
except KeyError:
raise InvalidParametersError("name has to be provided for hashing")
def __hash__(self):
return self.__class__._hash_func(name = self.name)
def __eq__(self, other):
return self.name == other.name
def __lt__(self, other):
return self.name < other.name
def __repr__(self):
return "<lastfm.Tag: %s>" % self.name
from lastfm.album import Album
from lastfm.api import Api
from lastfm.artist import Artist
from lastfm.error import LastfmError, InvalidParametersError
from lastfm.playlist import Playlist
from lastfm.stats import Stats
from lastfm.track import Track
from lastfm.chart import WeeklyChart, WeeklyArtistChart