Skip to content

fix(gui): improvements to gui_local_slot_editing - #169

Open
LukasGold wants to merge 2 commits into
mainfrom
fix/gui-local-slot-editing
Open

fix(gui): improvements to gui_local_slot_editing#169
LukasGold wants to merge 2 commits into
mainfrom
fix/gui-local-slot-editing

Conversation

@LukasGold

Copy link
Copy Markdown
Contributor

Fixes #42

Implements all five suggestions from the issue. Three of them needed small, backward compatible changes in shipped code; the rest is confined to examples/gui_local_slot_editing.py.

1. Purging the content folder is now optional

WtSite.create_page_package unconditionally ran shutil.rmtree(config.content_path), so a download silently wiped local edits.

  • PagePackageConfig.clear_content_dir (default True, so existing behaviour is unchanged) gates the purge.
  • The GUI writes Clearing '<dir>' and downloading slots... into the status box before it happens, which covers the "or note when downloading" half of the request.

2. + 5. Per-domain folder, and one shared path for download and upload

These two are coupled: adding a domain segment to the download path is pointless unless upload resolves the same path.

  • New compute_page_storage_path() helper builds <working_dir>/<domain>/<page_label_or_top_level> and sanitizes the domain for use as a directory name. Pages from different OSW instances no longer collide in one working directory.
  • Both the -DL- and -UL- handlers call it, so they cannot disagree.
  • This removes the reason uploads from a previous run were impossible. Previously the path reached the upload handler only as a side effect of create_page_package mutating dump_config.target_dir, which happened solely on an actual download; the upload handler otherwise fell back to the flat working directory, which is not where downloads were written. The path is now recomputed deterministically from state that "Load page" already sets, so load-then-upload works without a download in the same session.
  • Related defect fixed: the upload handler printed No slots downloaded! and then carried on to read and upload anyway.

3. Upload and JSON parsing no longer kill the app

The example script contained no try/except at all, so any exception escaped the PySimpleGUI event loop and took the window with it.

  • The -DL- and -UL- handler bodies now catch exceptions and display them in the existing status widgets.
  • read_page_package re-raises both json.load failures with the offending file path (chained with from). Without this the user sees only Expecting ',' delimiter: line 5 column 3 with no indication of which hand-edited slot file is broken. The error still propagates; it is just usable now.

4. The GUI starts, and stays usable, without credentials

read_domains_from_credentials_file was called before the window existed, so any credential problem killed the app at startup with a console traceback.

  • An empty file made yaml.safe_load return None and then raised AttributeError from .keys(), which the surrounding except yaml.YAMLError did not catch. It now raises the same clear ValueError an empty mapping already produced. No new exception type, success path unchanged.
  • Startup falls back to an empty domain list and reports the reason in the UI.
  • The -CREDENTIALS- handler is guarded too. That is the recovery path for a user who started with no credentials, and browsing to another bad file would otherwise kill the event loop. Previously loaded domains are kept on failure.
  • "Load page" no longer calls get_page on a None site; it asks the user to pick a domain first. Selecting a domain already rebuilds the site object, so the app recovers from the unconfigured state.
  • author=accounts[domains[0]]["username"] became accounts.get(domain, ...). It raised IndexError with no credentials loaded, and it read the first domain's username rather than the selected one.

Tests

8 new tests, offline, no network, no credentials, no PySimpleGUI import:

  • tests/test_wiki_tools.py - read_domains_from_credentials_file against an empty file, an empty mapping and a valid file
  • tests/test_wtsite_create_page_package.py - clear_content_dir defaults to True and is honoured both ways, via an offline fake site
  • tests/test_wtsite_read_page_package.py - malformed packages.json and a malformed slot file each raise naming the offending path

Each was confirmed to fail before the change for the right reason (AttributeError: 'NoneType' object has no attribute 'keys', JSON errors carrying no path, missing clear_content_dir attribute, and the marker file deleted by the unconditional rmtree).

199 passed, 1 skipped offline, ruff check clean.

Verification limits

PySimpleGUI is not installed in this environment, so examples/gui_local_slot_editing.py was never executed. It is covered by python -m py_compile and ruff only. The GUI changes need a manual run against a real wiki before this is trusted, in particular the download/upload round trip through the new per-domain folder.

Note that change 5 alters the on-disk layout: existing local working directories from previous runs will not be found under the new per-domain path.

- make the content dir purge opt-out via PagePackageConfig
- store downloads under a per-domain folder, shared by up/download
- catch errors in the download and upload handlers and display them
- name the offending file when slot or package JSON is malformed
- start the gui and keep it usable with empty or missing credentials
@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Release preview

Merging this PR would release v2.3.2 (current: v2.3.1).

Changelog preview (truncated)
## v2.3.2 (2026-09-04)

### Bug Fixes

- **gui**: Improvements to gui_local_slot_editing
  ([`a84e73a`](https://github.com/OpenSemanticLab/osw-python/commit/a84e73ad1e2f3a3f7c20eabce748d288bbb531a8))

### Build System

- **deps**: Require pysimplegui>=6 for the UI extra
  ([`4ca7ab9`](https://github.com/OpenSemanticLab/osw-python/commit/4ca7ab97ad94ad53629db2db513769af648acf5a))

Preview via python-semantic-release and conventional commits.

- PySimpleGUI 5 was commercial and is yanked from PyPI; the LGPLv3 line
  resumed at version 6
- the floor also excludes the still-published 4.60.5.1
- refresh uv.lock: pysimplegui 6.2 -> 6.3.0.1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

enhance: gui_local_slot_editing - collection of suggested improvements

1 participant