From 72e12fd178206e305a706b2e07d3175c88e5b61f Mon Sep 17 00:00:00 2001 From: Ryan Benson Date: Mon, 6 Jul 2026 16:22:03 -0700 Subject: [PATCH 1/3] Associate `source_item` with bookmark and session items in Firefox artifact processing --- pyhindsight/browsers/firefox.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pyhindsight/browsers/firefox.py b/pyhindsight/browsers/firefox.py index 570cb52..5e9c907 100644 --- a/pyhindsight/browsers/firefox.py +++ b/pyhindsight/browsers/firefox.py @@ -308,6 +308,7 @@ def get_bookmarks(self, path, database='places.sqlite'): rows = cursor.fetchall() folder_titles = {r['id']: (r['title'] or '') for r in rows if r['type'] == BOOKMARK_TYPE_FOLDER} + source_item = os.path.relpath(os.path.join(path, database), self.profile_path) for row in rows: bm_type = row.get('type') parent_folder = folder_titles.get(row.get('parent'), '') @@ -323,6 +324,7 @@ def get_bookmarks(self, path, database='places.sqlite'): url=row.get('url'), parent_folder=parent_folder, ) + item.source_item = source_item results.append(item) elif bm_type == BOOKMARK_TYPE_FOLDER: # Skip the synthetic top-level roots (menu/toolbar/tags/unfiled/mobile). @@ -335,6 +337,7 @@ def get_bookmarks(self, path, database='places.sqlite'): name=row.get('title') or '', parent_folder=parent_folder, ) + item.source_item = source_item results.append(item) self.artifacts_counts['Bookmarks'] = len(results) @@ -1182,6 +1185,7 @@ def _emit_entries(entries, window_idx, tab_idx, selected_index, ) item.row_type = row_label item.value = '' + item.source_item = source_item item.transition_type = ( 'selected' if nav_idx + 1 == selected_index else 'history' ) @@ -1216,6 +1220,7 @@ def _emit_entries(entries, window_idx, tab_idx, selected_index, ) item.row_type = f'session (closed tab, {source_label})' item.value = '' + item.source_item = source_item item.transition_type = 'closed' results.append(item) @@ -1241,6 +1246,7 @@ def _emit_entries(entries, window_idx, tab_idx, selected_index, ) item.row_type = f'session (closed window, {source_label})' item.value = '' + item.source_item = source_item item.transition_type = 'closed' results.append(item) From ad755402c08ee5a984783992168261a3c6df45fe Mon Sep 17 00:00:00 2001 From: Ryan Benson Date: Mon, 6 Jul 2026 16:22:10 -0700 Subject: [PATCH 2/3] Refactor `make_version_info` to ensure compatibility on non-Windows platforms by conditionally importing PyInstaller's versioninfo module. --- spec/_version_info.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/spec/_version_info.py b/spec/_version_info.py index c26cdc5..4e72fe3 100644 --- a/spec/_version_info.py +++ b/spec/_version_info.py @@ -9,12 +9,17 @@ from pyhindsight import __version__ -from PyInstaller.utils.win32.versioninfo import ( - VSVersionInfo, FixedFileInfo, StringFileInfo, StringTable, StringStruct, - VarFileInfo, VarStruct) - def make_version_info(original_filename): + # The version resource is Windows-only, and PyInstaller's versioninfo + # module can't even be imported elsewhere (pefile is a Windows-only dep). + if sys.platform != 'win32': + return None + + from PyInstaller.utils.win32.versioninfo import ( + VSVersionInfo, FixedFileInfo, StringFileInfo, StringTable, StringStruct, + VarFileInfo, VarStruct) + parts = __version__.split('.') year, month = int(parts[0]), int(parts[1]) micro = int(parts[2]) if len(parts) > 2 else 0 From 9d40cb002d6f839038e2da0935a6b93c68df7b72 Mon Sep 17 00:00:00 2001 From: Ryan Benson Date: Mon, 6 Jul 2026 16:22:16 -0700 Subject: [PATCH 3/3] Add UTC timezone info to datetime objects in test configurations --- tests/test_downloads.py | 10 +++++----- tests/test_history.py | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/test_downloads.py b/tests/test_downloads.py index 11ed2ac..b8cb954 100644 --- a/tests/test_downloads.py +++ b/tests/test_downloads.py @@ -9,11 +9,11 @@ class TestGetDownloads(unittest.TestCase): def test_get_downloads(self): test_config = [ - {'version': [1], 'record_count': 2, 'wikipedia_record': 0, 'wikipedia_timestamp': datetime.datetime(2013, 6, 5, 4, 28, 30)}, - {'version': [10], 'record_count': 2, 'wikipedia_record': 0, 'wikipedia_timestamp': datetime.datetime(2013, 6, 27, 4, 23, 25)}, - {'version': [20], 'record_count': 2, 'wikipedia_record': 0, 'wikipedia_timestamp': datetime.datetime(2013, 6, 30, 21, 26, 5)}, - {'version': [30], 'record_count': 2, 'wikipedia_record': 0, 'wikipedia_timestamp': datetime.datetime(2013, 10, 2, 23, 17, 29, 397160)}, - {'version': [60], 'record_count': 2, 'wikipedia_record': 0, 'wikipedia_timestamp': datetime.datetime(2017, 8, 5, 22, 6, 52, 88356)} + {'version': [1], 'record_count': 2, 'wikipedia_record': 0, 'wikipedia_timestamp': datetime.datetime(2013, 6, 5, 4, 28, 30, tzinfo=datetime.timezone.utc)}, + {'version': [10], 'record_count': 2, 'wikipedia_record': 0, 'wikipedia_timestamp': datetime.datetime(2013, 6, 27, 4, 23, 25, tzinfo=datetime.timezone.utc)}, + {'version': [20], 'record_count': 2, 'wikipedia_record': 0, 'wikipedia_timestamp': datetime.datetime(2013, 6, 30, 21, 26, 5, tzinfo=datetime.timezone.utc)}, + {'version': [30], 'record_count': 2, 'wikipedia_record': 0, 'wikipedia_timestamp': datetime.datetime(2013, 10, 2, 23, 17, 29, 397160, tzinfo=datetime.timezone.utc)}, + {'version': [60], 'record_count': 2, 'wikipedia_record': 0, 'wikipedia_timestamp': datetime.datetime(2017, 8, 5, 22, 6, 52, 88356, tzinfo=datetime.timezone.utc)} ] for config in test_config: diff --git a/tests/test_history.py b/tests/test_history.py index c978f3d..d162bd0 100644 --- a/tests/test_history.py +++ b/tests/test_history.py @@ -9,11 +9,11 @@ class TestGetHistory(unittest.TestCase): def test_get_history(self): test_config = [ - {'version': [1], 'record_count': 46, 'wikipedia_record': 7, 'wikipedia_timestamp': datetime.datetime(2013, 6, 5, 4, 28, 55, 498623)}, - {'version': [10], 'record_count': 84, 'wikipedia_record': 7, 'wikipedia_timestamp': datetime.datetime(2013, 6, 27, 4, 23, 14, 176756)}, - {'version': [20], 'record_count': 58, 'wikipedia_record': 7, 'wikipedia_timestamp': datetime.datetime(2013, 6, 30, 21, 26, 13, 162176)}, - {'version': [30], 'record_count': 46, 'wikipedia_record': 4, 'wikipedia_timestamp': datetime.datetime(2013, 10, 2, 23, 15, 13, 326712)}, - {'version': [60], 'record_count': 61, 'wikipedia_record': 5, 'wikipedia_timestamp': datetime.datetime(2017, 8, 5, 22, 6, 56, 507864)} + {'version': [1], 'record_count': 46, 'wikipedia_record': 7, 'wikipedia_timestamp': datetime.datetime(2013, 6, 5, 4, 28, 55, 498623, tzinfo=datetime.timezone.utc)}, + {'version': [10], 'record_count': 84, 'wikipedia_record': 7, 'wikipedia_timestamp': datetime.datetime(2013, 6, 27, 4, 23, 14, 176756, tzinfo=datetime.timezone.utc)}, + {'version': [20], 'record_count': 58, 'wikipedia_record': 7, 'wikipedia_timestamp': datetime.datetime(2013, 6, 30, 21, 26, 13, 162176, tzinfo=datetime.timezone.utc)}, + {'version': [30], 'record_count': 46, 'wikipedia_record': 4, 'wikipedia_timestamp': datetime.datetime(2013, 10, 2, 23, 15, 13, 326712, tzinfo=datetime.timezone.utc)}, + {'version': [60], 'record_count': 61, 'wikipedia_record': 5, 'wikipedia_timestamp': datetime.datetime(2017, 8, 5, 22, 6, 56, 507864, tzinfo=datetime.timezone.utc)} ] for config in test_config: