mirror of
https://github.com/SqrtMinusOne/lyrics-fetcher.el.git
synced 2025-12-10 17:03:03 +03:00
feat: download album cover from genius
This commit is contained in:
parent
0e34077165
commit
6fba8ac821
2 changed files with 100 additions and 6 deletions
|
|
@ -29,6 +29,7 @@
|
||||||
|
|
||||||
;;; Code:
|
;;; Code:
|
||||||
(require 'request)
|
(require 'request)
|
||||||
|
(require 'cl-lib)
|
||||||
(require 'json)
|
(require 'json)
|
||||||
(require 'seq)
|
(require 'seq)
|
||||||
(require 'shr)
|
(require 'shr)
|
||||||
|
|
@ -61,7 +62,7 @@ user to pick the matching search result."
|
||||||
:success (cl-function
|
:success (cl-function
|
||||||
(lambda (&key data &allow-other-keys)
|
(lambda (&key data &allow-other-keys)
|
||||||
(lyrics-fetcher--genius-fetch-lyrics
|
(lyrics-fetcher--genius-fetch-lyrics
|
||||||
(lyrics-fetcher--genius-get-url-from-response data sync)
|
(lyrics-fetcher--genius-get-data-from-response data 'key sync)
|
||||||
callback
|
callback
|
||||||
sync)))
|
sync)))
|
||||||
:error (cl-function
|
:error (cl-function
|
||||||
|
|
@ -89,8 +90,8 @@ contains `info-albumartist' or `info-artist' and `info-title'"
|
||||||
(cdr (assoc 'full_title result))
|
(cdr (assoc 'full_title result))
|
||||||
(cdr (assoc 'lyrics_state result)))))
|
(cdr (assoc 'lyrics_state result)))))
|
||||||
|
|
||||||
(defun lyrics-fetcher--genius-get-url-from-response (data &optional ask)
|
(defun lyrics-fetcher--genius-get-data-from-response (data key &optional ask)
|
||||||
"Retrive a song URL from the Genius response DATA.
|
"Retrive a song KEY from the Genius response DATA.
|
||||||
|
|
||||||
If ASK is non-nil, prompt user for a choice, otherwise select the
|
If ASK is non-nil, prompt user for a choice, otherwise select the
|
||||||
first song."
|
first song."
|
||||||
|
|
@ -109,7 +110,7 @@ first song."
|
||||||
(mapcar
|
(mapcar
|
||||||
(lambda (entry)
|
(lambda (entry)
|
||||||
(cons (lyrics-fetcher--genius-format-song-title entry)
|
(cons (lyrics-fetcher--genius-format-song-title entry)
|
||||||
(assoc 'url (assoc 'result entry))))
|
(assoc key (assoc 'result entry))))
|
||||||
results-songs)))
|
results-songs)))
|
||||||
(cdr
|
(cdr
|
||||||
(assoc
|
(assoc
|
||||||
|
|
@ -118,7 +119,7 @@ first song."
|
||||||
results-songs-for-select
|
results-songs-for-select
|
||||||
nil t)
|
nil t)
|
||||||
results-songs-for-select)))
|
results-songs-for-select)))
|
||||||
(assoc 'url (assoc 'result (car results-songs)))))))))
|
(assoc key (assoc 'result (car results-songs)))))))))
|
||||||
|
|
||||||
(defun lyrics-fetcher--genius-fetch-lyrics (url callback &optional sync)
|
(defun lyrics-fetcher--genius-fetch-lyrics (url callback &optional sync)
|
||||||
"Fetch lyrics from genius.com page at URL and call CALLBACK with result.
|
"Fetch lyrics from genius.com page at URL and call CALLBACK with result.
|
||||||
|
|
@ -148,5 +149,89 @@ expensive."
|
||||||
(lambda (&key error-thrown &allow-other-keys)
|
(lambda (&key error-thrown &allow-other-keys)
|
||||||
(message "Error!: %S" error-thrown)))))
|
(message "Error!: %S" error-thrown)))))
|
||||||
|
|
||||||
|
(defun lyrics-fetcher-genius-download-cover (track callback folder)
|
||||||
|
"Downloads album cover of TRACK.
|
||||||
|
|
||||||
|
Requies `lyrics-fetcher-genius-access-token' to be set.
|
||||||
|
|
||||||
|
TRACK should be EMMS-compatible alist or string, take a look at
|
||||||
|
`lyrics-fetcher--genius-format-query'. If the search is
|
||||||
|
successful, CALLBACK will be called with the resulting lyrics
|
||||||
|
text.
|
||||||
|
|
||||||
|
The file will be saved to FOLDER and will be named
|
||||||
|
\"cover_full.<extension>\".
|
||||||
|
|
||||||
|
CALLBACK will be called with a path to the resulting file."
|
||||||
|
(if (string-empty-p lyrics-fetcher-genius-access-token)
|
||||||
|
(message "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))
|
||||||
|
("access_token" . ,lyrics-fetcher-genius-access-token))
|
||||||
|
:parser 'json-read
|
||||||
|
:success (cl-function
|
||||||
|
(lambda (&key data &allow-other-keys)
|
||||||
|
(lyrics-fetcher--genius-save-album-picture
|
||||||
|
(lyrics-fetcher--genius-get-data-from-response data 'id)
|
||||||
|
callback
|
||||||
|
folder)))
|
||||||
|
:error (cl-function
|
||||||
|
(lambda (&key error-thrown &allow-other-keys)
|
||||||
|
(message "Error!: %S" error-thrown))))))
|
||||||
|
|
||||||
|
(defun lyrics-fetcher--genius-save-album-picture (id callback folder)
|
||||||
|
"Save an album cover of a song of given ID.
|
||||||
|
|
||||||
|
The file will be saved to FOLDER and will be named
|
||||||
|
\"cover_full.<extension>\".
|
||||||
|
|
||||||
|
CALLBACK will be called with a path to the resulting file."
|
||||||
|
(request
|
||||||
|
(format "https://api.genius.com/songs/%s" id)
|
||||||
|
:parser 'json-read
|
||||||
|
:params `(("access_token" . ,lyrics-fetcher-genius-access-token))
|
||||||
|
:success (cl-function
|
||||||
|
(lambda (&key data &allow-other-keys)
|
||||||
|
(lyrics-fetcher--genius-save-album-url data callback folder)))
|
||||||
|
:error (cl-function
|
||||||
|
(lambda (&key error-thrown &allow-other-keys)
|
||||||
|
(message "Error!: %S" error-thrown)))))
|
||||||
|
|
||||||
|
(defun lyrics-fetcher--genius-save-album-url (data callback folder)
|
||||||
|
"Save album cover of DATA to FOLDER.
|
||||||
|
|
||||||
|
DATA should be a response from GET /songs/:id. The file will be saved
|
||||||
|
to FOLDER and will be name \"cover_full.<extension>\".
|
||||||
|
|
||||||
|
CALLBACK will be called with the path to the resulting file."
|
||||||
|
(if (not (= (cdr (assoc 'status (assoc 'meta data))) 200))
|
||||||
|
(message "Error: %" (cdr (assoc 'message (assoc 'meta data))))
|
||||||
|
(let ((url (cdr
|
||||||
|
(assoc 'cover_art_url
|
||||||
|
(assoc 'album
|
||||||
|
(assoc 'song
|
||||||
|
(assoc 'response my/test-song)))))))
|
||||||
|
(if (not url)
|
||||||
|
(message "Album cover not found")
|
||||||
|
(message "Downloading cover image...")
|
||||||
|
(request url
|
||||||
|
:encoding 'binary
|
||||||
|
:complete
|
||||||
|
(cl-function
|
||||||
|
(lambda (&key data &allow-other-keys)
|
||||||
|
(let ((filename
|
||||||
|
(concat folder "cover_full" (url-file-extension url))))
|
||||||
|
(with-temp-file filename
|
||||||
|
(toggle-enable-multibyte-characters)
|
||||||
|
(set-buffer-file-coding-system 'raw-text)
|
||||||
|
(seq-doseq (char my/picture)
|
||||||
|
(insert char)))
|
||||||
|
(funcall callback filename))))
|
||||||
|
:error
|
||||||
|
(cl-function
|
||||||
|
(lambda (&key error-thrown &allow-other-keys)
|
||||||
|
(message "Error!: %S" error-thrown))))))))
|
||||||
|
|
||||||
(provide 'lyrics-fetcher-genius)
|
(provide 'lyrics-fetcher-genius)
|
||||||
;;; lyrics-fetcher-genius.el ends here
|
;;; lyrics-fetcher-genius.el ends here
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@
|
||||||
'lyrics-fetcher-genius-do-search
|
'lyrics-fetcher-genius-do-search
|
||||||
"A function to perform fetching.
|
"A function to perform fetching.
|
||||||
|
|
||||||
As for now, only genius is available, but this is a point of
|
As of now, only genius is available, but this is a point of
|
||||||
extensibility."
|
extensibility."
|
||||||
:type 'function
|
:type 'function
|
||||||
:options '(lyrics-fetcher-genius-do-search)
|
:options '(lyrics-fetcher-genius-do-search)
|
||||||
|
|
@ -83,6 +83,15 @@ Has to receive either a string or EMMS alist. Take a look at
|
||||||
:type 'function
|
:type 'function
|
||||||
:group 'lyrics-fetcher)
|
:group 'lyrics-fetcher)
|
||||||
|
|
||||||
|
(defcustom lyrics-fetcher-download-cover-method
|
||||||
|
'lyrics-fetcher-genius-download-cover
|
||||||
|
"A function to perform downloading album cover.
|
||||||
|
|
||||||
|
As of now, only genius is available, but this is a point of
|
||||||
|
extensibility."
|
||||||
|
:type 'function
|
||||||
|
:group 'lyrics-fetcher)
|
||||||
|
|
||||||
(defun lyrics-fetcher-format-song-name (track)
|
(defun lyrics-fetcher-format-song-name (track)
|
||||||
"Format TRACK to a human-readable form.
|
"Format TRACK to a human-readable form.
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue