mirror of
https://github.com/SqrtMinusOne/lyrics-fetcher.el.git
synced 2025-12-10 17:03:03 +03:00
feat: ability to edit the search query before sending
This commit is contained in:
parent
2d68bd4806
commit
cbbf6244af
3 changed files with 64 additions and 28 deletions
|
|
@ -40,6 +40,8 @@ Available commands:
|
|||
If called with =C-u=, then tries to fetch the text regardless of the latter.
|
||||
|
||||
If called with =C-u C-u=, prompts the user to select a matching song. That is helpful when there are multiple songs with similar names, and the top one isn't the right one.
|
||||
|
||||
If called with =C-u C-u C-u=, edit the search query in minibuffer before sending. This is helpful when there is extra information in the song title which prevents the API from finding the song.
|
||||
- ~M-x lyrics-fetcher-show-lyrics-query~ - fetch lyrics by a text query.
|
||||
|
||||
Modified by =C-u= the same way as ~lyrics-fetcher-show-lyrics~.
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ searching \"Song (feat. Artist)\""
|
|||
:type 'boolean
|
||||
:group 'lyrics-fetcher)
|
||||
|
||||
(defun lyrics-fetcher-genius-do-search (track callback &optional sync)
|
||||
(defun lyrics-fetcher-genius-do-search (track callback &optional sync edit)
|
||||
"Perform a lyrics search on 'genius.com'.
|
||||
|
||||
Requires `lyrics-fetcher-genius-access-token' to be set.
|
||||
|
|
@ -65,7 +65,11 @@ TRACK should be EMMS-compatible alist or string, take a look at
|
|||
successful, CALLBACK will be called with the result.
|
||||
|
||||
If SYNC is non-nil, perform request synchronously and ask the
|
||||
user to pick the matching search result."
|
||||
user to pick the matching search result.
|
||||
|
||||
When EDIT is non-nil, edit the query in minibuffer before search.
|
||||
Genius usually struggles to find song if there is extra
|
||||
information in the title."
|
||||
(lyrics-fetcher--genius-do-query
|
||||
track
|
||||
(lambda (data)
|
||||
|
|
@ -73,9 +77,10 @@ user to pick the matching search result."
|
|||
(lyrics-fetcher--genius-get-data-from-response data 'url sync)
|
||||
callback
|
||||
sync))
|
||||
sync))
|
||||
sync
|
||||
edit))
|
||||
|
||||
(defun lyrics-fetcher--genius-do-query (track callback &optional sync)
|
||||
(defun lyrics-fetcher--genius-do-query (track callback &optional sync edit)
|
||||
"Perform a song search on genius.com.
|
||||
|
||||
Requires `lyrics-fetcher-genius-access-token' to be set.
|
||||
|
|
@ -86,12 +91,16 @@ successful, CALLBACK will be called with the result.
|
|||
|
||||
SYNC determines whether the request is synchronous. The parameter
|
||||
is useful when it is necessary to ask the user for something right
|
||||
after the request."
|
||||
after the request.
|
||||
|
||||
When EDIT is non-nil, edit the query in minibuffer before search."
|
||||
(when (string-empty-p lyrics-fetcher-genius-access-token)
|
||||
(error "Genius client access token not set!"))
|
||||
(message "Sending a query to genius API...")
|
||||
(request "https://api.genius.com/search"
|
||||
:params `(("q" . ,(lyrics-fetcher--genius-format-query track))
|
||||
:params `(("q" . ,(lyrics-fetcher--genius-maybe-edit-query
|
||||
(lyrics-fetcher--genius-format-query track)
|
||||
edit))
|
||||
("access_token" . ,lyrics-fetcher-genius-access-token))
|
||||
:parser 'json-read
|
||||
:sync sync
|
||||
|
|
@ -102,6 +111,12 @@ after the request."
|
|||
(lambda (&key error-thrown &allow-other-keys)
|
||||
(message "Error!: %S" error-thrown)))))
|
||||
|
||||
(defun lyrics-fetcher--genius-maybe-edit-query (query edit)
|
||||
"If EDIT is non-nil, edit QUERY if minibuffer."
|
||||
(when edit
|
||||
(read-from-minibuffer "Query: " query))
|
||||
query)
|
||||
|
||||
(defun lyrics-fetcher--genius-format-query (track)
|
||||
"Format track to genius.com query.
|
||||
|
||||
|
|
@ -190,7 +205,7 @@ If SYNC is non-nil, the request will be performed synchronously."
|
|||
(lambda (&key error-thrown &allow-other-keys)
|
||||
(message "Error!: %S" error-thrown)))))
|
||||
|
||||
(defun lyrics-fetcher-genius-download-cover (track callback folder &optional sync)
|
||||
(defun lyrics-fetcher-genius-download-cover (track callback folder &optional sync edit)
|
||||
"Downloads album cover of TRACK.
|
||||
|
||||
Requires `lyrics-fetcher-genius-access-token' to be set and
|
||||
|
|
@ -209,7 +224,9 @@ The file will be saved to FOLDER and will be named
|
|||
|
||||
CALLBACK will be called with a path to the resulting file.
|
||||
|
||||
If SYNC is non-nil, the user will be prompted for a matching song."
|
||||
If SYNC is non-nil, the user will be prompted for a matching song.
|
||||
|
||||
When EDIT is non-nil, edit the query in minibuffer before search."
|
||||
(lyrics-fetcher--genius-do-query
|
||||
track
|
||||
(lambda (data)
|
||||
|
|
@ -217,7 +234,8 @@ If SYNC is non-nil, the user will be prompted for a matching song."
|
|||
(lyrics-fetcher--genius-get-data-from-response data 'id sync)
|
||||
callback
|
||||
folder))
|
||||
sync))
|
||||
sync
|
||||
edit))
|
||||
|
||||
(defun lyrics-fetcher--genius-save-album-picture (id callback folder)
|
||||
"Save an album cover of a song of a given ID.
|
||||
|
|
|
|||
|
|
@ -153,7 +153,7 @@ The function has to take into account that:
|
|||
(substring title 0 (min (length title) 190))))))
|
||||
|
||||
;;;###autoload
|
||||
(cl-defun lyrics-fetcher-show-lyrics (&optional track &key suppress-open suppress-switch callback force-fetch sync)
|
||||
(cl-defun lyrics-fetcher-show-lyrics (&optional track &key suppress-open suppress-switch callback force-fetch sync edit)
|
||||
"Show lyrics for TRACK.
|
||||
|
||||
TRACK can be either a string or an EMMS alist. If TRACK is not
|
||||
|
|
@ -184,7 +184,13 @@ always refetch the lyrics text.
|
|||
If called with \\[universal-argument] \\[universal-argument] or SYNC
|
||||
is non-nil, then ask the user to select a matching song. This may be
|
||||
useful if there are multiple tracks with similar names, and the top
|
||||
one isn’t the one required."
|
||||
one isn’t the one required.
|
||||
|
||||
If called with \\[universal-argument] \\[universal-argument]
|
||||
\\[universal-argument] or EDIT is non-nil, edit the search query
|
||||
in minibuffer before sending. This is helpful when there is
|
||||
extra information in the song title which prevents the API from
|
||||
finding the song."
|
||||
(interactive)
|
||||
(unless track
|
||||
(setq track (funcall lyrics-fetcher-current-track-method)))
|
||||
|
|
@ -196,8 +202,9 @@ one isn’t the one required."
|
|||
;; and via recursion in asyncronous callbacks, during with
|
||||
;; `current-prefix-arg' will be unset. So this is necessary
|
||||
;; to pass the behavior down the recursive calls.
|
||||
(force-fetch (or force-fetch (member (prefix-numeric-value current-prefix-arg) '(4 16))))
|
||||
(sync (or sync (member (prefix-numeric-value current-prefix-arg) '(16)))))
|
||||
(force-fetch (or force-fetch (member (prefix-numeric-value current-prefix-arg) '(4 16 64))))
|
||||
(sync (or sync (member (prefix-numeric-value current-prefix-arg) '(16 64))))
|
||||
(edit (or edit (member (prefix-numeric-value current-prefix-arg) '(64)))))
|
||||
(if (and (not force-fetch) (lyrics-fetcher--lyrics-saved-p file-name))
|
||||
(progn
|
||||
(message "Found fetched lyrics for: %s" song-name)
|
||||
|
|
@ -213,7 +220,8 @@ one isn’t the one required."
|
|||
(lyrics-fetcher--open-lyrics file-name track suppress-switch))
|
||||
(when callback
|
||||
(funcall callback file-name)))
|
||||
sync))))
|
||||
sync
|
||||
edit))))
|
||||
|
||||
;;;###autoload
|
||||
(defun lyrics-fetcher-show-lyrics-query (query)
|
||||
|
|
@ -226,18 +234,19 @@ See `lyrics-fetcher-show-lyrics' for behavior."
|
|||
(interactive "sEnter query: ")
|
||||
(lyrics-fetcher-show-lyrics query))
|
||||
|
||||
(cl-defun lyrics-fetcher--fetch-many (tracks &optional &key start force-fetch sync)
|
||||
(cl-defun lyrics-fetcher--fetch-many (tracks &optional &key start force-fetch sync edit)
|
||||
"Fetch lyrics for every track in the TRACKS list.
|
||||
|
||||
This function calls itself recursively. START is an indicator of
|
||||
position in the list.
|
||||
|
||||
FORCE-FETCH and SYNC are passed to `lyrics-fetcher-show-lyrics'."
|
||||
FORCE-FETCH, SYNC and EDIT are passed to `lyrics-fetcher-show-lyrics'."
|
||||
(unless start
|
||||
(setq start 0))
|
||||
(message "Fetching lyrics for %s / %s songs" start (+ start (length tracks)))
|
||||
(let ((force-fetch (or force-fetch (member (prefix-numeric-value current-prefix-arg) '(4 16))))
|
||||
(sync (or sync (member (prefix-numeric-value current-prefix-arg) '(16)))))
|
||||
(let ((force-fetch (or force-fetch (member (prefix-numeric-value current-prefix-arg) '(4 16 64))))
|
||||
(sync (or sync (member (prefix-numeric-value current-prefix-arg) '(16 64))))
|
||||
(edit (or edit (member (prefix-numeric-value current-prefix-arg) '(64)))))
|
||||
(unless (seq-empty-p tracks)
|
||||
(lyrics-fetcher-show-lyrics
|
||||
(car tracks)
|
||||
|
|
@ -248,7 +257,8 @@ FORCE-FETCH and SYNC are passed to `lyrics-fetcher-show-lyrics'."
|
|||
(cdr tracks)
|
||||
:start (+ start 1)
|
||||
:force-fetch force-fetch
|
||||
:sync sync))))))
|
||||
:sync sync
|
||||
:edit edit))))))
|
||||
|
||||
;;; EMMS integration
|
||||
|
||||
|
|
@ -417,20 +427,21 @@ the same way as `lyrics-fetcher-show-lyrics'."
|
|||
(read-only-mode 1))
|
||||
|
||||
;;; Album cover fetching
|
||||
(cl-defun lyrics-fetcher--fetch-cover-many (tracks &optional &key start force-fetch sync)
|
||||
(cl-defun lyrics-fetcher--fetch-cover-many (tracks &optional &key start force-fetch sync edit)
|
||||
"Fetch album covers for every track in the TRACKS list.
|
||||
|
||||
This functions calls itself recursively. START is an indicator of
|
||||
position in the list.
|
||||
|
||||
FORCE-FETCH and SYNC are passed to `lyrics-fetcher--fetch-cover'."
|
||||
FORCE-FETCH, SYNC and EDIT are passed to `lyrics-fetcher--fetch-cover'."
|
||||
(unless start
|
||||
(setq start 0))
|
||||
(message "Fetching covers for %s / %s albums" start (+ start (length tracks)))
|
||||
(if (seq-empty-p tracks)
|
||||
(message "Done. Refresh EMMS browser to see the result.")
|
||||
(let ((force-fetch (or force-fetch (member (prefix-numeric-value current-prefix-arg) '(4 16))))
|
||||
(sync (or sync (member (prefix-numeric-value current-prefix-arg) '(16)))))
|
||||
(let ((force-fetch (or force-fetch (member (prefix-numeric-value current-prefix-arg) '(4 16 64))))
|
||||
(sync (or sync (member (prefix-numeric-value current-prefix-arg) '(16 64))))
|
||||
(edit (or sync (member (prefix-numeric-value current-prefix-arg) '(64)))))
|
||||
(lyrics-fetcher--fetch-cover
|
||||
(car tracks)
|
||||
:callback
|
||||
|
|
@ -439,11 +450,13 @@ FORCE-FETCH and SYNC are passed to `lyrics-fetcher--fetch-cover'."
|
|||
(cdr tracks)
|
||||
:start (+ start 1)
|
||||
:force-fetch force-fetch
|
||||
:sync sync))
|
||||
:sync sync
|
||||
:edit edit))
|
||||
:sync sync
|
||||
:force-fetch force-fetch))))
|
||||
:force-fetch force-fetch
|
||||
:edit edit))))
|
||||
|
||||
(cl-defun lyrics-fetcher--fetch-cover (track &optional &key callback sync force-fetch)
|
||||
(cl-defun lyrics-fetcher--fetch-cover (track &optional &key callback sync force-fetch edit)
|
||||
"Fetch cover for a given TRACK.
|
||||
|
||||
Call CALLBACK with the resulting filename of full cover.
|
||||
|
|
@ -451,7 +464,9 @@ Call CALLBACK with the resulting filename of full cover.
|
|||
If SYNC is non-nil, prompt the user for a matching track.
|
||||
|
||||
If FORCE-FETCH is non-nil, always fetch regardless of whether the
|
||||
file exists."
|
||||
file exists.
|
||||
|
||||
If EDIT is non-nil, edit the query in minibuffer before search."
|
||||
(let ((cover-found (lyrics-fetcher--get-cover-in-directory
|
||||
(f-dirname (cdr (assoc 'name track))))))
|
||||
(if (and (not force-fetch) cover-found)
|
||||
|
|
@ -468,7 +483,8 @@ file exists."
|
|||
(when callback
|
||||
(funcall callback filename)))
|
||||
(concat (f-dirname (cdr (assoc 'name track))) "/")
|
||||
sync))))
|
||||
sync
|
||||
edit))))
|
||||
|
||||
(defun lyrics-fetcher--get-cover-in-directory (dirname)
|
||||
"Get a path to the large cover file in DIRNAME if one exists."
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue