Subject: Re: bug#76350: [PATCH] Add MPD stats viewer to 'mpc'

From: [email-masked]
Date: Sun, 16 Feb 2025 14:08:38 -0600

>From 29a0a567e0bc0543f6f40643e6d788407050ef24 Mon Sep 17 00:00:00 2001
From: john muhl <[email-masked]>
Date: Tue, 5 Nov 2024 10:24:28 -0600
Subject: [PATCH] Add MPD stats viewer to 'mpc' (Bug#76350)

* lisp/mpc.el (mpc-mpd-stats): New command.
(mpc-mode-menu): Add menu item.
(mpc-mpd-stats-date-format, mpc-mpd-stats-duration-format):
New option.
(mpc--mpd-stats-date, mpc--mpd-stats-duration): New function.
(mpc-song-viewer-value, mpc-song-viewer-tag):
(mpc-song-viewer-empty): Remove face.
(mpc-table-value, mpc-table-key, mpc-table-empty): New face.
(mpc-describe-song): Use new table face names.
---
 etc/NEWS    | 12 +++++++--
 lisp/mpc.el | 73 +++++++++++++++++++++++++++++++++++++++++++++--------
 2 files changed, 72 insertions(+), 13 deletions(-)

diff --git a/etc/NEWS b/etc/NEWS
index 6d934b2029c..6a698627f6a 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1134,8 +1134,16 @@ of seconds.  Crossfading can be toggled using the command
 This command displays information about the currently playing song or
 song at point in the "*MPC-Songs*" buffer.  The list of tags to display
 can be customized using the new user option 'mpc-song-viewer-tags' and
-the appearance of the list with the new faces 'mpc-song-viewer-tag',
-'mpc-song-viewer-value', and 'mpc-song-viewer-empty'.
+the appearance of the list with the new faces 'mpc-table-key',
+'mpc-table-value', and 'mpc-table-empty'.
+
+---
+*** New command 'mpc-mpd-stats'.
+This command displays information about the connected MPD server.  The
+appearance of the list can be customized with the new faces
+'mpc-table-key' and 'mpc-table-value'.  The formatting of displayed
+dates and durations can be customized using the new user options
+'mpc-mpd-stats-date-format' and 'mpc-mpd-stats-duration-format'.
 
 ** VC
 
diff --git a/lisp/mpc.el b/lisp/mpc.el
index e25983e48c9..a0e2866d2e0 100644
--- a/lisp/mpc.el
+++ b/lisp/mpc.el
@@ -93,6 +93,8 @@
 
 (require 'cl-lib)
 
+(require 'let-alist)
+
 (require 'notifications)
 
 (require 'vtable)
@@ -1212,6 +1214,7 @@ mpc-mode-menu
      :selected (alist-get 'xfade mpc-status)]
     "--"
     ["Add new browser" mpc-tagbrowser]
+    ["MPD Stats" mpc-mpd-stats]
     ["Update DB" mpc-update]
     ["Quit" mpc-quit]))
 
@@ -2874,17 +2877,17 @@ mpc-notifications-notify
 
 ;;; Song Viewer ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
-(defface mpc-song-viewer-value
+(defface mpc-table-value
   '((t (:inherit vtable)))
-  "Face for tag values in the MPC song viewer.")
+  "Face for values in MPC tables.")
 
-(defface mpc-song-viewer-tag
-  '((t (:inherit (mpc-song-viewer-value bold))))
-  "Face for tag types in the MPC song viewer.")
+(defface mpc-table-key
+  '((t (:inherit (mpc-table-value bold))))
+  "Face for keys in MPC tables.")
 
-(defface mpc-song-viewer-empty
-  '((t (:inherit (mpc-song-viewer-value italic shadow))))
-  "Face for empty tag values in the MPC song viewer.")
+(defface mpc-table-empty
+  '((t (:inherit (mpc-table-value italic shadow))))
+  "Face for empty values in MPC tables.")
 
 (defcustom mpc-song-viewer-tags
   '("Title" "Artist" "Album" "Performer" "Composer"
@@ -2929,15 +2932,15 @@ mpc-describe-song
                         :min-width 3
                         :displayer
                         (lambda (tag &rest _)
-                          (propertize tag 'face 'mpc-song-viewer-tag)))
+                          (propertize tag 'face 'mpc-table-key)))
                       ( :name "Value"
                         :align left
                         :min-width 5
                         :displayer
                         (lambda (value &rest _)
                           (if (and value (not (string-blank-p value)))
-                              (propertize value 'face 'mpc-song-viewer-value)
-                            (propertize "empty" 'face 'mpc-song-viewer-empty)))))
+                              (propertize value 'face 'mpc-table-value)
+                            (propertize "empty" 'face 'mpc-table-empty)))))
            :objects (mapcar
                      (lambda (tag)
                        (pcase tag
@@ -2964,6 +2967,54 @@ mpc-describe-song
                                display-buffer-same-window)
                               (reusable-frames . t))))))
 
+;;; Stats viewer ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defcustom mpc-mpd-stats-date-format "%c"
+  "Format used for dates in `mpc-mpd-stats'.
+See `format-time-string' for formatting details."
+  :version "31.1"
+  :type 'string)
+
+(defcustom mpc-mpd-stats-duration-format "%Y, %D, %z%h:%.2m:%.2s"
+  "Format used for durations in `mpc-mpd-stats'.
+See `format-seconds' for formatting details."
+  :version "31.1"
+  :type 'string)
+
+(defun mpc--mpd-stats-date (seconds)
+  "Format SECONDS as a date for display by `mpc-mpd-stats'."
+  (format-time-string mpc-mpd-stats-date-format (string-to-number seconds)))
+
+(defun mpc--mpd-stats-duration (seconds)
+  "Format SECONDS as a duration for display by `mpc-mpd-stats'."
+  (format-seconds mpc-mpd-stats-duration-format (string-to-number seconds)))
+
+(defun mpc-mpd-stats ()
+  "Display stats about the connected MPD instance."
+  (interactive)
+  (let ((buffer "*MPC Stats Viewer*"))
+    (with-current-buffer (get-buffer-create buffer)
+      (special-mode)
+      (let ((inhibit-read-only t))
+        (erase-buffer)
+        (make-vtable
+         :columns '((:name "MPD Stats" :align right) "")
+         :formatter (lambda (value column &rest _)
+                      (propertize value 'face (if (= column 0)
+                                                  'mpc-table-key
+                                                'mpc-table-value)))
+         :objects (let-alist (mpc-proc-cmd-to-alist (list "stats"))
+                    `(("Artists" ,.artists)
+                      ("Albums" ,.albums)
+                      ("Songs" ,.songs)
+                      ("Play Time" ,(mpc--mpd-stats-duration .playtime))
+                      ("Uptime" ,(mpc--mpd-stats-duration .uptime))
+                      ("DB Play Time" ,(mpc--mpd-stats-duration .db_playtime))
+                      ("DB Updated" ,(mpc--mpd-stats-date .db_update))))))
+      (pop-to-buffer buffer '((display-buffer-reuse-window)
+                              (reusable-frames . t)
+                              (window-height . 10))))))
+
 ;;; Toplevel ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 (defcustom mpc-frame-alist '((name . "MPC") (tool-bar-lines . 1)
-- 
2.48.1

[email-masked] writes:

> Tags: patch
>
> This adds a viewer for mpd stats.
>
> I wasn’t sure about what to do with the faces; reuse the existing
> names or add more so went with rename but don’t mind any of the
> options.