From 0d67d7bbcb544c578d185485561f7ff524fed69a Mon Sep 17 00:00:00 2001 From: a-Sansara Date: Tue, 7 May 2013 02:43:02 +0200 Subject: [PATCH] refactoring and manage multiproc interruption --- kirmah/cli.py | 201 +++++++------------------ kirmah/cliapp.py | 29 ++-- kirmah/crypt.py | 190 ++++++++++++----------- kirmah/gui.py | 8 +- kirmah/ui.py | 7 +- psr/cli.py | 224 ++++++++++++++++++++++++++++ psr/log.py | 2 +- psr/mproc.py | 22 +-- psr/sys.py | 39 +++-- resources/kirmah/glade/kirmah.glade | 12 +- 10 files changed, 438 insertions(+), 296 deletions(-) create mode 100644 psr/cli.py diff --git a/kirmah/cli.py b/kirmah/cli.py index 96fa2a3..280da10 100755 --- a/kirmah/cli.py +++ b/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() diff --git a/kirmah/cliapp.py b/kirmah/cliapp.py index 5875882..7851747 100755 --- a/kirmah/cliapp.py +++ b/kirmah/cliapp.py @@ -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() @@ -199,30 +200,30 @@ class CliApp: p = 85 Sys.cli_emit_progress(p) Io.touch(kcf, times) - frav = 0.24 + frav = 0.24 for row in hlst['data']: p += frav - Io.touch(row[1]+km.EXT,times) + Io.touch(row[1]+km.EXT,times) Sys.cli_emit_progress(p) if self.o.outputfile is not None : d = Sys.datetime.now() if Sys.g.DEBUG : Sys.wlog(Sys.dprint()) - Sys.ptask('Preparing tark file') + Sys.ptask('Preparing tark file') hlst['data'] = sorted(hlst['data'], key=lambda lst: lst[4]) with tarfile.open(self.o.outputfile, mode='w') as tar: tar.add(kcf, arcname=Sys.basename(kcf)) p = 90 - for row in hlst['data']: + for row in hlst['data']: tar.add(row[1]+km.EXT, arcname=Sys.basename(row[1]+km.EXT)) p += frav Sys.cli_emit_progress(p) Sys.pstep('Packing destination file', d, True) d = Sys.datetime.now() Sys.ptask('Finalize') - for row in hlst['data']: + for row in hlst['data']: Io.removeFile(row[1]+km.EXT) p += frav - Sys.cli_emit_progress(p) + Sys.cli_emit_progress(p) Io.removeFile(kcf) Sys.pstep('Cleaning', d, True) @@ -235,11 +236,11 @@ class CliApp: #~ raise e elif not Sys.g.QUIET : Sys.pwarn((str(e),)) - + if not Sys.g.QUIET: - Sys.cli_emit_progress(100) + Sys.cli_emit_progress(100) self.onend_cmd('Kirmah Split', self.stime, done, self.o.outputfile) - + @Log(Const.LOG_DEBUG) @@ -253,7 +254,7 @@ class CliApp: toPath = None try : Sys.ptask() - + key = Io.get_data(self.o.keyfile) km = Kirmah(key) @@ -303,7 +304,7 @@ class CliApp: @Log(Const.LOG_DEBUG) def onend_cmd(self, title, stime, done, outputfile): - """""" + """""" s = Const.LINE_SEP_CHAR*Const.LINE_SEP_LEN Sys.print(s, Sys.CLZ_HEAD_LINE) Sys.wlog([(s, Const.CLZ_HEAD_SEP)]) diff --git a/kirmah/crypt.py b/kirmah/crypt.py index 9ff31f3..4b907ed 100755 --- a/kirmah/crypt.py +++ b/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,30 +859,35 @@ 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): - """""" + """""" if not Sys.is_cli_cancel(): fp, tp, rmode, mmode, compend = self.encrypt_sp_start(fromPath, toPath, header) @@ -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) diff --git a/kirmah/gui.py b/kirmah/gui.py index 726c961..832e922 100644 --- a/kirmah/gui.py +++ b/kirmah/gui.py @@ -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 @@ -115,8 +114,9 @@ class AppGui(Gui): tree_iter = cbt.get_model().get_iter_from_string('3') cbt.set_active_iter(tree_iter) cbt = self.get('comboboxtext2') - cbt.connect("changed", self.on_logging_changed) + 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() diff --git a/kirmah/ui.py b/kirmah/ui.py index a357752..4497bb8 100644 --- a/kirmah/ui.py +++ b/kirmah/ui.py @@ -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) diff --git a/psr/cli.py b/psr/cli.py new file mode 100644 index 0000000..e91b37c --- /dev/null +++ b/psr/cli.py @@ -0,0 +1,224 @@ +# !/usr/bin/env python +# -*- coding: utf-8 -*- +# kirmah.cli.py +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# +# software : Kirmah +# version : 2.17 +# date : 2013 +# licence : GPLv3.0 +# author : a-Sansara <[a-sansara]at[clochardprod]dot[net]> +# copyright : 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 . +# + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# ~~ 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(): + """""" diff --git a/psr/log.py b/psr/log.py index 89d9731..d209a06 100644 --- a/psr/log.py +++ b/psr/log.py @@ -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) diff --git a/psr/mproc.py b/psr/mproc.py index 1a954e6..daad5ad 100644 --- a/psr/mproc.py +++ b/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) diff --git a/psr/sys.py b/psr/sys.py index 94f4711..e089a96 100644 --- a/psr/sys.py +++ b/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,8 +64,9 @@ class Sys: g.LOG_TIME = False g.LOG_LIM_ARG_LENGTH = Const.LOG_LIM_ARG_LENGTH g.QUIET = False - g.RLOCK = None - g.MPRLOCK = None + g.COLOR_MODE = True + g.RLOCK = None + g.MPRLOCK = None g.WPIPE = None g.THREAD_CLI = None g.UI_AUTO_SCROLL = True @@ -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,19 +130,11 @@ 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 def isUnix(): @@ -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 : @@ -237,7 +230,7 @@ class Sys: Sys.cli_emit_progress() except Exception as e: Sys.pwarn((('wlog exception ',(str(e),Sys.CLZ_ERROR_PARAM), ' !'),), True) - + else : Sys.g.THREAD_CLI.stop() @@ -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 @@ -435,7 +432,7 @@ class Sys: Sys.wlog(bdata) if not noelf : Sys.wlog(Sys.dprint()) - + if exitOnFailed and not done: Sys.exit(1) diff --git a/resources/kirmah/glade/kirmah.glade b/resources/kirmah/glade/kirmah.glade index 031dfa1..cac33c0 100644 --- a/resources/kirmah/glade/kirmah.glade +++ b/resources/kirmah/glade/kirmah.glade @@ -21,17 +21,17 @@ 1 10 - - - *.key - - *.kmh * + + + *.key + + *.* @@ -520,7 +520,6 @@ DISABLED LOG_ALL LOG_DEBUG - LOG_WARN LOG_UI LOG_DEFAULT @@ -845,7 +844,6 @@ show log - True True True True