]> kaliko git repositories - mpd-sima.git/blobdiff - sima/lib/simaecho.py
Fixed a stupid missing return
[mpd-sima.git] / sima / lib / simaecho.py
index 2706513b47c5f8d0ad2114ed316769fa493b2774..147c624578f74de13f44ef54dd20d6d07ce10861 100644 (file)
 Consume EchoNest web service
 """
 
 Consume EchoNest web service
 """
 
-__version__ = '0.0.2'
+__version__ = '0.0.5'
 __author__ = 'Jack Kaliko'
 
 
 __author__ = 'Jack Kaliko'
 
 
-from datetime import timedelta
-
-from requests import Session, Request, Timeout, ConnectionError
 
 from sima import ECH
 from sima.lib.meta import Artist
 from sima.lib.track import Track
 
 from sima import ECH
 from sima.lib.meta import Artist
 from sima.lib.track import Track
-from sima.lib.http import CacheController
-from sima.utils.utils import WSError, WSNotFound, WSTimeout, WSHTTPError
-from sima.utils.utils import getws, Throttle
+from sima.lib.http import HttpClient
+from sima.utils.utils import WSError, WSNotFound
+from sima.utils.utils import getws
 if len(ECH.get('apikey')) == 23:  # simple hack allowing imp.reload
     getws(ECH)
 
 if len(ECH.get('apikey')) == 23:  # simple hack allowing imp.reload
     getws(ECH)
 
-# Some definitions
-WAIT_BETWEEN_REQUESTS = timedelta(0, 2)
-SOCKET_TIMEOUT = 6
+
+def get_mbid(obj, foreign='foreign_ids'):
+    if foreign in obj:
+        for frgnid in obj.get(foreign):
+            if frgnid.get('catalog') == 'musicbrainz':
+                return frgnid.get('foreign_id').split(':')[2]
+    return None
 
 
 class SimaEch:
 
 
 class SimaEch:
@@ -51,52 +52,12 @@ class SimaEch:
     name = 'EchoNest'
     cache = False
     stats = {'etag':0,
     name = 'EchoNest'
     cache = False
     stats = {'etag':0,
-            'ccontrol':0,
-            'minrl':120,
-            'total':0}
+             'ccontrol':0,
+             'minrl':120,
+             'total':0}
 
     def __init__(self):
 
     def __init__(self):
-        self.controller = CacheController(self.cache)
-
-    def _fetch(self, ressource, payload):
-        """
-        Prepare http request
-        Use cached elements or proceed http request
-        """
-        req = Request('GET', ressource, params=payload,
-                      ).prepare()
-        SimaEch.stats.update(total=SimaEch.stats.get('total')+1)
-        if self.cache:
-            cached_response = self.controller.cached_request(req.url, req.headers)
-            if cached_response:
-                SimaEch.stats.update(ccontrol=SimaEch.stats.get('ccontrol')+1)
-                return cached_response.json()
-        try:
-            return self._fetch_ws(req)
-        except Timeout:
-            raise WSTimeout('Failed to reach server within {0}s'.format(
-                               SOCKET_TIMEOUT))
-        except ConnectionError as err:
-            raise WSError(err)
-
-    @Throttle(WAIT_BETWEEN_REQUESTS)
-    def _fetch_ws(self, prepreq):
-        """fetch from web service"""
-        sess = Session()
-        resp = sess.send(prepreq, timeout=SOCKET_TIMEOUT)
-        if resp.status_code == 304:
-            SimaEch.stats.update(etag=SimaEch.stats.get('etag')+1)
-            resp = self.controller.update_cached_response(prepreq, resp)
-        elif resp.status_code != 200:
-            raise WSHTTPError('{0.status_code}: {0.reason}'.format(resp))
-        ans = resp.json()
-        self._controls_answer(ans)
-        SimaEch.ratelimit = resp.headers.get('x-ratelimit-remaining', None)
-        minrl = min(int(SimaEch.ratelimit), SimaEch.stats.get('minrl'))
-        SimaEch.stats.update(minrl=minrl)
-        if self.cache:
-            self.controller.cache_response(resp.request, resp)
-        return ans
+        self.http = HttpClient(cache=self.cache, stats=self.stats)
 
     def _controls_answer(self, ans):
         """Controls answer.
 
     def _controls_answer(self, ans):
         """Controls answer.
@@ -141,14 +102,10 @@ class SimaEch:
         payload = self._forge_payload(artist)
         # Construct URL
         ressource = '{0}/artist/similar'.format(SimaEch.root_url)
         payload = self._forge_payload(artist)
         # Construct URL
         ressource = '{0}/artist/similar'.format(SimaEch.root_url)
-        ans = self._fetch(ressource, payload)
-        for art in ans.get('response').get('artists'):
-            mbid = None
-            if 'foreign_ids' in art:
-                for frgnid in art.get('foreign_ids'):
-                    if frgnid.get('catalog') == 'musicbrainz':
-                        mbid = frgnid.get('foreign_id'
-                                          ).lstrip('musicbrainz:artist:')
+        ans = self.http(ressource, payload)
+        self._controls_answer(ans.json())
+        for art in ans.json().get('response').get('artists'):
+            mbid = get_mbid(art)
             yield Artist(mbid=mbid, name=art.get('name'))
 
     def get_toptrack(self, artist=None):
             yield Artist(mbid=mbid, name=art.get('name'))
 
     def get_toptrack(self, artist=None):
@@ -157,14 +114,17 @@ class SimaEch:
         payload = self._forge_payload(artist, top=True)
         # Construct URL
         ressource = '{0}/song/search'.format(SimaEch.root_url)
         payload = self._forge_payload(artist, top=True)
         # Construct URL
         ressource = '{0}/song/search'.format(SimaEch.root_url)
-        ans = self._fetch(ressource, payload)
+        ans = self.http(ressource, payload)
+        self._controls_answer(ans.json())
         titles = list()
         art = {
                 'artist': artist.name,
                 'musicbrainz_artistid': artist.mbid,
                 }
         titles = list()
         art = {
                 'artist': artist.name,
                 'musicbrainz_artistid': artist.mbid,
                 }
-        for song in ans.get('response').get('songs'):
+        for song in ans.json().get('response').get('songs'):
             title = song.get('title')
             title = song.get('title')
+            if not art.get('musicbrainz_artistid'):
+                art['musicbrainz_artistid'] = get_mbid(song, 'artist_foreign_ids')
             if title not in titles:
                 titles.append(title)
                 yield Track(title=title, **art)
             if title not in titles:
                 titles.append(title)
                 yield Track(title=title, **art)