diff --git a/impra/cli.py b/impra/cli.py index 4bb76b9..6b5aeec 100644 --- a/impra/cli.py +++ b/impra/cli.py @@ -34,8 +34,15 @@ import sys import impra.crypt as crypt import impra.util as util import impra.core as core +from impra.util import C -desc=""" +LINE_SEP = C.IBLACK+'―'*120+C.OFF +APP_TITLE = 'ImpraStorage' +APP_VERSION = '0.5' +APP_AUTHOR = 'a-Sansara' +APP_COPY = 'pluie.org' +APP_LICENSE = 'GNU GPLv3' +APP_DESC = """ ImpraStorage provided a private imap access to store large files. Each file stored on the server is split in severals random parts. Each part also contains random noise data (lenght depends on a crypt key) @@ -75,16 +82,17 @@ class Cli: self.ini = util.IniFile(path+'impra.ini') parser = _OptionParser(prog='imprastorage', usage='\n\n\ ------------------------------------------------------------------------------\n\ --- ImpraStorage --\n\ +-- %s --\n\ ------------------------------------------------------------------------------\n\ --- version : 0.41 copyright : pluie.org --\n\ --- author : a-Sansara license : GNU GPLv3 --\n\ +-- version : %s copyright : %s --\n\ +-- author : %s license : %s --\n\ ------------------------------------------------------------------------------\n\ \n\ -%prog conf [-D|-L| -K,-H {host},-U {user},-X {password},-P {port},\n\ +%s conf [-D|-L| -K,-H {host},-U {user},-X {password},-P {port},\n\ -B {boxname}] [-A profileName]\n\ -%prog data [-l |-a {file, label} |-g {id} |-s {pattern} | -r {id}]\n\ - [-c {catg}, -u {owner}]', epilog=""" +%s data [-l |-a {file, label} |-g {id} |-s {pattern} | -r {id}]\n\ + [-c {catg}, -u {owner}]' + % (APP_TITLE,APP_VERSION,APP_COPY,APP_AUTHOR,APP_LICENSE,APP_TITLE.lower(),APP_TITLE.lower()) , epilog=""" conf command Examples: @@ -125,7 +133,7 @@ data command Examples: Search files upload by a particular user on a category : imprastorage data -s * -c films -u myfriend -""",description=desc) +""",description=APP_DESC) gpData = OptionGroup(parser, '\n------------------------------------\ndata related Options (command data)') gpConf = OptionGroup(parser, '\n------------------------------------\nconf related Options (command conf)') @@ -222,11 +230,11 @@ data command Examples: impst = None try: impst = core.ImpraStorage(conf) - except util.BadKeysException as e : + except crypt.BadKeyException as e : print('Error : ') print(e) print(""" -it seems that your current profile %s has bad keys to decrypt index on server. +it seems that your current profile %s has a wrong key to decrypt index on server. you can remove index but all presents files on the box %s will be unrecoverable """ % (o.active_profile, conf.get('box','imap'))) remIndex = input('remove index ? (yes/no)') @@ -244,7 +252,13 @@ you can remove index but all presents files on the box %s will be unrecoverable noData = impst.index.isEmpty() if uid == None or noData : uid = 'EMPTY' if date == None or noData : date = '' - impst.index.print('-'*120+'\n -- ImpraStorage -- [account:'+account+'] [index:`'+uid+'`] [boxname:`'+impst.rootBox+'`] '+date+'\n'+'-'*120) + impst.index.print('\ +'+LINE_SEP+'\n\ +%s -- %s -- %s ' % (C.ON_IBLUE+C.BWHITE , APP_TITLE , C.OFF+C.BYELLOW)+'\ + %s[%saccount%s:%s%s%s]%s ' % (C.BIBLACK,C.BYELLOW,C.BIBLACK,C.BBLUE, account , C.BIBLACK, C.BYELLOW)+'\ + %s[%sindex%s:%s%s%s]%s ' % (C.BIBLACK,C.BYELLOW,C.BIBLACK,C.BBLUE, uid , C.BIBLACK, C.BYELLOW)+'\ + %s[%sbox%s:%s%s%s]%s ' % (C.BIBLACK,C.BYELLOW,C.BIBLACK,C.BBLUE, impst.rootBox , C.BIBLACK, C.BYELLOW)+'\ + %s%s%s ' % (C.BWHITE , date , C.OFF+C.BYELLOW)+'\n'+LINE_SEP) status, resp = impst.ih.srv.search(None, '(SUBJECT "%s")' % '584d15abeb71fbd92fa5861970088b32ebb1d2d6650cec6115a28b64877d70f2') ids = [m for m in resp[0].split()] @@ -269,7 +283,7 @@ you can remove index but all presents files on the box %s will be unrecoverable elif o.search : matchIds = impst.index.getByPattern(o.search) if matchIds is not None: - headstr = util.hilite('-'*120+'\n -- SEARCH: `'+o.search+'` -- found '+str(len(matchIds))+' results --\n'+'-'*120) + headstr = '-'*120+'\n -- SEARCH: `'+o.search+'` -- found '+str(len(matchIds))+' results --\n'+'-'*120 impst.index.print(headstr,matchIds) else: print(' -- no match found for pattern `%s` --' % o.search) diff --git a/impra/core.py b/impra/core.py index 4e8ef65..577951a 100644 --- a/impra/core.py +++ b/impra/core.py @@ -46,9 +46,10 @@ from os.path import abspath, dirname, join, realpath, basename, get from re import split as regsplit, match as regmatch, compile as regcompile, search as regsearch from time import time from impra.imap import ImapHelper, ImapConfig -from impra.util import __CALLER__, RuTime, formatBytes, randomFrom, bstr, quote_escape, stack, run, file_exists, get_file_content, DEBUG, DEBUG_ALL, DEBUG_LEVEL, DEBUG_NOTICE, DEBUG_WARN, mkdir_p, is_binary -from impra.crypt import Kirmah, ConfigKey, Noiser, Randomiz, hash_sha256, hash_md5_file +from impra.util import __CALLER__, RuTime, formatBytes, randomFrom, bstr, quote_escape, stack, run, file_exists, get_file_content, DEBUG, DEBUG_ALL, DEBUG_LEVEL, DEBUG_NOTICE, DEBUG_WARN, mkdir_p, is_binary, C +from impra.crypt import Kirmah, ConfigKey, Noiser, Randomiz, hash_sha256, hash_md5_file, BadKeyException +LINE_SEP = C.IBLACK+'―'*120+C.OFF # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # ~~ class FSplitter ~~ @@ -199,6 +200,13 @@ class ImpraConf: self.ini.write() return v + def rem(self, key, section='main', profile=None): + """""" + if profile == None : profile = self.profile + v = self.ini.rem(key, profile+self.SEP_SECTION+section) + self.ini.write() + return v + # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # ~~ class ImpraIndex ~~ @@ -206,7 +214,7 @@ class ImpraConf: class ImpraIndex: """A representation of the index stored on the server""" - SEP_ITEM = ';' + SEP_ITEM = '―' """Separator used for entry""" SEP_TOKEN = '#' @@ -366,27 +374,6 @@ class ImpraIndex: rt.stop() return l - def toString(self,matchIds): - """Make a string representation of the index as it was store on the server""" - data = '' - r = [k for i, k in enumerate(self.dic) if not k.startswith(self.SEP_KEY_INTERN)] - for k in r : - v = self.dic.get(k) - k = k.lstrip('\n\r') - if not k[0]==self.SEP_KEY_INTERN and len(k)>1: - if matchIds==None or v[self.UID] in matchIds: - data += str(v[self.UID]).rjust(1+ceil(len(str(v[self.UID]))/10),' ')+' ' - data += str(k)[0:12]+'... ' - data += str(v[self.LABEL]).ljust(42,' ')+' ' - data += str(v[self.PARTS]).rjust(2,'0')+' ' - data += str(v[self.EXT]).ljust(5,' ')+' ' - data += self.getUser(str(v[self.OWNER])).ljust(15,' ')+' ' - data += str(v[self.CATG])+' ' - #~ elif len(k)>1: - #~ print(k,'=',v) - data = data+self.SEP_ITEM - return data; - def encrypt(self): """""" #~ print('encrypting index :') @@ -397,21 +384,51 @@ class ImpraIndex: def decrypt(self,data): """""" #~ print('decrypting index : ') - jdata = self.km.decrypt(data,'.index',22) - #~ print(jdata) - data = jloads(jdata) + try : + jdata = self.km.decrypt(data,'.index',22) + data = jloads(jdata) + except ValueError as e: + raise BadKeyException(e) return data def print(self,header='', matchIds=None): """Print index content as formated bloc""" data = self.toString(matchIds).split(self.SEP_ITEM) print(header) - print('id'+' '*2+'hash'+' '*13+'label'+' '*40+'part'+' '*2+'type'+' '*2+'owner'+' '*12+'category') - print('-'*120) + print(C.ON_IBLACK+' \ +%s%s%s' % (C.BYELLOW,'ID' ,' '*1 )+'\ +%s%s%s' % (C.BYELLOW,'HASH' ,' '*15)+'\ +%s%s%s' % (C.BYELLOW,'LABEL' ,' '*38)+'\ +%s%s%s' % (C.BYELLOW,'PART' ,' '*2 )+'\ +%s%s%s' % (C.BYELLOW,'TYPE' ,' '*2 )+'\ +%s%s%s' % (C.BYELLOW,'OWNER' ,' '*12)+'\ +%s%s%s' % (C.BYELLOW,'CATEGORY',' '*17)+C.OFF+'\n'+LINE_SEP) for row in data: if row.rstrip('\n') != '': print(row) - print('-'*120) + print(LINE_SEP) + def toString(self,matchIds): + """Make a string representation of the index as it was store on the server""" + data = '' + r = [k for i, k in enumerate(self.dic) if not k.startswith(self.SEP_KEY_INTERN)] + for k in r : + v = self.dic.get(k) + k = k.lstrip('\n\r') + + if not k[0]==self.SEP_KEY_INTERN and len(k)>1: + if matchIds==None or v[self.UID] in matchIds: + data += '%s%s%s' % (C.BIRED , str(v[self.UID]).rjust(1+ceil(len(str(v[self.UID]))/10),' '), ' '*2) + data += '%s%s%s' % (C.IGREEN , str(k)[0:12]+'... ' , ' '*2) + data += '%s%s%s' % (C.BWHITE , str(v[self.LABEL]).ljust(42,' ') , ' '*2) + data += '%s%s%s' % (C.BPURPLE , str(v[self.PARTS]).rjust(2 ,'0') , ' '*2) + data += '%s%s%s' % (C.BIGREEN , str(v[self.EXT]).ljust(5,' ') , ' '*2) + data += '%s%s%s' % (C.BWHITE , self.getUser(str(v[self.OWNER])).ljust(15,' ') , ' '*2) + data += '%s%s%s' % (C.BBLUE , str(v[self.CATG]) , ' '*2) + + #~ elif len(k)>1: + #~ print(k,'=',v) + data = data+self.SEP_ITEM + return data; # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -509,6 +526,7 @@ class ImpraStorage: if self.idx : self.ih.delete(self.idx, True) self.ih.deleteBin() + self.conf.rem('*','index') def saveIndex(self): """""" diff --git a/impra/crypt.py b/impra/crypt.py index 87a2b73..f937fbb 100644 --- a/impra/crypt.py +++ b/impra/crypt.py @@ -317,3 +317,10 @@ class Noiser: if noBytes: n = str(urlsafe_b64encode(n),'utf-8')[0:l] return n + + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# ~~ class BadKeyException ~~ + +class BadKeyException(BaseException): + pass diff --git a/impra/util.py b/impra/util.py index 64d07a3..b7dc771 100755 --- a/impra/util.py +++ b/impra/util.py @@ -224,8 +224,8 @@ def hilite(string, color=32, bold=True): # ~~ class RuTime ~~ class RuTime: - """Give basics time stats""" - + """Give basics time stats""" + def __init__(self,label,lvl=DEBUG_NOTICE): """Initialize duration with appropriate label""" from impra.util import DEBUG, DEBUG_LEVEL, DEBUG_INFO @@ -234,19 +234,27 @@ class RuTime: self.lvl = lvl self.label = label self._start() + def _start(self): - - if self.debug :print(' ==> '+self.label) + global C + if self.debug :print(C.BRED+' ==> '+C.BYELLOW+self._paramize(self.label)+C.OFF) self.sc = time() def stop(self): """Stop duration and print basics stats duration on console""" self.ec = time() if self.debug: self._stats() + + def _paramize(self,data): + global C + s = data.replace('(','('+C.GREEN) + s = s.replace(')',C.BYELLOW+')'+C.OFF) + return s def _stats(self): - print(' <== '+self.label+(' [%.9f s]' % (self.ec - self.sc))) + global C + print(C.BRED+' <== '+C.BYELLOW+self._paramize(self.label)+(' %s%.5f s%s' % (C.WHITE,self.ec-self.sc,C.OFF))) # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -340,15 +348,6 @@ class IniFile: except IOError : pass - - -# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# ~~ class ImpraStorage ~~ - -class BadKeysException(BaseException): - pass - - # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # ~~ class StrIterator ~~ @@ -372,3 +371,86 @@ class StrIterator: raise StopIteration self.i += 1 return self.d[self.i-1] + +class Coloriz: + + # Reset + OFF ='\033[1;m' + + # Regular Colors + BLACK ='\033[0;30m' + RED ='\033[0;31m' + GREEN ='\033[0;32m' + YELLOW ='\033[0;33m' + BLUE ='\033[0;34m' + PURPLE ='\033[0;35m' + CYAN ='\033[0;36m' + WHITE ='\033[0;37m' + + # Bold + BBLACK ='\033[1;30m' + BRED ='\033[1;31m' + BGREEN ='\033[1;32m' + BYELLOW ='\033[1;33m' + BBLUE ='\033[1;34m' + BPURPLE ='\033[1;35m' + BCYAN ='\033[1;36m' + BWHITE ='\033[1;37m' + + # Underline + UBLACK ='\033[4;30m' + URED ='\033[4;31m' + UGREEN ='\033[4;32m' + UYELLOW ='\033[4;33m' + UBLUE ='\033[4;34m' + UPURPLE ='\033[4;35m' + UCYAN ='\033[4;36m' + UWHITE ='\033[4;37m' + + # Background + ON_BLACK ='\033[40m' + ON_RED ='\033[41m' + ON_GREEN ='\033[42m' + ON_YELLOW ='\033[43m' + ON_BLUE ='\033[44m' + ON_PURPLE ='\033[45m' + ON_CYAN ='\033[46m' + ON_WHITE ='\033[47m' + + # High Intensity + IBLACK ='\033[0;90m' + IRED ='\033[0;91m' + IGREEN ='\033[0;92m' + IYELLOW ='\033[0;93m' + IBLUE ='\033[0;94m' + IPURPLE ='\033[0;95m' + ICYAN ='\033[0;96m' + IWHITE ='\033[0;97m' + + # Bold High Intensity + BIBLACK ='\033[1;90m' + BIRED ='\033[1;91m' + BIGREEN ='\033[1;92m' + BIYELLOW ='\033[1;93m' + BIBLUE ='\033[1;94m' + BIPURPLE ='\033[1;95m' + BICYAN ='\033[1;96m' + BIWHITE ='\033[1;97m' + + # High Intensity backgrounds + ON_IBLACK ='\033[0;100m' + ON_IRED ='\033[0;101m' + ON_IGREEN ='\033[0;102m' + ON_IYELLOW ='\033[0;103m' + ON_IBLUE ='\033[0;104m' + ON_IPURPLE ='\033[10;95m' + ON_ICYAN ='\033[0;106m' + ON_IWHITE ='\033[0;107m' + + def __init__(self): + """""" + global COLOR_MODE + if not COLOR_MODE : + self.OFF = self.BLACK = self.RED = self.GREEN = self.YELLOW = self.BLUE = self.PURPLE = self.CYAN = self.WHITE = self.BBLACK = self.BRED = self.BGREEN = self.BYELLOW = self.BBLUE = self.BPURPLE = self.BCYAN = self.BWHITE = self.UBLACK = self.URED = self.UGREEN = self.UYELLOW = self.UBLUE = self.UPURPLE = self.UCYAN = self.UWHITE = self.ON_BLACK = self.ON_RED = self.ON_GREEN = self.ON_YELLOW = self.ON_BLUE = self.ON_PURPLE = self.ON_CYAN = self.ON_WHITE = self.IBLACK = self.IRED = self.IGREEN = self.IYELLOW = self.IBLUE = self.IPURPLE = self.ICYAN = self.IWHITE = self.BIBLACK = self.BIRED = self.BIGREEN = self.BIYELLOW = self.BIBLUE = self.BIPURPLE = self.BICYAN = self.BIWHITE = self.ON_IBLACK = self.ON_IRED = self.ON_IGREEN = self.ON_IYELLOW = self.ON_IBLUE = self.ON_IPURPLE = self.ON_ICYAN = self.ON_IWHITE = '' + +C = Coloriz() diff --git a/imprastorage.py b/imprastorage.py index 8bcfd2d..45c02df 100755 --- a/imprastorage.py +++ b/imprastorage.py @@ -33,7 +33,23 @@ from impra.cli import Cli if __name__ == '__main__': #~ try : - + #~ print('\033[1;30mGray like Ghost\033[1;m') + #~ print('\033[1;31mRed like Radish\033[1;m') + #~ print('\033[1;32mGreen like Grass\033[1;m') + #~ print('\033[1;33mYellow like Yolk\033[1;m') + #~ print('\033[1;34mBlue like Blood\033[1;m') + #~ print('\033[1;35mMagenta like Mimosa\033[1;m') + #~ print('\033[1;36mCyan like Caribbean\033[1;m') + #~ print('\033[1;37mWhite like Whipped Cream\033[1;m') + #~ print('\033[1;38mCrimson like Chianti\033[1;m') + #~ print('\033[1;41mHighlighted Red like Radish\033[1;m') + #~ print('\033[1;42mHighlighted Green like Grass\033[1;m') + #~ print('\033[1;43mHighlighted Brown like Bear\033[1;m') + #~ print('\033[1;44mHighlighted Blue like Blood\033[1;m') + #~ print('\033[1;45mHighlighted Magenta like Mimosa\033[1;m') + #~ print('\033[1;46mHighlighted Cyan like Caribbean\033[1;m') + #~ print('\033[1;47mHighlighted Gray like Ghost\033[1;m') + #~ print('\033[1;48mHighlighted Crimson like Chianti\033[1;m') Cli(get_file_path(__file__ )) #~ except Exception as e : #~ print(e)