initial commit - kirmah-cli 2.1

This commit is contained in:
a-Sansara 2013-04-20 13:36:49 +02:00
commit a81cd2f13b
12 changed files with 3009 additions and 0 deletions

34
kirmah-cli.py Normal file
View File

@ -0,0 +1,34 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# #
# software : Kirmah <http://kirmah.sourceforge.net/> #
# version : 2.1 #
# date : 2013 #
# licence : GPLv3.0 <http://www.gnu.org/licenses/> #
# author : a-Sansara <http://www.a-sansara.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/>.
from psr.sys import init, Sys
from kirmah.cli import Cli
from kirmah import conf
init(conf.PRG_NAME, False)
Cli('.'+Sys.sep)

1
kirmah/__init__.py Executable file
View File

@ -0,0 +1 @@

523
kirmah/cli.py Executable file
View File

@ -0,0 +1,523 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# #
# software : Kirmah <http://kirmah.sourceforge.net/> #
# version : 2.1 #
# date : 2013 #
# licence : GPLv3.0 <http://www.gnu.org/licenses/> #
# author : a-Sansara <http://www.a-sansara.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/>.
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~ package cli ~~
from optparse import OptionParser, OptionGroup
import kirmah.conf as conf
from kirmah.cliapp import CliApp
from psr.sys import Sys
from psr.io import Io
LINE_SEP_LEN = 120
LINE_SEP_CHAR = ''
if not Sys.isUnix : LINE_SEP_CHAR = '-'
def printLineSep(sep,lenSep):
""""""
Sys.print(sep*lenSep, Sys.Clz.fgN0)
def printHeaderTitle(title):
""""""
Sys.print(' == '+title+' == ', Sys.Clz.BG4+Sys.Clz.fgB7, False, True)
def printHeaderPart(label,value):
""""""
Sys.print(' [' , Sys.Clz.fgB0, False)
Sys.print(label, Sys.Clz.fgB3, False)
Sys.print(':' , Sys.Clz.fgB0, False)
Sys.print(value, Sys.Clz.fgB4, False)
Sys.print('] ' , Sys.Clz.fgB0, False)
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,))
#~ Sys.exit(1)
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~ class Cli ~~
class Cli:
def __init__(self,path):
""""""
self.HOME = Sys.sep+'home'+Sys.sep+Sys.getUserLogin()+Sys.sep
self.DIRKEY = self.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)
#~ self.ini = util.IniFile(path+'impra.ini')
parser = _OptionParser()
parser.print_help = self.print_help
parser.print_usage = self.print_usage
gpData = OptionGroup(parser, '')
# metavar='<ARG1> <ARG2>', nargs=2
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)
gpData.add_option('-a', '--fullcompress' , action='store_true' )
gpData.add_option('-z', '--compress' , action='store_true' )
gpData.add_option('-Z', '--nocompress' , action='store_true' )
gpData.add_option('-r', '--random' , action='store_true' )
gpData.add_option('-R', '--norandom' , action='store_true' )
gpData.add_option('-m', '--mix' , action='store_true' )
gpData.add_option('-M', '--nomix' , action='store_true' )
gpData.add_option('-j', '--multiprocess' , action='store')
gpData.add_option('-k', '--keyfile' , action='store')
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)
(o, a) = parser.parse_args()
Sys.g.COLOR_MODE = not o.no_color
Sys.g.DEBUG = o.debug and not o.quiet
if not a:
try :
if not o.help :
self.error_cmd(('no command specified',))
else :
Sys.clear()
parser.print_help()
except :
self.error_cmd(('no command specified',))
else:
if a[0] == 'help':
Sys.clear()
parser.print_help()
elif a[0] in ['key','enc','dec','split','merge'] :
app = CliApp(self.HOME, path, self, a, o)
if a[0]=='key' :
app.onCommandKey()
else :
if not len(a)>1 :
self.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 !'),))
elif a[0]=='enc' : app.onCommandEnc()
elif a[0]=='dec' : app.onCommandDec()
elif a[0]=='split': app.onCommandSplit()
elif a[0]=='merge': app.onCommandMerge()
else :
self.error_cmd((('unknow command ',(a[0],Sys.Clz.fgb3)),))
if not o.quiet : Sys.dprint()
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):
""""""
printLineSep(LINE_SEP_CHAR,LINE_SEP_LEN)
printHeaderTitle(conf.PRG_CLI_NAME)
printHeaderPart('version' ,conf.PRG_VERS)
printHeaderPart('author' ,conf.PRG_AUTHOR)
printHeaderPart('license' ,conf.PRG_LICENSE)
printHeaderPart('copyright',conf.PRG_COPY)
Sys.print(' ', Sys.Clz.OFF)
printLineSep(LINE_SEP_CHAR,LINE_SEP_LEN)
Sys.dprint()
def print_version(self, data):
""""""
self.print_header()
def print_usage(self, data, withoutHeader=False):
""""""
if not withoutHeader : self.print_header()
Sys.print(' USAGE :\n' , Sys.Clz.fgB3)
Sys.print(' '+conf.PRG_CLI_NAME+' ' , Sys.Clz.fgb7, False)
Sys.print('help ' , Sys.Clz.fgB3)
Sys.print(' '+conf.PRG_CLI_NAME+' ' , Sys.Clz.fgb7, False)
Sys.print('key ' , Sys.Clz.fgB3, False)
Sys.print('[ -l ' , Sys.Clz.fgB3, False)
Sys.print('{' , Sys.Clz.fgB1, False)
Sys.print('length' , Sys.Clz.fgB1, False)
Sys.print('}' , Sys.Clz.fgB1, False)
Sys.print(' -o ' , Sys.Clz.fgB3, False)
Sys.print('{' , Sys.Clz.fgB1, False)
Sys.print('outputFile' , Sys.Clz.fgB1, False)
Sys.print('}' , Sys.Clz.fgB1, False)
Sys.print(']' , Sys.Clz.fgB3)
Sys.print(' '+conf.PRG_CLI_NAME+' ' , Sys.Clz.fgb7, False)
Sys.print('enc ' , Sys.Clz.fgB3, False)
Sys.print('{' , Sys.Clz.fgB1, False)
Sys.print('inputFile' , Sys.Clz.fgB1, False)
Sys.print('} ' , Sys.Clz.fgB1, False)
Sys.print('[' , Sys.Clz.fgB3, False)
Sys.print(' -z|Z|a -r|R -m|M -j ' , Sys.Clz.fgB3, False)
Sys.print('{' , Sys.Clz.fgB1, False)
Sys.print('numProcess' , Sys.Clz.fgB1, False)
Sys.print('}' , Sys.Clz.fgB1, False)
Sys.print(' -k ' , Sys.Clz.fgB3, False)
Sys.print('{' , Sys.Clz.fgB1, False)
Sys.print('keyFile' , Sys.Clz.fgB1, False)
Sys.print('}' , Sys.Clz.fgB1, False)
Sys.print(' -o ' , Sys.Clz.fgB3, False)
Sys.print('{' , Sys.Clz.fgB1, False)
Sys.print('outputFile' , Sys.Clz.fgB1, False)
Sys.print('}' , Sys.Clz.fgB1, False)
Sys.print(']' , Sys.Clz.fgB3)
Sys.print(' '+conf.PRG_CLI_NAME+' ' , Sys.Clz.fgb7, False)
Sys.print('dec ' , Sys.Clz.fgB3, False)
Sys.print('{' , Sys.Clz.fgB1, False)
Sys.print('inputFile' , Sys.Clz.fgB1, False)
Sys.print('} ' , Sys.Clz.fgB1, False)
Sys.print('[' , Sys.Clz.fgB3, False)
Sys.print(' -j ' , Sys.Clz.fgB3, False)
Sys.print('{' , Sys.Clz.fgB1, False)
Sys.print('numProcess' , Sys.Clz.fgB1, False)
Sys.print('}' , Sys.Clz.fgB1, False)
Sys.print(' -k ' , Sys.Clz.fgB3, False)
Sys.print('{' , Sys.Clz.fgB1, False)
Sys.print('keyFile' , Sys.Clz.fgB1, False)
Sys.print('}' , Sys.Clz.fgB1, False)
Sys.print(' -o ' , Sys.Clz.fgB3, False)
Sys.print('{' , Sys.Clz.fgB1, False)
Sys.print('outputFile' , Sys.Clz.fgB1, False)
Sys.print('}' , Sys.Clz.fgB1, False)
Sys.print(']' , Sys.Clz.fgB3)
Sys.print(' '+conf.PRG_CLI_NAME+' ' , Sys.Clz.fgb7, False)
Sys.print('split ' , Sys.Clz.fgB3, False)
Sys.print('{' , Sys.Clz.fgB1, False)
Sys.print('inputFile' , Sys.Clz.fgB1, False)
Sys.print('} ' , Sys.Clz.fgB1, False)
Sys.print('[' , Sys.Clz.fgB3, False)
Sys.print(' -p ' , Sys.Clz.fgB3, False)
Sys.print('{' , Sys.Clz.fgB1, False)
Sys.print('numParts' , Sys.Clz.fgB1, False)
Sys.print('}' , Sys.Clz.fgB1, False)
Sys.print(' -k ' , Sys.Clz.fgB3, False)
Sys.print('{' , Sys.Clz.fgB1, False)
Sys.print('keyFile' , Sys.Clz.fgB1, False)
Sys.print('}' , Sys.Clz.fgB1, False)
Sys.print(' -o ' , Sys.Clz.fgB3, False)
Sys.print('{' , Sys.Clz.fgB1, False)
Sys.print('tarOutputFile' , Sys.Clz.fgB1, False)
Sys.print('}' , Sys.Clz.fgB1, False)
Sys.print(']' , Sys.Clz.fgB3)
Sys.print(' '+conf.PRG_CLI_NAME+' ' , Sys.Clz.fgb7, False)
Sys.print('merge ' , Sys.Clz.fgB3, False)
Sys.print('{' , Sys.Clz.fgB1, False)
Sys.print('inputFile' , Sys.Clz.fgB1, False)
Sys.print('} ' , Sys.Clz.fgB1, False)
Sys.print('[' , Sys.Clz.fgB3, False)
Sys.print(' -k ' , Sys.Clz.fgB3, False)
Sys.print('{' , Sys.Clz.fgB1, False)
Sys.print('keyFile' , Sys.Clz.fgB1, False)
Sys.print('}' , Sys.Clz.fgB1, False)
Sys.print(' -o ' , Sys.Clz.fgB3, False)
Sys.print('{' , Sys.Clz.fgB1, False)
Sys.print('outputFile' , Sys.Clz.fgB1, False)
Sys.print('}' , Sys.Clz.fgB1, False)
Sys.print(']' , Sys.Clz.fgB3)
def print_options(self):
""""""
Sys.dprint('\n')
printLineSep(LINE_SEP_CHAR,LINE_SEP_LEN)
Sys.print(' MAIN OPTIONS :\n' , Sys.Clz.fgB3)
Sys.print(' '*4+'-v'.ljust(13,' ')+', --version' , Sys.Clz.fgB3)
Sys.print(' '*50+'display programm version' , Sys.Clz.fgB7)
Sys.print(' '*4+'-d'.ljust(13,' ')+', --debug' , Sys.Clz.fgB3)
Sys.print(' '*50+'enable debug mode' , Sys.Clz.fgB7)
Sys.print(' '*4+'-f'.ljust(13,' ')+', --force' , Sys.Clz.fgB3)
Sys.print(' '*50+'force rewriting existing files without alert' , Sys.Clz.fgB7)
Sys.print(' '*4+'-q'.ljust(13,' ')+', --quiet' , Sys.Clz.fgB3)
Sys.print(' '*50+'don\'t print status messages to stdout' , Sys.Clz.fgB7)
Sys.print(' '*4+'-h'.ljust(13,' ')+', --help' , Sys.Clz.fgB3)
Sys.print(' '*50+'display help' , Sys.Clz.fgB7)
Sys.dprint('\n')
Sys.print(' KEY OPTIONS :\n' , Sys.Clz.fgB3)
Sys.print(' '*4+'-l ' , Sys.Clz.fgB3, False)
Sys.print('LENGTH'.ljust(10,' ') , Sys.Clz.fgB1, False)
Sys.print(', --length'.ljust(18,' ') , Sys.Clz.fgB3, False)
Sys.print('LENGTH'.ljust(10,' ') , Sys.Clz.fgB1)
Sys.print(' '*50+'specified key length (128 to 4096 - default:1024)' , Sys.Clz.fgB7)
Sys.print(' '*4+'-o ' , Sys.Clz.fgB3, False)
Sys.print('FILE'.ljust(10,' ') , Sys.Clz.fgB1, False)
Sys.print(', --outputfile'.ljust(18,' ') , Sys.Clz.fgB3, False)
Sys.print('FILE'.ljust(10,' ') , Sys.Clz.fgB1)
Sys.print(' '*50+'specified key output filename' , Sys.Clz.fgB7)
Sys.dprint('\n')
Sys.print(' ENCRYPT OPTIONS :\n' , Sys.Clz.fgB3)
Sys.print(' '*4+'-a'.ljust(13,' ')+', --fullcompress' , Sys.Clz.fgB3)
Sys.print(' '*50+'enable full compression mode' , Sys.Clz.fgB7)
Sys.print(' '*4+'-z'.ljust(13,' ')+', --compress' , Sys.Clz.fgB3)
Sys.print(' '*50+'enable compression mode' , Sys.Clz.fgB7)
Sys.print(' '*4+'-Z'.ljust(13,' ')+', --nocompress' , Sys.Clz.fgB3)
Sys.print(' '*50+'disable compression mode' , Sys.Clz.fgB7)
Sys.print(' '*4+'-r'.ljust(13,' ')+', --random' , Sys.Clz.fgB3)
Sys.print(' '*50+'enable random mode' , Sys.Clz.fgB7)
Sys.print(' '*4+'-R'.ljust(13,' ')+', --norandom' , Sys.Clz.fgB3)
Sys.print(' '*50+'disable random mode' , Sys.Clz.fgB7)
Sys.print(' '*4+'-m'.ljust(13,' ')+', --mix' , Sys.Clz.fgB3)
Sys.print(' '*50+'enable mix mode' , Sys.Clz.fgB7)
Sys.print(' '*4+'-M'.ljust(13,' ')+', --nomix' , Sys.Clz.fgB3)
Sys.print(' '*50+'disable mix mode' , Sys.Clz.fgB7)
Sys.print(' '*4+'-j ' , Sys.Clz.fgB3, False)
Sys.print('COUNT'.ljust(10,' ') , Sys.Clz.fgB1, False)
Sys.print(', --multiprocess'.ljust(18,' ') , Sys.Clz.fgB3, False)
Sys.print('COUNT'.ljust(10,' ') , Sys.Clz.fgB1)
Sys.print(' '*50+'number of process for encryption (2 to 8)' , Sys.Clz.fgB7)
Sys.print(' '*4+'-k ' , Sys.Clz.fgB3, False)
Sys.print('FILE'.ljust(10,' ') , Sys.Clz.fgB1, False)
Sys.print(', --keyfile'.ljust(18,' ') , Sys.Clz.fgB3, False)
Sys.print('FILE'.ljust(10,' ') , Sys.Clz.fgB1)
Sys.print(' '*50+'key filename used to encrypt' , Sys.Clz.fgB7)
Sys.print(' '*4+'-o ' , Sys.Clz.fgB3, False)
Sys.print('FILE'.ljust(10,' ') , Sys.Clz.fgB1, False)
Sys.print(', --outputfile'.ljust(18,' ') , Sys.Clz.fgB3, False)
Sys.print('FILE'.ljust(10,' ') , Sys.Clz.fgB1)
Sys.print(' '*50+'specified encrypted output filename' , Sys.Clz.fgB7)
Sys.dprint('\n')
Sys.print(' DECRYPT OPTIONS :\n' , Sys.Clz.fgB3)
Sys.print(' '*4+'-j ' , Sys.Clz.fgB3, False)
Sys.print('COUNT'.ljust(10,' ') , Sys.Clz.fgB1, False)
Sys.print(', --multiprocess'.ljust(18,' ') , Sys.Clz.fgB3, False)
Sys.print('COUNT'.ljust(10,' ') , Sys.Clz.fgB1)
Sys.print(' '*50+'number of process for decryption (2 to 8)' , Sys.Clz.fgB7)
Sys.print(' '*4+'-k ' , Sys.Clz.fgB3, False)
Sys.print('FILE'.ljust(10,' ') , Sys.Clz.fgB1, False)
Sys.print(', --keyfile'.ljust(18,' ') , Sys.Clz.fgB3, False)
Sys.print('FILE'.ljust(10,' ') , Sys.Clz.fgB1)
Sys.print(' '*50+'key filename used to decrypt' , Sys.Clz.fgB7)
Sys.print(' '*4+'-o ' , Sys.Clz.fgB3, False)
Sys.print('FILE'.ljust(10,' ') , Sys.Clz.fgB1, False)
Sys.print(', --outputfile'.ljust(18,' ') , Sys.Clz.fgB3, False)
Sys.print('FILE'.ljust(10,' ') , Sys.Clz.fgB1)
Sys.print(' '*50+'specified decrypted output filename' , Sys.Clz.fgB7)
Sys.dprint('\n')
Sys.print(' SPLIT OPTIONS :\n' , Sys.Clz.fgB3)
Sys.print(' '*4+'-p ' , Sys.Clz.fgB3, False)
Sys.print('COUNT'.ljust(10,' ') , Sys.Clz.fgB1, False)
Sys.print(', --part'.ljust(18,' ') , Sys.Clz.fgB3, False)
Sys.print('COUNT'.ljust(10,' ') , Sys.Clz.fgB1)
Sys.print(' '*50+'count part to split' , Sys.Clz.fgB7)
Sys.print(' '*4+'-k ' , Sys.Clz.fgB3, False)
Sys.print('FILE'.ljust(10,' ') , Sys.Clz.fgB1, False)
Sys.print(', --keyfile'.ljust(18,' ') , Sys.Clz.fgB3, False)
Sys.print('FILE'.ljust(10,' ') , Sys.Clz.fgB1)
Sys.print(' '*50+'key filename used to split' , Sys.Clz.fgB7)
Sys.print(' '*4+'-o ' , Sys.Clz.fgB3, False)
Sys.print('TARFILE'.ljust(10,' ') , Sys.Clz.fgB1, False)
Sys.print(', --outputfile'.ljust(18,' ') , Sys.Clz.fgB3, False)
Sys.print('TARFILE'.ljust(10,' ') , Sys.Clz.fgB1)
Sys.print(' '*50+'specified tar output filename' , Sys.Clz.fgB7)
Sys.dprint('\n')
Sys.print(' MERGE OPTIONS :\n' , Sys.Clz.fgB3)
Sys.print(' '*4+'-k ' , Sys.Clz.fgB3, False)
Sys.print('FILE'.ljust(10,' ') , Sys.Clz.fgB1, False)
Sys.print(', --keyfile'.ljust(18,' ') , Sys.Clz.fgB3, False)
Sys.print('FILE'.ljust(10,' ') , Sys.Clz.fgB1)
Sys.print(' '*50+'key filename used to merge' , Sys.Clz.fgB7)
Sys.print(' '*4+'-o ' , Sys.Clz.fgB3, False)
Sys.print('FILE'.ljust(10,' ') , Sys.Clz.fgB1, False)
Sys.print(', --outputfile'.ljust(18,' ') , Sys.Clz.fgB3, False)
Sys.print('FILE'.ljust(10,' ') , Sys.Clz.fgB1)
Sys.print(' '*50+'specified decrypted output filename' , Sys.Clz.fgB7)
Sys.dprint('\n')
def print_help(self):
""""""
self.print_header()
Sys.print(conf.PRG_DESC, Sys.Clz.fgN1)
self.print_usage('',True)
self.print_options()
printLineSep(LINE_SEP_CHAR,LINE_SEP_LEN)
Sys.dprint()
Sys.print(' EXEMPLES :\n', Sys.Clz.fgB3)
CHQ = "'"
Sys.print(' '*4+'command key :', Sys.Clz.fgB3)
Sys.print(' '*8+'# generate a new crypted key of 2048 length', Sys.Clz.fgn7)
Sys.print(' '*8+conf.PRG_CLI_NAME+' ', Sys.Clz.fgB7, False)
Sys.print('key -l ', Sys.Clz.fgB3, False)
Sys.print('2048 ', Sys.Clz.fgB1)
Sys.print(' '*8+'# generate a new crypted key (default length is 1024) in a specified location', Sys.Clz.fgn7)
Sys.print(' '*8+conf.PRG_CLI_NAME+' ', Sys.Clz.fgB7, False)
Sys.print('key -o ', Sys.Clz.fgB3, False)
Sys.print(self.DIRKEY+'.myNewKey', Sys.Clz.fgB1)
printLineSep(LINE_SEP_CHAR,LINE_SEP_LEN)
Sys.print('\n'+' '*4+'command encrypt :', Sys.Clz.fgB3)
Sys.print(' '*8+'# encrypt specified file with default crypted key and default options', Sys.Clz.fgn7)
Sys.print(' '*8+conf.PRG_CLI_NAME+' ', Sys.Clz.fgB7, False)
Sys.print('enc ', Sys.Clz.fgB3, False)
Sys.print(self.HOME+'mySecretTextFile.txt', Sys.Clz.fgB1)
Sys.print(' '*8+'# encrypt specified file with specified crypted key (full compression, no random but mix mode)', Sys.Clz.fgn7)
Sys.print(' '*8+'# on specified output location', Sys.Clz.fgn7)
Sys.print(' '*8+conf.PRG_CLI_NAME+' ', Sys.Clz.fgB7, False)
Sys.print('enc ', Sys.Clz.fgB3, False)
Sys.print('mySecretTextFile.txt', Sys.Clz.fgB1, False)
Sys.print(' -aRm -k ' , Sys.Clz.fgB3, False)
Sys.print(self.DIRKEY+'.myNewKey', Sys.Clz.fgB1, False)
Sys.print(' -o ' , Sys.Clz.fgB3, False)
Sys.print('test.kmh', Sys.Clz.fgB1)
Sys.print(' '*8+'# encrypt specified file with default crypted key (no compression but random & mix mode and multiprocessing)', Sys.Clz.fgn7)
Sys.print(' '*8+conf.PRG_CLI_NAME+' ', Sys.Clz.fgB7, False)
Sys.print('enc ', Sys.Clz.fgB3, False)
Sys.print('myBigTextFile.txt', Sys.Clz.fgB1, False)
Sys.print(' -Zrm -j ' , Sys.Clz.fgB3, False)
Sys.print('4', Sys.Clz.fgB1)
printLineSep(LINE_SEP_CHAR,LINE_SEP_LEN)
Sys.print('\n'+' '*4+'command decrypt :', Sys.Clz.fgB3)
Sys.print(' '*8+'# decrypt specified file with default crypted key', Sys.Clz.fgn7)
Sys.print(' '*8+conf.PRG_CLI_NAME+' ', Sys.Clz.fgB7, False)
Sys.print('dec ', Sys.Clz.fgB3, False)
Sys.print(self.HOME+'mySecretFile.kmh', Sys.Clz.fgB1)
Sys.print(' '*8+'# decrypt specified file with specified crypted key on specified output location', Sys.Clz.fgn7)
Sys.print(' '*8+conf.PRG_CLI_NAME+' ', Sys.Clz.fgB7, False)
Sys.print('dec ', Sys.Clz.fgB3, False)
Sys.print('myEncryptedSecretFile.kmh', Sys.Clz.fgB1, False)
Sys.print(' -k ' , Sys.Clz.fgB3, False)
Sys.print(self.HOME+'.kirmah'+Sys.sep+'.myNewKey', Sys.Clz.fgB1, False)
Sys.print(' -o ' , Sys.Clz.fgB3, False)
Sys.print('myDecryptedSecretFile.txt', Sys.Clz.fgB1)
Sys.print(' '*8+'# decrypt specified file with default crypted key and multiprocessing', Sys.Clz.fgn7)
Sys.print(' '*8+conf.PRG_CLI_NAME+' ', Sys.Clz.fgB7, False)
Sys.print('dec ', Sys.Clz.fgB3, False)
Sys.print('myEncryptedSecretFile.kmh', Sys.Clz.fgB1, False)
Sys.print(' -j ' , Sys.Clz.fgB3, False)
Sys.print('4' , Sys.Clz.fgB1)
printLineSep(LINE_SEP_CHAR,LINE_SEP_LEN)
Sys.print('\n'+' '*4+'command split :', Sys.Clz.fgB3)
Sys.print(' '*8+'# split specified file with default crypted key', Sys.Clz.fgn7)
Sys.print(' '*8+conf.PRG_CLI_NAME+' ', Sys.Clz.fgB7, False)
Sys.print('split ', Sys.Clz.fgB3, False)
Sys.print(self.HOME+'myBigBinaryFile.avi', Sys.Clz.fgB1)
Sys.print(' '*8+'# split specified file on 55 parts with specified crypted key on specified output location', Sys.Clz.fgn7)
Sys.print(' '*8+conf.PRG_CLI_NAME+' ', Sys.Clz.fgB7, False)
Sys.print('split ', Sys.Clz.fgB3, False)
Sys.print('myBigBinaryFile.avi', Sys.Clz.fgB1, False)
Sys.print(' -p ' , Sys.Clz.fgB3, False)
Sys.print('55' , Sys.Clz.fgB1, False)
Sys.print(' -k ' , Sys.Clz.fgB3, False)
Sys.print(self.DIRKEY+'.myNewKey', Sys.Clz.fgB1, False)
Sys.print(' -o ' , Sys.Clz.fgB3, False)
Sys.print('myBigBinaryFile.encrypted', Sys.Clz.fgB1)
printLineSep(LINE_SEP_CHAR,LINE_SEP_LEN)
Sys.print('\n'+' '*4+'command merge :', Sys.Clz.fgB3)
Sys.print(' '*8+'# merge specified splitted file with default crypted key', Sys.Clz.fgn7)
Sys.print(' '*8+conf.PRG_CLI_NAME+' ', Sys.Clz.fgB7, False)
Sys.print('merge ', Sys.Clz.fgB3, False)
Sys.print(self.HOME+'6136bd1b53d84ecbad5380594eea7256176c19e0266c723ea2e982f8ca49922b.kcf', Sys.Clz.fgB1)
Sys.print(' '*8+'# merge specified tark splitted file with specified crypted key on specified output location', Sys.Clz.fgn7)
Sys.print(' '*8+conf.PRG_CLI_NAME+' ', Sys.Clz.fgB7, False)
Sys.print('merge ', Sys.Clz.fgB3, False)
Sys.print('myBigBinaryFile.encrypted.tark', Sys.Clz.fgB1, False)
Sys.print(' -k ' , Sys.Clz.fgB3, False)
Sys.print(self.DIRKEY+'.myNewKey', Sys.Clz.fgB1, False)
Sys.print(' -o ' , Sys.Clz.fgB3, False)
Sys.print('myBigBinaryFile.decrypted.avi', Sys.Clz.fgB1)
printLineSep(LINE_SEP_CHAR,LINE_SEP_LEN)
Sys.dprint()

297
kirmah/cliapp.py Executable file
View File

@ -0,0 +1,297 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# #
# software : Kirmah <http://kirmah.sourceforge.net/> #
# version : 2.1 #
# date : 2013 #
# licence : GPLv3.0 <http://www.gnu.org/licenses/> #
# author : a-Sansara <http://www.a-sansara.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/>.
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~ package cliapp ~~
import kirmah.conf as conf
from kirmah.crypt import KirmahHeader, Kirmah, BadKeyException, represents_int, KeyGen
from kirmah.kctrl import KCtrl
from psr.sys import Sys
from psr.io import Io
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~ class CliApp ~~
class CliApp:
def __init__(self, home, path, parser, a, o):
""""""
self.parser = parser
self.a = a
self.o = o
self.home = home
self.stime = Sys.datetime.now()
if not self.o.keyfile :
self.o.keyfile = self.home+'.kirmah'+Sys.sep+'.default.key'
def onCommandKey(self):
""""""
if int(self.o.length) >= 128 and int(self.o.length) <= 4096 :
self.parser.print_header()
if not self.o.outputfile : self.o.outputfile = self.home+'.kirmah'+Sys.sep+'.default.key'
kg = KeyGen(int(self.o.length))
done = True
if Io.file_exists(self.o.outputfile) and not self.o.force :
Sys.pwarn((('the key file ',(self.o.outputfile, Sys.Clz.fgb3), ' already exists !'),
'if you rewrite this file, all previous files encrypted with the corresponding key will be unrecoverable !'))
done = Sys.pask('Are you sure to rewrite this file')
self.stime = Sys.datetime.now()
if done :
Io.set_data(self.o.outputfile, kg.key)
Sys.pstep('Generate key file', self.stime, done)
if done :
Sys.print(' '*5+Sys.realpath(self.o.outputfile), Sys.Clz.fgB1, True)
else :
self.parser.error_cmd((('invalid option ',('-l, --length', Sys.Clz.fgb3), ' value (', ('128',Sys.Clz.fgb3),' to ', ('4096',Sys.Clz.fgb3),')'),))
def onCommandEnc(self):
""""""
done = True
if self.o.outputfile is None :
self.o.outputfile = Sys.basename(self.a[1])+Kirmah.EXT
d = self.getDefaultOption((self.o.compress,self.o.fullcompress,self.o.nocompress))
compress = (KirmahHeader.COMP_END if d == 0 or (d is None and Io.is_binary(self.a[1])) else (KirmahHeader.COMP_ALL if d==1 or d is None else KirmahHeader.COMP_NONE))
random = True if (self.o.random is None and self.o.norandom is None) or self.o.random else False
mix = True if (self.o.mix is None and self.o.nomix is None) or self.o.mix else False
if (self.o.multiprocess is not None and not represents_int(self.o.multiprocess)) or (not self.o.multiprocess is None and not(int(self.o.multiprocess)>=2 and int(self.o.multiprocess) <=8)) :
self.parser.error_cmd((('invalid option ',('-j, --multiprocess', Sys.Clz.fgb3), ' value (', ('2',Sys.Clz.fgb3),' to ', ('8',Sys.Clz.fgb3),')'),))
nproc = int(self.o.multiprocess) if not self.o.multiprocess is None and int(self.o.multiprocess)>=2 and int(self.o.multiprocess) <=8 else 1
if not self.o.quiet : self.parser.print_header()
if Io.file_exists(self.o.outputfile) and not self.o.force:
Sys.pwarn((('the file ',(self.o.outputfile, Sys.Clz.fgb3), ' already exists !'),))
done = Sys.pask('Are you sure to rewrite this file')
self.stime = Sys.datetime.now()
if done :
try :
if not self.o.quiet and not Sys.g.DEBUG : Sys.print(' Processing, please wait...\n', Sys.Clz.fgB2)
key = Io.get_data(self.o.keyfile)
km = Kirmah(key, None, compress, random, mix)
if nproc > 1 :
from gi.repository.Gdk import threads_enter, threads_leave
from gi.repository.GLib import threads_init
from gi.repository.Gtk import main as gtk_main, main_quit as gtk_quit
threads_init()
threads_enter()
kctrl = KCtrl(nproc, None)
kctrl.encrypt(self.a[1], self.o.outputfile, km, None, self.onend_mproc)
gtk_main()
threads_leave()
else :
km.encrypt(self.a[1],self.o.outputfile)
except Exception as e :
done = False
print(e)
pass
if not self.o.quiet :
self.onend_cmd('Encrypting file', self.stime, done, self.o.outputfile)
def onCommandDec(self):
""""""
done = True
if self.o.outputfile is None :
self.o.outputfile = self.a[1][:-4] if self.a[1][-4:] == Kirmah.EXT else self.a[1]
if not self.o.quiet : self.parser.print_header()
if Io.file_exists(self.o.outputfile) and not self.o.force:
Sys.pwarn((('the file ',(self.o.outputfile, Sys.Clz.fgb3), ' already exists !'),))
done = Sys.pask('Are you sure to rewrite this file')
self.stime = Sys.datetime.now()
if done :
try :
if (self.o.multiprocess is not None and not represents_int(self.o.multiprocess)) or (not self.o.multiprocess is None and not(int(self.o.multiprocess)>=2 and int(self.o.multiprocess) <=8)) :
self.parser.error_cmd((('invalid option ',('-j, --multiprocess', Sys.Clz.fgb3), ' value (', ('2',Sys.Clz.fgb3),' to ', ('8',Sys.Clz.fgb3),')'),))
nproc = int(self.o.multiprocess) if not self.o.multiprocess is None and int(self.o.multiprocess)>=2 and int(self.o.multiprocess) <=8 else 1
if not self.o.quiet and not Sys.g.DEBUG : Sys.print(' Processing, please wait...\n', Sys.Clz.fgB2)
key = Io.get_data(self.o.keyfile)
km = Kirmah(key)
if nproc > 1 :
from gi.repository.Gdk import threads_enter, threads_leave
from gi.repository.GLib import threads_init
from gi.repository.Gtk import main as gtk_main, main_quit as gtk_quit
threads_init()
threads_enter()
kctrl = KCtrl(nproc, None)
kctrl.decrypt(self.a[1], self.o.outputfile, km, self.onend_mproc)
gtk_main()
threads_leave()
else :
km.decrypt(self.a[1],self.o.outputfile)
except BadKeyException as e :
done = False
Sys.pwarn(('BadKeyException',))
if Sys.g.DEBUG :
raise e
if not self.o.quiet :
self.onend_cmd('Decrypting file', self.stime, done, self.o.outputfile)
def onCommandSplit(self):
""""""
done = True
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),')'),))
else : self.o.parts = int(self.o.parts)
if not self.o.quiet : self.parser.print_header()
if self.o.outputfile is not None :
if self.o.outputfile[-5:]!='.tark' : self.o.outputfile += '.tark'
if Io.file_exists(self.o.outputfile) and not self.o.force:
Sys.pwarn((('the file ',(self.o.outputfile, Sys.Clz.fgb3), ' already exists !'),))
done = Sys.pask('Are you sure to rewrite this file')
self.stime = Sys.datetime.now()
if done :
try :
if not self.o.quiet and not Sys.g.DEBUG : Sys.print(' Processing, please wait...\n', Sys.Clz.fgB2)
key = Io.get_data(self.o.keyfile)
km = Kirmah(key)
hlst = km.ck.getHashList(Sys.basename(self.a[1]), self.o.parts, True)
kcf = km.splitFile(self.a[1], hlst)
t = int(Sys.time())
times = (t,t)
Io.touch(kcf, times)
for row in hlst['data']:
Io.touch(row[1]+km.EXT,times)
if self.o.outputfile is not None :
import tarfile
hlst['data'] = sorted(hlst['data'], key=lambda lst: lst[4])
with tarfile.open(self.o.outputfile, mode='w') as tar:
tar.add(kcf)
Io.removeFile(kcf)
for row in hlst['data']:
tar.add(row[1]+km.EXT)
Io.removeFile(row[1]+km.EXT)
except Exception as e :
done = False
if Sys.g.DEBUG :
raise e
elif not self.o.quiet :
Sys.pwarn((str(e),))
if not self.o.quiet :
self.onend_cmd('Splitting file', self.stime, done, self.o.outputfile)
def onCommandMerge(self):
""""""
done = True
if not self.o.quiet : self.parser.print_header()
if done :
try :
if not self.o.quiet and not Sys.g.DEBUG : Sys.print(' Processing, please wait...\n', Sys.Clz.fgB2)
key = Io.get_data(self.o.keyfile)
km = Kirmah(key)
try:
import tarfile
with tarfile.open(self.a[1], mode='r') as tar:
path = Sys.dirname(self.o.outputfile) if self.o.outputfile is not None else '.'
tar.extractall(path=path)
for tarinfo in tar:
if tarinfo.isreg() and tarinfo.name[-4:]=='.kcf':
toPath = km.mergeFile(path+Sys.sep+tarinfo.name)
except :
pass
toPath = km.mergeFile(self.a[1])
except Exception as e :
done = False
if Sys.g.DEBUG :
raise e
elif not self.o.quiet :
Sys.pwarn((str(e),))
if not self.o.quiet :
self.onend_cmd('Merging file', self.stime, done, toPath)
def onend_mproc(self, tstart, done):
""""""
from gi.repository.Gtk import main_quit as gtk_quit
gtk_quit()
def getDefaultOption(self, args):
""""""
c = None
for i, a in enumerate(args) :
if a :
c = i
break
return c
def onend_cmd(self, title, stime, done, outputfile):
""""""
if Sys.g.DEBUG : Sys.dprint()
Sys.pstep(title, stime, done)
if done :
Sys.print(' '*5+Sys.realpath(outputfile), Sys.Clz.fgB1, False)
Sys.print(' ('+Sys.getFileSize(outputfile)+')', Sys.Clz.fgB3)

101
kirmah/conf.py Executable file
View File

@ -0,0 +1,101 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# #
# software : Kirmah <http://kirmah.sourceforge.net/> #
# version : 2.1 #
# date : 2013 #
# licence : GPLv3.0 <http://www.gnu.org/licenses/> #
# author : a-Sansara <http://www.a-sansara.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 conf ~~
from getpass import getuser as getUserLogin
PRG_NAME = 'Kirmah'
PRG_CLI_NAME = 'kirmah-cli'
PRG_VERS = '2.1'
PRG_AUTHOR = 'a-Sansara'
PRG_COPY = 'pluie.org 2013'
PRG_WEBSITE = 'http://kirmah.sourceforge.net'
PRG_LICENSE = 'GNU GPL v3'
PRG_LICENSE_PATH = 'gpl.txt'
PRG_LOGO_PATH = 'kirmah.png'
PRG_LOGO_ICON_PATH = 'kirmah_ico.png'
PRG_ABOUT_LOGO_SIZE = 160
PRG_ABOUT_COPYRIGHT = '(c) '+PRG_AUTHOR+' - '+PRG_COPY+' 2013'
PRG_ABOUT_COMMENTS = ''.join(['Kirmah simply encrypt/decrypt files','\n', 'license ',PRG_LICENSE])
PRG_DESC = """
Encryption with symmetric-key algorithm Kirmah.
three modes are available to encrypt :
- compression (full / disabled or only final step)
- random (simulate a random order - based on crypted key - to randomize data)
- mix (mix data according to a generated map - based on crypted key - with addition of noise)
Process is as follow :
for encryption :
file > [ compression > ] encryption > [randomiz data > mix data > compression > ] file.kmh
default options depends on file type (binary or text).
- binary files are compressed only at the end of process
- text files have a full compression mode
- random and mix modes are enabled on all files
for decryption :
file.kmh > [ uncompression > unmix data > unrandomiz data] > decryption > [uncompression > ] file
multiprocessing is avalaible for reducing encryption/decryption time.
for encrypt large binary files, a fastest alternative is possible :
the split command.
the split command consist on splitting file into severals parts (with noise addition) according to
a generated map based on the crypted key.
the map is fully encrypted as a configuration file (.kcf) which is required to merge all parts
the merge command is the opposite process.
"""
PRG_GLADE_PATH = 'kirmah.glade'
DEFVAL_NPROC = 2
DEFVAL_NPROC_MAX = 8
DEFVAL_NPROC_MIN = 2
DEFVAL_COMP = False
DEFVAL_ENCMODE = True
DEFVAL_MIXDATA = False
DEFVAL_USER_PATH = ''.join(['/home/', getUserLogin(), '/'])
DEFVAL_UKEY_PATH = ''.join([DEFVAL_USER_PATH, '.', PRG_NAME.lower(), '/'])
DEFVAL_UKEY_NAME = '.default.key'
DEFVAL_UKEY_LENGHT = 1024
DEFVAL_CRYPT_EXT = '.kmh'
DEBUG = True
UI_TRACE = True
PCOLOR = True

1015
kirmah/crypt.py Executable file

File diff suppressed because one or more lines are too long

111
kirmah/kctrl.py Executable file
View File

@ -0,0 +1,111 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# #
# software : Kirmah <http://kirmah.sourceforge.net/> #
# version : 2.1 #
# date : 2013 #
# licence : GPLv3.0 <http://www.gnu.org/licenses/> #
# author : a-Sansara <http://www.a-sansara.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/>.
from gi.repository.GObject import timeout_add
from psr.sys import Sys
from psr.mproc import Ctrl
from psr.decorate import log
from kirmah.crypt import Kirmah, ConfigKey, KeyGen, b2a_base64, a2b_base64, hash_sha256
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~ class KCtrl ~~
class KCtrl(Ctrl):
@log
def encrypt(self, fromPath, toPath, km, header=None, callback=None, timeout=50):
""""""
self.tstart = Sys.datetime.now()
self.km = km
self.callback = callback
self.fromPath = fromPath
self.toPath = toPath
if Sys.g.DEBUG : Sys.pcontent(' Encrypting file : '+self.fromPath+' ('+Sys.getFileSize(self.fromPath)+') by '+str(self.nproc)+' process')
if self.nproc < 2:
self.km.encrypt(self.fromPath, self.toPath, header)
self.on_end_mpenc()
else :
self.ppid = Sys.getpid()
self.fp, self.tp, self.rmode, self.mmode, self.compend = self.km.encrypt_sp_start(fromPath, toPath, header)
self.hsltPaths = self.km.prepare_mproc_encode(self.fp, self.nproc)
self.bind_task(self.mpenc)
self.start(timeout, None, self.on_end_mpenc)
@log
def decrypt(self, fromPath, toPath, km, callback=None, timeout=50):
""""""
self.tstart = Sys.datetime.now()
self.km = km
self.callback = callback
self.fromPath = fromPath
self.toPath = toPath
self.ppid = Sys.getpid()
if Sys.g.DEBUG : Sys.pcontent(' Decrypting file : '+self.fromPath+' ('+Sys.getFileSize(self.fromPath)+') by '+str(self.nproc)+' process')
if self.nproc < 2:
self.decrypt(fromPath, toPath)
self.on_end_mpdec()
else :
self.fp, self.tp, self.compstart = self.km.decrypt_sp_start(fromPath, toPath)
self.hsltPaths = self.km.prepare_mproc_decode(self.fp, self.nproc)
self.bind_task(self.mpdec)
self.start(50, None, self.on_end_mpdec)
#~ @log
def getSubStartIndice(self, id):
""""""
return sum([ len(x) for j, x in enumerate(self.data) if j < id ])%len(self.km.key)
@log
def mpenc(self, id):
""""""
self.km.mproc_encode_part(id, self.ppid)
@log
def mpdec(self, id):
""""""
self.km.mproc_decode_part(id, self.ppid)
@log
def on_end_mpdec(self):
""""""
if self.nproc > 1 :
self.km.mpMergeFiles(self.hsltPaths, self.tp)
self.km.decrypt_sp_end(self.tp, self.toPath, self.compstart)
if self.callback is not None : self.callback(self.tstart, True)
@log
def on_end_mpenc(self):
""""""
if self.nproc > 1 :
self.km.mpMergeFiles(self.hsltPaths, self.tp)
self.fp, self.tp = self.tp, self.km.tmpPath2 if self.tp == self.km.tmpPath1 else self.km.tmpPath1
self.km.encrypt_sp_end(self.fp, self.tp, self.toPath, self.rmode, self.mmode, self.compend)
if self.callback is not None : self.callback(self.tstart, True)

1
psr/__init__.py Executable file
View File

@ -0,0 +1 @@

111
psr/decorate.py Normal file
View File

@ -0,0 +1,111 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# #
# software : Kirmah <http://kirmah.sourceforge.net/> #
# version : 2.1 #
# date : 2013 #
# licence : GPLv3.0 <http://www.gnu.org/licenses/> #
# author : a-Sansara <http://www.a-sansara.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/>.
try :
from inspect import signature
except :
# < python 3.3
signature = None
pass
from psr.sys import Sys
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~ module decorate ~~
def _logs(sign, t=None, enter=True, wColor=False, args=''):
""""""
if Sys.g.DEBUG :
hasBind = Sys.g_has_ui_bind()
if hasBind : bind_data = []
if t is not None :
bd = Sys.pdate(t.timetuple(), True)
if hasBind: bind_data += bd
a, b, c, d, e = ('=> ' if enter else '<= '), '['+str(Sys.getpid())+']', ' '+sign+'(', _formatArgs(args), ') '
Sys.print(a , Sys.CLZ_IO , False)
Sys.print(b , Sys.CLZ_IO if not Sys.g_is_main_proc() else Sys.CLZ_SEC, False)
Sys.print(c , Sys.CLZ_FUNC, False)
Sys.print(d , Sys.CLZ_ARGS, False)
Sys.print(e , Sys.CLZ_FUNC, False)
if hasBind:
bd = [(a, 'io'),(b, 'pid' if not Sys.g_is_main_proc() else 'ppid'),(c , 'cfunc' if not Sys.g_is_main_proc() else 'func'),(d , 'args'),(e , 'cfunc' if not Sys.g_is_main_proc() else 'func')]
bind_data += bd
if not enter and t is not None :
bd = Sys.pdelta(t, '', True)
if hasBind: bind_data += bd
else :
bd = Sys.dprint(dbcall=True)
if hasBind: bind_data += bd
#~ if hasBind: bind_data += e
if hasBind :
Sys.wlog(bind_data)
#~ Sys.g.UI_BIND(bind_data)
def _formatArgs(args):
""""""
args = list(args)
for i,a in enumerate(args) :
if not (isinstance(a, str) or isinstance(a, bytes)):
a = str(a)
if len(a) > 30 :
args[i] = a[:30]+'...' if isinstance(a, str) else b'...'
args = str(args)[1:-1]
if args[-1:] == ',' : args = args[:-1]
return args
def log(func):
""""""
debug = True
wcolor = True
wtime = True
""""""
def wrapped_func(*args, **kwargs):
""""""
if debug :
t = None if not wtime else Sys.datetime.now()
# >= python 3.3
if signature is not None :
l = [p.name for p in signature(func).parameters.values()]
# < python 3.3
# !! BAD FIX !!
else :
l = ['self' if args[0].__class__ is not None else '']
n = args
if len(n)>0 and l[0] == 'self':
n = n[1:]
s = args[0].__class__.__name__ +'.'+func.__name__
else:
s = func.__name__
_logs(s, t, True, wcolor, n)
f = func(*args, **kwargs)
if debug : _logs(s, t, False, wcolor)
return f
return wrapped_func

226
psr/io.py Normal file
View File

@ -0,0 +1,226 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# #
# software : Kirmah <http://kirmah.sourceforge.net/> #
# version : 2.1 #
# date : 2013 #
# licence : GPLv3.0 <http://www.gnu.org/licenses/> #
# author : a-Sansara <http://www.a-sansara.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/>.
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~ class Io ~~
class Io:
from io import SEEK_CUR
from gzip import compress as gzcompress, decompress as gzdecompress
from bz2 import compress as bzcompress, decompress as bzdecompress
from errno import EEXIST
from os import remove as removeFile, utime
from mmap import mmap, PROT_READ
def __init__(self):
""""""
@staticmethod
def read_in_chunks(f, chsize=1024, utf8=False):
"""Lazy function (generator) to read a file piece by piece.
Default chunk size: 1k."""
c = 0
while True:
data = f.read(chsize)
if utf8 :
p = f.tell()
t = f.read(1)
f.seek(p)
if t!=b'' and not Io.is_utf8_start_sequence(ord(t)) :
delta = 0
for i in range(3) :
t = f.read(1)
if Io.is_utf8_start_sequence(ord(t)) :
delta += i
break
f.seek(p)
data += f.read(delta)
if not data : break
yield data, c
c += 1
@staticmethod
def read_utf8_chr(f, chsize=0, p=0):
""""""
with Io.mmap(f.fileno(), chsize*p) as mmp:
s, b, c = mmp.size(), b'', 0
while mmp.tell() < s :
b = mmp.read(1)
c = Io.count_utf8_continuation_bytes(b)
if c > 0 : b += mmp.read(c)
yield str(b,'utf-8')
@staticmethod
def is_utf8_continuation_byte(b):
""""""
return b >= 0x80 and b <= 0xbf
@staticmethod
def is_utf8_start_sequence(b):
""""""
return (b >= 0x00 and b <= 0x7f) or (b>= 0xc2 and b <= 0xf4)
@staticmethod
def count_utf8_continuation_bytes(b):
""""""
c = 0
try : d = ord(b)
except : d = int(b)
if d >= 0xc2 :
if d < 0xe0 : c = 1
elif d < 0xf0 : c = 2
else : c = 3
return c
@staticmethod
def get_data(path, binary=False, remove=False):
"""Get file content from `path`
:Returns: `str`
"""
d = ''
with Io.rfile(path, binary) as f :
d = f.read()
if remove :
Io.removeFile(path)
return d
@staticmethod
def get_file_obj(path, binary=False, writing=False, update=False, truncate=False):
""""""
if not writing :
f = open(path, mode='rt' if not binary else 'rb')
else :
#~ if not Io.file_exists(path): Io.set_data(path, '#')
m = ('w' if truncate else 'r')+('+' if update else '')+('b' if binary else 't')
if not binary :
f = open(path, mode=m, encoding='utf-8')
else :
f = open(path, mode=m)
return f
@staticmethod
def wfile(path, binary=True):
""""""
return Io.get_file_obj(path, binary, True, True, True)
@staticmethod
def ufile(path, binary=True):
""""""
return Io.get_file_obj(path, binary, True, True, False)
@staticmethod
def rfile(path, binary=True):
""""""
return Io.get_file_obj(path, binary)
@staticmethod
def set_data(path, content, binary=False):
""""""
with Io.wfile(path, binary) as f:
f.write(content)
@staticmethod
def readmmline(f, pos=0):
""""""
f.flush()
with Io.mmap(f.fileno(), 0, prot=Io.PROT_READ) as mmp:
mmp.seek(pos)
for line in iter(mmp.readline, b''):
pos = mmp.tell()
yield pos, Io.str(line[:-1])
@staticmethod
def copy(fromPath, toPath):
""""""
if not fromPath == toPath :
with Io.rfile(fromPath) as fi :
with Io.wfile(toPath) as fo :
fo.write(fi.read())
else : raise Exception('can\t copy to myself')
@staticmethod
def bytes(sdata, encoding='utf-8'):
""""""
return bytes(sdata,encoding)
@staticmethod
def str(bdata, encoding='utf-8'):
""""""
return str(bdata,encoding) if isinstance(bdata, bytes) else str(bdata)
@staticmethod
def printableBytes(bdata):
""""""
data = ''
if isinstance(bdata,bytes) :
try:
data = Io.str(bdata)
except Exception as e:
hexv = []
for i in bdata[1:] :
hexv.append(hex(i)[2:].rjust(2,'0'))
#~ self.app.g.UI_TXTBUF.insert_at_cursor('\n')
data = ' '.join(hexv)
pass
else :
data = bdata
return bdata
@staticmethod
def is_binary(filename):
"""Check if given filename is binary."""
done = False
f = Io.get_file_obj(filename, True)
try:
CHUNKSIZE = 1024
while 1:
chunk = f.read(CHUNKSIZE)
if b'\0' in chunk: done = True # found null byte
if done or len(chunk) < CHUNKSIZE: break
finally:
f.close()
return done
@staticmethod
def file_exists(path):
""""""
exist = False
try:
if path is not None :
with open(path) as f: exist = True
except IOError as e: pass
return exist
@staticmethod
def touch(fname, times=None):
""""""
if Io.file_exists(fname):
Io.utime(fname, times)

153
psr/mproc.py Normal file
View File

@ -0,0 +1,153 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# #
# software : Kirmah <http://kirmah.sourceforge.net/> #
# version : 2.1 #
# date : 2013 #
# licence : GPLv3.0 <http://www.gnu.org/licenses/> #
# author : a-Sansara <http://www.a-sansara.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 mproc ~~
from gi.repository.GObject import timeout_add
from multiprocessing import Process, Lock, Queue
from psr.decorate import log
from psr.sys import Sys
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~ class Ctrl ~~
class Ctrl:
""""""
@log
def __init__(self, nproc, npqueue_bind=None, task=None, *args, **kwargs ):
""""""
self.plist = []
self.queue = Queue()
self.npqueue = Queue()
self.nproc = nproc
self.done = False
self.npq_bind = npqueue_bind
if task is not None :
self.bind_task(task, *args, **kwargs)
def bind_task(self, task, *args, **kwargs):
""""""
if len(self.plist) > 0 :
del self.plist
self.plist = []
del self.queue
self.queue = Queue()
del self.npqueue
self.npqueue = Queue()
def mptask(npqueue, mproc_pid, mproc_queue, *args, **kwargs):
def wrapped(*args, **kwargs):
"""Only queue need result"""
def orgtask(*args, **kwargs):
Sys.g.MAIN_PROC = None
Sys.g.NPQUEUE = npqueue
return task(*args, **kwargs)
mproc_queue.put_nowait([mproc_pid, orgtask(*args, **kwargs)])
return wrapped(*args, **kwargs)
for i in range(self.nproc):
self.plist.append(Process(target=mptask, args=tuple([self.npqueue,i,self.queue,i])+tuple(args), kwargs=kwargs))
@log
def start(self, timeout=100, delay=None, maincb=None, childcb=None):
""""""
if childcb is not None : self.on_child_end = childcb
if maincb is not None : self.on_end = maincb
if delay is None :
self.launch(timeout)
else :
timeout_add(delay, self.launch, timeout)
#~ @log
def launch(self, timeout):
""""""
for p in self.plist:p.start()
self.list_process()
self.tid = timeout_add(timeout, self.check)
return False
#~ @log
def list_process(self):
""""""
if Sys.g.DEBUG :
Sys.pcontent('current pid :'+str(Sys.getpid()))
Sys.pcontent('childs pid :')
for p in self.plist:
Sys.pcontent(str(p.pid))
#~ @log
def end_process(self):
""""""
if not self.queue.empty():
d = self.queue.get_nowait()
if d is not None :
self.on_child_end(d[0], d[1])
p = self.plist[d[0]]
if p.is_alive(): p.join()
#~ @log
def on_child_end(self, pid, data):
""""""
#~ @log
def end_task(self):
""""""
self.queue.close()
self.queue.join_thread()
self.done = True
self.on_end()
#~ @log
def on_end(self):
""""""
print(self)
print('all child process terminated')
#~ @log
def check(self):
""""""
leave = True
# child process log queue
if self.npq_bind is not None :
while not self.npqueue.empty():
d = self.npqueue.get_nowait()
if d is not None: self.npq_bind(d)
# ctrl queue
if not self.queue.empty():
self.end_process()
for p in self.plist: leave = leave and not p.is_alive()
if leave :
while not self.queue.empty():
self.end_process()
self.end_task()
else : leave = False
return not leave

436
psr/sys.py Normal file
View File

@ -0,0 +1,436 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# #
# software : Kirmah <http://kirmah.sourceforge.net/> #
# version : 2.1 #
# date : 2013 #
# licence : GPLv3.0 <http://www.gnu.org/licenses/> #
# author : a-Sansara <http://www.a-sansara.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/>.
from psr.io import Io
def init(name, debug):
Sys.g_init(name, debug)
Sys.g_set_main_proc()
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~ class Sys ~~
class Sys:
""""""
from platform import system as getSysName
from os import system as sysCall, remove as removeFile, makedirs, sep, getpid
from getpass import getuser as getUserLogin
from time import strftime, mktime, time, localtime, sleep
from datetime import datetime
from sys import exit
from os.path import abspath, dirname, join, realpath, basename, getsize, isdir
from math import log, floor, ceil
from ast import literal_eval
import builtins as g
ERROR = 'error'
WARN = 'warn'
NOTICE = 'notice'
g.DEBUG = False
def __init__(self):
""""""
@staticmethod
def g_init(prjName, debug=False, ui_trace=None, bind=None, color=True):
Sys.g.PRJ_NAME = prjName
Sys.g.DEBUG = debug
Sys.g.LOG_FILE = '.'+prjName+'.log'
Sys.g.LOG_FO = Io.wfile(Sys.g.LOG_FILE, False) if bind is not None else None
#~ Sys.g.LOG_FO.write('# log '+prjName+'\n')
Sys.g.UI_TRACE = ui_trace
Sys.g.UI_BIND = bind
Sys.g.COLOR_MODE = color
#~ Sys.DEBUG = Debug(True,Debug.NOTICE)
from queue import Queue
Sys.g.QUEUE = Queue(0)
Sys.g.NPQUEUE = Queue(0)
Sys.g.MAIN_PROC = None
@staticmethod
def g_set_main_proc():
Sys.g.MAIN_PROC = Sys.getpid()
@staticmethod
def g_is_main_proc():
try :
return Sys.g.MAIN_PROC is None
except :
return False
@staticmethod
def g_has_ui_bind():
try:
return Sys.g.UI_BIND is not None and Sys.g.DEBUG
except Exception as e:
return False
@staticmethod
def isUnix():
""""""
return not Sys.getSysName() == 'Windows'
@staticmethod
def clear():
return Sys.sysCall('cls' if not Sys.isUnix() else 'clear')
@staticmethod
def mkdir_p(path):
""""""
try:
Sys.makedirs(path)
except OSError as e: # Python >2.5
if e.errno == Io.EEXIST:
pass
else: raise
@staticmethod
def readableBytes(b, p=2):
"""Give a human representation of bytes size `b`
:Returns: `str`
"""
units = ['B', 'KiB', 'MiB', 'GiB', 'TiB'];
b = max(b,0);
if b == 0 : lb= 0
else : lb = Sys.log(b)
p = Sys.floor(lb/Sys.log(1024))
p = min(p, len(units)- 1)
#Uncomment one of the following alternatives
b /= pow(1024,p)
#b /= (1 << (10 * p))
return str(round(b, 1))+' '+units[p]
@staticmethod
def getFileSize(path):
""""""
return Sys.readableBytes(Sys.getsize(path))
@staticmethod
def getPrintableBytes(bdata):
""""""
data = ''
if isinstance(bdata,bytes) :
try:
data = str(bdata, 'utf-8')
except Exception as e:
hexv = []
for i in bdata[1:] :
hexv.append(hex(i)[2:].rjust(2,'0'))
data = ' '.join(hexv)
pass
else :
data = bdata
return data
@staticmethod
def getHexaBytes(bdata):
""""""
data = ''
if isinstance(bdata,bytes) :
hexv = []
for i in bdata[1:] :
hexv.append(hex(i)[2:].rjust(2,'0'))
data = ' '.join(hexv)
else :
data = bdata
return data
@staticmethod
def wlog(data):
""""""
Sys.g.LOG_FO.write(str(data)+'\n')
@staticmethod
def print(data, colors, endLF=True, endClz=True):
""""""
if isinstance(data,bytes) :
data = Sys.getPrintableBytes(data)
ev = '' if not endLF else Sys.Clz._LF
tokens = [c.lstrip(Sys.Clz._MARKER[0]).rstrip(Sys.Clz._SEP) for c in colors.split(Sys.Clz._MARKER) if c is not '']
if Sys.isUnix() :
if data is None: data = ''
if endClz : data += Sys.Clz._uOFF
if Sys.g.COLOR_MODE :
Sys.dprint(eval('Sys.Clz._u'+'+Sys.Clz._u'.join(tokens))+data,end=ev, dbcall=True)
else :
Sys.dprint(data,end=ev, dbcall=True)
else :
if Sys.g.COLOR_MODE : Sys.Clz.setColor(eval('Sys.Clz._w'+'|Sys.Clz._w'.join(tokens)))
Sys.dprint(data,end=ev, dbcall=True)
stdout.flush()
if endClz and Sys.g.COLOR_MODE : Sys.Clz.setColor(Sys.Clz._wOFF)
#~ else:
#~ self.dprint(data,end=ev)
@staticmethod
def dprint(d='',end='\n', dbcall=False):
""""""
print(d,end=end)
if Sys.g_has_ui_bind():
bdata = [(d,'default')]
if not dbcall :
Sys.wlog(bdata)
else :
return bdata
@staticmethod
def eprint(d='', label='warn', dbcall=False):
""""""
c = Sys.CLZ_ERROR if label is Sys.ERROR else Sys.CLZ_WARN
Sys.print(' '+label+' : ', c, False, False)
Sys.print(str(d)+' ', c, True, True)
if Sys.g_has_ui_bind():
bdata = [(label+' : ' , label),(str(d)+' ', label)]
if not dbcall :
Sys.wlog(bdata)
else :
return bdata
@staticmethod
def pdate(t, dbcall = False):
""""""
t, s = Sys.strftime('%H:%M',t), Sys.strftime(':%S ',t)
Sys.print(t , Sys.CLZ_TIME, False)
Sys.print(s , Sys.CLZ_SEC , False)
if Sys.g_has_ui_bind():
bdata = [(t , 'time'),(s , 'sec')]
if not dbcall :
Sys.wlog(bdata)
else :
return bdata
@staticmethod
def pkval(label, value, pad=40, dbcall= False):
""""""
l, v = label.rjust(pad,' '), ' '+str(value)
Sys.print(l, Sys.CLZ_SEC , False)
Sys.print(v, Sys.CLZ_TIME , True)
if Sys.g_has_ui_bind():
bdata = [(l, 'sec'),(v, 'time')]
if not dbcall :
Sys.wlog(bdata)
else :
return bdata
@staticmethod
def pdelta(t, label='', dbcall= False):
""""""
if len(label)>0 : Sys.print(label+' ', Sys.CLZ_IO, False)
v = ''.join(["{:.5f}".format(Sys.time()-(Sys.mktime(t.timetuple())+1e-6*t.microsecond)),' s'])
Sys.print(v, Sys.CLZ_DELTA)
if Sys.g_has_ui_bind():
bdata = []
if len(label)>0 :
bdata.append((label+' ', 'io'))
bdata.append((v, 'delta'))
if not dbcall :
Sys.wlog(bdata)
else :
return bdata
@staticmethod
def pcontent(content, color=None, bcolor='default', dbcall= False):
""""""
Sys.print(content, Sys.CLZ_SEC if color is None else color)
if Sys.g_has_ui_bind():
bdata = [(content, bcolor)]
if not dbcall :
Sys.wlog(bdata)
else :
return bdata
@staticmethod
def pwarn(data, isError=False, length=120):
""" data struct :
( # line0
'simple line', # LF
# line1
# p0 p1 p2
('complex line with ',('paramValue',fgcolor), ' suit complex line'), # LF
# line2
'other simple line '
)
"""
w = ' WARNING : ' if not isError else ' ERROR : '
bg = Sys.Clz.bg5 if not isError else Sys.Clz.bg1
Sys.print(w, bg+Sys.Clz.fgb3, False, False)
for i, line in enumerate(data) :
if i > 0 :
Sys.print(' '*len(w), bg+Sys.Clz.fgb7, False, False)
if isinstance(line,str) :
Sys.print(line.ljust(length-len(w),' '), bg+Sys.Clz.fgb7, True, True)
else :
sl = 0
for p in line :
if isinstance(p,str) :
Sys.print(p, bg+Sys.Clz.fgb7, False, False)
sl += len(p)
else :
Sys.print(p[0], bg+p[1], False, False)
sl += len(p[0])
Sys.print(' '.ljust(length-sl-len(w),' '), bg+Sys.Clz.fgb7, True, True)
Sys.dprint()
@staticmethod
def _psymbol(ch):
""""""
Sys.print(' ', Sys.Clz.fgb7, False, False)
Sys.print(' '+ch+' ', Sys.Clz.BG4+Sys.Clz.fgb7, False, True)
Sys.print(' ', Sys.Clz.fgb7, False, True)
@staticmethod
def pask(ask, yesValue='yes', noValue='no'):
""""""
Sys._psymbol('?')
Sys.print('', Sys.Clz.fgb3, False, False)
ask = ask + ' ('+yesValue+'/'+noValue+') ? '
answer = input(ask)
while answer.lower()!=yesValue.lower() and answer.lower()!=noValue.lower() :
s = 'Please enter either '+yesValue+' or '+noValue+' : '
answer = input(' '.ljust(5,' ')+s.ljust(len(ask),' '))
Sys.dprint()
return answer.lower()==yesValue.lower()
@staticmethod
def pstep(title, stime, done, exitOnFailed=True, length=120):
""""""
if stime is not None :
v = ' ('+''.join(["{:.5f}".format(Sys.time()-(Sys.mktime(stime.timetuple())+1e-6*stime.microsecond)),' s'])+')'
else : v = ''
Sys._psymbol('¤')
Sys.print(title, Sys.Clz.fgB7, False, False)
Sys.print(v+' '.ljust(length-len(title)-20-len(v), ' '),Sys.CLZ_DELTA, False, True)
if done :
Sys.print(' == OK == ', Sys.Clz.bg2+Sys.Clz.fgb7)
else :
Sys.print(' == KO == ', Sys.Clz.bg1+Sys.Clz.fgb7)
Sys.dprint()
if exitOnFailed and not done:
#~ Sys.dprint(' '.ljust(length-14, ' '),end='')
#~ Sys.print(' == EXIT == ', Sys.Clz.bg1+Sys.Clz.fgb7)
#~ Sys.dprint()
Sys.exit(1)
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~ class Coloriz ~~
class Coloriz:
_MARKER = ''
""""""
_SEP = ';'
""""""
_PATTERN_COLOR = '^'+_MARKER[0]+'[nfNFbB][0-7]'+_SEP+'$'
""""""
_wFH = 0x0008
""""""
_wBH = 0x0080
""""""
_uOFF = '\033[1;m'
""""""
_wOFF = None
""""""
_LF = '\n'
""""""
OFF = _MARKER+_MARKER[0]+'OFF'+_SEP+_MARKER
""""""
def __init__(self):
"""Colors for both plateform are : 0: black - 1: red - 2:green - 3: yellow - 4: blue - 5: purple - 6: cyan - 7: white
available class members :
foreground normal (same as bold for w32):
self.fgn0 -> self.fgn7
foreground bold :
self.fgb0 -> self.fgb7
foreground high intensity (same as bold high intensity for w35):
self.fgN0 -> self.fgN7
foreground bold high intensity :
self.fgB0 -> self.fgB7
background
self.bg0 -> self.bg7
background high intensity
self.BG0 -> self.BG7
default colors :
self.OFF
usage :
pc = PColor()
pc.print('%smon label%s:%sma value%s' % (pc.BG4+pc.fgN7, pc.OFF+pc.fgn1, pc.fgb4, pc.OFF))
"""
global Sys
if not Sys.isUnix():
j = 0
for i in (0,4,2,6,1,5,3,7):
exec('self._wf%i = 0x000%i' % (i,j) + '\nself._wb%i = 0x00%i0' % (i,j) + '\nself._wF%i = 0x000%i | self._wFH' % (i,j) + '\nself._wB%i = 0x00%i0 | self._wBH' % (i,j))
# normal eq bold
exec('self._wn%i = self._wf%i' % (i,i))
# normal high intensity eq bold high intensity
exec('self._wN%i = self._wF%i' % (i,i))
j += 1
import impra.w32color as w32cons
self._wOFF = w32cons.get_text_attr()
self._wOFFbg = self._wOFF & 0x0070
self._wOFFfg = self._wOFF & 0x0007
self.setColor = w32cons.set_text_attr
for i in range(0,8):
# foreground normal
exec('self.fgn%i = self._MARKER + self._MARKER[0] + "n%i" + self._SEP + self._MARKER' % (i,i))
if True or Sys.isUnix() : exec('self._un%i = "\\033[0;3%im"' % (i,i))
# foreground bold
exec('self.fgb%i = self._MARKER + self._MARKER[0] + "f%i" + self._SEP + self._MARKER' % (i,i))
if True or Sys.isUnix() : exec('self._uf%i = "\\033[1;3%im"' % (i,i))
# foreground high intensity
exec('self.fgN%i = self._MARKER + self._MARKER[0] + "N%i" + self._SEP + self._MARKER' % (i,i))
if True or Sys.isUnix() : exec('self._uN%i = "\\033[0;9%im"' % (i,i))
# foreground bold high intensity
exec('self.fgB%i = self._MARKER + self._MARKER[0] + "F%i" + self._SEP + self._MARKER' % (i,i))
if True or Sys.isUnix() : exec('self._uF%i = "\\033[1;9%im"' % (i,i))
# background
exec('self.bg%i = self._MARKER + self._MARKER[0] + "b%i" + self._SEP + self._MARKER' % (i,i))
if True or Sys.isUnix() : exec('self._ub%i = "\\033[4%im"' % (i,i))
# background high intensity
exec('self.BG%i = self._MARKER + self._MARKER[0] + "B%i" + self._SEP + self._MARKER' % (i,i))
if True or Sys.isUnix() : exec('self._uB%i = "\\033[0;10%im"' % (i,i))
Sys.Clz = Coloriz()
Sys.CLZ_TIME = Sys.Clz.fgN2+Sys.Clz.bg0
Sys.CLZ_SEC = Sys.Clz.fgb7+Sys.Clz.bg0
Sys.CLZ_IO = Sys.Clz.fgB1+Sys.Clz.bg0
Sys.CLZ_FUNC = Sys.Clz.fgb3+Sys.Clz.bg0
Sys.CLZ_ARGS = Sys.Clz.fgn7+Sys.Clz.bg0
Sys.CLZ_DELTA = Sys.Clz.fgN4+Sys.Clz.bg0
Sys.CLZ_ERROR = Sys.Clz.fgb7+Sys.Clz.bg1
Sys.CLZ_WARN = Sys.Clz.fgb7+Sys.Clz.bg5
Sys.CLZ_DEFAULT = Sys.Clz.fgb7+Sys.Clz.bg0