# return the original handler
return False
- def add_headers(self, url):
- resp = self.cache.get(url)
- if resp and 'etag' in resp.headers:
- return {'If-None-Match': resp.headers['etag']}
- return {}
-
def cache_response(self, request, resp):
"""
Algorithm for caching requests.
class Meta:
"""Generic Class for Meta object
- Meta(name=<str>[, mbid=UUID4])
+
+ Using generic kwargs in constructor for convenience but the actual signature is:
+
+ >>> Meta(name, mbid=None, **kwargs)
+
+ :param string name: set name attribute
+ :param string mbid: set MusicBrainz ID (optional)
"""
use_mbid = True
def __init__(self, **kwargs):
+ """Meta(name=<str>[, mbid=UUID4])"""
self.__name = None #TODO: should be immutable
self.__mbid = None
self.__aliases = set()
class Album(Meta):
+ """Album object"""
@property
def album(self):
return self.name
class Artist(Meta):
+ """Artist object deriving from :class:`Meta`.
+
+ :param string name: Artist name, default ``None``
+ :param string mbid: Musicbrainz artist ID, defautl ``None``
+ :param string artist: Overrides "name" argument
+ :param string albumartist: Overrides "name" and "artist" argument
+ :param string musicbrainz_artistid: Overrides "mbid" argument
+ :param string musicbrainz_albumartistid: Overrides "musicbrainz_artistid" argument
+
+ :Example:
+
+ >>> trk = {'artist':'Art Name',
+ >>> 'albumartist': 'Alb Art Name', # optional
+ >>> 'musicbrainz_artistid': '<UUID4>', # optional
+ >>> 'musicbrainz_albumartistid': '<UUID4>', # optional
+ >>> }
+ >>> artobj0 = Artist(**trk)
+ >>> artobj1 = Artist(name='Tool')
+ """
@mbidfilter
def __init__(self, name=None, mbid=None, **kwargs):
- """Artist object built from a mapping dict containing at least an
- "artist" entry:
- >>> trk = {'artist':'Art Name',
- >>> 'albumartist': 'Alb Art Name', # optional
- >>> 'musicbrainz_artistid': '<UUID4>', # optional
- >>> 'musicbrainz_albumartistid': '<UUID4>', # optional
- >>> }
- >>> artobj0 = Artist(**trk)
- >>> artobj1 = Artist(name='Tool')
- """
if kwargs.get('artist', False):
name = kwargs.get('artist').split(SEPARATOR)[0]
if kwargs.get('musicbrainz_artistid', False):
# return a sorted list of 2-tuple to have consistent cache
return sorted(payload.items(), key=lambda param: param[0])
- def get_similar(self, artist=None):
+ def get_similar(self, artist):
"""Fetch similar artists
+
+ param: artist Artist: Artist object to get similarities from
"""
payload = self._forge_payload(artist)
# Construct URL
mbid = get_mbid(art)
yield Artist(mbid=mbid, name=art.get('name'))
- def get_toptrack(self, artist=None):
+ def get_toptrack(self, artist):
"""Fetch artist top tracks
+
+ param: artist Artist: Artist object to get top tracks from
"""
payload = self._forge_payload(artist, top=True)
# Construct URL
# return a sorted list of 2-tuple to have consistent cache
return sorted(payload.items(), key=lambda param: param[0])
- def get_similar(self, artist=None):
+ def get_similar(self, artist):
"""Fetch similar artists
+
+ :param Artist artist: :class:`Artist` to fetch similar artists from
+ :returns: generator of :class:`sima.lib.meta.Artist`
"""
payload = self._forge_payload(artist)
# Construct URL
for art in ans.json().get('similarartists').get('artist'): # pylint: disable=no-member
yield Artist(name=art.get('name'), mbid=art.get('mbid', None))
- def get_toptrack(self, artist=None):
+ def get_toptrack(self, artist):
"""Fetch artist top tracks
+
+ :param Artist artist: :class:`Artist` to fetch top tracks from
+ :returns: generator of :class:`sima.lib.track.Track`
"""
payload = self._forge_payload(artist, method='top')
ans = self.http(self.root_url, payload)
class Track:
"""
Track object.
- Instanciate with Player replies.
+ Instantiate with Player replies.
"""
def __init__(self, file=None, time=0, pos=-1, **kwargs):
# have tags been collapsed?
self.collapsed_tags = list()
# Needed for multiple tags which returns a list instead of a string
- self.collapse_tags()
+ self._collapse_tags()
- def collapse_tags(self):
+ def _collapse_tags(self):
"""
Necessary to deal with tags defined multiple times.
These entries are set as lists instead of strings.
"""set time property"""
self._time = int(value)
- time = property(get_time, set_time, doc='song duration in seconds')
+ time = property(get_time, set_time, doc='song duration in seconds (use :attr:`duration` for human readable time)')
@property
def duration(self):
- """Compute fancy duration"""
+ """Get a fancy duration %H:%M:%S (use :attr:`time` to get duration in second only)"""
temps = time.gmtime(int(self.time))
if temps.tm_hour:
fmt = '%H:%M:%S'
@property
def Artist(self):
- """Get artist object from track"""
+ """Get the :class:`sima.lib.meta.Artist` associated to this track"""
if not self.artist:
if not self.musicbrainz_artistid:
return Artist(name='[unknown]',