fordon_greeman / voidfiles

Branch: 2079ec5
Switch branches/tags
main
theidioticdev add emacs 2079ec5 1d ago
271 lines · 8.7 KB Raw Blame History
1 ;;; emms-score.el --- Scoring system for mp3player -*- lexical-binding: t; -*-
2
3 ;; Copyright (C) 2003-2021 Free Software Foundation, Inc.
4
5 ;; Authors: Jean-Philippe Theberge <jphiltheberge@videotron.ca>,
6 ;; Yoni Rabkin <yrk@gnu.org>
7 ;;
8 ;; Keywords: emms, mp3, mpeg, multimedia
9
10 ;; This file is part of EMMS.
11
12 ;; EMMS is free software; you can redistribute it and/or modify
13 ;; it under the terms of the GNU General Public License as published by
14 ;; the Free Software Foundation; either version 3, or (at your option)
15 ;; any later version.
16 ;;
17 ;; EMMS is distributed in the hope that it will be useful,
18 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
19 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 ;; GNU General Public License for more details.
21 ;;
22 ;; You should have received a copy of the GNU General Public License
23 ;; along with EMMS; see the file COPYING. If not, write to the
24 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
25 ;; Boston, MA 02110-1301, USA.
26
27 ;;; Commentary:
28
29 ;; NOTE: This is experimental stuff - comments welcome! There
30 ;; shouldn't worky anything in that file... scores aren't saved, they
31 ;; even don't have any consequence on playing order and there's just
32 ;; one mood in the moment. But it's a beginning and you can score down
33 ;; or up tracks... :)
34 ;;
35 ;; * How to use scoring in emms
36 ;;
37 ;; When you load emms, you are set to a default mood
38 ;; 'emms-default-mood' A mood is a one word string describing how
39 ;; you feel (like "funny", "tired", "aggresive"...) Each mood have is
40 ;; own set of scoring rules.
41 ;;
42 ;; You can change your mood with M-x emms-score-change-mood.
43 ;;
44 ;; Every music file start with a default score of 0 the command
45 ;; emms-score-up-playing and emms-score-down-playing modify the
46 ;; score of the file you are curently listening by 1 In addition,
47 ;; skipping a file (with emms-skip) automaticaly score the file
48 ;; down.
49 ;;
50 ;; With scoring on (this mean the variable emms-use-scoring is t),
51 ;; emms will compare the score of the file with your tolerance to
52 ;; decide if it is played or not.
53 ;;
54 ;; The default tolerance level is 0 (or the variable
55 ;; emms-score-min-score). This mean files with a score of 0 or more will
56 ;; be played and files with a score of -1 or less will be skipped.
57 ;;
58 ;; You can change the tolerance (by 1) with M-x
59 ;; emms-score-lower-tolerance and M-x
60 ;; emms-score-be-more-tolerant
61
62 ;;; Code:
63
64 (require 'emms)
65
66 (defvar emms-scores-list nil)
67 (defvar emms-score-current-mood 'default)
68 (defvar emms-score-min-score 0)
69 (defvar emms-score-default-score 0)
70 (defvar emms-score-hash (make-hash-table :test 'equal))
71 (defvar emms-score-enabled-p nil
72 "If non-nil, emms score is active.")
73
74 (defcustom emms-score-file (concat (file-name-as-directory emms-directory) "scores")
75 "*Directory to store the score file."
76 :type 'directory
77 :group 'emms)
78
79
80 ;;; User Interfaces
81
82 (defun emms-score (arg)
83 "Turn on emms-score if prefix argument ARG is a positive integer,
84 off otherwise."
85 (interactive "p")
86 (if (and arg (> arg 0))
87 (progn
88 (setq emms-score-enabled-p t)
89 (emms-score-load-hash)
90 (setq emms-ok-track-function #'emms-score-ok-track-function)
91 (unless noninteractive
92 (add-hook 'kill-emacs-hook #'emms-score-save-hash)))
93 (setq emms-score-enabled-p nil)
94 (emms-score-save-hash)
95 (setq emms-ok-track-function #'emms-default-ok-track-function)
96 (remove-hook 'kill-emacs-hook #'emms-score-save-hash)))
97
98 ;;;###autoload
99 (defun emms-score-enable ()
100 "Turn on emms-score."
101 (interactive)
102 (emms-score 1)
103 (message "emms score enabled"))
104
105 ;;;###autoload
106 (defun emms-score-disable ()
107 "Turn off emms-score."
108 (interactive)
109 (emms-score -1)
110 (message "emms score disabled"))
111
112 ;;;###autoload
113 (defun emms-score-toggle ()
114 "Toggle emms-score."
115 (interactive)
116 (if emms-score-enabled-p
117 (emms-score-disable)
118 (emms-score-enable)))
119
120 (defun emms-score-change-mood (mood)
121 "Change the current MOOD.
122 The score hash is automatically saved."
123 (interactive "sMood: ")
124 (emms-score-save-hash)
125 (setq emms-score-current-mood (intern (downcase mood))))
126
127 (defun emms-score-up-playing ()
128 (interactive)
129 (if emms-player-playing-p
130 (emms-score-change-score 1 (emms-score-current-selected-track-filename))
131 (error "No track currently playing")))
132
133 (defun emms-score-down-playing ()
134 (interactive)
135 (if emms-player-playing-p
136 (emms-score-change-score -1 (emms-score-current-selected-track-filename))
137 (error "No track currently playing")))
138
139 (defun emms-score-up-file-on-line ()
140 (interactive)
141 (emms-score-change-score 1 (emms-score-track-at-filename)))
142
143 (defun emms-score-down-file-on-line ()
144 (interactive)
145 (emms-score-change-score -1 (emms-score-track-at-filename)))
146
147 (defun emms-score-less-tolerant ()
148 "Only play mp3 with a higher score"
149 (interactive)
150 (setq emms-score-min-score (+ emms-score-min-score 1))
151 (message "Will play songs with a score >= %d" emms-score-min-score))
152
153 (defun emms-score-more-tolerant ()
154 "Allow playing of mp3 with a lower score."
155 (interactive)
156 (setq emms-score-min-score (- emms-score-min-score 1))
157 (message "Will play songs with a score >= %d" emms-score-min-score))
158
159 (defun emms-score-set-playing (score)
160 "Set score for current playing track."
161 (interactive "nSet score for playing track: ")
162 (let ((filename (emms-score-current-selected-track-filename)))
163 (if emms-player-playing-p
164 (emms-score-change-score
165 (- score (emms-score-get-score filename))
166 filename)
167 (error "No track currently playing"))))
168
169 (defun emms-score-set-file-on-line (score)
170 "Set score for track at point in emms-playlist buffer."
171 (interactive "nSet score for track at point: ")
172 (let ((filename (emms-score-track-at-filename)))
173 (if emms-player-playing-p
174 (emms-score-change-score
175 (- score (emms-score-get-score filename))
176 filename))))
177
178 (defun emms-score-set-tolerance (tolerance)
179 "Allow playing tracks with a score >= tolerance."
180 (interactive "nSet tolerance: ")
181 (setq emms-score-min-score tolerance)
182 (message "Will play songs with a score >= %d" emms-score-min-score))
183
184 (defun emms-score-show-playing ()
185 "Show score for current playing track in minibuf."
186 (interactive)
187 (message "track/tolerance score: %d/%d"
188 (emms-score-get-score
189 (emms-score-current-selected-track-filename))
190 emms-score-min-score))
191
192 (defun emms-score-show-file-on-line ()
193 "Show score for track at point in emms-playlist buffer."
194 (interactive)
195 (message "track/tolerance score: %d/%d"
196 (emms-score-get-score
197 (emms-score-track-at-filename))
198 emms-score-min-score))
199
200
201 ;;; Internal Functions
202
203 (defun emms-score-current-selected-track-filename ()
204 "Return filename of current selected track."
205 (emms-track-get (emms-playlist-current-selected-track) 'name))
206
207 (defun emms-score-track-at-filename ()
208 "Return file of track at point in emms-playlist buffer."
209 (emms-track-get (emms-playlist-track-at) 'name))
210
211 (defun emms-score-ok-track-function (track)
212 "Decide if to skip or play TRACK."
213 (emms-score-check-score (emms-track-get track 'name)))
214
215 (defun emms-score-save-hash ()
216 "Save score hash in `emms-score-file'."
217 (interactive)
218 (unless (file-directory-p (file-name-directory emms-score-file))
219 (make-directory (file-name-directory emms-score-file)))
220 (with-temp-file emms-score-file
221 (let ((standard-output (current-buffer)))
222 (insert "(")
223 (maphash (lambda (key value)
224 (prin1 (cons key value)))
225 emms-score-hash)
226 (insert ")"))))
227
228 (defun emms-score-load-hash ()
229 "Load score hash from `emms-score-file'."
230 (interactive)
231 (if (file-exists-p emms-score-file)
232 (let ((score-string (with-temp-buffer
233 (emms-insert-file-contents emms-score-file)
234 (buffer-string))))
235 (if (> (length score-string) 0)
236 (mapc (lambda (elt)
237 (puthash (car elt) (cdr elt) emms-score-hash))
238 (read score-string)))
239 ;; when file not exists, make empty but valid score file
240 (emms-score-save-hash))))
241
242 (defun emms-score-get-plist (filename)
243 (gethash filename emms-score-hash))
244
245 (defun emms-score-change-score (score filename)
246 (let ((sp (emms-score-get-plist filename) )
247 (sc (emms-score-get-score filename)))
248 (puthash filename
249 (plist-put sp emms-score-current-mood (+ sc score))
250 emms-score-hash)
251 (message "New score is %s" (+ score sc))))
252
253 (defun emms-score-create-entry (filename)
254 (puthash filename
255 `(,emms-score-current-mood ,emms-score-default-score)
256 emms-score-hash))
257
258 (defun emms-score-get-score (filename)
259 "Return score of TRACK."
260 (let ((plist (emms-score-get-plist filename)))
261 (if (member emms-score-current-mood plist)
262 (plist-get plist emms-score-current-mood)
263 (emms-score-create-entry filename)
264 (emms-score-get-score filename))))
265
266 (defun emms-score-check-score (filename)
267 (>= (emms-score-get-score filename) emms-score-min-score))
268
269 (provide 'emms-score)
270
271 ;;; emms-scores.el ends here