mirror of
https://github.com/mbusb/multibootusb
synced 2024-11-01 15:40:16 +00:00
Merge pull request #148 from alindt/fixes
Fixes & added colours to terminal output
This commit is contained in:
commit
7323699cbd
34
multibootusb
Normal file → Executable file
34
multibootusb
Normal file → Executable file
@ -18,11 +18,13 @@ try:
|
|||||||
from scripts.mbusb_cli import *
|
from scripts.mbusb_cli import *
|
||||||
from scripts import admin
|
from scripts import admin
|
||||||
from scripts import gen
|
from scripts import gen
|
||||||
|
from scripts import config
|
||||||
except:
|
except:
|
||||||
try:
|
try:
|
||||||
from .scripts.mbusb_cli import *
|
from .scripts.mbusb_cli import *
|
||||||
from .scripts import admin
|
from .scripts import admin
|
||||||
from .scripts import gen
|
from .scripts import gen
|
||||||
|
from .scripts import config
|
||||||
except:
|
except:
|
||||||
import scripts
|
import scripts
|
||||||
|
|
||||||
@ -33,16 +35,17 @@ uninstall = False
|
|||||||
|
|
||||||
|
|
||||||
def usage():
|
def usage():
|
||||||
print('\nAn advanced multi boot live usb creator using command line.')
|
print('\n An advanced multiboot live usb creator using command line.')
|
||||||
print('\nUsage: python3 multibootusb -c -i /path/to/iso [option(s)] -t /path/to/device\n')
|
print('\n Usage: python3 multibootusb [option(s)]\n')
|
||||||
print('[option(s)] are :\n')
|
print(' Options:\n')
|
||||||
print(' -h or --help : Print this help message and exit')
|
print(' -h or --help : Print this help message and exit')
|
||||||
print(' -i or --iso : Path to ISO file')
|
print(' -i or --iso : Path to ISO file')
|
||||||
print(' -t or --target : Path to target USB device partition (example /dev/sdb1)\n')
|
print(' -t or --target : Path to target USB device partition (example /dev/sdb1)')
|
||||||
print(' -c or --command : This option is must for invoking multibootusb from command line\n')
|
print(' -c or --command : This option is must for invoking multibootusb from command line')
|
||||||
print(' -u or --uninstall : List and uninstall distro from USB disk')
|
print(' -u or --uninstall : List and uninstall distro from USB disk')
|
||||||
print(' Command line example for making a bootable USB from command line should look like this:-\n')
|
print(' -d or --debug : Enable debug messages (very verbose!)\n')
|
||||||
print(' python3 multibootusb -c -i ../../favourite.iso -t /dev/sdb1\n')
|
print(' Command line example for making a bootable USB from command line should look like this:\n')
|
||||||
|
print('\tpython3 multibootusb -c -i ../../favourite.iso -t /dev/sdb1\n')
|
||||||
exit(2)
|
exit(2)
|
||||||
|
|
||||||
|
|
||||||
@ -63,8 +66,8 @@ if __name__ == '__main__':
|
|||||||
admin.runAsAdmin()
|
admin.runAsAdmin()
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
try:
|
try:
|
||||||
opts, args = getopt.getopt(sys.argv[1:], 'i:t:vhcu',
|
opts, args = getopt.getopt(sys.argv[1:], 'i:t:vhcud',
|
||||||
['iso=', 'target=', 'version', 'help', 'command', 'uninstall'])
|
['iso=', 'target=', 'version', 'help', 'command', 'uninstall', 'debug'])
|
||||||
except getopt.GetoptError:
|
except getopt.GetoptError:
|
||||||
usage()
|
usage()
|
||||||
sys.exit(2)
|
sys.exit(2)
|
||||||
@ -83,6 +86,8 @@ if __name__ == '__main__':
|
|||||||
gui = False
|
gui = False
|
||||||
elif opt in ('-u', '--uninstall'):
|
elif opt in ('-u', '--uninstall'):
|
||||||
uninstall = True
|
uninstall = True
|
||||||
|
elif opt in ('-d', '--debug'):
|
||||||
|
config.debug = True
|
||||||
else:
|
else:
|
||||||
gui = True
|
gui = True
|
||||||
#start_gui()
|
#start_gui()
|
||||||
@ -91,6 +96,11 @@ if __name__ == '__main__':
|
|||||||
sys.exit()
|
sys.exit()
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
if config.debug is True:
|
||||||
|
from scripts.debug import colors
|
||||||
|
print(colors.HEADER + "=== DEBUG ENABLED ===")
|
||||||
|
|
||||||
|
|
||||||
if gui is False:
|
if gui is False:
|
||||||
if uninstall is True and config.usb_disk is not None:
|
if uninstall is True and config.usb_disk is not None:
|
||||||
cli_uninstall_distro()
|
cli_uninstall_distro()
|
||||||
|
7
scripts/colorama/__init__.py
Normal file
7
scripts/colorama/__init__.py
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file.
|
||||||
|
from .initialise import init, deinit, reinit, colorama_text
|
||||||
|
from .ansi import Fore, Back, Style, Cursor
|
||||||
|
from .ansitowin32 import AnsiToWin32
|
||||||
|
|
||||||
|
__version__ = '0.3.8'
|
||||||
|
|
102
scripts/colorama/ansi.py
Normal file
102
scripts/colorama/ansi.py
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file.
|
||||||
|
'''
|
||||||
|
This module generates ANSI character codes to printing colors to terminals.
|
||||||
|
See: http://en.wikipedia.org/wiki/ANSI_escape_code
|
||||||
|
'''
|
||||||
|
|
||||||
|
CSI = '\033['
|
||||||
|
OSC = '\033]'
|
||||||
|
BEL = '\007'
|
||||||
|
|
||||||
|
|
||||||
|
def code_to_chars(code):
|
||||||
|
return CSI + str(code) + 'm'
|
||||||
|
|
||||||
|
def set_title(title):
|
||||||
|
return OSC + '2;' + title + BEL
|
||||||
|
|
||||||
|
def clear_screen(mode=2):
|
||||||
|
return CSI + str(mode) + 'J'
|
||||||
|
|
||||||
|
def clear_line(mode=2):
|
||||||
|
return CSI + str(mode) + 'K'
|
||||||
|
|
||||||
|
|
||||||
|
class AnsiCodes(object):
|
||||||
|
def __init__(self):
|
||||||
|
# the subclasses declare class attributes which are numbers.
|
||||||
|
# Upon instantiation we define instance attributes, which are the same
|
||||||
|
# as the class attributes but wrapped with the ANSI escape sequence
|
||||||
|
for name in dir(self):
|
||||||
|
if not name.startswith('_'):
|
||||||
|
value = getattr(self, name)
|
||||||
|
setattr(self, name, code_to_chars(value))
|
||||||
|
|
||||||
|
|
||||||
|
class AnsiCursor(object):
|
||||||
|
def UP(self, n=1):
|
||||||
|
return CSI + str(n) + 'A'
|
||||||
|
def DOWN(self, n=1):
|
||||||
|
return CSI + str(n) + 'B'
|
||||||
|
def FORWARD(self, n=1):
|
||||||
|
return CSI + str(n) + 'C'
|
||||||
|
def BACK(self, n=1):
|
||||||
|
return CSI + str(n) + 'D'
|
||||||
|
def POS(self, x=1, y=1):
|
||||||
|
return CSI + str(y) + ';' + str(x) + 'H'
|
||||||
|
|
||||||
|
|
||||||
|
class AnsiFore(AnsiCodes):
|
||||||
|
BLACK = 30
|
||||||
|
RED = 31
|
||||||
|
GREEN = 32
|
||||||
|
YELLOW = 33
|
||||||
|
BLUE = 34
|
||||||
|
MAGENTA = 35
|
||||||
|
CYAN = 36
|
||||||
|
WHITE = 37
|
||||||
|
RESET = 39
|
||||||
|
|
||||||
|
# These are fairly well supported, but not part of the standard.
|
||||||
|
LIGHTBLACK_EX = 90
|
||||||
|
LIGHTRED_EX = 91
|
||||||
|
LIGHTGREEN_EX = 92
|
||||||
|
LIGHTYELLOW_EX = 93
|
||||||
|
LIGHTBLUE_EX = 94
|
||||||
|
LIGHTMAGENTA_EX = 95
|
||||||
|
LIGHTCYAN_EX = 96
|
||||||
|
LIGHTWHITE_EX = 97
|
||||||
|
|
||||||
|
|
||||||
|
class AnsiBack(AnsiCodes):
|
||||||
|
BLACK = 40
|
||||||
|
RED = 41
|
||||||
|
GREEN = 42
|
||||||
|
YELLOW = 43
|
||||||
|
BLUE = 44
|
||||||
|
MAGENTA = 45
|
||||||
|
CYAN = 46
|
||||||
|
WHITE = 47
|
||||||
|
RESET = 49
|
||||||
|
|
||||||
|
# These are fairly well supported, but not part of the standard.
|
||||||
|
LIGHTBLACK_EX = 100
|
||||||
|
LIGHTRED_EX = 101
|
||||||
|
LIGHTGREEN_EX = 102
|
||||||
|
LIGHTYELLOW_EX = 103
|
||||||
|
LIGHTBLUE_EX = 104
|
||||||
|
LIGHTMAGENTA_EX = 105
|
||||||
|
LIGHTCYAN_EX = 106
|
||||||
|
LIGHTWHITE_EX = 107
|
||||||
|
|
||||||
|
|
||||||
|
class AnsiStyle(AnsiCodes):
|
||||||
|
BRIGHT = 1
|
||||||
|
DIM = 2
|
||||||
|
NORMAL = 22
|
||||||
|
RESET_ALL = 0
|
||||||
|
|
||||||
|
Fore = AnsiFore()
|
||||||
|
Back = AnsiBack()
|
||||||
|
Style = AnsiStyle()
|
||||||
|
Cursor = AnsiCursor()
|
239
scripts/colorama/ansitowin32.py
Normal file
239
scripts/colorama/ansitowin32.py
Normal file
@ -0,0 +1,239 @@
|
|||||||
|
# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file.
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
|
||||||
|
from .ansi import AnsiFore, AnsiBack, AnsiStyle, Style
|
||||||
|
from .winterm import WinTerm, WinColor, WinStyle
|
||||||
|
from .win32 import windll, winapi_test
|
||||||
|
|
||||||
|
|
||||||
|
winterm = None
|
||||||
|
if windll is not None:
|
||||||
|
winterm = WinTerm()
|
||||||
|
|
||||||
|
|
||||||
|
def is_stream_closed(stream):
|
||||||
|
return not hasattr(stream, 'closed') or stream.closed
|
||||||
|
|
||||||
|
|
||||||
|
def is_a_tty(stream):
|
||||||
|
return hasattr(stream, 'isatty') and stream.isatty()
|
||||||
|
|
||||||
|
|
||||||
|
class StreamWrapper(object):
|
||||||
|
'''
|
||||||
|
Wraps a stream (such as stdout), acting as a transparent proxy for all
|
||||||
|
attribute access apart from method 'write()', which is delegated to our
|
||||||
|
Converter instance.
|
||||||
|
'''
|
||||||
|
def __init__(self, wrapped, converter):
|
||||||
|
# double-underscore everything to prevent clashes with names of
|
||||||
|
# attributes on the wrapped stream object.
|
||||||
|
self.__wrapped = wrapped
|
||||||
|
self.__convertor = converter
|
||||||
|
|
||||||
|
def __getattr__(self, name):
|
||||||
|
return getattr(self.__wrapped, name)
|
||||||
|
|
||||||
|
def write(self, text):
|
||||||
|
self.__convertor.write(text)
|
||||||
|
|
||||||
|
def fileno():
|
||||||
|
raise OSError()
|
||||||
|
|
||||||
|
|
||||||
|
class AnsiToWin32(object):
|
||||||
|
'''
|
||||||
|
Implements a 'write()' method which, on Windows, will strip ANSI character
|
||||||
|
sequences from the text, and if outputting to a tty, will convert them into
|
||||||
|
win32 function calls.
|
||||||
|
'''
|
||||||
|
ANSI_CSI_RE = re.compile('\001?\033\\[((?:\\d|;)*)([a-zA-Z])\002?') # Control Sequence Introducer
|
||||||
|
ANSI_OSC_RE = re.compile('\001?\033\\]((?:.|;)*?)(\x07)\002?') # Operating System Command
|
||||||
|
|
||||||
|
def __init__(self, wrapped, convert=None, strip=None, autoreset=False):
|
||||||
|
# The wrapped stream (normally sys.stdout or sys.stderr)
|
||||||
|
self.wrapped = wrapped
|
||||||
|
|
||||||
|
# should we reset colors to defaults after every .write()
|
||||||
|
self.autoreset = autoreset
|
||||||
|
|
||||||
|
# create the proxy wrapping our output stream
|
||||||
|
self.stream = StreamWrapper(wrapped, self)
|
||||||
|
|
||||||
|
on_windows = os.name == 'nt'
|
||||||
|
# We test if the WinAPI works, because even if we are on Windows
|
||||||
|
# we may be using a terminal that doesn't support the WinAPI
|
||||||
|
# (e.g. Cygwin Terminal). In this case it's up to the terminal
|
||||||
|
# to support the ANSI codes.
|
||||||
|
conversion_supported = on_windows and winapi_test()
|
||||||
|
|
||||||
|
# should we strip ANSI sequences from our output?
|
||||||
|
if strip is None:
|
||||||
|
strip = conversion_supported or (not is_stream_closed(wrapped) and not is_a_tty(wrapped))
|
||||||
|
self.strip = strip
|
||||||
|
|
||||||
|
# should we should convert ANSI sequences into win32 calls?
|
||||||
|
if convert is None:
|
||||||
|
convert = conversion_supported and not is_stream_closed(wrapped) and is_a_tty(wrapped)
|
||||||
|
self.convert = convert
|
||||||
|
|
||||||
|
# dict of ansi codes to win32 functions and parameters
|
||||||
|
self.win32_calls = self.get_win32_calls()
|
||||||
|
|
||||||
|
# are we wrapping stderr?
|
||||||
|
self.on_stderr = self.wrapped is sys.stderr
|
||||||
|
|
||||||
|
def should_wrap(self):
|
||||||
|
'''
|
||||||
|
True if this class is actually needed. If false, then the output
|
||||||
|
stream will not be affected, nor will win32 calls be issued, so
|
||||||
|
wrapping stdout is not actually required. This will generally be
|
||||||
|
False on non-Windows platforms, unless optional functionality like
|
||||||
|
autoreset has been requested using kwargs to init()
|
||||||
|
'''
|
||||||
|
return self.convert or self.strip or self.autoreset
|
||||||
|
|
||||||
|
def get_win32_calls(self):
|
||||||
|
if self.convert and winterm:
|
||||||
|
return {
|
||||||
|
AnsiStyle.RESET_ALL: (winterm.reset_all, ),
|
||||||
|
AnsiStyle.BRIGHT: (winterm.style, WinStyle.BRIGHT),
|
||||||
|
AnsiStyle.DIM: (winterm.style, WinStyle.NORMAL),
|
||||||
|
AnsiStyle.NORMAL: (winterm.style, WinStyle.NORMAL),
|
||||||
|
AnsiFore.BLACK: (winterm.fore, WinColor.BLACK),
|
||||||
|
AnsiFore.RED: (winterm.fore, WinColor.RED),
|
||||||
|
AnsiFore.GREEN: (winterm.fore, WinColor.GREEN),
|
||||||
|
AnsiFore.YELLOW: (winterm.fore, WinColor.YELLOW),
|
||||||
|
AnsiFore.BLUE: (winterm.fore, WinColor.BLUE),
|
||||||
|
AnsiFore.MAGENTA: (winterm.fore, WinColor.MAGENTA),
|
||||||
|
AnsiFore.CYAN: (winterm.fore, WinColor.CYAN),
|
||||||
|
AnsiFore.WHITE: (winterm.fore, WinColor.GREY),
|
||||||
|
AnsiFore.RESET: (winterm.fore, ),
|
||||||
|
AnsiFore.LIGHTBLACK_EX: (winterm.fore, WinColor.BLACK, True),
|
||||||
|
AnsiFore.LIGHTRED_EX: (winterm.fore, WinColor.RED, True),
|
||||||
|
AnsiFore.LIGHTGREEN_EX: (winterm.fore, WinColor.GREEN, True),
|
||||||
|
AnsiFore.LIGHTYELLOW_EX: (winterm.fore, WinColor.YELLOW, True),
|
||||||
|
AnsiFore.LIGHTBLUE_EX: (winterm.fore, WinColor.BLUE, True),
|
||||||
|
AnsiFore.LIGHTMAGENTA_EX: (winterm.fore, WinColor.MAGENTA, True),
|
||||||
|
AnsiFore.LIGHTCYAN_EX: (winterm.fore, WinColor.CYAN, True),
|
||||||
|
AnsiFore.LIGHTWHITE_EX: (winterm.fore, WinColor.GREY, True),
|
||||||
|
AnsiBack.BLACK: (winterm.back, WinColor.BLACK),
|
||||||
|
AnsiBack.RED: (winterm.back, WinColor.RED),
|
||||||
|
AnsiBack.GREEN: (winterm.back, WinColor.GREEN),
|
||||||
|
AnsiBack.YELLOW: (winterm.back, WinColor.YELLOW),
|
||||||
|
AnsiBack.BLUE: (winterm.back, WinColor.BLUE),
|
||||||
|
AnsiBack.MAGENTA: (winterm.back, WinColor.MAGENTA),
|
||||||
|
AnsiBack.CYAN: (winterm.back, WinColor.CYAN),
|
||||||
|
AnsiBack.WHITE: (winterm.back, WinColor.GREY),
|
||||||
|
AnsiBack.RESET: (winterm.back, ),
|
||||||
|
AnsiBack.LIGHTBLACK_EX: (winterm.back, WinColor.BLACK, True),
|
||||||
|
AnsiBack.LIGHTRED_EX: (winterm.back, WinColor.RED, True),
|
||||||
|
AnsiBack.LIGHTGREEN_EX: (winterm.back, WinColor.GREEN, True),
|
||||||
|
AnsiBack.LIGHTYELLOW_EX: (winterm.back, WinColor.YELLOW, True),
|
||||||
|
AnsiBack.LIGHTBLUE_EX: (winterm.back, WinColor.BLUE, True),
|
||||||
|
AnsiBack.LIGHTMAGENTA_EX: (winterm.back, WinColor.MAGENTA, True),
|
||||||
|
AnsiBack.LIGHTCYAN_EX: (winterm.back, WinColor.CYAN, True),
|
||||||
|
AnsiBack.LIGHTWHITE_EX: (winterm.back, WinColor.GREY, True),
|
||||||
|
}
|
||||||
|
return dict()
|
||||||
|
|
||||||
|
def write(self, text):
|
||||||
|
if self.strip or self.convert:
|
||||||
|
self.write_and_convert(text)
|
||||||
|
else:
|
||||||
|
self.wrapped.write(text)
|
||||||
|
self.wrapped.flush()
|
||||||
|
if self.autoreset:
|
||||||
|
self.reset_all()
|
||||||
|
|
||||||
|
|
||||||
|
def reset_all(self):
|
||||||
|
if self.convert:
|
||||||
|
self.call_win32('m', (0,))
|
||||||
|
elif not self.strip and not is_stream_closed(self.wrapped):
|
||||||
|
self.wrapped.write(Style.RESET_ALL)
|
||||||
|
|
||||||
|
|
||||||
|
def write_and_convert(self, text):
|
||||||
|
'''
|
||||||
|
Write the given text to our wrapped stream, stripping any ANSI
|
||||||
|
sequences from the text, and optionally converting them into win32
|
||||||
|
calls.
|
||||||
|
'''
|
||||||
|
cursor = 0
|
||||||
|
text = self.convert_osc(text)
|
||||||
|
for match in self.ANSI_CSI_RE.finditer(text):
|
||||||
|
start, end = match.span()
|
||||||
|
self.write_plain_text(text, cursor, start)
|
||||||
|
self.convert_ansi(*match.groups())
|
||||||
|
cursor = end
|
||||||
|
self.write_plain_text(text, cursor, len(text))
|
||||||
|
|
||||||
|
|
||||||
|
def write_plain_text(self, text, start, end):
|
||||||
|
if start < end:
|
||||||
|
self.wrapped.write(text[start:end])
|
||||||
|
self.wrapped.flush()
|
||||||
|
|
||||||
|
|
||||||
|
def convert_ansi(self, paramstring, command):
|
||||||
|
if self.convert:
|
||||||
|
params = self.extract_params(command, paramstring)
|
||||||
|
self.call_win32(command, params)
|
||||||
|
|
||||||
|
|
||||||
|
def extract_params(self, command, paramstring):
|
||||||
|
if command in 'Hf':
|
||||||
|
params = tuple(int(p) if len(p) != 0 else 1 for p in paramstring.split(';'))
|
||||||
|
while len(params) < 2:
|
||||||
|
# defaults:
|
||||||
|
params = params + (1,)
|
||||||
|
else:
|
||||||
|
params = tuple(int(p) for p in paramstring.split(';') if len(p) != 0)
|
||||||
|
if len(params) == 0:
|
||||||
|
# defaults:
|
||||||
|
if command in 'JKm':
|
||||||
|
params = (0,)
|
||||||
|
elif command in 'ABCD':
|
||||||
|
params = (1,)
|
||||||
|
|
||||||
|
return params
|
||||||
|
|
||||||
|
|
||||||
|
def call_win32(self, command, params):
|
||||||
|
if command == 'm':
|
||||||
|
for param in params:
|
||||||
|
if param in self.win32_calls:
|
||||||
|
func_args = self.win32_calls[param]
|
||||||
|
func = func_args[0]
|
||||||
|
args = func_args[1:]
|
||||||
|
kwargs = dict(on_stderr=self.on_stderr)
|
||||||
|
func(*args, **kwargs)
|
||||||
|
elif command in 'J':
|
||||||
|
winterm.erase_screen(params[0], on_stderr=self.on_stderr)
|
||||||
|
elif command in 'K':
|
||||||
|
winterm.erase_line(params[0], on_stderr=self.on_stderr)
|
||||||
|
elif command in 'Hf': # cursor position - absolute
|
||||||
|
winterm.set_cursor_position(params, on_stderr=self.on_stderr)
|
||||||
|
elif command in 'ABCD': # cursor position - relative
|
||||||
|
n = params[0]
|
||||||
|
# A - up, B - down, C - forward, D - back
|
||||||
|
x, y = {'A': (0, -n), 'B': (0, n), 'C': (n, 0), 'D': (-n, 0)}[command]
|
||||||
|
winterm.cursor_adjust(x, y, on_stderr=self.on_stderr)
|
||||||
|
|
||||||
|
|
||||||
|
def convert_osc(self, text):
|
||||||
|
for match in self.ANSI_OSC_RE.finditer(text):
|
||||||
|
start, end = match.span()
|
||||||
|
text = text[:start] + text[end:]
|
||||||
|
paramstring, command = match.groups()
|
||||||
|
if command in '\x07': # \x07 = BEL
|
||||||
|
params = paramstring.split(";")
|
||||||
|
# 0 - change title and icon (we will only change title)
|
||||||
|
# 1 - change icon (we don't support this)
|
||||||
|
# 2 - change title
|
||||||
|
if params[0] in '02':
|
||||||
|
winterm.set_title(params[1])
|
||||||
|
return text
|
82
scripts/colorama/initialise.py
Normal file
82
scripts/colorama/initialise.py
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file.
|
||||||
|
import atexit
|
||||||
|
import contextlib
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from .ansitowin32 import AnsiToWin32
|
||||||
|
|
||||||
|
|
||||||
|
orig_stdout = None
|
||||||
|
orig_stderr = None
|
||||||
|
|
||||||
|
wrapped_stdout = None
|
||||||
|
wrapped_stderr = None
|
||||||
|
|
||||||
|
atexit_done = False
|
||||||
|
|
||||||
|
|
||||||
|
def reset_all():
|
||||||
|
if AnsiToWin32 is not None: # Issue #74: objects might become None at exit
|
||||||
|
AnsiToWin32(orig_stdout).reset_all()
|
||||||
|
|
||||||
|
|
||||||
|
def init(autoreset=False, convert=None, strip=None, wrap=True):
|
||||||
|
|
||||||
|
if not wrap and any([autoreset, convert, strip]):
|
||||||
|
raise ValueError('wrap=False conflicts with any other arg=True')
|
||||||
|
|
||||||
|
global wrapped_stdout, wrapped_stderr
|
||||||
|
global orig_stdout, orig_stderr
|
||||||
|
|
||||||
|
orig_stdout = sys.stdout
|
||||||
|
orig_stderr = sys.stderr
|
||||||
|
|
||||||
|
if sys.stdout is None:
|
||||||
|
wrapped_stdout = None
|
||||||
|
else:
|
||||||
|
sys.stdout = wrapped_stdout = \
|
||||||
|
wrap_stream(orig_stdout, convert, strip, autoreset, wrap)
|
||||||
|
if sys.stderr is None:
|
||||||
|
wrapped_stderr = None
|
||||||
|
else:
|
||||||
|
sys.stderr = wrapped_stderr = \
|
||||||
|
wrap_stream(orig_stderr, convert, strip, autoreset, wrap)
|
||||||
|
|
||||||
|
global atexit_done
|
||||||
|
if not atexit_done:
|
||||||
|
atexit.register(reset_all)
|
||||||
|
atexit_done = True
|
||||||
|
|
||||||
|
|
||||||
|
def deinit():
|
||||||
|
if orig_stdout is not None:
|
||||||
|
sys.stdout = orig_stdout
|
||||||
|
if orig_stderr is not None:
|
||||||
|
sys.stderr = orig_stderr
|
||||||
|
|
||||||
|
|
||||||
|
@contextlib.contextmanager
|
||||||
|
def colorama_text(*args, **kwargs):
|
||||||
|
init(*args, **kwargs)
|
||||||
|
try:
|
||||||
|
yield
|
||||||
|
finally:
|
||||||
|
deinit()
|
||||||
|
|
||||||
|
|
||||||
|
def reinit():
|
||||||
|
if wrapped_stdout is not None:
|
||||||
|
sys.stdout = wrapped_stdout
|
||||||
|
if wrapped_stderr is not None:
|
||||||
|
sys.stderr = wrapped_stderr
|
||||||
|
|
||||||
|
|
||||||
|
def wrap_stream(stream, convert, strip, autoreset, wrap):
|
||||||
|
if wrap:
|
||||||
|
wrapper = AnsiToWin32(stream,
|
||||||
|
convert=convert, strip=strip, autoreset=autoreset)
|
||||||
|
if wrapper.should_wrap():
|
||||||
|
stream = wrapper.stream
|
||||||
|
return stream
|
||||||
|
|
||||||
|
|
156
scripts/colorama/win32.py
Normal file
156
scripts/colorama/win32.py
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file.
|
||||||
|
|
||||||
|
# from winbase.h
|
||||||
|
STDOUT = -11
|
||||||
|
STDERR = -12
|
||||||
|
|
||||||
|
try:
|
||||||
|
import ctypes
|
||||||
|
from ctypes import LibraryLoader
|
||||||
|
windll = LibraryLoader(ctypes.WinDLL)
|
||||||
|
from ctypes import wintypes
|
||||||
|
except (AttributeError, ImportError):
|
||||||
|
windll = None
|
||||||
|
SetConsoleTextAttribute = lambda *_: None
|
||||||
|
winapi_test = lambda *_: None
|
||||||
|
else:
|
||||||
|
from ctypes import byref, Structure, c_char, POINTER
|
||||||
|
|
||||||
|
COORD = wintypes._COORD
|
||||||
|
|
||||||
|
class CONSOLE_SCREEN_BUFFER_INFO(Structure):
|
||||||
|
"""struct in wincon.h."""
|
||||||
|
_fields_ = [
|
||||||
|
("dwSize", COORD),
|
||||||
|
("dwCursorPosition", COORD),
|
||||||
|
("wAttributes", wintypes.WORD),
|
||||||
|
("srWindow", wintypes.SMALL_RECT),
|
||||||
|
("dwMaximumWindowSize", COORD),
|
||||||
|
]
|
||||||
|
def __str__(self):
|
||||||
|
return '(%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)' % (
|
||||||
|
self.dwSize.Y, self.dwSize.X
|
||||||
|
, self.dwCursorPosition.Y, self.dwCursorPosition.X
|
||||||
|
, self.wAttributes
|
||||||
|
, self.srWindow.Top, self.srWindow.Left, self.srWindow.Bottom, self.srWindow.Right
|
||||||
|
, self.dwMaximumWindowSize.Y, self.dwMaximumWindowSize.X
|
||||||
|
)
|
||||||
|
|
||||||
|
_GetStdHandle = windll.kernel32.GetStdHandle
|
||||||
|
_GetStdHandle.argtypes = [
|
||||||
|
wintypes.DWORD,
|
||||||
|
]
|
||||||
|
_GetStdHandle.restype = wintypes.HANDLE
|
||||||
|
|
||||||
|
_GetConsoleScreenBufferInfo = windll.kernel32.GetConsoleScreenBufferInfo
|
||||||
|
_GetConsoleScreenBufferInfo.argtypes = [
|
||||||
|
wintypes.HANDLE,
|
||||||
|
POINTER(CONSOLE_SCREEN_BUFFER_INFO),
|
||||||
|
]
|
||||||
|
_GetConsoleScreenBufferInfo.restype = wintypes.BOOL
|
||||||
|
|
||||||
|
_SetConsoleTextAttribute = windll.kernel32.SetConsoleTextAttribute
|
||||||
|
_SetConsoleTextAttribute.argtypes = [
|
||||||
|
wintypes.HANDLE,
|
||||||
|
wintypes.WORD,
|
||||||
|
]
|
||||||
|
_SetConsoleTextAttribute.restype = wintypes.BOOL
|
||||||
|
|
||||||
|
_SetConsoleCursorPosition = windll.kernel32.SetConsoleCursorPosition
|
||||||
|
_SetConsoleCursorPosition.argtypes = [
|
||||||
|
wintypes.HANDLE,
|
||||||
|
COORD,
|
||||||
|
]
|
||||||
|
_SetConsoleCursorPosition.restype = wintypes.BOOL
|
||||||
|
|
||||||
|
_FillConsoleOutputCharacterA = windll.kernel32.FillConsoleOutputCharacterA
|
||||||
|
_FillConsoleOutputCharacterA.argtypes = [
|
||||||
|
wintypes.HANDLE,
|
||||||
|
c_char,
|
||||||
|
wintypes.DWORD,
|
||||||
|
COORD,
|
||||||
|
POINTER(wintypes.DWORD),
|
||||||
|
]
|
||||||
|
_FillConsoleOutputCharacterA.restype = wintypes.BOOL
|
||||||
|
|
||||||
|
_FillConsoleOutputAttribute = windll.kernel32.FillConsoleOutputAttribute
|
||||||
|
_FillConsoleOutputAttribute.argtypes = [
|
||||||
|
wintypes.HANDLE,
|
||||||
|
wintypes.WORD,
|
||||||
|
wintypes.DWORD,
|
||||||
|
COORD,
|
||||||
|
POINTER(wintypes.DWORD),
|
||||||
|
]
|
||||||
|
_FillConsoleOutputAttribute.restype = wintypes.BOOL
|
||||||
|
|
||||||
|
_SetConsoleTitleW = windll.kernel32.SetConsoleTitleW
|
||||||
|
_SetConsoleTitleW.argtypes = [
|
||||||
|
wintypes.LPCWSTR
|
||||||
|
]
|
||||||
|
_SetConsoleTitleW.restype = wintypes.BOOL
|
||||||
|
|
||||||
|
handles = {
|
||||||
|
STDOUT: _GetStdHandle(STDOUT),
|
||||||
|
STDERR: _GetStdHandle(STDERR),
|
||||||
|
}
|
||||||
|
|
||||||
|
def _winapi_test(handle):
|
||||||
|
csbi = CONSOLE_SCREEN_BUFFER_INFO()
|
||||||
|
success = _GetConsoleScreenBufferInfo(
|
||||||
|
handle, byref(csbi))
|
||||||
|
return bool(success)
|
||||||
|
|
||||||
|
def winapi_test():
|
||||||
|
return any(_winapi_test(h) for h in handles.values())
|
||||||
|
|
||||||
|
def GetConsoleScreenBufferInfo(stream_id=STDOUT):
|
||||||
|
handle = handles[stream_id]
|
||||||
|
csbi = CONSOLE_SCREEN_BUFFER_INFO()
|
||||||
|
success = _GetConsoleScreenBufferInfo(
|
||||||
|
handle, byref(csbi))
|
||||||
|
return csbi
|
||||||
|
|
||||||
|
def SetConsoleTextAttribute(stream_id, attrs):
|
||||||
|
handle = handles[stream_id]
|
||||||
|
return _SetConsoleTextAttribute(handle, attrs)
|
||||||
|
|
||||||
|
def SetConsoleCursorPosition(stream_id, position, adjust=True):
|
||||||
|
position = COORD(*position)
|
||||||
|
# If the position is out of range, do nothing.
|
||||||
|
if position.Y <= 0 or position.X <= 0:
|
||||||
|
return
|
||||||
|
# Adjust for Windows' SetConsoleCursorPosition:
|
||||||
|
# 1. being 0-based, while ANSI is 1-based.
|
||||||
|
# 2. expecting (x,y), while ANSI uses (y,x).
|
||||||
|
adjusted_position = COORD(position.Y - 1, position.X - 1)
|
||||||
|
if adjust:
|
||||||
|
# Adjust for viewport's scroll position
|
||||||
|
sr = GetConsoleScreenBufferInfo(STDOUT).srWindow
|
||||||
|
adjusted_position.Y += sr.Top
|
||||||
|
adjusted_position.X += sr.Left
|
||||||
|
# Resume normal processing
|
||||||
|
handle = handles[stream_id]
|
||||||
|
return _SetConsoleCursorPosition(handle, adjusted_position)
|
||||||
|
|
||||||
|
def FillConsoleOutputCharacter(stream_id, char, length, start):
|
||||||
|
handle = handles[stream_id]
|
||||||
|
char = c_char(char.encode())
|
||||||
|
length = wintypes.DWORD(length)
|
||||||
|
num_written = wintypes.DWORD(0)
|
||||||
|
# Note that this is hard-coded for ANSI (vs wide) bytes.
|
||||||
|
success = _FillConsoleOutputCharacterA(
|
||||||
|
handle, char, length, start, byref(num_written))
|
||||||
|
return num_written.value
|
||||||
|
|
||||||
|
def FillConsoleOutputAttribute(stream_id, attr, length, start):
|
||||||
|
''' FillConsoleOutputAttribute( hConsole, csbi.wAttributes, dwConSize, coordScreen, &cCharsWritten )'''
|
||||||
|
handle = handles[stream_id]
|
||||||
|
attribute = wintypes.WORD(attr)
|
||||||
|
length = wintypes.DWORD(length)
|
||||||
|
num_written = wintypes.DWORD(0)
|
||||||
|
# Note that this is hard-coded for ANSI (vs wide) bytes.
|
||||||
|
return _FillConsoleOutputAttribute(
|
||||||
|
handle, attribute, length, start, byref(num_written))
|
||||||
|
|
||||||
|
def SetConsoleTitle(title):
|
||||||
|
return _SetConsoleTitleW(title)
|
162
scripts/colorama/winterm.py
Normal file
162
scripts/colorama/winterm.py
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file.
|
||||||
|
from . import win32
|
||||||
|
|
||||||
|
|
||||||
|
# from wincon.h
|
||||||
|
class WinColor(object):
|
||||||
|
BLACK = 0
|
||||||
|
BLUE = 1
|
||||||
|
GREEN = 2
|
||||||
|
CYAN = 3
|
||||||
|
RED = 4
|
||||||
|
MAGENTA = 5
|
||||||
|
YELLOW = 6
|
||||||
|
GREY = 7
|
||||||
|
|
||||||
|
# from wincon.h
|
||||||
|
class WinStyle(object):
|
||||||
|
NORMAL = 0x00 # dim text, dim background
|
||||||
|
BRIGHT = 0x08 # bright text, dim background
|
||||||
|
BRIGHT_BACKGROUND = 0x80 # dim text, bright background
|
||||||
|
|
||||||
|
class WinTerm(object):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self._default = win32.GetConsoleScreenBufferInfo(win32.STDOUT).wAttributes
|
||||||
|
self.set_attrs(self._default)
|
||||||
|
self._default_fore = self._fore
|
||||||
|
self._default_back = self._back
|
||||||
|
self._default_style = self._style
|
||||||
|
# In order to emulate LIGHT_EX in windows, we borrow the BRIGHT style.
|
||||||
|
# So that LIGHT_EX colors and BRIGHT style do not clobber each other,
|
||||||
|
# we track them separately, since LIGHT_EX is overwritten by Fore/Back
|
||||||
|
# and BRIGHT is overwritten by Style codes.
|
||||||
|
self._light = 0
|
||||||
|
|
||||||
|
def get_attrs(self):
|
||||||
|
return self._fore + self._back * 16 + (self._style | self._light)
|
||||||
|
|
||||||
|
def set_attrs(self, value):
|
||||||
|
self._fore = value & 7
|
||||||
|
self._back = (value >> 4) & 7
|
||||||
|
self._style = value & (WinStyle.BRIGHT | WinStyle.BRIGHT_BACKGROUND)
|
||||||
|
|
||||||
|
def reset_all(self, on_stderr=None):
|
||||||
|
self.set_attrs(self._default)
|
||||||
|
self.set_console(attrs=self._default)
|
||||||
|
|
||||||
|
def fore(self, fore=None, light=False, on_stderr=False):
|
||||||
|
if fore is None:
|
||||||
|
fore = self._default_fore
|
||||||
|
self._fore = fore
|
||||||
|
# Emulate LIGHT_EX with BRIGHT Style
|
||||||
|
if light:
|
||||||
|
self._light |= WinStyle.BRIGHT
|
||||||
|
else:
|
||||||
|
self._light &= ~WinStyle.BRIGHT
|
||||||
|
self.set_console(on_stderr=on_stderr)
|
||||||
|
|
||||||
|
def back(self, back=None, light=False, on_stderr=False):
|
||||||
|
if back is None:
|
||||||
|
back = self._default_back
|
||||||
|
self._back = back
|
||||||
|
# Emulate LIGHT_EX with BRIGHT_BACKGROUND Style
|
||||||
|
if light:
|
||||||
|
self._light |= WinStyle.BRIGHT_BACKGROUND
|
||||||
|
else:
|
||||||
|
self._light &= ~WinStyle.BRIGHT_BACKGROUND
|
||||||
|
self.set_console(on_stderr=on_stderr)
|
||||||
|
|
||||||
|
def style(self, style=None, on_stderr=False):
|
||||||
|
if style is None:
|
||||||
|
style = self._default_style
|
||||||
|
self._style = style
|
||||||
|
self.set_console(on_stderr=on_stderr)
|
||||||
|
|
||||||
|
def set_console(self, attrs=None, on_stderr=False):
|
||||||
|
if attrs is None:
|
||||||
|
attrs = self.get_attrs()
|
||||||
|
handle = win32.STDOUT
|
||||||
|
if on_stderr:
|
||||||
|
handle = win32.STDERR
|
||||||
|
win32.SetConsoleTextAttribute(handle, attrs)
|
||||||
|
|
||||||
|
def get_position(self, handle):
|
||||||
|
position = win32.GetConsoleScreenBufferInfo(handle).dwCursorPosition
|
||||||
|
# Because Windows coordinates are 0-based,
|
||||||
|
# and win32.SetConsoleCursorPosition expects 1-based.
|
||||||
|
position.X += 1
|
||||||
|
position.Y += 1
|
||||||
|
return position
|
||||||
|
|
||||||
|
def set_cursor_position(self, position=None, on_stderr=False):
|
||||||
|
if position is None:
|
||||||
|
# I'm not currently tracking the position, so there is no default.
|
||||||
|
# position = self.get_position()
|
||||||
|
return
|
||||||
|
handle = win32.STDOUT
|
||||||
|
if on_stderr:
|
||||||
|
handle = win32.STDERR
|
||||||
|
win32.SetConsoleCursorPosition(handle, position)
|
||||||
|
|
||||||
|
def cursor_adjust(self, x, y, on_stderr=False):
|
||||||
|
handle = win32.STDOUT
|
||||||
|
if on_stderr:
|
||||||
|
handle = win32.STDERR
|
||||||
|
position = self.get_position(handle)
|
||||||
|
adjusted_position = (position.Y + y, position.X + x)
|
||||||
|
win32.SetConsoleCursorPosition(handle, adjusted_position, adjust=False)
|
||||||
|
|
||||||
|
def erase_screen(self, mode=0, on_stderr=False):
|
||||||
|
# 0 should clear from the cursor to the end of the screen.
|
||||||
|
# 1 should clear from the cursor to the beginning of the screen.
|
||||||
|
# 2 should clear the entire screen, and move cursor to (1,1)
|
||||||
|
handle = win32.STDOUT
|
||||||
|
if on_stderr:
|
||||||
|
handle = win32.STDERR
|
||||||
|
csbi = win32.GetConsoleScreenBufferInfo(handle)
|
||||||
|
# get the number of character cells in the current buffer
|
||||||
|
cells_in_screen = csbi.dwSize.X * csbi.dwSize.Y
|
||||||
|
# get number of character cells before current cursor position
|
||||||
|
cells_before_cursor = csbi.dwSize.X * csbi.dwCursorPosition.Y + csbi.dwCursorPosition.X
|
||||||
|
if mode == 0:
|
||||||
|
from_coord = csbi.dwCursorPosition
|
||||||
|
cells_to_erase = cells_in_screen - cells_before_cursor
|
||||||
|
if mode == 1:
|
||||||
|
from_coord = win32.COORD(0, 0)
|
||||||
|
cells_to_erase = cells_before_cursor
|
||||||
|
elif mode == 2:
|
||||||
|
from_coord = win32.COORD(0, 0)
|
||||||
|
cells_to_erase = cells_in_screen
|
||||||
|
# fill the entire screen with blanks
|
||||||
|
win32.FillConsoleOutputCharacter(handle, ' ', cells_to_erase, from_coord)
|
||||||
|
# now set the buffer's attributes accordingly
|
||||||
|
win32.FillConsoleOutputAttribute(handle, self.get_attrs(), cells_to_erase, from_coord)
|
||||||
|
if mode == 2:
|
||||||
|
# put the cursor where needed
|
||||||
|
win32.SetConsoleCursorPosition(handle, (1, 1))
|
||||||
|
|
||||||
|
def erase_line(self, mode=0, on_stderr=False):
|
||||||
|
# 0 should clear from the cursor to the end of the line.
|
||||||
|
# 1 should clear from the cursor to the beginning of the line.
|
||||||
|
# 2 should clear the entire line.
|
||||||
|
handle = win32.STDOUT
|
||||||
|
if on_stderr:
|
||||||
|
handle = win32.STDERR
|
||||||
|
csbi = win32.GetConsoleScreenBufferInfo(handle)
|
||||||
|
if mode == 0:
|
||||||
|
from_coord = csbi.dwCursorPosition
|
||||||
|
cells_to_erase = csbi.dwSize.X - csbi.dwCursorPosition.X
|
||||||
|
if mode == 1:
|
||||||
|
from_coord = win32.COORD(0, csbi.dwCursorPosition.Y)
|
||||||
|
cells_to_erase = csbi.dwCursorPosition.X
|
||||||
|
elif mode == 2:
|
||||||
|
from_coord = win32.COORD(0, csbi.dwCursorPosition.Y)
|
||||||
|
cells_to_erase = csbi.dwSize.X
|
||||||
|
# fill the entire screen with blanks
|
||||||
|
win32.FillConsoleOutputCharacter(handle, ' ', cells_to_erase, from_coord)
|
||||||
|
# now set the buffer's attributes accordingly
|
||||||
|
win32.FillConsoleOutputAttribute(handle, self.get_attrs(), cells_to_erase, from_coord)
|
||||||
|
|
||||||
|
def set_title(self, title):
|
||||||
|
win32.SetConsoleTitle(title)
|
@ -37,3 +37,5 @@ editors_linux = ["xdg-open", "gedit", "kate", "kwrite"]
|
|||||||
editors_win = ["notepad++.exe", "notepad.exe"]
|
editors_win = ["notepad++.exe", "notepad.exe"]
|
||||||
|
|
||||||
imager_usb_disk = []
|
imager_usb_disk = []
|
||||||
|
|
||||||
|
debug = False
|
||||||
|
53
scripts/debug.py
Normal file
53
scripts/debug.py
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
import os
|
||||||
|
import platform
|
||||||
|
import inspect
|
||||||
|
from . import config
|
||||||
|
|
||||||
|
try:
|
||||||
|
from colorama import init as colorama_init, Fore, Back, Style
|
||||||
|
except:
|
||||||
|
try:
|
||||||
|
from .colorama import init as colorama_init, Fore, Back, Style
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
finally:
|
||||||
|
try:
|
||||||
|
colorama_init(autoreset=True)
|
||||||
|
class colors:
|
||||||
|
HEADER = Fore.MAGENTA + Style.BRIGHT
|
||||||
|
OKBLUE = Fore.BLUE + Style.BRIGHT
|
||||||
|
OKGREEN = Fore.GREEN + Style.BRIGHT
|
||||||
|
WARNING = Fore.YELLOW + Style.BRIGHT
|
||||||
|
FAIL = Fore.RED + Style.BRIGHT
|
||||||
|
RESET = Style.RESET_ALL
|
||||||
|
BOLD = Style.BRIGHT
|
||||||
|
UNDERLINE = '\033[4m'
|
||||||
|
except NameError:
|
||||||
|
class colors:
|
||||||
|
HEADER = ''
|
||||||
|
OKBLUE = ''
|
||||||
|
OKGREEN = ''
|
||||||
|
WARNING = ''
|
||||||
|
FAIL = ''
|
||||||
|
RESET = ''
|
||||||
|
BOLD = ''
|
||||||
|
UNDERLINE = ''
|
||||||
|
finally:
|
||||||
|
config.debug and print(colors.HEADER + "=== DEBUG ENABLED ===")
|
||||||
|
|
||||||
|
def fnCall():
|
||||||
|
"""
|
||||||
|
Prints filename:line:function for parent and grandparent.
|
||||||
|
"""
|
||||||
|
|
||||||
|
if not config.debug: return
|
||||||
|
|
||||||
|
print(colors.OKGREEN + colors.BOLD + "=== DEBUG === | %s:%d:%s() called from %s:%d:%s()" % (
|
||||||
|
inspect.stack()[1][1].split(os.sep)[-1],
|
||||||
|
inspect.stack()[1][2],
|
||||||
|
inspect.stack()[1][3],
|
||||||
|
inspect.stack()[2][1].split(os.sep)[-1],
|
||||||
|
inspect.stack()[2][2],
|
||||||
|
inspect.stack()[2][3],
|
||||||
|
)+colors.RESET)
|
||||||
|
|
@ -140,9 +140,8 @@ def install_progress():
|
|||||||
thrd.start()
|
thrd.start()
|
||||||
pbar = progressbar.ProgressBar(maxval=100).start() # bar = progressbar.ProgressBar(redirect_stdout=True)
|
pbar = progressbar.ProgressBar(maxval=100).start() # bar = progressbar.ProgressBar(redirect_stdout=True)
|
||||||
while thrd.is_alive():
|
while thrd.is_alive():
|
||||||
current_size = details(config.usb_disk)['size_used']
|
current_size = shutil.disk_usage(usb_details['mount_point'])[1]
|
||||||
percentage = int((current_size / final_size) * 100)
|
percentage = int((current_size / final_size) * 100)
|
||||||
# log("Install at " + str(percentage) + "%")
|
|
||||||
if percentage > 100:
|
if percentage > 100:
|
||||||
percentage = 100
|
percentage = 100
|
||||||
config.percentage = percentage
|
config.percentage = percentage
|
||||||
|
Loading…
Reference in New Issue
Block a user