Commit Graph

53 Commits

Author SHA1 Message Date
Martin Tranberg
0dfef3e611 feat: task 9 — add _graph_request helper with retry on 429/503
Add module-level _graph_request() that wraps requests.request() with:
- Up to 3 retries on HTTP 429 (rate limited) and 503 (unavailable)
- Exponential backoff capped at 60 s, honouring Retry-After header
- Default timeout=30 s injected via setdefault (caller can override)

Wire all 13 retry-eligible API calls through _graph_request(). The 3
file-upload requests.put(data=f) calls are kept direct since an open
stream cannot be re-read after the first attempt.

Add 9 unit tests covering: success path, 429/503 retry, Retry-After
header, max-retry exhaustion, timeout injection and override.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-12 10:29:39 +02:00
Martin Tranberg
707645ab36 fix: task 8 — add timeout to all requests calls
Add timeout= to every requests.get/post/put/patch/delete call so that
background threads cannot hang indefinitely when the network is stalled:

- timeout=30 on all API calls (delete, post, patch, get — 13 locations)
- timeout=120 on file upload calls (requests.put with data= — 3 locations)
  to allow sufficient time for large file transfers

Add 1 new unit test that scans the source file and fails if any
requests.* call is missing a timeout= parameter.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-12 10:26:04 +02:00
Martin Tranberg
df55660291 fix: task 7 — production hardening quick fixes
- Replace 4 bare `except:` with `except Exception:` (load_settings,
  get_txt, get_icon_idx_for_file, process_file cleanup block) so
  SystemExit and KeyboardInterrupt are no longer swallowed
- Replace 2 print() calls with logger.error() (__init__ MSAL init,
  ensure_valid_token) so errors appear in the configurable log output
- Sanitize item['name'] with os.path.basename() in on_download_clicked
  and _download_folder_recursive_sync to prevent path traversal from
  server-controlled filenames
- Add 8 new unit tests covering all Task 7 changes

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-12 10:22:54 +02:00
Martin Tranberg
e8e1d8b60d docs: update README with latest features and fixes
- Add pagination / large-tenant support section
- Add status bar gauge feature
- Document tabbed settings dialog with fane overview
- Add data-driven breadcrumb navigation note
- Add stale-result protection (_nav_gen) to architecture section
- Add unit test run instructions
- Update build instructions to use the spec file
- Fix typo "Star op" → "Start op"

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-12 10:11:09 +02:00
Martin Tranberg
ba3d8dded5 chore: ignore tasks/ and .claude/ directories
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-12 10:00:52 +02:00
Martin Tranberg
d7c0fdd091 test: add unit tests for all code-review bug fixes
19 tests covering:
- I2/I3: STRINGS dict entries (System tab label, status_loading_items)
- I1/C-1/S-2: nav_gen guard logic in _finalize_list_loading
  (matching gen applies, stale gen discards, None bypasses guard,
   old zero default now correctly treated as stale)
- C1: url=None initialization order in _fetch_tree_children_bg
- S2: dead SITE branch absent from _append_list_items
- S-1: is_breadcrumb parameter removed from _navigate_to_item_data

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-12 09:57:44 +02:00
Martin Tranberg
f168d0c60a refactor: remove dead is_breadcrumb parameter from _navigate_to_item_data (S-1)
The S3 fix removed the only conditional that read is_breadcrumb. Remove
the parameter from the signature and its kwarg from the one call site in
the breadcrumb button handler.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-12 09:53:58 +02:00
Martin Tranberg
0cbec6477f fix: restore refresh operations broken by nav_gen regression (C-1, S-2)
Change nav_gen default from 0 to None in _fetch_list_contents_bg and
_finalize_list_loading. The guard is updated to only apply when a gen
is explicitly provided (`nav_gen is not None`).

Refresh call sites (lines 1515, 1529, 1538) pass no gen, so they receive
None and bypass the guard — their results are always applied. Navigation
calls still pass an explicit integer gen, so stale-navigation protection
remains fully intact.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-12 09:52:42 +02:00
Martin Tranberg
a55365259c refactor: remove redundant pulse_gauge calls and fix breadcrumb dedup (S1, S3)
- S1: drop pulse_gauge(True) from inside pagination while-loops in
  _fetch_sites_bg, _fetch_tree_children_bg, and _fetch_list_contents_bg;
  the gauge is already running from the call before the loop
- S3: remove the is_breadcrumb bypass on the early-return guard so
  clicking the already-active breadcrumb segment no longer fires a
  redundant network request

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-12 09:45:49 +02:00
Martin Tranberg
d529568798 fix: add navigation generation counter to prevent stale list overwrite (I1)
Introduces self._nav_gen, incremented on every _navigate_to_item_data
call. The counter is threaded through _fetch_list_contents_bg and
checked in _finalize_list_loading: if the user navigated away while a
fetch was in flight, the stale results are silently discarded instead of
overwriting the active folder view and re-sorting its items.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-12 09:44:39 +02:00
Martin Tranberg
b800f0308d fix: resolve C2/I4 review findings
- C2: remove duplicate EVT_SIZE binding (on_status_bar_resize); merge
  gauge repositioning into the single on_resize handler
- I4: position gauge correctly on first show by updating rect inside
  pulse_gauge._do() when start=True, so no resize event is required

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-12 09:42:52 +02:00
Martin Tranberg
dadbb4d51a fix: resolve C1/I2/I3/S2 review findings
- C1: initialize url=None before conditional in _fetch_tree_children_bg
  to prevent UnboundLocalError on unexpected data types
- I2: translate System tab label via get_txt instead of hardcoded string
- I3: add status_loading_items to STRINGS (da+en) and use it in
  _fetch_list_contents_bg instead of hardcoded Danish f-string
- S2: remove unreachable SITE branch from _append_list_items

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-12 09:41:25 +02:00
Martin Tranberg
be7a78deb8 feat: update credits section with company address and contact information 2026-04-07 13:34:56 +02:00
Martin Tranberg
4abf221887 refactor: convert settings dialog to tabbed interface and add about section 2026-04-07 13:32:19 +02:00
Martin Tranberg
205b1ac241 refactor: consolidate navigation logic and improve refresh reliability using path data context 2026-04-07 13:21:23 +02:00
Martin Tranberg
0159b91c69 feat: add status bar gauge and implement pagination for site and folder fetching 2026-04-07 12:30:33 +02:00
Martin Tranberg
2dfe1a41be refactor: replace path-based breadcrumb rendering with data-driven navigation and synchronization 2026-04-01 10:38:41 +02:00
Martin Tranberg
f11f487ba3 feat: add get_txt helper method for localized string retrieval 2026-04-01 10:25:44 +02:00
Martin Tranberg
ad6055963d feat: add configurable logging toggle to settings and implement dynamic log level management 2026-04-01 10:19:21 +02:00
Martin Tranberg
e14012d2a5 feat: add path tracking to items and improve checkout/checkin logic with discard support 2026-04-01 10:17:58 +02:00
Martin Tranberg
62725f9be6 feat: implement QuickXorHash integrity verification for downloads and add SharePoint site navigation support 2026-04-01 09:42:06 +02:00
Martin Tranberg
1a85f1d963 feat: update status bar to ready state after drive initialization 2026-04-01 09:30:09 +02:00
Martin Tranberg
62639632dc refactor: improve context menu separator logic and update login button label for compact mode 2026-04-01 09:18:59 +02:00
Martin Tranberg
bff066d3fb feat: migrate to wxPython, add setup wizard, and update documentation 2026-04-01 09:04:12 +02:00
Martin Tranberg
232ab85cc7 feat: add StartGuideDialog for initial Azure configuration and conditional MSAL initialization 2026-04-01 08:43:33 +02:00
Martin Tranberg
044559c913 Remove search 2026-03-31 19:56:12 +02:00
Martin Tranberg
2dd31d19c6 feat: implement global search functionality with indexing support and UI controls 2026-03-31 17:50:37 +02:00
Martin Tranberg
6b6387f5c8 feat: add native Windows icon support and context menu options to open items in browser 2026-03-31 17:21:10 +02:00
Martin Tranberg
6ab9901cc8 feat: implement responsive UI with compact mode for navigation buttons on window resize 2026-03-31 17:04:43 +02:00
Martin Tranberg
c5f18b520a feat: implement natural sorting and column-based list view sorting with visual indicators 2026-03-31 16:56:10 +02:00
Martin Tranberg
784ca755d5 feat: add license key configuration to settings and update UI with system icons and button bitmaps 2026-03-31 16:48:36 +02:00
Martin Tranberg
fa6840de75 refactor: update path display to derive breadcrumbs from current_path instead of tree selection 2026-03-31 16:37:51 +02:00
Martin Tranberg
8e53f69e68 feat: implement favorites sidebar with add, remove, and navigation functionality 2026-03-31 16:37:28 +02:00
Martin Tranberg
8f80611d32 feat: implement settings dialog for configuration of authentication, paths, and language 2026-03-31 16:32:26 +02:00
Martin Tranberg
86ff8043f1 refactor: replace global editing lock with active_edits dictionary to support concurrent file editing 2026-03-31 16:21:02 +02:00
Martin Tranberg
0d8407f624 feat: add application icon and improve path handling for bundled executables 2026-03-31 16:11:08 +02:00
Martin Tranberg
6659ebd6ac feat: add refresh functionality to UI and document future feature requests 2026-03-31 12:05:50 +02:00
Martin Tranberg
f7cebfc489 feat: add file and folder download functionality to context menu 2026-03-31 11:41:46 +02:00
Martin Tranberg
b1c46fbace feat: add open in browser context menu option and optimize MSAL authentication handling 2026-03-31 11:35:55 +02:00
Martin Tranberg
ed931f2088 refactor: implement token validation and localize UI labels and status messages 2026-03-31 11:25:09 +02:00
Martin Tranberg
9ccbcbaf0c feat: implement multi-language support, file drag-and-drop, and new UI controls for file management 2026-03-31 11:21:41 +02:00
Martin Tranberg
07913c0224 fix: add safety checks to path display and tree selection to prevent runtime errors during object destruction 2026-03-31 10:48:55 +02:00
Martin Tranberg
dfbef36558 feat: add file size column and formatting helper to list view 2026-03-31 10:45:29 +02:00
Martin Tranberg
220bedda48 refactor: move project_description.md to dev directory and remove obsolete screenshot 2026-03-31 10:41:28 +02:00
Martin Tranberg
d3a7ce69e9 feat: implement UI locking and prevent application exit during active file editing sessions 2026-03-30 19:49:16 +02:00
Martin Tranberg
2b82a7aa5c feat: add ImageList to TreeCtrl and ListCtrl for visual item classification 2026-03-30 19:40:00 +02:00
Martin Tranberg
14e327989c feat: add file editing workflow with manual completion button and info bar notifications 2026-03-30 19:34:51 +02:00
Martin Tranberg
16fca9d7d2 feat: replace static path label with interactive breadcrumb navigation panel 2026-03-30 19:25:10 +02:00
Martin Tranberg
125e9e8232 refactor: replace customtkinter with wxPython and implement tree-based navigation 2026-03-30 19:11:51 +02:00
Martin Tranberg
4e028aaf66 Fix navigation loop: Synchronize breadcrumb path with displayed folder ID when navigating back. 2026-03-30 15:53:59 +02:00