refactor: use error

This commit is contained in:
Pavel Korytov 2021-08-07 13:08:25 +03:00
parent 8c3df2bbe0
commit 8f4586dbf8
2 changed files with 120 additions and 103 deletions

View file

@ -78,20 +78,20 @@ successful, CALLBACK will be called with the result.
SYNC determines whether the request is syncronous. The parameter SYNC determines whether the request is syncronous. The parameter
is useful when it is neccessary to ask user for something right is useful when it is neccessary to ask user for something right
after the request." after the request."
(if (string-empty-p lyrics-fetcher-genius-access-token) (when (string-empty-p lyrics-fetcher-genius-access-token)
(message "Genius client access token not set!") (error "Genius client access token not set!"))
(message "Sending a query to genius API...") (message "Sending a query to genius API...")
(request "https://api.genius.com/search" (request "https://api.genius.com/search"
:params `(("q" . ,(lyrics-fetcher--genius-format-query track)) :params `(("q" . ,(lyrics-fetcher--genius-format-query track))
("access_token" . ,lyrics-fetcher-genius-access-token)) ("access_token" . ,lyrics-fetcher-genius-access-token))
:parser 'json-read :parser 'json-read
:sync sync :sync sync
:success (cl-function :success (cl-function
(lambda (&key data &allow-other-keys) (lambda (&key data &allow-other-keys)
(funcall callback data))) (funcall callback data)))
:error (cl-function :error (cl-function
(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-format-query (track) (defun lyrics-fetcher--genius-format-query (track)
"Format track to genius.com query. "Format track to genius.com query.
@ -119,31 +119,31 @@ contains `info-albumartist' or `info-artist' and `info-title'"
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."
(if (not (= (cdr (assoc 'status (assoc 'meta data))) 200)) (when (not (= (cdr (assoc 'status (assoc 'meta data))) 200))
(message "Error: %" (cdr (assoc 'message (assoc 'meta data)))) (error "Error: %" (cdr (assoc 'message (assoc 'meta data)))))
(let* ((results (cdr (assoc 'hits (assoc 'response data)))) (let* ((results (cdr (assoc 'hits (assoc 'response data))))
(results-songs (seq-filter (results-songs (seq-filter
(lambda (entry) (lambda (entry)
(string-equal (cdr (assoc 'type entry)) "song")) (string-equal (cdr (assoc 'type entry)) "song"))
results))) results)))
(if (seq-empty-p results-songs) (when (seq-empty-p results-songs)
(message "Error: no results!") (error "Error: no results!"))
(cdr (cdr
(if ask (if ask
(let ((results-songs-for-select (let ((results-songs-for-select
(mapcar (mapcar
(lambda (entry) (lambda (entry)
(cons (lyrics-fetcher--genius-format-song-title entry) (cons (lyrics-fetcher--genius-format-song-title entry)
(assoc key (assoc 'result entry)))) (assoc key (assoc 'result entry))))
results-songs))) results-songs)))
(cdr (cdr
(assoc (assoc
(completing-read (completing-read
"Pick a result: " "Pick a result: "
results-songs-for-select results-songs-for-select
nil t) nil t)
results-songs-for-select))) results-songs-for-select)))
(assoc key (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.
@ -225,33 +225,33 @@ DATA should be a response from GET /songs/:id. The file will be saved
to FOLDER and will be name \"cover_full.<extension>\". to FOLDER and will be name \"cover_full.<extension>\".
CALLBACK will be called with the path to the resulting file." CALLBACK will be called with the path to the resulting file."
(if (not (= (cdr (assoc 'status (assoc 'meta data))) 200)) (when (not (= (cdr (assoc 'status (assoc 'meta data))) 200))
(message "Error: %" (cdr (assoc 'message (assoc 'meta data)))) (error "Error: %" (cdr (assoc 'message (assoc 'meta data)))))
(let ((url (cdr (let ((url (cdr
(assoc 'cover_art_url (assoc 'cover_art_url
(assoc 'album (assoc 'album
(assoc 'song (assoc 'song
(assoc 'response data))))))) (assoc 'response data)))))))
(if (not url) (if (not url)
(message "Album cover not found") (message "Album cover not found")
(message "Downloading the cover image...") (message "Downloading the cover image...")
(request url (request url
:encoding 'binary :encoding 'binary
:complete :complete
(cl-function (cl-function
(lambda (&key data &allow-other-keys) (lambda (&key data &allow-other-keys)
(let ((filename (let ((filename
(concat folder "cover_large" (url-file-extension url)))) (concat folder "cover_large" (url-file-extension url))))
(with-temp-file filename (with-temp-file filename
(toggle-enable-multibyte-characters) (toggle-enable-multibyte-characters)
(set-buffer-file-coding-system 'raw-text) (set-buffer-file-coding-system 'raw-text)
(seq-doseq (char data) (seq-doseq (char data)
(insert char))) (insert char)))
(funcall callback filename)))) (funcall callback filename))))
:error :error
(cl-function (cl-function
(lambda (&key error-thrown &allow-other-keys) (lambda (&key error-thrown &allow-other-keys)
(message "Error!: %S" error-thrown)))))))) (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

View file

@ -173,34 +173,34 @@ 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 useful if there are multiple tracks with similar names, and the top
one isnt the one required." one isnt the one required."
(interactive) (interactive)
(when (not track) (unless track
(setq track (funcall lyrics-fetcher-current-track-method))) (setq track (funcall lyrics-fetcher-current-track-method)))
(if (not track) (unless track
(message "Error: no track found!") (error "Error: no track found!"))
(let ((song-name (funcall lyrics-fetcher-format-song-name-method track)) (let ((song-name (funcall lyrics-fetcher-format-song-name-method track))
(file-name (funcall lyrics-fetcher-format-file-name-method track)) (file-name (funcall lyrics-fetcher-format-file-name-method track))
;; The function is indented to be called both interactively ;; The function is indented to be called both interactively
;; and via recursion in asyncronous callbacks, during with ;; and via recursion in asyncronous callbacks, during with
;; `current-prefix-arg' will be unset. So this is necessary ;; `current-prefix-arg' will be unset. So this is necessary
;; to pass the behavior down the recursive calls. ;; to pass the behavior down the recursive calls.
(force-fetch (or force-fetch (member (prefix-numeric-value current-prefix-arg) '(4 16)))) (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))))) (sync (or sync (member (prefix-numeric-value current-prefix-arg) '(16)))))
(if (and (not force-fetch) (lyrics-fetcher--lyrics-saved-p file-name)) (if (and (not force-fetch) (lyrics-fetcher--lyrics-saved-p file-name))
(progn (progn
(message "Found fetched lyrics for: %s" song-name) (message "Found fetched lyrics for: %s" song-name)
(when callback (when callback
(funcall callback file-name)) (funcall callback file-name))
(unless suppress-open (unless suppress-open
(lyrics-fetcher--open-lyrics file-name track))) (lyrics-fetcher--open-lyrics file-name track)))
(funcall (funcall
lyrics-fetcher-fetch-method track lyrics-fetcher-fetch-method track
(lambda (result) (lambda (result)
(lyrics-fetcher--save-lyrics result file-name) (lyrics-fetcher--save-lyrics result file-name)
(unless suppress-open (unless suppress-open
(lyrics-fetcher--open-lyrics file-name track)) (lyrics-fetcher--open-lyrics file-name track))
(when callback (when callback
(funcall callback file-name))) (funcall callback file-name)))
sync))))) sync))))
(defun lyrics-fetcher-show-lyrics-query (query) (defun lyrics-fetcher-show-lyrics-query (query)
"Fetch lyrics from a text QUERY. "Fetch lyrics from a text QUERY.
@ -253,7 +253,7 @@ the same way as `lyrics-fetcher-show-lyrics'."
(interactive) (interactive)
(let ((data (emms-browser-bdata-at-point))) (let ((data (emms-browser-bdata-at-point)))
(if (not data) (if (not data)
(message "Nothing is found at point!") (error "Nothing is found at point!")
(if (eq (cdr (assoc 'type data)) 'info-title) (if (eq (cdr (assoc 'type data)) 'info-title)
(lyrics-fetcher-show-lyrics (cdadr (assoc 'data data))) (lyrics-fetcher-show-lyrics (cdadr (assoc 'data data)))
(lyrics-fetcher--fetch-many (lyrics-fetcher--fetch-many
@ -280,10 +280,23 @@ the same way as `lyrics-fetcher-show-lyrics'."
(interactive) (interactive)
(let ((data (emms-browser-bdata-at-point))) (let ((data (emms-browser-bdata-at-point)))
(if (not data) (if (not data)
(message "Nothing is found at point!") (error "Nothing is found at point!")
(lyrics-fetcher--fetch-cover-many (lyrics-fetcher--fetch-cover-many
(lyrics-fetcher--emms-extract-albums data))))) (lyrics-fetcher--emms-extract-albums data)))))
(defun lyrics-fetcher-emms-browser-open-large-cover-at-point ()
"Open large_cover for the current point in EMMS browser."
(interactive)
(let ((tracks (lyrics-fetcher--emms-extract-albums (emms-browser-bdata-at-point))))
(when (seq-empty-p tracks)
(error "Nothing is found at point!"))
(let ((cover-file (lyrics-fetcher--get-cover-in-directory
(f-dirname (cdr (assoc 'name (car tracks)))))))
(if (not cover-file)
(error "Cover not found")
(start-process "cover-open" nil
"xdg-open" cover-file)))))
(defun lyrics-fetcher--emms-extract-albums (bdata) (defun lyrics-fetcher--emms-extract-albums (bdata)
"Extract a list of sample song alists from each album in BDATA. "Extract a list of sample song alists from each album in BDATA.
@ -387,17 +400,13 @@ If SYNC is non-nil, prompt user for a matching track.
If FORCE-FETCH is non-nil, always fetch regardless of whether the If FORCE-FETCH is non-nil, always fetch regardless of whether the
file exists." file exists."
(let ((covers-found (f-entries (let ((cover-found (lyrics-fetcher--get-cover-in-directory
(f-dirname (cdr (assoc 'name track))) (f-dirname (cdr (assoc 'name track))))))
(lambda (f) (if (and (not force-fetch) cover-found)
(string-match-p
(rx (* nonl) "cover_large" (* nonl)) f)))))
(if (and (not force-fetch)
(not (seq-empty-p covers-found)))
(progn (progn
(message "Cover already downloaded") (message "Cover already downloaded")
(when callback (when callback
(funcall callback (car covers-found)))) (funcall callback cover-found)))
(funcall lyrics-fetcher-download-cover-method (funcall lyrics-fetcher-download-cover-method
track track
(lambda (filename) (lambda (filename)
@ -409,6 +418,14 @@ file exists."
(concat (f-dirname (cdr (assoc 'name track))) "/") (concat (f-dirname (cdr (assoc 'name track))) "/")
sync)))) sync))))
(defun lyrics-fetcher--get-cover-in-directory (dirname)
"Get a path to the large cover file in DIRNAME if one exists."
(car (f-entries
dirname
(lambda (f)
(string-match-p
(rx (* nonl) "cover_large" (* nonl)) f)))))
(defun lyrics-fetcher--generate-cover-sizes (filename) (defun lyrics-fetcher--generate-cover-sizes (filename)
"Create small and medium versions of FILENAME. "Create small and medium versions of FILENAME.