Skip to content

Commit

Permalink
Merge branch 'master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
danielfm authored Dec 7, 2023
2 parents f458a6f + 5f4cf01 commit 0e69fce
Show file tree
Hide file tree
Showing 12 changed files with 98 additions and 54 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/melpazoid.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Python 3.6
- name: Set up Python 3.12
uses: actions/setup-python@v1
with: { python-version: 3.6 }
with: { python-version: 3.12 }
- name: Install
run: |
python -m pip install --upgrade pip
Expand Down
10 changes: 6 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -195,10 +195,10 @@ via their corresponding variables:
| Playing | `smudge-player-status-playing-text` | `"Playing"` |
| Paused | `smudge-player-status-paused-text` | `"Paused"` |
| Stopped | `smudge-player-status-stopped-text` | `"Stopped"` |
| Shuffling On | `smudge-player-status-repeating-text` | `"R"` |
| Shuffling Off | `smudge-player-status-not-repeating-text` | `"-"` |
| Repeating On | `smudge-player-status-shuffling-text` | `"S"` |
| Repeating Off | `smudge-player-status-not-shuffling-text` | `"-"` |
| Repeating On | `smudge-player-status-repeating-text` | `"R"` |
| Repeating Off | `smudge-player-status-not-repeating-text` | `"-"` |
| Shuffling On | `smudge-player-status-shuffling-text` | `"S"` |
| Shuffling Off | `smudge-player-status-not-shuffling-text` | `"-"` |

#### Global Remote Mode

Expand All @@ -216,6 +216,7 @@ key bindings:
| <kbd>a</kbd> | Adds track to a playlist |
| <kbd>l</kbd> | Loads the next page of results (pagination) |
| <kbd>g</kbd> | Clears the results and reloads the first page of results |
| <kbd>k</kbd> | Adds track to the queue |
| <kbd>M-RET</kbd> | Plays the track under the cursor in the context of its album [1] |

[1] D-Bus implementation for GNU/Linux do not support passing the context, so
Expand Down Expand Up @@ -286,6 +287,7 @@ bindings in the resulting buffer:
| <kbd>g</kbd> | Clears the results and reloads the first page of results |
| <kbd>f</kbd> | Follows the current playlist |
| <kbd>u</kbd> | Unfollows the current playlist |
| <kbd>k</kbd> | Adds track to the queue |
| <kbd>M-RET</kbd> | Plays the track under the cursor in the context of the playlist [1] |

Both buffers load the `global-smudge-remote-mode` by default.
Expand Down
29 changes: 27 additions & 2 deletions smudge-api.el
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@

;;; Commentary:

;; This library is the interface to the Spotify RESTful API. It also does some custom handling of
;; the OAuth code exchange via 'simple-httpd
;; This library is the interface to the Spotify RESTful API. It also does some
;; custom handling of the OAuth code exchange via 'simple-httpd

;;; Code:

(require 'simple-httpd)
(require 'request)
(require 'oauth2)
(require 'browse-url)

(defcustom smudge-oauth2-client-id ""
"The unique identifier for your application.
Expand Down Expand Up @@ -613,5 +614,29 @@ Call CALLBACK if provided."
nil
callback))


(defun smudge-api-queue-add-track (track-id &optional callback)
"Add given TRACK-ID to the queue and call CALLBACK afterwards."
(smudge-api-call-async
"POST"
(concat "/me/player/queue?"
(url-build-query-string `((uri ,track-id))
nil t))
nil
callback))

(defun smudge-api-queue-add-tracks (track-ids &optional callback)
"Add given TRACK-IDS to the queue and call CALLBACK afterwards."
;; Spotify's API doesn't provide a endpoint that would enable us to
;; add multiple tracks to the queue at the same time.
;; Thus we have to synchronously add the tracks
;; one by one to the queue.
(if (car track-ids)
(smudge-api-queue-add-track (car track-ids)
(lambda (_)
(smudge-api-queue-add-tracks (cdr track-ids)
nil)))
(funcall callback)))

(provide 'smudge-api)
;;; smudge-api.el ends here
14 changes: 6 additions & 8 deletions smudge-apple.el
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,21 @@

;;; Commentary:

;; This library handles controlling Spotify via Applescript commands. It implements a set of
;; multimethod-like functions that are dispatched in smudge-controller.el.
;; This library handles controlling Spotify via Applescript commands. It
;; implements a set of multimethod-like functions that are dispatched in
;; smudge-controller.el.

;;; Code:

(require 'smudge-controller)

(defvar smudge-apple-player-status-script)
(defvar smudge-apple-player-status-script-file)

(defcustom smudge-osascript-bin-path "/usr/bin/osascript"
"Path to `osascript' binary."
:group 'smudge
:type 'string)

;; Do not change this unless you know what you're doing
(setq smudge-apple-player-status-script "
(defconst smudge-apple-player-status-script "
# Source: https://github.com/andrehaveman/smudge-node-applescript
on escape_quotes(string_to_escape)
set AppleScript's text item delimiters to the \"\\\"\"
Expand All @@ -49,8 +47,8 @@ end tell
")

;; Write script to a temp file
(setq smudge-apple-player-status-script-file
(make-temp-file "smudge.el" nil nil smudge-apple-player-status-script))
(defconst smudge-apple-player-status-script-file
(make-temp-file "smudge.el" nil nil smudge-apple-player-status-script))

(defun smudge-apple-command-line (cmd)
"Return a command line prefix for any Spotify command CMD."
Expand Down
14 changes: 7 additions & 7 deletions smudge-connect.el
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@

;;; Commentary:

;; This library uses the "connect" APIs to control transport functions of remote and local instances
;; of Spotify clients. It implements a set of multimethod-like functions that are dispatched in
;; smudge-controller.el.
;; This library uses the "connect" APIs to control transport functions of
;; remote and local instances of Spotify clients. It implements a set of
;; multimethod-like functions that are dispatched in smudge-controller.el.

;; smudge-connect.el --- Smudge transport for the Spotify Connect API

Expand Down Expand Up @@ -118,16 +118,16 @@ Returns a JSON string in the format:
(message "Volume decreased to %d%%" new-volume))))))))

(defun smudge-connect-volume-mute-unmute ()
"Mute/unmute the volume on the actively playing device by setting the volume to 0."
"Mute/unmute the actively playing device by setting the volume to 0."
(smudge-connect-when-device-active
(smudge-api-get-player-status
(lambda (status)
(let ((volume (smudge-connect-get-volume status)))
(if (eq volume 0)
(smudge-api-set-volume (smudge-connect-get-device-id status) 100
(lambda (_) (message "Volume unmuted")))
(lambda (_) (message "Volume unmuted")))
(smudge-api-set-volume (smudge-connect-get-device-id status) 0
(lambda (_) (message "Volume muted")))))))))
(lambda (_) (message "Volume muted")))))))))

(defun smudge-connect-toggle-repeat ()
"Toggle repeat for the current track."
Expand Down Expand Up @@ -156,7 +156,7 @@ Returns a JSON string in the format:
(defun smudge-connect--is-shuffling (player-status)
"Business logic for shuffling state of PLAYER-STATUS."
(and player-status
(not (eq (gethash 'shuffle_state player-status) :json-false))))
(not (eq (gethash 'shuffle_state player-status) :json-false))))

(defun smudge-connect--is-repeating (player-status)
"Business logic for repeat state of PLAYER-STATUS."
Expand Down
19 changes: 10 additions & 9 deletions smudge-controller.el
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,16 @@

;;; Commentary:

;; This library defines a set of commands for controlling an instance of a Spotify client. The
;; commands are sent via a multimethod-like dispatch to the chosen transport.
;; This library defines a set of commands for controlling an instance of a
;; Spotify client. The commands are sent via a multimethod-like dispatch to
;; the chosen transport.

;;; Code:

(require 'smudge-api)

(defmacro smudge-if-gnu-linux (then else)
"Evaluate THEN form if Emacs is running in GNU/Linux, otherwise evaluate ELSE form."
"Evaluate THEN form if Emacs is running in Linux, otherwise evaluate ELSE."
`(if (eq system-type 'gnu/linux) ,then ,else))

(defmacro smudge-when-gnu-linux (then)
Expand All @@ -31,10 +32,10 @@

(defcustom smudge-transport 'connect
"How the commands should be sent to Spotify process.
Defaults to 'connect, as it provides a consistent UX across all OSes."
Defaults to \\='connect, as it provides a consistent UX across all OSes."
:type '(choice (symbol :tag "AppleScript" apple)
(symbol :tag "D-Bus" dbus)
(symbol :tag "Connect" connect))
(symbol :tag "D-Bus" dbus)
(symbol :tag "Connect" connect))
:group 'smudge)

(defcustom smudge-player-status-refresh-interval 5
Expand Down Expand Up @@ -93,7 +94,7 @@ The following placeholders are supported:
* %t - Track name (truncated)
* %n - Track #
* %l - Track duration, in minutes (i.e. 01:35)
* %p - Player status indicator for 'playing', 'paused', and 'stopped' states
* %p - Player status indicator for playing, paused, and stopped states
* %s - Player shuffling status indicator
* %r - Player repeating status indicator"
:type 'string
Expand All @@ -116,7 +117,7 @@ Apply SUFFIX to smudge-controller-prefixed functions, applying ARGS."
(run-at-time 1 nil #'smudge-controller-player-status))))

(defun smudge-controller-update-metadata (metadata)
"Compose the playing status string to be displayed in the mode-line from METADATA."
"Build the playing status to be displayed in the mode-line from METADATA."
(let* ((player-status smudge-player-status-format)
(duration-format "%m:%02s")
(json-object-type 'hash-table)
Expand Down Expand Up @@ -168,7 +169,7 @@ This corresponds to the current REPEATING state."
(and (boundp 'smudge-controller-timer) (timerp smudge-controller-timer)))

(defun smudge-controller-start-player-status-timer ()
"Start the timer that will update the mode line according to the Spotify player status."
"Start the timer that will update the mode line with Spotify player status."
(when (and (not (smudge-controller-timerp)) (> smudge-player-status-refresh-interval 0))
(setq smudge-controller-timer
(run-at-time t smudge-player-status-refresh-interval #'smudge-controller-player-status))))
Expand Down
11 changes: 6 additions & 5 deletions smudge-dbus.el
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@

;;; Commentary:

;; This library handles controlling Spotify via the D-Bus interface. It implements a set of
;; multimethod-like functions that are dispatched in smudge-controller.el.
;; This library handles controlling Spotify via the D-Bus interface. It
;; implements a set of multimethod-like functions that are dispatched in
;; smudge-controller.el.

;; Somehow shuffling, setting volume and loop status do not work as expected. Querying the
;; attribute does not return the expected value and setting it has no effect. The dbus interface of
;; Spotify seems to be broken.
;; Somehow shuffling, setting volume and loop status do not work as expected.
;; Querying the attribute does not return the expected value and setting it
;; has no effect. The dbus interface of Spotify seems to be broken.

;;; Code:

Expand Down
4 changes: 2 additions & 2 deletions smudge-device-select.el
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@

;;; Commentary:

;; This library implements methods, UI, and a minor mode to use the "connect" RESTful APIs to manage
;; and query Spotify clients on the network.
;; This library implements methods, UI, and a minor mode to use the "connect"
;; RESTful APIs to manage and query Spotify clients on the network.

;;; Code:

Expand Down
3 changes: 2 additions & 1 deletion smudge-playlist.el
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@

;;; Commentary:

;; This library implements UI and a major mode for searching and acting on Spotify playlists.
;; This library implements UI and a major mode for searching and acting on
;; Spotify playlists.

;;; Code:

Expand Down
13 changes: 7 additions & 6 deletions smudge-remote.el
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@

;;; Commentary:

;; This library implements a minor mode that allows for interacting with Spotify and displaying
;; transport status. This also includes a global minor mode definition.
;; This library implements a minor mode that allows for interacting with
;; Spotify and displaying transport status. This also includes a global
;; minor mode definition.

;;; Code:

Expand All @@ -20,10 +21,10 @@
:type 'string)

(defcustom smudge-status-location 'modeline
"Specify where to show the player status: one of '(modeline title-bar nil)."
"Specify where to show the player status: one of \\='(modeline title-bar nil)."
:type '(choice (const :tag "Modeline" modeline)
(const :tag "Title Bar" title-bar)
(const :tag "Do not show" nil))
(const :tag "Title Bar" title-bar)
(const :tag "Do not show" nil))
:group 'smudge)

(defcustom smudge-title-bar-separator " "
Expand Down Expand Up @@ -106,7 +107,7 @@ See commands \\[smudge-toggle-repeating] and
(defvar smudge-remote-player-status-map
(let ((map (make-sparse-keymap)))
(define-key map (kbd "<mode-line> <mouse-1>")
'smudge-remote-popup-menu)
'smudge-remote-popup-menu)
map)
"Keymap for Smudge mode-line status.")

Expand Down
15 changes: 14 additions & 1 deletion smudge-track.el
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@

;;; Commentary:

;; This library implements UI and a major mode for searching and acting on Spotify playlists.
;; This library implements UI and a major mode for searching and acting on
;; Spotify playlists.

;;; Code:

Expand All @@ -28,6 +29,7 @@
(define-key map (kbd "g") #'smudge-track-reload)
(define-key map (kbd "f") #'smudge-track-playlist-follow)
(define-key map (kbd "u") #'smudge-track-playlist-unfollow)
(define-key map (kbd "k") #'smudge-track-add-to-queue)
map)
"Local keymap for `smudge-track-search-mode' buffers.")

Expand Down Expand Up @@ -298,5 +300,16 @@ Default to sortin tracks by number when listing the tracks from an album."
(message "Song removed."))))
(message "Cannot remove a track from a playlist from here")))

(defun smudge-track-add-to-queue ()
"Add the track under the cursor to the queue."
(interactive)
(let ((selected-track (tabulated-list-get-id)))
(let ((track-id (smudge-api-get-item-uri selected-track)))
(smudge-api-queue-add-track
track-id
(lambda(_)
(message "Added \"%s\" to your queue." (smudge-api-get-item-name selected-track)))))))


(provide 'smudge-track)
;;; smudge-track.el ends here
16 changes: 9 additions & 7 deletions smudge.el
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

;; Keywords: multimedia, music, spotify, smudge
;; Package: smudge
;; Package-Requires: ((emacs "27.1") (simple-httpd "1.5") (request "0.3") (oauth2 "0.16"))
;; Package-Requires: ((emacs "27.1") (simple-httpd "20230821.1458") (request "0.3") (oauth2 "0.16"))
;; Version: 1.0.0
;; Homepage: https://github.com/danielfm/smudge

Expand All @@ -15,12 +15,13 @@
;; This mode requires at least GNU Emacs 24.4

;; Before using this mode, first go the Spotify Web API console
;; <https://developer.spotify.com/my-applications> and create a new application, adding
;; <http://localhost:8080/smudge-callback> as the redirect URI (or whichever port you have
;; specified via customize).
;; <https://developer.spotify.com/my-applications> and create a new application,
;; adding <http://localhost:8080/smudge-callback> as the redirect URI (or
;; whichever port you have specified via customize).

;; After requiring `smudge', make sure to define the client id and client secrets, along with some
;; other important settings. See README.md for the complete list of settings and usage information.
;; After requiring `smudge', make sure to define the client id and client
;; secrets, along with some other important settings. See README.md for the
;; complete list of settings and usage information.

;;; Code:

Expand Down Expand Up @@ -152,7 +153,8 @@ Prompt for the NAME and whether it should be made PUBLIC."
(define-key map (kbd "t s") #'smudge-track-search)
(define-key map (kbd "d") #'smudge-select-device)
map)
"Keymap for Spotify commands after 'smudge-keymap-prefix'.")
"Keymap for Spotify commands after \\='smudge-keymap-prefix\\='.")

(fset 'smudge-command-map smudge-command-map)

(easy-menu-add-item nil '("Tools")
Expand Down

0 comments on commit 0e69fce

Please sign in to comment.