mirror of
https://github.com/platomav/BIOSUtilities.git
synced 2025-05-23 19:47:05 -04:00
Created common template for executing all utilities
Unified extracted output directory naming logic Multiple code fixes, refactors and improvements
This commit is contained in:
parent
5f364f4759
commit
6de50c422f
26 changed files with 377 additions and 1169 deletions
|
@ -45,7 +45,7 @@ def efi_decompress(in_path, out_path, padding=0, silent=False, comp_type='--uefi
|
|||
|
||||
if os.path.getsize(out_path) != size_orig:
|
||||
raise Exception('EFI_DECOMPRESS_ERROR')
|
||||
except:
|
||||
except Exception:
|
||||
if not silent:
|
||||
printer(f'Error: TianoCompress could not extract file {in_path}!', padding)
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ def is_szip_supported(in_path, padding=0, args=None, check=False, silent=False):
|
|||
|
||||
if check:
|
||||
check_bad_exit_code(szip_t.returncode)
|
||||
except:
|
||||
except Exception:
|
||||
if not silent:
|
||||
printer(f'Error: 7-Zip could not check support for file {in_path}!', padding)
|
||||
|
||||
|
@ -60,7 +60,7 @@ def szip_decompress(in_path, out_path, in_name, padding=0, args=None, check=Fals
|
|||
|
||||
if not os.path.isdir(out_path):
|
||||
raise Exception('EXTRACT_DIR_MISSING')
|
||||
except:
|
||||
except Exception:
|
||||
if not silent:
|
||||
printer(f'Error: 7-Zip could not extract {in_name} file {in_path}!', padding)
|
||||
|
||||
|
|
|
@ -12,8 +12,9 @@ from common.system import get_os_ver
|
|||
# https://github.com/platomav/BGScriptTool by Plato Mavropoulos
|
||||
def get_bgs_tool():
|
||||
try:
|
||||
from external.big_script_tool import BigScript
|
||||
except:
|
||||
# noinspection PyUnresolvedReferences
|
||||
from external.big_script_tool import BigScript # pylint: disable=E0401,E0611
|
||||
except Exception:
|
||||
BigScript = None
|
||||
|
||||
return BigScript
|
||||
|
@ -22,10 +23,16 @@ def get_bgs_tool():
|
|||
def get_uefifind_path():
|
||||
exec_name = f'UEFIFind{".exe" if get_os_ver()[1] else ""}'
|
||||
|
||||
return safe_path(project_root(), ['external',exec_name])
|
||||
return safe_path(project_root(), ['external', exec_name])
|
||||
|
||||
# Get UEFIExtract path
|
||||
def get_uefiextract_path():
|
||||
exec_name = f'UEFIExtract{".exe" if get_os_ver()[1] else ""}'
|
||||
|
||||
return safe_path(project_root(), ['external',exec_name])
|
||||
return safe_path(project_root(), ['external', exec_name])
|
||||
|
||||
# Get ToshibaComExtractor path
|
||||
def get_comextract_path():
|
||||
exec_name = f'comextract{".exe" if get_os_ver()[1] else ""}'
|
||||
|
||||
return safe_path(project_root(), ['external', exec_name])
|
||||
|
|
|
@ -130,58 +130,13 @@ def get_dequoted_path(in_path):
|
|||
|
||||
return out_path
|
||||
|
||||
# Get absolute file path of argparse object
|
||||
def get_argparse_path(argparse_path):
|
||||
if not argparse_path:
|
||||
# Use runtime directory if no user path is specified
|
||||
absolute_path = runtime_root()
|
||||
else:
|
||||
# Check if user specified path is absolute
|
||||
if is_path_absolute(argparse_path):
|
||||
absolute_path = argparse_path
|
||||
# Otherwise, make it runtime directory relative
|
||||
else:
|
||||
absolute_path = safe_path(runtime_root(), argparse_path)
|
||||
|
||||
return absolute_path
|
||||
# Set utility extraction stem
|
||||
def extract_suffix():
|
||||
return '_extracted'
|
||||
|
||||
# Process input files (argparse object)
|
||||
def process_input_files(argparse_args, sys_argv=None):
|
||||
input_files = []
|
||||
|
||||
if sys_argv is None:
|
||||
sys_argv = []
|
||||
|
||||
if len(sys_argv) >= 2:
|
||||
# Drag & Drop or CLI
|
||||
if argparse_args.input_dir:
|
||||
input_path_user = argparse_args.input_dir
|
||||
input_path_full = get_argparse_path(input_path_user) if input_path_user else ''
|
||||
input_files = get_path_files(input_path_full)
|
||||
else:
|
||||
# Parse list of input files (i.e. argparse FileType objects)
|
||||
for file_object in argparse_args.files:
|
||||
# Store each argparse FileType object's name (i.e. path)
|
||||
input_files.append(file_object.name)
|
||||
# Close each argparse FileType object (i.e. allow input file changes)
|
||||
file_object.close()
|
||||
|
||||
# Set output fallback value for missing argparse Output and Input Path
|
||||
output_fallback = path_parent(input_files[0]) if input_files else None
|
||||
|
||||
# Set output path via argparse Output path or argparse Input path or first input file path
|
||||
output_path = argparse_args.output_dir or argparse_args.input_dir or output_fallback
|
||||
else:
|
||||
# Script w/o parameters
|
||||
input_path_user = get_dequoted_path(input('\nEnter input directory path: '))
|
||||
input_path_full = get_argparse_path(input_path_user) if input_path_user else ''
|
||||
input_files = get_path_files(input_path_full)
|
||||
|
||||
output_path = get_dequoted_path(input('\nEnter output directory path: '))
|
||||
|
||||
output_path_final = get_argparse_path(output_path)
|
||||
|
||||
return input_files, output_path_final
|
||||
# Get utility extraction path
|
||||
def get_extract_path(in_path, suffix=extract_suffix()):
|
||||
return f'{in_path}{suffix}'
|
||||
|
||||
# Get project's root directory
|
||||
def project_root():
|
||||
|
|
|
@ -21,7 +21,7 @@ def get_pe_file(in_file, fast=True):
|
|||
try:
|
||||
# Analyze detected MZ > PE image buffer
|
||||
pe_file = pefile.PE(data=in_buffer, fast_load=fast)
|
||||
except:
|
||||
except Exception:
|
||||
pe_file = None
|
||||
|
||||
return pe_file
|
||||
|
@ -34,7 +34,7 @@ def get_pe_info(pe_file):
|
|||
|
||||
# Retrieve MZ > PE > FileInfo > StringTable information
|
||||
pe_info = pe_file.FileInfo[0][0].StringTable[0].entries
|
||||
except:
|
||||
except Exception:
|
||||
pe_info = {}
|
||||
|
||||
return pe_info
|
||||
|
|
|
@ -6,12 +6,8 @@ Copyright (C) 2022 Plato Mavropoulos
|
|||
"""
|
||||
|
||||
import sys
|
||||
import ctypes
|
||||
import argparse
|
||||
import traceback
|
||||
|
||||
from common.text_ops import padder, to_string
|
||||
from common.path_ops import process_input_files
|
||||
|
||||
# Get Python Version (tuple)
|
||||
def get_py_ver():
|
||||
|
@ -59,62 +55,6 @@ def check_sys_os():
|
|||
if os_win:
|
||||
sys.stdout.reconfigure(encoding='utf-8')
|
||||
|
||||
# Initialize common argparse arguments
|
||||
def argparse_init():
|
||||
argparser = argparse.ArgumentParser()
|
||||
|
||||
argparser.add_argument('files', type=argparse.FileType('r'), nargs='*')
|
||||
argparser.add_argument('-e', '--auto-exit', help='skip press enter to exit prompts', action='store_true')
|
||||
argparser.add_argument('-v', '--version', help='show utility name and version', action='store_true')
|
||||
argparser.add_argument('-o', '--output-dir', help='extract in given output directory')
|
||||
argparser.add_argument('-i', '--input-dir', help='extract from given input directory')
|
||||
|
||||
return argparser
|
||||
|
||||
# Initialize Script (must be after argparse)
|
||||
def script_init(title, arguments, padding=0):
|
||||
# Pretty Python exception handler
|
||||
sys.excepthook = nice_exc_handler
|
||||
|
||||
# Check Python Version
|
||||
check_sys_py()
|
||||
|
||||
# Check OS Platform
|
||||
check_sys_os()
|
||||
|
||||
# Show Script Title
|
||||
printer(title, new_line=False)
|
||||
|
||||
# Show Utility Version on demand
|
||||
if arguments.version:
|
||||
sys.exit(0)
|
||||
|
||||
# Set console/terminal window title (Windows only)
|
||||
if get_os_ver()[1]:
|
||||
ctypes.windll.kernel32.SetConsoleTitleW(title)
|
||||
|
||||
# Process input files and generate output path
|
||||
input_files,output_path = process_input_files(arguments, sys.argv)
|
||||
|
||||
# Count input files for exit code
|
||||
input_count = len(input_files)
|
||||
|
||||
return input_count, input_files, output_path, padding
|
||||
|
||||
# https://stackoverflow.com/a/781074 by Torsten Marek
|
||||
def nice_exc_handler(exc_type, exc_value, tb):
|
||||
if exc_type is KeyboardInterrupt:
|
||||
printer('')
|
||||
else:
|
||||
printer('Error: Script crashed, please report the following:\n')
|
||||
|
||||
traceback.print_exception(exc_type, exc_value, tb)
|
||||
|
||||
if not is_auto_exit():
|
||||
input('\nPress enter to exit')
|
||||
|
||||
sys.exit(127)
|
||||
|
||||
# Show message(s) while controlling padding, newline, pausing & separator
|
||||
def printer(in_message='', padd_count=0, new_line=True, pause=False, sep_char=' '):
|
||||
message = to_string(in_message, sep_char)
|
||||
|
|
152
common/templates.py
Normal file
152
common/templates.py
Normal file
|
@ -0,0 +1,152 @@
|
|||
#!/usr/bin/env python3
|
||||
#coding=utf-8
|
||||
|
||||
"""
|
||||
Copyright (C) 2022 Plato Mavropoulos
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import ctypes
|
||||
import argparse
|
||||
import traceback
|
||||
|
||||
from common.path_ops import runtime_root, is_path_absolute, safe_path, get_dequoted_path, get_path_files, path_parent, get_extract_path
|
||||
from common.system import check_sys_py, check_sys_os, get_os_ver, printer, is_auto_exit
|
||||
|
||||
class BIOSUtility:
|
||||
|
||||
def __init__(self, title, check, main, padding=0):
|
||||
self._title = title
|
||||
self._main = main
|
||||
self._check = check
|
||||
self._padding = padding
|
||||
self._arguments_kw = {}
|
||||
|
||||
# Initialize argparse argument parser
|
||||
self._argparser = argparse.ArgumentParser()
|
||||
|
||||
self._argparser.add_argument('files', type=argparse.FileType('r', encoding='utf-8'), nargs='*')
|
||||
self._argparser.add_argument('-e', '--auto-exit', help='skip press enter to exit prompts', action='store_true')
|
||||
self._argparser.add_argument('-v', '--version', help='show utility name and version', action='store_true')
|
||||
self._argparser.add_argument('-o', '--output-dir', help='extract in given output directory')
|
||||
self._argparser.add_argument('-i', '--input-dir', help='extract from given input directory')
|
||||
|
||||
self._arguments,self._arguments_unk = self._argparser.parse_known_args()
|
||||
|
||||
# Managed Python exception handler
|
||||
sys.excepthook = self._exception_handler
|
||||
|
||||
# Check Python Version
|
||||
check_sys_py()
|
||||
|
||||
# Check OS Platform
|
||||
check_sys_os()
|
||||
|
||||
# Show Script Title
|
||||
printer(self._title, new_line=False)
|
||||
|
||||
# Show Utility Version on demand
|
||||
if self._arguments.version:
|
||||
sys.exit(0)
|
||||
|
||||
# Set console/terminal window title (Windows only)
|
||||
if get_os_ver()[1]:
|
||||
ctypes.windll.kernel32.SetConsoleTitleW(self._title)
|
||||
|
||||
# Process input files and generate output path
|
||||
self._process_input_files()
|
||||
|
||||
# Count input files for exit code
|
||||
self.exit_code = len(self._input_files)
|
||||
|
||||
def parse_argument(self, *args, **kwargs):
|
||||
_dest = self._argparser.add_argument(*args, **kwargs).dest
|
||||
self._arguments = self._argparser.parse_known_args(self._arguments_unk)[0]
|
||||
self._arguments_kw.update({_dest: self._arguments.__dict__[_dest]})
|
||||
|
||||
def run_utility(self):
|
||||
for _input_file in self._input_files:
|
||||
_input_name = os.path.basename(_input_file)
|
||||
|
||||
printer(['***', _input_name], self._padding)
|
||||
|
||||
if not self._check(_input_file):
|
||||
printer('Error: This is not a supported input!', self._padding + 4)
|
||||
|
||||
continue # Next input file
|
||||
|
||||
_extract_path = os.path.join(self._output_path, get_extract_path(_input_name))
|
||||
|
||||
if self._main(_input_file, _extract_path, self._padding + 4, **self._arguments_kw) in [0, None]:
|
||||
self.exit_code -= 1
|
||||
|
||||
#print(self.exit_code)
|
||||
|
||||
printer('Done!', pause=True)
|
||||
|
||||
sys.exit(self.exit_code)
|
||||
|
||||
# Process input files
|
||||
def _process_input_files(self):
|
||||
self._input_files = []
|
||||
|
||||
if len(sys.argv) >= 2:
|
||||
# Drag & Drop or CLI
|
||||
if self._arguments.input_dir:
|
||||
_input_path_user = self._arguments.input_dir
|
||||
_input_path_full = self._get_input_path(_input_path_user) if _input_path_user else ''
|
||||
self._input_files = get_path_files(_input_path_full)
|
||||
else:
|
||||
# Parse list of input files (i.e. argparse FileType objects)
|
||||
for _file_object in self._arguments.files:
|
||||
# Store each argparse FileType object's name (i.e. path)
|
||||
self._input_files.append(_file_object.name)
|
||||
# Close each argparse FileType object (i.e. allow input file changes)
|
||||
_file_object.close()
|
||||
|
||||
# Set output fallback value for missing argparse Output and Input Path
|
||||
_output_fallback = path_parent(self._input_files[0]) if self._input_files else None
|
||||
|
||||
# Set output path via argparse Output path or argparse Input path or first input file path
|
||||
_output_path = self._arguments.output_dir or self._arguments.input_dir or _output_fallback
|
||||
else:
|
||||
# Script w/o parameters
|
||||
_input_path_user = get_dequoted_path(input('\nEnter input directory path: '))
|
||||
_input_path_full = self._get_input_path(_input_path_user) if _input_path_user else ''
|
||||
self._input_files = get_path_files(_input_path_full)
|
||||
|
||||
_output_path = get_dequoted_path(input('\nEnter output directory path: '))
|
||||
|
||||
self._output_path = self._get_input_path(_output_path)
|
||||
|
||||
# Get absolute input file path
|
||||
@staticmethod
|
||||
def _get_input_path(input_path):
|
||||
if not input_path:
|
||||
# Use runtime directory if no user path is specified
|
||||
absolute_path = runtime_root()
|
||||
else:
|
||||
# Check if user specified path is absolute
|
||||
if is_path_absolute(input_path):
|
||||
absolute_path = input_path
|
||||
# Otherwise, make it runtime directory relative
|
||||
else:
|
||||
absolute_path = safe_path(runtime_root(), input_path)
|
||||
|
||||
return absolute_path
|
||||
|
||||
# https://stackoverflow.com/a/781074 by Torsten Marek
|
||||
@staticmethod
|
||||
def _exception_handler(exc_type, exc_value, exc_traceback):
|
||||
if exc_type is KeyboardInterrupt:
|
||||
printer('')
|
||||
else:
|
||||
printer('Error: Utility crashed, please report the following:\n')
|
||||
|
||||
traceback.print_exception(exc_type, exc_value, exc_traceback)
|
||||
|
||||
if not is_auto_exit():
|
||||
input('\nPress enter to exit')
|
||||
|
||||
sys.exit(127)
|
Loading…
Add table
Add a link
Reference in a new issue