change: extract the server catalog model into aqomui/catalog.py #181

Merged
mysticalsoap merged 3 commits from server-catalog into trunk 2026-08-27 18:40:03 -04:00
Owner

Problem

The #83 seam-3 tangle (#125): server_dict/protocol_dict and every operation on them lived inline in the gui — list derivation, filtering, the latency-sorted index, favourites, profile resolution, protocol selection, the import merge, deletion, and the connect-time projection — while the cli recreated several of the same operations by hand and drifted doing it.

Fix

aqomui/catalog.py: a Qt-free ServerCatalog owning both dicts, their persistence (every mutation saves what it changed — the #139 bug class can no longer recur), and all of the operations above, including connect_dict absorbing utils.create_server_dict. The gui keeps only row hiding and widget population; the cli's hand-rolled copies are gone. Per the #126/#173 tangle rule, the catalog takes over the server.json/protocol.json call sites that landed in config.

Behavior unified or fixed on the way (each noted in its commit):

  • cli's import merge gains the gui's existence check on the carried-over protocol selection (Mullvad-shrink case)
  • set_hop's deleted-server toast called self.motify — AttributeError inside a Qt slot instead of an error toast
  • Airvpn projection: tlscrypt was unassigned on the ip-fallback path (NameError)
  • protocol tab: the no-selection fallback compared keys against protocol_1's value dict, so no checkbox was ever checked on a table without a selection

Verification

  • ruff E9,F63,F7,F82 clean; 434 tests pass including 37 new catalog tests (persistence round-trips, merge rules, profile modes, per-provider projection quirks)
  • Live gui/cli pass pending — steps below

Closes #125

🤖 Generated with Claude Code

## Problem The #83 seam-3 tangle (#125): server_dict/protocol_dict and every operation on them lived inline in the gui — list derivation, filtering, the latency-sorted index, favourites, profile resolution, protocol selection, the import merge, deletion, and the connect-time projection — while the cli recreated several of the same operations by hand and drifted doing it. ## Fix `aqomui/catalog.py`: a Qt-free ServerCatalog owning both dicts, their persistence (every mutation saves what it changed — the #139 bug class can no longer recur), and all of the operations above, including `connect_dict` absorbing `utils.create_server_dict`. The gui keeps only row hiding and widget population; the cli's hand-rolled copies are gone. Per the #126/#173 tangle rule, the catalog takes over the server.json/protocol.json call sites that landed in config. Behavior unified or fixed on the way (each noted in its commit): - cli's import merge gains the gui's existence check on the carried-over protocol selection (Mullvad-shrink case) - `set_hop`'s deleted-server toast called `self.motify` — AttributeError inside a Qt slot instead of an error toast - Airvpn projection: `tlscrypt` was unassigned on the ip-fallback path (NameError) - protocol tab: the no-selection fallback compared keys against protocol_1's *value dict*, so no checkbox was ever checked on a table without a selection ## Verification - ruff E9,F63,F7,F82 clean; 434 tests pass including 37 new catalog tests (persistence round-trips, merge rules, profile modes, per-provider projection quirks) - Live gui/cli pass pending — steps below Closes #125 🤖 Generated with [Claude Code](https://claude.com/claude-code)
The #83 seam-3 move (#125), step one: ServerCatalog owns server_dict/
protocol_dict and every operation on them -- load/save, list derivation
and malformed-entry pruning, filter predicates, the latency-sorted row
index, favourites, profile resolution, protocol selection and overrides,
the import merge, deletion, and the connect-time projection that lived
in utils.create_server_dict. Qt-free so the cli can import it. Every
mutation persists what it changed, which retires the #139 bug class.

Two latent projection bugs do not carry over: tlscrypt is preset before
the Airvpn ip fallback (a missing ip key raised NameError), and the
selected-protocol fallback returns the protocol_1 key instead of its
value dict (the gui compared keys against it, so no checkbox was ever
checked on a table without a selection).

The frontends switch over in the following commits.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
server_dict/protocol_dict, the row index and every operation on them
move behind self.catalog; the filter methods keep only the row hiding,
pop_boxes keeps only widget population, and connect/hop/bypass project
through catalog.connect_dict.

Rides along: the set_hop deleted-server path called self.motify, so
the error toast for a stale hop choice raised AttributeError inside a
Qt slot instead of showing.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
change: run the cli's server operations through the catalog
All checks were successful
ci / test (pull_request) Successful in 26s
ci / test (push) Successful in 26s
1b5b14063e
The hand-rolled copies of protocol selection, provider deletion, the
import merge and the connect projections go through ServerCatalog like
the gui's. The cli's merge kept an older carry-over rule that trusted
any stored protocol selection; it now gets the existence check the gui
gained when Mullvad's table shrank. utils.create_server_dict and the
catalog-owned JSON_FILE_LIST entries retire with their last consumers.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
mysticalsoap deleted branch server-catalog 2026-08-27 18:40:04 -04:00
Sign in to join this conversation.
No description provided.