refactoring and manage multiproc interruption
This commit is contained in:
parent
0dea1e7db0
commit
0d67d7bbcb
199
kirmah/cli.py
199
kirmah/cli.py
|
@ -31,91 +31,33 @@
|
|||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# ~~ module cli ~~
|
||||
|
||||
from optparse import OptionParser, OptionGroup
|
||||
import kirmah.conf as conf
|
||||
from kirmah.cliapp import CliApp
|
||||
from optparse import OptionGroup
|
||||
from psr.sys import Sys, Io, Const, init
|
||||
from psr.log import Log
|
||||
|
||||
if not Sys.isUnix : Const.LINE_SEP_CHAR = '-'
|
||||
|
||||
|
||||
def printLineSep(sep,lenSep):
|
||||
""""""
|
||||
s = sep*lenSep
|
||||
Sys.print(s, Sys.CLZ_HEAD_LINE)
|
||||
return [(s, Const.CLZ_HEAD_SEP)]
|
||||
|
||||
|
||||
def printHeaderTitle(title):
|
||||
""""""
|
||||
s = ' == '+title+' == '
|
||||
Sys.print(s, Sys.CLZ_HEAD_APP, False, True)
|
||||
return [(s, Const.CLZ_HEAD_APP)]
|
||||
|
||||
|
||||
def printHeaderPart(label,value):
|
||||
""""""
|
||||
a, b, c = ' [',':' ,'] '
|
||||
Sys.print(a , Sys.CLZ_HEAD_SEP, False)
|
||||
Sys.print(label, Sys.CLZ_HEAD_KEY, False)
|
||||
Sys.print(b , Sys.CLZ_HEAD_SEP, False)
|
||||
Sys.print(value, Sys.CLZ_HEAD_VAL, False)
|
||||
Sys.print(c , Sys.CLZ_HEAD_SEP, False)
|
||||
return [(a,Const.CLZ_HEAD_SEP),(label,Const.CLZ_HEAD_KEY),(b,Const.CLZ_HEAD_SEP),(value,Const.CLZ_HEAD_VAL),(c,Const.CLZ_HEAD_SEP)]
|
||||
|
||||
|
||||
class _OptionParser(OptionParser):
|
||||
"""A simplified OptionParser"""
|
||||
|
||||
def format_description(self, formatter):
|
||||
return self.description
|
||||
|
||||
|
||||
def format_epilog(self, formatter):
|
||||
return self.epilog
|
||||
|
||||
|
||||
def error(self, errMsg, errData=None):
|
||||
self.print_usage('')
|
||||
Cli.error_cmd(self, (errMsg,))
|
||||
from psr.cli import AbstractCli
|
||||
from kirmah.cliapp import CliApp
|
||||
import kirmah.conf as conf
|
||||
|
||||
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# ~~ class Cli ~~
|
||||
|
||||
class Cli:
|
||||
class Cli(AbstractCli):
|
||||
|
||||
def __init__(self, path, remote=False, rwargs=None, thread=None, loglvl=Const.LOG_DEFAULT):
|
||||
""""""
|
||||
if thread is not None :
|
||||
Sys.g.THREAD_CLI = thread
|
||||
Sys.g.GUI = True
|
||||
else :
|
||||
Sys.g.GUI = False
|
||||
AbstractCli.__init__(self, conf)
|
||||
|
||||
|
||||
self.HOME = conf.DEFVAL_USER_PATH
|
||||
self.DIRKEY = self.HOME+'.'+conf.PRG_NAME.lower()+Sys.sep
|
||||
Cli.HOME = conf.DEFVAL_USER_PATH
|
||||
Cli.DIRKEY = Cli.HOME+'.'+conf.PRG_NAME.lower()+Sys.sep
|
||||
if not Sys.isUnix() :
|
||||
CHQ = '"'
|
||||
self.HOME = 'C:'+Sys.sep+conf.PRG_NAME.lower()+Sys.sep
|
||||
self.DIRKEY = self.HOME+'keys'+Sys.sep
|
||||
Sys.mkdir_p(self.DIRKEY)
|
||||
|
||||
parser = _OptionParser()
|
||||
parser.print_help = self.print_help
|
||||
parser.print_usage = self.print_usage
|
||||
|
||||
gpData = OptionGroup(parser, '')
|
||||
|
||||
parser.add_option('-v', '--version' , action='store_true', default=False)
|
||||
parser.add_option('-d', '--debug' , action='store_true', default=False)
|
||||
parser.add_option('-f', '--force' , action='store_true', default=False)
|
||||
parser.add_option('-q', '--quiet' , action='store_true', default=False)
|
||||
|
||||
parser.add_option('--no-color' , action='store_true' , default=False)
|
||||
Sys.mkdir_p(Cli.DIRKEY)
|
||||
|
||||
gpData = OptionGroup(self.parser, '')
|
||||
gpData.add_option('-a', '--fullcompress' , action='store_true' )
|
||||
gpData.add_option('-z', '--compress' , action='store_true' )
|
||||
gpData.add_option('-Z', '--nocompress' , action='store_true' )
|
||||
|
@ -128,35 +70,38 @@ class Cli:
|
|||
gpData.add_option('-l', '--length' , action='store', default=1024)
|
||||
gpData.add_option('-p', '--parts' , action='store', default=22)
|
||||
gpData.add_option('-o', '--outputfile' , action='store')
|
||||
parser.add_option_group(gpData)
|
||||
self.parser.add_option_group(gpData)
|
||||
|
||||
# rewrite argv sended by remote
|
||||
if rwargs is not None :
|
||||
import sys
|
||||
sys.argv = rwargs
|
||||
|
||||
(o, a) = parser.parse_args()
|
||||
(o, a) = self.parser.parse_args()
|
||||
|
||||
Sys.g.QUIET = o.quiet
|
||||
Sys.g.QUIET = o.quiet
|
||||
Sys.g.THREAD_CLI = thread
|
||||
Sys.g.GUI = thread is not None
|
||||
|
||||
init(conf.PRG_NAME, o.debug, remote, not o.no_color, loglvl)
|
||||
|
||||
|
||||
if not a:
|
||||
|
||||
try :
|
||||
if not o.help :
|
||||
self.error_cmd(('no command specified',))
|
||||
Cli.error_cmd(('no command specified',))
|
||||
else :
|
||||
Sys.clear()
|
||||
parser.print_help()
|
||||
Cli.print_help()
|
||||
except :
|
||||
self.error_cmd(('no command specified',))
|
||||
Cli.error_cmd(('no command specified',))
|
||||
|
||||
else:
|
||||
|
||||
if a[0] == 'help':
|
||||
Sys.clear()
|
||||
parser.print_help()
|
||||
Cli.print_help()
|
||||
|
||||
elif a[0] in ['key','enc','dec','split','merge'] :
|
||||
|
||||
|
@ -166,9 +111,9 @@ class Cli:
|
|||
app.onCommandKey()
|
||||
else :
|
||||
if not len(a)>1 :
|
||||
self.error_cmd((('an ',('inputFile',Sys.Clz.fgb3),' is required !'),))
|
||||
Cli.error_cmd((('an ',('inputFile',Sys.Clz.fgb3),' is required !'),))
|
||||
elif not Io.file_exists(a[1]):
|
||||
self.error_cmd((('the file ',(a[1], Sys.Clz.fgb3), ' doesn\'t exists !'),))
|
||||
Cli.error_cmd((('the file ',(a[1], Sys.Clz.fgb3), ' doesn\'t exists !'),))
|
||||
|
||||
elif a[0]=='enc' : app.onCommandEnc()
|
||||
elif a[0]=='dec' : app.onCommandDec()
|
||||
|
@ -180,59 +125,21 @@ class Cli:
|
|||
Sys.g.LOG_QUEUE.put(Sys.g.SIGNAL_STOP)
|
||||
|
||||
else :
|
||||
self.error_cmd((('unknow command ',(a[0],Sys.Clz.fgb3)),))
|
||||
Cli.error_cmd((('unknow command ',(a[0],Sys.Clz.fgb3)),))
|
||||
|
||||
if not o.quiet : Sys.dprint()
|
||||
|
||||
|
||||
def clean(self):
|
||||
@staticmethod
|
||||
def print_usage(data, withoutHeader=False):
|
||||
""""""
|
||||
print('cleaning')
|
||||
|
||||
|
||||
def error_cmd(self, data):
|
||||
""""""
|
||||
self.print_usage('')
|
||||
Sys.dprint()
|
||||
Sys.pwarn(data, True)
|
||||
self.exit(1)
|
||||
|
||||
|
||||
def exit(self, code):
|
||||
""""""
|
||||
if Sys.isUnix() : Sys.exit(code)
|
||||
|
||||
|
||||
def print_header(self):
|
||||
""""""
|
||||
a = printLineSep(Const.LINE_SEP_CHAR,Const.LINE_SEP_LEN)
|
||||
b = printHeaderTitle(conf.PRG_CLI_NAME)
|
||||
c = printHeaderPart('version' ,conf.PRG_VERS)
|
||||
d = printHeaderPart('author' ,conf.PRG_AUTHOR)
|
||||
e = printHeaderPart('license' ,conf.PRG_LICENSE)
|
||||
f = printHeaderPart('copyright',conf.PRG_COPY)
|
||||
Sys.print(' ', Sys.Clz.OFF)
|
||||
printLineSep(Const.LINE_SEP_CHAR,Const.LINE_SEP_LEN)
|
||||
Sys.wlog(a)
|
||||
Sys.wlog(b + c + d + e + f )
|
||||
Sys.wlog(a)
|
||||
Sys.wlog(Sys.dprint())
|
||||
|
||||
|
||||
def print_version(self, data):
|
||||
""""""
|
||||
self.print_header()
|
||||
|
||||
|
||||
def print_usage(self, data, withoutHeader=False):
|
||||
""""""
|
||||
if not withoutHeader : self.print_header()
|
||||
if not withoutHeader : Cli.print_header()
|
||||
|
||||
Sys.print(' USAGE :\n' , Sys.CLZ_HELP_CMD)
|
||||
Sys.print(' '+conf.PRG_CLI_NAME+' ' , Sys.CLZ_HELP_PRG, False)
|
||||
Sys.print(' '+Cli.conf.PRG_CLI_NAME+' ' , Sys.CLZ_HELP_PRG, False)
|
||||
Sys.print('help ' , Sys.CLZ_HELP_CMD)
|
||||
|
||||
Sys.print(' '+conf.PRG_CLI_NAME+' ' , Sys.CLZ_HELP_PRG, False)
|
||||
Sys.print(' '+Cli.conf.PRG_CLI_NAME+' ' , Sys.CLZ_HELP_PRG, False)
|
||||
Sys.print('key ' , Sys.CLZ_HELP_CMD, False)
|
||||
Sys.print('[ -l ' , Sys.CLZ_HELP_ARG, False)
|
||||
Sys.print('{' , Sys.CLZ_HELP_PARAM, False)
|
||||
|
@ -244,7 +151,7 @@ class Cli:
|
|||
Sys.print('}' , Sys.CLZ_HELP_PARAM, False)
|
||||
Sys.print(']' , Sys.CLZ_HELP_ARG)
|
||||
|
||||
Sys.print(' '+conf.PRG_CLI_NAME+' ' , Sys.CLZ_HELP_PRG, False)
|
||||
Sys.print(' '+Cli.conf.PRG_CLI_NAME+' ' , Sys.CLZ_HELP_PRG, False)
|
||||
Sys.print('enc ' , Sys.CLZ_HELP_CMD, False)
|
||||
Sys.print('{' , Sys.CLZ_HELP_PARAM, False)
|
||||
Sys.print('inputFile' , Sys.CLZ_HELP_PARAM, False)
|
||||
|
@ -321,10 +228,11 @@ class Cli:
|
|||
Sys.print(']' , Sys.CLZ_HELP_ARG)
|
||||
|
||||
|
||||
def print_options(self):
|
||||
@staticmethod
|
||||
def print_options():
|
||||
""""""
|
||||
Sys.dprint('\n')
|
||||
printLineSep(Const.LINE_SEP_CHAR,Const.LINE_SEP_LEN)
|
||||
Cli.printLineSep(Const.LINE_SEP_CHAR,Const.LINE_SEP_LEN)
|
||||
|
||||
Sys.print(' MAIN OPTIONS :\n' , Sys.CLZ_HELP_CMD)
|
||||
Sys.print(' '*4+'-v'.ljust(13,' ')+', --version' , Sys.CLZ_HELP_ARG)
|
||||
|
@ -435,13 +343,14 @@ class Cli:
|
|||
Sys.dprint('\n')
|
||||
|
||||
|
||||
def print_help(self):
|
||||
@staticmethod
|
||||
def print_help():
|
||||
""""""
|
||||
self.print_header()
|
||||
Sys.print(conf.PRG_DESC, Sys.CLZ_HELP_DESC)
|
||||
self.print_usage('',True)
|
||||
self.print_options()
|
||||
printLineSep(Const.LINE_SEP_CHAR,Const.LINE_SEP_LEN)
|
||||
Cli.print_header()
|
||||
Sys.print(Cli.conf.PRG_DESC, Sys.CLZ_HELP_DESC)
|
||||
Cli.print_usage('',True)
|
||||
Cli.print_options()
|
||||
Cli.printLineSep(Const.LINE_SEP_CHAR,Const.LINE_SEP_LEN)
|
||||
Sys.dprint()
|
||||
Sys.print(' EXEMPLES :\n', Sys.CLZ_HELP_CMD)
|
||||
CHQ = "'"
|
||||
|
@ -456,16 +365,16 @@ class Cli:
|
|||
Sys.print(' '*8+'# generate a new crypted key (default length is 1024) in a specified location', Sys.CLZ_HELP_COMMENT)
|
||||
Sys.print(' '*8+conf.PRG_CLI_NAME+' ', Sys.CLZ_HELP_PRG, False)
|
||||
Sys.print('key -o ', Sys.CLZ_HELP_CMD, False)
|
||||
Sys.print(self.DIRKEY+'.myNewKey', Sys.CLZ_HELP_PARAM)
|
||||
Sys.print(Cli.DIRKEY+'.myNewKey', Sys.CLZ_HELP_PARAM)
|
||||
|
||||
|
||||
printLineSep(Const.LINE_SEP_CHAR,Const.LINE_SEP_LEN)
|
||||
Cli.printLineSep(Const.LINE_SEP_CHAR,Const.LINE_SEP_LEN)
|
||||
Sys.print('\n'+' '*4+'command encrypt :', Sys.CLZ_HELP_CMD)
|
||||
|
||||
Sys.print(' '*8+'# encrypt specified file with default crypted key and default options', Sys.CLZ_HELP_COMMENT)
|
||||
Sys.print(' '*8+conf.PRG_CLI_NAME+' ', Sys.CLZ_HELP_PRG, False)
|
||||
Sys.print('enc ', Sys.CLZ_HELP_CMD, False)
|
||||
Sys.print(self.HOME+'mySecretTextFile.txt', Sys.CLZ_HELP_PARAM)
|
||||
Sys.print(Cli.HOME+'mySecretTextFile.txt', Sys.CLZ_HELP_PARAM)
|
||||
|
||||
Sys.print(' '*8+'# encrypt specified file with specified crypted key (full compression, no random but mix mode)', Sys.CLZ_HELP_COMMENT)
|
||||
Sys.print(' '*8+'# on specified output location', Sys.CLZ_HELP_COMMENT)
|
||||
|
@ -473,7 +382,7 @@ class Cli:
|
|||
Sys.print('enc ', Sys.CLZ_HELP_CMD, False)
|
||||
Sys.print('mySecretTextFile.txt', Sys.CLZ_HELP_PARAM, False)
|
||||
Sys.print(' -aRm -k ' , Sys.CLZ_HELP_ARG, False)
|
||||
Sys.print(self.DIRKEY+'.myNewKey', Sys.CLZ_HELP_PARAM, False)
|
||||
Sys.print(Cli.DIRKEY+'.myNewKey', Sys.CLZ_HELP_PARAM, False)
|
||||
Sys.print(' -o ' , Sys.CLZ_HELP_ARG, False)
|
||||
Sys.print('test.kmh', Sys.CLZ_HELP_PARAM)
|
||||
|
||||
|
@ -485,20 +394,20 @@ class Cli:
|
|||
Sys.print('4', Sys.CLZ_HELP_PARAM)
|
||||
|
||||
|
||||
printLineSep(Const.LINE_SEP_CHAR,Const.LINE_SEP_LEN)
|
||||
Cli.printLineSep(Const.LINE_SEP_CHAR,Const.LINE_SEP_LEN)
|
||||
Sys.print('\n'+' '*4+'command decrypt :', Sys.CLZ_HELP_CMD)
|
||||
|
||||
Sys.print(' '*8+'# decrypt specified file with default crypted key', Sys.CLZ_HELP_COMMENT)
|
||||
Sys.print(' '*8+conf.PRG_CLI_NAME+' ', Sys.CLZ_HELP_PRG, False)
|
||||
Sys.print('dec ', Sys.CLZ_HELP_CMD, False)
|
||||
Sys.print(self.HOME+'mySecretFile.kmh', Sys.CLZ_HELP_PARAM)
|
||||
Sys.print(Cli.HOME+'mySecretFile.kmh', Sys.CLZ_HELP_PARAM)
|
||||
|
||||
Sys.print(' '*8+'# decrypt specified file with specified crypted key on specified output location', Sys.CLZ_HELP_COMMENT)
|
||||
Sys.print(' '*8+conf.PRG_CLI_NAME+' ', Sys.CLZ_HELP_PRG, False)
|
||||
Sys.print(' '*8+Cli.conf.PRG_CLI_NAME+' ', Sys.CLZ_HELP_PRG, False)
|
||||
Sys.print('dec ', Sys.CLZ_HELP_CMD, False)
|
||||
Sys.print('myEncryptedSecretFile.kmh', Sys.CLZ_HELP_PARAM, False)
|
||||
Sys.print(' -k ' , Sys.CLZ_HELP_ARG, False)
|
||||
Sys.print(self.HOME+'.kirmah'+Sys.sep+'.myNewKey', Sys.CLZ_HELP_PARAM, False)
|
||||
Sys.print(Cli.HOME+'.kirmah'+Sys.sep+'.myNewKey', Sys.CLZ_HELP_PARAM, False)
|
||||
Sys.print(' -o ' , Sys.CLZ_HELP_ARG, False)
|
||||
Sys.print('myDecryptedSecretFile.txt', Sys.CLZ_HELP_PARAM)
|
||||
|
||||
|
@ -510,13 +419,13 @@ class Cli:
|
|||
Sys.print('4' , Sys.CLZ_HELP_PARAM)
|
||||
|
||||
|
||||
printLineSep(Const.LINE_SEP_CHAR,Const.LINE_SEP_LEN)
|
||||
Cli.printLineSep(Const.LINE_SEP_CHAR,Const.LINE_SEP_LEN)
|
||||
Sys.print('\n'+' '*4+'command split :', Sys.CLZ_HELP_CMD)
|
||||
|
||||
Sys.print(' '*8+'# split specified file with default crypted key', Sys.CLZ_HELP_COMMENT)
|
||||
Sys.print(' '*8+conf.PRG_CLI_NAME+' ', Sys.CLZ_HELP_PRG, False)
|
||||
Sys.print('split ', Sys.CLZ_HELP_CMD, False)
|
||||
Sys.print(self.HOME+'myBigBinaryFile.avi', Sys.CLZ_HELP_PARAM)
|
||||
Sys.print(Cli.HOME+'myBigBinaryFile.avi', Sys.CLZ_HELP_PARAM)
|
||||
|
||||
Sys.print(' '*8+'# split specified file on 55 parts with specified crypted key on specified output location', Sys.CLZ_HELP_COMMENT)
|
||||
Sys.print(' '*8+conf.PRG_CLI_NAME+' ', Sys.CLZ_HELP_PRG, False)
|
||||
|
@ -525,27 +434,27 @@ class Cli:
|
|||
Sys.print(' -p ' , Sys.CLZ_HELP_ARG, False)
|
||||
Sys.print('55' , Sys.CLZ_HELP_PARAM, False)
|
||||
Sys.print(' -k ' , Sys.CLZ_HELP_ARG, False)
|
||||
Sys.print(self.DIRKEY+'.myNewKey', Sys.CLZ_HELP_PARAM, False)
|
||||
Sys.print(Cli.DIRKEY+'.myNewKey', Sys.CLZ_HELP_PARAM, False)
|
||||
Sys.print(' -o ' , Sys.CLZ_HELP_ARG, False)
|
||||
Sys.print('myBigBinaryFile.encrypted', Sys.CLZ_HELP_PARAM)
|
||||
|
||||
|
||||
printLineSep(Const.LINE_SEP_CHAR,Const.LINE_SEP_LEN)
|
||||
Cli.printLineSep(Const.LINE_SEP_CHAR,Const.LINE_SEP_LEN)
|
||||
Sys.print('\n'+' '*4+'command merge :', Sys.CLZ_HELP_CMD)
|
||||
|
||||
Sys.print(' '*8+'# merge specified splitted file with default crypted key', Sys.CLZ_HELP_COMMENT)
|
||||
Sys.print(' '*8+conf.PRG_CLI_NAME+' ', Sys.CLZ_HELP_PRG, False)
|
||||
Sys.print('merge ', Sys.CLZ_HELP_CMD, False)
|
||||
Sys.print(self.HOME+'6136bd1b53d84ecbad5380594eea7256176c19e0266c723ea2e982f8ca49922b.kcf', Sys.CLZ_HELP_PARAM)
|
||||
Sys.print(Cli.HOME+'6136bd1b53d84ecbad5380594eea7256176c19e0266c723ea2e982f8ca49922b.kcf', Sys.CLZ_HELP_PARAM)
|
||||
|
||||
Sys.print(' '*8+'# merge specified tark splitted file with specified crypted key on specified output location', Sys.CLZ_HELP_COMMENT)
|
||||
Sys.print(' '*8+conf.PRG_CLI_NAME+' ', Sys.CLZ_HELP_PRG, False)
|
||||
Sys.print('merge ', Sys.CLZ_HELP_CMD, False)
|
||||
Sys.print('myBigBinaryFile.encrypted.tark', Sys.CLZ_HELP_PARAM, False)
|
||||
Sys.print(' -k ' , Sys.CLZ_HELP_ARG, False)
|
||||
Sys.print(self.DIRKEY+'.myNewKey', Sys.CLZ_HELP_PARAM, False)
|
||||
Sys.print(Cli.DIRKEY+'.myNewKey', Sys.CLZ_HELP_PARAM, False)
|
||||
Sys.print(' -o ' , Sys.CLZ_HELP_ARG, False)
|
||||
Sys.print('myBigBinaryFile.decrypted.avi', Sys.CLZ_HELP_PARAM)
|
||||
|
||||
printLineSep(Const.LINE_SEP_CHAR,Const.LINE_SEP_LEN)
|
||||
Cli.printLineSep(Const.LINE_SEP_CHAR,Const.LINE_SEP_LEN)
|
||||
Sys.dprint()
|
||||
|
|
|
@ -121,10 +121,11 @@ class CliApp:
|
|||
except Exception as e :
|
||||
done = False
|
||||
print(e)
|
||||
raise e
|
||||
pass
|
||||
|
||||
if not Sys.g.QUIET :
|
||||
self.onend_cmd('Encrypting file', self.stime, done, self.o.outputfile)
|
||||
self.onend_cmd('Kirmah Encrypt', self.stime, done, self.o.outputfile)
|
||||
|
||||
|
||||
@Log(Const.LOG_DEBUG)
|
||||
|
@ -164,7 +165,7 @@ class CliApp:
|
|||
raise e
|
||||
|
||||
if not Sys.g.QUIET :
|
||||
self.onend_cmd('Decrypting file', self.stime, done, self.o.outputfile)
|
||||
self.onend_cmd('Kirmah Decrypt', self.stime, done, self.o.outputfile)
|
||||
|
||||
|
||||
@Log(Const.LOG_DEBUG)
|
||||
|
@ -173,7 +174,7 @@ class CliApp:
|
|||
done = True
|
||||
Sys.cli_emit_progress(1)
|
||||
if not self.o.parts is None and not(int(self.o.parts)>=12 and int(self.o.parts) <=62) :
|
||||
self.error_cmd((('invalid option ',('-p, --parts', Sys.Clz.fgb3), ' value (', ('12',Sys.Clz.fgb3),' to ', ('62',Sys.Clz.fgb3),')'),))
|
||||
self.parser.error_cmd((('invalid option ',('-p, --parts', Sys.Clz.fgb3), ' value (', ('12',Sys.Clz.fgb3),' to ', ('62',Sys.Clz.fgb3),')'),))
|
||||
else : self.o.parts = int(self.o.parts)
|
||||
|
||||
if not Sys.g.QUIET : self.parser.print_header()
|
||||
|
|
188
kirmah/crypt.py
188
kirmah/crypt.py
|
@ -91,60 +91,6 @@ def represents_int(s):
|
|||
return False
|
||||
|
||||
|
||||
@Log(Const.LOG_DEBUG)
|
||||
def getRandomListFromKey(key, size):
|
||||
""""""
|
||||
j, ok, lk, r, ho, hr, lv, hv, rev = 0, False, len(key), None, [], [], 0, size-1, False
|
||||
for i in range(size) :
|
||||
if j >= lk : j = 0
|
||||
r = key[j]
|
||||
ok = r < size and not r in ho
|
||||
if not ok:
|
||||
r = hv if not rev else lv
|
||||
while r in ho :
|
||||
r = r - 1 if not rev else r + 1
|
||||
if r > size-1 : r = 0
|
||||
elif r < 0 : r = size - 1
|
||||
if not rev : hv = r
|
||||
else : lv = r
|
||||
ok = not r in ho
|
||||
if ok : ho.append(r)
|
||||
j += 1
|
||||
rev = not rev
|
||||
return getSimulRandomList(ho, getSimulNumber(key, size//5 if not size//5==0 else size*2, size//10 if not size//10 ==0 else size))
|
||||
|
||||
|
||||
@Log(Const.LOG_ALL)
|
||||
def getSimulRandomList(lst, chsize):
|
||||
""""""
|
||||
return _getSimulRandomList(list(reversed(_getSimulRandomList(_getSimulRandomList(lst, chsize), 4))),4)
|
||||
|
||||
|
||||
@Log(Const.LOG_PRIVATE)
|
||||
def _getSimulRandomList(lst, chsize):
|
||||
""""""
|
||||
size, rlst, pos = len(lst), [], 0
|
||||
if chsize > 0 :
|
||||
for i in range(chsize+1):
|
||||
for j in range(ceil(size/chsize)+1):
|
||||
pos = j*chsize+i
|
||||
if pos in lst and not lst[pos] in rlst:
|
||||
rlst.append(lst[pos])
|
||||
else : rlst = lst
|
||||
return rlst
|
||||
|
||||
|
||||
@Log(Const.LOG_DEBUG)
|
||||
def getSimulNumber(key, lim, delta=12):
|
||||
""""""
|
||||
s = 0
|
||||
for c in key[::-1] :
|
||||
if represents_int(chr(c)): c = int(chr(c))
|
||||
if c > 2 and (lim-delta > c + s or c + s < lim + delta ) :
|
||||
s += c
|
||||
return s
|
||||
|
||||
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# ~~ class KeyGen ~~
|
||||
|
||||
|
@ -231,8 +177,8 @@ class ConfigKey:
|
|||
self.rdmz.new(count)
|
||||
dic, lst, hroot = {}, [], hash_sha256(self.salt+name)
|
||||
|
||||
#~ srdl = Kirmah.getRandomListFromKey(self.key, count)
|
||||
srdl = getRandomListFromKey(self.key, count)
|
||||
srdl = Kirmah.getRandomListFromKey(self.key, count)
|
||||
#~ srdl = getRandomListFromKey(self.key, count)
|
||||
for i in range(count) :
|
||||
self.noiser.build(i,ConfigKey.sumNumber(hash_sha256(str(i)+self.salt+name),1 if i%2 else 2))
|
||||
d = str(i).rjust(2,'0')
|
||||
|
@ -419,27 +365,37 @@ class Kirmah:
|
|||
@Log()
|
||||
def compress_start(self, fromPath, toPath, compress=True, lvl=9):
|
||||
""""""
|
||||
if not Sys.is_cli_cancel():
|
||||
d = Sys.datetime.now()
|
||||
c = not Sys.is_cli_cancel()
|
||||
if c :
|
||||
with Io.rfile(fromPath) as fi :
|
||||
with Io.wfile(toPath) as fo :
|
||||
data = fi.read() if not compress else Io.gzcompress(fi.read(), lvl)
|
||||
fo.write(b2a_base64(data))
|
||||
Sys.wlog(Sys.dprint())
|
||||
Sys.pstep('Compression', d, c)
|
||||
|
||||
|
||||
@Log()
|
||||
def uncompress_start(self, fromPath, toPath, decompress=True):
|
||||
""""""
|
||||
if not Sys.is_cli_cancel():
|
||||
d = Sys.datetime.now()
|
||||
c = not Sys.is_cli_cancel()
|
||||
if c :
|
||||
with Io.rfile(fromPath) as fi :
|
||||
with Io.wfile(toPath) as fo :
|
||||
data = a2b_base64(fi.read())
|
||||
fo.write(data if not decompress else Io.gzdecompress(data))
|
||||
Sys.wlog(Sys.dprint())
|
||||
Sys.pstep('Compression mode', d, c)
|
||||
|
||||
|
||||
@Log()
|
||||
def compress_end(self, fromPath, toPath, compress=True, lvl=9):
|
||||
""""""
|
||||
if not Sys.is_cli_cancel():
|
||||
d = Sys.datetime.now()
|
||||
c = not Sys.is_cli_cancel()
|
||||
if c:
|
||||
with Io.rfile(fromPath) as fi :
|
||||
with Io.wfile(toPath) as fo :
|
||||
data = fi.read()
|
||||
|
@ -447,17 +403,22 @@ class Kirmah:
|
|||
header = self.kh.buildHeader(len(data))
|
||||
fo.write(header)
|
||||
fo.write(data)
|
||||
Sys.wlog(Sys.dprint())
|
||||
Sys.pstep('Compression mode', d, c)
|
||||
|
||||
|
||||
@Log()
|
||||
def uncompress_end(self, fromPath, toPath, decompress=True):
|
||||
""""""
|
||||
if not Sys.is_cli_cancel():
|
||||
d = Sys.datetime.now()
|
||||
c = not Sys.is_cli_cancel()
|
||||
if c:
|
||||
with Io.rfile(fromPath) as fi :
|
||||
with Io.wfile(toPath) as fo :
|
||||
fi.seek(self.kh.POS_END)
|
||||
fo.write(fi.read() if not decompress else Io.gzdecompress(fi.read()))
|
||||
|
||||
Sys.wlog(Sys.dprint())
|
||||
Sys.pstep('Compression mode', d, c)
|
||||
|
||||
@Log(Const.LOG_ALL)
|
||||
def encryptStr(self, data):
|
||||
|
@ -474,7 +435,7 @@ class Kirmah:
|
|||
|
||||
|
||||
@Log()
|
||||
def encryptToFile(self, fromPath, toPath, i=0, lock=None):
|
||||
def encryptToFile(self, fromPath, toPath, i=0, event=None):
|
||||
""""""
|
||||
if not Sys.is_cli_cancel():
|
||||
with Io.ufile(fromPath) as fi :
|
||||
|
@ -483,14 +444,15 @@ class Kirmah:
|
|||
for c in Io.read_utf8_chr(fi):
|
||||
if i >= lk:
|
||||
i = 0
|
||||
if Sys.is_cli_cancel(lock):
|
||||
if Sys.is_cli_cancel(event) :
|
||||
Sys.pwarn((('terminating child process ',(str(Sys.getpid()),Sys.CLZ_WARN_PARAM), ' !'),), False)
|
||||
break
|
||||
fo.write(chr(ord(c) + i//4 + (self.key[i] if ord(c) + self.key[i] + i//4 < 11000 else -self.key[i])))
|
||||
i += 1
|
||||
|
||||
|
||||
@Log()
|
||||
def decryptToFile(self, fromPath, toPath, i=0):
|
||||
def decryptToFile(self, fromPath, toPath, i=0, event=None):
|
||||
""""""
|
||||
if not Sys.is_cli_cancel():
|
||||
with Io.ufile(fromPath) as fi :
|
||||
|
@ -502,7 +464,9 @@ class Kirmah:
|
|||
for c in Io.read_utf8_chr(fi):
|
||||
if i >= lk:
|
||||
i = 0
|
||||
if Sys.is_cli_cancel(): break
|
||||
if Sys.is_cli_cancel(event) :
|
||||
Sys.pwarn((('terminating child process ',(str(Sys.getpid()),Sys.CLZ_WARN_PARAM), ' !'),), False)
|
||||
break
|
||||
try :
|
||||
fo.write(chr(ord(c)- i//4 + (-self.key[i] if ord(c) + self.key[i] +i//4 < 110000 else self.key[i])))
|
||||
except Exception as e :
|
||||
|
@ -516,7 +480,9 @@ class Kirmah:
|
|||
@Log()
|
||||
def randomFileContent(self, fromPath, toPath):
|
||||
""""""
|
||||
if not Sys.is_cli_cancel():
|
||||
d = Sys.datetime.now()
|
||||
c = not Sys.is_cli_cancel()
|
||||
if c:
|
||||
with Io.rfile(fromPath) as fi :
|
||||
with Io.wfile(toPath) as fo :
|
||||
fsize, chsize, size = Kirmah.getSizes(fromPath)
|
||||
|
@ -525,6 +491,8 @@ class Kirmah:
|
|||
for piece, i in Io.read_in_chunks(fi, chsize):
|
||||
fo.seek(lst[i]*chsize-(rest if lst[i] > lst[size-1] else 0))
|
||||
fo.write(piece[::-1])
|
||||
Sys.wlog(Sys.dprint())
|
||||
Sys.pstep('Random mode', d, c)
|
||||
|
||||
|
||||
@Log()
|
||||
|
@ -562,7 +530,9 @@ class Kirmah:
|
|||
@Log()
|
||||
def mpMergeFiles(self,hlstPaths, toPath, noRemove=False):
|
||||
""""""
|
||||
if not Sys.is_cli_cancel():
|
||||
d = Sys.datetime.now()
|
||||
c = not Sys.is_cli_cancel()
|
||||
if c:
|
||||
with Io.wfile(toPath) as fo:
|
||||
for fromPath in hlstPaths :
|
||||
with Io.rfile(fromPath) as fi :
|
||||
|
@ -573,25 +543,31 @@ class Kirmah:
|
|||
@Log()
|
||||
def unRandomFileContent(self, fromPath, toPath):
|
||||
""""""
|
||||
if not Sys.is_cli_cancel():
|
||||
d = Sys.datetime.now()
|
||||
c = not Sys.is_cli_cancel()
|
||||
if c:
|
||||
with Io.rfile(fromPath) as fi :
|
||||
with Io.wfile(toPath) as fo :
|
||||
fsize, chsize, size = Kirmah.getSizes(fromPath)
|
||||
lst, rest, piece, data = Kirmah.getRandomListFromKey(self.ck.key, size), chsize - fsize%chsize, b'', []
|
||||
if rest == chsize : rest = 0
|
||||
for i, pos in enumerate(lst):
|
||||
d = pos*chsize-(rest if pos >= lst[size-1] and pos!=0 else 0)
|
||||
if d >= 0 : fi.seek(d)
|
||||
dp = pos*chsize-(rest if pos >= lst[size-1] and pos!=0 else 0)
|
||||
if dp >= 0 : fi.seek(dp)
|
||||
piece = fi.read(chsize)
|
||||
if i == size-1 and rest > 0 :
|
||||
piece = piece[:-rest] if lst[i]==0 else piece[rest:]
|
||||
fo.write(piece[::-1])
|
||||
Sys.wlog(Sys.dprint())
|
||||
Sys.pstep('Random mode', d, c)
|
||||
|
||||
|
||||
@Log()
|
||||
def mixdata(self, fromPath, toPath, encryptNoise=False, label='kirmah', cpart=22):
|
||||
""""""
|
||||
if not Sys.is_cli_cancel():
|
||||
d = Sys.datetime.now()
|
||||
c = not Sys.is_cli_cancel()
|
||||
if c:
|
||||
hlst = self.ck.getHashList(label, cpart, False)
|
||||
hlst['data'] = sorted(hlst['data'], key=lambda hlst: hlst[0])
|
||||
size = Sys.getsize(fromPath)
|
||||
|
@ -607,9 +583,10 @@ class Kirmah:
|
|||
if encryptNoise :
|
||||
bdata, adata = self.encryptStr(bdata)[:row[2]], self.encryptStr(adata)[:row[3]]
|
||||
fi.seek(psize*row[5])
|
||||
d = fi.read(psize)
|
||||
fo.write(bdata[:row[2]] + d + adata[:row[3]])
|
||||
fo.write(bdata[:row[2]] + fi.read(psize) + adata[:row[3]])
|
||||
cp += 1
|
||||
Sys.wlog(Sys.dprint())
|
||||
Sys.pstep('Mix mode', d, c)
|
||||
|
||||
|
||||
@Log(Const.LOG_DEBUG)
|
||||
|
@ -634,7 +611,9 @@ class Kirmah:
|
|||
@Log()
|
||||
def unmixdata(self, fromPath, toPath, label='kirmah', cpart=22):
|
||||
""""""
|
||||
if not Sys.is_cli_cancel():
|
||||
d = Sys.datetime.now()
|
||||
c = not Sys.is_cli_cancel()
|
||||
if c:
|
||||
rsz, cp, hlst = 0, 0, self.ck.getHashList(label, cpart, True)
|
||||
for row in hlst['data']:
|
||||
rsz += row[2]+row[3]
|
||||
|
@ -652,12 +631,14 @@ class Kirmah:
|
|||
fi.seek(0,Io.SEEK_CUR)
|
||||
for row in hlst['data']:
|
||||
fi.seek(lbi[row[0]]+row[2])
|
||||
d = fi.read(psize if row[5] <= mxp else (rest if rest!=psize or (psize*cpart==size) else 0))
|
||||
dp = fi.read(psize if row[5] <= mxp else (rest if rest!=psize or (psize*cpart==size) else 0))
|
||||
cp += 1
|
||||
if fo.tell() + len(d) > size :
|
||||
fo.write(d[:rest])
|
||||
if fo.tell() + len(dp) > size :
|
||||
fo.write(dp[:rest])
|
||||
break
|
||||
fo.write(d)
|
||||
fo.write(dp)
|
||||
Sys.wlog(Sys.dprint())
|
||||
Sys.pstep('Mix mode', d, c)
|
||||
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
|
@ -822,7 +803,8 @@ class Kirmah:
|
|||
self.tmpPath2 = self.DIR_TEMP + Sys.basename(fromPath) + '.tmp2'
|
||||
compend, compstart = not decHeader['cmode']== KirmahHeader.COMP_NONE, decHeader['cmode']== KirmahHeader.COMP_ALL
|
||||
fp, tp = fromPath, self.tmpPath1
|
||||
|
||||
Sys.wlog(Sys.dprint())
|
||||
Sys.ptask('Compressing data')
|
||||
self.compress_start(fp, tp, compstart)
|
||||
fp, tp = tp, self.tmpPath2 if tp == self.tmpPath1 else self.tmpPath1
|
||||
return fp, tp, decHeader['rmode'], decHeader['mmode'], compend
|
||||
|
@ -834,16 +816,23 @@ class Kirmah:
|
|||
if not Sys.is_cli_cancel():
|
||||
if rmode :
|
||||
#~ self.mpRandomFileContent(fp, tp, 4)
|
||||
Sys.wlog(Sys.dprint())
|
||||
Sys.ptask('Randomizing data')
|
||||
self.randomFileContent(fp, tp)
|
||||
fp, tp = tp, self.tmpPath2 if tp == self.tmpPath1 else self.tmpPath1
|
||||
|
||||
if mmode :
|
||||
Sys.wlog(Sys.dprint())
|
||||
Sys.ptask('Mixing data')
|
||||
self.mixdata(fp, tp, True)
|
||||
fp, tp = tp, self.tmpPath2 if tp == self.tmpPath1 else self.tmpPath1
|
||||
|
||||
Sys.wlog(Sys.dprint())
|
||||
Sys.ptask('Compressing data')
|
||||
self.compress_end(fp, toPath, compend)
|
||||
|
||||
# clean tmp files
|
||||
Sys.wlog(Sys.dprint())
|
||||
Sys.ptask('Cleaning')
|
||||
try :
|
||||
Sys.removeFile(self.tmpPath1)
|
||||
Sys.removeFile(self.tmpPath2)
|
||||
|
@ -870,26 +859,31 @@ class Kirmah:
|
|||
|
||||
|
||||
@Log()
|
||||
def mproc_encode_part(self, id, lock=None):
|
||||
def mproc_encode_part(self, id, event=None):
|
||||
""""""
|
||||
if not Sys.is_cli_cancel():
|
||||
mpfile, mpfilenc = self.KMP_FILE+'_'+str(Sys.g.MAIN_PROC)+'_'+str(id), self.KMP_FILE+'enc_'+str(Sys.g.MAIN_PROC)+'_'+str(id)
|
||||
self.encryptToFile(mpfile, mpfilenc, self.getSubStartIndice(id), lock)
|
||||
self.encryptToFile(mpfile, mpfilenc, self.getSubStartIndice(id), event)
|
||||
Sys.removeFile(mpfile)
|
||||
|
||||
|
||||
@Log()
|
||||
def encrypt_mproc(self, fp, tp, nproc=1):
|
||||
""""""
|
||||
if not Sys.is_cli_cancel():
|
||||
Sys.wlog(Sys.dprint())
|
||||
Sys.ptask('Encrypting data')
|
||||
d = Sys.datetime.now()
|
||||
c = not Sys.is_cli_cancel()
|
||||
if c:
|
||||
if nproc == 1 :
|
||||
self.encryptToFile(fp, tp)
|
||||
else :
|
||||
hlstPaths = self.prepare_mproc_encode(fp, nproc)
|
||||
mg = Manager(self.mproc_encode_part, nproc, None, Sys.g.MPRLOCK)
|
||||
mg = Manager(self.mproc_encode_part, nproc, None, Sys.g.MPEVENT)
|
||||
mg.run()
|
||||
self.mpMergeFiles(hlstPaths, tp)
|
||||
|
||||
Sys.wlog(Sys.dprint())
|
||||
Sys.pstep('Encrypt data', d, c)
|
||||
|
||||
@Log()
|
||||
def encrypt(self, fromPath, toPath, nproc=1, header=None):
|
||||
|
@ -926,13 +920,19 @@ class Kirmah:
|
|||
compend, compstart = not decHeader['cmode']== KirmahHeader.COMP_NONE, decHeader['cmode']== KirmahHeader.COMP_ALL
|
||||
fp, tp = fromPath, self.tmpPath1
|
||||
|
||||
Sys.wlog(Sys.dprint())
|
||||
Sys.ptask('Uncompressing data')
|
||||
self.uncompress_end(fp, tp, compend)
|
||||
fp, tp = tp, self.tmpPath2 if tp == self.tmpPath1 else self.tmpPath1
|
||||
|
||||
if decHeader['mmode'] :
|
||||
Sys.wlog(Sys.dprint())
|
||||
Sys.ptask('Sorting data')
|
||||
self.unmixdata(fp, tp)
|
||||
fp, tp = tp, self.tmpPath2 if tp == self.tmpPath1 else self.tmpPath1
|
||||
if decHeader['rmode'] :
|
||||
Sys.wlog(Sys.dprint())
|
||||
Sys.ptask('Reordering data')
|
||||
self.unRandomFileContent(fp, tp)
|
||||
fp, tp = tp, self.tmpPath2 if tp == self.tmpPath1 else self.tmpPath1
|
||||
return fp, tp, compstart
|
||||
|
@ -942,7 +942,11 @@ class Kirmah:
|
|||
def decrypt_sp_end(self, fromPath, toPath, compstart):
|
||||
""""""
|
||||
if not Sys.is_cli_cancel():
|
||||
Sys.wlog(Sys.dprint())
|
||||
Sys.ptask('Uncompressing data')
|
||||
self.uncompress_start(fromPath, toPath, compstart)
|
||||
Sys.wlog(Sys.dprint())
|
||||
Sys.ptask('Cleaning')
|
||||
try :
|
||||
Sys.removeFile(self.tmpPath1)
|
||||
Sys.removeFile(self.tmpPath2)
|
||||
|
@ -953,14 +957,20 @@ class Kirmah:
|
|||
@Log()
|
||||
def decrypt_mproc(self, fromPath, toPath, nproc=1):
|
||||
""""""
|
||||
if not Sys.is_cli_cancel():
|
||||
Sys.wlog(Sys.dprint())
|
||||
Sys.ptask('Decrypting data')
|
||||
d = Sys.datetime.now()
|
||||
c = not Sys.is_cli_cancel()
|
||||
if c:
|
||||
if nproc == 1 :
|
||||
self.decryptToFile(fromPath, toPath)
|
||||
else :
|
||||
hlstPaths = self.prepare_mproc_decode(fromPath, nproc)
|
||||
mg = Manager(self.mproc_decode_part, nproc, None, Sys.g.MPRLOCK)
|
||||
mg = Manager(self.mproc_decode_part, nproc, None, Sys.g.MPEVENT)
|
||||
mg.run()
|
||||
self.mpMergeFiles(hlstPaths, toPath)
|
||||
Sys.wlog(Sys.dprint())
|
||||
Sys.pstep('Decrypt data', d, c)
|
||||
|
||||
|
||||
@Log()
|
||||
|
@ -985,11 +995,11 @@ class Kirmah:
|
|||
|
||||
|
||||
@Log()
|
||||
def mproc_decode_part(self, id):
|
||||
def mproc_decode_part(self, id, event=None):
|
||||
""""""
|
||||
if not Sys.is_cli_cancel():
|
||||
mpfile, mpfiledec = self.KMP_FILE+'_'+str(Sys.g.MAIN_PROC)+'_'+str(id), self.KMP_FILE+'dec_'+str(Sys.g.MAIN_PROC)+'_'+str(id)
|
||||
self.decryptToFile(mpfile, mpfiledec, self.getSubStartIndice(id))
|
||||
self.decryptToFile(mpfile, mpfiledec, self.getSubStartIndice(id), event)
|
||||
Sys.removeFile(mpfile)
|
||||
|
||||
|
||||
|
|
|
@ -39,7 +39,6 @@ from time import time, sleep
|
|||
from getpass import getuser as getUserLogin
|
||||
from mmap import mmap
|
||||
from math import ceil
|
||||
from threading import Thread, Event, Timer, Condition, RLock, current_thread, get_ident, enumerate as thread_enum
|
||||
|
||||
from kirmah.crypt import KeyGen, Kirmah, KirmahHeader, ConfigKey, BadKeyException, b2a_base64, a2b_base64, hash_sha256_file
|
||||
from kirmah.app import KirmahApp, FileNotFoundException, FileNeedOverwriteException
|
||||
|
@ -47,7 +46,7 @@ from kirmah.ui import Gui, CliThread
|
|||
from kirmah import conf
|
||||
from psr.sys import Sys, Io, Const
|
||||
from psr.log import Log
|
||||
from psr.mproc import Manager, Lock
|
||||
from psr.mproc import Manager
|
||||
import pdb
|
||||
|
||||
|
||||
|
@ -117,6 +116,7 @@ class AppGui(Gui):
|
|||
cbt = self.get('comboboxtext2')
|
||||
cbt.connect("changed", self.on_logging_changed)
|
||||
tree_iter = cbt.get_model().get_iter_first()
|
||||
tree_iter = cbt.get_model().get_iter_from_string('4')
|
||||
cbt.set_active_iter(tree_iter)
|
||||
Sys.clear()
|
||||
Sys.dprint('INIT UI')
|
||||
|
@ -135,7 +135,7 @@ class AppGui(Gui):
|
|||
return thread
|
||||
cliargs = ['kirmah-cli.py', 'split', '-df', '/media/Hermes/webbakup/The Raven.avi', '-z', '-r', '-m', '-o', '/home/dev/git_repos/kirmah2.15/The Raven.avi.kmh']
|
||||
cliargs = self.app.getCall()
|
||||
self.thkmh = getKmhThread(self.thread_finished, self.thread_interrupted, self.thread_progress, None, cliargs)
|
||||
self.thkmh = getKmhThread(self.thread_finished, self.thread_interrupted, self.thread_progress, None, cliargs, Sys.g.MPEVENT)
|
||||
self.thkmh.start()
|
||||
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@ from gi.repository.Gtk import AboutDialog, Builder, main as main_enter,
|
|||
from gi.repository.GdkPixbuf import Pixbuf
|
||||
from gi.repository.GObject import threads_init, GObject, idle_add, SIGNAL_RUN_LAST, TYPE_NONE, TYPE_STRING, TYPE_FLOAT, TYPE_BOOLEAN
|
||||
from threading import Thread, current_thread, enumerate as thread_enum
|
||||
from multiprocessing import Event
|
||||
from psr.sys import Sys, Io, Const
|
||||
from psr.log import Log
|
||||
from kirmah import conf
|
||||
|
@ -317,17 +318,18 @@ class CliThread(Thread, IdleObject):
|
|||
|
||||
|
||||
@Log(Const.LOG_DEBUG)
|
||||
def __init__(self, rwargs):
|
||||
def __init__(self, rwargs, event):
|
||||
Thread.__init__(self)
|
||||
IdleObject.__init__(self)
|
||||
self.setName('CliThread')
|
||||
self.cliargs = rwargs
|
||||
|
||||
self.event = event
|
||||
|
||||
@Log(Const.LOG_DEBUG)
|
||||
def run(self):
|
||||
""""""
|
||||
self.cancelled = False
|
||||
Sys.g.MPEVENT.clear()
|
||||
print(Sys.g.LOG_LEVEL)
|
||||
Cli('./', Sys.getpid(), self.cliargs, self, Sys.g.LOG_LEVEL)
|
||||
self.emit("completed")
|
||||
|
@ -346,6 +348,7 @@ class CliThread(Thread, IdleObject):
|
|||
cancellation logic
|
||||
"""
|
||||
self.cancelled = True
|
||||
self.event.set()
|
||||
|
||||
|
||||
@Log(Const.LOG_NEVER)
|
||||
|
|
224
psr/cli.py
Normal file
224
psr/cli.py
Normal file
|
@ -0,0 +1,224 @@
|
|||
# !/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
# kirmah.cli.py
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
#
|
||||
# software : Kirmah <http://kirmah.sourceforge.net/>
|
||||
# version : 2.17
|
||||
# date : 2013
|
||||
# licence : GPLv3.0 <http://www.gnu.org/licenses/>
|
||||
# author : a-Sansara <[a-sansara]at[clochardprod]dot[net]>
|
||||
# copyright : pluie.org <http://www.pluie.org/>
|
||||
#
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
#
|
||||
# This file is part of Kirmah.
|
||||
#
|
||||
# Kirmah is free software (free as in speech) : you can redistribute it
|
||||
# and/or modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the License,
|
||||
# or (at your option) any later version.
|
||||
#
|
||||
# Kirmah is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
# more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Kirmah. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# ~~ module cli ~~
|
||||
|
||||
from optparse import OptionParser, OptionGroup
|
||||
from psr.sys import Sys, Io, Const, init
|
||||
from psr.log import Log
|
||||
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# ~~ class TinyParser ~~
|
||||
|
||||
class TinyParser(OptionParser):
|
||||
|
||||
|
||||
def format_description(self, formatter):
|
||||
""""""
|
||||
return self.description
|
||||
|
||||
|
||||
def format_epilog(self, formatter):
|
||||
""""""
|
||||
return self.epilog
|
||||
|
||||
|
||||
def error(self, errMsg, errData=None):
|
||||
""""""
|
||||
self.print_usage('')
|
||||
AbstractCli.error_cmd((errMsg,))
|
||||
|
||||
|
||||
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# ~~ class AbstractConf ~~
|
||||
|
||||
class YourConf():
|
||||
|
||||
PRG_NAME = 'your-program'
|
||||
PRG_VERS = '1.0'
|
||||
PRG_AUTHOR = 'you'
|
||||
PRG_LICENSE = 'GNU GPL v3'
|
||||
PRG_COPY = 'company'
|
||||
PRG_CLI_NAME = 'your-cli-program'
|
||||
PRG_DESC = 'your desc'
|
||||
|
||||
# you must provide a global conf object
|
||||
|
||||
prgconf = YourConf()
|
||||
|
||||
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# ~~ class AbstractCli ~~
|
||||
|
||||
class AbstractCli():
|
||||
|
||||
conf = YourConf()
|
||||
|
||||
def __init__(self, prgconf=None, *args, **kwargs):
|
||||
""""""
|
||||
if not Sys.isUnix : Const.LINE_SEP_CHAR = '-'
|
||||
AbstractCli.conf = prgconf
|
||||
self.parser = TinyParser()
|
||||
self.parser.print_help = AbstractCli.print_help
|
||||
self.parser.print_usage = AbstractCli.print_usage
|
||||
|
||||
self.parser.add_option('-v', '--version' , action='store_true', default=False)
|
||||
self.parser.add_option('-d', '--debug' , action='store_true', default=False)
|
||||
self.parser.add_option('-f', '--force' , action='store_true', default=False)
|
||||
self.parser.add_option('-q', '--quiet' , action='store_true', default=False)
|
||||
|
||||
self.parser.add_option('--no-color' , action='store_true' , default=False)
|
||||
|
||||
|
||||
@staticmethod
|
||||
def error_cmd(data):
|
||||
""""""
|
||||
AbstractCli.print_usage('')
|
||||
Sys.dprint()
|
||||
Sys.pwarn(data, True)
|
||||
AbstractCli.exit(1)
|
||||
|
||||
|
||||
@staticmethod
|
||||
def exit(code):
|
||||
""""""
|
||||
if Sys.isUnix() : Sys.exit(code)
|
||||
|
||||
|
||||
@staticmethod
|
||||
def print_header():
|
||||
""""""
|
||||
a = AbstractCli.printLineSep(Const.LINE_SEP_CHAR,Const.LINE_SEP_LEN)
|
||||
b = AbstractCli.printHeaderTitle(AbstractCli.conf.PRG_CLI_NAME)
|
||||
c = AbstractCli.printHeaderPart('version' ,AbstractCli.conf.PRG_VERS)
|
||||
d = AbstractCli.printHeaderPart('author' ,AbstractCli.conf.PRG_AUTHOR)
|
||||
e = AbstractCli.printHeaderPart('license' ,AbstractCli.conf.PRG_LICENSE)
|
||||
f = AbstractCli.printHeaderPart('copyright',AbstractCli.conf.PRG_COPY)
|
||||
Sys.print(' ', Sys.Clz.OFF)
|
||||
AbstractCli.printLineSep(Const.LINE_SEP_CHAR,Const.LINE_SEP_LEN)
|
||||
Sys.wlog(a)
|
||||
Sys.wlog(b + c + d + e + f )
|
||||
Sys.wlog(a)
|
||||
Sys.wlog(Sys.dprint())
|
||||
|
||||
|
||||
@staticmethod
|
||||
def printLineSep(sep,lenSep):
|
||||
""""""
|
||||
s = sep*lenSep
|
||||
Sys.print(s, Sys.CLZ_HEAD_LINE)
|
||||
return [(s, Const.CLZ_HEAD_SEP)]
|
||||
|
||||
|
||||
@staticmethod
|
||||
def printHeaderTitle(title):
|
||||
""""""
|
||||
s = ' == '+title+' == '
|
||||
Sys.print(s, Sys.CLZ_HEAD_APP, False, True)
|
||||
return [(s, Const.CLZ_HEAD_APP)]
|
||||
|
||||
|
||||
@staticmethod
|
||||
def printHeaderPart(label,value):
|
||||
""""""
|
||||
a, b, c = ' [',':' ,'] '
|
||||
Sys.print(a , Sys.CLZ_HEAD_SEP, False)
|
||||
Sys.print(label, Sys.CLZ_HEAD_KEY, False)
|
||||
Sys.print(b , Sys.CLZ_HEAD_SEP, False)
|
||||
Sys.print(value, Sys.CLZ_HEAD_VAL, False)
|
||||
Sys.print(c , Sys.CLZ_HEAD_SEP, False)
|
||||
return [(a,Const.CLZ_HEAD_SEP),(label,Const.CLZ_HEAD_KEY),(b,Const.CLZ_HEAD_SEP),(value,Const.CLZ_HEAD_VAL),(c,Const.CLZ_HEAD_SEP)]
|
||||
|
||||
|
||||
@staticmethod
|
||||
def print_version(data):
|
||||
""""""
|
||||
AbstractCli.print_header()
|
||||
|
||||
|
||||
@staticmethod
|
||||
def print_options():
|
||||
""""""
|
||||
Sys.dprint('\n')
|
||||
AbstractCli.printLineSep(Const.LINE_SEP_CHAR,Const.LINE_SEP_LEN)
|
||||
|
||||
Sys.print(' MAIN OPTIONS :\n' , Sys.CLZ_HELP_CMD)
|
||||
Sys.print(' '*4+'-v'.ljust(13,' ')+', --version' , Sys.CLZ_HELP_ARG)
|
||||
Sys.print(' '*50+'display programm version' , Sys.CLZ_HELP_ARG_INFO)
|
||||
Sys.print(' '*4+'-d'.ljust(13,' ')+', --debug' , Sys.CLZ_HELP_ARG)
|
||||
Sys.print(' '*50+'enable debug mode' , Sys.CLZ_HELP_ARG_INFO)
|
||||
Sys.print(' '*4+'-f'.ljust(13,' ')+', --force' , Sys.CLZ_HELP_ARG)
|
||||
Sys.print(' '*50+'force rewriting existing files without alert' , Sys.CLZ_HELP_ARG_INFO)
|
||||
Sys.print(' '*4+'-q'.ljust(13,' ')+', --quiet' , Sys.CLZ_HELP_ARG)
|
||||
Sys.print(' '*50+'don\'t print status messages to stdout' , Sys.CLZ_HELP_ARG_INFO)
|
||||
Sys.print(' '*4+'-h'.ljust(13,' ')+', --help' , Sys.CLZ_HELP_ARG)
|
||||
Sys.print(' '*50+'display help' , Sys.CLZ_HELP_ARG_INFO)
|
||||
|
||||
Sys.dprint('\n')
|
||||
Sys.print(' KEY OPTIONS :\n' , Sys.CLZ_HELP_CMD)
|
||||
Sys.print(' '*4+'-a ' , Sys.CLZ_HELP_ARG, False)
|
||||
Sys.print('VALUE'.ljust(10,' ') , Sys.CLZ_HELP_PARAM, False)
|
||||
Sys.print(', --bind_opt_a'.ljust(18,' ') , Sys.CLZ_HELP_ARG, False)
|
||||
Sys.print('VALUE'.ljust(10,' ') , Sys.CLZ_HELP_PARAM)
|
||||
Sys.print(' '*50+'description option a' , Sys.CLZ_HELP_ARG_INFO)
|
||||
Sys.print(' '*4+'-b ' , Sys.CLZ_HELP_ARG, False)
|
||||
Sys.print('VALUE'.ljust(10,' ') , Sys.CLZ_HELP_PARAM, False)
|
||||
Sys.print(', --bind_opt_b'.ljust(18,' ') , Sys.CLZ_HELP_ARG, False)
|
||||
Sys.print('VALUE'.ljust(10,' ') , Sys.CLZ_HELP_PARAM)
|
||||
Sys.print(' '*50+'description option b' , Sys.CLZ_HELP_ARG_INFO)
|
||||
|
||||
|
||||
@staticmethod
|
||||
def print_usage(data, withoutHeader=False):
|
||||
""""""
|
||||
if not withoutHeader : AbstractCli.print_header()
|
||||
|
||||
Sys.print(' USAGE :\n' , Sys.CLZ_HELP_CMD)
|
||||
Sys.print(' '+AbstractCli.conf.PRG_CLI_NAME+' ' , Sys.CLZ_HELP_PRG, False)
|
||||
Sys.print('help ' , Sys.CLZ_HELP_CMD)
|
||||
|
||||
Sys.print(' '+AbstractCli.conf.PRG_CLI_NAME+' ' , Sys.CLZ_HELP_PRG, False)
|
||||
Sys.print('cmd ' , Sys.CLZ_HELP_CMD, False)
|
||||
Sys.print('[ -a ' , Sys.CLZ_HELP_ARG, False)
|
||||
Sys.print('{' , Sys.CLZ_HELP_PARAM, False)
|
||||
Sys.print('param_a' , Sys.CLZ_HELP_PARAM, False)
|
||||
Sys.print('}' , Sys.CLZ_HELP_PARAM, False)
|
||||
Sys.print(' -b ' , Sys.CLZ_HELP_ARG, False)
|
||||
Sys.print('{' , Sys.CLZ_HELP_PARAM, False)
|
||||
Sys.print('param_b' , Sys.CLZ_HELP_PARAM, False)
|
||||
Sys.print('}' , Sys.CLZ_HELP_PARAM, False)
|
||||
Sys.print(']' , Sys.CLZ_HELP_ARG)
|
||||
|
||||
|
||||
@staticmethod
|
||||
def print_help():
|
||||
""""""
|
|
@ -102,7 +102,7 @@ class Log:
|
|||
if t is not None :
|
||||
bind_data += Sys.pdate(t.timetuple() if enter else Sys.datetime.now().timetuple(), isChildProc)
|
||||
|
||||
a, b, c, d, e = ('=> ' if enter else '<= '), '['+str(Sys.getpid())+']', ' '+sign+'(', Log._formatArgs(args), ') '
|
||||
a, b, c, d, e = ('=> ' if enter else '<= '), '['+str(Sys.getpid()).rjust(5,' ')+']', ' '+sign+'(', Log._formatArgs(args), ') '
|
||||
if not isChildProc :
|
||||
Sys.print(a , Sys.CLZ_IO , False)
|
||||
Sys.print(b , Sys.CLZ_PID if not isChildProc else Sys.CLZ_CPID, False)
|
||||
|
|
22
psr/mproc.py
22
psr/mproc.py
|
@ -31,7 +31,7 @@
|
|||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# ~~ module mproc ~~
|
||||
|
||||
from multiprocessing import Process, current_process, Pipe, Lock
|
||||
from multiprocessing import Process, current_process, Pipe
|
||||
from multiprocessing.connection import wait
|
||||
from threading import current_thread
|
||||
from psr.sys import Sys, Const, init
|
||||
|
@ -43,22 +43,22 @@ from psr.log import Log
|
|||
class Worker:
|
||||
|
||||
@Log(Const.LOG_BUILD)
|
||||
def __init__(self, appname, debug, gui, color, loglvl, ppid, lock, id, wp, delay, task, *args, **kwargs):
|
||||
|
||||
def __init__(self, appname, debug, gui, color, loglvl, ppid, event, id, wp, delay, task, *args, **kwargs):
|
||||
def mptask(id, *args, **kwargs):
|
||||
Sys.sendMainProcMsg(Manager.MSG_INIT, None)
|
||||
otask = task(id=id, lock=lock, *args, **kwargs)
|
||||
otask = task(id=id, event=event, *args, **kwargs)
|
||||
Sys.sendMainProcMsg(Manager.MSG_END, None)
|
||||
return otask
|
||||
|
||||
init(appname, debug, ppid, color, loglvl)
|
||||
Sys.g.WPIPE = wp
|
||||
Sys.g.CPID = id
|
||||
Sys.g.GUI = gui
|
||||
Sys.g.RLOCK = lock
|
||||
Sys.g.WPIPE = wp
|
||||
Sys.g.CPID = id
|
||||
Sys.g.GUI = gui
|
||||
# initialize child process event with parent process event
|
||||
Sys.g.MPEVENT = event
|
||||
if delay : Sys.sleep(delay)
|
||||
mptask(id, *args, **kwargs)
|
||||
# don't directly close pipe 'cause of eventual loging
|
||||
# don't directly close pipe 'cause of eventual logging
|
||||
# pipe will auto close on terminating child process
|
||||
|
||||
|
||||
|
@ -81,7 +81,7 @@ class Manager:
|
|||
checktime = None
|
||||
|
||||
@Log(Const.LOG_UI)
|
||||
def __init__(self, task, nproc=2, delay=None, lock=None, *args, **kwargs):
|
||||
def __init__(self, task, nproc=2, delay=None, event=None, *args, **kwargs):
|
||||
""""""
|
||||
self.readers = []
|
||||
self.plist = []
|
||||
|
@ -92,7 +92,7 @@ class Manager:
|
|||
r, w = Pipe(duplex=False)
|
||||
self.readers.append(r)
|
||||
# (process, wpipe)
|
||||
p = Process(target=Worker, args=tuple([Sys.g.PRJ_NAME, Sys.g.DEBUG, Sys.g.GUI, Sys.g.COLOR_MODE, Sys.g.LOG_LEVEL, Sys.getpid(), lock, id, w, delay, task])+tuple(args), kwargs=kwargs)
|
||||
p = Process(target=Worker, args=tuple([Sys.g.PRJ_NAME, Sys.g.DEBUG, Sys.g.GUI, Sys.g.COLOR_MODE, Sys.g.LOG_LEVEL, Sys.getpid(), event, id, w, delay, task])+tuple(args), kwargs=kwargs)
|
||||
self.plist.append((p, w))
|
||||
|
||||
@Log(Const.LOG_APP)
|
||||
|
|
29
psr/sys.py
29
psr/sys.py
|
@ -34,7 +34,7 @@
|
|||
from psr.io import Io
|
||||
from psr.const import Const
|
||||
from threading import RLock
|
||||
from multiprocessing import RLock as MPRLock
|
||||
from multiprocessing import Event
|
||||
from queue import Queue
|
||||
|
||||
def init(name, debug, remote=False, color=True, loglvl=Const.LOG_DEFAULT):
|
||||
|
@ -64,6 +64,7 @@ class Sys:
|
|||
g.LOG_TIME = False
|
||||
g.LOG_LIM_ARG_LENGTH = Const.LOG_LIM_ARG_LENGTH
|
||||
g.QUIET = False
|
||||
g.COLOR_MODE = True
|
||||
g.RLOCK = None
|
||||
g.MPRLOCK = None
|
||||
g.WPIPE = None
|
||||
|
@ -75,7 +76,7 @@ class Sys:
|
|||
g.SIGNAL_RUN = 2
|
||||
g.GUI = False
|
||||
g.GUI_PRINT_STDOUT = True
|
||||
g.MPRLOCK = MPRLock()
|
||||
g.MPEVENT = Event()
|
||||
|
||||
|
||||
@staticmethod
|
||||
|
@ -129,18 +130,10 @@ class Sys:
|
|||
|
||||
|
||||
@staticmethod
|
||||
def is_cli_cancel(mprlock=None):
|
||||
def is_cli_cancel(event=None):
|
||||
""""""
|
||||
if mprlock is None :
|
||||
return Sys.g.THREAD_CLI is not None and Sys.g.THREAD_CLI.cancelled
|
||||
else :
|
||||
with mprlock :
|
||||
try:
|
||||
print(Sys.g.THREAD_CLI)
|
||||
print(Sys.g.THREAD_CLI.cancelled)
|
||||
except:
|
||||
pass
|
||||
return Sys.g.THREAD_CLI is not None and Sys.g.THREAD_CLI.cancelled
|
||||
c = Sys.g.THREAD_CLI is not None and Sys.g.THREAD_CLI.cancelled
|
||||
return c or (event is not None and event.is_set())
|
||||
|
||||
|
||||
@staticmethod
|
||||
|
@ -228,7 +221,7 @@ class Sys:
|
|||
|
||||
@staticmethod
|
||||
# never log this func -> maximum recursion
|
||||
def wlog(data):
|
||||
def wlog(data=[('','default')]):
|
||||
""""""
|
||||
if not Sys.is_cli_cancel():
|
||||
if Sys.g.LOG_QUEUE is not None :
|
||||
|
@ -269,8 +262,12 @@ class Sys:
|
|||
""""""
|
||||
if not dbcall :
|
||||
if not Sys.g.GUI or Sys.g.GUI_PRINT_STDOUT :
|
||||
with Sys.g.RLOCK :
|
||||
if not Sys.g.QUIET : print(d,end=end)
|
||||
if Sys.g.RLOCK is not None :
|
||||
with Sys.g.RLOCK :
|
||||
if not Sys.g.QUIET : print(d,end=end)
|
||||
else :
|
||||
if not Sys.g.QUIET :
|
||||
print(d,end=end)
|
||||
|
||||
bdata = [(d,Const.CLZ_DEFAULT)]
|
||||
return bdata
|
||||
|
|
|
@ -21,17 +21,17 @@
|
|||
<property name="step_increment">1</property>
|
||||
<property name="page_increment">10</property>
|
||||
</object>
|
||||
<object class="GtkFileFilter" id="filefilter1">
|
||||
<patterns>
|
||||
<pattern>*.key</pattern>
|
||||
</patterns>
|
||||
</object>
|
||||
<object class="GtkFileFilter" id="filefilter2">
|
||||
<patterns>
|
||||
<pattern>*.kmh</pattern>
|
||||
<pattern>*</pattern>
|
||||
</patterns>
|
||||
</object>
|
||||
<object class="GtkFileFilter" id="filefilter1">
|
||||
<patterns>
|
||||
<pattern>*.key</pattern>
|
||||
</patterns>
|
||||
</object>
|
||||
<object class="GtkFileFilter" id="filefilter3">
|
||||
<patterns>
|
||||
<pattern>*.*</pattern>
|
||||
|
@ -520,7 +520,6 @@
|
|||
<item translatable="yes">DISABLED</item>
|
||||
<item translatable="yes">LOG_ALL</item>
|
||||
<item translatable="yes">LOG_DEBUG</item>
|
||||
<item translatable="yes">LOG_WARN</item>
|
||||
<item translatable="yes">LOG_UI</item>
|
||||
<item translatable="yes">LOG_DEFAULT</item>
|
||||
</items>
|
||||
|
@ -845,7 +844,6 @@
|
|||
<child>
|
||||
<object class="GtkButton" id="button3">
|
||||
<property name="label" translatable="yes">show log</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="no_show_all">True</property>
|
||||
|
|
Loading…
Reference in New Issue
Block a user