You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
93 lines
2.3 KiB
93 lines
2.3 KiB
6 years ago
|
from __future__ import absolute_import
|
||
|
|
||
|
import os
|
||
|
import shutil
|
||
|
import locket
|
||
|
import string
|
||
|
from toolz import memoize
|
||
|
from contextlib import contextmanager
|
||
|
from .utils import nested_get, flatten
|
||
|
|
||
|
|
||
|
|
||
|
# http://stackoverflow.com/questions/295135/turn-a-string-into-a-valid-filename-in-python
|
||
|
valid_chars = "-_.() " + string.ascii_letters + string.digits + os.path.sep
|
||
|
|
||
|
|
||
|
def escape_filename(fn):
|
||
|
""" Escape text so that it is a valid filename
|
||
|
|
||
|
>>> escape_filename('Foo!bar?')
|
||
|
'Foobar'
|
||
|
|
||
|
"""
|
||
|
return ''.join(filter(valid_chars.__contains__, fn))
|
||
|
|
||
|
|
||
|
def filename(path, key):
|
||
|
return os.path.join(path, escape_filename(token(key)))
|
||
|
|
||
|
|
||
|
def token(key):
|
||
|
"""
|
||
|
|
||
|
>>> token('hello')
|
||
|
'hello'
|
||
|
>>> token(('hello', 'world')) # doctest: +SKIP
|
||
|
'hello/world'
|
||
|
"""
|
||
|
if isinstance(key, str):
|
||
|
return key
|
||
|
elif isinstance(key, tuple):
|
||
|
return os.path.join(*map(token, key))
|
||
|
else:
|
||
|
return str(key)
|
||
|
|
||
|
|
||
|
class Interface(object):
|
||
|
def __init__(self):
|
||
|
self._iset_seen = set()
|
||
|
|
||
|
def __setstate__(self, state):
|
||
|
self.__dict__.update(state)
|
||
|
self._iset_seen = set()
|
||
|
|
||
|
def iset(self, key, value, **kwargs):
|
||
|
if key in self._iset_seen:
|
||
|
return
|
||
|
else:
|
||
|
self._iset(key, value, **kwargs)
|
||
|
self._iset_seen.add(key)
|
||
|
|
||
|
def __enter__(self):
|
||
|
return self
|
||
|
|
||
|
def __exit__(self, type, value, traceback):
|
||
|
self.drop()
|
||
|
|
||
|
def iget(self, key):
|
||
|
return self._get([key], lock=False)[0]
|
||
|
|
||
|
def get(self, keys, **kwargs):
|
||
|
if not isinstance(keys, list):
|
||
|
return self.get([keys], **kwargs)[0]
|
||
|
elif any(isinstance(key, list) for key in keys): # nested case
|
||
|
flatkeys = list(flatten(keys))
|
||
|
result = self.get(flatkeys, **kwargs)
|
||
|
return nested_get(keys, dict(zip(flatkeys, result)))
|
||
|
else:
|
||
|
return self._get(keys, **kwargs)
|
||
|
|
||
|
def delete(self, keys, **kwargs):
|
||
|
if not isinstance(keys, list):
|
||
|
return self._delete([keys], **kwargs)
|
||
|
else:
|
||
|
return self._delete(keys, **kwargs)
|
||
|
|
||
|
def pop(self, keys, **kwargs):
|
||
|
with self.partd.lock:
|
||
|
result = self.partd.get(keys, lock=False)
|
||
|
self.partd.delete(keys, lock=False)
|
||
|
return result
|
||
|
|