;;; jao-mpdn.el --- Notifications using elmpd -*- lexical-binding: t; -*- ;; Copyright (C) 2021 jao ;; Author: jao ;; Keywords: convenience ;; Version: 0.1 ;; Package-requires: ((emacs "27.1") (elmpd "0.1.9")) ;; URL: https://codeberg.org/jao/lib/media ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, either version 3 of the License, or ;; (at your option) any later version. ;; This program is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with this program. If not, see . ;;; Commentary: ;; React to mpd player status changes. ;;; Code: (require 'elmpd) (require 'jao-minibuffer) (defvar jao-mpdn--connection nil) (defvar jao-mpdn-host "localhost") (defvar jao-mpdn-port 6600) (defvar-local jao-mpdn--local-port nil) (defun jao-mpdn--disconnect (conn) (delete-process (elmpd-connection--fd conn))) (defun jao-mpdn--connect (name &optional cb) (elmpd-connect :name name :host jao-mpdn-host :port jao-mpdn-port :subsystems (when cb `((player) . ,cb)))) (defun jao-mpdn-disconnect () (interactive) (when jao-mpdn--connection (jao-mpdn--disconnect jao-mpdn--connection) (setq jao-mpdn--connection nil))) (defun jao-mpdn-connect (&optional force) (interactive) (when force (jao-mpdn-disconnect)) (unless jao-mpdn--connection (setq jao-mpdn--connection (jao-mpdn--connect "jao-mpc" 'jao-mpdn--watcher)) (jao-mpdn--watcher jao-mpdn--connection 'player)) jao-mpdn--connection) (defun jao-mpdn--send (cmd cb) (elmpd-send jao-mpdn--connection cmd cb)) (defvar jao-mpdn--play-status '()) (defvar jao-mpdn--current '()) (defvar jao-mpdn-minibuffer-str "") (defun jao-mpdn--parse-retort (txt) (let (res) (dolist (e (split-string txt "\n" t " ") res) (let ((e (split-string e ": " t " "))) (when (and (car e) (cadr e)) (push (cons (car e) (cadr e)) res)))))) (defun jao-mpdn--update-status (next) (let ((cb (lambda (_c ok txt) (when ok (setq jao-mpdn--play-status (jao-mpdn--parse-retort txt)) (when next (funcall next)))))) (jao-mpdn--send "status" cb))) (defun jao-mpdn--current-get (x &optional def) (alist-get x jao-mpdn--current def nil #'string=)) (defun jao-mpdn--status-get (x &optional def) (alist-get x jao-mpdn--play-status def nil #'string=)) (defun jao-mpdn--playing-p () (string= (jao-mpdn--status-get "state" "") "play")) (defun jao-mpdn--current-str () (let ((title (jao-mpdn--current-get "Title")) (album (jao-mpdn--current-get "Album")) (no (string-to-number (jao-mpdn--current-get "Track" "0"))) (len (string-to-number (jao-mpdn--status-get "playlistlength" "1"))) (artist (jao-mpdn--current-get "Artist")) (composer (jao-mpdn--current-get "Composer"))) (format " %s%s %s%s%s" (jao--put-face (if (zerop no) "" (format "%02d/%s " no len)) 'jao-themes-f02) (jao--put-face title 'jao-themes-f00) (jao--put-face artist 'jao-themes-f01) (jao--put-face (if composer (format " [%s]" composer) "") 'jao-themes-f01) (jao--put-face (if album (format " (%s)" album) "") 'jao-themes-f11)))) (defun jao-mpdn--update-minibuffer () (setq jao-mpdn-minibuffer-str (if (jao-mpdn--playing-p) (jao-mpdn--current-str) "")) (jao-minibuffer-refresh)) (defun jao-mpdn--update-current (&optional next) (let ((cb (lambda (_c ok txt) (when ok (setq jao-mpdn--current (jao-mpdn--parse-retort txt)) (jao-mpdn--update-minibuffer) (cond (next (funcall next)) ((and (null jao-mpdn--current) jao-random-album-p) (jao-random-album-next))))))) (jao-mpdn--send "currentsong" cb))) (defun jao-mpdn--watcher (_conn _subsys) (jao-mpdn--update-status #'jao-mpdn--update-current)) ;;;###autoload (defun jao-mpdn-setup () (jao-mpdn-connect t) (jao-minibuffer-add-msg-variable 'jao-mpdn-minibuffer-str 1)) (provide 'jao-mpdn) ;;; jao-mpdn.el ends here