<s> import os <EOL> import uuid <EOL> import logging <EOL> import leveldb <EOL> import ujson as json <EOL> from shutil import rmtree <EOL> from threading import Thread , Event <EOL> from leveldb import LevelDBError <EOL> from . env import Environment <EOL> from . constants import OS_ERROR , DATABASE_ERROR <EOL> from . utils . snippets import from_bytes_to_mo <EOL> from . utils . patterns import enum <EOL> from . helpers . internals import failure , success <EOL> activity_logger = logging . getLogger ( "<STR_LIT>" ) <EOL> errors_logger = logging . getLogger ( "<STR_LIT>" ) <EOL> class Ocd ( Thread ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , interval , function , iterations = <NUM_LIT:0> , args = [ ] , kwargs = { } ) : <EOL> Thread . __init__ ( self ) <EOL> self . interval = interval <EOL> self . function = function <EOL> self . iterations = iterations <EOL> self . args = args <EOL> self . kwargs = kwargs <EOL> self . finished = Event ( ) <EOL> def run ( self ) : <EOL> count = <NUM_LIT:0> <EOL> while not self . finished . is_set ( ) and ( self . iterations <= <NUM_LIT:0> or count < self . iterations ) : <EOL> self . finished . wait ( self . interval ) <EOL> if not self . finished . is_set ( ) : <EOL> self . function ( * self . args , ** self . kwargs ) <EOL> count += <NUM_LIT:1> <EOL> def cancel ( self ) : <EOL> self . finished . set ( ) <EOL> class DatabaseOptions ( dict ) : <EOL> def __init__ ( self , * args , ** kwargs ) : <EOL> self [ '<STR_LIT>' ] = True <EOL> self [ '<STR_LIT>' ] = False <EOL> self [ '<STR_LIT>' ] = False <EOL> self [ '<STR_LIT>' ] = <NUM_LIT:8> * ( <NUM_LIT:2> << <NUM_LIT:20> ) <EOL> self [ '<STR_LIT>' ] = <NUM_LIT:2> * ( <NUM_LIT:2> << <NUM_LIT:20> ) <EOL> self [ '<STR_LIT>' ] = <NUM_LIT> <EOL> self [ '<STR_LIT>' ] = <NUM_LIT:1000> <EOL> for key , value in kwargs . iteritems ( ) : <EOL> if key in self : <EOL> self [ key ] = value <EOL> class DatabasesHandler ( dict ) : <EOL> STATUSES = enum ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> def __init__ ( self , store , dest , * args , ** kwargs ) : <EOL> self . env = Environment ( ) <EOL> self . index = dict ( ) . fromkeys ( '<STR_LIT>' ) <EOL> self . index [ '<STR_LIT>' ] = { } <EOL> self [ '<STR_LIT>' ] = { } <EOL> self [ '<STR_LIT>' ] = { } <EOL> self . dest = dest <EOL> self . store = store <EOL> self . _global_cache_size = None <EOL> self . load ( ) <EOL> self . mount ( '<STR_LIT:default>' ) <EOL> @ property <EOL> def global_cache_size ( self ) : <EOL> store_datas = self . extract_store_datas ( ) <EOL> max_caches = [ int ( db [ "<STR_LIT>" ] [ "<STR_LIT>" ] ) for db <EOL> in store_datas . itervalues ( ) ] <EOL> return sum ( [ from_bytes_to_mo ( x ) for x in max_caches ] ) <EOL> def _disposable_cache ( self , new_cache_size ) : <EOL> next_cache_size = self . global_cache_size + from_bytes_to_mo ( new_cache_size ) <EOL> ratio = int ( self . env [ "<STR_LIT>" ] [ "<STR_LIT>" ] ) - next_cache_size <EOL> if ratio < <NUM_LIT:0> : <EOL> return ( False , ratio ) <EOL> return ( True , ratio ) <EOL> def _get_db_connector ( self , path , * args , ** kwargs ) : <EOL> connector = None <EOL> try : <EOL> connector = leveldb . LevelDB ( path , * args , ** kwargs ) <EOL> except LevelDBError as e : <EOL> errors_logger . exception ( e . message ) <EOL> return connector <EOL> def extract_store_datas ( self ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> store_datas = json . load ( open ( self . store , '<STR_LIT:r>' ) ) <EOL> except ( IOError , ValueError ) : <EOL> store_datas = { } <EOL> return store_datas <EOL> def load ( self ) : <EOL> """<STR_LIT>""" <EOL> store_datas = self . extract_store_datas ( ) <EOL> for db_name , db_desc in store_datas . iteritems ( ) : <EOL> self . index [ '<STR_LIT>' ] . update ( { db_name : db_desc [ '<STR_LIT>' ] } ) <EOL> self . update ( { <EOL> db_desc [ '<STR_LIT>' ] : { <EOL> '<STR_LIT>' : None , <EOL> '<STR_LIT:name>' : db_name , <EOL> '<STR_LIT:path>' : db_desc [ '<STR_LIT:path>' ] , <EOL> '<STR_LIT:status>' : self . STATUSES . UNMOUNTED , <EOL> '<STR_LIT>' : <NUM_LIT:0> , <EOL> } <EOL> } ) <EOL> if '<STR_LIT:default>' not in self . index [ '<STR_LIT>' ] : <EOL> self . add ( '<STR_LIT:default>' ) <EOL> def store_update ( self , db_name , db_desc ) : <EOL> """<STR_LIT>""" <EOL> store_datas = self . extract_store_datas ( ) <EOL> store_datas . update ( { db_name : db_desc } ) <EOL> json . dump ( store_datas , open ( self . store , '<STR_LIT:w>' ) ) <EOL> def store_remove ( self , db_name ) : <EOL> """<STR_LIT>""" <EOL> store_datas = self . extract_store_datas ( ) <EOL> store_datas . pop ( db_name ) <EOL> json . dump ( store_datas , open ( self . store , '<STR_LIT:w>' ) ) <EOL> def mount ( self , db_name ) : <EOL> db_uid = self . index [ '<STR_LIT>' ] [ db_name ] if db_name in self . index [ '<STR_LIT>' ] else None <EOL> if self [ db_uid ] [ '<STR_LIT:status>' ] == self . STATUSES . UNMOUNTED : <EOL> db_path = self [ db_uid ] [ '<STR_LIT:path>' ] <EOL> connector = self . _get_db_connector ( db_path ) <EOL> if connector is None : <EOL> return failure ( DATABASE_ERROR , "<STR_LIT>" % db_path ) <EOL> self [ db_uid ] [ '<STR_LIT:status>' ] = self . STATUSES . MOUNTED <EOL> self [ db_uid ] [ '<STR_LIT>' ] = leveldb . LevelDB ( db_path ) <EOL> else : <EOL> return failure ( DATABASE_ERROR , "<STR_LIT>" % db_name ) <EOL> return success ( ) <EOL> def umount ( self , db_name ) : <EOL> db_uid = self . index [ '<STR_LIT>' ] [ db_name ] if db_name in self . index [ '<STR_LIT>' ] else None <EOL> if self [ db_uid ] [ '<STR_LIT:status>' ] == self . STATUSES . MOUNTED : <EOL> self [ db_uid ] [ '<STR_LIT:status>' ] = self . STATUSES . UNMOUNTED <EOL> del self [ db_uid ] [ '<STR_LIT>' ] <EOL> self [ db_uid ] [ '<STR_LIT>' ] = None <EOL> else : <EOL> return failure ( DATABASE_ERROR , "<STR_LIT>" % db_name ) <EOL> return success ( ) <EOL> def add ( self , db_name , db_options = None ) : <EOL> """<STR_LIT>""" <EOL> db_options = db_options or DatabaseOptions ( ) <EOL> cache_status , ratio = self . _disposable_cache ( db_options [ "<STR_LIT>" ] ) <EOL> if not cache_status : <EOL> return failure ( DATABASE_ERROR , <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" % ratio ) <EOL> db_name_is_path = db_name . startswith ( '<STR_LIT:.>' ) or ( '<STR_LIT:/>' in db_name ) <EOL> is_abspath = lambda : not db_name . startswith ( '<STR_LIT:.>' ) and ( '<STR_LIT:/>' in db_name ) <EOL> if db_name_is_path : <EOL> if not is_abspath ( ) : <EOL> return failure ( DATABASE_ERROR , "<STR_LIT>" ) <EOL> try : <EOL> new_db_path = db_name <EOL> if not os . path . exists ( new_db_path ) : <EOL> os . mkdir ( new_db_path ) <EOL> except OSError as e : <EOL> return failure ( OS_ERROR , e . strerror ) <EOL> else : <EOL> new_db_path = os . path . join ( self . dest , db_name ) <EOL> path = new_db_path <EOL> connector = self . _get_db_connector ( path ) <EOL> if connector is None : <EOL> return ( DATABASE_ERROR , "<STR_LIT>" % path ) <EOL> uid = str ( uuid . uuid4 ( ) ) <EOL> options = db_options <EOL> self . store_update ( db_name , { <EOL> '<STR_LIT:path>' : path , <EOL> '<STR_LIT>' : uid , <EOL> '<STR_LIT>' : options , <EOL> } ) <EOL> self . index [ '<STR_LIT>' ] . update ( { db_name : uid } ) <EOL> self . update ( { <EOL> uid : { <EOL> '<STR_LIT>' : connector , <EOL> '<STR_LIT:name>' : db_name , <EOL> '<STR_LIT:path>' : path , <EOL> '<STR_LIT:status>' : self . STATUSES . MOUNTED , <EOL> '<STR_LIT>' : <NUM_LIT:0> , <EOL> } , <EOL> } ) <EOL> return success ( ) <EOL> def drop ( self , db_name ) : <EOL> """<STR_LIT>""" <EOL> db_uid = self . index [ '<STR_LIT>' ] . pop ( db_name ) <EOL> db_path = self [ db_uid ] [ '<STR_LIT:path>' ] <EOL> self . pop ( db_uid ) <EOL> self . store_remove ( db_name ) <EOL> try : <EOL> rmtree ( db_path ) <EOL> except OSError : <EOL> return failure ( DATABASE_ERROR , "<STR_LIT>" ) <EOL> return success ( ) <EOL> def exists ( self , db_name ) : <EOL> """<STR_LIT>""" <EOL> db_uid = self . index [ '<STR_LIT>' ] [ db_name ] if db_name in self . index [ '<STR_LIT>' ] else None <EOL> if db_uid : <EOL> if os . path . exists ( self [ db_uid ] [ '<STR_LIT:path>' ] ) : <EOL> return True <EOL> else : <EOL> self . drop ( db_name ) <EOL> return False <EOL> def list ( self ) : <EOL> """<STR_LIT>""" <EOL> return [ db_name for db_name <EOL> in [ key for key <EOL> in self . index [ '<STR_LIT>' ] . iterkeys ( ) ] <EOL> if self . exists ( db_name ) ] </s>
