Skip to content

Commit

Permalink
Merge pull request #472 from Johann-PLW/main
Browse files Browse the repository at this point in the history
Version 3.2.1 - .spec files for Windows et macOS binaries
  • Loading branch information
Johann-PLW authored Mar 24, 2024
2 parents 82c6296 + 0bf3481 commit 85328a6
Show file tree
Hide file tree
Showing 7 changed files with 170 additions and 98 deletions.
107 changes: 53 additions & 54 deletions aleapp.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,74 +42,70 @@ def validate_args(args):
raise argparse.ArgumentError(None, 'Unknown timezone! Run the program again.')


def create_profile(available_plugins, path):
available_parsers = []
for parser_data in available_plugins:
if parser_data.name != 'usagestatsVersion':
available_parsers.append((parser_data.category, parser_data.name))

available_parsers.sort()
parsers_in_profile = {}

def create_profile(plugins, path):
available_modules = [(module_data.category, module_data.name) for module_data in plugins]
available_modules.sort()
modules_in_profile = {}

user_choice = ''
print('--- ALEAPP Profile file creation ---\n')
instructions = 'You can type:\n'
instructions += ' - \'a\' to add or remove parsers in the profile file\n'
instructions += ' - \'l\' to display the list of all available parsers with their number\n'
instructions += ' - \'p\' to display the parsers added into the profile file\n'
instructions += ' - \'a\' to add or remove modules in the profile file\n'
instructions += ' - \'l\' to display the list of all available modules with their number\n'
instructions += ' - \'p\' to display the modules added into the profile file\n'
instructions += ' - \'q\' to quit and save\n'
while not user_choice:
print(instructions)
user_choice = input('Please enter your choice: ').lower()
print()
if user_choice == "l":
print('Available parsers:')
for number, available_plugin in enumerate(available_parsers):
print(number + 1, available_plugin)
print('Available modules:')
for number, available_module in enumerate(available_modules):
print(number + 1, available_module)
print()
user_choice = ''
elif user_choice == "p":
if parsers_in_profile:
for number, parser in parsers_in_profile.items():
print(number, parser)
if modules_in_profile:
for number, module in modules_in_profile.items():
print(number, module)
print()
else:
print('No parser added to the profile file\n')
print('No module added to the profile file\n')
user_choice = ''
elif user_choice == 'a':
parser_numbers = input('Enter the numbers of parsers, seperated by a comma, to add or remove in the profile file: ')
parser_numbers = parser_numbers.split(',')
parser_numbers = [parser_number.strip() for parser_number in parser_numbers]
for parser_number in parser_numbers:
if parser_number.isdigit():
parser_number = int(parser_number)
if parser_number > 0 and parser_number <= len(available_parsers):
if parser_number not in parsers_in_profile:
parser_to_add = available_parsers[parser_number - 1]
parsers_in_profile[parser_number] = parser_to_add
print(f'parser number {parser_number} {parser_to_add} was added')
modules_numbers = input('Enter the numbers of modules, seperated by a comma, to add or remove in the profile file: ')
modules_numbers = modules_numbers.split(',')
modules_numbers = [module_number.strip() for module_number in modules_numbers]
for module_number in modules_numbers:
if module_number.isdigit():
module_number = int(module_number)
if module_number > 0 and module_number <= len(available_modules):
if module_number not in modules_in_profile:
module_to_add = available_modules[module_number - 1]
modules_in_profile[module_number] = module_to_add
print(f'module number {module_number} {module_to_add} was added')
else:
parser_to_remove = parsers_in_profile[parser_number]
print(f'parser number {parser_number} {parser_to_remove} was removed')
del parsers_in_profile[parser_number]
module_to_remove = modules_in_profile[module_number]
print(f'module number {module_number} {module_to_remove} was removed')
del modules_in_profile[module_number]
else:
print('Please enter the number of a parser!!!\n')
print('Please enter the number of a module!!!\n')
print()
user_choice = ''
elif user_choice == "q":
if parsers_in_profile:
parsers = [parser_info[1] for parser_info in parsers_in_profile.values()]
if modules_in_profile:
modules = [module_info[1] for module_info in modules_in_profile.values()]
profile_filename = ''
while not profile_filename:
profile_filename = input('Enter the name of the profile: ')
profile_filename += '.alprofile'
filename = os.path.join(path, profile_filename)
with open(filename, "wt", encoding="utf-8") as profile_file:
json.dump({"leapp": "aleapp", "format_version": 1, "plugins": parsers}, profile_file)
json.dump({"leapp": "aleapp", "format_version": 1, "plugins": modules}, profile_file)
print('\nProfile saved:', filename)
print()
else:
print('No parser added. The profile file was not created.\n')
print('No module added. The profile file was not created.\n')
print()
return
else:
Expand Down Expand Up @@ -162,13 +158,16 @@ def main():
profile_filename = None
casedata = {}

# Move usagestatsVersion plugin to first position
usagestatsVersion_index = next((i for i, selected_plugin in enumerate(available_plugins)
if selected_plugin.name == 'usagestatsVersion'), -1)
if usagestatsVersion_index != -1:
available_plugins.insert(0, available_plugins.pop(usagestatsVersion_index))
plugins = []
plugins_parsed_first = []

for plugin in available_plugins:
if plugin.name == 'usagestatsVersion':
plugins_parsed_first.append(plugin)
else:
plugins.append(plugin)

selected_plugins = available_plugins.copy()
selected_plugins = plugins.copy()

args = parser.parse_args()

Expand Down Expand Up @@ -207,7 +206,7 @@ def main():
create_choice = input('Please enter your choice: ').lower()
print()
if create_choice == '1':
create_profile(selected_plugins, args.create_profile_casedata)
create_profile(plugins, args.create_profile_casedata)
create_choice = ''
elif create_choice == '2':
create_casedata(args.create_profile_casedata)
Expand Down Expand Up @@ -264,10 +263,9 @@ def main():
print(profile_load_error)
return
else:
print(f'Profile loaded: {profile_filename}')
profile_plugins = set(profile.get("plugins", []))
selected_plugins = [selected_plugin for selected_plugin in available_plugins
if selected_plugin.name in profile_plugins or selected_plugin.name == 'usagestatsVersion']
selected_plugins = [selected_plugin for selected_plugin in plugins
if selected_plugin.name in profile_plugins]
else:
profile_load_error = "File was not a valid profile file: invalid format"
print(profile_load_error)
Expand All @@ -278,16 +276,17 @@ def main():
wrap_text = args.wrap_text
output_path = os.path.abspath(args.output_path)
time_offset = args.timezone

# Android file system extractions contain paths > 260 char, which causes problems
# This fixes the problem by prefixing \\?\ on each windows path.
if is_platform_windows():
if input_path[1] == ':' and extracttype =='fs': input_path = '\\\\?\\' + input_path.replace('/', '\\')
if output_path[1] == ':': output_path = '\\\\?\\' + output_path.replace('/', '\\')

out_params = OutputParameters(output_path)
print(f"Info: {len(available_plugins)} plugins loaded.")

selected_plugins = plugins_parsed_first + selected_plugins

crunch_artifacts(selected_plugins, extracttype, input_path, out_params, wrap_text, loader, casedata, time_offset, profile_filename)


Expand Down Expand Up @@ -329,9 +328,10 @@ def crunch_artifacts(
return False

# Now ready to run
logfunc(f'Info: {len(loader) - 1} modules loaded.') # excluding usagestatsVersion
if profile_filename:
logfunc(f'Loaded profile: {profile_filename}')
logfunc(f'Artifact categories to parse: {len(plugins)}')
logfunc(f'Artifact categories to parse: {len(plugins) - 1}') # excluding usagestatsVersion always executed first
logfunc(f'File/Directory selected: {input_path}')
logfunc('\n--------------------------------------------------------------------------------------')

Expand All @@ -340,7 +340,7 @@ def crunch_artifacts(
log.write(f'Timezone selected: {time_offset}<br><br>')

parsed_modules = 0

# Search for the files per the arguments
for plugin in plugins:
if isinstance(plugin.search, list) or isinstance(plugin.search, tuple):
Expand All @@ -350,7 +350,7 @@ def crunch_artifacts(
parsed_modules += 1
GuiWindow.SetProgressBar(parsed_modules, len(plugins))
files_found = []
log.write(f'<b>For {plugin.name} parser</b>')
log.write(f'<b>For {plugin.name} module</b>')
for artifact_search_regex in search_regexes:
found = seeker.search(artifact_search_regex)
if not found:
Expand Down Expand Up @@ -383,7 +383,6 @@ def crunch_artifacts(
continue # nope

logfunc('{} [{}] artifact completed'.format(plugin.name, plugin.module_name))
logfunc('')

log.close()

Expand Down
22 changes: 1 addition & 21 deletions aleapp.spec
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,7 @@ block_cipher = None
a = Analysis(['aleapp.py'],
pathex=['.\\scripts\\artifacts'],
binaries=[],
datas=[('.\\scripts\\logo.jpg', '.\\scripts'),
('.\\scripts\\dashboard.css', '.\\scripts'),
('.\\scripts\\dark-mode.css', '.\\scripts'),
('.\\scripts\\dark-mode-switch.js', '.\\scripts'),
('.\\scripts\\feather.min.js', '.\\scripts'),
('.\\scripts\\chart.umd.min.js', '.\\scripts'),
('.\\scripts\\cal-heatmap.min.js', '.\\scripts'),
('.\\scripts\\cal-heatmap.css', '.\\scripts'),
('.\\scripts\\d3.v7.min.js', '.\\scripts'),
('.\\scripts\\chat.js', '.\\scripts'),
('.\\scripts\\chat.css', '.\\scripts'),
('.\\scripts\\garmin-functions.js', '.\\scripts'),
('.\\scripts\\highlight.min.js', '.\\scripts'),
('.\\scripts\\highlight.min.css', '.\\scripts'),
('.\\scripts\\moment.min.js', '.\\scripts'),
('.\\scripts\\popper.min.js', '.\\scripts'),
('.\\scripts\\Tooltip.min.js', '.\\scripts'),
('.\\scripts\\MDB-Free_4.13.0', '.\\scripts\\MDB-Free_4.13.0'),
('.\\scripts\\timeline', '.\\scripts\\timeline'),
('.\\scripts\\artifacts', '.\\scripts\\artifacts')],
datas=[('.\\scripts', '.\\scripts')],
hiddenimports=['simplekml'],
hookspath=['.\\'],
runtime_hooks=[],
Expand All @@ -49,4 +30,3 @@ exe = EXE(pyz,
upx_exclude=[],
runtime_tmpdir=None,
console=True )

1 change: 0 additions & 1 deletion aleappGUI.py
Original file line number Diff line number Diff line change
Expand Up @@ -480,7 +480,6 @@ def load_case():
v.grid(row=0, column=1, sticky='ns')
mlist_text = tk.Text(mlist_frame, name='tbox', bg=theme_bgcolor, highlightthickness=0,
yscrollcommand=v.set, height=mlist_window_height)
# mlist_text.pack(anchor='w')
mlist_text.grid(row=0, column=0, sticky='we')
v.config(command=mlist_text.yview)
for plugin, enabled in mlist.items():
Expand Down
25 changes: 4 additions & 21 deletions aleappGUI.spec
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,7 @@ block_cipher = None
a = Analysis(['aleappGUI.py'],
pathex=['.\\scripts\\artifacts'],
binaries=[],
datas=[('.\\scripts\\logo.jpg', '.\\scripts'),
('.\\scripts\\dashboard.css', '.\\scripts'),
('.\\scripts\\dark-mode.css', '.\\scripts'),
('.\\scripts\\dark-mode-switch.js', '.\\scripts'),
('.\\scripts\\feather.min.js', '.\\scripts'),
('.\\scripts\\chart.umd.min.js', '.\\scripts'),
('.\\scripts\\cal-heatmap.min.js', '.\\scripts'),
('.\\scripts\\cal-heatmap.css', '.\\scripts'),
('.\\scripts\\d3.v7.min.js', '.\\scripts'),
('.\\scripts\\chat.js', '.\\scripts'),
('.\\scripts\\chat.css', '.\\scripts'),
('.\\scripts\\garmin-functions.js', '.\\scripts'),
('.\\scripts\\highlight.min.js', '.\\scripts'),
('.\\scripts\\highlight.min.css', '.\\scripts'),
('.\\scripts\\moment.min.js', '.\\scripts'),
('.\\scripts\\popper.min.js', '.\\scripts'),
('.\\scripts\\Tooltip.min.js', '.\\scripts'),
('.\\scripts\\MDB-Free_4.13.0', '.\\scripts\\MDB-Free_4.13.0'),
('.\\scripts\\timeline', '.\\scripts\\timeline'),
('.\\scripts\\artifacts', '.\\scripts\\artifacts')],
datas=[('.\\scripts', '.\\scripts')],
hiddenimports=[],
hookspath=['.\\'],
runtime_hooks=[],
Expand All @@ -44,6 +25,8 @@ exe = EXE(pyz,
bootloader_ignore_signals=False,
strip=False,
upx=True,
console=False,
console=True,
hide_console='hide-early',
disable_windowed_traceback=False,
upx_exclude=[],
runtime_tmpdir=None )
62 changes: 62 additions & 0 deletions aleappGUI_macOS.spec
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# -*- mode: python ; coding: utf-8 -*-


a = Analysis(
['aleappGUI.py'],
pathex=['scripts/artifacts'],
binaries=[],
datas=[('scripts/', 'scripts')],
hiddenimports=[
'bcrypt',
'bencoding',
'blackboxprotobuf',
'Crypto.Cipher.AES',
'Crypto.Util.Padding',
'fitdecode',
'folium',
'PIL.Image',
'polyline',
'xmltodict',
'xlsxwriter',
],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
noarchive=False,
)
pyz = PYZ(a.pure)

exe = EXE(
pyz,
a.scripts,
[],
exclude_binaries=True,
name='aleappGUI',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
console=False,
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity='42F9AD88C52A9888352AB869F1E6EC207A29D308',
entitlements_file=None,
)
coll = COLLECT(
exe,
a.binaries,
a.datas,
strip=False,
upx=True,
upx_exclude=[],
name='aleappGUI',
)
app = BUNDLE(
coll,
name='aleappGUI.app',
icon='../icon.icns',
bundle_identifier='4n6.brigs.ALEAPP',
version='3.2.1',
)
Loading

0 comments on commit 85328a6

Please sign in to comment.