kirmah/psr/sys.py
2013-04-20 13:36:49 +02:00

437 lines
15 KiB
Python

#!/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