]> kaliko git repositories - mpd-sima.git/blobdiff - sima/utils/utils.py
Some clean-up (pylint audit)
[mpd-sima.git] / sima / utils / utils.py
index 017af9fd4b96ded621c9a31bfec0c8affac98ac3..475a54859305d2dbbff604546a6333b05c97eac6 100644 (file)
 #  along with sima.  If not, see <http://www.gnu.org/licenses/>.
 #
 #
-"""generic tools and utilitaries for sima
+"""generic tools and utilities for sima
 """
+# pylint: disable=C0111
 
 import traceback
 import sys
 
-from argparse import (ArgumentError, Action)
-from os import (environ, access, getcwd, W_OK, R_OK)
-from os.path import (dirname, isabs, join, normpath, exists, isdir, isfile)
+from argparse import ArgumentError, Action
+from base64 import b64decode as push
+from codecs import getencoder
+from datetime import datetime, timedelta
+from os import environ, access, getcwd, W_OK, R_OK
+from os.path import dirname, isabs, join, normpath, exists, isdir, isfile
+from time import sleep
+
+
+def getws(dic):
+    """
+    Decode Obfuscated api key.
+    Only preventing API keys harvesting over the network
+    https://developer.echonest.com/forums/thread/105
+    """
+    aka = push(bytes(dic.get('apikey') + '=', 'utf-8'))
+    aka = getencoder('rot-13')(str((aka), 'utf-8'))[0]
+    dic.update({'apikey':aka})
 
 def get_mpd_environ():
     """
@@ -63,6 +79,24 @@ def exception_log():
     log.info('Quiting now!')
     sys.exit(1)
 
+def purge_cache(obj, age=4):
+    """purge old entries in http client cache
+    """
+    now = datetime.utcnow()
+    if now.hour == obj.timestamp.hour:
+        return
+    obj.timestamp = datetime.utcnow()
+    cache = obj.cache
+    delta = timedelta(hours=age)
+    for url in list(cache.keys()):
+        timestamp = cache.get(url).created()
+        if now - timestamp > delta:
+            cache.pop(url)
+
+
+class SigHup(Exception):
+    """SIGHUP raises this Exception"""
+    pass
 
 # ArgParse Callbacks
 class Obsolete(Action):
@@ -73,7 +107,7 @@ class Obsolete(Action):
         raise ArgumentError(self, 'obsolete argument')
 
 class FileAction(Action):
-    """Generic class to inherit from for ARgPArse action on file/dir
+    """Generic class to inherit from for ArgParse action on file/dir
     """
     # pylint: disable=R0903
     def __call__(self, parser, namespace, values, option_string=None):
@@ -128,6 +162,50 @@ class Wdir(FileAction):
         if not access(self._file, W_OK):
             self.parser.error('no write access to "{0}"'.format(self._file))
 
+class Throttle:
+    """throttle decorator"""
+    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:
+    """Plain cache object"""
+    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
+
+
+# http client exceptions (for webservices)
+
+class WSError(Exception):
+    pass
+
+class WSNotFound(WSError):
+    pass
+
+class WSTimeout(WSError):
+    pass
+
+class WSHTTPError(WSError):
+    pass
+
 
 # VIM MODLINE
 # vim: ai ts=4 sw=4 sts=4 expandtab