fordon_greeman / voidfiles

Branch: main
Switch branches/tags
main
theidioticdev add emacs 2079ec5 1d ago
193 lines · 6.4 KB Raw Blame History
1 ;;; emms-cache.el --- persistence for emms-track -*- lexical-binding: t; -*-
2
3 ;; Copyright (C) 2006, 2007, 2008, 2009, 2022 Free Software Foundation, Inc.
4
5 ;; Author: Damien Elmes <emacs@repose.cx>, Yoni Rabkin <yrk@gnu.org>
6 ;; Keywords: emms, mp3, mpeg, multimedia
7
8 ;; This file is part of EMMS.
9
10 ;; EMMS is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
13 ;; any later version.
14
15 ;; EMMS is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
19
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with EMMS; see the file COPYING. If not, write to the
22 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
23 ;; Boston, MA 02110-1301, USA.
24
25 ;;; Commentary:
26
27 ;; The cache is a mapping of a full path name to information, and so
28 ;; it is invalidated when you rename or move files about. It also
29 ;; does not differentiate between file or uri tracks.
30
31 ;; Because cache lookups are much faster than disk access, this works
32 ;; much better with a emms-later-do-interval of something like 0.001. Also
33 ;; consider using synchronous mode, as it's quite fast now.
34
35 ;; This code is activated by (emms-standard) and above.
36
37 ;; To activate it by hand, use:
38
39 ;; (emms-cache 1)
40
41 ;;; Code:
42
43 (require 'emms)
44 (require 'emms-info)
45
46 (when (fboundp 'define-hash-table-test)
47 (define-hash-table-test 'string-hash 'string= 'sxhash))
48
49 (defvar emms-cache-db (make-hash-table
50 :test (if (fboundp 'define-hash-table-test)
51 'string-hash
52 'equal))
53 "A mapping of paths to file info.
54 This is used to cache over emacs sessions.")
55
56 (defvar emms-cache-dirty nil
57 "True if the cache has been updated since init.")
58
59 (defcustom emms-cache-file (concat (file-name-as-directory emms-directory) "cache")
60 "A file used to store cached file information over sessions."
61 :group 'emms
62 :type 'file)
63
64 (defcustom emms-cache-file-coding-system 'utf-8
65 "Coding system used for saving `emms-cache-file'."
66 :group 'emms
67 :type 'coding-system)
68
69 (defun emms-cache (arg)
70 "Turn on Emms caching if ARG is positive, off otherwise."
71 (interactive "p")
72 (if (and arg (> arg 0))
73 (progn
74 (unless emms-cache-dirty
75 (emms-cache-restore))
76 (unless noninteractive
77 (add-hook 'kill-emacs-hook 'emms-cache-save))
78 (setq emms-cache-get-function 'emms-cache-get)
79 (setq emms-cache-set-function 'emms-cache-set)
80 (setq emms-cache-modified-function 'emms-cache-dirty))
81 (remove-hook 'kill-emacs-hook 'emms-cache-save)
82 (setq emms-cache-get-function nil)
83 (setq emms-cache-set-function nil)
84 (setq emms-cache-modified-function nil)))
85
86 ;;;###autoload
87 (defun emms-cache-enable ()
88 "Enable caching of Emms track data."
89 (interactive)
90 (emms-cache 1)
91 (message "Emms cache enabled"))
92
93 ;;;###autoload
94 (defun emms-cache-disable ()
95 "Disable caching of Emms track data."
96 (interactive)
97 (emms-cache -1)
98 (message "Emms cache disabled"))
99
100 ;;;###autoload
101 (defun emms-cache-toggle ()
102 "Toggle caching of Emms track data."
103 (interactive)
104 (if emms-cache-get-function
105 (emms-cache-disable)
106 (emms-cache-enable)))
107
108 (defsubst emms-cache-dirty (&rest _ignored)
109 "Mark the cache as dirty."
110 (setq emms-cache-dirty t))
111
112 (defun emms-cache-get (type path)
113 "Return a cache element for PATH, or nil."
114 (ignore type) ;; implicitly ignored before 2021-03-02
115 (gethash path emms-cache-db))
116
117 (defun emms-cache-set (type path track)
118 "Set PATH to TRACK in the cache."
119 (ignore type) ;; implicitly ignored before 2021-03-02
120 (puthash path track emms-cache-db)
121 (emms-cache-dirty))
122
123 (defun emms-cache-del (path)
124 "Remove a track from the cache, with key PATH."
125 (remhash path emms-cache-db)
126 (emms-cache-dirty))
127
128 (defun emms-cache-save ()
129 "Save the track cache to a file."
130 (interactive)
131 (when emms-cache-dirty
132 (message "Saving emms track cache...")
133 (with-temp-buffer
134 (insert
135 (concat ";;; .emms-cache -*- mode: emacs-lisp; coding: "
136 (symbol-name emms-cache-file-coding-system)
137 "; lexical-binding: t; -*-\n"))
138 (maphash (lambda (k v)
139 (insert (format
140 "(puthash %S '%S emms-cache-db)\n" k v)))
141 emms-cache-db)
142 (when (fboundp 'set-buffer-file-coding-system)
143 (set-buffer-file-coding-system emms-cache-file-coding-system))
144 (unless (file-directory-p (file-name-directory emms-cache-file))
145 (make-directory (file-name-directory emms-cache-file)))
146 (write-region (point-min) (point-max) emms-cache-file)
147 (message "Saving emms track cache...done"))
148 (setq emms-cache-dirty nil)))
149
150 (defun emms-cache-restore ()
151 "Restore the track cache from a file."
152 (interactive)
153 (load emms-cache-file t nil t)
154 (setq emms-cache-dirty nil))
155
156 (defun emms-cache-sync (arg)
157 "Sync the cache with the data on disc.
158 Remove non-existent files, and update data for files which have
159 been modified. With prefix argument, update data for all files
160 regardless of whether they have been modified or not."
161 (interactive "P")
162 (let (removed)
163 (maphash (lambda (path track)
164 (when (emms-track-file-p track)
165 ;; if no longer here, remove
166 (if (not (file-exists-p path))
167 (progn
168 (remhash path emms-cache-db)
169 (setq removed t))
170 (let ((file-mtime (emms-info-track-file-mtime track))
171 (info-mtime (emms-track-get track 'info-mtime)))
172 (when (or (not info-mtime)
173 (emms-time-less-p info-mtime file-mtime)
174 arg)
175 (emms-info-initialize-track track arg))))))
176 emms-cache-db)
177 (when removed
178 (setq emms-cache-dirty t))))
179
180 (defun emms-cache-reset ()
181 "Reset the cache."
182 (interactive)
183 (when (yes-or-no-p "Really reset the cache? ")
184 (setq emms-cache-db
185 (make-hash-table
186 :test (if (fboundp 'define-hash-table-test)
187 'string-hash
188 'equal)))
189 (setq emms-cache-dirty t)
190 (emms-cache-save)))
191
192 (provide 'emms-cache)
193 ;;; emms-cache.el ends here