amend displaying step and task + compat project imprastorage
This commit is contained in:
parent
23741be148
commit
14b5e9fab4
|
@ -126,19 +126,10 @@ class Cli(AbstractCli):
|
||||||
Sys.g.LOG_QUEUE.put(Sys.g.SIGNAL_STOP)
|
Sys.g.LOG_QUEUE.put(Sys.g.SIGNAL_STOP)
|
||||||
|
|
||||||
else :
|
else :
|
||||||
self.parser.error_cmd((('unknow command ',(a[0],Sys.Clz.fgb3)),))
|
self.parser.error_cmd((('unknow command ',(a[0],Sys.Clz.fgb3)),), True)
|
||||||
|
|
||||||
if not o.quiet : Sys.dprint()
|
if not o.quiet : Sys.dprint()
|
||||||
|
|
||||||
#~
|
|
||||||
#~ @staticmethod
|
|
||||||
#~ def error_cmd(data):
|
|
||||||
#~ """"""
|
|
||||||
#~ Cli.print_usage('')
|
|
||||||
#~ Sys.dprint()
|
|
||||||
#~ Sys.pwarn(data, True)
|
|
||||||
#~ Cli.exit(1)
|
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def print_usage(data, withoutHeader=False):
|
def print_usage(data, withoutHeader=False):
|
||||||
|
|
|
@ -87,9 +87,7 @@ class CliApp:
|
||||||
if self.o.outputfile is None :
|
if self.o.outputfile is None :
|
||||||
self.o.outputfile = Sys.basename(self.a[1])
|
self.o.outputfile = Sys.basename(self.a[1])
|
||||||
if self.o.outputfile[-len(Kirmah.EXT):] != Kirmah.EXT :
|
if self.o.outputfile[-len(Kirmah.EXT):] != Kirmah.EXT :
|
||||||
print(self.o.outputfile[-len(Kirmah.EXT):])
|
|
||||||
self.o.outputfile += Kirmah.EXT
|
self.o.outputfile += Kirmah.EXT
|
||||||
print(self.o.outputfile)
|
|
||||||
|
|
||||||
d = self.getDefaultOption((self.o.compress,self.o.fullcompress,self.o.nocompress))
|
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))
|
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))
|
||||||
|
|
|
@ -48,7 +48,7 @@ PRG_LICENSE = 'GNU GPL v3'
|
||||||
PRG_RESOURCES_PATH = '/usr/share/'+PRG_PACKAGE+sep
|
PRG_RESOURCES_PATH = '/usr/share/'+PRG_PACKAGE+sep
|
||||||
if not isdir(PRG_RESOURCES_PATH):
|
if not isdir(PRG_RESOURCES_PATH):
|
||||||
PRG_RESOURCES_PATH = dirname(dirname(realpath(__file__)))+sep+'resources'+sep+PRG_PACKAGE+sep
|
PRG_RESOURCES_PATH = dirname(dirname(realpath(__file__)))+sep+'resources'+sep+PRG_PACKAGE+sep
|
||||||
print(PRG_RESOURCES_PATH)
|
#~ print(PRG_RESOURCES_PATH)
|
||||||
PRG_GLADE_PATH = PRG_RESOURCES_PATH+'glade'+sep+PRG_PACKAGE+'.glade'
|
PRG_GLADE_PATH = PRG_RESOURCES_PATH+'glade'+sep+PRG_PACKAGE+'.glade'
|
||||||
PRG_LICENSE_PATH = PRG_RESOURCES_PATH+'/LICENSE'
|
PRG_LICENSE_PATH = PRG_RESOURCES_PATH+'/LICENSE'
|
||||||
PRG_LOGO_PATH = join(PRG_RESOURCES_PATH,'..'+sep,'pixmaps'+sep,PRG_PACKAGE+sep,PRG_PACKAGE+'.png')
|
PRG_LOGO_PATH = join(PRG_RESOURCES_PATH,'..'+sep,'pixmaps'+sep,PRG_PACKAGE+sep,PRG_PACKAGE+'.png')
|
||||||
|
|
|
@ -63,7 +63,7 @@ def hash_sha256_file(path):
|
||||||
return sha256(open(path, mode='rb').read()).hexdigest()
|
return sha256(open(path, mode='rb').read()).hexdigest()
|
||||||
|
|
||||||
|
|
||||||
@Log()
|
@Log(Const.LOG_ALL)
|
||||||
def hash_md5_file(path):
|
def hash_md5_file(path):
|
||||||
"""Get a md5 hash of file from path
|
"""Get a md5 hash of file from path
|
||||||
:Returns: `str`
|
:Returns: `str`
|
||||||
|
@ -104,7 +104,7 @@ class KeyGen :
|
||||||
""""""
|
""""""
|
||||||
|
|
||||||
@Log(Const.LOG_BUILD)
|
@Log(Const.LOG_BUILD)
|
||||||
def __init__(self, length, salt=None):
|
def __init__(self, length=1024, salt=None):
|
||||||
""""""
|
""""""
|
||||||
self.new(length, salt)
|
self.new(length, salt)
|
||||||
|
|
||||||
|
@ -613,8 +613,7 @@ class Kirmah:
|
||||||
@Log()
|
@Log()
|
||||||
def split(self, fromPath, hlst):
|
def split(self, fromPath, hlst):
|
||||||
""""""
|
""""""
|
||||||
if not Sys.is_cli_cancel():
|
if not Sys.is_cli_cancel():
|
||||||
self.DIR_OUTBOX = ''
|
|
||||||
f = open(fromPath, 'rb+')
|
f = open(fromPath, 'rb+')
|
||||||
m, p, rsz = mmap(f.fileno(), 0), 0, 0
|
m, p, rsz = mmap(f.fileno(), 0), 0, 0
|
||||||
fsize = Sys.getsize(fromPath)
|
fsize = Sys.getsize(fromPath)
|
||||||
|
@ -766,11 +765,11 @@ class Kirmah:
|
||||||
d = Sys.datetime.now()
|
d = Sys.datetime.now()
|
||||||
if compstart :
|
if compstart :
|
||||||
if Sys.g.DEBUG : Sys.wlog(Sys.dprint())
|
if Sys.g.DEBUG : Sys.wlog(Sys.dprint())
|
||||||
Sys.ptask('Compressing data')
|
if not Sys.g.QUIET : Sys.ptask('Compressing data')
|
||||||
self.compress_start(fp, tp, compstart, emit=emit)
|
self.compress_start(fp, tp, compstart, emit=emit)
|
||||||
if compstart :
|
if compstart :
|
||||||
if Sys.g.DEBUG : Sys.wlog(Sys.dprint())
|
if Sys.g.DEBUG : Sys.wlog(Sys.dprint())
|
||||||
Sys.pstep('Compression mode', d, True)
|
if not Sys.g.QUIET : Sys.pstep('Compression mode', d, True)
|
||||||
fp, tp = tp, self.tmpPath2 if tp == self.tmpPath1 else self.tmpPath1
|
fp, tp = tp, self.tmpPath2 if tp == self.tmpPath1 else self.tmpPath1
|
||||||
if emit : Sys.cli_emit_progress(5)
|
if emit : Sys.cli_emit_progress(5)
|
||||||
return fp, tp, decHeader['rmode'], decHeader['mmode'], compend
|
return fp, tp, decHeader['rmode'], decHeader['mmode'], compend
|
||||||
|
@ -783,14 +782,14 @@ class Kirmah:
|
||||||
if rmode :
|
if rmode :
|
||||||
#~ self.mpRandomFileContent(fp, tp, 4)
|
#~ self.mpRandomFileContent(fp, tp, 4)
|
||||||
if Sys.g.DEBUG : Sys.wlog(Sys.dprint())
|
if Sys.g.DEBUG : Sys.wlog(Sys.dprint())
|
||||||
Sys.ptask('Randomizing data')
|
if not Sys.g.QUIET : Sys.ptask('Randomizing data')
|
||||||
self.randomFileContent(fp, tp, emit=emit)
|
self.randomFileContent(fp, tp, emit=emit)
|
||||||
fp, tp = tp, self.tmpPath2 if tp == self.tmpPath1 else self.tmpPath1
|
fp, tp = tp, self.tmpPath2 if tp == self.tmpPath1 else self.tmpPath1
|
||||||
if emit : Sys.cli_emit_progress(75)
|
if emit : Sys.cli_emit_progress(75)
|
||||||
|
|
||||||
if mmode :
|
if mmode :
|
||||||
if Sys.g.DEBUG : Sys.wlog(Sys.dprint())
|
if Sys.g.DEBUG : Sys.wlog(Sys.dprint())
|
||||||
Sys.ptask('Mixing data')
|
if not Sys.g.QUIET : Sys.ptask('Mixing data')
|
||||||
self.mixdata(fp, tp, True, emit=emit)
|
self.mixdata(fp, tp, True, emit=emit)
|
||||||
|
|
||||||
fp, tp = tp, self.tmpPath2 if tp == self.tmpPath1 else self.tmpPath1
|
fp, tp = tp, self.tmpPath2 if tp == self.tmpPath1 else self.tmpPath1
|
||||||
|
@ -799,17 +798,17 @@ class Kirmah:
|
||||||
if compend :
|
if compend :
|
||||||
d = Sys.datetime.now()
|
d = Sys.datetime.now()
|
||||||
if Sys.g.DEBUG : Sys.wlog(Sys.dprint())
|
if Sys.g.DEBUG : Sys.wlog(Sys.dprint())
|
||||||
Sys.ptask('Compressing data')
|
if not Sys.g.QUIET : Sys.ptask('Compressing data')
|
||||||
self.compress_end(fp, toPath, compend, emit=emit)
|
self.compress_end(fp, toPath, compend, emit=emit)
|
||||||
if emit : Sys.cli_emit_progress(95)
|
if emit : Sys.cli_emit_progress(95)
|
||||||
|
|
||||||
if compend :
|
if compend :
|
||||||
if Sys.g.DEBUG : Sys.wlog(Sys.dprint())
|
if Sys.g.DEBUG : Sys.wlog(Sys.dprint())
|
||||||
Sys.pstep('Compression mode', d, True)
|
if not Sys.g.QUIET : Sys.pstep('Compression mode', d, True)
|
||||||
|
|
||||||
# clean tmp files
|
# clean tmp files
|
||||||
if Sys.g.DEBUG : Sys.wlog(Sys.dprint())
|
if Sys.g.DEBUG : Sys.wlog(Sys.dprint())
|
||||||
Sys.ptask('Cleaning')
|
if not Sys.g.QUIET : Sys.ptask('Cleaning')
|
||||||
|
|
||||||
try :
|
try :
|
||||||
Sys.removeFile(self.tmpPath1)
|
Sys.removeFile(self.tmpPath1)
|
||||||
|
@ -850,21 +849,21 @@ class Kirmah:
|
||||||
def encrypt_mproc(self, fp, tp, nproc=1, emit=True):
|
def encrypt_mproc(self, fp, tp, nproc=1, emit=True):
|
||||||
""""""
|
""""""
|
||||||
if Sys.g.DEBUG : Sys.wlog(Sys.dprint())
|
if Sys.g.DEBUG : Sys.wlog(Sys.dprint())
|
||||||
Sys.ptask('Encrypting data')
|
if not Sys.g.QUIET : Sys.ptask('Encrypting data')
|
||||||
d = Sys.datetime.now()
|
d = Sys.datetime.now()
|
||||||
c = not Sys.is_cli_cancel()
|
c = not Sys.is_cli_cancel()
|
||||||
if c:
|
if c:
|
||||||
if nproc == 1 :
|
if nproc == 1 :
|
||||||
self.encryptToFile(fp, tp)
|
self.encryptToFile(fp, tp)
|
||||||
if Sys.g.DEBUG : Sys.wlog(Sys.dprint())
|
if Sys.g.DEBUG : Sys.wlog(Sys.dprint())
|
||||||
Sys.pstep('Encrypt data', d, c)
|
if not Sys.g.QUIET : Sys.pstep('Encrypt data', d, c)
|
||||||
else :
|
else :
|
||||||
hlstPaths = self.prepare_mproc_encode(fp, nproc)
|
hlstPaths = self.prepare_mproc_encode(fp, nproc)
|
||||||
mg = Manager(self.mproc_encode_part, nproc, None, Sys.g.MPEVENT)
|
mg = Manager(self.mproc_encode_part, nproc, None, Sys.g.MPEVENT)
|
||||||
mg.run()
|
mg.run()
|
||||||
self.mpMergeFiles(hlstPaths, tp, emit=emit)
|
self.mpMergeFiles(hlstPaths, tp, emit=emit)
|
||||||
if Sys.g.DEBUG : Sys.wlog(Sys.dprint())
|
if Sys.g.DEBUG : Sys.wlog(Sys.dprint())
|
||||||
Sys.pstep('Encrypt data (multiproc)', d, c)
|
if not Sys.g.QUIET : Sys.pstep('Encrypt data (multiproc)', d, c)
|
||||||
if emit : Sys.cli_emit_progress(70)
|
if emit : Sys.cli_emit_progress(70)
|
||||||
|
|
||||||
|
|
||||||
|
@ -901,9 +900,9 @@ class Kirmah:
|
||||||
if len(decHeader) > 0 :
|
if len(decHeader) > 0 :
|
||||||
if Sys.g.DEBUG : Sys.wlog(Sys.dprint())
|
if Sys.g.DEBUG : Sys.wlog(Sys.dprint())
|
||||||
if decHeader['smode'] == self.mark[fsize%len(self.mark)] :
|
if decHeader['smode'] == self.mark[fsize%len(self.mark)] :
|
||||||
Sys.pstep('Reading Header', d, True)
|
if not Sys.g.QUIET : Sys.pstep('Reading Header', d, True)
|
||||||
else :
|
else :
|
||||||
Sys.pstep('Reading Header', d, False, False, False)
|
if not Sys.g.QUIET : Sys.pstep('Reading Header', d, False, False, False)
|
||||||
raise BadKeyException('wrong key')
|
raise BadKeyException('wrong key')
|
||||||
|
|
||||||
compend, compstart = not decHeader['cmode']== KirmahHeader.COMP_NONE, decHeader['cmode']== KirmahHeader.COMP_ALL
|
compend, compstart = not decHeader['cmode']== KirmahHeader.COMP_NONE, decHeader['cmode']== KirmahHeader.COMP_ALL
|
||||||
|
@ -913,26 +912,26 @@ class Kirmah:
|
||||||
if compend :
|
if compend :
|
||||||
d = Sys.datetime.now()
|
d = Sys.datetime.now()
|
||||||
if Sys.g.DEBUG : Sys.wlog(Sys.dprint())
|
if Sys.g.DEBUG : Sys.wlog(Sys.dprint())
|
||||||
Sys.ptask('Uncompressing data')
|
if not Sys.g.QUIET : Sys.ptask('Uncompressing data')
|
||||||
self.uncompress_end(fp, tp, compend, emit=emit)
|
self.uncompress_end(fp, tp, compend, emit=emit)
|
||||||
if emit : Sys.cli_emit_progress(10)
|
if emit : Sys.cli_emit_progress(10)
|
||||||
if compend :
|
if compend :
|
||||||
if Sys.g.DEBUG : Sys.wlog(Sys.dprint())
|
if Sys.g.DEBUG : Sys.wlog(Sys.dprint())
|
||||||
Sys.pstep('Compression mode', d, True)
|
if not Sys.g.QUIET : Sys.pstep('Compression mode', d, True)
|
||||||
fp, tp = tp, self.tmpPath2 if tp == self.tmpPath1 else self.tmpPath1
|
fp, tp = tp, self.tmpPath2 if tp == self.tmpPath1 else self.tmpPath1
|
||||||
|
|
||||||
|
|
||||||
if decHeader['mmode'] :
|
if decHeader['mmode'] :
|
||||||
d = Sys.datetime.now()
|
d = Sys.datetime.now()
|
||||||
if Sys.g.DEBUG : Sys.wlog(Sys.dprint())
|
if Sys.g.DEBUG : Sys.wlog(Sys.dprint())
|
||||||
Sys.ptask('Sorting data')
|
if not Sys.g.QUIET : Sys.ptask('Sorting data')
|
||||||
self.unmixdata(fp, tp, emit=emit)
|
self.unmixdata(fp, tp, emit=emit)
|
||||||
fp, tp = tp, self.tmpPath2 if tp == self.tmpPath1 else self.tmpPath1
|
fp, tp = tp, self.tmpPath2 if tp == self.tmpPath1 else self.tmpPath1
|
||||||
if emit : Sys.cli_emit_progress(20)
|
if emit : Sys.cli_emit_progress(20)
|
||||||
if decHeader['rmode'] :
|
if decHeader['rmode'] :
|
||||||
d = Sys.datetime.now()
|
d = Sys.datetime.now()
|
||||||
if Sys.g.DEBUG : Sys.wlog(Sys.dprint())
|
if Sys.g.DEBUG : Sys.wlog(Sys.dprint())
|
||||||
Sys.ptask('Reordering data')
|
if not Sys.g.QUIET : Sys.ptask('Reordering data')
|
||||||
self.unRandomFileContent(fp, tp, emit=emit)
|
self.unRandomFileContent(fp, tp, emit=emit)
|
||||||
fp, tp = tp, self.tmpPath2 if tp == self.tmpPath1 else self.tmpPath1
|
fp, tp = tp, self.tmpPath2 if tp == self.tmpPath1 else self.tmpPath1
|
||||||
if emit : Sys.cli_emit_progress(25)
|
if emit : Sys.cli_emit_progress(25)
|
||||||
|
@ -947,15 +946,15 @@ class Kirmah:
|
||||||
if emit : Sys.cli_emit_progress(80)
|
if emit : Sys.cli_emit_progress(80)
|
||||||
if compstart :
|
if compstart :
|
||||||
if Sys.g.DEBUG : Sys.wlog(Sys.dprint())
|
if Sys.g.DEBUG : Sys.wlog(Sys.dprint())
|
||||||
Sys.ptask('Uncompressing data')
|
if not Sys.g.QUIET : Sys.ptask('Uncompressing data')
|
||||||
self.uncompress_start(fromPath, toPath, compstart, emit=emit)
|
self.uncompress_start(fromPath, toPath, compstart, emit=emit)
|
||||||
if emit : Sys.cli_emit_progress(90)
|
if emit : Sys.cli_emit_progress(90)
|
||||||
if compstart:
|
if compstart:
|
||||||
if Sys.g.DEBUG : Sys.wlog(Sys.dprint())
|
if Sys.g.DEBUG : Sys.wlog(Sys.dprint())
|
||||||
Sys.pstep('Compression mode', d, True)
|
if not Sys.g.QUIET : Sys.pstep('Compression mode', d, True)
|
||||||
|
|
||||||
if Sys.g.DEBUG : Sys.wlog(Sys.dprint())
|
if Sys.g.DEBUG : Sys.wlog(Sys.dprint())
|
||||||
Sys.ptask('Cleaning')
|
if not Sys.g.QUIET : Sys.ptask('Cleaning')
|
||||||
if emit : Sys.cli_emit_progress(95)
|
if emit : Sys.cli_emit_progress(95)
|
||||||
try :
|
try :
|
||||||
Sys.removeFile(self.tmpPath1)
|
Sys.removeFile(self.tmpPath1)
|
||||||
|
@ -969,7 +968,7 @@ class Kirmah:
|
||||||
def decrypt_mproc(self, fromPath, toPath, nproc=1, emit=True):
|
def decrypt_mproc(self, fromPath, toPath, nproc=1, emit=True):
|
||||||
""""""
|
""""""
|
||||||
if Sys.g.DEBUG : Sys.wlog(Sys.dprint())
|
if Sys.g.DEBUG : Sys.wlog(Sys.dprint())
|
||||||
Sys.ptask('Decrypting data')
|
if not Sys.g.QUIET : Sys.ptask('Decrypting data')
|
||||||
d = Sys.datetime.now()
|
d = Sys.datetime.now()
|
||||||
c = not Sys.is_cli_cancel()
|
c = not Sys.is_cli_cancel()
|
||||||
if c:
|
if c:
|
||||||
|
@ -977,14 +976,14 @@ class Kirmah:
|
||||||
if nproc == 1 :
|
if nproc == 1 :
|
||||||
self.decryptToFile(fromPath, toPath)
|
self.decryptToFile(fromPath, toPath)
|
||||||
if Sys.g.DEBUG : Sys.wlog(Sys.dprint())
|
if Sys.g.DEBUG : Sys.wlog(Sys.dprint())
|
||||||
Sys.pstep('Decrypt data', d, True)
|
if not Sys.g.QUIET : Sys.pstep('Decrypt data', d, True)
|
||||||
else :
|
else :
|
||||||
hlstPaths = self.prepare_mproc_decode(fromPath, nproc)
|
hlstPaths = self.prepare_mproc_decode(fromPath, nproc)
|
||||||
mg = Manager(self.mproc_decode_part, nproc, None, Sys.g.MPEVENT, emit=True)
|
mg = Manager(self.mproc_decode_part, nproc, None, Sys.g.MPEVENT, emit=True)
|
||||||
mg.run()
|
mg.run()
|
||||||
self.mpMergeFiles(hlstPaths, toPath, emit=emit)
|
self.mpMergeFiles(hlstPaths, toPath, emit=emit)
|
||||||
if Sys.g.DEBUG : Sys.wlog(Sys.dprint())
|
if Sys.g.DEBUG : Sys.wlog(Sys.dprint())
|
||||||
Sys.pstep('Decrypt data (multiproc)', d, True)
|
if not Sys.g.QUIET : Sys.pstep('Decrypt data (multiproc)', d, True)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -87,6 +87,7 @@ class AbstractCli():
|
||||||
""""""
|
""""""
|
||||||
if not Sys.isUnix : Const.LINE_SEP_CHAR = '-'
|
if not Sys.isUnix : Const.LINE_SEP_CHAR = '-'
|
||||||
AbstractCli.conf = prgconf
|
AbstractCli.conf = prgconf
|
||||||
|
self.CHQ = "'"
|
||||||
self.parser = TinyParser()
|
self.parser = TinyParser()
|
||||||
self.parser.print_help = self.print_help
|
self.parser.print_help = self.print_help
|
||||||
self.parser.print_usage = self.print_usage
|
self.parser.print_usage = self.print_usage
|
||||||
|
@ -98,7 +99,7 @@ class AbstractCli():
|
||||||
self.parser.add_option('-q', '--quiet' , 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)
|
self.parser.add_option('--no-color' , action='store_true' , default=False)
|
||||||
|
|
||||||
|
|
||||||
def error_cmd(self, data, pusage=False):
|
def error_cmd(self, data, pusage=False):
|
||||||
""""""
|
""""""
|
||||||
|
@ -127,7 +128,7 @@ class AbstractCli():
|
||||||
Sys.wlog(a)
|
Sys.wlog(a)
|
||||||
Sys.wlog(b + c + d + e + f )
|
Sys.wlog(b + c + d + e + f )
|
||||||
Sys.wlog(a)
|
Sys.wlog(a)
|
||||||
Sys.wlog(Sys.dprint())
|
#~ Sys.wlog(Sys.dprint())
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
|
488
psr/imap.py
Normal file
488
psr/imap.py
Normal file
|
@ -0,0 +1,488 @@
|
||||||
|
from imaplib import Commands, IMAP4_SSL, Time2Internaldate
|
||||||
|
from binascii import b2a_base64, a2b_base64
|
||||||
|
from codecs import register, StreamReader, StreamWriter
|
||||||
|
from email import message_from_bytes
|
||||||
|
from email.header import decode_header
|
||||||
|
from email.message import Message
|
||||||
|
from re import search as research, split as resplit
|
||||||
|
|
||||||
|
from psr.sys import Io, Sys, Const
|
||||||
|
from psr.log import Log
|
||||||
|
|
||||||
|
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
# ~~ ImapUtf7 decoding/encoding ~~
|
||||||
|
|
||||||
|
def _seq_encode(seq,l):
|
||||||
|
""""""
|
||||||
|
if len(seq) > 0 :
|
||||||
|
l.append('&%s-' % str(b2a_base64(bytes(''.join(seq),'utf-16be')),'utf-8').rstrip('\n=').replace('/', ','))
|
||||||
|
elif l:
|
||||||
|
l.append('-')
|
||||||
|
|
||||||
|
|
||||||
|
def _seq_decode(seq,l):
|
||||||
|
""""""
|
||||||
|
d = ''.join(seq[1:])
|
||||||
|
pad = 4-(len(d)%4)
|
||||||
|
l.append(str(a2b_base64(bytes(d.replace(',', '/')+pad*'=','utf-16be')),'utf-16be'))
|
||||||
|
|
||||||
|
|
||||||
|
def encode(s):
|
||||||
|
""""""
|
||||||
|
l, e, = [], []
|
||||||
|
for c in s :
|
||||||
|
if ord(c) in range(0x20,0x7e):
|
||||||
|
if e : _seq_encode(e,l)
|
||||||
|
e = []
|
||||||
|
l.append(c)
|
||||||
|
if c == '&' : l.append('-')
|
||||||
|
else :
|
||||||
|
e.append(c)
|
||||||
|
if e : _seq_encode(e,l)
|
||||||
|
return ''.join(l)
|
||||||
|
|
||||||
|
|
||||||
|
def decode(s):
|
||||||
|
""""""
|
||||||
|
l, d = [], []
|
||||||
|
for c in s:
|
||||||
|
if c == '&' and not d : d.append('&')
|
||||||
|
elif c == '-' and d:
|
||||||
|
if len(d) == 1: l.append('&')
|
||||||
|
else : _seq_decode(d,l)
|
||||||
|
d = []
|
||||||
|
elif d: d.append(c)
|
||||||
|
else: l.append(c)
|
||||||
|
if d: _seq_decode(d,l)
|
||||||
|
return ''.join(l)
|
||||||
|
|
||||||
|
|
||||||
|
def _encoder(s):
|
||||||
|
""""""
|
||||||
|
e = bytes(encode(s),'utf-8')
|
||||||
|
return e, len(e)
|
||||||
|
|
||||||
|
|
||||||
|
def _decoder(s):
|
||||||
|
""""""
|
||||||
|
d = decode(str(s,'utf-8'))
|
||||||
|
return d, len(d)
|
||||||
|
|
||||||
|
|
||||||
|
def _codec_imap4utf7(name):
|
||||||
|
""""""
|
||||||
|
if name == 'imap4-utf-7':
|
||||||
|
return (_encoder, _decoder, Imap4Utf7StreamReader, Imap4Utf7StreamWriter)
|
||||||
|
|
||||||
|
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
# ~~ StreamReader & StreamWriter ~~
|
||||||
|
|
||||||
|
class Imap4Utf7StreamReader(StreamReader):
|
||||||
|
def decode(self, s, errors='strict'): return _decoder(s)
|
||||||
|
|
||||||
|
class Imap4Utf7StreamWriter(StreamWriter):
|
||||||
|
def decode(self, s, errors='strict'): return _encoder(s)
|
||||||
|
|
||||||
|
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
# ~~ registering codec ~~
|
||||||
|
|
||||||
|
register(_codec_imap4utf7)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
# ~~ Imap utilities ~~
|
||||||
|
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
# ~~ class ImapConfig ~~
|
||||||
|
|
||||||
|
class ImapConfig:
|
||||||
|
""""""
|
||||||
|
|
||||||
|
def __init__(self, host, user, pwd, port=993):
|
||||||
|
""""""
|
||||||
|
self.host = host
|
||||||
|
self.user = user
|
||||||
|
self.pwd = pwd
|
||||||
|
self.port = port
|
||||||
|
|
||||||
|
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
# ~~ class ImapClient ~~
|
||||||
|
|
||||||
|
class ImapClient(IMAP4_SSL):
|
||||||
|
""""""
|
||||||
|
|
||||||
|
Commands['XLIST'] = ('AUTH', 'SELECTED')
|
||||||
|
|
||||||
|
@Log(Const.LOG_DEBUG)
|
||||||
|
def xlist(self, directory='""', pattern='*'):
|
||||||
|
"""(X)List mailbox names in directory matching pattern. Using Google's XLIST extension
|
||||||
|
|
||||||
|
(status, [data]) = <instance>.xlist(directory='""', pattern='*')
|
||||||
|
|
||||||
|
'data' is list of XLIST responses.
|
||||||
|
|
||||||
|
thks to barduck : http://stackoverflow.com/users/602242/barduck
|
||||||
|
"""
|
||||||
|
try :
|
||||||
|
name = 'XLIST'
|
||||||
|
status, data = self._simple_command(name, directory, pattern)
|
||||||
|
return self._untagged_response(status, data, name)
|
||||||
|
except :
|
||||||
|
return 'NO', ''
|
||||||
|
|
||||||
|
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
# ~~ class ImapHelper ~~
|
||||||
|
|
||||||
|
class ImapHelper:
|
||||||
|
""""""
|
||||||
|
|
||||||
|
K_HEAD, K_DATA = 0, 1
|
||||||
|
""""""
|
||||||
|
OK = 'OK'
|
||||||
|
""""""
|
||||||
|
KO = 'NO'
|
||||||
|
""""""
|
||||||
|
ENCODING = 'utf-8'
|
||||||
|
""""""
|
||||||
|
REG_SATUS = r'^"?(.*)"? \(([^\(]*)\)'
|
||||||
|
""""""
|
||||||
|
NO_SELECT = '\\Noselect'
|
||||||
|
""""""
|
||||||
|
CHILDREN = '\\HasChildren'
|
||||||
|
""""""
|
||||||
|
NO_CHILDREN = '\\HasNoChildren'
|
||||||
|
""""""
|
||||||
|
INBOX = '\\Inbox'
|
||||||
|
""""""
|
||||||
|
DRAFTS = '\\Drafts'
|
||||||
|
""""""
|
||||||
|
TRASH = '\\Trash'
|
||||||
|
""""""
|
||||||
|
SENT = '\\Sent'
|
||||||
|
""""""
|
||||||
|
DELETED = '\\Deleted'
|
||||||
|
""""""
|
||||||
|
FLAGS = '+FLAGS'
|
||||||
|
""""""
|
||||||
|
|
||||||
|
@Log(Const.LOG_BUILD)
|
||||||
|
def __init__(self, conf, box='INBOX'):
|
||||||
|
""""""
|
||||||
|
if research('yahoo.com', conf.host) is not None :
|
||||||
|
self.DRAFTS = self.DRAFTS[:-1]
|
||||||
|
self.conf = conf
|
||||||
|
self.rootBox = box
|
||||||
|
self.BOXS = {}
|
||||||
|
self.cnx = None
|
||||||
|
self.cnxusr = None
|
||||||
|
self.switchAccount(self.conf, self.rootBox, True)
|
||||||
|
|
||||||
|
|
||||||
|
@Log()
|
||||||
|
def switchAccount(self, conf, box='INBOX', force=False):
|
||||||
|
if force or self.cnx is None or self.cnxusr is not conf.user :
|
||||||
|
try :
|
||||||
|
Sys.print(' Attempt to login... ' , Sys.Clz.fgB7, False)
|
||||||
|
Sys.print('(' , Sys.Clz.fgn7, False)
|
||||||
|
Sys.print(conf.user , Sys.Clz.fgB2, False)
|
||||||
|
Sys.print('@' , Sys.Clz.fgn7, False)
|
||||||
|
Sys.print(conf.host , Sys.Clz.fgB4, False)
|
||||||
|
Sys.print(':' , Sys.Clz.fgn7, False)
|
||||||
|
Sys.print(conf.port , Sys.Clz.fgB3, False)
|
||||||
|
Sys.print(')' , Sys.Clz.fgn7)
|
||||||
|
self.cnx = ImapClient(conf.host,conf.port)
|
||||||
|
except Exception as e :
|
||||||
|
raise BadHostException()
|
||||||
|
|
||||||
|
try :
|
||||||
|
status, resp = self.cnx.login(conf.user,conf.pwd)
|
||||||
|
|
||||||
|
except Exception as e :
|
||||||
|
status = self.KO
|
||||||
|
pass
|
||||||
|
finally :
|
||||||
|
if status == self.KO :
|
||||||
|
self.cnxusr = None
|
||||||
|
raise BadLoginException(' Cannot login with '+conf.user+':'+conf.pwd)
|
||||||
|
else :
|
||||||
|
Sys.print(' connected' , Sys.Clz.fgB2)
|
||||||
|
self.cnxusr = conf.user
|
||||||
|
try :
|
||||||
|
status, resp = self.cnx.select(self.rootBox)
|
||||||
|
if status == self.KO :
|
||||||
|
self.createBox(self.rootBox)
|
||||||
|
status, resp = self.cnx.select(self.rootBox)
|
||||||
|
self.initBoxNames()
|
||||||
|
except Exception as e :
|
||||||
|
print(e)
|
||||||
|
|
||||||
|
|
||||||
|
@Log()
|
||||||
|
def createBox(self, box):
|
||||||
|
""""""
|
||||||
|
status, resp = self.cnx.create(encode(box))
|
||||||
|
return status==self.OK
|
||||||
|
|
||||||
|
|
||||||
|
@Log()
|
||||||
|
def deleteBox(self, box):
|
||||||
|
""""""
|
||||||
|
status, resp = self.cnx.delete(encode(box))
|
||||||
|
return status==self.OK
|
||||||
|
|
||||||
|
|
||||||
|
@Log(Const.LOG_DEBUG)
|
||||||
|
def initBoxNames(self):
|
||||||
|
""""""
|
||||||
|
status, resp = self.cnx.xlist()
|
||||||
|
if status == self.OK :
|
||||||
|
bdef, bname, c = None, None, None
|
||||||
|
for c in resp :
|
||||||
|
bdef, bname = c[1:-1].split(b') "/" "')
|
||||||
|
if bdef == Io.bytes(self.NO_SELECT+' '+self.CHILDREN) :
|
||||||
|
self.BOXS['/'] = Io.str(bname)
|
||||||
|
elif bdef == Io.bytes(self.NO_CHILDREN+' '+self.INBOX) :
|
||||||
|
self.BOXS[self.INBOX] = self.INBOX[1:].upper()
|
||||||
|
elif bdef == Io.bytes(self.NO_CHILDREN+' '+self.DRAFTS) :
|
||||||
|
self.BOXS[self.DRAFTS] = Io.str(bname)
|
||||||
|
elif bdef == Io.bytes(self.NO_CHILDREN+' '+self.TRASH) :
|
||||||
|
self.BOXS[self.TRASH] = Io.str(bname)
|
||||||
|
elif bdef == Io.bytes(self.NO_CHILDREN+' '+self.SENT) :
|
||||||
|
self.BOXS[self.SENT] = Io.str(bname)
|
||||||
|
else :
|
||||||
|
self.BOXS = { '/' : '/', self.INBOX : self.INBOX[1:].upper(), self.DRAFTS : self.DRAFTS[1:], self.TRASH : self.TRASH[1:], self.SENT : self.SENT[1:] }
|
||||||
|
|
||||||
|
|
||||||
|
@Log(Const.LOG_DEBUG)
|
||||||
|
def listBox(self, box='INBOX', pattern='*'):
|
||||||
|
""""""
|
||||||
|
status, resp = self.cnx.list(box,pattern)
|
||||||
|
l = []
|
||||||
|
for r in resp :
|
||||||
|
if r is not None :
|
||||||
|
name = Io.str(r).split(' "/" ')
|
||||||
|
l.append((name[0][1:-1].split(' '),name[1][1:-1]))
|
||||||
|
return l
|
||||||
|
|
||||||
|
|
||||||
|
@Log(Const.LOG_DEBUG)
|
||||||
|
def status(self, box='INBOX'):
|
||||||
|
""""""
|
||||||
|
status, resp = self.cnx.status(box, '(MESSAGES RECENT UIDNEXT UIDVALIDITY UNSEEN)')
|
||||||
|
if status == self.OK :
|
||||||
|
data = research(self.REG_SATUS, Io.str(resp[self.K_HEAD]))
|
||||||
|
l = resplit(' ',data.group(2))
|
||||||
|
dic = {'BOX' : box}
|
||||||
|
for i in range(len(l)):
|
||||||
|
if i%2 == 0 : dic[l[i]] = int(l[i+1])
|
||||||
|
else : dic = {}
|
||||||
|
return dic
|
||||||
|
|
||||||
|
|
||||||
|
@Log()
|
||||||
|
def countSeen(self, box='INBOX'):
|
||||||
|
""""""
|
||||||
|
s = self.status(box)
|
||||||
|
return s['MESSAGES']-s['UNSEEN']
|
||||||
|
|
||||||
|
|
||||||
|
@Log()
|
||||||
|
def countUnseen(self, box='INBOX'):
|
||||||
|
""""""
|
||||||
|
return self.status(box)['UNSEEN']
|
||||||
|
|
||||||
|
|
||||||
|
@Log()
|
||||||
|
def countMsg(self, box='INBOX'):
|
||||||
|
""""""
|
||||||
|
return self.status(box)['MESSAGES']
|
||||||
|
|
||||||
|
|
||||||
|
@Log(Const.LOG_DEBUG)
|
||||||
|
def _ids(self, box='INBOX', search='ALL', charset=None, byUid=False):
|
||||||
|
""""""
|
||||||
|
status, resp = self.cnx.select(box)
|
||||||
|
if status == self.KO :
|
||||||
|
self.createBox(box)
|
||||||
|
self.cnx.select(box)
|
||||||
|
status, resp = self.cnx.search(charset, '(%s)' % search)
|
||||||
|
return resplit(' ',Io.str(resp[self.K_HEAD]))
|
||||||
|
|
||||||
|
|
||||||
|
@Log()
|
||||||
|
def idsUnseen(self, box='INBOX', charset=None):
|
||||||
|
""""""
|
||||||
|
return self._ids(box,'UNSEEN', charset)
|
||||||
|
|
||||||
|
|
||||||
|
@Log()
|
||||||
|
def idsMsg(self, box='INBOX', charset=None):
|
||||||
|
""""""
|
||||||
|
return self._ids(box,'ALL', charset)
|
||||||
|
|
||||||
|
|
||||||
|
@Log()
|
||||||
|
def idsSeen(self, box='INBOX', charset=None):
|
||||||
|
""""""
|
||||||
|
return self._ids(box,'NOT UNSEEN', charset)
|
||||||
|
|
||||||
|
|
||||||
|
@Log(Const.LOG_DEBUG)
|
||||||
|
def search(self, query, byUid=False):
|
||||||
|
""""""
|
||||||
|
if byUid :
|
||||||
|
status, resp = self.cnx.uid('search', None, query)
|
||||||
|
else :
|
||||||
|
status, resp = self.cnx.search(None, query)
|
||||||
|
ids = [m for m in resp[0].split()]
|
||||||
|
return ids
|
||||||
|
|
||||||
|
|
||||||
|
@Log()
|
||||||
|
def searchBySubject(self, subject, byUid=False):
|
||||||
|
""""""
|
||||||
|
return self.search('(SUBJECT "%s")' % subject, byUid)
|
||||||
|
|
||||||
|
|
||||||
|
@Log()
|
||||||
|
def getUid(self, mid):
|
||||||
|
""""""
|
||||||
|
value = ''
|
||||||
|
status, resp = self.cnx.fetch(mid, '(UID)')
|
||||||
|
if status==self.OK :
|
||||||
|
# '$mid (UID $uid)'
|
||||||
|
value = resp[0][len(str(mid))+6:-1]
|
||||||
|
return value
|
||||||
|
|
||||||
|
|
||||||
|
@Log(Const.LOG_DEBUG)
|
||||||
|
def fetch(self, mid, query, byUid=False):
|
||||||
|
""""""
|
||||||
|
if not byUid :
|
||||||
|
status, resp = self.cnx.fetch(mid, query)
|
||||||
|
else:
|
||||||
|
status, resp = self.cnx.uid('fetch', mid, query)
|
||||||
|
return status, resp
|
||||||
|
|
||||||
|
|
||||||
|
@Log()
|
||||||
|
def headerField(self, mid, field, byUid=False):
|
||||||
|
""""""
|
||||||
|
value = ''
|
||||||
|
field = field.upper()
|
||||||
|
query = '(UID BODY[HEADER' + ('])' if field=='*' or field=='ALL' else '.FIELDS (%s)])' % field)
|
||||||
|
status, resp = self.fetch(mid, query, byUid)
|
||||||
|
if status==self.OK and resp[0]!=None:
|
||||||
|
value = Io.str(resp[0][1][len(field)+2:-4])
|
||||||
|
return value
|
||||||
|
|
||||||
|
|
||||||
|
@Log()
|
||||||
|
def getSubject(self, mid, byUid=False):
|
||||||
|
""""""
|
||||||
|
status, resp = self.fetch(mid, '(UID BODY[HEADER.FIELDS (SUBJECT)])', byUid)
|
||||||
|
subject = decode_header(str(resp[self.K_HEAD][1][9:-4], 'utf-8'))[0]
|
||||||
|
s = subject[0]
|
||||||
|
if subject[1] :
|
||||||
|
s = str(s,subject[1])
|
||||||
|
return s
|
||||||
|
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _getIdsList(ids):
|
||||||
|
idslist = None
|
||||||
|
if isinstance(ids,list):
|
||||||
|
if len(ids) > 0 and ids[0]!='' and ids[0]!=None:
|
||||||
|
li = len(ids)-1
|
||||||
|
if int(ids[0])+li == int(ids[li]):
|
||||||
|
idslist = Io.str(ids[0]+b':'+ids[li]) if isinstance(ids[0],bytes) else str(ids[0])+':'+str(ids[li])
|
||||||
|
else :
|
||||||
|
idslist = Io.str(b','.join(ids)) if isinstance(ids[0],bytes) else ','.join(ids)
|
||||||
|
elif isinstance(ids, int) and ids > 0:
|
||||||
|
idslist = Io.str(ids)
|
||||||
|
return idslist
|
||||||
|
|
||||||
|
|
||||||
|
@Log()
|
||||||
|
def delete(self, ids, byUid=False, expunge=True):
|
||||||
|
""""""
|
||||||
|
status, delids = None, ImapHelper._getIdsList(ids)
|
||||||
|
#~ print(delids)
|
||||||
|
if delids is not None :
|
||||||
|
if byUid:
|
||||||
|
status, resp = self.cnx.uid( 'store', delids, self.FLAGS, self.DELETED )
|
||||||
|
else :
|
||||||
|
status, resp = self.cnx.store(delids, self.FLAGS, self.DELETED)
|
||||||
|
if expunge :
|
||||||
|
self.cnx.expunge()
|
||||||
|
return status == self.OK
|
||||||
|
|
||||||
|
|
||||||
|
@Log()
|
||||||
|
def clearTrash(self):
|
||||||
|
""""""
|
||||||
|
self.cnx.select(self.BOXS[self.TRASH])
|
||||||
|
ids = self.search('ALL',True)
|
||||||
|
if len(ids) > 0 and ids[0]!='' and ids[0]!=None:
|
||||||
|
delids = ImapHelper._getIdsList(ids)
|
||||||
|
status, resp = self.cnx.uid('store', delids, self.FLAGS, self.DELETED )
|
||||||
|
Sys.print(' Deleting msg ', Sys.Clz.fgn7, False, False)
|
||||||
|
Sys.print(delids , Sys.Clz.fgB1, False, False)
|
||||||
|
Sys.print(' '+status , Sys.Clz.fgB7)
|
||||||
|
self.cnx.expunge()
|
||||||
|
self.cnx.select(self.rootBox)
|
||||||
|
|
||||||
|
|
||||||
|
@Log()
|
||||||
|
def getEmail(self, mid, byUid=False):
|
||||||
|
""""""
|
||||||
|
status, resp = self.fetch(mid,'(UID RFC822)', byUid)
|
||||||
|
if status == self.OK and resp[0]!=None:
|
||||||
|
msg = message_from_bytes(resp[0][1])
|
||||||
|
else :
|
||||||
|
msg = None
|
||||||
|
return msg
|
||||||
|
|
||||||
|
|
||||||
|
@Log(Const.LOG_APP)
|
||||||
|
def getAttachment(self, msg, toDir='./', byUid=False):
|
||||||
|
""""""
|
||||||
|
if not isinstance(msg, Message) :
|
||||||
|
msg = self.getEmail(msg, byUid)
|
||||||
|
for part in msg.walk():
|
||||||
|
filename = part.get_filename()
|
||||||
|
if part.get_content_maintype() == 'multipart' or not filename : continue
|
||||||
|
with Io.wfile(Sys.join(toDir, filename)) as fo :
|
||||||
|
fo.write(part.get_payload(decode=True))
|
||||||
|
|
||||||
|
|
||||||
|
@Log()
|
||||||
|
def send(self, msg, box='INBOX'):
|
||||||
|
""""""
|
||||||
|
mid = None
|
||||||
|
date = Time2Internaldate(Sys.time())
|
||||||
|
status, resp = self.cnx.append(box, '\Draft', date, bytes(msg,'utf-8'))
|
||||||
|
if status==self.OK:
|
||||||
|
mid = str(resp[0],'utf-8')[11:-11].split(' ')
|
||||||
|
return mid
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
# ~~ class BadLoginException ~~
|
||||||
|
|
||||||
|
class BadLoginException(BaseException):
|
||||||
|
pass
|
||||||
|
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
# ~~ class BadLoginException ~~
|
||||||
|
|
||||||
|
class BadHostException(BaseException):
|
||||||
|
pass
|
170
psr/ini.py
Normal file
170
psr/ini.py
Normal file
|
@ -0,0 +1,170 @@
|
||||||
|
from re import split as regsplit
|
||||||
|
from psr.sys import Sys, Io, Const
|
||||||
|
from psr.log import Log
|
||||||
|
|
||||||
|
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
# ~~ class IniFile ~~
|
||||||
|
|
||||||
|
class IniFile:
|
||||||
|
"""Read and write inifile"""
|
||||||
|
|
||||||
|
@Log(Const.LOG_BUILD)
|
||||||
|
def __init__(self, path):
|
||||||
|
""""""
|
||||||
|
self.path = path
|
||||||
|
self.dic = {}
|
||||||
|
self.read()
|
||||||
|
|
||||||
|
|
||||||
|
@Log(Const.LOG_DEBUG)
|
||||||
|
def isEmpty(self):
|
||||||
|
""""""
|
||||||
|
return len(self.dic)==0
|
||||||
|
|
||||||
|
|
||||||
|
@Log(Const.LOG_DEBUG)
|
||||||
|
def has(self, key, section='main'):
|
||||||
|
""""""
|
||||||
|
d = self.hasSection(section) and (key in self.dic[section])
|
||||||
|
return d
|
||||||
|
|
||||||
|
|
||||||
|
@Log(Const.LOG_DEBUG)
|
||||||
|
def hasSection(self, section):
|
||||||
|
""""""
|
||||||
|
d = (section in self.dic)
|
||||||
|
return d
|
||||||
|
|
||||||
|
|
||||||
|
@Log(Const.LOG_DEBUG)
|
||||||
|
def get(self, key, section='main'):
|
||||||
|
""""""
|
||||||
|
return self.dic[section][key]
|
||||||
|
|
||||||
|
|
||||||
|
@Log(Const.LOG_DEBUG)
|
||||||
|
def set(self, key, val, section='main'):
|
||||||
|
""""""
|
||||||
|
v = None
|
||||||
|
if not section in self.dic:
|
||||||
|
self.dic[section] = {}
|
||||||
|
if key in self.dic[section]:
|
||||||
|
v = self.dic[section].pop(key)
|
||||||
|
self.dic[section][key] = str(val)
|
||||||
|
return v
|
||||||
|
|
||||||
|
|
||||||
|
@Log()
|
||||||
|
def rem(self, key, section):
|
||||||
|
""""""
|
||||||
|
v = None
|
||||||
|
if section in self.dic :
|
||||||
|
if key == '*' :
|
||||||
|
v = self.dic.pop(section)
|
||||||
|
elif key in self.dic[section]:
|
||||||
|
v = self.dic[section].pop(key)
|
||||||
|
return v
|
||||||
|
|
||||||
|
|
||||||
|
@Log()
|
||||||
|
def save(self,path=None):
|
||||||
|
""""""
|
||||||
|
Io.set_data(path if path is not None else self.path, '# last updated : '+str(Sys.datetime.now())+Const.LF+self.toString())
|
||||||
|
|
||||||
|
|
||||||
|
@Log(Const.LOG_DEBUG)
|
||||||
|
def getSection(self, section):
|
||||||
|
""""""
|
||||||
|
data = {}
|
||||||
|
for s in self.dic :
|
||||||
|
if s.startswith(section, 0) : data[s[len(section)+1:]] = self.dic[s]
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
@Log(Const.LOG_DEBUG)
|
||||||
|
def getSections(self):
|
||||||
|
""""""
|
||||||
|
l = {}
|
||||||
|
for s in self.dic:
|
||||||
|
section = s.split('.')
|
||||||
|
if len(section)> 1 and not section[0] in l :
|
||||||
|
l[section[0]] = 1
|
||||||
|
return [k for i,k in enumerate(l)]
|
||||||
|
|
||||||
|
|
||||||
|
@Log(Const.LOG_DEBUG)
|
||||||
|
def toString(self, section='*'):
|
||||||
|
""""""
|
||||||
|
content = ''
|
||||||
|
main = ''
|
||||||
|
for s in self.dic:
|
||||||
|
if section=='*' or section+'.'==s[:len(section)+1]:
|
||||||
|
if s!='main':
|
||||||
|
content += Const.LF+'['+s+']'+Const.LF
|
||||||
|
for k in sorted(self.dic[s]):
|
||||||
|
k = k.rstrip(' ')
|
||||||
|
v = self.dic[s][k] if self.dic[s][k] is not None else ''
|
||||||
|
if s!='main' :
|
||||||
|
content += k+' = '+str(v)+Const.LF
|
||||||
|
else : main += k+' = '+str(v)+Const.LF
|
||||||
|
return main + content
|
||||||
|
|
||||||
|
|
||||||
|
@Log(Const.LOG_DEBUG)
|
||||||
|
def print(self, section='*', withoutSectionName=False):
|
||||||
|
""""""
|
||||||
|
if section=='main' or section=='*' :
|
||||||
|
self.printSection('main', withoutSectionName)
|
||||||
|
|
||||||
|
for s in self.dic:
|
||||||
|
if section=='*' or section+'.'==s[:len(section)+1]:
|
||||||
|
if s!='main':
|
||||||
|
self.printSection(s, withoutSectionName)
|
||||||
|
|
||||||
|
|
||||||
|
@Log(Const.LOG_DEBUG)
|
||||||
|
def printSection(self, sectionName, withoutSectionName=False):
|
||||||
|
""""""
|
||||||
|
if sectionName!='main':
|
||||||
|
Sys.dprint()
|
||||||
|
if not withoutSectionName :
|
||||||
|
Sys.print('['+sectionName+']', Sys.Clz.fgB3)
|
||||||
|
else:
|
||||||
|
Sys.print('['+sectionName.split('.')[1]+']', Sys.Clz.fgB3)
|
||||||
|
if sectionName in self.dic :
|
||||||
|
for k in sorted(self.dic[sectionName]):
|
||||||
|
k = k.rstrip(' ')
|
||||||
|
a = ''
|
||||||
|
Sys.print(k.ljust(10,' ')+' = ' , Sys.Clz.fgn7, False)
|
||||||
|
if self.dic[sectionName][k] is not None :
|
||||||
|
if len(self.dic[sectionName][k]) > 98: a = '…'
|
||||||
|
if Sys.isUnix() or k is not 'key' :
|
||||||
|
Sys.print(self.dic[sectionName][k][:98]+a, Sys.Clz.fgN2)
|
||||||
|
else:
|
||||||
|
Sys.print('key is masked', Sys.Clz.fgb1)
|
||||||
|
|
||||||
|
@Log()
|
||||||
|
def read(self):
|
||||||
|
""""""
|
||||||
|
try:
|
||||||
|
with Io.rfile(self.path, False) as fi:
|
||||||
|
csection = 'main'
|
||||||
|
self.dic[csection] = {}
|
||||||
|
for l in fi:
|
||||||
|
l = l.rstrip().lstrip()
|
||||||
|
if len(l) > 0 and not l[0]=='#' :
|
||||||
|
d = regsplit(' *= *', l , 1)
|
||||||
|
if len(d)> 1:
|
||||||
|
self.dic[csection][d[0]] = d[1] if d[1] is not None else ''
|
||||||
|
elif len(l)>0 and l[0]=='[':
|
||||||
|
csection = l.strip('[]')
|
||||||
|
self.dic[csection] = {}
|
||||||
|
except IOError :
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@Log()
|
||||||
|
def delete(self):
|
||||||
|
Io.removeFile(self.path)
|
||||||
|
self.dic = {}
|
|
@ -86,7 +86,7 @@ class Log:
|
||||||
if not (isinstance(a, str) or isinstance(a, bytes)):
|
if not (isinstance(a, str) or isinstance(a, bytes)):
|
||||||
a = str(a)
|
a = str(a)
|
||||||
if len(a) > Sys.g.LOG_LIM_ARG_LENGTH :
|
if len(a) > Sys.g.LOG_LIM_ARG_LENGTH :
|
||||||
args[i] = a[:Sys.g.LOG_LIM_ARG_LENGTH]+'...' if isinstance(a, str) else b'...'
|
args[i] = a[:Sys.g.LOG_LIM_ARG_LENGTH]+'…' if isinstance(a, str) else bytes('…','utf-8')
|
||||||
args = str(args)[1:-1]
|
args = str(args)[1:-1]
|
||||||
if args[-1:] == ',' : args = args[:-1]
|
if args[-1:] == ',' : args = args[:-1]
|
||||||
return args
|
return args
|
||||||
|
|
14
psr/sys.py
14
psr/sys.py
|
@ -48,10 +48,10 @@ class Sys:
|
||||||
""""""
|
""""""
|
||||||
|
|
||||||
from platform import system as getSysName
|
from platform import system as getSysName
|
||||||
from os import system as sysCall, remove as removeFile, makedirs, sep, getpid
|
from os import system as sysCall, remove as removeFile, makedirs, sep, getpid, listdir
|
||||||
from getpass import getuser as getUserLogin
|
from getpass import getuser as getUserLogin
|
||||||
from time import strftime, mktime, time, localtime, sleep
|
from time import strftime, mktime, time, localtime, sleep
|
||||||
from datetime import datetime
|
from datetime import datetime, timedelta
|
||||||
from sys import exit
|
from sys import exit
|
||||||
from os.path import abspath, dirname, join, realpath, basename, getsize, isdir, splitext
|
from os.path import abspath, dirname, join, realpath, basename, getsize, isdir, splitext
|
||||||
from math import log, floor, ceil
|
from math import log, floor, ceil
|
||||||
|
@ -164,6 +164,8 @@ class Sys:
|
||||||
"""Give a human representation of bytes size `b`
|
"""Give a human representation of bytes size `b`
|
||||||
:Returns: `str`
|
:Returns: `str`
|
||||||
"""
|
"""
|
||||||
|
if b is None or b=='': return '0'
|
||||||
|
else :b = int(b)
|
||||||
units = [Const.UNIT_SHORT_B, Const.UNIT_SHORT_KIB, Const.UNIT_SHORT_MIB, Const.UNIT_SHORT_GIB, Const.UNIT_SHORT_TIB];
|
units = [Const.UNIT_SHORT_B, Const.UNIT_SHORT_KIB, Const.UNIT_SHORT_MIB, Const.UNIT_SHORT_GIB, Const.UNIT_SHORT_TIB];
|
||||||
b = max(b,0);
|
b = max(b,0);
|
||||||
if b == 0 : lb= 0
|
if b == 0 : lb= 0
|
||||||
|
@ -261,6 +263,7 @@ class Sys:
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def dprint(d='',end=Const.LF, dbcall=False):
|
def dprint(d='',end=Const.LF, dbcall=False):
|
||||||
""""""
|
""""""
|
||||||
|
dbcall = Sys.g.QUIET
|
||||||
if not dbcall :
|
if not dbcall :
|
||||||
if not Sys.g.GUI or Sys.g.GUI_PRINT_STDOUT :
|
if not Sys.g.GUI or Sys.g.GUI_PRINT_STDOUT :
|
||||||
if Sys.g.RLOCK is not None :
|
if Sys.g.RLOCK is not None :
|
||||||
|
@ -309,11 +312,16 @@ class Sys:
|
||||||
return bdata
|
return bdata
|
||||||
|
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def getDelta(t):
|
||||||
|
v = ''.join(['{:.5f}'.format(Sys.time()-(Sys.mktime(t.timetuple())+1e-6*t.microsecond)),' s'])
|
||||||
|
return v
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def pdelta(t, label='', dbcall= False):
|
def pdelta(t, label='', dbcall= False):
|
||||||
""""""
|
""""""
|
||||||
if len(label)>0 and not dbcall : Sys.print(label+' ', Sys.CLZ_IO, False)
|
if len(label)>0 and not dbcall : Sys.print(label+' ', Sys.CLZ_IO, False)
|
||||||
v = ''.join(['{:.5f}'.format(Sys.time()-(Sys.mktime(t.timetuple())+1e-6*t.microsecond)),' s'])
|
v = Sys.getDelta(t)
|
||||||
if not dbcall :
|
if not dbcall :
|
||||||
Sys.print(v, Sys.CLZ_DELTA)
|
Sys.print(v, Sys.CLZ_DELTA)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user