<s> from datetime import datetime <EOL> import logging <EOL> import os <EOL> import shutil <EOL> from tinydb import TinyDB , Storage , where , Query <EOL> import yaml <EOL> from . utils import mkdir_open <EOL> from . history import Repository <EOL> from . credential import split_fullname , make_fullname <EOL> class PasspieStorage ( Storage ) : <EOL> extension = "<STR_LIT>" <EOL> def __init__ ( self , path ) : <EOL> super ( PasspieStorage , self ) . __init__ ( ) <EOL> self . path = path <EOL> def make_credpath ( self , name , login ) : <EOL> dirname , filename = name , login + self . extension <EOL> credpath = os . path . join ( self . path , dirname , filename ) <EOL> return credpath <EOL> def delete ( self , credentials ) : <EOL> for cred in credentials : <EOL> credpath = self . make_credpath ( cred [ "<STR_LIT:name>" ] , cred [ "<STR_LIT>" ] ) <EOL> os . remove ( credpath ) <EOL> if not os . listdir ( os . path . dirname ( credpath ) ) : <EOL> shutil . rmtree ( os . path . dirname ( credpath ) ) <EOL> def read ( self ) : <EOL> elements = [ ] <EOL> for rootdir , dirs , files in os . walk ( self . path ) : <EOL> filenames = [ f for f in files if f . endswith ( self . extension ) ] <EOL> for filename in filenames : <EOL> docpath = os . path . join ( rootdir , filename ) <EOL> with open ( docpath ) as f : <EOL> elements . append ( yaml . load ( f . read ( ) ) ) <EOL> return { "<STR_LIT>" : <EOL> { idx : elem for idx , elem in enumerate ( elements , start = <NUM_LIT:1> ) } } <EOL> def write ( self , data ) : <EOL> deleted = [ c for c in self . read ( ) [ "<STR_LIT>" ] . values ( ) <EOL> if c not in data [ "<STR_LIT>" ] . values ( ) ] <EOL> self . delete ( deleted ) <EOL> for eid , cred in data [ "<STR_LIT>" ] . items ( ) : <EOL> credpath = self . make_credpath ( cred [ "<STR_LIT:name>" ] , cred [ "<STR_LIT>" ] ) <EOL> with mkdir_open ( credpath , "<STR_LIT:w>" ) as f : <EOL> f . write ( yaml . dump ( dict ( cred ) , default_flow_style = False ) ) <EOL> class Database ( TinyDB ) : <EOL> def __init__ ( self , config , storage = PasspieStorage ) : <EOL> self . config = config <EOL> self . path = config [ '<STR_LIT:path>' ] <EOL> self . repo = Repository ( self . path , <EOL> autopull = config . get ( '<STR_LIT>' ) , <EOL> autopush = config . get ( '<STR_LIT>' ) ) <EOL> PasspieStorage . extension = config [ '<STR_LIT>' ] <EOL> super ( Database , self ) . __init__ ( self . path , storage = storage ) <EOL> def has_keys ( self ) : <EOL> return os . path . exists ( os . path . join ( self . path , '<STR_LIT>' ) ) <EOL> def filename ( self , fullname ) : <EOL> login , name = split_fullname ( fullname ) <EOL> return self . _storage . make_credpath ( name = name , login = login ) <EOL> def credential ( self , fullname ) : <EOL> login , name = split_fullname ( fullname ) <EOL> Credential = Query ( ) <EOL> if login is None : <EOL> creds = self . get ( Credential . name == name ) <EOL> else : <EOL> creds = self . get ( ( Credential . login == login ) & ( Credential . name == name ) ) <EOL> return creds <EOL> def add ( self , fullname , password , comment ) : <EOL> login , name = split_fullname ( fullname ) <EOL> if login is None : <EOL> logging . error ( '<STR_LIT>' ) <EOL> return None <EOL> credential = dict ( fullname = fullname , <EOL> name = name , <EOL> login = login , <EOL> password = password , <EOL> comment = comment , <EOL> modified = datetime . now ( ) ) <EOL> self . insert ( credential ) <EOL> return credential <EOL> def update ( self , fullname , values ) : <EOL> values [ '<STR_LIT>' ] = make_fullname ( values [ "<STR_LIT>" ] , values [ "<STR_LIT:name>" ] ) <EOL> values [ '<STR_LIT>' ] = datetime . now ( ) <EOL> self . table ( ) . update ( values , ( where ( "<STR_LIT>" ) == fullname ) ) <EOL> def credentials ( self , fullname = None ) : <EOL> if fullname : <EOL> login , name = split_fullname ( fullname ) <EOL> Credential = Query ( ) <EOL> if login is None : <EOL> creds = self . search ( Credential . name == name ) <EOL> else : <EOL> creds = self . search ( ( Credential . login == login ) & ( Credential . name == name ) ) <EOL> else : <EOL> creds = self . all ( ) <EOL> return sorted ( creds , key = lambda x : x [ "<STR_LIT:name>" ] + x [ "<STR_LIT>" ] ) <EOL> def remove ( self , fullname ) : <EOL> self . table ( ) . remove ( where ( '<STR_LIT>' ) == fullname ) <EOL> def matches ( self , regex ) : <EOL> Credential = Query ( ) <EOL> credentials = self . search ( <EOL> Credential . name . matches ( regex ) | <EOL> Credential . login . matches ( regex ) | <EOL> Credential . comment . matches ( regex ) <EOL> ) <EOL> return sorted ( credentials , key = lambda x : x [ "<STR_LIT:name>" ] + x [ "<STR_LIT>" ] ) </s>
