From 53bed5b85d5db59511d036a6c103efae6e9ecb3f Mon Sep 17 00:00:00 2001 From: Christophe Rhodes Date: Fri, 21 Mar 2014 19:33:56 +0000 Subject: [PATCH] minimally useful squeeze control mode I can turn players on and off! Yes! --- squeeze.el | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 89 insertions(+), 2 deletions(-) diff --git a/squeeze.el b/squeeze.el index dbedd7a..c4c8b4e 100644 --- a/squeeze.el +++ b/squeeze.el @@ -17,7 +17,88 @@ (define-derived-mode squeeze-mode comint-mode "Squeeze" "Major mode for interacting with the Squeezebox Server CLI.\\" - (add-hook 'comint-preoutput-filter-functions 'url-unhex-string nil t)) + (add-hook 'comint-preoutput-filter-functions 'url-unhex-string nil t) + (add-hook 'comint-preoutput-filter-functions 'squeeze-update-state nil t)) + +(defvar squeeze-control-mode-map + (let ((map (make-sparse-keymap))) + (define-key map (kbd "SPC") 'squeeze-control-toggle-power) + (define-key map (kbd "g") 'squeeze-control-display-players) + map)) + +(define-derived-mode squeeze-control-mode special-mode "SqueezeControl" + "Major mode for controlling Squeezebox Servers.\\") + +(defun squeeze-update-state (string) + (cond + ((string-match "^players 0" string) + (setq squeeze-players (squeeze-parse-players-line string)))) + string) + +(defface squeeze-player-face + '((t :weight bold)) + "Face for displaying players") + +(defvar squeeze-players ()) + +(defun squeeze-control-toggle-power (&optional id) + (interactive) + (unless id + (setq id (get-text-property (point) 'squeeze-playerid))) + (comint-send-string (get-buffer-process "*squeeze*") (format "%s power\n" id))) + +(defun squeeze-control-query-power (&optional id) + (interactive) + (unless id + (setq id (get-text-property (point) 'squeeze-playerid))) + (comint-send-string (get-buffer-process "*squeeze*") (format "%s power ?\n" id))) + +(defun squeeze-control-display-players () + (interactive) + (let ((players squeeze-players)) + (with-current-buffer (get-buffer-create "*squeeze-control*") + (squeeze-control-mode) + (read-only-mode -1) + (erase-buffer) + (dolist (player players) + (insert (propertize (squeeze-player-name player) + 'face 'squeeze-player-face + 'squeeze-playerid (squeeze-player-playerid player)) + "\n")) + (read-only-mode 1)))) + +(cl-defstruct (squeeze-player (:constructor squeeze-make-player)) + playerindex playerid uuid ip name model isplayer displaytype canpoweroff connected) + +(defun squeeze-string-plistify (string start end) + (save-match-data + (let (result) + (loop + (message "start: %d" start) + (if (string-match "\\([a-z]+\\)%3A\\([^ ]+\\)" string start) + (let ((mend (match-end 0))) + (when (> mend end) + (return)) + (push (intern (format ":%s" (substring string (match-beginning 1) (match-end 1)))) result) + (push (url-unhex-string (substring string (match-beginning 2) (match-end 2))) result) + (setq start mend)) + (return))) + (nreverse result)))) + +(defun squeeze-parse-players-line (string) + (let ((countpos (string-match " count%3A\\([0-9]\\) " string)) + (startpos (match-end 0))) + (unless countpos + (message "no count found in players line")) + (let ((count (parse-integer string (match-beginning 1) (match-end 1))) + result endpos) + (dotimes (i (1- count)) + (setq endpos (progn (string-match " connected%3A[0-1] " string startpos) + (match-end 0))) + (push (apply 'squeeze-make-player (squeeze-string-plistify string startpos endpos)) result) + (setq startpos endpos)) + (push (apply 'squeeze-make-player (squeeze-string-plistify string startpos (length string))) result) + result))) (defun squeeze-complete-command-at-point () (save-excursion @@ -61,7 +142,6 @@ ;; Plugins commands and queries "favorites" - )))) (defun squeeze () @@ -71,3 +151,10 @@ squeeze-server-port)))) (switch-to-buffer buffer) (squeeze-mode))) + +(defun squeeze-control () + (interactive) + (squeeze) + (let ((buffer (get-buffer-create "*squeeze-control*"))) + (switch-to-buffer buffer) + (squeeze-control-display-players))) -- 2.30.2