mirror of
https://github.com/Py-KMS-Organization/py-kms.git
synced 2025-07-27 12:06:09 +02:00
Made py-kms Gui working again
This commit is contained in:
parent
7c14eb10dc
commit
59fe27744e
14 changed files with 1208 additions and 335 deletions
|
@ -4,7 +4,7 @@ from __future__ import print_function, unicode_literals
|
|||
import re
|
||||
import sys
|
||||
import os
|
||||
import threading
|
||||
from collections import OrderedDict
|
||||
|
||||
try:
|
||||
# Python 2.x imports
|
||||
|
@ -21,19 +21,16 @@ pyver = sys.version_info[:2]
|
|||
def enco(strg, typ = 'latin-1'):
|
||||
if pyver >= (3, 0):
|
||||
if isinstance(strg, str):
|
||||
strgenc = strg.encode(typ)
|
||||
return strgenc
|
||||
return strg.encode(typ)
|
||||
else:
|
||||
return strg
|
||||
return strg
|
||||
|
||||
def deco(strg, typ = 'latin-1'):
|
||||
if pyver >= (3, 0):
|
||||
if isinstance(strg, bytes):
|
||||
strgdec = strg.decode(typ)
|
||||
return strgdec
|
||||
return strg.decode(typ)
|
||||
else:
|
||||
return strg
|
||||
|
||||
return strg
|
||||
|
||||
def byterize(obj):
|
||||
|
||||
|
@ -95,59 +92,96 @@ ExtraMap = {'end' : '\x1b[0m',
|
|||
}
|
||||
|
||||
ColorExtraMap = dict(ColorMap, **ExtraMap)
|
||||
ColorMapReversed = dict(zip(ColorMap.values(), ColorMap.keys()))
|
||||
ExtraMapReversed = dict(zip(ExtraMap.values(), ExtraMap.keys()))
|
||||
|
||||
MsgMap = {0 : {'text' : "{yellow}\n\t\t\tClient generating RPC Bind Request...{end}", 'where' : "clt"},
|
||||
1 : {'text' : "{white}<==============={end}{yellow}\tClient sending RPC Bind Request...{end}", 'where' : "clt"},
|
||||
2 : {'text' : "{yellow}Server received RPC Bind Request !!!\t\t\t\t{end}{white}<==============={end}", 'where' : "srv"},
|
||||
3 : {'text' : "{yellow}Server parsing RPC Bind Request...{end}", 'where' : "srv"},
|
||||
4 : {'text' : "{yellow}Server generating RPC Bind Response...{end}", 'where' : "srv"},
|
||||
5 : {'text' : "{yellow}Server sending RPC Bind Response...\t\t\t\t{end}{white}===============>{end}", 'where' : "srv"},
|
||||
6 : {'text' : "{green}{bold}\nRPC Bind acknowledged !!!{end}", 'where' : "srv"},
|
||||
7 : {'text' : "{white}===============>{end}{yellow}\tClient received RPC Bind Response !!!{end}", 'where' : "clt"},
|
||||
8 : {'text' : "{green}{bold}\t\t\tRPC Bind acknowledged !!!{end}", 'where' : "clt"},
|
||||
9 : {'text' : "{blue}\t\t\tClient generating Activation Request dictionary...{end}", 'where' : "clt"},
|
||||
10 : {'text' : "{blue}\t\t\tClient generating Activation Request data...{end}", 'where' : "clt"},
|
||||
11 : {'text' : "{blue}\t\t\tClient generating RPC Activation Request...{end}", 'where' : "clt"},
|
||||
12 : {'text' : "{white}<==============={end}{blue}\tClient sending RPC Activation Request...{end}", 'where' : "clt"},
|
||||
13 : {'text' : "{blue}Server received RPC Activation Request !!!\t\t\t{end}{white}<==============={end}", 'where' : "srv"},
|
||||
14 : {'text' : "{blue}Server parsing RPC Activation Request...{end}", 'where' : "srv"},
|
||||
15 : {'text' : "{blue}Server processing KMS Activation Request...{end}", 'where' : "srv"},
|
||||
16 : {'text' : "{blue}Server processing KMS Activation Response...{end}", 'where' : "srv"},
|
||||
17 : {'text' : "{blue}Server generating RPC Activation Response...{end}", 'where' : "srv"},
|
||||
18 : {'text' : "{blue}Server sending RPC Activation Response...\t\t\t{end}{white}===============>{end}", 'where' : "srv"},
|
||||
19 : {'text' : "{green}{bold}\nServer responded, now in Stand by...\n{end}", 'where' : "srv"},
|
||||
20 : {'text' : "{white}===============>{end}{blue}\tClient received Response !!!{end}", 'where' : "clt"},
|
||||
21 : {'text' : "{green}{bold}\t\t\tActivation Done !!!{end}", 'where' : "clt"},
|
||||
-1 : {'text' : "{white}Server receiving{end}", 'where' : "clt"},
|
||||
-2 : {'text' : "{white}\t\t\t\t\t\t\t\tClient sending{end}", 'where' : "srv"},
|
||||
-3 : {'text' : "{white}\t\t\t\t\t\t\t\tClient receiving{end}", 'where' : "srv"},
|
||||
-4 : {'text' : "{white}Server sending{end}", 'where' : "clt"},
|
||||
MsgMap = {0 : {'text' : "{yellow}\n\t\t\tClient generating RPC Bind Request...{end}", 'align' : ()},
|
||||
1 : {'text' : "{white}<==============={end}{yellow}\tClient sending RPC Bind Request...{end}", 'align' : ()},
|
||||
2 : {'text' : "{yellow}Server received RPC Bind Request !!!\t\t\t\t{end}{white}<==============={end}", 'align' : ()},
|
||||
3 : {'text' : "{yellow}Server parsing RPC Bind Request...{end}", 'align' : ()},
|
||||
4 : {'text' : "{yellow}Server generating RPC Bind Response...{end}", 'align' : ()},
|
||||
5 : {'text' : "{yellow}Server sending RPC Bind Response...\t\t\t\t{end}{white}===============>{end}", 'align' : ()},
|
||||
6 : {'text' : "{green}{bold}\nRPC Bind acknowledged !!!{end}", 'align' : ()},
|
||||
7 : {'text' : "{white}===============>{end}{yellow}\tClient received RPC Bind Response !!!{end}", 'align' : ()},
|
||||
8 : {'text' : "{green}{bold}\t\t\tRPC Bind acknowledged !!!{end}", 'align' : ()},
|
||||
9 : {'text' : "{blue}\t\t\tClient generating Activation Request dictionary...{end}", 'align' : ()},
|
||||
10 : {'text' : "{blue}\t\t\tClient generating Activation Request data...{end}", 'align' : ()},
|
||||
11 : {'text' : "{blue}\t\t\tClient generating RPC Activation Request...{end}", 'align' : ()},
|
||||
12 : {'text' : "{white}<==============={end}{blue}\tClient sending RPC Activation Request...{end}", 'align' : ()},
|
||||
13 : {'text' : "{blue}Server received RPC Activation Request !!!\t\t\t{end}{white}<==============={end}", 'align' : ()},
|
||||
14 : {'text' : "{blue}Server parsing RPC Activation Request...{end}", 'align' : ()},
|
||||
15 : {'text' : "{blue}Server processing KMS Activation Request...{end}", 'align' : ()},
|
||||
16 : {'text' : "{blue}Server processing KMS Activation Response...{end}", 'align' : ()},
|
||||
17 : {'text' : "{blue}Server generating RPC Activation Response...{end}", 'align' : ()},
|
||||
18 : {'text' : "{blue}Server sending RPC Activation Response...\t\t\t{end}{white}===============>{end}", 'align' : ()},
|
||||
19 : {'text' : "{green}{bold}\nServer responded, now in Stand by...\n{end}", 'align' : ()},
|
||||
20 : {'text' : "{white}===============>{end}{blue}\tClient received Response !!!{end}", 'align' : ()},
|
||||
21 : {'text' : "{green}{bold}\t\t\tActivation Done !!!{end}", 'align' : ()},
|
||||
-1 : {'text' : "{white}Server receiving{end}", 'align' : ()},
|
||||
-2 : {'text' : "{white}\t\t\t\t\t\t\t\tClient sending{end}", 'align' : ()},
|
||||
-3 : {'text' : "{white}\t\t\t\t\t\t\t\tClient receiving{end}", 'align' : ()},
|
||||
-4 : {'text' : "{white}Server sending{end}", 'align' : ()},
|
||||
}
|
||||
|
||||
def MsgMap_unformat(messagelist):
|
||||
def unformat_message(symbolic_string_list):
|
||||
""" `symbolic_string_list` : a list of strings with symbolic formattation, example:
|
||||
symbolic_string_list = ["{yellow}\tPluto\n{end}",
|
||||
"{reverse}{blue}======>{end}{red}\t\tPaperino{end}"]
|
||||
>>> unformat_message(symbolic_string_list)
|
||||
>>> [['\tPluto\n'], ['======>', '\t\tPaperino']]
|
||||
"""
|
||||
pattern = r"(?<!\{)\{([^}]+)\}(?!\})"
|
||||
picktxt, pickarrw = [ [] for _ in range(2) ]
|
||||
|
||||
for messageitem in messagelist:
|
||||
picklist = re.sub(pattern, '*', messageitem['text'])
|
||||
picklist = list(filter(None, picklist.split('*')))
|
||||
picktxt.append(picklist[0])
|
||||
for item in symbolic_string_list:
|
||||
try:
|
||||
pickarrw.append(picklist[1])
|
||||
except IndexError:
|
||||
pass
|
||||
return picktxt, pickarrw
|
||||
# only for py-kms MsgMap.
|
||||
picklist = re.sub(pattern, '*', item['text'])
|
||||
except:
|
||||
# generalization.
|
||||
picklist = re.sub(pattern, '*', item)
|
||||
picklist = list(filter(None, picklist.split('*')))
|
||||
picktxt.append(picklist)
|
||||
return picktxt
|
||||
|
||||
def MsgMap_unshell(arrows):
|
||||
unMsgMap = {}
|
||||
for key, values in MsgMap.items():
|
||||
txt = MsgMap_unformat([values])
|
||||
def unshell_message(ansi_string, count):
|
||||
""" `ansi_string` : a string with ansi formattation, example:
|
||||
ansi_string = '\x1b[97mPippo\x1b[0m\n\x1b[94mPluto\t\t\x1b[0m\n\x1b[92m\x1b[1m\nPaperino\n\x1b[0m\n
|
||||
`count` : int progressive increment for tag.
|
||||
>>> unshell_message(ansi_string count = 0)
|
||||
>>> ({'tag00': {'color': 'white', 'extra': [], 'text': 'Pippo'},
|
||||
'tag01': {'color': 'blue', 'extra': [], 'text': 'Pluto\t\t'}
|
||||
'tag02': {'color': 'green', 'extra': ['bold'], 'text': '\nPaperino\n'}
|
||||
}, 3)
|
||||
"""
|
||||
ansi_find = re.compile(r'\x1B\[[0-?]*[ -/]*[@-~]')
|
||||
ansi_list = re.findall(ansi_find, ansi_string)
|
||||
ansi_indx_start = [ n for n in range(len(ansi_string)) for ansi in list(set(ansi_list)) if ansi_string.find(ansi, n) == n ]
|
||||
ansi_indx_stop = [ n + len(value) for n, value in zip(ansi_indx_start, ansi_list)]
|
||||
ansi_indx = sorted(list(set(ansi_indx_start + ansi_indx_stop)))
|
||||
|
||||
if txt[0][0] in arrows:
|
||||
unMsgMap.update({txt[1][0] : values['where']})
|
||||
else:
|
||||
unMsgMap.update({txt[0][0] : values['where']})
|
||||
return unMsgMap
|
||||
msgcolored = {}
|
||||
|
||||
for k in range(len(ansi_indx) - 1):
|
||||
ansi_value = ansi_string[ansi_indx[k] : ansi_indx[k + 1]]
|
||||
if ansi_value not in ['\x1b[0m', '\n']:
|
||||
tagname = "tag" + str(count).zfill(2)
|
||||
if tagname not in msgcolored:
|
||||
msgcolored[tagname] = {'color' : '', 'extra' : [], 'text' : ''}
|
||||
|
||||
if ansi_value in ColorMapReversed.keys():
|
||||
msgcolored[tagname]['color'] = ColorMapReversed[ansi_value]
|
||||
elif ansi_value in ExtraMapReversed.keys():
|
||||
msgcolored[tagname]['extra'].append(ExtraMapReversed[ansi_value])
|
||||
else:
|
||||
msgcolored[tagname]['text'] = ansi_value
|
||||
else:
|
||||
if ansi_value != '\n':
|
||||
count += 1
|
||||
# Ordering.
|
||||
msgcolored = OrderedDict(sorted(msgcolored.items()))
|
||||
|
||||
return msgcolored, count
|
||||
|
||||
#-------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
# https://stackoverflow.com/questions/230751/how-to-flush-output-of-print-function
|
||||
|
@ -161,7 +195,10 @@ if pyver < (3, 3):
|
|||
file = kwargs.get('file', sys.stdout)
|
||||
file.flush() if file is not None else sys.stdout.flush()
|
||||
|
||||
# https://ryanjoneil.github.io/posts/2014-02-14-capturing-stdout-in-a-python-child-process.html
|
||||
# based on: https://ryanjoneil.github.io/posts/2014-02-14-capturing-stdout-in-a-python-child-process.html,
|
||||
# but not using threading/multiprocessing so:
|
||||
# 1) message visualization order preserved.
|
||||
# 2) newlines_count function output not wrong.
|
||||
class ShellMessage(object):
|
||||
view = True
|
||||
count, remain, numlist = (0, 0, [])
|
||||
|
@ -170,19 +207,20 @@ class ShellMessage(object):
|
|||
# Capture string sent to stdout.
|
||||
def write(self, s):
|
||||
StringIO.write(self, s)
|
||||
|
||||
|
||||
class Process(object):
|
||||
def __init__(self, nshell, get_text = False, put_text = None):
|
||||
def __init__(self, nshell, get_text = False, put_text = None, where = 'srv'):
|
||||
self.nshell = nshell
|
||||
self.get_text = get_text
|
||||
self.put_text = put_text
|
||||
self.print_queue = Queue.Queue()
|
||||
self.where = where
|
||||
self.plaintext = []
|
||||
self.path = os.path.dirname(os.path.abspath( __file__ )) + '/newlines.txt'
|
||||
self.print_queue = Queue.Queue()
|
||||
|
||||
def formatter(self, msgtofrmt):
|
||||
if self.newlines:
|
||||
text = MsgMap_unformat([msgtofrmt])[0][0]
|
||||
text = unformat_message([msgtofrmt])[0][0]
|
||||
msgtofrmt = msgtofrmt['text'].replace(text, self.newlines * '\n' + text)
|
||||
self.newlines = 0
|
||||
else:
|
||||
|
@ -194,40 +232,7 @@ class ShellMessage(object):
|
|||
pass
|
||||
self.msgfrmt = msgtofrmt.format(**ColorExtraMap)
|
||||
if self.get_text:
|
||||
self.plaintext.append(unshell_message(self.msgfrmt, m = 0)[0]["tag00"]['text'])
|
||||
|
||||
def run(self):
|
||||
if not ShellMessage.view:
|
||||
if self.get_text:
|
||||
self.newlines = 0
|
||||
if self.put_text is not None:
|
||||
for msg in self.put_text:
|
||||
self.formatter(msg)
|
||||
else:
|
||||
for num in self.nshell:
|
||||
self.formatter(MsgMap[num])
|
||||
return self.plaintext
|
||||
else:
|
||||
return
|
||||
|
||||
# Start thread process.
|
||||
print_thread = threading.Thread(target = self.spawn(), args=(self.print_queue,))
|
||||
print_thread.setDaemon(True)
|
||||
print_thread.start()
|
||||
# Do something with output.
|
||||
toprint = self.read(0.1) # 0.1 s to let the shell output the result
|
||||
# Redirect output.
|
||||
if sys.stdout.isatty():
|
||||
print(toprint)
|
||||
else:
|
||||
try:
|
||||
from pykms_GuiBase import gui_redirect # Import after variables creation.
|
||||
gui_redirect(toprint)
|
||||
except:
|
||||
print(toprint)
|
||||
# Get string/s printed.
|
||||
if self.get_text:
|
||||
return self.plaintext
|
||||
self.plaintext.append(unshell_message(self.msgfrmt, count = 0)[0]["tag00"]['text'])
|
||||
|
||||
def newlines_file(self, mode, *args):
|
||||
try:
|
||||
|
@ -238,15 +243,16 @@ class ShellMessage(object):
|
|||
data = [int(i) for i in [line.rstrip('\n') for line in file.readlines()]]
|
||||
self.newlines, ShellMessage.remain = data[0], sum(data[1:])
|
||||
except:
|
||||
with open(self.path, 'w') as file: pass
|
||||
with open(self.path, 'w') as file:
|
||||
pass
|
||||
|
||||
def newlines_count(self, num):
|
||||
ShellMessage.count += MsgMap[num]['text'].count('\n')
|
||||
if num >= 0:
|
||||
ShellMessage.numlist.append(num)
|
||||
if self.continuecount:
|
||||
# Note: bypassed '\n' counted after message with arrow,
|
||||
# isn't: str(len(ShellMessage.numlist) + ShellMessage.count)
|
||||
# Note: is bypassed '\n' counted after message with arrow,
|
||||
# so isn't: str(len(ShellMessage.numlist) + ShellMessage.count)
|
||||
towrite = str(len(ShellMessage.numlist)) + '\n'
|
||||
self.newlines_file('a', towrite)
|
||||
ShellMessage.count, ShellMessage.numlist = (0, [])
|
||||
|
@ -260,9 +266,41 @@ class ShellMessage(object):
|
|||
elif num in [-2 ,-4]:
|
||||
self.newlines_file('r')
|
||||
if num == 21:
|
||||
ShellMessage.count, ShellMessage.remain, ShellMessage.numlist = (0, 0, [])
|
||||
os.remove(self.path)
|
||||
|
||||
def spawn(self):
|
||||
def run(self):
|
||||
# view = False part.
|
||||
if not ShellMessage.view:
|
||||
if self.get_text:
|
||||
self.newlines = 0
|
||||
if self.put_text is not None:
|
||||
for msg in self.put_text:
|
||||
self.formatter(msg)
|
||||
else:
|
||||
for num in self.nshell:
|
||||
self.formatter(MsgMap[num])
|
||||
return self.plaintext
|
||||
else:
|
||||
return
|
||||
# Do job.
|
||||
self.produce()
|
||||
toprint = self.consume(timeout = 0.1)
|
||||
# Redirect output.
|
||||
if sys.stdout.isatty():
|
||||
print(toprint)
|
||||
else:
|
||||
try:
|
||||
# Import after variables creation.
|
||||
from pykms_GuiBase import gui_redirect
|
||||
gui_redirect(toprint, self.where)
|
||||
except:
|
||||
print(toprint)
|
||||
# Get string/s printed.
|
||||
if self.get_text:
|
||||
return self.plaintext
|
||||
|
||||
def produce(self):
|
||||
# Save everything that would otherwise go to stdout.
|
||||
outstream = ShellMessage.Collect()
|
||||
sys.stdout = outstream
|
||||
|
@ -275,6 +313,7 @@ class ShellMessage(object):
|
|||
if self.put_text is not None:
|
||||
for msg in self.put_text:
|
||||
ShellMessage.count += msg.count('\n')
|
||||
# Append a dummy element.
|
||||
ShellMessage.numlist.append('put')
|
||||
self.formatter(msg)
|
||||
print(self.msgfrmt, end = '\n', flush = True)
|
||||
|
@ -283,6 +322,8 @@ class ShellMessage(object):
|
|||
self.newlines_count(num)
|
||||
self.formatter(MsgMap[num])
|
||||
print(self.msgfrmt, end = '\n', flush = True)
|
||||
except Exception as e:
|
||||
print(e, end = '\n', flush = True)
|
||||
finally:
|
||||
# Restore stdout and send content.
|
||||
sys.stdout = sys.__stdout__
|
||||
|
@ -291,7 +332,7 @@ class ShellMessage(object):
|
|||
except Queue.Full:
|
||||
pass
|
||||
|
||||
def read(self, timeout = None):
|
||||
def consume(self, timeout = None):
|
||||
try:
|
||||
toprint = self.print_queue.get(block = timeout is not None, timeout = timeout)
|
||||
self.print_queue.task_done()
|
||||
|
@ -299,34 +340,54 @@ class ShellMessage(object):
|
|||
except Queue.Empty:
|
||||
return None
|
||||
|
||||
def pretty_printer(**kwargs):
|
||||
"""kwargs:
|
||||
`log_obj` --> if logging object specified the text not ansi
|
||||
formatted is logged.
|
||||
`get_text` --> if True obtain text not ansi formatted,
|
||||
after printing it with ansi formattation.
|
||||
`put_text` --> a string or list of strings with ansi formattation.
|
||||
if None refer to `num_text` for printing process.
|
||||
`num_text` --> a number or list of numbers refering numbered message map.
|
||||
if None `put_text` must be defined for printing process.
|
||||
`to_exit ` --> if True system exit is called.
|
||||
`where` --> specifies if message is server-side or client-side
|
||||
(useful for GUI redirect).
|
||||
"""
|
||||
# Set defaults for not defined options.
|
||||
options = {'log_obj' : None,
|
||||
'get_text' : False,
|
||||
'put_text' : None,
|
||||
'num_text' : None,
|
||||
'to_exit' : False,
|
||||
'where' : 'srv'
|
||||
}
|
||||
options.update(kwargs)
|
||||
# Check options.
|
||||
if (options['num_text'] is None) and (options['put_text'] is None):
|
||||
raise ValueError('One of `num_text` and `put_text` must be provided.')
|
||||
elif (options['num_text'] is not None) and (options['put_text'] is not None):
|
||||
raise ValueError('These parameters are mutually exclusive.')
|
||||
|
||||
def unshell_message(ansi_string, m):
|
||||
ansi_find = re.compile(r'\x1B\[[0-?]*[ -/]*[@-~]')
|
||||
ansi_list = re.findall(ansi_find, ansi_string)
|
||||
ansi_indx_start = [ n for n in range(len(ansi_string)) for ansi in list(set(ansi_list)) if ansi_string.find(ansi, n) == n ]
|
||||
ansi_indx_stop = [ n + len(value) for n, value in zip(ansi_indx_start, ansi_list)]
|
||||
ansi_indx = sorted(list(set(ansi_indx_start + ansi_indx_stop)))
|
||||
if (options['num_text'] is not None) and (not isinstance(options['num_text'], list)):
|
||||
options['num_text'] = [options['num_text']]
|
||||
if (options['put_text'] is not None) and (not isinstance(options['put_text'], list)):
|
||||
options['put_text'] = [options['put_text']]
|
||||
|
||||
msgcolored = {}
|
||||
ColorMapReversed = dict(zip(ColorMap.values(), ColorMap.keys()))
|
||||
ExtraMapReversed = dict(zip(ExtraMap.values(), ExtraMap.keys()))
|
||||
# Overwrite `get_text` (used as hidden).
|
||||
if options['put_text']:
|
||||
options['get_text'] = True
|
||||
elif options['num_text']:
|
||||
options['get_text'] = False
|
||||
|
||||
for k in range(len(ansi_indx) - 1):
|
||||
ansi_value = ansi_string[ansi_indx[k] : ansi_indx[k + 1]]
|
||||
if ansi_value != '\x1b[0m':
|
||||
tagname = "tag" + str(m).zfill(2)
|
||||
if tagname not in msgcolored:
|
||||
msgcolored[tagname] = {'color' : '', 'extra' : [], 'text' : ''}
|
||||
|
||||
if ansi_value in ColorMapReversed.keys():
|
||||
msgcolored[tagname]['color'] = ColorMapReversed[ansi_value]
|
||||
elif ansi_value in ExtraMapReversed.keys():
|
||||
msgcolored[tagname]['extra'].append(ExtraMapReversed[ansi_value])
|
||||
else:
|
||||
msgcolored[tagname]['text'] = ansi_value
|
||||
else:
|
||||
m += 1
|
||||
# Ordering.
|
||||
msgcolored = dict(sorted(msgcolored.items()))
|
||||
|
||||
return msgcolored, m
|
||||
# Process messages.
|
||||
plain_messages = ShellMessage.Process(options['num_text'],
|
||||
get_text = options['get_text'],
|
||||
put_text = options['put_text'],
|
||||
where = options['where']).run()
|
||||
|
||||
if options['log_obj']:
|
||||
for plain_message in plain_messages:
|
||||
options['log_obj'](plain_message)
|
||||
if options['to_exit']:
|
||||
sys.exit(1)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue