]> kaliko git repositories - mpd-sima.git/commitdiff
Move Cache & Throttle to utils
authorkaliko <efrim@azylum.org>
Sat, 8 Feb 2014 00:56:19 +0000 (01:56 +0100)
committerkaliko <efrim@azylum.org>
Sat, 8 Feb 2014 00:56:19 +0000 (01:56 +0100)
sima/lib/simafm.py
sima/utils/utils.py

index d29817ee01e930eecfa12eca8f4d13ab2a3d0aff..170488b9ad00f1f6ad9fe05d7709c3ba0a2d6c05 100644 (file)
@@ -23,7 +23,7 @@ Consume last.fm web service
 
 """
 
-__version__ = '0.3.1'
+__version__ = '0.4.0'
 __author__ = 'Jack Kaliko'
 
 
@@ -32,28 +32,17 @@ import urllib.request, urllib.error, urllib.parse
 from datetime import datetime, timedelta
 from http.client import BadStatusLine
 from socket import timeout as SocketTimeOut
-from time import sleep
 from xml.etree.cElementTree import ElementTree
 
+from request import get
+
 from sima import LFM
-from sima.utils.utils import getws
-getws(LFM)
+from sima.utils.utils import getws, Throttle, Cache
+if len(LFM.get('apikey')) == 43:  # simple hack allowing imp.reload
+    getws(LFM)
 
 # Some definitions
 WAIT_BETWEEN_REQUESTS = timedelta(0, 0.4)
-LFM_ERRORS = dict({'2': 'Invalid service -This service does not exist',
-    '3': 'Invalid Method - No method with that name in this package',
-    '4': 'Authentication Failed - You do not have permissions to access the service',
-    '5': "'Invalid format - This service doesn't exist in that format",
-    '6': 'Invalid parameters - Your request is missing a required parameter',
-    '7': 'Invalid resource specified',
-    '9': 'Invalid session key - Please re-authenticate',
-    '10': 'Invalid API key - You must be granted a valid key by last.fm',
-    '11': 'Service Offline - This service is temporarily offline. Try again later.',
-    '12': 'Subscription Error - The user needs to be subscribed in order to do that',
-    '13': 'Invalid method signature supplied',
-    '26': 'Suspended API key - Access for your account has been suspended, please contact Last.fm',
-    })
 
 
 class XmlFMError(Exception):  # Errors
@@ -111,34 +100,6 @@ class XmlFMTimeOut(XmlFMError):
         self.expression = (message)
 
 
-class Throttle():
-    def __init__(self, wait):
-        self.wait = wait
-        self.last_called = datetime.now()
-
-    def __call__(self, func):
-        def wrapper(*args, **kwargs):
-            while self.last_called + self.wait > datetime.now():
-                #print('waiting…')
-                sleep(0.1)
-            result = func(*args, **kwargs)
-            self.last_called = datetime.now()
-            return result
-        return wrapper
-
-
-class AudioScrobblerCache():
-    def __init__(self, elem, last):
-        self.elemtree = elem
-        self.requestdate = last
-
-    def created(self):
-        return self.requestdate
-
-    def gettree(self):
-        return self.elemtree
-
-
 class SimaFM():
     """
     """
@@ -152,6 +113,16 @@ class SimaFM():
                     'info': '?method=artist.getinfo&artist=%s' +\
                             'api_key={apikey}'.format(**LFM),
                     })
+    payloads = dict({'similar': {'method':'artist.getsimilar',
+                                'artist':None, 'api_key':LFM.get('apikey'),},
+                    'top': {'method':'artist.gettoptracks',
+                            'artist':None, 'api_key':LFM.get('apikey'),},
+                    'track': {'method':'track.getsimilar',
+                              'artist':None, 'track':None,
+                              'api_key':LFM.get('apikey'),},
+                    'info': {'method':'artist.getinfo', 'artist':None,
+                             'api_key':LFM.get('apikey'),},
+                    })
     cache = dict({})
     timestamp = datetime.utcnow()
     count = 0
@@ -178,6 +149,10 @@ class SimaFM():
             return
         self._fetch_lfm()
 
+    @Throttle(WAIT_BETWEEN_REQUESTS)
+    def _fetch_ws(self):
+        pass
+
     @Throttle(WAIT_BETWEEN_REQUESTS)
     def _fetch_lfm(self):
         """Get artists, fetch xml from last.fm"""
@@ -212,8 +187,7 @@ class SimaFM():
             fd.close()
         self._controls_lfm_answer()
         if self.caching:
-            SimaFM.cache[self._url] = AudioScrobblerCache(self.current_element,
-                    datetime.utcnow())
+            SimaFM.cache[self._url] = Cache(self.current_element)
 
     def _controls_lfm_answer(self):
         """Controls last.fm answer.
@@ -224,8 +198,6 @@ class SimaFM():
         if status == 'failed':
             error = self.current_element.find('error').attrib.get('code')
             errormsg = self.current_element.findtext('error')
-            #if error in LFM_ERRORS.keys():
-            #    print LFM_ERRORS.get(error)
             raise XmlFMNotFound(errormsg)
 
     def _controls_artist(self, artist):
@@ -251,6 +223,21 @@ class SimaFM():
             if now - timestamp > delta:
                 cache.pop(url)
 
+    def get_similar_ng(self, artist=None):
+        """
+        """
+        self._controls_artist(artist)
+        # Construct URL
+        self._req = get(SimaFM.root_url, params=None, timeout=5)
+        self._url = req.url
+        if self._is_in_cache():
+            self.current_element = SimaFM.cache.get(self._url).gettree()
+        else:
+            self._fetch_ws()
+        elem = self.current_element
+        for art in elem.getiterator(tag='artist'):
+            yield str(art.findtext('name')), 100 * float(art.findtext('match'))
+
     def get_similar(self, artist=None):
         """
         """
index a75effd603ea3ccc87653942a35d8f3278ffa396..c3bc6c0175db30f36325c941d41d63d378c5f36e 100644 (file)
@@ -27,6 +27,7 @@ import sys
 from argparse import ArgumentError, Action
 from base64 import b64decode as push
 from codecs import getencoder
+from datetime import datetime
 from os import environ, access, getcwd, W_OK, R_OK
 from os.path import dirname, isabs, join, normpath, exists, isdir, isfile
 
@@ -143,6 +144,32 @@ class Wdir(FileAction):
         if not access(self._file, W_OK):
             self.parser.error('no write access to "{0}"'.format(self._file))
 
+class Throttle():
+    def __init__(self, wait):
+        self.wait = wait
+        self.last_called = datetime.now()
+
+    def __call__(self, func):
+        def wrapper(*args, **kwargs):
+            while self.last_called + self.wait > datetime.now():
+                sleep(0.1)
+            result = func(*args, **kwargs)
+            self.last_called = datetime.now()
+            return result
+        return wrapper
+
+class Cache():
+    def __init__(self, elem, last=None):
+        self.elem = elem
+        self.requestdate = last
+        if not last:
+            self.requestdate = datetime.utcnow()
+
+    def created(self):
+        return self.requestdate
+
+    def get(self):
+        return self.elem
 
 # VIM MODLINE
 # vim: ai ts=4 sw=4 sts=4 expandtab