Removed
- Dead file
tsm/ui/components/realm_row.py(RealmRowWidgetwas never used) - Dead method
WoWDetectorService.add_custom_path()(never called) - Unused DB tables
addon_versionsandsync_historyremoved from schema
and migrations
Fixed
assert self._db is not Noneindatabase.pyreplaced with a proper
RuntimeError(assert can be silenced with-O)- Silent
except Exception: passon backup purge now logs aWARNING asyncio.get_event_loop()replaced withasyncio.get_running_loop()in
jobs.py,wow_detector.py, andapp_window.py(deprecated in Python 3.12)auction.pyno longer accessesaddon_writer._detectordirectly; uses the
new publicAddonWriterService.get_detector()method instead- All external
getattr(x, "_installs", [])accesses replaced with the new
publicWoWDetectorService.installsproperty and the delegating
AddonWriterService.installsproperty SettingsDialog._logout_reset()no longer pokesself._vm._configdirectly;
uses the newSettingsViewModel.reset_to_defaults()method- Late imports at the bottom of
scheduler.pymoved to the top (no actual
circular dependency existed) __main__.pyno longer reaches intowindow._app_vm,window._settings_vm,
andwindow._realm_vmdirectly; uses the newAppWindow.on_authenticated()
method insteadapp_window.pyline 111 now connects to publicAccountingExportView.populate
instead of the private_populate- Backup delete in
BackupsViewnow callsBackupService.delete()instead of
callingzip_path.unlink()directly in the view - README WoW detection frequency corrected: detection runs at startup only, not
every 5 minutes
Added
WoWDetectorService.installs- public property returning the cached install listAddonWriterService.get_detector()andinstalls- public API on the writerSettingsViewModel.reset_to_defaults()- resets config and persists in one callAppWindow.on_authenticated(session)- encapsulates post-login window setupAccountingExportView.populate()- renamed from_populate(public slot)BackupService.delete(zip_path)- file deletion belongs in the service layertsm/ui/views/_utils.pywith shared helpers:set_table_cell()- replaces the duplicated_set_cell()methods in
realm_data.pyandbackups.pystart_rate_limit_countdown()- replaces the duplicated countdown timer
pattern inrealm_data.pyandbackups.pybuild_realm_tree()- replaces the duplicated API response parsing in
app_window.pyandsettings.py
tsm/wow/utils.pywithiter_wow_gv_roots()- replaces the duplicated
installs x game-version directory loops inupdater.pyandbackup.pytsm/wow/accounts.pygainsscan_tsm_accounts()andscan_realm_names(),
moved from inline functions inaccounting_export.pypackaging/debian/ci-depends- single source of truth for concrete package
deps used in CI (no dpkg substitution variables); both the.debcontrol
file step and the.rpmfpm flags now read from this file
Changed
apschedulerdependency constraint updated from>=4.0.0a5to>=4.0.0,<5
(APScheduler 4.0 stable has released)packaging/debian/control- added missing runtime deps:python3-pydantic,
python3-aiosqlite,python3-apscheduler,python3-structlog,
python3-tomli-w,python3-yamlrelease.yml.deband.rpmsteps now derive deps fromci-depends
instead of each maintaining their own hardcoded listtsm/core/scheduler.py:ServiceContainerfields typed with six Protocol
classes (AuctionServiceProtocol,AuthServiceProtocol,UpdateServiceProtocol,
ConfigStoreProtocol,WoWDetectorProtocol,BackupServiceProtocol) instead
ofobject, enabling mypy to validate method calls injobs.pyandscheduler.py
Tests
tests/integration/test_scheduler.pyrewritten: uses a realServiceContainer
with mocked services, callsstart()/stop(), and asserts scheduler lifecycle
and idempotencytests/conftest.py: removed the redundantevent_loopfixture (superseded by
asyncio_mode = "auto"in pyproject.toml)tests/unit/test_config_store.py(new): covers load defaults, TOML parsing,
corrupt TOML fallback, save round-trip, and parent directory creationtests/unit/test_wow_detector_service.py(new): covers empty initial state,
set_installs, get_installs cache hit/miss, and scan() executor calltests/unit/test_backup_service.py(new): covers delete success/missing,
restore bad filename, _list_backups parsing, _find_sv_files glob, and
run() with no accountstests/unit/test_addon_writer.py(new): covers write_data with no detector,
missing addon dir, and successful LuaWriter calltests/unit/test_auction_cache.py: added snapshot save/load round-trip and
missing snapshot returns empty tests
CI
- Python 3.13 added to the CI test matrix (
python-versioninci.yml)
Chore
- Fixed syntax error in
app.py:impottypo corrected toimport auction.py:realm["name"]changed torealm.get("name", "")-nameis
optional inRealmEntryTypedDict- Removed unused
_SUFFIX_TO_GVdict fromupdater.pyand_GAME_VERSIONS
tuple frombackup.py - Removed unused
Qtimport fromrealm_data.py;Generatormoved to
collections.abcinutils.py(UP035) app_window.py: capturedbackup_servicelocal before lambda to narrow
Optional type; renamed*_argsto*_in signal handlerssettings.py: renamed_indexto_in two combo-box signal handlers__main__.py:_async_runnerrenamed to_(conventional discard for
tuple-unpacking a value kept alive only by the blockingexec()call)__init__.py: added# type: ignore[import-not-found]on_versionimport
(file is generated at build time by hatch-vcs)