Skip to content

Releases: Patrickjaillet/WinMusic

Release list

WinMusic v1.0.1

Choose a tag to compare

@Patrickjaillet Patrickjaillet released this 01 Aug 22:54

Changelog

All notable changes to WinMusic are documented in this file.
The format follows Keep a Changelog,
and this project adheres to Semantic Versioning.

[1.0.1] - 2026-08-02

Fixed

  • scripts/build_installer.ps1: auto-detects ISCC.exe (Inno Setup
    compiler) instead of assuming it's on PATH. Checks, in order: the
    current PATH, the default Inno Setup 7 (64-bit) install location
    (C:\Program Files\Inno Setup 7\), then the default Inno Setup 6
    (32-bit) location (C:\Program Files (x86)\Inno Setup 6\). Raises a
    clear, actionable error (download link + -IsccPath override
    instructions) instead of PowerShell's raw "term not recognized" error
    when Inno Setup isn't found anywhere.

[1.0.0] - 2026-08-02

First stable release. Feature set is now frozen; the 1.0.x line will
only receive bug fixes.

Added

  • scripts/generate_screenshot.py: renders MainWindow off-screen
    against a small in-memory demo library to produce a genuine, reviewable
    assets/docs/screenshot.png for the README (not part of the shipped
    application).

Fixed

  • LibraryFilterProxyModel: replaced the deprecated
    QSortFilterProxyModel.invalidateFilter() calls with the
    beginFilterChange()/endFilterChange() pair recommended since Qt
    6.6, removing the last remaining deprecation warnings from the test
    suite.
  • tests/test_audio_analysis.py: two tests had gone stale after the
    PcmCapture crash-safety fix (introduced while packaging for v0.9.5)
    that defers wiring libVLC's audio_set_format/audio_set_callbacks
    from __init__ to an explicit attach() call. The tests still
    asserted the pre-fix, immediate-registration behaviour and were
    failing under a real libVLC install. Rewritten to reflect the current,
    correct contract (attach() registers the callbacks exactly once,
    idempotently, and only once called) instead of reverting the
    underlying safety fix.
  • Minor style debt cleared project-wide (black, ruff): three
    over-length lines reflowed (core/database/dao.py,
    ui/views/playlist_panel.py), one unused import removed, import
    ordering fixed, and justified noqa annotations added for the Qt
    model API overrides that cannot follow Python naming/default-argument
    conventions (rowCount, columnCount, headerData in
    LibraryTableModel). Zero outstanding black/ruff findings.

Changed

  • Application version bumped to 1.0.0 (main.py, pyproject.toml,
    installer/winmusic.iss).
  • README.md rewritten for the stable release: drops the "planned
    for v1.0.0" framing, documents the actual installer download/install
    steps, and embeds a real interface screenshot instead of the previous
    placeholder note.
  • Full regression pass: pytest + pytest-qt, 144 tests passing, 1
    skipped (a crossfade-start test that requires a live OpenGL context,
    unavailable in headless/offscreen environments — unrelated to this
    release).

[0.9.5] - 2026-08-01

Added

  • PyInstaller --onedir packaging (winmusic.spec, project root):
    freezes src/main.py into a windowed (console=False) WinMusic.exe
    plus its supporting dist/WinMusic/ folder, using the app icon
    (assets/icons/winmusic.ico). Bundles the shaders/ folder and
    assets/icons/ as data, and explicit hiddenimports for the runtime
    dependencies PyInstaller's static analysis cannot always discover on
    its own (vlc, pytesseract, imagehash, acoustid, PIL).
    Optionally vendors the native runtimes the app needs at runtime
    (libVLC, Tesseract OCR, Chromaprint fpcalc) from a local vendor/
    staging folder (see vendor/README.md) so the packaged app stays
    Offline-First: any vendor sub-folder missing at build time is skipped
    rather than failing the build, and the matching optional feature
    degrades gracefully at runtime, exactly as already implemented in
    core/cover_recognition/ocr.py and core/fingerprinting/.
  • core/app_paths.py: centralizes resolution of bundled-resource
    directories (shaders_dir(), icons_dir(), vendor_dir()) so the
    same code works both from a source checkout and from a frozen
    PyInstaller --onedir build (is_frozen() / sys.executable-relative
    resolution instead of a __file__-relative one, which is not reliable
    once modules run from PyInstaller's frozen archive).
    ui/visualizer/shader_registry.py and main.py now resolve the
    shaders folder and the app icon through this module instead of ad hoc
    Path(__file__).resolve().parents[...] expressions.
  • Inno Setup installer script (installer/winmusic.iss): builds
    WinMusicSetup-<version>.exe from the PyInstaller --onedir output,
    with a Start Menu group + uninstaller shortcut, an optional desktop
    shortcut, an optional (opt-in, unchecked by default) .mp3 file
    association, a clean uninstall ([UninstallDelete] removes the
    install directory only — the local database/logs/settings under
    %AppData%\WinMusic are preserved across reinstalls), 64-bit-only
    install (ArchitecturesAllowed=x64compatible), and
    MinVersion=10.0 to enforce the Windows 10/11 target.
  • scripts/build_installer.ps1: orchestrates the full release build
    on a Windows machine — dependency install, pyinstaller winmusic.spec --clean --noconfirm, then ISCC.exe installer\winmusic.iss — failing
    fast with a clear error if either step doesn't produce its expected
    output.
  • vendor/README.md: documents the exact folder layout
    (vendor/vlc/, vendor/tesseract/, vendor/chromaprint/fpcalc.exe)
    and upstream sources expected before running the packaging build, and
    how to verify a produced dist/WinMusic/ folder on a clean Windows
    10/11 VM with no Python/VLC/Tesseract installed system-wide.
  • Test suite extended with test_v095_features.py (frozen vs.
    source-checkout path resolution in core.app_paths, PyInstaller spec
    content — onedir/console/icon/datas/hidden imports, Inno Setup script
    content — required sections, shortcuts, opt-in .mp3 association,
    clean-uninstall behaviour, build script wiring, and cross-file version
    consistency between main.py/pyproject.toml/winmusic.iss) — 14 new
    tests, 143 tests cumulated (VLC-backed playback tests and the
    OpenGL-backed visualizer tests remain environment-dependent on a real
    libVLC install / GPU context, unrelated to this release).

Changed

  • Application version bumped to 0.9.5 (main.py, pyproject.toml,
    installer/winmusic.iss).
  • .gitignore: excludes vendored native runtime binaries
    (vendor/*, keeping vendor/README.md tracked) in addition to the
    existing *.spec/build//dist/ exclusions — none of this packaging
    build output or third-party binary is published to the source-free
    public repository (§9 of ROADMAP.md).

[0.9.0] - 2026-08-01

Added

  • About tab (ui/about_tab.pyAboutTab widget + AboutDialog):
    displays application name, version, copyright, e-mail and website (as
    clickable links), and a short license summary. Reachable from a new
    Help > About WinMusic… menu entry.
  • Application and installer icons (assets/icons/winmusic.ico,
    assets/icons/installer.ico): multi-resolution .ico files (16, 24,
    32, 48, 64, 128, 256 px) generated from a single dark-themed,
    accent-purple design (scripts/generate_icons.py, Pillow-based, fully
    offline/reproducible). The app icon is applied to the QApplication
    window icon at startup.
  • Persisted user settings (core/database/dao.pySettingsDAO
    backed by the existing app_settings table): generic
    get/set/get_int/set_int/delete/all key-value accessors with
    INSERT ... ON CONFLICT DO UPDATE upsert semantics. Three settings are
    now persisted and restored across sessions: last scanned library
    folder (library_folder, pre-fills the folder picker), last shader
    used in the visualizer (last_shader_id, restored on startup), and
    playback volume (volume).
  • Local error logging (core/logging_setup.py): rotating local log
    file (<app-data>/logs/winmusic.log, 2 MB × 3 backups, UTF-8),
    offline-only (no network handler is ever attached), plus a
    sys.excepthook that logs any unhandled exception before the default
    handler runs. Initialized at startup in main.py. Previously-silent
    except: pass blocks in MainWindow (stored cover read failures,
    perceptual-hash computation failures) now log a warning instead of
    failing silently, and scan/tag-write failures are logged with
    logger.exception/logger.error in addition to the existing UI
    message boxes.
  • Test suite extended with test_v090_features.py (SettingsDAO
    CRUD/upsert/int-coercion, configure_logging/log file creation and
    content, About tab constants) — 11 new tests, 129 tests cumulated
    (VLC-backed playback tests remain environment-dependent on a real
    libVLC install, unrelated to this release).

Changed

  • MainWindow: restores persisted settings after the initial UI/library
    load (_restore_settings), and now persists the shader selection and
    volume as they change, and the scanned folder each time File > Scan Folder… is used.
  • main.py: application version bumped to 0.9.0; local logging is
    configured before the Qt application starts.

[0.8.0] - 2026-08-01

Added

  • Online enrichment (core/online_enrichment/), manual/on-demand only,
    never called automatically in the background (Offline-First):
    • MusicBrainzClient: recording search (artist + title) and free-text
      release search (used to search from OCR output), both against the
      public MusicBrainz web service (JSON API, proper User-Agent).
    • CoverArtClient: downloads the front cover for a MusicBrainz release
      id from the Cover Art Archive; raises a dedicated CoverArtError
      (including a clean 404 → "no cover available" case) instead of
      crashing the UI.
    • genre_fallback.py: full ID3v...
Read more