mirror of
https://github.com/moparisthebest/SickRage
synced 2024-12-12 02:52:20 -05:00
Improved RSS feedparser/feedcache code for better performance and reliability.
Removed Shove module and depends. Logging now automatically omits sensitive data such as usernames, passwords, and api keys and replaces them with asterisks in both log file and console. Fixed versionChecker module to confirm it created a updater class before attempting to execute functions to avoid NoneType errors.
This commit is contained in:
parent
35c84c9449
commit
e6389e47b1
@ -1,519 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
'''Common object storage frontend.'''
|
||||
|
||||
import os
|
||||
import zlib
|
||||
import urllib
|
||||
try:
|
||||
import cPickle as pickle
|
||||
except ImportError:
|
||||
import pickle
|
||||
from collections import deque
|
||||
|
||||
try:
|
||||
# Import store and cache entry points if setuptools installed
|
||||
import pkg_resources
|
||||
stores = dict((_store.name, _store) for _store in
|
||||
pkg_resources.iter_entry_points('shove.stores'))
|
||||
caches = dict((_cache.name, _cache) for _cache in
|
||||
pkg_resources.iter_entry_points('shove.caches'))
|
||||
# Pass if nothing loaded
|
||||
if not stores and not caches:
|
||||
raise ImportError()
|
||||
except ImportError:
|
||||
# Static store backend registry
|
||||
stores = dict(
|
||||
bsddb='shove.store.bsdb:BsdStore',
|
||||
cassandra='shove.store.cassandra:CassandraStore',
|
||||
dbm='shove.store.dbm:DbmStore',
|
||||
durus='shove.store.durusdb:DurusStore',
|
||||
file='shove.store.file:FileStore',
|
||||
firebird='shove.store.db:DbStore',
|
||||
ftp='shove.store.ftp:FtpStore',
|
||||
hdf5='shove.store.hdf5:HDF5Store',
|
||||
leveldb='shove.store.leveldbstore:LevelDBStore',
|
||||
memory='shove.store.memory:MemoryStore',
|
||||
mssql='shove.store.db:DbStore',
|
||||
mysql='shove.store.db:DbStore',
|
||||
oracle='shove.store.db:DbStore',
|
||||
postgres='shove.store.db:DbStore',
|
||||
redis='shove.store.redisdb:RedisStore',
|
||||
s3='shove.store.s3:S3Store',
|
||||
simple='shove.store.simple:SimpleStore',
|
||||
sqlite='shove.store.db:DbStore',
|
||||
svn='shove.store.svn:SvnStore',
|
||||
zodb='shove.store.zodb:ZodbStore',
|
||||
)
|
||||
# Static cache backend registry
|
||||
caches = dict(
|
||||
bsddb='shove.cache.bsdb:BsdCache',
|
||||
file='shove.cache.file:FileCache',
|
||||
filelru='shove.cache.filelru:FileLRUCache',
|
||||
firebird='shove.cache.db:DbCache',
|
||||
memcache='shove.cache.memcached:MemCached',
|
||||
memlru='shove.cache.memlru:MemoryLRUCache',
|
||||
memory='shove.cache.memory:MemoryCache',
|
||||
mssql='shove.cache.db:DbCache',
|
||||
mysql='shove.cache.db:DbCache',
|
||||
oracle='shove.cache.db:DbCache',
|
||||
postgres='shove.cache.db:DbCache',
|
||||
redis='shove.cache.redisdb:RedisCache',
|
||||
simple='shove.cache.simple:SimpleCache',
|
||||
simplelru='shove.cache.simplelru:SimpleLRUCache',
|
||||
sqlite='shove.cache.db:DbCache',
|
||||
)
|
||||
|
||||
|
||||
def getbackend(uri, engines, **kw):
|
||||
'''
|
||||
Loads the right backend based on a URI.
|
||||
|
||||
@param uri Instance or name string
|
||||
@param engines A dictionary of scheme/class pairs
|
||||
'''
|
||||
if isinstance(uri, basestring):
|
||||
mod = engines[uri.split('://', 1)[0]]
|
||||
# Load module if setuptools not present
|
||||
if isinstance(mod, basestring):
|
||||
# Isolate classname from dot path
|
||||
module, klass = mod.split(':')
|
||||
# Load module
|
||||
mod = getattr(__import__(module, '', '', ['']), klass)
|
||||
# Load appropriate class from setuptools entry point
|
||||
else:
|
||||
mod = mod.load()
|
||||
# Return instance
|
||||
return mod(uri, **kw)
|
||||
# No-op for existing instances
|
||||
return uri
|
||||
|
||||
|
||||
def synchronized(func):
|
||||
'''
|
||||
Decorator to lock and unlock a method (Phillip J. Eby).
|
||||
|
||||
@param func Method to decorate
|
||||
'''
|
||||
def wrapper(self, *__args, **__kw):
|
||||
self._lock.acquire()
|
||||
try:
|
||||
return func(self, *__args, **__kw)
|
||||
finally:
|
||||
self._lock.release()
|
||||
wrapper.__name__ = func.__name__
|
||||
wrapper.__dict__ = func.__dict__
|
||||
wrapper.__doc__ = func.__doc__
|
||||
return wrapper
|
||||
|
||||
|
||||
class Base(object):
|
||||
|
||||
'''Base Mapping class.'''
|
||||
|
||||
def __init__(self, engine, **kw):
|
||||
'''
|
||||
@keyword compress True, False, or an integer compression level (1-9).
|
||||
'''
|
||||
self._compress = kw.get('compress', False)
|
||||
self._protocol = kw.get('protocol', pickle.HIGHEST_PROTOCOL)
|
||||
|
||||
def __getitem__(self, key):
|
||||
raise NotImplementedError()
|
||||
|
||||
def __setitem__(self, key, value):
|
||||
raise NotImplementedError()
|
||||
|
||||
def __delitem__(self, key):
|
||||
raise NotImplementedError()
|
||||
|
||||
def __contains__(self, key):
|
||||
try:
|
||||
value = self[key]
|
||||
except KeyError:
|
||||
return False
|
||||
return True
|
||||
|
||||
def get(self, key, default=None):
|
||||
'''
|
||||
Fetch a given key from the mapping. If the key does not exist,
|
||||
return the default.
|
||||
|
||||
@param key Keyword of item in mapping.
|
||||
@param default Default value (default: None)
|
||||
'''
|
||||
try:
|
||||
return self[key]
|
||||
except KeyError:
|
||||
return default
|
||||
|
||||
def dumps(self, value):
|
||||
'''Optionally serializes and compresses an object.'''
|
||||
# Serialize everything but ASCII strings
|
||||
value = pickle.dumps(value, protocol=self._protocol)
|
||||
if self._compress:
|
||||
level = 9 if self._compress is True else self._compress
|
||||
value = zlib.compress(value, level)
|
||||
return value
|
||||
|
||||
def loads(self, value):
|
||||
'''Deserializes and optionally decompresses an object.'''
|
||||
if self._compress:
|
||||
try:
|
||||
value = zlib.decompress(value)
|
||||
except zlib.error:
|
||||
pass
|
||||
value = pickle.loads(value)
|
||||
return value
|
||||
|
||||
|
||||
class BaseStore(Base):
|
||||
|
||||
'''Base Store class (based on UserDict.DictMixin).'''
|
||||
|
||||
def __init__(self, engine, **kw):
|
||||
super(BaseStore, self).__init__(engine, **kw)
|
||||
self._store = None
|
||||
|
||||
def __cmp__(self, other):
|
||||
if other is None:
|
||||
return False
|
||||
if isinstance(other, BaseStore):
|
||||
return cmp(dict(self.iteritems()), dict(other.iteritems()))
|
||||
|
||||
def __del__(self):
|
||||
# __init__ didn't succeed, so don't bother closing
|
||||
if not hasattr(self, '_store'):
|
||||
return
|
||||
self.close()
|
||||
|
||||
def __iter__(self):
|
||||
for k in self.keys():
|
||||
yield k
|
||||
|
||||
def __len__(self):
|
||||
return len(self.keys())
|
||||
|
||||
def __repr__(self):
|
||||
return repr(dict(self.iteritems()))
|
||||
|
||||
def close(self):
|
||||
'''Closes internal store and clears object references.'''
|
||||
try:
|
||||
self._store.close()
|
||||
except AttributeError:
|
||||
pass
|
||||
self._store = None
|
||||
|
||||
def clear(self):
|
||||
'''Removes all keys and values from a store.'''
|
||||
for key in self.keys():
|
||||
del self[key]
|
||||
|
||||
def items(self):
|
||||
'''Returns a list with all key/value pairs in the store.'''
|
||||
return list(self.iteritems())
|
||||
|
||||
def iteritems(self):
|
||||
'''Lazily returns all key/value pairs in a store.'''
|
||||
for k in self:
|
||||
yield (k, self[k])
|
||||
|
||||
def iterkeys(self):
|
||||
'''Lazy returns all keys in a store.'''
|
||||
return self.__iter__()
|
||||
|
||||
def itervalues(self):
|
||||
'''Lazily returns all values in a store.'''
|
||||
for _, v in self.iteritems():
|
||||
yield v
|
||||
|
||||
def keys(self):
|
||||
'''Returns a list with all keys in a store.'''
|
||||
raise NotImplementedError()
|
||||
|
||||
def pop(self, key, *args):
|
||||
'''
|
||||
Removes and returns a value from a store.
|
||||
|
||||
@param args Default to return if key not present.
|
||||
'''
|
||||
if len(args) > 1:
|
||||
raise TypeError('pop expected at most 2 arguments, got ' + repr(
|
||||
1 + len(args))
|
||||
)
|
||||
try:
|
||||
value = self[key]
|
||||
# Return default if key not in store
|
||||
except KeyError:
|
||||
if args:
|
||||
return args[0]
|
||||
del self[key]
|
||||
return value
|
||||
|
||||
def popitem(self):
|
||||
'''Removes and returns a key, value pair from a store.'''
|
||||
try:
|
||||
k, v = self.iteritems().next()
|
||||
except StopIteration:
|
||||
raise KeyError('Store is empty.')
|
||||
del self[k]
|
||||
return (k, v)
|
||||
|
||||
def setdefault(self, key, default=None):
|
||||
'''
|
||||
Returns the value corresponding to an existing key or sets the
|
||||
to key to the default and returns the default.
|
||||
|
||||
@param default Default value (default: None)
|
||||
'''
|
||||
try:
|
||||
return self[key]
|
||||
except KeyError:
|
||||
self[key] = default
|
||||
return default
|
||||
|
||||
def update(self, other=None, **kw):
|
||||
'''
|
||||
Adds to or overwrites the values in this store with values from
|
||||
another store.
|
||||
|
||||
other Another store
|
||||
kw Additional keys and values to store
|
||||
'''
|
||||
if other is None:
|
||||
pass
|
||||
elif hasattr(other, 'iteritems'):
|
||||
for k, v in other.iteritems():
|
||||
self[k] = v
|
||||
elif hasattr(other, 'keys'):
|
||||
for k in other.keys():
|
||||
self[k] = other[k]
|
||||
else:
|
||||
for k, v in other:
|
||||
self[k] = v
|
||||
if kw:
|
||||
self.update(kw)
|
||||
|
||||
def values(self):
|
||||
'''Returns a list with all values in a store.'''
|
||||
return list(v for _, v in self.iteritems())
|
||||
|
||||
|
||||
class Shove(BaseStore):
|
||||
|
||||
'''Common object frontend class.'''
|
||||
|
||||
def __init__(self, store='simple://', cache='simple://', **kw):
|
||||
super(Shove, self).__init__(store, **kw)
|
||||
# Load store
|
||||
self._store = getbackend(store, stores, **kw)
|
||||
# Load cache
|
||||
self._cache = getbackend(cache, caches, **kw)
|
||||
# Buffer for lazy writing and setting for syncing frequency
|
||||
self._buffer, self._sync = dict(), kw.get('sync', 2)
|
||||
|
||||
def __getitem__(self, key):
|
||||
'''Gets a item from shove.'''
|
||||
try:
|
||||
return self._cache[key]
|
||||
except KeyError:
|
||||
# Synchronize cache and store
|
||||
self.sync()
|
||||
value = self._store[key]
|
||||
self._cache[key] = value
|
||||
return value
|
||||
|
||||
def __setitem__(self, key, value):
|
||||
'''Sets an item in shove.'''
|
||||
self._cache[key] = self._buffer[key] = value
|
||||
# When the buffer reaches self._limit, writes the buffer to the store
|
||||
if len(self._buffer) >= self._sync:
|
||||
self.sync()
|
||||
|
||||
def __delitem__(self, key):
|
||||
'''Deletes an item from shove.'''
|
||||
try:
|
||||
del self._cache[key]
|
||||
except KeyError:
|
||||
pass
|
||||
self.sync()
|
||||
del self._store[key]
|
||||
|
||||
def keys(self):
|
||||
'''Returns a list of keys in shove.'''
|
||||
self.sync()
|
||||
return self._store.keys()
|
||||
|
||||
def sync(self):
|
||||
'''Writes buffer to store.'''
|
||||
for k, v in self._buffer.iteritems():
|
||||
self._store[k] = v
|
||||
self._buffer.clear()
|
||||
|
||||
def close(self):
|
||||
'''Finalizes and closes shove.'''
|
||||
# If close has been called, pass
|
||||
if self._store is not None:
|
||||
try:
|
||||
self.sync()
|
||||
except AttributeError:
|
||||
pass
|
||||
self._store.close()
|
||||
self._store = self._cache = self._buffer = None
|
||||
|
||||
|
||||
class FileBase(Base):
|
||||
|
||||
'''Base class for file based storage.'''
|
||||
|
||||
def __init__(self, engine, **kw):
|
||||
super(FileBase, self).__init__(engine, **kw)
|
||||
if engine.startswith('file://'):
|
||||
engine = urllib.url2pathname(engine.split('://')[1])
|
||||
self._dir = engine
|
||||
# Create directory
|
||||
if not os.path.exists(self._dir):
|
||||
self._createdir()
|
||||
|
||||
def __getitem__(self, key):
|
||||
# (per Larry Meyn)
|
||||
try:
|
||||
item = open(self._key_to_file(key), 'rb')
|
||||
data = item.read()
|
||||
item.close()
|
||||
return self.loads(data)
|
||||
except:
|
||||
raise KeyError(key)
|
||||
|
||||
def __setitem__(self, key, value):
|
||||
# (per Larry Meyn)
|
||||
try:
|
||||
item = open(self._key_to_file(key), 'wb')
|
||||
item.write(self.dumps(value))
|
||||
item.close()
|
||||
except (IOError, OSError):
|
||||
raise KeyError(key)
|
||||
|
||||
def __delitem__(self, key):
|
||||
try:
|
||||
os.remove(self._key_to_file(key))
|
||||
except (IOError, OSError):
|
||||
raise KeyError(key)
|
||||
|
||||
def __contains__(self, key):
|
||||
return os.path.exists(self._key_to_file(key))
|
||||
|
||||
def __len__(self):
|
||||
return len(os.listdir(self._dir))
|
||||
|
||||
def _createdir(self):
|
||||
'''Creates the store directory.'''
|
||||
try:
|
||||
os.makedirs(self._dir)
|
||||
except OSError:
|
||||
raise EnvironmentError(
|
||||
'Cache directory "%s" does not exist and ' \
|
||||
'could not be created' % self._dir
|
||||
)
|
||||
|
||||
def _key_to_file(self, key):
|
||||
'''Gives the filesystem path for a key.'''
|
||||
return os.path.join(self._dir, urllib.quote_plus(key))
|
||||
|
||||
def keys(self):
|
||||
'''Returns a list of keys in the store.'''
|
||||
return [urllib.unquote_plus(name) for name in os.listdir(self._dir)]
|
||||
|
||||
|
||||
class SimpleBase(Base):
|
||||
|
||||
'''Single-process in-memory store base class.'''
|
||||
|
||||
def __init__(self, engine, **kw):
|
||||
super(SimpleBase, self).__init__(engine, **kw)
|
||||
self._store = dict()
|
||||
|
||||
def __getitem__(self, key):
|
||||
try:
|
||||
return self._store[key]
|
||||
except:
|
||||
raise KeyError(key)
|
||||
|
||||
def __setitem__(self, key, value):
|
||||
self._store[key] = value
|
||||
|
||||
def __delitem__(self, key):
|
||||
try:
|
||||
del self._store[key]
|
||||
except:
|
||||
raise KeyError(key)
|
||||
|
||||
def __len__(self):
|
||||
return len(self._store)
|
||||
|
||||
def keys(self):
|
||||
'''Returns a list of keys in the store.'''
|
||||
return self._store.keys()
|
||||
|
||||
|
||||
class LRUBase(SimpleBase):
|
||||
|
||||
def __init__(self, engine, **kw):
|
||||
super(LRUBase, self).__init__(engine, **kw)
|
||||
self._max_entries = kw.get('max_entries', 300)
|
||||
self._hits = 0
|
||||
self._misses = 0
|
||||
self._queue = deque()
|
||||
self._refcount = dict()
|
||||
|
||||
def __getitem__(self, key):
|
||||
try:
|
||||
value = super(LRUBase, self).__getitem__(key)
|
||||
self._hits += 1
|
||||
except KeyError:
|
||||
self._misses += 1
|
||||
raise
|
||||
self._housekeep(key)
|
||||
return value
|
||||
|
||||
def __setitem__(self, key, value):
|
||||
super(LRUBase, self).__setitem__(key, value)
|
||||
self._housekeep(key)
|
||||
if len(self._store) > self._max_entries:
|
||||
while len(self._store) > self._max_entries:
|
||||
k = self._queue.popleft()
|
||||
self._refcount[k] -= 1
|
||||
if not self._refcount[k]:
|
||||
super(LRUBase, self).__delitem__(k)
|
||||
del self._refcount[k]
|
||||
|
||||
def _housekeep(self, key):
|
||||
self._queue.append(key)
|
||||
self._refcount[key] = self._refcount.get(key, 0) + 1
|
||||
if len(self._queue) > self._max_entries * 4:
|
||||
self._purge_queue()
|
||||
|
||||
def _purge_queue(self):
|
||||
for i in [None] * len(self._queue):
|
||||
k = self._queue.popleft()
|
||||
if self._refcount[k] == 1:
|
||||
self._queue.append(k)
|
||||
else:
|
||||
self._refcount[k] -= 1
|
||||
|
||||
|
||||
class DbBase(Base):
|
||||
|
||||
'''Database common base class.'''
|
||||
|
||||
def __init__(self, engine, **kw):
|
||||
super(DbBase, self).__init__(engine, **kw)
|
||||
|
||||
def __delitem__(self, key):
|
||||
self._store.delete(self._store.c.key == key).execute()
|
||||
|
||||
def __len__(self):
|
||||
return self._store.count().execute().fetchone()[0]
|
||||
|
||||
|
||||
__all__ = ['Shove']
|
1
lib/shove/cache/__init__.py
vendored
1
lib/shove/cache/__init__.py
vendored
@ -1 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
117
lib/shove/cache/db.py
vendored
117
lib/shove/cache/db.py
vendored
@ -1,117 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
Database object cache.
|
||||
|
||||
The shove psuedo-URL used for database object caches is the format used by
|
||||
SQLAlchemy:
|
||||
|
||||
<driver>://<username>:<password>@<host>:<port>/<database>
|
||||
|
||||
<driver> is the database engine. The engines currently supported SQLAlchemy are
|
||||
sqlite, mysql, postgres, oracle, mssql, and firebird.
|
||||
<username> is the database account user name
|
||||
<password> is the database accound password
|
||||
<host> is the database location
|
||||
<port> is the database port
|
||||
<database> is the name of the specific database
|
||||
|
||||
For more information on specific databases see:
|
||||
|
||||
http://www.sqlalchemy.org/docs/dbengine.myt#dbengine_supported
|
||||
'''
|
||||
|
||||
import time
|
||||
import random
|
||||
from datetime import datetime
|
||||
try:
|
||||
from sqlalchemy import (
|
||||
MetaData, Table, Column, String, Binary, DateTime, select, update,
|
||||
insert, delete,
|
||||
)
|
||||
from shove import DbBase
|
||||
except ImportError:
|
||||
raise ImportError('Requires SQLAlchemy >= 0.4')
|
||||
|
||||
__all__ = ['DbCache']
|
||||
|
||||
|
||||
class DbCache(DbBase):
|
||||
|
||||
'''database cache backend'''
|
||||
|
||||
def __init__(self, engine, **kw):
|
||||
super(DbCache, self).__init__(engine, **kw)
|
||||
# Get table name
|
||||
tablename = kw.get('tablename', 'cache')
|
||||
# Bind metadata
|
||||
self._metadata = MetaData(engine)
|
||||
# Make cache table
|
||||
self._store = Table(tablename, self._metadata,
|
||||
Column('key', String(60), primary_key=True, nullable=False),
|
||||
Column('value', Binary, nullable=False),
|
||||
Column('expires', DateTime, nullable=False),
|
||||
)
|
||||
# Create cache table if it does not exist
|
||||
if not self._store.exists():
|
||||
self._store.create()
|
||||
# Set maximum entries
|
||||
self._max_entries = kw.get('max_entries', 300)
|
||||
# Maximum number of entries to cull per call if cache is full
|
||||
self._maxcull = kw.get('maxcull', 10)
|
||||
# Set timeout
|
||||
self.timeout = kw.get('timeout', 300)
|
||||
|
||||
def __getitem__(self, key):
|
||||
row = select(
|
||||
[self._store.c.value, self._store.c.expires],
|
||||
self._store.c.key == key
|
||||
).execute().fetchone()
|
||||
if row is not None:
|
||||
# Remove if item expired
|
||||
if row.expires < datetime.now().replace(microsecond=0):
|
||||
del self[key]
|
||||
raise KeyError(key)
|
||||
return self.loads(str(row.value))
|
||||
raise KeyError(key)
|
||||
|
||||
def __setitem__(self, key, value):
|
||||
timeout, value, cache = self.timeout, self.dumps(value), self._store
|
||||
# Cull if too many items
|
||||
if len(self) >= self._max_entries:
|
||||
self._cull()
|
||||
# Generate expiration time
|
||||
expires = datetime.fromtimestamp(
|
||||
time.time() + timeout
|
||||
).replace(microsecond=0)
|
||||
# Update database if key already present
|
||||
if key in self:
|
||||
update(
|
||||
cache,
|
||||
cache.c.key == key,
|
||||
dict(value=value, expires=expires),
|
||||
).execute()
|
||||
# Insert new key if key not present
|
||||
else:
|
||||
insert(
|
||||
cache, dict(key=key, value=value, expires=expires)
|
||||
).execute()
|
||||
|
||||
def _cull(self):
|
||||
'''Remove items in cache to make more room.'''
|
||||
cache, maxcull = self._store, self._maxcull
|
||||
# Remove items that have timed out
|
||||
now = datetime.now().replace(microsecond=0)
|
||||
delete(cache, cache.c.expires < now).execute()
|
||||
# Remove any items over the maximum allowed number in the cache
|
||||
if len(self) >= self._max_entries:
|
||||
# Upper limit for key query
|
||||
ul = maxcull * 2
|
||||
# Get list of keys
|
||||
keys = [
|
||||
i[0] for i in select(
|
||||
[cache.c.key], limit=ul
|
||||
).execute().fetchall()
|
||||
]
|
||||
# Get some keys at random
|
||||
delkeys = list(random.choice(keys) for i in xrange(maxcull))
|
||||
delete(cache, cache.c.key.in_(delkeys)).execute()
|
46
lib/shove/cache/file.py
vendored
46
lib/shove/cache/file.py
vendored
@ -1,46 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
File-based cache
|
||||
|
||||
shove's psuedo-URL for file caches follows the form:
|
||||
|
||||
file://<path>
|
||||
|
||||
Where the path is a URL path to a directory on a local filesystem.
|
||||
Alternatively, a native pathname to the directory can be passed as the 'engine'
|
||||
argument.
|
||||
'''
|
||||
|
||||
import time
|
||||
|
||||
from shove import FileBase
|
||||
from shove.cache.simple import SimpleCache
|
||||
|
||||
|
||||
class FileCache(FileBase, SimpleCache):
|
||||
|
||||
'''File-based cache backend'''
|
||||
|
||||
def __init__(self, engine, **kw):
|
||||
super(FileCache, self).__init__(engine, **kw)
|
||||
|
||||
def __getitem__(self, key):
|
||||
try:
|
||||
exp, value = super(FileCache, self).__getitem__(key)
|
||||
# Remove item if time has expired.
|
||||
if exp < time.time():
|
||||
del self[key]
|
||||
raise KeyError(key)
|
||||
return value
|
||||
except:
|
||||
raise KeyError(key)
|
||||
|
||||
def __setitem__(self, key, value):
|
||||
if len(self) >= self._max_entries:
|
||||
self._cull()
|
||||
super(FileCache, self).__setitem__(
|
||||
key, (time.time() + self.timeout, value)
|
||||
)
|
||||
|
||||
|
||||
__all__ = ['FileCache']
|
23
lib/shove/cache/filelru.py
vendored
23
lib/shove/cache/filelru.py
vendored
@ -1,23 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
File-based LRU cache
|
||||
|
||||
shove's psuedo-URL for file caches follows the form:
|
||||
|
||||
file://<path>
|
||||
|
||||
Where the path is a URL path to a directory on a local filesystem.
|
||||
Alternatively, a native pathname to the directory can be passed as the 'engine'
|
||||
argument.
|
||||
'''
|
||||
|
||||
from shove import FileBase
|
||||
from shove.cache.simplelru import SimpleLRUCache
|
||||
|
||||
|
||||
class FileCache(FileBase, SimpleLRUCache):
|
||||
|
||||
'''File-based LRU cache backend'''
|
||||
|
||||
|
||||
__all__ = ['FileCache']
|
43
lib/shove/cache/memcached.py
vendored
43
lib/shove/cache/memcached.py
vendored
@ -1,43 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
"memcached" cache.
|
||||
|
||||
The shove psuedo-URL for a memcache cache is:
|
||||
|
||||
memcache://<memcache_server>
|
||||
'''
|
||||
|
||||
try:
|
||||
import memcache
|
||||
except ImportError:
|
||||
raise ImportError("Memcache cache requires the 'memcache' library")
|
||||
|
||||
from shove import Base
|
||||
|
||||
|
||||
class MemCached(Base):
|
||||
|
||||
'''Memcached cache backend'''
|
||||
|
||||
def __init__(self, engine, **kw):
|
||||
super(MemCached, self).__init__(engine, **kw)
|
||||
if engine.startswith('memcache://'):
|
||||
engine = engine.split('://')[1]
|
||||
self._store = memcache.Client(engine.split(';'))
|
||||
# Set timeout
|
||||
self.timeout = kw.get('timeout', 300)
|
||||
|
||||
def __getitem__(self, key):
|
||||
value = self._store.get(key)
|
||||
if value is None:
|
||||
raise KeyError(key)
|
||||
return self.loads(value)
|
||||
|
||||
def __setitem__(self, key, value):
|
||||
self._store.set(key, self.dumps(value), self.timeout)
|
||||
|
||||
def __delitem__(self, key):
|
||||
self._store.delete(key)
|
||||
|
||||
|
||||
__all__ = ['MemCached']
|
38
lib/shove/cache/memlru.py
vendored
38
lib/shove/cache/memlru.py
vendored
@ -1,38 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
Thread-safe in-memory cache using LRU.
|
||||
|
||||
The shove psuedo-URL for a memory cache is:
|
||||
|
||||
memlru://
|
||||
'''
|
||||
|
||||
import copy
|
||||
import threading
|
||||
|
||||
from shove import synchronized
|
||||
from shove.cache.simplelru import SimpleLRUCache
|
||||
|
||||
|
||||
class MemoryLRUCache(SimpleLRUCache):
|
||||
|
||||
'''Thread-safe in-memory cache backend using LRU.'''
|
||||
|
||||
def __init__(self, engine, **kw):
|
||||
super(MemoryLRUCache, self).__init__(engine, **kw)
|
||||
self._lock = threading.Condition()
|
||||
|
||||
@synchronized
|
||||
def __setitem__(self, key, value):
|
||||
super(MemoryLRUCache, self).__setitem__(key, value)
|
||||
|
||||
@synchronized
|
||||
def __getitem__(self, key):
|
||||
return copy.deepcopy(super(MemoryLRUCache, self).__getitem__(key))
|
||||
|
||||
@synchronized
|
||||
def __delitem__(self, key):
|
||||
super(MemoryLRUCache, self).__delitem__(key)
|
||||
|
||||
|
||||
__all__ = ['MemoryLRUCache']
|
38
lib/shove/cache/memory.py
vendored
38
lib/shove/cache/memory.py
vendored
@ -1,38 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
Thread-safe in-memory cache.
|
||||
|
||||
The shove psuedo-URL for a memory cache is:
|
||||
|
||||
memory://
|
||||
'''
|
||||
|
||||
import copy
|
||||
import threading
|
||||
|
||||
from shove import synchronized
|
||||
from shove.cache.simple import SimpleCache
|
||||
|
||||
|
||||
class MemoryCache(SimpleCache):
|
||||
|
||||
'''Thread-safe in-memory cache backend.'''
|
||||
|
||||
def __init__(self, engine, **kw):
|
||||
super(MemoryCache, self).__init__(engine, **kw)
|
||||
self._lock = threading.Condition()
|
||||
|
||||
@synchronized
|
||||
def __setitem__(self, key, value):
|
||||
super(MemoryCache, self).__setitem__(key, value)
|
||||
|
||||
@synchronized
|
||||
def __getitem__(self, key):
|
||||
return copy.deepcopy(super(MemoryCache, self).__getitem__(key))
|
||||
|
||||
@synchronized
|
||||
def __delitem__(self, key):
|
||||
super(MemoryCache, self).__delitem__(key)
|
||||
|
||||
|
||||
__all__ = ['MemoryCache']
|
45
lib/shove/cache/redisdb.py
vendored
45
lib/shove/cache/redisdb.py
vendored
@ -1,45 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
Redis-based object cache
|
||||
|
||||
The shove psuedo-URL for a redis cache is:
|
||||
|
||||
redis://<host>:<port>/<db>
|
||||
'''
|
||||
|
||||
import urlparse
|
||||
|
||||
try:
|
||||
import redis
|
||||
except ImportError:
|
||||
raise ImportError('This store requires the redis library')
|
||||
|
||||
from shove import Base
|
||||
|
||||
|
||||
class RedisCache(Base):
|
||||
|
||||
'''Redis cache backend'''
|
||||
|
||||
init = 'redis://'
|
||||
|
||||
def __init__(self, engine, **kw):
|
||||
super(RedisCache, self).__init__(engine, **kw)
|
||||
spliturl = urlparse.urlsplit(engine)
|
||||
host, port = spliturl[1].split(':')
|
||||
db = spliturl[2].replace('/', '')
|
||||
self._store = redis.Redis(host, int(port), db)
|
||||
# Set timeout
|
||||
self.timeout = kw.get('timeout', 300)
|
||||
|
||||
def __getitem__(self, key):
|
||||
return self.loads(self._store[key])
|
||||
|
||||
def __setitem__(self, key, value):
|
||||
self._store.setex(key, self.dumps(value), self.timeout)
|
||||
|
||||
def __delitem__(self, key):
|
||||
self._store.delete(key)
|
||||
|
||||
|
||||
__all__ = ['RedisCache']
|
68
lib/shove/cache/simple.py
vendored
68
lib/shove/cache/simple.py
vendored
@ -1,68 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
Single-process in-memory cache.
|
||||
|
||||
The shove psuedo-URL for a simple cache is:
|
||||
|
||||
simple://
|
||||
'''
|
||||
|
||||
import time
|
||||
import random
|
||||
|
||||
from shove import SimpleBase
|
||||
|
||||
|
||||
class SimpleCache(SimpleBase):
|
||||
|
||||
'''Single-process in-memory cache.'''
|
||||
|
||||
def __init__(self, engine, **kw):
|
||||
super(SimpleCache, self).__init__(engine, **kw)
|
||||
# Get random seed
|
||||
random.seed()
|
||||
# Set maximum number of items to cull if over max
|
||||
self._maxcull = kw.get('maxcull', 10)
|
||||
# Set max entries
|
||||
self._max_entries = kw.get('max_entries', 300)
|
||||
# Set timeout
|
||||
self.timeout = kw.get('timeout', 300)
|
||||
|
||||
def __getitem__(self, key):
|
||||
exp, value = super(SimpleCache, self).__getitem__(key)
|
||||
# Delete if item timed out.
|
||||
if exp < time.time():
|
||||
super(SimpleCache, self).__delitem__(key)
|
||||
raise KeyError(key)
|
||||
return value
|
||||
|
||||
def __setitem__(self, key, value):
|
||||
# Cull values if over max # of entries
|
||||
if len(self) >= self._max_entries:
|
||||
self._cull()
|
||||
# Set expiration time and value
|
||||
exp = time.time() + self.timeout
|
||||
super(SimpleCache, self).__setitem__(key, (exp, value))
|
||||
|
||||
def _cull(self):
|
||||
'''Remove items in cache to make room.'''
|
||||
num, maxcull = 0, self._maxcull
|
||||
# Cull number of items allowed (set by self._maxcull)
|
||||
for key in self.keys():
|
||||
# Remove only maximum # of items allowed by maxcull
|
||||
if num <= maxcull:
|
||||
# Remove items if expired
|
||||
try:
|
||||
self[key]
|
||||
except KeyError:
|
||||
num += 1
|
||||
else:
|
||||
break
|
||||
# Remove any additional items up to max # of items allowed by maxcull
|
||||
while len(self) >= self._max_entries and num <= maxcull:
|
||||
# Cull remainder of allowed quota at random
|
||||
del self[random.choice(self.keys())]
|
||||
num += 1
|
||||
|
||||
|
||||
__all__ = ['SimpleCache']
|
18
lib/shove/cache/simplelru.py
vendored
18
lib/shove/cache/simplelru.py
vendored
@ -1,18 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
Single-process in-memory LRU cache.
|
||||
|
||||
The shove psuedo-URL for a simple cache is:
|
||||
|
||||
simplelru://
|
||||
'''
|
||||
|
||||
from shove import LRUBase
|
||||
|
||||
|
||||
class SimpleLRUCache(LRUBase):
|
||||
|
||||
'''In-memory cache that purges based on least recently used item.'''
|
||||
|
||||
|
||||
__all__ = ['SimpleLRUCache']
|
@ -1,48 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from urllib import url2pathname
|
||||
from shove.store.simple import SimpleStore
|
||||
|
||||
|
||||
class ClientStore(SimpleStore):
|
||||
|
||||
'''Base class for stores where updates have to be committed.'''
|
||||
|
||||
def __init__(self, engine, **kw):
|
||||
super(ClientStore, self).__init__(engine, **kw)
|
||||
if engine.startswith(self.init):
|
||||
self._engine = url2pathname(engine.split('://')[1])
|
||||
|
||||
def __getitem__(self, key):
|
||||
return self.loads(super(ClientStore, self).__getitem__(key))
|
||||
|
||||
def __setitem__(self, key, value):
|
||||
super(ClientStore, self).__setitem__(key, self.dumps(value))
|
||||
|
||||
|
||||
class SyncStore(ClientStore):
|
||||
|
||||
'''Base class for stores where updates have to be committed.'''
|
||||
|
||||
def __getitem__(self, key):
|
||||
return self.loads(super(SyncStore, self).__getitem__(key))
|
||||
|
||||
def __setitem__(self, key, value):
|
||||
super(SyncStore, self).__setitem__(key, value)
|
||||
try:
|
||||
self.sync()
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
def __delitem__(self, key):
|
||||
super(SyncStore, self).__delitem__(key)
|
||||
try:
|
||||
self.sync()
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
|
||||
__all__ = [
|
||||
'bsdb', 'db', 'dbm', 'durusdb', 'file', 'ftp', 'memory', 's3', 'simple',
|
||||
'svn', 'zodb', 'redisdb', 'hdf5db', 'leveldbstore', 'cassandra',
|
||||
]
|
@ -1,48 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
Berkeley Source Database Store.
|
||||
|
||||
shove's psuedo-URL for BSDDB stores follows the form:
|
||||
|
||||
bsddb://<path>
|
||||
|
||||
Where the path is a URL path to a Berkeley database. Alternatively, the native
|
||||
pathname to a Berkeley database can be passed as the 'engine' parameter.
|
||||
'''
|
||||
try:
|
||||
import bsddb
|
||||
except ImportError:
|
||||
raise ImportError('requires bsddb library')
|
||||
|
||||
import threading
|
||||
|
||||
from shove import synchronized
|
||||
from shove.store import SyncStore
|
||||
|
||||
|
||||
class BsdStore(SyncStore):
|
||||
|
||||
'''Class for Berkeley Source Database Store.'''
|
||||
|
||||
init = 'bsddb://'
|
||||
|
||||
def __init__(self, engine, **kw):
|
||||
super(BsdStore, self).__init__(engine, **kw)
|
||||
self._store = bsddb.hashopen(self._engine)
|
||||
self._lock = threading.Condition()
|
||||
self.sync = self._store.sync
|
||||
|
||||
@synchronized
|
||||
def __getitem__(self, key):
|
||||
return super(BsdStore, self).__getitem__(key)
|
||||
|
||||
@synchronized
|
||||
def __setitem__(self, key, value):
|
||||
super(BsdStore, self).__setitem__(key, value)
|
||||
|
||||
@synchronized
|
||||
def __delitem__(self, key):
|
||||
super(BsdStore, self).__delitem__(key)
|
||||
|
||||
|
||||
__all__ = ['BsdStore']
|
@ -1,72 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
Cassandra-based object store
|
||||
|
||||
The shove psuedo-URL for a cassandra-based store is:
|
||||
|
||||
cassandra://<host>:<port>/<keyspace>/<columnFamily>
|
||||
'''
|
||||
|
||||
import urlparse
|
||||
|
||||
try:
|
||||
import pycassa
|
||||
except ImportError:
|
||||
raise ImportError('This store requires the pycassa library')
|
||||
|
||||
from shove import BaseStore
|
||||
|
||||
|
||||
class CassandraStore(BaseStore):
|
||||
|
||||
'''Cassandra based store'''
|
||||
|
||||
init = 'cassandra://'
|
||||
|
||||
def __init__(self, engine, **kw):
|
||||
super(CassandraStore, self).__init__(engine, **kw)
|
||||
spliturl = urlparse.urlsplit(engine)
|
||||
_, keyspace, column_family = spliturl[2].split('/')
|
||||
try:
|
||||
self._pool = pycassa.connect(keyspace, [spliturl[1]])
|
||||
self._store = pycassa.ColumnFamily(self._pool, column_family)
|
||||
except pycassa.InvalidRequestException:
|
||||
from pycassa.system_manager import SystemManager
|
||||
system_manager = SystemManager(spliturl[1])
|
||||
system_manager.create_keyspace(
|
||||
keyspace,
|
||||
pycassa.system_manager.SIMPLE_STRATEGY,
|
||||
{'replication_factor': str(kw.get('replication', 1))}
|
||||
)
|
||||
system_manager.create_column_family(keyspace, column_family)
|
||||
self._pool = pycassa.connect(keyspace, [spliturl[1]])
|
||||
self._store = pycassa.ColumnFamily(self._pool, column_family)
|
||||
|
||||
def __getitem__(self, key):
|
||||
try:
|
||||
item = self._store.get(key).get(key)
|
||||
if item is not None:
|
||||
return self.loads(item)
|
||||
raise KeyError(key)
|
||||
except pycassa.NotFoundException:
|
||||
raise KeyError(key)
|
||||
|
||||
def __setitem__(self, key, value):
|
||||
self._store.insert(key, dict(key=self.dumps(value)))
|
||||
|
||||
def __delitem__(self, key):
|
||||
# beware eventual consistency
|
||||
try:
|
||||
self._store.remove(key)
|
||||
except pycassa.NotFoundException:
|
||||
raise KeyError(key)
|
||||
|
||||
def clear(self):
|
||||
# beware eventual consistency
|
||||
self._store.truncate()
|
||||
|
||||
def keys(self):
|
||||
return list(i[0] for i in self._store.get_range())
|
||||
|
||||
|
||||
__all__ = ['CassandraStore']
|
@ -1,73 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
Database object store.
|
||||
|
||||
The shove psuedo-URL used for database object stores is the format used by
|
||||
SQLAlchemy:
|
||||
|
||||
<driver>://<username>:<password>@<host>:<port>/<database>
|
||||
|
||||
<driver> is the database engine. The engines currently supported SQLAlchemy are
|
||||
sqlite, mysql, postgres, oracle, mssql, and firebird.
|
||||
<username> is the database account user name
|
||||
<password> is the database accound password
|
||||
<host> is the database location
|
||||
<port> is the database port
|
||||
<database> is the name of the specific database
|
||||
|
||||
For more information on specific databases see:
|
||||
|
||||
http://www.sqlalchemy.org/docs/dbengine.myt#dbengine_supported
|
||||
'''
|
||||
|
||||
try:
|
||||
from sqlalchemy import MetaData, Table, Column, String, Binary, select
|
||||
from shove import BaseStore, DbBase
|
||||
except ImportError, e:
|
||||
raise ImportError('Error: ' + e + ' Requires SQLAlchemy >= 0.4')
|
||||
|
||||
|
||||
class DbStore(BaseStore, DbBase):
|
||||
|
||||
'''Database cache backend.'''
|
||||
|
||||
def __init__(self, engine, **kw):
|
||||
super(DbStore, self).__init__(engine, **kw)
|
||||
# Get tablename
|
||||
tablename = kw.get('tablename', 'store')
|
||||
# Bind metadata
|
||||
self._metadata = MetaData(engine)
|
||||
# Make store table
|
||||
self._store = Table(tablename, self._metadata,
|
||||
Column('key', String(255), primary_key=True, nullable=False),
|
||||
Column('value', Binary, nullable=False),
|
||||
)
|
||||
# Create store table if it does not exist
|
||||
if not self._store.exists():
|
||||
self._store.create()
|
||||
|
||||
def __getitem__(self, key):
|
||||
row = select(
|
||||
[self._store.c.value], self._store.c.key == key,
|
||||
).execute().fetchone()
|
||||
if row is not None:
|
||||
return self.loads(str(row.value))
|
||||
raise KeyError(key)
|
||||
|
||||
def __setitem__(self, k, v):
|
||||
v, store = self.dumps(v), self._store
|
||||
# Update database if key already present
|
||||
if k in self:
|
||||
store.update(store.c.key == k).execute(value=v)
|
||||
# Insert new key if key not present
|
||||
else:
|
||||
store.insert().execute(key=k, value=v)
|
||||
|
||||
def keys(self):
|
||||
'''Returns a list of keys in the store.'''
|
||||
return list(i[0] for i in select(
|
||||
[self._store.c.key]
|
||||
).execute().fetchall())
|
||||
|
||||
|
||||
__all__ = ['DbStore']
|
@ -1,33 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
DBM Database Store.
|
||||
|
||||
shove's psuedo-URL for DBM stores follows the form:
|
||||
|
||||
dbm://<path>
|
||||
|
||||
Where <path> is a URL path to a DBM database. Alternatively, the native
|
||||
pathname to a DBM database can be passed as the 'engine' parameter.
|
||||
'''
|
||||
|
||||
import anydbm
|
||||
|
||||
from shove.store import SyncStore
|
||||
|
||||
|
||||
class DbmStore(SyncStore):
|
||||
|
||||
'''Class for variants of the DBM database.'''
|
||||
|
||||
init = 'dbm://'
|
||||
|
||||
def __init__(self, engine, **kw):
|
||||
super(DbmStore, self).__init__(engine, **kw)
|
||||
self._store = anydbm.open(self._engine, 'c')
|
||||
try:
|
||||
self.sync = self._store.sync
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
|
||||
__all__ = ['DbmStore']
|
@ -1,43 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
Durus object database frontend.
|
||||
|
||||
shove's psuedo-URL for Durus stores follows the form:
|
||||
|
||||
durus://<path>
|
||||
|
||||
|
||||
Where the path is a URL path to a durus FileStorage database. Alternatively, a
|
||||
native pathname to a durus database can be passed as the 'engine' parameter.
|
||||
'''
|
||||
|
||||
try:
|
||||
from durus.connection import Connection
|
||||
from durus.file_storage import FileStorage
|
||||
except ImportError:
|
||||
raise ImportError('Requires Durus library')
|
||||
|
||||
from shove.store import SyncStore
|
||||
|
||||
|
||||
class DurusStore(SyncStore):
|
||||
|
||||
'''Class for Durus object database frontend.'''
|
||||
|
||||
init = 'durus://'
|
||||
|
||||
def __init__(self, engine, **kw):
|
||||
super(DurusStore, self).__init__(engine, **kw)
|
||||
self._db = FileStorage(self._engine)
|
||||
self._connection = Connection(self._db)
|
||||
self.sync = self._connection.commit
|
||||
self._store = self._connection.get_root()
|
||||
|
||||
def close(self):
|
||||
'''Closes all open storage and connections.'''
|
||||
self.sync()
|
||||
self._db.close()
|
||||
super(DurusStore, self).close()
|
||||
|
||||
|
||||
__all__ = ['DurusStore']
|
@ -1,25 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
Filesystem-based object store
|
||||
|
||||
shove's psuedo-URL for filesystem-based stores follows the form:
|
||||
|
||||
file://<path>
|
||||
|
||||
Where the path is a URL path to a directory on a local filesystem.
|
||||
Alternatively, a native pathname to the directory can be passed as the 'engine'
|
||||
argument.
|
||||
'''
|
||||
|
||||
from shove import BaseStore, FileBase
|
||||
|
||||
|
||||
class FileStore(FileBase, BaseStore):
|
||||
|
||||
'''File-based store.'''
|
||||
|
||||
def __init__(self, engine, **kw):
|
||||
super(FileStore, self).__init__(engine, **kw)
|
||||
|
||||
|
||||
__all__ = ['FileStore']
|
@ -1,88 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
FTP-accessed stores
|
||||
|
||||
shove's URL for FTP accessed stores follows the standard form for FTP URLs
|
||||
defined in RFC-1738:
|
||||
|
||||
ftp://<user>:<password>@<host>:<port>/<url-path>
|
||||
'''
|
||||
|
||||
import urlparse
|
||||
try:
|
||||
from cStringIO import StringIO
|
||||
except ImportError:
|
||||
from StringIO import StringIO
|
||||
from ftplib import FTP, error_perm
|
||||
|
||||
from shove import BaseStore
|
||||
|
||||
|
||||
class FtpStore(BaseStore):
|
||||
|
||||
def __init__(self, engine, **kw):
|
||||
super(FtpStore, self).__init__(engine, **kw)
|
||||
user = kw.get('user', 'anonymous')
|
||||
password = kw.get('password', '')
|
||||
spliturl = urlparse.urlsplit(engine)
|
||||
# Set URL, path, and strip 'ftp://' off
|
||||
base, path = spliturl[1], spliturl[2] + '/'
|
||||
if '@' in base:
|
||||
auth, base = base.split('@')
|
||||
user, password = auth.split(':')
|
||||
self._store = FTP(base, user, password)
|
||||
# Change to remote path if it exits
|
||||
try:
|
||||
self._store.cwd(path)
|
||||
except error_perm:
|
||||
self._makedir(path)
|
||||
self._base, self._user, self._password = base, user, password
|
||||
self._updated, self ._keys = True, None
|
||||
|
||||
def __getitem__(self, key):
|
||||
try:
|
||||
local = StringIO()
|
||||
# Download item
|
||||
self._store.retrbinary('RETR %s' % key, local.write)
|
||||
self._updated = False
|
||||
return self.loads(local.getvalue())
|
||||
except:
|
||||
raise KeyError(key)
|
||||
|
||||
def __setitem__(self, key, value):
|
||||
local = StringIO(self.dumps(value))
|
||||
self._store.storbinary('STOR %s' % key, local)
|
||||
self._updated = True
|
||||
|
||||
def __delitem__(self, key):
|
||||
try:
|
||||
self._store.delete(key)
|
||||
self._updated = True
|
||||
except:
|
||||
raise KeyError(key)
|
||||
|
||||
def _makedir(self, path):
|
||||
'''Makes remote paths on an FTP server.'''
|
||||
paths = list(reversed([i for i in path.split('/') if i != '']))
|
||||
while paths:
|
||||
tpath = paths.pop()
|
||||
self._store.mkd(tpath)
|
||||
self._store.cwd(tpath)
|
||||
|
||||
def keys(self):
|
||||
'''Returns a list of keys in a store.'''
|
||||
if self._updated or self._keys is None:
|
||||
rlist, nlist = list(), list()
|
||||
# Remote directory listing
|
||||
self._store.retrlines('LIST -a', rlist.append)
|
||||
for rlisting in rlist:
|
||||
# Split remote file based on whitespace
|
||||
rfile = rlisting.split()
|
||||
# Append tuple of remote item type & name
|
||||
if rfile[-1] not in ('.', '..') and rfile[0].startswith('-'):
|
||||
nlist.append(rfile[-1])
|
||||
self._keys = nlist
|
||||
return self._keys
|
||||
|
||||
|
||||
__all__ = ['FtpStore']
|
@ -1,34 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
HDF5 Database Store.
|
||||
|
||||
shove's psuedo-URL for HDF5 stores follows the form:
|
||||
|
||||
hdf5://<path>/<group>
|
||||
|
||||
Where <path> is a URL path to a HDF5 database. Alternatively, the native
|
||||
pathname to a HDF5 database can be passed as the 'engine' parameter.
|
||||
<group> is the name of the database.
|
||||
'''
|
||||
|
||||
try:
|
||||
import h5py
|
||||
except ImportError:
|
||||
raise ImportError('This store requires h5py library')
|
||||
|
||||
from shove.store import ClientStore
|
||||
|
||||
|
||||
class HDF5Store(ClientStore):
|
||||
|
||||
'''LevelDB based store'''
|
||||
|
||||
init = 'hdf5://'
|
||||
|
||||
def __init__(self, engine, **kw):
|
||||
super(HDF5Store, self).__init__(engine, **kw)
|
||||
engine, group = self._engine.rsplit('/')
|
||||
self._store = h5py.File(engine).require_group(group).attrs
|
||||
|
||||
|
||||
__all__ = ['HDF5Store']
|
@ -1,47 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
LevelDB Database Store.
|
||||
|
||||
shove's psuedo-URL for LevelDB stores follows the form:
|
||||
|
||||
leveldb://<path>
|
||||
|
||||
Where <path> is a URL path to a LevelDB database. Alternatively, the native
|
||||
pathname to a LevelDB database can be passed as the 'engine' parameter.
|
||||
'''
|
||||
|
||||
try:
|
||||
import leveldb
|
||||
except ImportError:
|
||||
raise ImportError('This store requires py-leveldb library')
|
||||
|
||||
from shove.store import ClientStore
|
||||
|
||||
|
||||
class LevelDBStore(ClientStore):
|
||||
|
||||
'''LevelDB based store'''
|
||||
|
||||
init = 'leveldb://'
|
||||
|
||||
def __init__(self, engine, **kw):
|
||||
super(LevelDBStore, self).__init__(engine, **kw)
|
||||
self._store = leveldb.LevelDB(self._engine)
|
||||
|
||||
def __getitem__(self, key):
|
||||
item = self.loads(self._store.Get(key))
|
||||
if item is not None:
|
||||
return item
|
||||
raise KeyError(key)
|
||||
|
||||
def __setitem__(self, key, value):
|
||||
self._store.Put(key, self.dumps(value))
|
||||
|
||||
def __delitem__(self, key):
|
||||
self._store.Delete(key)
|
||||
|
||||
def keys(self):
|
||||
return list(k for k in self._store.RangeIter(include_value=False))
|
||||
|
||||
|
||||
__all__ = ['LevelDBStore']
|
@ -1,38 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
Thread-safe in-memory store.
|
||||
|
||||
The shove psuedo-URL for a memory store is:
|
||||
|
||||
memory://
|
||||
'''
|
||||
|
||||
import copy
|
||||
import threading
|
||||
|
||||
from shove import synchronized
|
||||
from shove.store.simple import SimpleStore
|
||||
|
||||
|
||||
class MemoryStore(SimpleStore):
|
||||
|
||||
'''Thread-safe in-memory store.'''
|
||||
|
||||
def __init__(self, engine, **kw):
|
||||
super(MemoryStore, self).__init__(engine, **kw)
|
||||
self._lock = threading.Condition()
|
||||
|
||||
@synchronized
|
||||
def __getitem__(self, key):
|
||||
return copy.deepcopy(super(MemoryStore, self).__getitem__(key))
|
||||
|
||||
@synchronized
|
||||
def __setitem__(self, key, value):
|
||||
super(MemoryStore, self).__setitem__(key, value)
|
||||
|
||||
@synchronized
|
||||
def __delitem__(self, key):
|
||||
super(MemoryStore, self).__delitem__(key)
|
||||
|
||||
|
||||
__all__ = ['MemoryStore']
|
@ -1,50 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
Redis-based object store
|
||||
|
||||
The shove psuedo-URL for a redis-based store is:
|
||||
|
||||
redis://<host>:<port>/<db>
|
||||
'''
|
||||
|
||||
import urlparse
|
||||
|
||||
try:
|
||||
import redis
|
||||
except ImportError:
|
||||
raise ImportError('This store requires the redis library')
|
||||
|
||||
from shove.store import ClientStore
|
||||
|
||||
|
||||
class RedisStore(ClientStore):
|
||||
|
||||
'''Redis based store'''
|
||||
|
||||
init = 'redis://'
|
||||
|
||||
def __init__(self, engine, **kw):
|
||||
super(RedisStore, self).__init__(engine, **kw)
|
||||
spliturl = urlparse.urlsplit(engine)
|
||||
host, port = spliturl[1].split(':')
|
||||
db = spliturl[2].replace('/', '')
|
||||
self._store = redis.Redis(host, int(port), db)
|
||||
|
||||
def __contains__(self, key):
|
||||
return self._store.exists(key)
|
||||
|
||||
def clear(self):
|
||||
self._store.flushdb()
|
||||
|
||||
def keys(self):
|
||||
return self._store.keys()
|
||||
|
||||
def setdefault(self, key, default=None):
|
||||
return self._store.getset(key, default)
|
||||
|
||||
def update(self, other=None, **kw):
|
||||
args = kw if other is not None else other
|
||||
self._store.mset(args)
|
||||
|
||||
|
||||
__all__ = ['RedisStore']
|
@ -1,91 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
S3-accessed stores
|
||||
|
||||
shove's psuedo-URL for stores found on Amazon.com's S3 web service follows this
|
||||
form:
|
||||
|
||||
s3://<s3_key>:<s3_secret>@<bucket>
|
||||
|
||||
<s3_key> is the Access Key issued by Amazon
|
||||
<s3_secret> is the Secret Access Key issued by Amazon
|
||||
<bucket> is the name of the bucket accessed through the S3 service
|
||||
'''
|
||||
|
||||
try:
|
||||
from boto.s3.connection import S3Connection
|
||||
from boto.s3.key import Key
|
||||
except ImportError:
|
||||
raise ImportError('Requires boto library')
|
||||
|
||||
from shove import BaseStore
|
||||
|
||||
|
||||
class S3Store(BaseStore):
|
||||
|
||||
def __init__(self, engine=None, **kw):
|
||||
super(S3Store, self).__init__(engine, **kw)
|
||||
# key = Access Key, secret=Secret Access Key, bucket=bucket name
|
||||
key, secret, bucket = kw.get('key'), kw.get('secret'), kw.get('bucket')
|
||||
if engine is not None:
|
||||
auth, bucket = engine.split('://')[1].split('@')
|
||||
key, secret = auth.split(':')
|
||||
# kw 'secure' = (True or False, use HTTPS)
|
||||
self._conn = S3Connection(key, secret, kw.get('secure', False))
|
||||
buckets = self._conn.get_all_buckets()
|
||||
# Use bucket if it exists
|
||||
for b in buckets:
|
||||
if b.name == bucket:
|
||||
self._store = b
|
||||
break
|
||||
# Create bucket if it doesn't exist
|
||||
else:
|
||||
self._store = self._conn.create_bucket(bucket)
|
||||
# Set bucket permission ('private', 'public-read',
|
||||
# 'public-read-write', 'authenticated-read'
|
||||
self._store.set_acl(kw.get('acl', 'private'))
|
||||
# Updated flag used for avoiding network calls
|
||||
self._updated, self._keys = True, None
|
||||
|
||||
def __getitem__(self, key):
|
||||
rkey = self._store.lookup(key)
|
||||
if rkey is None:
|
||||
raise KeyError(key)
|
||||
# Fetch string
|
||||
value = self.loads(rkey.get_contents_as_string())
|
||||
# Flag that the store has not been updated
|
||||
self._updated = False
|
||||
return value
|
||||
|
||||
def __setitem__(self, key, value):
|
||||
rkey = Key(self._store)
|
||||
rkey.key = key
|
||||
rkey.set_contents_from_string(self.dumps(value))
|
||||
# Flag that the store has been updated
|
||||
self._updated = True
|
||||
|
||||
def __delitem__(self, key):
|
||||
try:
|
||||
self._store.delete_key(key)
|
||||
# Flag that the store has been updated
|
||||
self._updated = True
|
||||
except:
|
||||
raise KeyError(key)
|
||||
|
||||
def keys(self):
|
||||
'''Returns a list of keys in the store.'''
|
||||
return list(i[0] for i in self.items())
|
||||
|
||||
def items(self):
|
||||
'''Returns a list of items from the store.'''
|
||||
if self._updated or self._keys is None:
|
||||
self._keys = self._store.get_all_keys()
|
||||
return list((str(k.key), k) for k in self._keys)
|
||||
|
||||
def iteritems(self):
|
||||
'''Lazily returns items from the store.'''
|
||||
for k in self.items():
|
||||
yield (k.key, k)
|
||||
|
||||
|
||||
__all__ = ['S3Store']
|
@ -1,21 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
Single-process in-memory store.
|
||||
|
||||
The shove psuedo-URL for a simple store is:
|
||||
|
||||
simple://
|
||||
'''
|
||||
|
||||
from shove import BaseStore, SimpleBase
|
||||
|
||||
|
||||
class SimpleStore(SimpleBase, BaseStore):
|
||||
|
||||
'''Single-process in-memory store.'''
|
||||
|
||||
def __init__(self, engine, **kw):
|
||||
super(SimpleStore, self).__init__(engine, **kw)
|
||||
|
||||
|
||||
__all__ = ['SimpleStore']
|
@ -1,110 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
subversion managed store.
|
||||
|
||||
The shove psuedo-URL used for a subversion store that is password protected is:
|
||||
|
||||
svn:<username><password>:<path>?url=<url>
|
||||
|
||||
or for non-password protected repositories:
|
||||
|
||||
svn://<path>?url=<url>
|
||||
|
||||
<path> is the local repository copy
|
||||
<url> is the URL of the subversion repository
|
||||
'''
|
||||
|
||||
import os
|
||||
import urllib
|
||||
import threading
|
||||
|
||||
try:
|
||||
import pysvn
|
||||
except ImportError:
|
||||
raise ImportError('Requires Python Subversion library')
|
||||
|
||||
from shove import BaseStore, synchronized
|
||||
|
||||
|
||||
class SvnStore(BaseStore):
|
||||
|
||||
'''Class for subversion store.'''
|
||||
|
||||
def __init__(self, engine=None, **kw):
|
||||
super(SvnStore, self).__init__(engine, **kw)
|
||||
# Get path, url from keywords if used
|
||||
path, url = kw.get('path'), kw.get('url')
|
||||
# Get username. password from keywords if used
|
||||
user, password = kw.get('user'), kw.get('password')
|
||||
# Process psuedo URL if used
|
||||
if engine is not None:
|
||||
path, query = engine.split('n://')[1].split('?')
|
||||
url = query.split('=')[1]
|
||||
# Check for username, password
|
||||
if '@' in path:
|
||||
auth, path = path.split('@')
|
||||
user, password = auth.split(':')
|
||||
path = urllib.url2pathname(path)
|
||||
# Create subversion client
|
||||
self._client = pysvn.Client()
|
||||
# Assign username, password
|
||||
if user is not None:
|
||||
self._client.set_username(user)
|
||||
if password is not None:
|
||||
self._client.set_password(password)
|
||||
# Verify that store exists in repository
|
||||
try:
|
||||
self._client.info2(url)
|
||||
# Create store in repository if it doesn't exist
|
||||
except pysvn.ClientError:
|
||||
self._client.mkdir(url, 'Adding directory')
|
||||
# Verify that local copy exists
|
||||
try:
|
||||
if self._client.info(path) is None:
|
||||
self._client.checkout(url, path)
|
||||
# Check it out if it doesn't exist
|
||||
except pysvn.ClientError:
|
||||
self._client.checkout(url, path)
|
||||
self._path, self._url = path, url
|
||||
# Lock
|
||||
self._lock = threading.Condition()
|
||||
|
||||
@synchronized
|
||||
def __getitem__(self, key):
|
||||
try:
|
||||
return self.loads(self._client.cat(self._key_to_file(key)))
|
||||
except:
|
||||
raise KeyError(key)
|
||||
|
||||
@synchronized
|
||||
def __setitem__(self, key, value):
|
||||
fname = self._key_to_file(key)
|
||||
# Write value to file
|
||||
open(fname, 'wb').write(self.dumps(value))
|
||||
# Add to repository
|
||||
if key not in self:
|
||||
self._client.add(fname)
|
||||
self._client.checkin([fname], 'Adding %s' % fname)
|
||||
|
||||
@synchronized
|
||||
def __delitem__(self, key):
|
||||
try:
|
||||
fname = self._key_to_file(key)
|
||||
self._client.remove(fname)
|
||||
# Remove deleted value from repository
|
||||
self._client.checkin([fname], 'Removing %s' % fname)
|
||||
except:
|
||||
raise KeyError(key)
|
||||
|
||||
def _key_to_file(self, key):
|
||||
'''Gives the filesystem path for a key.'''
|
||||
return os.path.join(self._path, urllib.quote_plus(key))
|
||||
|
||||
@synchronized
|
||||
def keys(self):
|
||||
'''Returns a list of keys in the subversion repository.'''
|
||||
return list(str(i.name.split('/')[-1]) for i
|
||||
in self._client.ls(self._path))
|
||||
|
||||
|
||||
__all__ = ['SvnStore']
|
@ -1,48 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
Zope Object Database store frontend.
|
||||
|
||||
shove's psuedo-URL for ZODB stores follows the form:
|
||||
|
||||
zodb:<path>
|
||||
|
||||
|
||||
Where the path is a URL path to a ZODB FileStorage database. Alternatively, a
|
||||
native pathname to a ZODB database can be passed as the 'engine' argument.
|
||||
'''
|
||||
|
||||
try:
|
||||
import transaction
|
||||
from ZODB import FileStorage, DB
|
||||
except ImportError:
|
||||
raise ImportError('Requires ZODB library')
|
||||
|
||||
from shove.store import SyncStore
|
||||
|
||||
|
||||
class ZodbStore(SyncStore):
|
||||
|
||||
'''ZODB store front end.'''
|
||||
|
||||
init = 'zodb://'
|
||||
|
||||
def __init__(self, engine, **kw):
|
||||
super(ZodbStore, self).__init__(engine, **kw)
|
||||
# Handle psuedo-URL
|
||||
self._storage = FileStorage.FileStorage(self._engine)
|
||||
self._db = DB(self._storage)
|
||||
self._connection = self._db.open()
|
||||
self._store = self._connection.root()
|
||||
# Keeps DB in synch through commits of transactions
|
||||
self.sync = transaction.commit
|
||||
|
||||
def close(self):
|
||||
'''Closes all open storage and connections.'''
|
||||
self.sync()
|
||||
super(ZodbStore, self).close()
|
||||
self._connection.close()
|
||||
self._db.close()
|
||||
self._storage.close()
|
||||
|
||||
|
||||
__all__ = ['ZodbStore']
|
@ -1 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
@ -1,133 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import unittest
|
||||
|
||||
|
||||
class TestBsdbStore(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
from shove import Shove
|
||||
self.store = Shove('bsddb://test.db', compress=True)
|
||||
|
||||
def tearDown(self):
|
||||
import os
|
||||
self.store.close()
|
||||
os.remove('test.db')
|
||||
|
||||
def test__getitem__(self):
|
||||
self.store['max'] = 3
|
||||
self.assertEqual(self.store['max'], 3)
|
||||
|
||||
def test__setitem__(self):
|
||||
self.store['max'] = 3
|
||||
self.assertEqual(self.store['max'], 3)
|
||||
|
||||
def test__delitem__(self):
|
||||
self.store['max'] = 3
|
||||
del self.store['max']
|
||||
self.assertEqual('max' in self.store, False)
|
||||
|
||||
def test_get(self):
|
||||
self.store['max'] = 3
|
||||
self.assertEqual(self.store.get('min'), None)
|
||||
|
||||
def test__cmp__(self):
|
||||
from shove import Shove
|
||||
tstore = Shove()
|
||||
self.store['max'] = 3
|
||||
tstore['max'] = 3
|
||||
self.assertEqual(self.store, tstore)
|
||||
|
||||
def test__len__(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.assertEqual(len(self.store), 2)
|
||||
|
||||
def test_close(self):
|
||||
self.store.close()
|
||||
self.assertEqual(self.store, None)
|
||||
|
||||
def test_clear(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
self.store.clear()
|
||||
self.assertEqual(len(self.store), 0)
|
||||
|
||||
def test_items(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
slist = list(self.store.items())
|
||||
self.assertEqual(('min', 6) in slist, True)
|
||||
|
||||
def test_iteritems(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
slist = list(self.store.iteritems())
|
||||
self.assertEqual(('min', 6) in slist, True)
|
||||
|
||||
def test_iterkeys(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
slist = list(self.store.iterkeys())
|
||||
self.assertEqual('min' in slist, True)
|
||||
|
||||
def test_itervalues(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
slist = list(self.store.itervalues())
|
||||
self.assertEqual(6 in slist, True)
|
||||
|
||||
def test_pop(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
item = self.store.pop('min')
|
||||
self.assertEqual(item, 6)
|
||||
|
||||
def test_popitem(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
item = self.store.popitem()
|
||||
self.assertEqual(len(item) + len(self.store), 4)
|
||||
|
||||
def test_setdefault(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['powl'] = 7
|
||||
self.store.setdefault('pow', 8)
|
||||
self.assertEqual(self.store['pow'], 8)
|
||||
|
||||
def test_update(self):
|
||||
from shove import Shove
|
||||
tstore = Shove()
|
||||
tstore['max'] = 3
|
||||
tstore['min'] = 6
|
||||
tstore['pow'] = 7
|
||||
self.store['max'] = 2
|
||||
self.store['min'] = 3
|
||||
self.store['pow'] = 7
|
||||
self.store.update(tstore)
|
||||
self.assertEqual(self.store['min'], 6)
|
||||
|
||||
def test_values(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
slist = self.store.values()
|
||||
self.assertEqual(6 in slist, True)
|
||||
|
||||
def test_keys(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
slist = self.store.keys()
|
||||
self.assertEqual('min' in slist, True)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
@ -1,137 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import unittest
|
||||
|
||||
|
||||
class TestCassandraStore(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
from shove import Shove
|
||||
from pycassa.system_manager import SystemManager
|
||||
system_manager = SystemManager('localhost:9160')
|
||||
try:
|
||||
system_manager.create_column_family('Foo', 'shove')
|
||||
except:
|
||||
pass
|
||||
self.store = Shove('cassandra://localhost:9160/Foo/shove')
|
||||
|
||||
def tearDown(self):
|
||||
self.store.clear()
|
||||
self.store.close()
|
||||
from pycassa.system_manager import SystemManager
|
||||
system_manager = SystemManager('localhost:9160')
|
||||
system_manager.drop_column_family('Foo', 'shove')
|
||||
|
||||
def test__getitem__(self):
|
||||
self.store['max'] = 3
|
||||
self.assertEqual(self.store['max'], 3)
|
||||
|
||||
def test__setitem__(self):
|
||||
self.store['max'] = 3
|
||||
self.assertEqual(self.store['max'], 3)
|
||||
|
||||
def test__delitem__(self):
|
||||
self.store['max'] = 3
|
||||
del self.store['max']
|
||||
self.assertEqual('max' in self.store, False)
|
||||
|
||||
def test_get(self):
|
||||
self.store['max'] = 3
|
||||
self.assertEqual(self.store.get('min'), None)
|
||||
|
||||
def test__cmp__(self):
|
||||
from shove import Shove
|
||||
tstore = Shove()
|
||||
self.store['max'] = 3
|
||||
tstore['max'] = 3
|
||||
self.assertEqual(self.store, tstore)
|
||||
|
||||
def test__len__(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.assertEqual(len(self.store), 2)
|
||||
|
||||
# def test_clear(self):
|
||||
# self.store['max'] = 3
|
||||
# self.store['min'] = 6
|
||||
# self.store['pow'] = 7
|
||||
# self.store.clear()
|
||||
# self.assertEqual(len(self.store), 0)
|
||||
|
||||
def test_items(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
slist = list(self.store.items())
|
||||
self.assertEqual(('min', 6) in slist, True)
|
||||
|
||||
def test_iteritems(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
slist = list(self.store.iteritems())
|
||||
self.assertEqual(('min', 6) in slist, True)
|
||||
|
||||
def test_iterkeys(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
slist = list(self.store.iterkeys())
|
||||
self.assertEqual('min' in slist, True)
|
||||
|
||||
def test_itervalues(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
slist = list(self.store.itervalues())
|
||||
self.assertEqual(6 in slist, True)
|
||||
|
||||
def test_pop(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
item = self.store.pop('min')
|
||||
self.assertEqual(item, 6)
|
||||
|
||||
# def test_popitem(self):
|
||||
# self.store['max'] = 3
|
||||
# self.store['min'] = 6
|
||||
# self.store['pow'] = 7
|
||||
# item = self.store.popitem()
|
||||
# self.assertEqual(len(item) + len(self.store), 4)
|
||||
|
||||
def test_setdefault(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
# self.store['pow'] = 7
|
||||
self.store.setdefault('pow', 8)
|
||||
self.assertEqual(self.store.setdefault('pow', 8), 8)
|
||||
self.assertEqual(self.store['pow'], 8)
|
||||
|
||||
def test_update(self):
|
||||
from shove import Shove
|
||||
tstore = Shove()
|
||||
tstore['max'] = 3
|
||||
tstore['min'] = 6
|
||||
tstore['pow'] = 7
|
||||
self.store['max'] = 2
|
||||
self.store['min'] = 3
|
||||
self.store['pow'] = 7
|
||||
self.store.update(tstore)
|
||||
self.assertEqual(self.store['min'], 6)
|
||||
|
||||
def test_values(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
slist = self.store.values()
|
||||
self.assertEqual(6 in slist, True)
|
||||
|
||||
def test_keys(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
slist = self.store.keys()
|
||||
self.assertEqual('min' in slist, True)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
@ -1,54 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import unittest
|
||||
|
||||
|
||||
class TestDbCache(unittest.TestCase):
|
||||
|
||||
initstring = 'sqlite:///'
|
||||
|
||||
def setUp(self):
|
||||
from shove.cache.db import DbCache
|
||||
self.cache = DbCache(self.initstring)
|
||||
|
||||
def tearDown(self):
|
||||
self.cache = None
|
||||
|
||||
def test_getitem(self):
|
||||
self.cache['test'] = 'test'
|
||||
self.assertEqual(self.cache['test'], 'test')
|
||||
|
||||
def test_setitem(self):
|
||||
self.cache['test'] = 'test'
|
||||
self.assertEqual(self.cache['test'], 'test')
|
||||
|
||||
def test_delitem(self):
|
||||
self.cache['test'] = 'test'
|
||||
del self.cache['test']
|
||||
self.assertEqual('test' in self.cache, False)
|
||||
|
||||
def test_get(self):
|
||||
self.assertEqual(self.cache.get('min'), None)
|
||||
|
||||
def test_timeout(self):
|
||||
import time
|
||||
from shove.cache.db import DbCache
|
||||
cache = DbCache(self.initstring, timeout=1)
|
||||
cache['test'] = 'test'
|
||||
time.sleep(2)
|
||||
|
||||
def tmp():
|
||||
cache['test']
|
||||
self.assertRaises(KeyError, tmp)
|
||||
|
||||
def test_cull(self):
|
||||
from shove.cache.db import DbCache
|
||||
cache = DbCache(self.initstring, max_entries=1)
|
||||
cache['test'] = 'test'
|
||||
cache['test2'] = 'test'
|
||||
cache['test2'] = 'test'
|
||||
self.assertEquals(len(cache), 1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
@ -1,131 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import unittest
|
||||
|
||||
|
||||
class TestDbStore(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
from shove import Shove
|
||||
self.store = Shove('sqlite://', compress=True)
|
||||
|
||||
def tearDown(self):
|
||||
self.store.close()
|
||||
|
||||
def test__getitem__(self):
|
||||
self.store['max'] = 3
|
||||
self.assertEqual(self.store['max'], 3)
|
||||
|
||||
def test__setitem__(self):
|
||||
self.store['max'] = 3
|
||||
self.assertEqual(self.store['max'], 3)
|
||||
|
||||
def test__delitem__(self):
|
||||
self.store['max'] = 3
|
||||
del self.store['max']
|
||||
self.assertEqual('max' in self.store, False)
|
||||
|
||||
def test_get(self):
|
||||
self.store['max'] = 3
|
||||
self.assertEqual(self.store.get('min'), None)
|
||||
|
||||
def test__cmp__(self):
|
||||
from shove import Shove
|
||||
tstore = Shove()
|
||||
self.store['max'] = 3
|
||||
tstore['max'] = 3
|
||||
self.assertEqual(self.store, tstore)
|
||||
|
||||
def test__len__(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.assertEqual(len(self.store), 2)
|
||||
|
||||
def test_close(self):
|
||||
self.store.close()
|
||||
self.assertEqual(self.store, None)
|
||||
|
||||
def test_clear(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
self.store.clear()
|
||||
self.assertEqual(len(self.store), 0)
|
||||
|
||||
def test_items(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
slist = list(self.store.items())
|
||||
self.assertEqual(('min', 6) in slist, True)
|
||||
|
||||
def test_iteritems(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
slist = list(self.store.iteritems())
|
||||
self.assertEqual(('min', 6) in slist, True)
|
||||
|
||||
def test_iterkeys(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
slist = list(self.store.iterkeys())
|
||||
self.assertEqual('min' in slist, True)
|
||||
|
||||
def test_itervalues(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
slist = list(self.store.itervalues())
|
||||
self.assertEqual(6 in slist, True)
|
||||
|
||||
def test_pop(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
item = self.store.pop('min')
|
||||
self.assertEqual(item, 6)
|
||||
|
||||
def test_popitem(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
item = self.store.popitem()
|
||||
self.assertEqual(len(item) + len(self.store), 4)
|
||||
|
||||
def test_setdefault(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['powl'] = 7
|
||||
self.store.setdefault('pow', 8)
|
||||
self.assertEqual(self.store['pow'], 8)
|
||||
|
||||
def test_update(self):
|
||||
from shove import Shove
|
||||
tstore = Shove()
|
||||
tstore['max'] = 3
|
||||
tstore['min'] = 6
|
||||
tstore['pow'] = 7
|
||||
self.store['max'] = 2
|
||||
self.store['min'] = 3
|
||||
self.store['pow'] = 7
|
||||
self.store.update(tstore)
|
||||
self.assertEqual(self.store['min'], 6)
|
||||
|
||||
def test_values(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
slist = self.store.values()
|
||||
self.assertEqual(6 in slist, True)
|
||||
|
||||
def test_keys(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
slist = self.store.keys()
|
||||
self.assertEqual('min' in slist, True)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
@ -1,136 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import unittest
|
||||
|
||||
|
||||
class TestDbmStore(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
from shove import Shove
|
||||
self.store = Shove('dbm://test.dbm', compress=True)
|
||||
|
||||
def tearDown(self):
|
||||
import os
|
||||
self.store.close()
|
||||
try:
|
||||
os.remove('test.dbm.db')
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
def test__getitem__(self):
|
||||
self.store['max'] = 3
|
||||
self.assertEqual(self.store['max'], 3)
|
||||
|
||||
def test__setitem__(self):
|
||||
self.store['max'] = 3
|
||||
self.assertEqual(self.store['max'], 3)
|
||||
|
||||
def test__delitem__(self):
|
||||
self.store['max'] = 3
|
||||
del self.store['max']
|
||||
self.assertEqual('max' in self.store, False)
|
||||
|
||||
def test_get(self):
|
||||
self.store['max'] = 3
|
||||
self.assertEqual(self.store.get('min'), None)
|
||||
|
||||
def test__cmp__(self):
|
||||
from shove import Shove
|
||||
tstore = Shove()
|
||||
self.store['max'] = 3
|
||||
tstore['max'] = 3
|
||||
self.assertEqual(self.store, tstore)
|
||||
|
||||
def test__len__(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.assertEqual(len(self.store), 2)
|
||||
|
||||
def test_close(self):
|
||||
self.store.close()
|
||||
self.assertEqual(self.store, None)
|
||||
|
||||
def test_clear(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
self.store.clear()
|
||||
self.assertEqual(len(self.store), 0)
|
||||
|
||||
def test_items(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
slist = list(self.store.items())
|
||||
self.assertEqual(('min', 6) in slist, True)
|
||||
|
||||
def test_iteritems(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
slist = list(self.store.iteritems())
|
||||
self.assertEqual(('min', 6) in slist, True)
|
||||
|
||||
def test_iterkeys(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
slist = list(self.store.iterkeys())
|
||||
self.assertEqual('min' in slist, True)
|
||||
|
||||
def test_itervalues(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
slist = list(self.store.itervalues())
|
||||
self.assertEqual(6 in slist, True)
|
||||
|
||||
def test_pop(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
item = self.store.pop('min')
|
||||
self.assertEqual(item, 6)
|
||||
|
||||
def test_popitem(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
item = self.store.popitem()
|
||||
self.assertEqual(len(item) + len(self.store), 4)
|
||||
|
||||
def test_setdefault(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
self.store.setdefault('how', 8)
|
||||
self.assertEqual(self.store['how'], 8)
|
||||
|
||||
def test_update(self):
|
||||
from shove import Shove
|
||||
tstore = Shove()
|
||||
tstore['max'] = 3
|
||||
tstore['min'] = 6
|
||||
tstore['pow'] = 7
|
||||
self.store['max'] = 2
|
||||
self.store['min'] = 3
|
||||
self.store['pow'] = 7
|
||||
self.store.update(tstore)
|
||||
self.assertEqual(self.store['min'], 6)
|
||||
|
||||
def test_values(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
slist = self.store.values()
|
||||
self.assertEqual(6 in slist, True)
|
||||
|
||||
def test_keys(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
slist = self.store.keys()
|
||||
self.assertEqual('min' in slist, True)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
@ -1,133 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import unittest
|
||||
|
||||
|
||||
class TestDurusStore(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
from shove import Shove
|
||||
self.store = Shove('durus://test.durus', compress=True)
|
||||
|
||||
def tearDown(self):
|
||||
import os
|
||||
self.store.close()
|
||||
os.remove('test.durus')
|
||||
|
||||
def test__getitem__(self):
|
||||
self.store['max'] = 3
|
||||
self.assertEqual(self.store['max'], 3)
|
||||
|
||||
def test__setitem__(self):
|
||||
self.store['max'] = 3
|
||||
self.assertEqual(self.store['max'], 3)
|
||||
|
||||
def test__delitem__(self):
|
||||
self.store['max'] = 3
|
||||
del self.store['max']
|
||||
self.assertEqual('max' in self.store, False)
|
||||
|
||||
def test_get(self):
|
||||
self.store['max'] = 3
|
||||
self.assertEqual(self.store.get('min'), None)
|
||||
|
||||
def test__cmp__(self):
|
||||
from shove import Shove
|
||||
tstore = Shove()
|
||||
self.store['max'] = 3
|
||||
tstore['max'] = 3
|
||||
self.assertEqual(self.store, tstore)
|
||||
|
||||
def test__len__(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.assertEqual(len(self.store), 2)
|
||||
|
||||
def test_close(self):
|
||||
self.store.close()
|
||||
self.assertEqual(self.store, None)
|
||||
|
||||
def test_clear(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
self.store.clear()
|
||||
self.assertEqual(len(self.store), 0)
|
||||
|
||||
def test_items(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
slist = list(self.store.items())
|
||||
self.assertEqual(('min', 6) in slist, True)
|
||||
|
||||
def test_iteritems(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
slist = list(self.store.iteritems())
|
||||
self.assertEqual(('min', 6) in slist, True)
|
||||
|
||||
def test_iterkeys(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
slist = list(self.store.iterkeys())
|
||||
self.assertEqual('min' in slist, True)
|
||||
|
||||
def test_itervalues(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
slist = list(self.store.itervalues())
|
||||
self.assertEqual(6 in slist, True)
|
||||
|
||||
def test_pop(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
item = self.store.pop('min')
|
||||
self.assertEqual(item, 6)
|
||||
|
||||
def test_popitem(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
item = self.store.popitem()
|
||||
self.assertEqual(len(item) + len(self.store), 4)
|
||||
|
||||
def test_setdefault(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['powl'] = 7
|
||||
self.store.setdefault('pow', 8)
|
||||
self.assertEqual(self.store['pow'], 8)
|
||||
|
||||
def test_update(self):
|
||||
from shove import Shove
|
||||
tstore = Shove()
|
||||
tstore['max'] = 3
|
||||
tstore['min'] = 6
|
||||
tstore['pow'] = 7
|
||||
self.store['max'] = 2
|
||||
self.store['min'] = 3
|
||||
self.store['pow'] = 7
|
||||
self.store.update(tstore)
|
||||
self.assertEqual(self.store['min'], 6)
|
||||
|
||||
def test_values(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
slist = self.store.values()
|
||||
self.assertEqual(6 in slist, True)
|
||||
|
||||
def test_keys(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
slist = self.store.keys()
|
||||
self.assertEqual('min' in slist, True)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
@ -1,58 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import unittest
|
||||
|
||||
|
||||
class TestFileCache(unittest.TestCase):
|
||||
|
||||
initstring = 'file://test'
|
||||
|
||||
def setUp(self):
|
||||
from shove.cache.file import FileCache
|
||||
self.cache = FileCache(self.initstring)
|
||||
|
||||
def tearDown(self):
|
||||
import os
|
||||
self.cache = None
|
||||
for x in os.listdir('test'):
|
||||
os.remove(os.path.join('test', x))
|
||||
os.rmdir('test')
|
||||
|
||||
def test_getitem(self):
|
||||
self.cache['test'] = 'test'
|
||||
self.assertEqual(self.cache['test'], 'test')
|
||||
|
||||
def test_setitem(self):
|
||||
self.cache['test'] = 'test'
|
||||
self.assertEqual(self.cache['test'], 'test')
|
||||
|
||||
def test_delitem(self):
|
||||
self.cache['test'] = 'test'
|
||||
del self.cache['test']
|
||||
self.assertEqual('test' in self.cache, False)
|
||||
|
||||
def test_get(self):
|
||||
self.assertEqual(self.cache.get('min'), None)
|
||||
|
||||
def test_timeout(self):
|
||||
import time
|
||||
from shove.cache.file import FileCache
|
||||
cache = FileCache(self.initstring, timeout=1)
|
||||
cache['test'] = 'test'
|
||||
time.sleep(2)
|
||||
|
||||
def tmp():
|
||||
cache['test']
|
||||
self.assertRaises(KeyError, tmp)
|
||||
|
||||
def test_cull(self):
|
||||
from shove.cache.file import FileCache
|
||||
cache = FileCache(self.initstring, max_entries=1)
|
||||
cache['test'] = 'test'
|
||||
cache['test2'] = 'test'
|
||||
num = len(cache)
|
||||
self.assertEquals(num, 1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
@ -1,140 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import unittest
|
||||
|
||||
|
||||
class TestFileStore(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
from shove import Shove
|
||||
self.store = Shove('file://test', compress=True)
|
||||
|
||||
def tearDown(self):
|
||||
import os
|
||||
self.store.close()
|
||||
for x in os.listdir('test'):
|
||||
os.remove(os.path.join('test', x))
|
||||
os.rmdir('test')
|
||||
|
||||
def test__getitem__(self):
|
||||
self.store['max'] = 3
|
||||
self.store.sync()
|
||||
self.assertEqual(self.store['max'], 3)
|
||||
|
||||
def test__setitem__(self):
|
||||
self.store['max'] = 3
|
||||
self.store.sync()
|
||||
self.assertEqual(self.store['max'], 3)
|
||||
|
||||
def test__delitem__(self):
|
||||
self.store['max'] = 3
|
||||
del self.store['max']
|
||||
self.assertEqual('max' in self.store, False)
|
||||
|
||||
def test_get(self):
|
||||
self.store['max'] = 3
|
||||
self.store.sync()
|
||||
self.assertEqual(self.store.get('min'), None)
|
||||
|
||||
def test__cmp__(self):
|
||||
from shove import Shove
|
||||
tstore = Shove()
|
||||
self.store['max'] = 3
|
||||
tstore['max'] = 3
|
||||
self.store.sync()
|
||||
tstore.sync()
|
||||
self.assertEqual(self.store, tstore)
|
||||
|
||||
def test__len__(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.assertEqual(len(self.store), 2)
|
||||
|
||||
def test_close(self):
|
||||
self.store.close()
|
||||
self.assertEqual(self.store, None)
|
||||
|
||||
def test_clear(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
self.store.clear()
|
||||
self.assertEqual(len(self.store), 0)
|
||||
|
||||
def test_items(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
slist = list(self.store.items())
|
||||
self.assertEqual(('min', 6) in slist, True)
|
||||
|
||||
def test_iteritems(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
slist = list(self.store.iteritems())
|
||||
self.assertEqual(('min', 6) in slist, True)
|
||||
|
||||
def test_iterkeys(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
slist = list(self.store.iterkeys())
|
||||
self.assertEqual('min' in slist, True)
|
||||
|
||||
def test_itervalues(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
slist = list(self.store.itervalues())
|
||||
self.assertEqual(6 in slist, True)
|
||||
|
||||
def test_pop(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
item = self.store.pop('min')
|
||||
self.assertEqual(item, 6)
|
||||
|
||||
def test_popitem(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
item = self.store.popitem()
|
||||
self.assertEqual(len(item) + len(self.store), 4)
|
||||
|
||||
def test_setdefault(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['powl'] = 7
|
||||
self.store.setdefault('pow', 8)
|
||||
self.assertEqual(self.store['pow'], 8)
|
||||
|
||||
def test_update(self):
|
||||
from shove import Shove
|
||||
tstore = Shove()
|
||||
tstore['max'] = 3
|
||||
tstore['min'] = 6
|
||||
tstore['pow'] = 7
|
||||
self.store['max'] = 2
|
||||
self.store['min'] = 3
|
||||
self.store['pow'] = 7
|
||||
self.store.update(tstore)
|
||||
self.assertEqual(self.store['min'], 6)
|
||||
|
||||
def test_values(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
slist = self.store.values()
|
||||
self.assertEqual(6 in slist, True)
|
||||
|
||||
def test_keys(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
slist = self.store.keys()
|
||||
self.assertEqual('min' in slist, True)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
@ -1,149 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import unittest
|
||||
|
||||
|
||||
class TestFtpStore(unittest.TestCase):
|
||||
|
||||
ftpstring = 'put ftp string here'
|
||||
|
||||
def setUp(self):
|
||||
from shove import Shove
|
||||
self.store = Shove(self.ftpstring, compress=True)
|
||||
|
||||
def tearDown(self):
|
||||
self.store.clear()
|
||||
self.store.close()
|
||||
|
||||
def test__getitem__(self):
|
||||
self.store['max'] = 3
|
||||
self.store.sync()
|
||||
self.assertEqual(self.store['max'], 3)
|
||||
|
||||
def test__setitem__(self):
|
||||
self.store['max'] = 3
|
||||
self.store.sync()
|
||||
self.assertEqual(self.store['max'], 3)
|
||||
|
||||
def test__delitem__(self):
|
||||
self.store['max'] = 3
|
||||
del self.store['max']
|
||||
self.assertEqual('max' in self.store, False)
|
||||
|
||||
def test_get(self):
|
||||
self.store['max'] = 3
|
||||
self.store.sync()
|
||||
self.assertEqual(self.store.get('min'), None)
|
||||
|
||||
def test__cmp__(self):
|
||||
from shove import Shove
|
||||
tstore = Shove()
|
||||
self.store['max'] = 3
|
||||
tstore['max'] = 3
|
||||
self.store.sync()
|
||||
tstore.sync()
|
||||
self.assertEqual(self.store, tstore)
|
||||
|
||||
def test__len__(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store.sync()
|
||||
self.assertEqual(len(self.store), 2)
|
||||
|
||||
def test_clear(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
self.store.sync()
|
||||
self.store.clear()
|
||||
self.assertEqual(len(self.store), 0)
|
||||
|
||||
def test_items(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
self.store.sync()
|
||||
slist = list(self.store.items())
|
||||
self.assertEqual(('min', 6) in slist, True)
|
||||
|
||||
def test_iteritems(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
self.store.sync()
|
||||
slist = list(self.store.iteritems())
|
||||
self.assertEqual(('min', 6) in slist, True)
|
||||
|
||||
def test_iterkeys(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
self.store.sync()
|
||||
slist = list(self.store.iterkeys())
|
||||
self.assertEqual('min' in slist, True)
|
||||
|
||||
def test_itervalues(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
self.store.sync()
|
||||
slist = list(self.store.itervalues())
|
||||
self.assertEqual(6 in slist, True)
|
||||
|
||||
def test_pop(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store.sync()
|
||||
item = self.store.pop('min')
|
||||
self.assertEqual(item, 6)
|
||||
|
||||
def test_popitem(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
self.store.sync()
|
||||
item = self.store.popitem()
|
||||
self.store.sync()
|
||||
self.assertEqual(len(item) + len(self.store), 4)
|
||||
|
||||
def test_setdefault(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['powl'] = 7
|
||||
self.store.setdefault('pow', 8)
|
||||
self.store.sync()
|
||||
self.assertEqual(self.store['pow'], 8)
|
||||
|
||||
def test_update(self):
|
||||
from shove import Shove
|
||||
tstore = Shove()
|
||||
tstore['max'] = 3
|
||||
tstore['min'] = 6
|
||||
tstore['pow'] = 7
|
||||
self.store['max'] = 2
|
||||
self.store['min'] = 3
|
||||
self.store['pow'] = 7
|
||||
self.store.sync()
|
||||
self.store.update(tstore)
|
||||
self.store.sync()
|
||||
self.assertEqual(self.store['min'], 6)
|
||||
|
||||
def test_values(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
self.store.sync()
|
||||
slist = self.store.values()
|
||||
self.assertEqual(6 in slist, True)
|
||||
|
||||
def test_keys(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
self.store.sync()
|
||||
slist = self.store.keys()
|
||||
self.assertEqual('min' in slist, True)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
@ -1,135 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import unittest2
|
||||
|
||||
|
||||
class TestHDF5Store(unittest2.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
from shove import Shove
|
||||
self.store = Shove('hdf5://test.hdf5/test')
|
||||
|
||||
def tearDown(self):
|
||||
import os
|
||||
self.store.close()
|
||||
try:
|
||||
os.remove('test.hdf5')
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
def test__getitem__(self):
|
||||
self.store['max'] = 3
|
||||
self.assertEqual(self.store['max'], 3)
|
||||
|
||||
def test__setitem__(self):
|
||||
self.store['max'] = 3
|
||||
self.assertEqual(self.store['max'], 3)
|
||||
|
||||
def test__delitem__(self):
|
||||
self.store['max'] = 3
|
||||
del self.store['max']
|
||||
self.assertEqual('max' in self.store, False)
|
||||
|
||||
def test_get(self):
|
||||
self.store['max'] = 3
|
||||
self.assertEqual(self.store.get('min'), None)
|
||||
|
||||
def test__cmp__(self):
|
||||
from shove import Shove
|
||||
tstore = Shove()
|
||||
self.store['max'] = 3
|
||||
tstore['max'] = 3
|
||||
self.assertEqual(self.store, tstore)
|
||||
|
||||
def test__len__(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.assertEqual(len(self.store), 2)
|
||||
|
||||
def test_close(self):
|
||||
self.store.close()
|
||||
self.assertEqual(self.store, None)
|
||||
|
||||
def test_clear(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
self.store.clear()
|
||||
self.assertEqual(len(self.store), 0)
|
||||
|
||||
def test_items(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
slist = list(self.store.items())
|
||||
self.assertEqual(('min', 6) in slist, True)
|
||||
|
||||
def test_iteritems(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
slist = list(self.store.iteritems())
|
||||
self.assertEqual(('min', 6) in slist, True)
|
||||
|
||||
def test_iterkeys(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
slist = list(self.store.iterkeys())
|
||||
self.assertEqual('min' in slist, True)
|
||||
|
||||
def test_itervalues(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
slist = list(self.store.itervalues())
|
||||
self.assertEqual(6 in slist, True)
|
||||
|
||||
def test_pop(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
item = self.store.pop('min')
|
||||
self.assertEqual(item, 6)
|
||||
|
||||
def test_popitem(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
item = self.store.popitem()
|
||||
self.assertEqual(len(item) + len(self.store), 4)
|
||||
|
||||
def test_setdefault(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
self.store.setdefault('bow', 8)
|
||||
self.assertEqual(self.store['bow'], 8)
|
||||
|
||||
def test_update(self):
|
||||
from shove import Shove
|
||||
tstore = Shove()
|
||||
tstore['max'] = 3
|
||||
tstore['min'] = 6
|
||||
tstore['pow'] = 7
|
||||
self.store['max'] = 2
|
||||
self.store['min'] = 3
|
||||
self.store['pow'] = 7
|
||||
self.store.update(tstore)
|
||||
self.assertEqual(self.store['min'], 6)
|
||||
|
||||
def test_values(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
slist = self.store.values()
|
||||
self.assertEqual(6 in slist, True)
|
||||
|
||||
def test_keys(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
slist = self.store.keys()
|
||||
self.assertEqual('min' in slist, True)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest2.main()
|
@ -1,132 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import unittest2
|
||||
|
||||
|
||||
class TestLevelDBStore(unittest2.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
from shove import Shove
|
||||
self.store = Shove('leveldb://test', compress=True)
|
||||
|
||||
def tearDown(self):
|
||||
import shutil
|
||||
shutil.rmtree('test')
|
||||
|
||||
def test__getitem__(self):
|
||||
self.store['max'] = 3
|
||||
self.assertEqual(self.store['max'], 3)
|
||||
|
||||
def test__setitem__(self):
|
||||
self.store['max'] = 3
|
||||
self.assertEqual(self.store['max'], 3)
|
||||
|
||||
def test__delitem__(self):
|
||||
self.store['max'] = 3
|
||||
del self.store['max']
|
||||
self.assertEqual('max' in self.store, False)
|
||||
|
||||
def test_get(self):
|
||||
self.store['max'] = 3
|
||||
self.assertEqual(self.store.get('min'), None)
|
||||
|
||||
def test__cmp__(self):
|
||||
from shove import Shove
|
||||
tstore = Shove()
|
||||
self.store['max'] = 3
|
||||
tstore['max'] = 3
|
||||
self.assertEqual(self.store, tstore)
|
||||
|
||||
def test__len__(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.assertEqual(len(self.store), 2)
|
||||
|
||||
def test_close(self):
|
||||
self.store.close()
|
||||
self.assertEqual(self.store, None)
|
||||
|
||||
def test_clear(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
self.store.clear()
|
||||
self.assertEqual(len(self.store), 0)
|
||||
|
||||
def test_items(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
slist = list(self.store.items())
|
||||
self.assertEqual(('min', 6) in slist, True)
|
||||
|
||||
def test_iteritems(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
slist = list(self.store.iteritems())
|
||||
self.assertEqual(('min', 6) in slist, True)
|
||||
|
||||
def test_iterkeys(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
slist = list(self.store.iterkeys())
|
||||
self.assertEqual('min' in slist, True)
|
||||
|
||||
def test_itervalues(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
slist = list(self.store.itervalues())
|
||||
self.assertEqual(6 in slist, True)
|
||||
|
||||
def test_pop(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
item = self.store.pop('min')
|
||||
self.assertEqual(item, 6)
|
||||
|
||||
def test_popitem(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
item = self.store.popitem()
|
||||
self.assertEqual(len(item) + len(self.store), 4)
|
||||
|
||||
def test_setdefault(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
self.store.setdefault('bow', 8)
|
||||
self.assertEqual(self.store['bow'], 8)
|
||||
|
||||
def test_update(self):
|
||||
from shove import Shove
|
||||
tstore = Shove()
|
||||
tstore['max'] = 3
|
||||
tstore['min'] = 6
|
||||
tstore['pow'] = 7
|
||||
self.store['max'] = 2
|
||||
self.store['min'] = 3
|
||||
self.store['pow'] = 7
|
||||
self.store.update(tstore)
|
||||
self.assertEqual(self.store['min'], 6)
|
||||
|
||||
def test_values(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
slist = self.store.values()
|
||||
self.assertEqual(6 in slist, True)
|
||||
|
||||
def test_keys(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
slist = self.store.keys()
|
||||
self.assertEqual('min' in slist, True)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest2.main()
|
@ -1,46 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import unittest
|
||||
|
||||
|
||||
class TestMemcached(unittest.TestCase):
|
||||
|
||||
initstring = 'memcache://localhost:11211'
|
||||
|
||||
def setUp(self):
|
||||
from shove.cache.memcached import MemCached
|
||||
self.cache = MemCached(self.initstring)
|
||||
|
||||
def tearDown(self):
|
||||
self.cache = None
|
||||
|
||||
def test_getitem(self):
|
||||
self.cache['test'] = 'test'
|
||||
self.assertEqual(self.cache['test'], 'test')
|
||||
|
||||
def test_setitem(self):
|
||||
self.cache['test'] = 'test'
|
||||
self.assertEqual(self.cache['test'], 'test')
|
||||
|
||||
def test_delitem(self):
|
||||
self.cache['test'] = 'test'
|
||||
del self.cache['test']
|
||||
self.assertEqual('test' in self.cache, False)
|
||||
|
||||
def test_get(self):
|
||||
self.assertEqual(self.cache.get('min'), None)
|
||||
|
||||
def test_timeout(self):
|
||||
import time
|
||||
from shove.cache.memcached import MemCached
|
||||
cache = MemCached(self.initstring, timeout=1)
|
||||
cache['test'] = 'test'
|
||||
time.sleep(1)
|
||||
|
||||
def tmp():
|
||||
cache['test']
|
||||
self.assertRaises(KeyError, tmp)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
@ -1,54 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import unittest
|
||||
|
||||
|
||||
class TestMemoryCache(unittest.TestCase):
|
||||
|
||||
initstring = 'memory://'
|
||||
|
||||
def setUp(self):
|
||||
from shove.cache.memory import MemoryCache
|
||||
self.cache = MemoryCache(self.initstring)
|
||||
|
||||
def tearDown(self):
|
||||
self.cache = None
|
||||
|
||||
def test_getitem(self):
|
||||
self.cache['test'] = 'test'
|
||||
self.assertEqual(self.cache['test'], 'test')
|
||||
|
||||
def test_setitem(self):
|
||||
self.cache['test'] = 'test'
|
||||
self.assertEqual(self.cache['test'], 'test')
|
||||
|
||||
def test_delitem(self):
|
||||
self.cache['test'] = 'test'
|
||||
del self.cache['test']
|
||||
self.assertEqual('test' in self.cache, False)
|
||||
|
||||
def test_get(self):
|
||||
self.assertEqual(self.cache.get('min'), None)
|
||||
|
||||
def test_timeout(self):
|
||||
import time
|
||||
from shove.cache.memory import MemoryCache
|
||||
cache = MemoryCache(self.initstring, timeout=1)
|
||||
cache['test'] = 'test'
|
||||
time.sleep(1)
|
||||
|
||||
def tmp():
|
||||
cache['test']
|
||||
self.assertRaises(KeyError, tmp)
|
||||
|
||||
def test_cull(self):
|
||||
from shove.cache.memory import MemoryCache
|
||||
cache = MemoryCache(self.initstring, max_entries=1)
|
||||
cache['test'] = 'test'
|
||||
cache['test2'] = 'test'
|
||||
cache['test2'] = 'test'
|
||||
self.assertEquals(len(cache), 1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
@ -1,135 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import unittest
|
||||
|
||||
|
||||
class TestMemoryStore(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
from shove import Shove
|
||||
self.store = Shove('memory://', compress=True)
|
||||
|
||||
def tearDown(self):
|
||||
self.store.close()
|
||||
|
||||
def test__getitem__(self):
|
||||
self.store['max'] = 3
|
||||
self.store.sync()
|
||||
self.assertEqual(self.store['max'], 3)
|
||||
|
||||
def test__setitem__(self):
|
||||
self.store['max'] = 3
|
||||
self.store.sync()
|
||||
self.assertEqual(self.store['max'], 3)
|
||||
|
||||
def test__delitem__(self):
|
||||
self.store['max'] = 3
|
||||
del self.store['max']
|
||||
self.assertEqual('max' in self.store, False)
|
||||
|
||||
def test_get(self):
|
||||
self.store['max'] = 3
|
||||
self.store.sync()
|
||||
self.assertEqual(self.store.get('min'), None)
|
||||
|
||||
def test__cmp__(self):
|
||||
from shove import Shove
|
||||
tstore = Shove()
|
||||
self.store['max'] = 3
|
||||
tstore['max'] = 3
|
||||
self.store.sync()
|
||||
tstore.sync()
|
||||
self.assertEqual(self.store, tstore)
|
||||
|
||||
def test__len__(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.assertEqual(len(self.store), 2)
|
||||
|
||||
def test_close(self):
|
||||
self.store.close()
|
||||
self.assertEqual(self.store, None)
|
||||
|
||||
def test_clear(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
self.store.clear()
|
||||
self.assertEqual(len(self.store), 0)
|
||||
|
||||
def test_items(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
slist = list(self.store.items())
|
||||
self.assertEqual(('min', 6) in slist, True)
|
||||
|
||||
def test_iteritems(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
slist = list(self.store.iteritems())
|
||||
self.assertEqual(('min', 6) in slist, True)
|
||||
|
||||
def test_iterkeys(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
slist = list(self.store.iterkeys())
|
||||
self.assertEqual('min' in slist, True)
|
||||
|
||||
def test_itervalues(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
slist = list(self.store.itervalues())
|
||||
self.assertEqual(6 in slist, True)
|
||||
|
||||
def test_pop(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
item = self.store.pop('min')
|
||||
self.assertEqual(item, 6)
|
||||
|
||||
def test_popitem(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
item = self.store.popitem()
|
||||
self.assertEqual(len(item) + len(self.store), 4)
|
||||
|
||||
def test_setdefault(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['powl'] = 7
|
||||
self.store.setdefault('pow', 8)
|
||||
self.assertEqual(self.store['pow'], 8)
|
||||
|
||||
def test_update(self):
|
||||
from shove import Shove
|
||||
tstore = Shove()
|
||||
tstore['max'] = 3
|
||||
tstore['min'] = 6
|
||||
tstore['pow'] = 7
|
||||
self.store['max'] = 2
|
||||
self.store['min'] = 3
|
||||
self.store['pow'] = 7
|
||||
self.store.update(tstore)
|
||||
self.assertEqual(self.store['min'], 6)
|
||||
|
||||
def test_values(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
slist = self.store.values()
|
||||
self.assertEqual(6 in slist, True)
|
||||
|
||||
def test_keys(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
slist = self.store.keys()
|
||||
self.assertEqual('min' in slist, True)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
@ -1,45 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import unittest
|
||||
|
||||
|
||||
class TestRedisCache(unittest.TestCase):
|
||||
|
||||
initstring = 'redis://localhost:6379/0'
|
||||
|
||||
def setUp(self):
|
||||
from shove.cache.redisdb import RedisCache
|
||||
self.cache = RedisCache(self.initstring)
|
||||
|
||||
def tearDown(self):
|
||||
self.cache = None
|
||||
|
||||
def test_getitem(self):
|
||||
self.cache['test'] = 'test'
|
||||
self.assertEqual(self.cache['test'], 'test')
|
||||
|
||||
def test_setitem(self):
|
||||
self.cache['test'] = 'test'
|
||||
self.assertEqual(self.cache['test'], 'test')
|
||||
|
||||
def test_delitem(self):
|
||||
self.cache['test'] = 'test'
|
||||
del self.cache['test']
|
||||
self.assertEqual('test' in self.cache, False)
|
||||
|
||||
def test_get(self):
|
||||
self.assertEqual(self.cache.get('min'), None)
|
||||
|
||||
def test_timeout(self):
|
||||
import time
|
||||
from shove.cache.redisdb import RedisCache
|
||||
cache = RedisCache(self.initstring, timeout=1)
|
||||
cache['test'] = 'test'
|
||||
time.sleep(3)
|
||||
def tmp(): #@IgnorePep8
|
||||
return cache['test']
|
||||
self.assertRaises(KeyError, tmp)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
@ -1,128 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import unittest
|
||||
|
||||
|
||||
class TestRedisStore(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
from shove import Shove
|
||||
self.store = Shove('redis://localhost:6379/0')
|
||||
|
||||
def tearDown(self):
|
||||
self.store.clear()
|
||||
self.store.close()
|
||||
|
||||
def test__getitem__(self):
|
||||
self.store['max'] = 3
|
||||
self.assertEqual(self.store['max'], 3)
|
||||
|
||||
def test__setitem__(self):
|
||||
self.store['max'] = 3
|
||||
self.assertEqual(self.store['max'], 3)
|
||||
|
||||
def test__delitem__(self):
|
||||
self.store['max'] = 3
|
||||
del self.store['max']
|
||||
self.assertEqual('max' in self.store, False)
|
||||
|
||||
def test_get(self):
|
||||
self.store['max'] = 3
|
||||
self.assertEqual(self.store.get('min'), None)
|
||||
|
||||
def test__cmp__(self):
|
||||
from shove import Shove
|
||||
tstore = Shove()
|
||||
self.store['max'] = 3
|
||||
tstore['max'] = 3
|
||||
self.assertEqual(self.store, tstore)
|
||||
|
||||
def test__len__(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.assertEqual(len(self.store), 2)
|
||||
|
||||
def test_clear(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
self.store.clear()
|
||||
self.assertEqual(len(self.store), 0)
|
||||
|
||||
def test_items(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
slist = list(self.store.items())
|
||||
self.assertEqual(('min', 6) in slist, True)
|
||||
|
||||
def test_iteritems(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
slist = list(self.store.iteritems())
|
||||
self.assertEqual(('min', 6) in slist, True)
|
||||
|
||||
def test_iterkeys(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
slist = list(self.store.iterkeys())
|
||||
self.assertEqual('min' in slist, True)
|
||||
|
||||
def test_itervalues(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
slist = list(self.store.itervalues())
|
||||
self.assertEqual(6 in slist, True)
|
||||
|
||||
def test_pop(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
item = self.store.pop('min')
|
||||
self.assertEqual(item, 6)
|
||||
|
||||
def test_popitem(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
item = self.store.popitem()
|
||||
self.assertEqual(len(item) + len(self.store), 4)
|
||||
|
||||
def test_setdefault(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['powl'] = 7
|
||||
self.store.setdefault('pow', 8)
|
||||
self.assertEqual(self.store.setdefault('pow', 8), 8)
|
||||
self.assertEqual(self.store['pow'], 8)
|
||||
|
||||
def test_update(self):
|
||||
from shove import Shove
|
||||
tstore = Shove()
|
||||
tstore['max'] = 3
|
||||
tstore['min'] = 6
|
||||
tstore['pow'] = 7
|
||||
self.store['max'] = 2
|
||||
self.store['min'] = 3
|
||||
self.store['pow'] = 7
|
||||
self.store.update(tstore)
|
||||
self.assertEqual(self.store['min'], 6)
|
||||
|
||||
def test_values(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
slist = self.store.values()
|
||||
self.assertEqual(6 in slist, True)
|
||||
|
||||
def test_keys(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
slist = self.store.keys()
|
||||
self.assertEqual('min' in slist, True)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
@ -1,149 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import unittest
|
||||
|
||||
|
||||
class TestS3Store(unittest.TestCase):
|
||||
|
||||
s3string = 's3 test string here'
|
||||
|
||||
def setUp(self):
|
||||
from shove import Shove
|
||||
self.store = Shove(self.s3string, compress=True)
|
||||
|
||||
def tearDown(self):
|
||||
self.store.clear()
|
||||
self.store.close()
|
||||
|
||||
def test__getitem__(self):
|
||||
self.store['max'] = 3
|
||||
self.store.sync()
|
||||
self.assertEqual(self.store['max'], 3)
|
||||
|
||||
def test__setitem__(self):
|
||||
self.store['max'] = 3
|
||||
self.store.sync()
|
||||
self.assertEqual(self.store['max'], 3)
|
||||
|
||||
def test__delitem__(self):
|
||||
self.store['max'] = 3
|
||||
del self.store['max']
|
||||
self.assertEqual('max' in self.store, False)
|
||||
|
||||
def test_get(self):
|
||||
self.store['max'] = 3
|
||||
self.store.sync()
|
||||
self.assertEqual(self.store.get('min'), None)
|
||||
|
||||
def test__cmp__(self):
|
||||
from shove import Shove
|
||||
tstore = Shove()
|
||||
self.store['max'] = 3
|
||||
tstore['max'] = 3
|
||||
self.store.sync()
|
||||
tstore.sync()
|
||||
self.assertEqual(self.store, tstore)
|
||||
|
||||
def test__len__(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store.sync()
|
||||
self.assertEqual(len(self.store), 2)
|
||||
|
||||
def test_clear(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
self.store.sync()
|
||||
self.store.clear()
|
||||
self.assertEqual(len(self.store), 0)
|
||||
|
||||
def test_items(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
self.store.sync()
|
||||
slist = list(self.store.items())
|
||||
self.assertEqual(('min', 6) in slist, True)
|
||||
|
||||
def test_iteritems(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
self.store.sync()
|
||||
slist = list(self.store.iteritems())
|
||||
self.assertEqual(('min', 6) in slist, True)
|
||||
|
||||
def test_iterkeys(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
self.store.sync()
|
||||
slist = list(self.store.iterkeys())
|
||||
self.assertEqual('min' in slist, True)
|
||||
|
||||
def test_itervalues(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
self.store.sync()
|
||||
slist = list(self.store.itervalues())
|
||||
self.assertEqual(6 in slist, True)
|
||||
|
||||
def test_pop(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store.sync()
|
||||
item = self.store.pop('min')
|
||||
self.assertEqual(item, 6)
|
||||
|
||||
def test_popitem(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
self.store.sync()
|
||||
item = self.store.popitem()
|
||||
self.store.sync()
|
||||
self.assertEqual(len(item) + len(self.store), 4)
|
||||
|
||||
def test_setdefault(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['powl'] = 7
|
||||
self.store.setdefault('pow', 8)
|
||||
self.store.sync()
|
||||
self.assertEqual(self.store['pow'], 8)
|
||||
|
||||
def test_update(self):
|
||||
from shove import Shove
|
||||
tstore = Shove()
|
||||
tstore['max'] = 3
|
||||
tstore['min'] = 6
|
||||
tstore['pow'] = 7
|
||||
self.store['max'] = 2
|
||||
self.store['min'] = 3
|
||||
self.store['pow'] = 7
|
||||
self.store.sync()
|
||||
self.store.update(tstore)
|
||||
self.store.sync()
|
||||
self.assertEqual(self.store['min'], 6)
|
||||
|
||||
def test_values(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
self.store.sync()
|
||||
slist = self.store.values()
|
||||
self.assertEqual(6 in slist, True)
|
||||
|
||||
def test_keys(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
self.store.sync()
|
||||
slist = self.store.keys()
|
||||
self.assertEqual('min' in slist, True)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
@ -1,54 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import unittest
|
||||
|
||||
|
||||
class TestSimpleCache(unittest.TestCase):
|
||||
|
||||
initstring = 'simple://'
|
||||
|
||||
def setUp(self):
|
||||
from shove.cache.simple import SimpleCache
|
||||
self.cache = SimpleCache(self.initstring)
|
||||
|
||||
def tearDown(self):
|
||||
self.cache = None
|
||||
|
||||
def test_getitem(self):
|
||||
self.cache['test'] = 'test'
|
||||
self.assertEqual(self.cache['test'], 'test')
|
||||
|
||||
def test_setitem(self):
|
||||
self.cache['test'] = 'test'
|
||||
self.assertEqual(self.cache['test'], 'test')
|
||||
|
||||
def test_delitem(self):
|
||||
self.cache['test'] = 'test'
|
||||
del self.cache['test']
|
||||
self.assertEqual('test' in self.cache, False)
|
||||
|
||||
def test_get(self):
|
||||
self.assertEqual(self.cache.get('min'), None)
|
||||
|
||||
def test_timeout(self):
|
||||
import time
|
||||
from shove.cache.simple import SimpleCache
|
||||
cache = SimpleCache(self.initstring, timeout=1)
|
||||
cache['test'] = 'test'
|
||||
time.sleep(1)
|
||||
|
||||
def tmp():
|
||||
cache['test']
|
||||
self.assertRaises(KeyError, tmp)
|
||||
|
||||
def test_cull(self):
|
||||
from shove.cache.simple import SimpleCache
|
||||
cache = SimpleCache(self.initstring, max_entries=1)
|
||||
cache['test'] = 'test'
|
||||
cache['test2'] = 'test'
|
||||
cache['test2'] = 'test'
|
||||
self.assertEquals(len(cache), 1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
@ -1,135 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import unittest
|
||||
|
||||
|
||||
class TestSimpleStore(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
from shove import Shove
|
||||
self.store = Shove('simple://', compress=True)
|
||||
|
||||
def tearDown(self):
|
||||
self.store.close()
|
||||
|
||||
def test__getitem__(self):
|
||||
self.store['max'] = 3
|
||||
self.store.sync()
|
||||
self.assertEqual(self.store['max'], 3)
|
||||
|
||||
def test__setitem__(self):
|
||||
self.store['max'] = 3
|
||||
self.store.sync()
|
||||
self.assertEqual(self.store['max'], 3)
|
||||
|
||||
def test__delitem__(self):
|
||||
self.store['max'] = 3
|
||||
del self.store['max']
|
||||
self.assertEqual('max' in self.store, False)
|
||||
|
||||
def test_get(self):
|
||||
self.store['max'] = 3
|
||||
self.store.sync()
|
||||
self.assertEqual(self.store.get('min'), None)
|
||||
|
||||
def test__cmp__(self):
|
||||
from shove import Shove
|
||||
tstore = Shove()
|
||||
self.store['max'] = 3
|
||||
tstore['max'] = 3
|
||||
self.store.sync()
|
||||
tstore.sync()
|
||||
self.assertEqual(self.store, tstore)
|
||||
|
||||
def test__len__(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.assertEqual(len(self.store), 2)
|
||||
|
||||
def test_close(self):
|
||||
self.store.close()
|
||||
self.assertEqual(self.store, None)
|
||||
|
||||
def test_clear(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
self.store.clear()
|
||||
self.assertEqual(len(self.store), 0)
|
||||
|
||||
def test_items(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
slist = list(self.store.items())
|
||||
self.assertEqual(('min', 6) in slist, True)
|
||||
|
||||
def test_iteritems(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
slist = list(self.store.iteritems())
|
||||
self.assertEqual(('min', 6) in slist, True)
|
||||
|
||||
def test_iterkeys(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
slist = list(self.store.iterkeys())
|
||||
self.assertEqual('min' in slist, True)
|
||||
|
||||
def test_itervalues(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
slist = list(self.store.itervalues())
|
||||
self.assertEqual(6 in slist, True)
|
||||
|
||||
def test_pop(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
item = self.store.pop('min')
|
||||
self.assertEqual(item, 6)
|
||||
|
||||
def test_popitem(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
item = self.store.popitem()
|
||||
self.assertEqual(len(item) + len(self.store), 4)
|
||||
|
||||
def test_setdefault(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['powl'] = 7
|
||||
self.store.setdefault('pow', 8)
|
||||
self.assertEqual(self.store['pow'], 8)
|
||||
|
||||
def test_update(self):
|
||||
from shove import Shove
|
||||
tstore = Shove()
|
||||
tstore['max'] = 3
|
||||
tstore['min'] = 6
|
||||
tstore['pow'] = 7
|
||||
self.store['max'] = 2
|
||||
self.store['min'] = 3
|
||||
self.store['pow'] = 7
|
||||
self.store.update(tstore)
|
||||
self.assertEqual(self.store['min'], 6)
|
||||
|
||||
def test_values(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
slist = self.store.values()
|
||||
self.assertEqual(6 in slist, True)
|
||||
|
||||
def test_keys(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
slist = self.store.keys()
|
||||
self.assertEqual('min' in slist, True)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
@ -1,148 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import unittest
|
||||
|
||||
|
||||
class TestSvnStore(unittest.TestCase):
|
||||
|
||||
svnstring = 'SVN test string here'
|
||||
|
||||
def setUp(self):
|
||||
from shove import Shove
|
||||
self.store = Shove(self.svnstring, compress=True)
|
||||
|
||||
def tearDown(self):
|
||||
self.store.clear()
|
||||
self.store.close()
|
||||
|
||||
def test__getitem__(self):
|
||||
self.store['max'] = 3
|
||||
self.store.sync()
|
||||
self.assertEqual(self.store['max'], 3)
|
||||
|
||||
def test__setitem__(self):
|
||||
self.store['max'] = 3
|
||||
self.store.sync()
|
||||
self.assertEqual(self.store['max'], 3)
|
||||
|
||||
def test__delitem__(self):
|
||||
self.store['max'] = 3
|
||||
del self.store['max']
|
||||
self.assertEqual('max' in self.store, False)
|
||||
|
||||
def test_get(self):
|
||||
self.store['max'] = 3
|
||||
self.store.sync()
|
||||
self.assertEqual(self.store.get('min'), None)
|
||||
|
||||
def test__cmp__(self):
|
||||
from shove import Shove
|
||||
tstore = Shove()
|
||||
self.store['max'] = 3
|
||||
tstore['max'] = 3
|
||||
self.store.sync()
|
||||
tstore.sync()
|
||||
self.assertEqual(self.store, tstore)
|
||||
|
||||
def test__len__(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store.sync()
|
||||
self.assertEqual(len(self.store), 2)
|
||||
|
||||
def test_clear(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
self.store.sync()
|
||||
self.store.clear()
|
||||
self.assertEqual(len(self.store), 0)
|
||||
|
||||
def test_items(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
self.store.sync()
|
||||
slist = list(self.store.items())
|
||||
self.assertEqual(('min', 6) in slist, True)
|
||||
|
||||
def test_iteritems(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
self.store.sync()
|
||||
slist = list(self.store.iteritems())
|
||||
self.assertEqual(('min', 6) in slist, True)
|
||||
|
||||
def test_iterkeys(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
self.store.sync()
|
||||
slist = list(self.store.iterkeys())
|
||||
self.assertEqual('min' in slist, True)
|
||||
|
||||
def test_itervalues(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
self.store.sync()
|
||||
slist = list(self.store.itervalues())
|
||||
self.assertEqual(6 in slist, True)
|
||||
|
||||
def test_pop(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store.sync()
|
||||
item = self.store.pop('min')
|
||||
self.assertEqual(item, 6)
|
||||
|
||||
def test_popitem(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
self.store.sync()
|
||||
item = self.store.popitem()
|
||||
self.store.sync()
|
||||
self.assertEqual(len(item) + len(self.store), 4)
|
||||
|
||||
def test_setdefault(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['powl'] = 7
|
||||
self.store.setdefault('pow', 8)
|
||||
self.store.sync()
|
||||
self.assertEqual(self.store['pow'], 8)
|
||||
|
||||
def test_update(self):
|
||||
from shove import Shove
|
||||
tstore = Shove()
|
||||
tstore['max'] = 3
|
||||
tstore['min'] = 6
|
||||
tstore['pow'] = 7
|
||||
self.store['max'] = 2
|
||||
self.store['min'] = 3
|
||||
self.store['pow'] = 7
|
||||
self.store.sync()
|
||||
self.store.update(tstore)
|
||||
self.store.sync()
|
||||
self.assertEqual(self.store['min'], 6)
|
||||
|
||||
def test_values(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
self.store.sync()
|
||||
slist = self.store.values()
|
||||
self.assertEqual(6 in slist, True)
|
||||
|
||||
def test_keys(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
self.store.sync()
|
||||
slist = self.store.keys()
|
||||
self.assertEqual('min' in slist, True)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
@ -1,138 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import unittest
|
||||
|
||||
|
||||
class TestZodbStore(unittest.TestCase):
|
||||
|
||||
init = 'zodb://test.db'
|
||||
|
||||
def setUp(self):
|
||||
from shove import Shove
|
||||
self.store = Shove(self.init, compress=True)
|
||||
|
||||
def tearDown(self):
|
||||
self.store.close()
|
||||
import os
|
||||
os.remove('test.db')
|
||||
os.remove('test.db.index')
|
||||
os.remove('test.db.tmp')
|
||||
os.remove('test.db.lock')
|
||||
|
||||
def test__getitem__(self):
|
||||
self.store['max'] = 3
|
||||
self.assertEqual(self.store['max'], 3)
|
||||
|
||||
def test__setitem__(self):
|
||||
self.store['max'] = 3
|
||||
self.assertEqual(self.store['max'], 3)
|
||||
|
||||
def test__delitem__(self):
|
||||
self.store['max'] = 3
|
||||
del self.store['max']
|
||||
self.assertEqual('max' in self.store, False)
|
||||
|
||||
def test_get(self):
|
||||
self.store['max'] = 3
|
||||
self.assertEqual(self.store.get('min'), None)
|
||||
|
||||
def test__cmp__(self):
|
||||
from shove import Shove
|
||||
tstore = Shove()
|
||||
self.store['max'] = 3
|
||||
tstore['max'] = 3
|
||||
self.assertEqual(self.store, tstore)
|
||||
|
||||
def test__len__(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.assertEqual(len(self.store), 2)
|
||||
|
||||
def test_close(self):
|
||||
self.store.close()
|
||||
self.assertEqual(self.store, None)
|
||||
|
||||
def test_clear(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
self.store.clear()
|
||||
self.assertEqual(len(self.store), 0)
|
||||
|
||||
def test_items(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
slist = list(self.store.items())
|
||||
self.assertEqual(('min', 6) in slist, True)
|
||||
|
||||
def test_iteritems(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
slist = list(self.store.iteritems())
|
||||
self.assertEqual(('min', 6) in slist, True)
|
||||
|
||||
def test_iterkeys(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
slist = list(self.store.iterkeys())
|
||||
self.assertEqual('min' in slist, True)
|
||||
|
||||
def test_itervalues(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
slist = list(self.store.itervalues())
|
||||
self.assertEqual(6 in slist, True)
|
||||
|
||||
def test_pop(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
item = self.store.pop('min')
|
||||
self.assertEqual(item, 6)
|
||||
|
||||
def test_popitem(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
item = self.store.popitem()
|
||||
self.assertEqual(len(item) + len(self.store), 4)
|
||||
|
||||
def test_setdefault(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['powl'] = 7
|
||||
self.store.setdefault('pow', 8)
|
||||
self.assertEqual(self.store['pow'], 8)
|
||||
|
||||
def test_update(self):
|
||||
from shove import Shove
|
||||
tstore = Shove()
|
||||
tstore['max'] = 3
|
||||
tstore['min'] = 6
|
||||
tstore['pow'] = 7
|
||||
self.store['max'] = 2
|
||||
self.store['min'] = 3
|
||||
self.store['pow'] = 7
|
||||
self.store.update(tstore)
|
||||
self.assertEqual(self.store['min'], 6)
|
||||
|
||||
def test_values(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
slist = self.store.values()
|
||||
self.assertEqual(6 in slist, True)
|
||||
|
||||
def test_keys(self):
|
||||
self.store['max'] = 3
|
||||
self.store['min'] = 6
|
||||
self.store['pow'] = 7
|
||||
slist = self.store.keys()
|
||||
self.assertEqual('min' in slist, True)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
161
lib/sqliteshelf.py
Normal file
161
lib/sqliteshelf.py
Normal file
@ -0,0 +1,161 @@
|
||||
"""
|
||||
by default, things are stored in a "shelf" table
|
||||
|
||||
>>> d = SQLiteShelf("test.sdb")
|
||||
|
||||
you can put multiple shelves into a single SQLite database
|
||||
|
||||
>>> e = SQLiteShelf("test.sdb", "othertable")
|
||||
|
||||
both are empty to start with
|
||||
|
||||
>>> d
|
||||
{}
|
||||
>>> e
|
||||
{}
|
||||
|
||||
adding stuff is as simple as a regular dict
|
||||
>>> d['a'] = "moo"
|
||||
>>> e['a'] = "moo"
|
||||
|
||||
regular dict actions work
|
||||
|
||||
>>> d['a']
|
||||
'moo'
|
||||
>>> e['a']
|
||||
'moo'
|
||||
>>> 'a' in d
|
||||
True
|
||||
>>> len(d)
|
||||
1
|
||||
>>> del d['a']
|
||||
>>> 'a' in d
|
||||
False
|
||||
>>> len(d)
|
||||
0
|
||||
>>> del e['a']
|
||||
|
||||
objects can be stored in shelves
|
||||
|
||||
>> class Test:
|
||||
.. def __init__(self):
|
||||
.. self.foo = "bar"
|
||||
..
|
||||
>> t = Test()
|
||||
>> d['t'] = t
|
||||
>> print d['t'].foo
|
||||
bar
|
||||
|
||||
errors are as normal for a dict
|
||||
|
||||
>>> d['x']
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
KeyError: 'x'
|
||||
>>> del d['x']
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
KeyError: 'x'
|
||||
|
||||
Adding and fetching binary strings
|
||||
|
||||
>>> d[1] = "a\\x00b"
|
||||
>>> d[1]
|
||||
'a\\x00b'
|
||||
"""
|
||||
|
||||
try:
|
||||
from UserDict import DictMixin
|
||||
except ImportError:
|
||||
from collections import MutableMapping as DictMixin
|
||||
|
||||
try:
|
||||
import cPickle as pickle
|
||||
except ImportError:
|
||||
import pickle
|
||||
|
||||
import sys
|
||||
valtype = str
|
||||
if sys.version > '3':
|
||||
buffer = memoryview
|
||||
valtype = bytes
|
||||
|
||||
import sqlite3
|
||||
|
||||
class SQLiteDict(DictMixin):
|
||||
def __init__(self, filename=':memory:', table='shelf', flags='r', mode=None, valtype=valtype):
|
||||
self.table = table
|
||||
self.valtype = valtype
|
||||
MAKE_SHELF = 'CREATE TABLE IF NOT EXISTS '+self.table+' (key TEXT, value BLOB)'
|
||||
MAKE_INDEX = 'CREATE UNIQUE INDEX IF NOT EXISTS '+self.table+'_keyndx ON '+self.table+'(key)'
|
||||
self.conn = sqlite3.connect(filename)
|
||||
self.conn.text_factory = str
|
||||
self.conn.execute(MAKE_SHELF)
|
||||
self.conn.execute(MAKE_INDEX)
|
||||
self.conn.commit()
|
||||
|
||||
def __getitem__(self, key):
|
||||
GET_ITEM = 'SELECT value FROM '+self.table+' WHERE key = ?'
|
||||
item = self.conn.execute(GET_ITEM, (key,)).fetchone()
|
||||
if item is None:
|
||||
raise KeyError(key)
|
||||
return self.valtype(item[0])
|
||||
|
||||
def __setitem__(self, key, item):
|
||||
ADD_ITEM = 'REPLACE INTO '+self.table+' (key, value) VALUES (?,?)'
|
||||
self.conn.execute(ADD_ITEM, (key, sqlite3.Binary(item)))
|
||||
self.conn.commit()
|
||||
|
||||
def __delitem__(self, key):
|
||||
if key not in self:
|
||||
raise KeyError(key)
|
||||
DEL_ITEM = 'DELETE FROM '+self.table+' WHERE key = ?'
|
||||
self.conn.execute(DEL_ITEM, (key,))
|
||||
self.conn.commit()
|
||||
|
||||
def __iter__(self):
|
||||
c = self.conn.cursor()
|
||||
try:
|
||||
c.execute('SELECT key FROM '+self.table+' ORDER BY key')
|
||||
for row in c:
|
||||
yield row[0]
|
||||
finally:
|
||||
c.close()
|
||||
|
||||
def keys(self):
|
||||
c = self.conn.cursor()
|
||||
try:
|
||||
c.execute('SELECT key FROM '+self.table+' ORDER BY key')
|
||||
return [row[0] for row in c]
|
||||
finally:
|
||||
c.close()
|
||||
|
||||
###################################################################
|
||||
# optional bits
|
||||
|
||||
def __len__(self):
|
||||
GET_LEN = 'SELECT COUNT(*) FROM '+self.table
|
||||
return self.conn.execute(GET_LEN).fetchone()[0]
|
||||
|
||||
def close(self):
|
||||
if self.conn is not None:
|
||||
self.conn.commit()
|
||||
self.conn.close()
|
||||
self.conn = None
|
||||
|
||||
def __del__(self):
|
||||
self.close()
|
||||
|
||||
def __repr__(self):
|
||||
return repr(dict(self))
|
||||
|
||||
class SQLiteShelf(SQLiteDict):
|
||||
def __getitem__(self, key):
|
||||
return pickle.loads(SQLiteDict.__getitem__(self, key))
|
||||
|
||||
def __setitem__(self, key, item):
|
||||
SQLiteDict.__setitem__(self, key, pickle.dumps(item))
|
||||
|
||||
if __name__ == "__main__":
|
||||
import doctest
|
||||
doctest.testmod()
|
@ -547,7 +547,10 @@ def initialize(consoleLogging=True):
|
||||
CheckSection(CFG, 'Subtitles')
|
||||
|
||||
# github api
|
||||
gh = Github().get_organization(GIT_ORG).get_repo(GIT_REPO) # wanted branch
|
||||
try:
|
||||
gh = Github().get_organization(GIT_ORG).get_repo(GIT_REPO)
|
||||
except:
|
||||
gh = None
|
||||
|
||||
BRANCH = check_setting_str(CFG, 'General', 'branch', '')
|
||||
|
||||
@ -609,8 +612,8 @@ def initialize(consoleLogging=True):
|
||||
WEB_ROOT = check_setting_str(CFG, 'General', 'web_root', '').rstrip("/")
|
||||
WEB_LOG = bool(check_setting_int(CFG, 'General', 'web_log', 0))
|
||||
ENCRYPTION_VERSION = check_setting_int(CFG, 'General', 'encryption_version', 0)
|
||||
WEB_USERNAME = check_setting_str(CFG, 'General', 'web_username', '')
|
||||
WEB_PASSWORD = check_setting_str(CFG, 'General', 'web_password', '')
|
||||
WEB_USERNAME = check_setting_str(CFG, 'General', 'web_username', '', censor_log=True)
|
||||
WEB_PASSWORD = check_setting_str(CFG, 'General', 'web_password', '', censor_log=True)
|
||||
LAUNCH_BROWSER = bool(check_setting_int(CFG, 'General', 'launch_browser', 1))
|
||||
|
||||
PLAY_VIDEOS = bool(check_setting_int(CFG, 'General', 'play_videos', 0))
|
||||
@ -634,7 +637,7 @@ def initialize(consoleLogging=True):
|
||||
SORT_ARTICLE = bool(check_setting_int(CFG, 'General', 'sort_article', 0))
|
||||
|
||||
USE_API = bool(check_setting_int(CFG, 'General', 'use_api', 0))
|
||||
API_KEY = check_setting_str(CFG, 'General', 'api_key', '')
|
||||
API_KEY = check_setting_str(CFG, 'General', 'api_key', '', censor_log=True)
|
||||
|
||||
DEBUG = bool(check_setting_int(CFG, 'General', 'debug', 0))
|
||||
|
||||
@ -738,30 +741,30 @@ def initialize(consoleLogging=True):
|
||||
ADD_SHOWS_WO_DIR = bool(check_setting_int(CFG, 'General', 'add_shows_wo_dir', 0))
|
||||
|
||||
NZBS = bool(check_setting_int(CFG, 'NZBs', 'nzbs', 0))
|
||||
NZBS_UID = check_setting_str(CFG, 'NZBs', 'nzbs_uid', '')
|
||||
NZBS_HASH = check_setting_str(CFG, 'NZBs', 'nzbs_hash', '')
|
||||
NZBS_UID = check_setting_str(CFG, 'NZBs', 'nzbs_uid', '', censor_log=True)
|
||||
NZBS_HASH = check_setting_str(CFG, 'NZBs', 'nzbs_hash', '', censor_log=True)
|
||||
|
||||
NEWZBIN = bool(check_setting_int(CFG, 'Newzbin', 'newzbin', 0))
|
||||
NEWZBIN_USERNAME = check_setting_str(CFG, 'Newzbin', 'newzbin_username', '')
|
||||
NEWZBIN_PASSWORD = check_setting_str(CFG, 'Newzbin', 'newzbin_password', '')
|
||||
NEWZBIN_USERNAME = check_setting_str(CFG, 'Newzbin', 'newzbin_username', '', censor_log=True)
|
||||
NEWZBIN_PASSWORD = check_setting_str(CFG, 'Newzbin', 'newzbin_password', '', censor_log=True)
|
||||
|
||||
SAB_USERNAME = check_setting_str(CFG, 'SABnzbd', 'sab_username', '')
|
||||
SAB_PASSWORD = check_setting_str(CFG, 'SABnzbd', 'sab_password', '')
|
||||
SAB_APIKEY = check_setting_str(CFG, 'SABnzbd', 'sab_apikey', '')
|
||||
SAB_USERNAME = check_setting_str(CFG, 'SABnzbd', 'sab_username', '', censor_log=True)
|
||||
SAB_PASSWORD = check_setting_str(CFG, 'SABnzbd', 'sab_password', '', censor_log=True)
|
||||
SAB_APIKEY = check_setting_str(CFG, 'SABnzbd', 'sab_apikey', '', censor_log=True)
|
||||
SAB_CATEGORY = check_setting_str(CFG, 'SABnzbd', 'sab_category', 'tv')
|
||||
SAB_CATEGORY_ANIME = check_setting_str(CFG, 'SABnzbd', 'sab_category_anime', 'anime')
|
||||
SAB_HOST = check_setting_str(CFG, 'SABnzbd', 'sab_host', '')
|
||||
|
||||
NZBGET_USERNAME = check_setting_str(CFG, 'NZBget', 'nzbget_username', 'nzbget')
|
||||
NZBGET_PASSWORD = check_setting_str(CFG, 'NZBget', 'nzbget_password', 'tegbzn6789')
|
||||
NZBGET_USERNAME = check_setting_str(CFG, 'NZBget', 'nzbget_username', 'nzbget', censor_log=True)
|
||||
NZBGET_PASSWORD = check_setting_str(CFG, 'NZBget', 'nzbget_password', 'tegbzn6789', censor_log=True)
|
||||
NZBGET_CATEGORY = check_setting_str(CFG, 'NZBget', 'nzbget_category', 'tv')
|
||||
NZBGET_CATEGORY_ANIME = check_setting_str(CFG, 'NZBget', 'nzbget_category_anime', 'anime')
|
||||
NZBGET_HOST = check_setting_str(CFG, 'NZBget', 'nzbget_host', '')
|
||||
NZBGET_USE_HTTPS = bool(check_setting_int(CFG, 'NZBget', 'nzbget_use_https', 0))
|
||||
NZBGET_PRIORITY = check_setting_int(CFG, 'NZBget', 'nzbget_priority', 100)
|
||||
|
||||
TORRENT_USERNAME = check_setting_str(CFG, 'TORRENT', 'torrent_username', '')
|
||||
TORRENT_PASSWORD = check_setting_str(CFG, 'TORRENT', 'torrent_password', '')
|
||||
TORRENT_USERNAME = check_setting_str(CFG, 'TORRENT', 'torrent_username', '', censor_log=True)
|
||||
TORRENT_PASSWORD = check_setting_str(CFG, 'TORRENT', 'torrent_password', '', censor_log=True)
|
||||
TORRENT_HOST = check_setting_str(CFG, 'TORRENT', 'torrent_host', '')
|
||||
TORRENT_PATH = check_setting_str(CFG, 'TORRENT', 'torrent_path', '')
|
||||
TORRENT_SEED_TIME = check_setting_int(CFG, 'TORRENT', 'torrent_seed_time', 0)
|
||||
@ -780,8 +783,8 @@ def initialize(consoleLogging=True):
|
||||
KODI_UPDATE_FULL = bool(check_setting_int(CFG, 'KODI', 'kodi_update_full', 0))
|
||||
KODI_UPDATE_ONLYFIRST = bool(check_setting_int(CFG, 'KODI', 'kodi_update_onlyfirst', 0))
|
||||
KODI_HOST = check_setting_str(CFG, 'KODI', 'kodi_host', '')
|
||||
KODI_USERNAME = check_setting_str(CFG, 'KODI', 'kodi_username', '')
|
||||
KODI_PASSWORD = check_setting_str(CFG, 'KODI', 'kodi_password', '')
|
||||
KODI_USERNAME = check_setting_str(CFG, 'KODI', 'kodi_username', '', censor_log=True)
|
||||
KODI_PASSWORD = check_setting_str(CFG, 'KODI', 'kodi_password', '', censor_log=True)
|
||||
|
||||
USE_PLEX = bool(check_setting_int(CFG, 'Plex', 'use_plex', 0))
|
||||
PLEX_NOTIFY_ONSNATCH = bool(check_setting_int(CFG, 'Plex', 'plex_notify_onsnatch', 0))
|
||||
@ -790,21 +793,21 @@ def initialize(consoleLogging=True):
|
||||
PLEX_UPDATE_LIBRARY = bool(check_setting_int(CFG, 'Plex', 'plex_update_library', 0))
|
||||
PLEX_SERVER_HOST = check_setting_str(CFG, 'Plex', 'plex_server_host', '')
|
||||
PLEX_HOST = check_setting_str(CFG, 'Plex', 'plex_host', '')
|
||||
PLEX_USERNAME = check_setting_str(CFG, 'Plex', 'plex_username', '')
|
||||
PLEX_PASSWORD = check_setting_str(CFG, 'Plex', 'plex_password', '')
|
||||
PLEX_USERNAME = check_setting_str(CFG, 'Plex', 'plex_username', '', censor_log=True)
|
||||
PLEX_PASSWORD = check_setting_str(CFG, 'Plex', 'plex_password', '', censor_log=True)
|
||||
|
||||
USE_GROWL = bool(check_setting_int(CFG, 'Growl', 'use_growl', 0))
|
||||
GROWL_NOTIFY_ONSNATCH = bool(check_setting_int(CFG, 'Growl', 'growl_notify_onsnatch', 0))
|
||||
GROWL_NOTIFY_ONDOWNLOAD = bool(check_setting_int(CFG, 'Growl', 'growl_notify_ondownload', 0))
|
||||
GROWL_NOTIFY_ONSUBTITLEDOWNLOAD = bool(check_setting_int(CFG, 'Growl', 'growl_notify_onsubtitledownload', 0))
|
||||
GROWL_HOST = check_setting_str(CFG, 'Growl', 'growl_host', '')
|
||||
GROWL_PASSWORD = check_setting_str(CFG, 'Growl', 'growl_password', '')
|
||||
GROWL_PASSWORD = check_setting_str(CFG, 'Growl', 'growl_password', '', censor_log=True)
|
||||
|
||||
USE_PROWL = bool(check_setting_int(CFG, 'Prowl', 'use_prowl', 0))
|
||||
PROWL_NOTIFY_ONSNATCH = bool(check_setting_int(CFG, 'Prowl', 'prowl_notify_onsnatch', 0))
|
||||
PROWL_NOTIFY_ONDOWNLOAD = bool(check_setting_int(CFG, 'Prowl', 'prowl_notify_ondownload', 0))
|
||||
PROWL_NOTIFY_ONSUBTITLEDOWNLOAD = bool(check_setting_int(CFG, 'Prowl', 'prowl_notify_onsubtitledownload', 0))
|
||||
PROWL_API = check_setting_str(CFG, 'Prowl', 'prowl_api', '')
|
||||
PROWL_API = check_setting_str(CFG, 'Prowl', 'prowl_api', '', censor_log=True)
|
||||
PROWL_PRIORITY = check_setting_str(CFG, 'Prowl', 'prowl_priority', "0")
|
||||
|
||||
USE_TWITTER = bool(check_setting_int(CFG, 'Twitter', 'use_twitter', 0))
|
||||
@ -812,30 +815,30 @@ def initialize(consoleLogging=True):
|
||||
TWITTER_NOTIFY_ONDOWNLOAD = bool(check_setting_int(CFG, 'Twitter', 'twitter_notify_ondownload', 0))
|
||||
TWITTER_NOTIFY_ONSUBTITLEDOWNLOAD = bool(
|
||||
check_setting_int(CFG, 'Twitter', 'twitter_notify_onsubtitledownload', 0))
|
||||
TWITTER_USERNAME = check_setting_str(CFG, 'Twitter', 'twitter_username', '')
|
||||
TWITTER_PASSWORD = check_setting_str(CFG, 'Twitter', 'twitter_password', '')
|
||||
TWITTER_USERNAME = check_setting_str(CFG, 'Twitter', 'twitter_username', '', censor_log=True)
|
||||
TWITTER_PASSWORD = check_setting_str(CFG, 'Twitter', 'twitter_password', '', censor_log=True)
|
||||
TWITTER_PREFIX = check_setting_str(CFG, 'Twitter', 'twitter_prefix', 'SickRage')
|
||||
|
||||
USE_BOXCAR = bool(check_setting_int(CFG, 'Boxcar', 'use_boxcar', 0))
|
||||
BOXCAR_NOTIFY_ONSNATCH = bool(check_setting_int(CFG, 'Boxcar', 'boxcar_notify_onsnatch', 0))
|
||||
BOXCAR_NOTIFY_ONDOWNLOAD = bool(check_setting_int(CFG, 'Boxcar', 'boxcar_notify_ondownload', 0))
|
||||
BOXCAR_NOTIFY_ONSUBTITLEDOWNLOAD = bool(check_setting_int(CFG, 'Boxcar', 'boxcar_notify_onsubtitledownload', 0))
|
||||
BOXCAR_USERNAME = check_setting_str(CFG, 'Boxcar', 'boxcar_username', '')
|
||||
BOXCAR_USERNAME = check_setting_str(CFG, 'Boxcar', 'boxcar_username', '', censor_log=True)
|
||||
|
||||
USE_BOXCAR2 = bool(check_setting_int(CFG, 'Boxcar2', 'use_boxcar2', 0))
|
||||
BOXCAR2_NOTIFY_ONSNATCH = bool(check_setting_int(CFG, 'Boxcar2', 'boxcar2_notify_onsnatch', 0))
|
||||
BOXCAR2_NOTIFY_ONDOWNLOAD = bool(check_setting_int(CFG, 'Boxcar2', 'boxcar2_notify_ondownload', 0))
|
||||
BOXCAR2_NOTIFY_ONSUBTITLEDOWNLOAD = bool(
|
||||
check_setting_int(CFG, 'Boxcar2', 'boxcar2_notify_onsubtitledownload', 0))
|
||||
BOXCAR2_ACCESSTOKEN = check_setting_str(CFG, 'Boxcar2', 'boxcar2_accesstoken', '')
|
||||
BOXCAR2_ACCESSTOKEN = check_setting_str(CFG, 'Boxcar2', 'boxcar2_accesstoken', '', censor_log=True)
|
||||
|
||||
USE_PUSHOVER = bool(check_setting_int(CFG, 'Pushover', 'use_pushover', 0))
|
||||
PUSHOVER_NOTIFY_ONSNATCH = bool(check_setting_int(CFG, 'Pushover', 'pushover_notify_onsnatch', 0))
|
||||
PUSHOVER_NOTIFY_ONDOWNLOAD = bool(check_setting_int(CFG, 'Pushover', 'pushover_notify_ondownload', 0))
|
||||
PUSHOVER_NOTIFY_ONSUBTITLEDOWNLOAD = bool(
|
||||
check_setting_int(CFG, 'Pushover', 'pushover_notify_onsubtitledownload', 0))
|
||||
PUSHOVER_USERKEY = check_setting_str(CFG, 'Pushover', 'pushover_userkey', '')
|
||||
PUSHOVER_APIKEY = check_setting_str(CFG, 'Pushover', 'pushover_apikey', '')
|
||||
PUSHOVER_USERKEY = check_setting_str(CFG, 'Pushover', 'pushover_userkey', '', censor_log=True)
|
||||
PUSHOVER_APIKEY = check_setting_str(CFG, 'Pushover', 'pushover_apikey', '', censor_log=True)
|
||||
USE_LIBNOTIFY = bool(check_setting_int(CFG, 'Libnotify', 'use_libnotify', 0))
|
||||
LIBNOTIFY_NOTIFY_ONSNATCH = bool(check_setting_int(CFG, 'Libnotify', 'libnotify_notify_onsnatch', 0))
|
||||
LIBNOTIFY_NOTIFY_ONDOWNLOAD = bool(check_setting_int(CFG, 'Libnotify', 'libnotify_notify_ondownload', 0))
|
||||
@ -863,9 +866,9 @@ def initialize(consoleLogging=True):
|
||||
check_setting_int(CFG, 'SynologyNotifier', 'synologynotifier_notify_onsubtitledownload', 0))
|
||||
|
||||
USE_TRAKT = bool(check_setting_int(CFG, 'Trakt', 'use_trakt', 0))
|
||||
TRAKT_USERNAME = check_setting_str(CFG, 'Trakt', 'trakt_username', '')
|
||||
TRAKT_PASSWORD = check_setting_str(CFG, 'Trakt', 'trakt_password', '')
|
||||
TRAKT_API = check_setting_str(CFG, 'Trakt', 'trakt_api', '')
|
||||
TRAKT_USERNAME = check_setting_str(CFG, 'Trakt', 'trakt_username', '', censor_log=True)
|
||||
TRAKT_PASSWORD = check_setting_str(CFG, 'Trakt', 'trakt_password', '', censor_log=True)
|
||||
TRAKT_API = check_setting_str(CFG, 'Trakt', 'trakt_api', '', censor_log=True)
|
||||
TRAKT_REMOVE_WATCHLIST = bool(check_setting_int(CFG, 'Trakt', 'trakt_remove_watchlist', 0))
|
||||
TRAKT_REMOVE_SERIESLIST = bool(check_setting_int(CFG, 'Trakt', 'trakt_remove_serieslist', 0))
|
||||
TRAKT_USE_WATCHLIST = bool(check_setting_int(CFG, 'Trakt', 'trakt_use_watchlist', 0))
|
||||
@ -889,7 +892,7 @@ def initialize(consoleLogging=True):
|
||||
NMA_NOTIFY_ONSNATCH = bool(check_setting_int(CFG, 'NMA', 'nma_notify_onsnatch', 0))
|
||||
NMA_NOTIFY_ONDOWNLOAD = bool(check_setting_int(CFG, 'NMA', 'nma_notify_ondownload', 0))
|
||||
NMA_NOTIFY_ONSUBTITLEDOWNLOAD = bool(check_setting_int(CFG, 'NMA', 'nma_notify_onsubtitledownload', 0))
|
||||
NMA_API = check_setting_str(CFG, 'NMA', 'nma_api', '')
|
||||
NMA_API = check_setting_str(CFG, 'NMA', 'nma_api', '', censor_log=True)
|
||||
NMA_PRIORITY = check_setting_str(CFG, 'NMA', 'nma_priority', "0")
|
||||
|
||||
USE_PUSHALOT = bool(check_setting_int(CFG, 'Pushalot', 'use_pushalot', 0))
|
||||
@ -897,14 +900,14 @@ def initialize(consoleLogging=True):
|
||||
PUSHALOT_NOTIFY_ONDOWNLOAD = bool(check_setting_int(CFG, 'Pushalot', 'pushalot_notify_ondownload', 0))
|
||||
PUSHALOT_NOTIFY_ONSUBTITLEDOWNLOAD = bool(
|
||||
check_setting_int(CFG, 'Pushalot', 'pushalot_notify_onsubtitledownload', 0))
|
||||
PUSHALOT_AUTHORIZATIONTOKEN = check_setting_str(CFG, 'Pushalot', 'pushalot_authorizationtoken', '')
|
||||
PUSHALOT_AUTHORIZATIONTOKEN = check_setting_str(CFG, 'Pushalot', 'pushalot_authorizationtoken', '', censor_log=True)
|
||||
|
||||
USE_PUSHBULLET = bool(check_setting_int(CFG, 'Pushbullet', 'use_pushbullet', 0))
|
||||
PUSHBULLET_NOTIFY_ONSNATCH = bool(check_setting_int(CFG, 'Pushbullet', 'pushbullet_notify_onsnatch', 0))
|
||||
PUSHBULLET_NOTIFY_ONDOWNLOAD = bool(check_setting_int(CFG, 'Pushbullet', 'pushbullet_notify_ondownload', 0))
|
||||
PUSHBULLET_NOTIFY_ONSUBTITLEDOWNLOAD = bool(
|
||||
check_setting_int(CFG, 'Pushbullet', 'pushbullet_notify_onsubtitledownload', 0))
|
||||
PUSHBULLET_API = check_setting_str(CFG, 'Pushbullet', 'pushbullet_api', '')
|
||||
PUSHBULLET_API = check_setting_str(CFG, 'Pushbullet', 'pushbullet_api', '', censor_log=True)
|
||||
PUSHBULLET_DEVICE = check_setting_str(CFG, 'Pushbullet', 'pushbullet_device', '')
|
||||
|
||||
USE_EMAIL = bool(check_setting_int(CFG, 'Email', 'use_email', 0))
|
||||
@ -914,8 +917,8 @@ def initialize(consoleLogging=True):
|
||||
EMAIL_HOST = check_setting_str(CFG, 'Email', 'email_host', '')
|
||||
EMAIL_PORT = check_setting_int(CFG, 'Email', 'email_port', 25)
|
||||
EMAIL_TLS = bool(check_setting_int(CFG, 'Email', 'email_tls', 0))
|
||||
EMAIL_USER = check_setting_str(CFG, 'Email', 'email_user', '')
|
||||
EMAIL_PASSWORD = check_setting_str(CFG, 'Email', 'email_password', '')
|
||||
EMAIL_USER = check_setting_str(CFG, 'Email', 'email_user', '', censor_log=True)
|
||||
EMAIL_PASSWORD = check_setting_str(CFG, 'Email', 'email_password', '', censor_log=True)
|
||||
EMAIL_FROM = check_setting_str(CFG, 'Email', 'email_from', '')
|
||||
EMAIL_LIST = check_setting_str(CFG, 'Email', 'email_list', '')
|
||||
|
||||
@ -949,8 +952,8 @@ def initialize(consoleLogging=True):
|
||||
|
||||
ANIMESUPPORT = False
|
||||
USE_ANIDB = bool(check_setting_int(CFG, 'ANIDB', 'use_anidb', 0))
|
||||
ANIDB_USERNAME = check_setting_str(CFG, 'ANIDB', 'anidb_username', '')
|
||||
ANIDB_PASSWORD = check_setting_str(CFG, 'ANIDB', 'anidb_password', '')
|
||||
ANIDB_USERNAME = check_setting_str(CFG, 'ANIDB', 'anidb_username', '', censor_log=True)
|
||||
ANIDB_PASSWORD = check_setting_str(CFG, 'ANIDB', 'anidb_password', '', censor_log=True)
|
||||
ANIDB_USE_MYLIST = bool(check_setting_int(CFG, 'ANIDB', 'anidb_use_mylist', 0))
|
||||
|
||||
ANIME_SPLIT_HOME = bool(check_setting_int(CFG, 'ANIME', 'anime_split_home', 0))
|
||||
@ -995,22 +998,22 @@ def initialize(consoleLogging=True):
|
||||
curTorrentProvider.getID(), 0))
|
||||
if hasattr(curTorrentProvider, 'api_key'):
|
||||
curTorrentProvider.api_key = check_setting_str(CFG, curTorrentProvider.getID().upper(),
|
||||
curTorrentProvider.getID() + '_api_key', '')
|
||||
curTorrentProvider.getID() + '_api_key', '', censor_log=True)
|
||||
if hasattr(curTorrentProvider, 'hash'):
|
||||
curTorrentProvider.hash = check_setting_str(CFG, curTorrentProvider.getID().upper(),
|
||||
curTorrentProvider.getID() + '_hash', '')
|
||||
curTorrentProvider.getID() + '_hash', '', censor_log=True)
|
||||
if hasattr(curTorrentProvider, 'digest'):
|
||||
curTorrentProvider.digest = check_setting_str(CFG, curTorrentProvider.getID().upper(),
|
||||
curTorrentProvider.getID() + '_digest', '')
|
||||
curTorrentProvider.getID() + '_digest', '', censor_log=True)
|
||||
if hasattr(curTorrentProvider, 'username'):
|
||||
curTorrentProvider.username = check_setting_str(CFG, curTorrentProvider.getID().upper(),
|
||||
curTorrentProvider.getID() + '_username', '')
|
||||
curTorrentProvider.getID() + '_username', '', censor_log=True)
|
||||
if hasattr(curTorrentProvider, 'password'):
|
||||
curTorrentProvider.password = check_setting_str(CFG, curTorrentProvider.getID().upper(),
|
||||
curTorrentProvider.getID() + '_password', '')
|
||||
curTorrentProvider.getID() + '_password', '', censor_log=True)
|
||||
if hasattr(curTorrentProvider, 'passkey'):
|
||||
curTorrentProvider.passkey = check_setting_str(CFG, curTorrentProvider.getID().upper(),
|
||||
curTorrentProvider.getID() + '_passkey', '')
|
||||
curTorrentProvider.getID() + '_passkey', '', censor_log=True)
|
||||
if hasattr(curTorrentProvider, 'proxy'):
|
||||
curTorrentProvider.proxy.enabled = bool(check_setting_int(CFG, curTorrentProvider.getID().upper(),
|
||||
curTorrentProvider.getID() + '_proxy', 0))
|
||||
@ -1060,10 +1063,10 @@ def initialize(consoleLogging=True):
|
||||
check_setting_int(CFG, curNzbProvider.getID().upper(), curNzbProvider.getID(), 0))
|
||||
if hasattr(curNzbProvider, 'api_key'):
|
||||
curNzbProvider.api_key = check_setting_str(CFG, curNzbProvider.getID().upper(),
|
||||
curNzbProvider.getID() + '_api_key', '')
|
||||
curNzbProvider.getID() + '_api_key', '', censor_log=True)
|
||||
if hasattr(curNzbProvider, 'username'):
|
||||
curNzbProvider.username = check_setting_str(CFG, curNzbProvider.getID().upper(),
|
||||
curNzbProvider.getID() + '_username', '')
|
||||
curNzbProvider.getID() + '_username', '', censor_log=True)
|
||||
if hasattr(curNzbProvider, 'search_mode'):
|
||||
curNzbProvider.search_mode = check_setting_str(CFG, curNzbProvider.getID().upper(),
|
||||
curNzbProvider.getID() + '_search_mode',
|
||||
|
@ -404,7 +404,7 @@ def check_setting_float(config, cfg_name, item_name, def_val):
|
||||
################################################################################
|
||||
# Check_setting_str #
|
||||
################################################################################
|
||||
def check_setting_str(config, cfg_name, item_name, def_val, log=True):
|
||||
def check_setting_str(config, cfg_name, item_name, def_val, log=True, censor_log=False):
|
||||
# For passwords you must include the word `password` in the item_name and add `helpers.encrypt(ITEM_NAME, ENCRYPTION_VERSION)` in save_config()
|
||||
if bool(item_name.find('password') + 1):
|
||||
log = False
|
||||
@ -422,6 +422,9 @@ def check_setting_str(config, cfg_name, item_name, def_val, log=True):
|
||||
config[cfg_name] = {}
|
||||
config[cfg_name][item_name] = helpers.encrypt(my_val, encryption_version)
|
||||
|
||||
if censor_log or (cfg_name, item_name) in logger.censoredItems.items():
|
||||
logger.censoredItems[cfg_name, item_name] = my_val
|
||||
|
||||
if log:
|
||||
logger.log(item_name + " -> " + str(my_val), logger.DEBUG)
|
||||
else:
|
||||
|
@ -25,7 +25,6 @@ from sickbeard import logger
|
||||
import six
|
||||
import chardet
|
||||
|
||||
|
||||
# This module tries to deal with the apparently random behavior of python when dealing with unicode <-> utf-8
|
||||
# encodings. It tries to just use unicode, but if that fails then it tries forcing it to utf-8. Any functions
|
||||
# which return something should always return unicode.
|
||||
|
@ -34,7 +34,6 @@ try:
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
|
||||
# number of log files to keep
|
||||
NUM_LOGS = 3
|
||||
|
||||
@ -53,13 +52,24 @@ reverseNames = {u'ERROR': ERROR,
|
||||
u'DEBUG': DEBUG,
|
||||
u'DB': DB}
|
||||
|
||||
censoredItems = {}
|
||||
|
||||
# send logging to null
|
||||
class NullHandler(logging.Handler):
|
||||
def emit(self, record):
|
||||
pass
|
||||
|
||||
class CensorFilter(logging.Filter):
|
||||
def filter(self, record):
|
||||
for k,v in censoredItems.items():
|
||||
if v and len(v) > 0 and v in record.msg:
|
||||
record.msg = record.msg.replace(v, len(v)*'*')
|
||||
return True
|
||||
|
||||
class SBRotatingLogHandler(object):
|
||||
def __init__(self, log_file, num_files, num_bytes):
|
||||
self.blacklistFilter = CensorFilter()
|
||||
|
||||
self.num_files = num_files
|
||||
self.num_bytes = num_bytes
|
||||
|
||||
@ -115,6 +125,9 @@ class SBRotatingLogHandler(object):
|
||||
# define a Handler which writes INFO messages or higher to the sys.stderr
|
||||
console = logging.StreamHandler()
|
||||
|
||||
# filter blacklisted words and replace them with asterisks
|
||||
console.addFilter(self.blacklistFilter)
|
||||
|
||||
console.setLevel(logging.INFO)
|
||||
if sickbeard.DEBUG:
|
||||
console.setLevel(logging.DEBUG)
|
||||
@ -141,8 +154,8 @@ class SBRotatingLogHandler(object):
|
||||
logging.getLogger('feedcache').addHandler(console)
|
||||
|
||||
self.log_file_path = os.path.join(sickbeard.LOG_DIR, self.log_file)
|
||||
|
||||
self.cur_handler = self._config_handler()
|
||||
|
||||
logging.getLogger('sickbeard').addHandler(self.cur_handler)
|
||||
logging.getLogger('tornado.access').addHandler(NullHandler())
|
||||
logging.getLogger('tornado.general').addHandler(self.cur_handler)
|
||||
@ -167,14 +180,6 @@ class SBRotatingLogHandler(object):
|
||||
# already logging in new log folder, close the old handler
|
||||
if old_handler:
|
||||
self.close_log(old_handler)
|
||||
# old_handler.flush()
|
||||
# old_handler.close()
|
||||
# sb_logger = logging.getLogger('sickbeard')
|
||||
# sub_logger = logging.getLogger('subliminal')
|
||||
# imdb_logger = logging.getLogger('imdbpy')
|
||||
# sb_logger.removeHandler(old_handler)
|
||||
# subli_logger.removeHandler(old_handler)
|
||||
# imdb_logger.removeHandler(old_handler)
|
||||
|
||||
def _config_handler(self):
|
||||
"""
|
||||
@ -182,6 +187,10 @@ class SBRotatingLogHandler(object):
|
||||
"""
|
||||
|
||||
file_handler = logging.FileHandler(self.log_file_path, encoding='utf-8')
|
||||
|
||||
# filter blacklisted words and replace them with asterisks
|
||||
file_handler.addFilter(self.blacklistFilter)
|
||||
|
||||
file_handler.setLevel(DB)
|
||||
file_handler.setFormatter(DispatchingFormatter(
|
||||
{'sickbeard': logging.Formatter('%(asctime)s %(levelname)-8s %(message)s', '%Y-%m-%d %H:%M:%S'),
|
||||
@ -273,7 +282,7 @@ class SBRotatingLogHandler(object):
|
||||
meThread = threading.currentThread().getName()
|
||||
message = meThread + u" :: " + toLog
|
||||
|
||||
out_line = message
|
||||
out_line = message.encode('utf-8')
|
||||
|
||||
sb_logger = logging.getLogger('sickbeard')
|
||||
setattr(sb_logger, 'db', lambda *args: sb_logger.log(DB, *args))
|
||||
@ -292,6 +301,7 @@ class SBRotatingLogHandler(object):
|
||||
sb_logger.warning(out_line)
|
||||
elif logLevel == ERROR:
|
||||
sb_logger.error(out_line)
|
||||
|
||||
# add errors to the UI logger
|
||||
classes.ErrorViewer.add(classes.UIError(message))
|
||||
elif logLevel == DB:
|
||||
@ -325,14 +335,11 @@ class DispatchingFormatter:
|
||||
|
||||
sb_log_instance = SBRotatingLogHandler('sickbeard.log', NUM_LOGS, LOG_SIZE)
|
||||
|
||||
|
||||
def log(toLog, logLevel=MESSAGE):
|
||||
sb_log_instance.log(toLog, logLevel)
|
||||
|
||||
|
||||
def log_error_and_exit(error_msg):
|
||||
sb_log_instance.log_error_and_exit(error_msg)
|
||||
|
||||
|
||||
def close():
|
||||
sb_log_instance.close_log()
|
||||
sb_log_instance.close_log()
|
@ -136,7 +136,7 @@ class ProperFinder():
|
||||
curProper.indexer = parse_result.show.indexer
|
||||
|
||||
# populate our Proper instance
|
||||
curProper.season = parse_result.season_number if parse_result.season_number != None else 1
|
||||
curProper.season = parse_result.season_number if parse_result.season_number is not None else 1
|
||||
curProper.episode = parse_result.episode_numbers[0]
|
||||
curProper.release_group = parse_result.release_group
|
||||
curProper.version = parse_result.version
|
||||
|
@ -4,25 +4,31 @@ import os
|
||||
import urllib
|
||||
import urlparse
|
||||
import re
|
||||
|
||||
import sickbeard
|
||||
|
||||
from sickbeard import logger
|
||||
from sickbeard import encodingKludge as ek
|
||||
from contextlib import closing
|
||||
from sickbeard.exceptions import ex
|
||||
from lib.feedcache import cache
|
||||
from shove import Shove
|
||||
|
||||
from contextlib import closing
|
||||
from lib.feedcache import cache
|
||||
from sqliteshelf import SQLiteShelf
|
||||
|
||||
class RSSFeeds:
|
||||
def __init__(self, db_name):
|
||||
self.db_name = ek.ek(os.path.join, sickbeard.CACHE_DIR, 'rss', db_name + '.db')
|
||||
if not os.path.exists(os.path.dirname(self.db_name)):
|
||||
sickbeard.helpers.makeDir(os.path.dirname(self.db_name))
|
||||
db_name = ek.ek(os.path.join, sickbeard.CACHE_DIR, 'rss', db_name) + '.db'
|
||||
if not os.path.exists(os.path.dirname(db_name)):
|
||||
sickbeard.helpers.makeDir(os.path.dirname(db_name))
|
||||
|
||||
try:
|
||||
self.rssDB = SQLiteShelf(db_name)
|
||||
except Exception as e:
|
||||
logger.log(u"RSS error: " + ex(e), logger.DEBUG)
|
||||
|
||||
def clearCache(self, age=None):
|
||||
try:
|
||||
with closing(Shove('sqlite:///' + self.db_name, compress=True)) as fs:
|
||||
with closing(self.rssDB) as fs:
|
||||
fc = cache.Cache(fs)
|
||||
fc.purge(age)
|
||||
except Exception as e:
|
||||
@ -36,7 +42,7 @@ class RSSFeeds:
|
||||
url += urllib.urlencode(post_data)
|
||||
|
||||
try:
|
||||
with closing(Shove('sqlite:///' + self.db_name, compress=True)) as fs:
|
||||
with closing(self.rssDB) as fs:
|
||||
fc = cache.Cache(fs)
|
||||
feed = fc.fetch(url, False, False, request_headers)
|
||||
|
||||
|
@ -1665,8 +1665,7 @@ class TVEpisode(object):
|
||||
if getattr(myEp, 'absolute_number', None) is None:
|
||||
logger.log(u"This episode (" + self.show.name + " - " + str(season) + "x" + str(
|
||||
episode) + ") has no absolute number on " + sickbeard.indexerApi(
|
||||
self.indexer).name
|
||||
, logger.DEBUG)
|
||||
self.indexer).name, logger.DEBUG)
|
||||
else:
|
||||
logger.log(
|
||||
str(self.show.indexerid) + ": The absolute_number for " + str(season) + "x" + str(episode) + " is : " +
|
||||
|
@ -40,29 +40,30 @@ class CheckVersion():
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.install_type = self.find_install_type()
|
||||
self.updater = None
|
||||
|
||||
if self.install_type == 'win':
|
||||
self.updater = WindowsUpdateManager()
|
||||
elif self.install_type == 'git':
|
||||
self.updater = GitUpdateManager()
|
||||
elif self.install_type == 'source':
|
||||
self.updater = SourceUpdateManager()
|
||||
else:
|
||||
self.updater = None
|
||||
if sickbeard.gh:
|
||||
self.install_type = self.find_install_type()
|
||||
if self.install_type == 'win':
|
||||
self.updater = WindowsUpdateManager()
|
||||
elif self.install_type == 'git':
|
||||
self.updater = GitUpdateManager()
|
||||
elif self.install_type == 'source':
|
||||
self.updater = SourceUpdateManager()
|
||||
|
||||
def run(self, force=False):
|
||||
# set current branch version
|
||||
sickbeard.BRANCH = self.get_branch()
|
||||
if self.updater:
|
||||
# set current branch version
|
||||
sickbeard.BRANCH = self.get_branch()
|
||||
|
||||
if self.check_for_new_version(force):
|
||||
if sickbeard.AUTO_UPDATE:
|
||||
logger.log(u"New update found for SickRage, starting auto-updater ...")
|
||||
ui.notifications.message('New update found for SickRage, starting auto-updater')
|
||||
if sickbeard.versionCheckScheduler.action.update():
|
||||
logger.log(u"Update was successful!")
|
||||
ui.notifications.message('Update was successful')
|
||||
sickbeard.events.put(sickbeard.events.SystemEvent.RESTART)
|
||||
if self.check_for_new_version(force):
|
||||
if sickbeard.AUTO_UPDATE:
|
||||
logger.log(u"New update found for SickRage, starting auto-updater ...")
|
||||
ui.notifications.message('New update found for SickRage, starting auto-updater')
|
||||
if sickbeard.versionCheckScheduler.action.update():
|
||||
logger.log(u"Update was successful!")
|
||||
ui.notifications.message('Update was successful')
|
||||
sickbeard.events.put(sickbeard.events.SystemEvent.RESTART)
|
||||
|
||||
def find_install_type(self):
|
||||
"""
|
||||
@ -93,7 +94,7 @@ class CheckVersion():
|
||||
force: if true the VERSION_NOTIFY setting will be ignored and a check will be forced
|
||||
"""
|
||||
|
||||
if not sickbeard.VERSION_NOTIFY and not sickbeard.AUTO_UPDATE and not force:
|
||||
if not self.updater or not sickbeard.VERSION_NOTIFY and not sickbeard.AUTO_UPDATE and not force:
|
||||
logger.log(u"Version checking is disabled, not checking for the newest version")
|
||||
return False
|
||||
|
||||
@ -112,18 +113,21 @@ class CheckVersion():
|
||||
return True
|
||||
|
||||
def update(self):
|
||||
# update branch with current config branch value
|
||||
self.updater.branch = sickbeard.BRANCH
|
||||
if self.updater:
|
||||
# update branch with current config branch value
|
||||
self.updater.branch = sickbeard.BRANCH
|
||||
|
||||
# check for updates
|
||||
if self.updater.need_update():
|
||||
return self.updater.update()
|
||||
# check for updates
|
||||
if self.updater.need_update():
|
||||
return self.updater.update()
|
||||
|
||||
def list_remote_branches(self):
|
||||
return self.updater.list_remote_branches()
|
||||
if self.updater:
|
||||
return self.updater.list_remote_branches()
|
||||
|
||||
def get_branch(self):
|
||||
return self.updater.branch
|
||||
if self.updater:
|
||||
return self.updater.branch
|
||||
|
||||
|
||||
class UpdateManager():
|
||||
|
@ -189,13 +189,13 @@ class Api(webserve.MainHandler):
|
||||
msg = u"API :: " + remoteIp + " - SR API Disabled. ACCESS DENIED"
|
||||
return False, msg, args, kwargs
|
||||
elif apiKey == realKey:
|
||||
msg = u"API :: " + remoteIp + " - gave correct API KEY. ACCESS GRANTED"
|
||||
msg = u"API :: " + remoteIp + " - gave correct API KEY - [" + apiKey + "] - ACCESS GRANTED"
|
||||
return True, msg, args, kwargs
|
||||
elif not apiKey:
|
||||
msg = u"API :: " + remoteIp + " - gave NO API KEY. ACCESS DENIED"
|
||||
return False, msg, args, kwargs
|
||||
else:
|
||||
msg = u"API :: " + remoteIp + " - gave WRONG API KEY " + apiKey + ". ACCESS DENIED"
|
||||
msg = u"API :: " + remoteIp + " - gave WRONG API KEY - [" + apiKey + "] - ACCESS DENIED"
|
||||
return False, msg, args, kwargs
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user