summaryrefslogtreecommitdiffhomepage
path: root/lib/media/jao-lyrics.el
blob: 985c9d91f2b3298c165116993c12b827e50fd562 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
;; jao-lyrics.el -- simple show lyrics using glyrc

;; Copyright (C) 2009, 2010, 2017, 2019, 2020, 2022 Jose Antonio Ortega Ruiz

;; Author: Jose Antonio Ortega Ruiz <jao@gnu.org>
;; Start date: Sat Jul 04, 2009 13:41

;; This file 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 file 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 <http://www.gnu.org/licenses/>.

;;; Code:

(defgroup jao-lyrics-faces nil "Faces"
  :group 'faces)

(defface jao-lyrics-font-lock-album '((t (:foreground "lightgoldenrod2")))
  "Album name in lyrics."
  :group 'jao-lyrics-faces)

(defface jao-lyrics-font-lock-title '((t (:foreground "dodgerblue2")))
  "Track title in lyrics."
  :group 'jao-lyrics-faces)

(defface jao-lyrics-font-lock-artist '((t (:foreground "dodgerblue3")))
  "Artist name in lyrics."
  :group 'jao-lyrics-faces)

(defvar jao-lyrics-cache-dir "~/.lyrics")

(defun jao-lyrics--filename (artist title)
  (expand-file-name (format "%s - %s.txt" artist title)
                    jao-lyrics-cache-dir))

(defun jao-lyrics--get-cached (artist title)
  (let ((candidate (jao-lyrics--filename artist title)))
    (and (file-exists-p candidate)
         (with-current-buffer (find-file-noselect candidate)
           (prog1
               (buffer-string)
             (kill-buffer))))))

(defun jao-lyrics--cache (artist title lyrics)
  (with-current-buffer
      (find-file-noselect (jao-lyrics--filename artist title))
    (delete-region (point-min) (point-max))
    (insert lyrics)
    (save-buffer)
    (kill-buffer)))

(make-variable-buffer-local
 (defvar jao-lyrics--path nil))

(defvar jao-lyrics-mode-map)
(setq jao-lyrics-mode-map
      (let ((map (make-keymap)))
        (suppress-keymap map)
        (define-key map [?q] 'bury-buffer)
        (define-key map [?g] 'jao-show-lyrics)
        (define-key map [?G] (lambda () (interactive) (jao-show-lyrics t)))
        (define-key map [?e] 'jao-edit-lyrics)
        map))

(defun jao-lyrics-mode ()
  (interactive)
  (kill-all-local-variables)
  (use-local-map jao-lyrics-mode-map)
  (setq major-mode 'jao-lyrics-mode)
  (setq mode-name "lyrics")
  (read-only-mode))

(defun jao-lyrics-buffer ()
  (or (get-buffer "*Lyrics*")
      (with-current-buffer (get-buffer-create "*Lyrics*")
        (jao-lyrics-mode)
        (current-buffer))))

(defun jao-edit-lyrics ()
  (interactive)
  (unless jao-lyrics--path
    (error "No track data available."))
  (find-file-other-window jao-lyrics--path))



(defun jao-lyrics--clean-download (fn)
  (with-current-buffer (find-file-noselect fn)
    (goto-char (point-min))
    (when (re-search-forward
           "^\\(CreditsWritten by:\\|External linksNominate\\)" nil t)
      (beginning-of-line)
      (kill-region (point) (point-max)))
    (replace-string "
" "" nil (point-min) (point-max))
    (replace-string "\\'" "'"  nil (point-min) (point-max))
    (save-buffer)))

(defun jao-lyrics--download (artist title &optional noartist)
  (message "Retrieving lyrics...")
  (or (executable-find "glyrc")
      (error "glyrc not installed"))
  (let ((fn (jao-lyrics--filename (or noartist artist) title)))
    (shell-command-to-string (format "glyrc lyrics -n 1-8 -Y -a %s -t %s -w %s"
                                     (shell-quote-argument artist)
                                     (shell-quote-argument title)
                                     (shell-quote-argument fn)))
    (jao-lyrics--clean-download fn)
    (prog1 (jao-lyrics--get-cached artist title) (message nil))))

(defvar jao-lyrics-info-function)
(defvar-local jao-lyrics--info-function nil)

;;;###autoload
(defun jao-show-lyrics (&optional force info-function)
  (interactive "P")
  (let* ((fun (or info-function
                  jao-lyrics--info-function
                  jao-lyrics-info-function))
         (a/t (when fun (funcall fun)))
         (_ (unless a/t (user-error "No info returned by %s" fun)))
         (artist (car a/t))
         (title (cdr a/t))
         (artist (if force (read-string "Artist: " artist) artist))
         (title (if force (read-string "Title: " title) title))
         (buffer (jao-lyrics-buffer))
         (cached (and (not force) (jao-lyrics--get-cached artist title)))
         (cached (and (not (zerop (length cached))) cached))
         (lyrics (or cached
                     (jao-lyrics--download artist title)
                     (jao-lyrics--download "" title artist)))
         (inhibit-read-only t))
    (with-current-buffer buffer
      (when info-function
        (setq-local jao-lyrics--info-function info-function))
      (delete-region (point-min) (point-max))
      (insert (format "♪ %s - %s\n\n"
                      (propertize artist 'face 'jao-lyrics-font-lock-artist)
                      (propertize title 'face 'jao-lyrics-font-lock-title)))
      (when lyrics (insert lyrics))
      (goto-char (point-min))
      (setq jao-lyrics--path (jao-lyrics--filename artist title)))
    (pop-to-buffer buffer)))


(provide 'jao-lyrics)
;;; jao-lyrics.el ends here