aboutsummaryrefslogtreecommitdiffstats
path: root/lisp/image
diff options
context:
space:
mode:
authorLars Ingebrigtsen2020-08-18 16:45:29 +0200
committerLars Ingebrigtsen2020-08-18 16:45:29 +0200
commit23e6c36645bb8f07f55ba94af21cebaaab2c91d3 (patch)
tree37e8284749a3603fc76fa0d768002c910676c33e /lisp/image
parent82893e9e8e0dae5cbd3ae26a7ee92896fcadfdae (diff)
downloademacs-23e6c36645bb8f07f55ba94af21cebaaab2c91d3.tar.gz
emacs-23e6c36645bb8f07f55ba94af21cebaaab2c91d3.zip
Implement a cache for all types of gravatars
* lisp/image/gravatar.el (gravatar-automatic-caching): Made obsolete. (gravatar-cache-ttl): Ditto. (gravatar--cache): New variable to cache gravatars in-memory. (gravatar-retrieve): Maintain the cache. (gravatar--prune-cache): Remove old entries. (gravatar-retrieved): Remove use of the old-style cache (bug#40355).
Diffstat (limited to 'lisp/image')
-rw-r--r--lisp/image/gravatar.el57
1 files changed, 42 insertions, 15 deletions
diff --git a/lisp/image/gravatar.el b/lisp/image/gravatar.el
index d1091e57cb5..e917033562e 100644
--- a/lisp/image/gravatar.el
+++ b/lisp/image/gravatar.el
@@ -39,6 +39,7 @@
39 "Whether to cache retrieved gravatars." 39 "Whether to cache retrieved gravatars."
40 :type 'boolean 40 :type 'boolean
41 :group 'gravatar) 41 :group 'gravatar)
42(make-obsolete-variable 'gravatar-automatic-caching nil "28.1")
42 43
43(defcustom gravatar-cache-ttl 2592000 44(defcustom gravatar-cache-ttl 2592000
44 "Time to live in seconds for gravatar cache entries. 45 "Time to live in seconds for gravatar cache entries.
@@ -48,6 +49,7 @@ is retrieved anew. The default value is 30 days."
48 ;; Restricted :type to number of seconds. 49 ;; Restricted :type to number of seconds.
49 :version "27.1" 50 :version "27.1"
50 :group 'gravatar) 51 :group 'gravatar)
52(make-obsolete-variable 'gravatar-cache-ttl nil "28.1")
51 53
52(defcustom gravatar-rating "g" 54(defcustom gravatar-rating "g"
53 "Most explicit Gravatar rating level to allow. 55 "Most explicit Gravatar rating level to allow.
@@ -206,19 +208,50 @@ to track whether you're reading a specific mail."
206 (search-forward "\n\n" nil t) 208 (search-forward "\n\n" nil t)
207 (buffer-substring (point) (point-max))))) 209 (buffer-substring (point) (point-max)))))
208 210
211(defvar gravatar--cache (make-hash-table :test 'equal)
212 "Cache for gravatars.")
213
209;;;###autoload 214;;;###autoload
210(defun gravatar-retrieve (mail-address callback &optional cbargs) 215(defun gravatar-retrieve (mail-address callback &optional cbargs)
211 "Asynchronously retrieve a gravatar for MAIL-ADDRESS. 216 "Asynchronously retrieve a gravatar for MAIL-ADDRESS.
212When finished, call CALLBACK as (apply CALLBACK GRAVATAR CBARGS), 217When finished, call CALLBACK as (apply CALLBACK GRAVATAR CBARGS),
213where GRAVATAR is either an image descriptor, or the symbol 218where GRAVATAR is either an image descriptor, or the symbol
214`error' if the retrieval failed." 219`error' if the retrieval failed."
215 (gravatar-build-url 220 (let ((cached (gethash mail-address gravatar--cache)))
216 mail-address 221 (gravatar--prune-cache)
217 (lambda (url) 222 (if cached
218 (if (url-cache-expired url gravatar-cache-ttl) 223 (apply callback (cdr cached) cbargs)
219 (url-retrieve url #'gravatar-retrieved (list callback cbargs) t) 224 ;; Nothing in the cache, fetch it.
220 (with-current-buffer (url-fetch-from-cache url) 225 (gravatar-build-url
221 (gravatar-retrieved () callback cbargs)))))) 226 mail-address
227 (lambda (url)
228 (url-retrieve
229 url
230 (lambda (status)
231 (let* ((data (and (not (plist-get status :error))
232 (gravatar-get-data)))
233 (image (and data (create-image data nil t))))
234 ;; Store the image in the cache.
235 (when image
236 (setf (gethash mail-address gravatar--cache)
237 (cons (time-convert (current-time) 'integer)
238 image)))
239 (prog1
240 (apply callback (if data image 'error) cbargs)
241 (kill-buffer))))
242 nil t))))))
243
244(defun gravatar--prune-cache ()
245 (let ((expired nil)
246 (time (- (time-convert (current-time) 'integer)
247 ;; Twelve hours.
248 (* 12 60 60))))
249 (maphash (lambda (key val)
250 (when (< (car val) time)
251 (push key expired)))
252 gravatar--cache)
253 (dolist (key expired)
254 (remhash key gravatar--cache))))
222 255
223;;;###autoload 256;;;###autoload
224(defun gravatar-retrieve-synchronously (mail-address) 257(defun gravatar-retrieve-synchronously (mail-address)
@@ -229,10 +262,8 @@ retrieval failed."
229 (gravatar-build-url mail-address (lambda (u) (setq url u))) 262 (gravatar-build-url mail-address (lambda (u) (setq url u)))
230 (while (not url) 263 (while (not url)
231 (sleep-for 0.01)) 264 (sleep-for 0.01))
232 (with-current-buffer (if (url-cache-expired url gravatar-cache-ttl) 265 (with-current-buffer (url-retrieve-synchronously url t)
233 (url-retrieve-synchronously url t) 266 (gravatar-retrieved nil #'identity))))
234 (url-fetch-from-cache url))
235 (gravatar-retrieved () #'identity))))
236 267
237(defun gravatar-retrieved (status cb &optional cbargs) 268(defun gravatar-retrieved (status cb &optional cbargs)
238 "Handle Gravatar response data in current buffer. 269 "Handle Gravatar response data in current buffer.
@@ -241,10 +272,6 @@ an image descriptor, or the symbol `error' on failure.
241This function is intended as a callback for `url-retrieve'." 272This function is intended as a callback for `url-retrieve'."
242 (let ((data (unless (plist-get status :error) 273 (let ((data (unless (plist-get status :error)
243 (gravatar-get-data)))) 274 (gravatar-get-data))))
244 (and data ; Only cache on success.
245 url-current-object ; Only cache if not already cached.
246 gravatar-automatic-caching
247 (url-store-in-cache))
248 (prog1 (apply cb (if data (create-image data nil t) 'error) cbargs) 275 (prog1 (apply cb (if data (create-image data nil t) 'error) cbargs)
249 (kill-buffer)))) 276 (kill-buffer))))
250 277