diff --git a/aleapp.py b/aleapp.py
index 1d0c873d..4c860bb4 100755
--- a/aleapp.py
+++ b/aleapp.py
@@ -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:
@@ -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()
@@ -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)
@@ -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)
@@ -278,7 +276,7 @@ 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():
@@ -286,8 +284,9 @@ def main():
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)
@@ -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--------------------------------------------------------------------------------------')
@@ -340,7 +340,7 @@ def crunch_artifacts(
log.write(f'Timezone selected: {time_offset}
')
parsed_modules = 0
-
+
# Search for the files per the arguments
for plugin in plugins:
if isinstance(plugin.search, list) or isinstance(plugin.search, tuple):
@@ -350,7 +350,7 @@ def crunch_artifacts(
parsed_modules += 1
GuiWindow.SetProgressBar(parsed_modules, len(plugins))
files_found = []
- log.write(f'For {plugin.name} parser')
+ log.write(f'For {plugin.name} module')
for artifact_search_regex in search_regexes:
found = seeker.search(artifact_search_regex)
if not found:
@@ -383,7 +383,6 @@ def crunch_artifacts(
continue # nope
logfunc('{} [{}] artifact completed'.format(plugin.name, plugin.module_name))
- logfunc('')
log.close()
diff --git a/aleapp.spec b/aleapp.spec
index 14e02ef4..01d72c30 100755
--- a/aleapp.spec
+++ b/aleapp.spec
@@ -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=[],
@@ -49,4 +30,3 @@ exe = EXE(pyz,
upx_exclude=[],
runtime_tmpdir=None,
console=True )
-
diff --git a/aleappGUI.py b/aleappGUI.py
index 38fc2cec..9a10b92e 100755
--- a/aleappGUI.py
+++ b/aleappGUI.py
@@ -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():
diff --git a/aleappGUI.spec b/aleappGUI.spec
index f3fbbd46..91ea6b16 100755
--- a/aleappGUI.spec
+++ b/aleappGUI.spec
@@ -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=[],
@@ -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 )
\ No newline at end of file
diff --git a/aleappGUI_macOS.spec b/aleappGUI_macOS.spec
new file mode 100755
index 00000000..689f73a8
--- /dev/null
+++ b/aleappGUI_macOS.spec
@@ -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',
+)
diff --git a/aleapp_macOS.spec b/aleapp_macOS.spec
new file mode 100644
index 00000000..96c96322
--- /dev/null
+++ b/aleapp_macOS.spec
@@ -0,0 +1,49 @@
+# -*- mode: python ; coding: utf-8 -*-
+
+
+a = Analysis(
+ ['aleapp.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,
+ a.binaries,
+ a.datas,
+ [],
+ name='aleapp',
+ debug=False,
+ bootloader_ignore_signals=False,
+ strip=False,
+ upx=True,
+ upx_exclude=[],
+ runtime_tmpdir=None,
+ console=True,
+ disable_windowed_traceback=False,
+ argv_emulation=False,
+ target_arch=None,
+ codesign_identity='42F9AD88C52A9888352AB869F1E6EC207A29D308',
+ entitlements_file=None,
+)
diff --git a/scripts/version_info.py b/scripts/version_info.py
index 24bfa56a..f49ac87a 100755
--- a/scripts/version_info.py
+++ b/scripts/version_info.py
@@ -1,4 +1,4 @@
-aleapp_version = '3.1.11'
+aleapp_version = '3.2.1'
# Contributors List
# Format = [ Name, Blog-url, Twitter-handle, Github-url]