SUN (Slackware Update Notifier)
===============================

### Version 2.5.2 - *(29/05/2026)*
- Fixed:
    * `sun-tray.desktop` removed invalid `&` from `Exec` key (reported by B. Watson)
    * `PACKAGES.TXT` reading now tolerates non-UTF-8 bytes (e.g. latin-1 characters
      in package descriptions) instead of crashing the tray icon (reported by B. Watson)

- Updated:
    * `Config file` comments about slack_patches repository for stable 15.0 version
    and current.

### Version 2.5.1 - *(23/04/2026)*
- Fixed:
    * `pending` command reordered after `check` in CLI help output and man page
      to match the tray icon menu order

- Added:
    * `Pending` new icon color for tray icon menu
    * Tray ChangeLog dialog limited to 1000 lines for performance; full file
      available via `sun changelog` in the terminal
    * `/etc/sun/blacklist.conf` to exclude packages from `sun pending`;
      package names listed under `PACKAGES` in `[BLACKLIST]` are skipped

### Version 2.5.0 - *(16/04/2026)*
- Added:
    * `sun pending` CLI command to list installed packages that have a newer
      version available in the repository but have not yet been upgraded
    * Yellow tray badge when packages are pending upgrade (lower priority than
      the red badge for available updates); tooltip shows the pending count
    * Tray menu item "Pending Upgrades" to view the pending package list
    * Package manager auto-detected from LOG_PATH: data.json (slpkg) or
      PACKAGES.TXT (slackpkg); no extra configuration required
    * Tray badge refreshes immediately when data.json, PACKAGES.TXT, or
      /var/log/packages changes, in addition to the existing ChangeLog watcher

### Version 2.4.0 - *(25/03/2026)*
- Added:
    * OK button added to ChangeLog and SUN Log dialogs, centered to match
      the About dialog style
    * NOTIFICATIONS option in sun.conf [TIME] section to enable/disable desktop
      notifications independently; the tray badge continues to update regardless
    * HTTP_TIMEOUT option in sun.conf [REPOSITORY] section to set the timeout
      in seconds for HTTP requests to the mirror (default: 30)
    * `sun config` CLI command to view the loaded sun.conf configuration with
      aligned key = value output per section
    * Tray icon Config menu item to view the configuration in a dialog

- Fixed:
    * HTTP response decoded with explicit UTF-8 and errors='replace' to prevent
      UnicodeDecodeError crash when mirror returns non-UTF-8 content
    * IndexError crash in process_pids when a ps aux output line is malformed
    * ValueError crash in config_html when sun.conf has no sections
    * Zombie process detection race condition in daemon_status: if /proc/{pid}/status
      disappears between os.kill(0) check and read, process is now correctly
      reported as not running
    * Unexpected exceptions in the daemon update loop now log a full traceback
      instead of just the error message

### Version 2.3.0 - *(23/03/2026)*
- Added:
    * -n/--no-color flag for `sun check` and `sun info` to disable colored output
    * COLORED_OUTPUT option in sun.conf [TRAY_ICON] section to enable/disable
      colors in the tray icon Check Updates and OS Info dialogs
    * BADGE_INTERVAL option in sun.conf [TRAY_ICON] section: independent check
      interval (minutes) for the tray badge, separate from the daemon INTERVAL
      (default: 180 minutes)
    * Tray badge syncs immediately with daemon notification via SIGUSR1: daemon
      sends SIGUSR1 to the tray process after finding updates, so badge and
      desktop notification appear at the same time
    * `sun check` and tray Check Updates warn if HTTP_MIRROR does not match
      the installed Slackware version (stable 15.0 vs current 15.0+);
      suppressed by setting IGNORE_MIRROR_WARNING = true in sun.conf
    * Tray icon badge: numeric update count overlaid on the tray icon, updated
      silently in the background at the daemon's check interval
    * QFileSystemWatcher on the local ChangeLog: badge refreshes immediately
      when slpkg/slackpkg updates the file, with automatic re-watch after
      atomic writes (editor save via rename)
    * `sun log` CLI command to view the daemon log via pager
    * Tray icon SUN Log menu item to view the daemon log in a scrollable dialog
    * Tray icon shows greyscale icon when daemon is not running; restores
      normal/badge icon automatically after daemon start or restart
    * Tray ChangeLog dialog colors date headers (yellow/bold) and Patrick's
      indented comment lines (blue-grey) when COLORED_OUTPUT = true
    * LOG_FONT_SIZE option in sun.conf [TRAY_ICON] section to set the font
      size (points) for the ChangeLog and SUN Log dialogs (default: 10)
    * OK button added to ChangeLog and SUN Log dialogs, centered to match
      the About dialog style

- Fixed:
    * daemon_status() incorrectly reported zombie sun-daemon processes as
      running, preventing `sun start` after `sun stop`
    * Greyscale offline icon had black background due to alpha channel loss
      during Format_Grayscale8 conversion; fixed by manual per-pixel ARGB
      conversion preserving original alpha
    * Tray icon briefly showed normal icon on reload when daemon was offline;
      fixed by immediate daemon state check (PID only, no HTTP) at startup

- Improved:
    * Tray icon menu order: Os Info moved below Check Updates
    * Fetcher: If-Modified-Since HTTP caching avoids re-downloading the remote
      ChangeLog when it has not changed; cached content reused on 304 responses
    * Fetcher: early-return guards for missing mirror, empty local ChangeLog and
      missing date prevent showing false "no updates" results
    * Fetcher: `last_fetch_error` flag propagated to `check_updates()` so a
      network failure returns an explicit error message instead of "No news is
      good news!"

- Improved:
    * `sun check` CLI: bold header, numbered packages, color-coded actions
      (Upgraded/Rebuilt/Added/Removed), aligned action columns
    * Tray icon Check Updates dialog: monospace font, aligned columns, HTML
      color spans inside <pre> block, dynamic width, h3 bold header, theme-adaptive
      colors (dark/light palette)
    * Desktop notification: auto-centered title, bold package count via Pango
      markup, category hint set to 'software'

### Version 2.2.0 - *(22/03/2026)*
- Added:
    * About dialog replaced with custom QDialog: centered icon, title, QTextBrowser
      with clickable links (email, license, website), Close button, theme colors support
    * Rotating file logger in daemon.py (~/.local/share/sun/sun-daemon.log, 1MB, 2 backups)
      logs: daemon start/stop, update check results, notifications shown, errors
    * Module-level logger in utils.py (logging.getLogger) for network and file errors
      alongside existing print() output for CLI visibility
    * sun check [pattern] — optional filter to match package names (e.g. sun check kernel)
    * sun changelog — fetch and display remote ChangeLog.txt via pager ($PAGER or less)
    * Tray icon ChangeLog menu item — scrollable QDialog with monospace font
    * Cyan color for section headers ([System], [Processor], [Memory], [Disk], [GPU])
      in both `sun info` CLI output (ANSI) and OS Info tray dialog (HTML inline style)
    * sun_about.png (72x72) dedicated icon for the About dialog
    * sun-autostart note added to manpage NOTES section and CLI help epilog

- Refactored:
    * get_static_paths() split from get_os_info() in sys_info.py — returns only
      installation paths (no subprocess/proc reads), called by Configs.__init__
    * get_os_info() now returns hardware info only, called lazily by os_info_html()
      so sun -h, sun start, sun check etc. no longer pay the lspci/proc scan cost
    * configs_load singleton added to configs.py (pattern from slpkg) — shared
      across all modules, replacing per-call Configs() instantiation

- Fixed:
    * daemon_start() spawns a daemon thread calling proc.wait() to reap sun-daemon
      on exit, preventing [sun-daemon] <defunct> zombie entries. Replaces the
      double-fork approach which was unsafe in multithreaded contexts (PyQt5 tray)
      due to inherited Qt locks in the forked child
    * configs.py now catches configparser.Error for malformed config files
    * tray_icon.py stylesheet applied only when get_theme_colors() returns valid values,
      preventing invalid CSS with literal "None" when GTK theme detection fails
    * configs.py validates numeric config values: INTERVAL/STANDBY >= 1,
      DELAY_LOAD >= 0, MAX_PACKAGES >= 1 — raises SystemExit with clear message
    * daemon.py now writes its own PID file on startup so `sun status` works
      correctly when the daemon is launched via XDG autostart (not through `sun start`)
    * daemon.py removes the PID file on exit via finally block
    * handle PackageNotFoundError when sun is not installed (importlib.metadata)

- Refactored:
    * get_theme_colors() rewritten to use Qt QPalette instead of gsettings/GTK CSS parsing,
      works on all desktops (KDE, XFCE, etc.) without external process calls
    * autostart.py CLI replaced with argparse (ArgumentParser with enable/disable/status subcommand)
    * Autostart class introduced with enable(), disable(), status() and run() methods
    * enable and disable actions now report 'not installed' when no autostart files are found
    * shutil.move() replaced with Path.rename() for file operations
    * notifier.py renamed back to daemon.py (reverts erroneous rename from 2.1.0)
    * PID file path defined once in Manager.PID_FILE and referenced from daemon.py
    * daemon owns PID file lifecycle, removed redundant write from _daemon_start

### Version 2.1.0 - *(20/03/2026)*
- Fixed:
    * Configs class-level get_os_info() call moved to __init__ to avoid side effects on import
    * FileNotFoundError now properly caught in Configs alongside KeyError
    * subprocess check=False for lspci to prevent crash when VGA not available
    * IndexError guard for disk_partitions() when no partitions found
    * None guard for psutil.cpu_count() on systems that cannot determine CPU count
    * autostart status command now reports when autostart files are not installed

- Added:
    * urllib3 and psutil declared as dependencies in pyproject.toml
    * MAX_PACKAGES option in sun.conf to configure the maximum number of
      packages displayed in the tray icon popup. Default is 10.

- Refactored:
    * Fetch.__init__ super() call corrected from super(Utilities) to super()
    * Utilities.__init__ removed as redundant after moving data_configs to Configs
    * data_configs moved to Configs.__init__ as instance attribute to avoid redundant get_os_info() calls
    * Removed unused get_os_info import from utils.py

- Fixed:
    * Removed debug print statement left in process_pids()
    * urllib3.exceptions.LocationValueError now correctly caught instead of KeyError for FTP mirrors
    * Removed redundant get_os_info() call in Notify.__init__ (already set via Configs)
    * Removed unused Tools instantiation in Notify.__init__
    * Removed unused imports in daemon.py (Any, Tools, get_os_info)
    * Fixed bug in view_os_info where <br> tags were stripped before newline conversion
    * daemon_status() now called once per daemon_process() invocation
    * Removed redundant Configs base class from Cli (already inherited via Tools)
    * Removed duplicate Utilities instantiation in Cli.__init__
    * Removed unused repositories_message variable in check_updates()
    * Fixed typo in daemon_process docstring
    * Simplified daemon_status() return statement
    * Fixed crash in get_theme_colors() on non-GNOME desktops (missing gsettings)
    * Fixed KeyError in is_xserver_ready() when DISPLAY is not set (Wayland)
    * Removed redundant get_os_info() call in TrayIcon.__init__
    * Replaced multiple Utilities() instantiations with self.tool.utils in TrayIcon
    * Removed dead setIconPixmap call in show_message()
    * Replaced old-style .format() with f-string in show_check_updates()
    * Removed unused get_os_info import from tray_icon.py
    * Fixed daemon_process() always showing "FAILED" prefix for early-exit conditions (output initialized to 1 instead of 0)

- Removed:
    * External `daemon` tool dependency replaced with Python-native process management
    * [DAEMON] section removed from sun.conf (implementation detail, not user config)
    * sun_daemon_start/stop/restart/running attributes removed from Configs class
    * psutil dependency replaced with native Linux interfaces (/proc/uptime,
      /proc/cpuinfo, /proc/meminfo, os.statvfs, /proc/mounts)

- Changed:
    * daemon_status() now uses os.kill(pid, 0) via PID file instead of external daemon --running
    * daemon_start() uses subprocess.Popen with start_new_session=True to detach from terminal
    * daemon_stop() uses os.kill(pid, SIGTERM) and removes PID file
    * daemon_process() handles restart with stop → sleep(1) → start sequence
    * CLI menu replaced with argparse subcommands (start, stop, restart, status, check, info)
    * sun start --tray is now a flag of the start subcommand
    * --help and --version are now built-in via argparse
    * Removed PID from restart message to avoid showing stale pre-restart PID
    * sun start and sun restart now display the new PID after the daemon starts
    * sun start --tray uses Popen with start_new_session=True instead of shell=True
    * daemon_stop() raises OSError if PID file is missing instead of ValueError
    * repo_pattern and repo_days moved to Fetch class constants REPO_PATTERN and REPO_DAYS
    * process_pids() return type corrected from list to list[int]
    * Removed assert statements in tray_icon.py for Qt menu actions
    * Union[str, None] replaced with Optional[str] in tray_icon.py
    * pycodestyle and flake8 config moved from setup.cfg to pyproject.toml
    * setup.cfg removed
    * install.sh copyright updated to 2026 and useless cat replaced with grep -oP
    * Python 3.10, 3.11, 3.12 classifiers added to pyproject.toml
    * sun-daemon.desktop.sample Exec updated to use sun-daemon directly
    * Test coverage increased from 58% to 92%

- Added:
    * Comprehensive pytest test suite covering configs, sys_info, utils, cli/tool, daemon and tray_icon modules
    * Type annotations: tuple[str, list[str]] and Callable[[], None] in cli/tool.py
    * Optional[str] annotations and None guards for mirror_log and local_log in utils.py
    * Return type annotation -> None for Fetch.__init__

### Version 2.0.3 - *(12/03/2025)*
- Fixed:
    * Kill double start the tray icon app after unexpected PC terminated

### Version 2.0.2 - *(08/03/2025)*
- Renamed:
    * Autostart desktop file and script

- Fixed:
    * sun-autostart help menu
    * Allow exiting tray app with ctrl-c

### Version 2.0.1 - *(03/03/2025)*
- Fixed:
    * Desktop sun icon path

- Added:
    * Menu to reload the tray icon app
    * For X Server tray icon app load
    * Config to delay tray icon app

### Version 2.0.0 - *(27/02/2025)*
- Added:
    * New tray app based to PyQT5 library
    * PID daemon process to messages
    * Extra system information
    * python3-psutil dependency

- Removed:
    * Multiple repository supports
    * Require python3-tomlkit

- Merged:
    * sun.toml and repositories.toml files into sun.conf.file

- Fixed:
    * Load OS system information for tray app

### Version 1.6.3 - *(19/09/2024)*
- Fixed:
    * ModuleNotFoundError: No module named 'tomli' for Slackware current

- Added:
    * Added new dependency: python3-tomlkit

### Version 1.6.2 - *(15/05/2024)*
- Fixed:
    * Slackbuild script version

### Version 1.6.1 - *(13/05/2024)*
- Updated:
    * Improve code quality

- Fixed:
    * Default regex compare pattern

### Version 1.6.0 - *(13/02/2024)*
- Updated:
    * Copyright year
    * Python requirement >= 3.9
    * Installation script and slackbuild
    * Rename /usr/sbin/sun_daemon to /usr/sbin/sun-autostart
    * Rename /usr/bin/sun_daemon to /usr/bin/sun-daemon
    * Rename /usr/bin/sun_gtk to /usr/bin/sun-gtk

### Version 1.5.2 - *(07/06/2023)*
- Updated:
    * For urllib3.exceptions.HTTPError

### Version 1.5.1 - *(24/05/2023)*
- Fixed:
    * SlackBuild script for repositories.toml file

### Version 1.5.0 - *(19/05/2023)*
- Fixed:
    * Daemon notification message
- Added:
    * Configuration file /etc/sun/repositories.toml

### Version 1.4.9 - *(22/02/2023)*
- BugFixed:
    * Time interval sleep

### Version 1.4.8 - *(22/02/2023)*
- Updated:
    * The daemon passed to the config file
    * sun_daemon completed control with daemon tool
    * sun_daemon works independently of sun check command
    * The comparison of the logs passed to the repository section

### Version 1.4.7 - *(22/02/2023)*
- Fixed:
    * Slackbuild script

### Version 1.4.6 - *(19/02/2023)*
- Updated:
    * Error for http connection error
    * Error for the Log file if not exists
    * Increased the interval to 720 minutes
- Added:
    * Prefix to the config to check for in the Log files
- Fixed:
    * sun_daemon process in KDE env

### Version 1.4.5 - *(17/02/2023)*
- Updated:
    * Support multi repositories
- Fixed:
    * f string in the config file

### Version 1.4.4 - *(14/02/2023)*
- Updated:
    * For a Regular Expression Syntax

### Version 1.4.3 - *(06/02/2023)*
- Added:
    * Packages pattern and kernel pattern in the config file
    * Mirror and library in the config file

### Version 1.4.2 - *(23/12/2022)*
- Updated:
    * Improve the code
    * Dependencies (remove python-toml)

### Version 1.4.1 - *(08/12/2022)*
- Updated:
    * Replace the bash autostart daemon script with python script

### Version 1.4.0 - *(06/12/2022)*
- Updated:
    * Code style
    * Daemon autostart scripts
- Fixed:
    * Function bash scripts

### Version 1.3.9 - *(05/12/2022)*
- Updated:
    * Utilities to class object
    * Metadata switch to dictionary

### Version 1.3.8 - *(03/12/2022)*
- Fixed:
    * Restarting daemon message
- Added:
    * Some scripts for enable or disable daemon by the user (Thanks to marav) #12
    * Check the subprocess output status
- Updated:
    * subprocess run once from cli either from gtk

### Version 1.3.7 - *(02/12/2022)*
- Updated:
    * CLI menu
- Added:
    * Getting processor information
    * Getting memory information
    * Getting disk information
    * Uptime information

### Version 1.3.6 - *(01/12/2022)*
- Fixed:
    * Fixed stderr error output
    * sun.conf is overwritten on reinstall #13
- Updated:
    * Switch sun configuration file with python toml
    * Install sun.desktop in the /etc/xdg/autostart (Thanks to marav) #12
    * Install sun_daemon.desktop in the /etc/xdg/autostart #12
    * Add daemon tool to manage sun_daemon

### Version 1.3.5 - *(18/02/2022)*
- Fixed:
    * Version in SlackBuild file

### Version 1.3.4 - *(18/02/2022)*
- Updated:
    * For ftp mirrors

### Version 1.3.3 - *(16/02/2022)*
- Updated:
    * Replace sun icon with new

### Version 1.3.2 - *(09/02/2022)*
- Updated:
    * Copyright year
    * Dependencies

### Version 1.3.1 - *(03/04/2020)*
- Updated:
    * Temporary avoid working with ftp mirrors #9

### Version 1.3.0 - *(12/02/2020)*
- Updated:
    * Migrate to Gtk 3.0
    * Migrate to Python 3
- Added:
    * Testing with pytest

### Version 1.2.3 - *(07/07/2018)*
- Updated:
    * Switch to gitlab repository

### Version 1.2.2 - *(03/03/2018)*
- Updated:
    * Switch to python-notify2
- Fixed:
    * Added directories and removed packages

### Version 1.2.1 - *(09/03/2016)*
- Fixed:
    * Start daemon when GTK icon loaded
- Updated:
    * Rename main.py to daemon.py 

### Version 1.2.0 - *(08/03/2016)*
- Updated:
    * Management daemon without using rc.sun file. Thanks to Robby
Workman for the contribution #6

### Version 1.1.7 - *(16/02/2016)*
- Fixed:
    * Avoid terminate gtk status icon

### Version 1.1.6 - *(10/02/2016)*
- Added:
    * Keyboard interrupt on cli, daemon and gtk
- Fixed:
    * IOError: [Errno 2] No such file or directory: '/var/lib/slackpkg/ChangeLog.txt'

### Version 1.1.5 - *(30/01/2016)*
- Updated:
    * Copyright 2015-2016
    * Year int to string
- Fixed:
    * SUN status icon

### Version 1.1.4 - *(07/09/2015)*
- Updated:
    * ChangeLog.txt url
- Removed:
    * sun mirrors file

### Version 1.1.3 - *(11/8/2015)*
- Fixed:
    * setup.py install requirements

### Version 1.1.2 - *(11/08/2015)*
- Added:
    * Support Slackware ARM

### Version 1.1.1 - *(01/08/2015)*
- Fixed:
    * Support old Slackware versions
- Updated:
    * SlackBuild script

### Version 1.1.0 - *(10/06/2015)*
- Added:
    * Preserve_perms to doinst.sh. Thanks to Thibaut Notteboom
    * Submenu gtk icons
- Fixed:
    * Doc strings
    * Tooltip message
    * Merge added packages in count

### Version 1.0.9 - *(15/05/2015)*
- Fixed:
    * Messages and added status icon message
- Updated:
    * CLI tool
- Added:
    * Username in info

### Version 1.0.8 - *(23/04/2015)*
- Added:
    * Counted new packages added

### Version 1.0.71 - *(16/04/2015)*
- Fixed:
    * License

### Version 1.0.7 - *(15/04/2015)*
- Updated:
    * Merge license to about

### Version 1.0.6 - *(31/03/2015)*
- Fixed:
    * Daemon loop wait one second before connect to ISP

### Version 1.0.5 - *(20/03/2015)*
- Fixed:
    * Ignore current in information
- Updated:
    * Update CLI tool

### Version 1.0.4 - *(18/03/2015)*
- Added:
    * Information, license and update gtk.MessageBox

### Version 1.0.3 - *(14/03/2015)*
- Fixed:
    * BugFix with slackpkg+ update. Thanks to Maciej Gołuchowski for report
    * BugFix gtk display large number of packages

### Version 1.0.2 - *(14/03/2015)*
- Added:
    * Gtk status icon with popup menu

### Version 1.0.1 - *(11/03/2015)*
- Updated:
    * CLI options
- Added:
    * Check software updates
    * Display upgraded or rebuilt packages

### Version 1.0.0 - *(04/03/2015)*
- Added:
    * Released version 1.0.0
