]> kaliko git repositories - mpd-sima.git/blobdiff - sima/lib/simaecho.py
Fixed blacklisting in track mode
[mpd-sima.git] / sima / lib / simaecho.py
index 716a43eb169094bf7e8d0c67963484f4197a436d..bbfc11416d8fafd8a4f7eaa4b1e064af924848d5 100644 (file)
@@ -25,15 +25,14 @@ __version__ = '0.0.1'
 __author__ = 'Jack Kaliko'
 
 
 __author__ = 'Jack Kaliko'
 
 
-import logging
-
 from datetime import datetime, timedelta
 from datetime import datetime, timedelta
-from time import sleep
 
 from requests import get, Request, Timeout, ConnectionError
 
 from sima import ECH
 from sima.lib.meta import Artist
 
 from requests import get, Request, Timeout, ConnectionError
 
 from sima import ECH
 from sima.lib.meta import Artist
+from sima.lib.track import Track
+from sima.utils.utils import WSError, WSNotFound, WSTimeout, WSHTTPError
 from sima.utils.utils import getws, Throttle, Cache, purge_cache
 if len(ECH.get('apikey')) == 23:  # simple hack allowing imp.reload
     getws(ECH)
 from sima.utils.utils import getws, Throttle, Cache, purge_cache
 if len(ECH.get('apikey')) == 23:  # simple hack allowing imp.reload
     getws(ECH)
@@ -43,25 +42,14 @@ WAIT_BETWEEN_REQUESTS = timedelta(0, 1)
 SOCKET_TIMEOUT = 4
 
 
 SOCKET_TIMEOUT = 4
 
 
-class EchoError(Exception):
-    pass
-
-class EchoNotFound(EchoError):
-    pass
-
-class EchoTimeout(EchoError):
-    pass
-
-class EchoHTTPError(EchoError):
-    pass
-
-class SimaEch():
-    """
+class SimaEch:
+    """EchoNest http client
     """
     root_url = 'http://{host}/api/{version}'.format(**ECH)
     cache = {}
     timestamp = datetime.utcnow()
     ratelimit = None
     """
     root_url = 'http://{host}/api/{version}'.format(**ECH)
     cache = {}
     timestamp = datetime.utcnow()
     ratelimit = None
+    name = 'EchoNest'
 
     def __init__(self, cache=True):
         self.artist = None
 
     def __init__(self, cache=True):
         self.artist = None
@@ -77,21 +65,21 @@ class SimaEch():
             self.current_element = SimaEch.cache.get(url).elem
             return
         try:
             self.current_element = SimaEch.cache.get(url).elem
             return
         try:
-            self._fetch_ech(payload)
+            self._fetch_ws(payload)
         except Timeout:
         except Timeout:
-            raise EchoTimeout('Failed to reach server within {0}s'.format(
+            raise WSTimeout('Failed to reach server within {0}s'.format(
                                SOCKET_TIMEOUT))
         except ConnectionError as err:
                                SOCKET_TIMEOUT))
         except ConnectionError as err:
-            raise EchoError(err)
+            raise WSError(err)
 
     @Throttle(WAIT_BETWEEN_REQUESTS)
 
     @Throttle(WAIT_BETWEEN_REQUESTS)
-    def _fetch_ech(self, payload):
+    def _fetch_ws(self, payload):
         """fetch from web service"""
         req = get(self._ressource, params=payload,
                             timeout=SOCKET_TIMEOUT)
         self.__class__.ratelimit = req.headers.get('x-ratelimit-remaining', None)
         if req.status_code is not 200:
         """fetch from web service"""
         req = get(self._ressource, params=payload,
                             timeout=SOCKET_TIMEOUT)
         self.__class__.ratelimit = req.headers.get('x-ratelimit-remaining', None)
         if req.status_code is not 200:
-            raise EchoHTTPError(req.status_code)
+            raise WSHTTPError('{0.status_code}: {0.reason}'.format(req))
         self.current_element = req.json()
         self._controls_answer()
         if self.caching:
         self.current_element = req.json()
         self._controls_answer()
         if self.caching:
@@ -106,11 +94,11 @@ class SimaEch():
         if code is 0:
             return True
         if code is 5:
         if code is 0:
             return True
         if code is 5:
-            raise EchoNotFound('Artist not found: "{0}"'.format(self.artist))
-        raise EchoError(status.get('message'))
+            raise WSNotFound('Artist not found: "{0}"'.format(self.artist))
+        raise WSError(status.get('message'))
 
 
-    def _forge_payload(self, artist):
-        """
+    def _forge_payload(self, artist, top=False):
+        """Build payload
         """
         payload = {'api_key': ECH.get('apikey')}
         if not isinstance(artist, Artist):
         """
         payload = {'api_key': ECH.get('apikey')}
         if not isinstance(artist, Artist):
@@ -120,13 +108,22 @@ class SimaEch():
             payload.update(
                     id='musicbrainz:artist:{0}'.format(artist.mbid))
         else:
             payload.update(
                     id='musicbrainz:artist:{0}'.format(artist.mbid))
         else:
-           payload.update(name=artist.name)
+            payload.update(name=artist.name)
         payload.update(bucket='id:musicbrainz')
         payload.update(results=100)
         payload.update(bucket='id:musicbrainz')
         payload.update(results=100)
+        if top:
+            if artist.mbid:
+                aid = payload.pop('id')
+                payload.update(artist_id=aid)
+            else:
+                name = payload.pop('name')
+                payload.update(artist=name)
+            payload.update(results=100)
+            payload.update(sort='song_hotttnesss-desc')
         return payload
 
     def get_similar(self, artist=None):
         return payload
 
     def get_similar(self, artist=None):
-        """
+        """Fetch similar artists
         """
         payload = self._forge_payload(artist)
         # Construct URL
         """
         payload = self._forge_payload(artist)
         # Construct URL
@@ -142,6 +139,24 @@ class SimaEch():
                                           ).lstrip('musicbrainz:artist:')
             yield Artist(mbid=mbid, name=art.get('name'))
 
                                           ).lstrip('musicbrainz:artist:')
             yield Artist(mbid=mbid, name=art.get('name'))
 
+    def get_toptrack(self, artist=None):
+        """Fetch artist top tracks
+        """
+        payload = self._forge_payload(artist, top=True)
+        # Construct URL
+        self._ressource = '{0}/song/search'.format(SimaEch.root_url)
+        self._fetch(payload)
+        titles = list()
+        artist = {
+                'artist': artist.name,
+                'musicbrainz_artistid': artist.mbid,
+                }
+        for song in self.current_element.get('response').get('songs'):
+            title = song.get('title')
+            if title not in titles:
+                titles.append(title)
+                yield Track(title=title, **artist)
+
 
 # VIM MODLINE
 # vim: ai ts=4 sw=4 sts=4 expandtab
 
 # VIM MODLINE
 # vim: ai ts=4 sw=4 sts=4 expandtab