diff options
| author | Basil L. Contovounesios | 2019-07-22 21:57:39 +0100 |
|---|---|---|
| committer | Basil L. Contovounesios | 2019-08-02 16:33:30 +0300 |
| commit | eddf4664d786e16b34f6bd0af238a567feb5012c (patch) | |
| tree | c4da65620a382bbe612e7631d51a1044ce38c144 | |
| parent | b4b1eda7fbf4c4f3fa6377bd18d1d1a22e6e4b42 (diff) | |
| download | emacs-eddf4664d786e16b34f6bd0af238a567feb5012c.tar.gz emacs-eddf4664d786e16b34f6bd0af238a567feb5012c.zip | |
Make gravatar.el more configurable
For discussion, see the following thread:
https://lists.gnu.org/archive/html/emacs-devel/2019-07/msg00528.html
* etc/NEWS: Announce changes in gravatar.el user options.
* lisp/image/gravatar.el (gravatar-cache-ttl): Change :type to
number of seconds without changing the default value and while still
accepting other timestamp formats.
(gravatar-rating): Restrict :type to ratings recognized by Gravatar.
(gravatar-size): Allow nil as a value, in which case Gravatar's
default size is used.
(gravatar-default-image, gravatar-force-default): New user options
controlling the Gravatar query parameters 'default' and
'forcedefault', respectively.
(gravatar-base-url): Use HTTPS.
(gravatar--query-string): New helper function to facilitate testing.
(gravatar-build-url): Use it.
* test/lisp/image/gravatar-tests.el (gravatar-size)
(gravatar-default-image, gravatar-force-default)
(gravatar-build-url): New tests.
| -rw-r--r-- | etc/NEWS | 16 | ||||
| -rw-r--r-- | lisp/image/gravatar.el | 82 | ||||
| -rw-r--r-- | test/lisp/image/gravatar-tests.el | 38 |
3 files changed, 123 insertions, 13 deletions
| @@ -1788,6 +1788,22 @@ particular when the end of the buffer is visible in the window. | |||
| 1788 | Use 'mouse-wheel-mode' instead. Note that 'mouse-wheel-mode' is | 1788 | Use 'mouse-wheel-mode' instead. Note that 'mouse-wheel-mode' is |
| 1789 | already enabled by default on most graphical displays. | 1789 | already enabled by default on most graphical displays. |
| 1790 | 1790 | ||
| 1791 | ** Gravatar | ||
| 1792 | |||
| 1793 | +++ | ||
| 1794 | *** 'gravatar-cache-ttl' is now a number of seconds. | ||
| 1795 | The previously used timestamp format of a list of integers is still | ||
| 1796 | supported, but is deprecated. The default value has not changed. | ||
| 1797 | |||
| 1798 | +++ | ||
| 1799 | *** 'gravatar-size' can now be nil. | ||
| 1800 | This results in the use of Gravatar's default size of 80 pixels. | ||
| 1801 | |||
| 1802 | +++ | ||
| 1803 | *** The default fallback gravatar is now configurable. | ||
| 1804 | This is possible using the new user options 'gravatar-default-image' | ||
| 1805 | and 'gravatar-force-default'. | ||
| 1806 | |||
| 1791 | 1807 | ||
| 1792 | * New Modes and Packages in Emacs 27.1 | 1808 | * New Modes and Packages in Emacs 27.1 |
| 1793 | 1809 | ||
diff --git a/lisp/image/gravatar.el b/lisp/image/gravatar.el index 52fd875d68c..e235fdd76f3 100644 --- a/lisp/image/gravatar.el +++ b/lisp/image/gravatar.el | |||
| @@ -39,12 +39,13 @@ | |||
| 39 | :type 'boolean | 39 | :type 'boolean |
| 40 | :group 'gravatar) | 40 | :group 'gravatar) |
| 41 | 41 | ||
| 42 | ;; FIXME a time value is not the nicest format for a custom variable. | 42 | (defcustom gravatar-cache-ttl 2592000 |
| 43 | (defcustom gravatar-cache-ttl (days-to-time 30) | 43 | "Time to live in seconds for gravatar cache entries. |
| 44 | "Time to live for gravatar cache entries. | ||
| 45 | If a requested gravatar has been cached for longer than this, it | 44 | If a requested gravatar has been cached for longer than this, it |
| 46 | is retrieved anew." | 45 | is retrieved anew. The default value is 30 days." |
| 47 | :type '(repeat integer) | 46 | :type 'integer |
| 47 | ;; Restricted :type to number of seconds. | ||
| 48 | :version "27.1" | ||
| 48 | :group 'gravatar) | 49 | :group 'gravatar) |
| 49 | 50 | ||
| 50 | (defcustom gravatar-rating "g" | 51 | (defcustom gravatar-rating "g" |
| @@ -64,17 +65,61 @@ of increasing explicitness, the following: | |||
| 64 | Each level covers itself as well as all less explicit levels. | 65 | Each level covers itself as well as all less explicit levels. |
| 65 | For example, setting this variable to \"pg\" will allow gravatars | 66 | For example, setting this variable to \"pg\" will allow gravatars |
| 66 | rated either \"g\" or \"pg\"." | 67 | rated either \"g\" or \"pg\"." |
| 67 | :type 'string | 68 | :type '(choice (const :tag "General Audience" "g") |
| 69 | (const :tag "Parental Guidance" "pg") | ||
| 70 | (const :tag "Restricted" "r") | ||
| 71 | (const :tag "Explicit" "x")) | ||
| 72 | ;; Restricted :type to ratings recognized by Gravatar. | ||
| 73 | :version "27.1" | ||
| 68 | :group 'gravatar) | 74 | :group 'gravatar) |
| 69 | 75 | ||
| 70 | (defcustom gravatar-size 32 | 76 | (defcustom gravatar-size 32 |
| 71 | "Gravatar size in pixels to request. | 77 | "Gravatar size in pixels to request. |
| 72 | Valid sizes range from 1 to 2048 inclusive." | 78 | Valid sizes range from 1 to 2048 inclusive. If nil, use the |
| 73 | :type 'integer | 79 | Gravatar default (usually 80)." |
| 80 | :type '(choice (const :tag "Gravatar default" nil) | ||
| 81 | (integer :tag "Pixels")) | ||
| 82 | :version "27.1" | ||
| 83 | :group 'gravatar) | ||
| 84 | |||
| 85 | (defcustom gravatar-default-image "404" | ||
| 86 | "Default gravatar to use when none match the request. | ||
| 87 | This happens when no gravatar satisfying `gravatar-rating' exists | ||
| 88 | for a given email address. The following options are supported: | ||
| 89 | |||
| 90 | nil - Default placeholder. | ||
| 91 | \"404\" - No placeholder. | ||
| 92 | \"mp\" - Mystery Person: generic avatar outline. | ||
| 93 | \"identicon\" - Geometric pattern based on email address. | ||
| 94 | \"monsterid\" - Generated \"monster\" with different colors, faces, etc. | ||
| 95 | \"wavatar\" - Generated faces with different features and backgrounds. | ||
| 96 | \"retro\" - Generated 8-bit arcade-style pixelated faces. | ||
| 97 | \"robohash\" - Generated robot with different colors, faces, etc. | ||
| 98 | \"blank\" - Transparent PNG image. | ||
| 99 | URL - Custom image URL." | ||
| 100 | :type '(choice (const :tag "Default" nil) | ||
| 101 | (const :tag "None" "404") | ||
| 102 | (const :tag "Mystery person" "mp") | ||
| 103 | (const :tag "Geometric patterns" "identicon") | ||
| 104 | (const :tag "Monsters" "monsterid") | ||
| 105 | (const :tag "Faces" "wavatar") | ||
| 106 | (const :tag "Retro" "retro") | ||
| 107 | (const :tag "Robots" "robohash") | ||
| 108 | (const :tag "Blank" "blank") | ||
| 109 | (string :tag "Custom URL")) | ||
| 110 | :version "27.1" | ||
| 111 | :group 'gravatar) | ||
| 112 | |||
| 113 | (defcustom gravatar-force-default nil | ||
| 114 | "Whether to force use of `gravatar-default-image'. | ||
| 115 | Non-nil means use `gravatar-default-image' even when there exists | ||
| 116 | a gravatar for a given email address." | ||
| 117 | :type 'boolean | ||
| 118 | :version "27.1" | ||
| 74 | :group 'gravatar) | 119 | :group 'gravatar) |
| 75 | 120 | ||
| 76 | (defconst gravatar-base-url | 121 | (defconst gravatar-base-url |
| 77 | "http://www.gravatar.com/avatar" | 122 | "https://www.gravatar.com/avatar" |
| 78 | "Base URL for getting gravatars.") | 123 | "Base URL for getting gravatars.") |
| 79 | 124 | ||
| 80 | (defun gravatar-hash (mail-address) | 125 | (defun gravatar-hash (mail-address) |
| @@ -82,13 +127,24 @@ Valid sizes range from 1 to 2048 inclusive." | |||
| 82 | ;; https://gravatar.com/site/implement/hash/ | 127 | ;; https://gravatar.com/site/implement/hash/ |
| 83 | (md5 (downcase (string-trim mail-address)))) | 128 | (md5 (downcase (string-trim mail-address)))) |
| 84 | 129 | ||
| 130 | (defun gravatar--query-string () | ||
| 131 | "Return URI-encoded query string for Gravatar." | ||
| 132 | (url-build-query-string | ||
| 133 | `((r ,gravatar-rating) | ||
| 134 | ,@(and gravatar-default-image | ||
| 135 | `((d ,gravatar-default-image))) | ||
| 136 | ,@(and gravatar-force-default | ||
| 137 | '((f y))) | ||
| 138 | ,@(and gravatar-size | ||
| 139 | `((s ,gravatar-size)))))) | ||
| 140 | |||
| 85 | (defun gravatar-build-url (mail-address) | 141 | (defun gravatar-build-url (mail-address) |
| 86 | "Return a URL to retrieve MAIL-ADDRESS gravatar." | 142 | "Return the URL of a gravatar for MAIL-ADDRESS." |
| 87 | (format "%s/%s?d=404&r=%s&s=%d" | 143 | ;; https://gravatar.com/site/implement/images/ |
| 144 | (format "%s/%s?%s" | ||
| 88 | gravatar-base-url | 145 | gravatar-base-url |
| 89 | (gravatar-hash mail-address) | 146 | (gravatar-hash mail-address) |
| 90 | gravatar-rating | 147 | (gravatar--query-string))) |
| 91 | gravatar-size)) | ||
| 92 | 148 | ||
| 93 | (defun gravatar-get-data () | 149 | (defun gravatar-get-data () |
| 94 | "Return body of current URL buffer, or nil on failure." | 150 | "Return body of current URL buffer, or nil on failure." |
diff --git a/test/lisp/image/gravatar-tests.el b/test/lisp/image/gravatar-tests.el index e6239da0084..bd61663f0e8 100644 --- a/test/lisp/image/gravatar-tests.el +++ b/test/lisp/image/gravatar-tests.el | |||
| @@ -31,4 +31,42 @@ | |||
| 31 | (should (equal (gravatar-hash " foo") hash)) | 31 | (should (equal (gravatar-hash " foo") hash)) |
| 32 | (should (equal (gravatar-hash " foo ") hash)))) | 32 | (should (equal (gravatar-hash " foo ") hash)))) |
| 33 | 33 | ||
| 34 | (ert-deftest gravatar-size () | ||
| 35 | "Test query strings for `gravatar-size'." | ||
| 36 | (let ((gravatar-default-image nil) | ||
| 37 | (gravatar-force-default nil)) | ||
| 38 | (let ((gravatar-size 2048)) | ||
| 39 | (should (equal (gravatar--query-string) "r=g&s=2048"))) | ||
| 40 | (let ((gravatar-size nil)) | ||
| 41 | (should (equal (gravatar--query-string) "r=g"))))) | ||
| 42 | |||
| 43 | (ert-deftest gravatar-default-image () | ||
| 44 | "Test query strings for `gravatar-default-image'." | ||
| 45 | (let ((gravatar-force-default nil) | ||
| 46 | (gravatar-size nil)) | ||
| 47 | (let ((gravatar-default-image nil)) | ||
| 48 | (should (equal (gravatar--query-string) "r=g"))) | ||
| 49 | (let ((gravatar-default-image "404")) | ||
| 50 | (should (equal (gravatar--query-string) "r=g&d=404"))) | ||
| 51 | (let ((gravatar-default-image "https://foo/bar.png")) | ||
| 52 | (should (equal (gravatar--query-string) | ||
| 53 | "r=g&d=https%3A%2F%2Ffoo%2Fbar.png"))))) | ||
| 54 | |||
| 55 | (ert-deftest gravatar-force-default () | ||
| 56 | "Test query strings for `gravatar-force-default'." | ||
| 57 | (let ((gravatar-default-image nil) | ||
| 58 | (gravatar-size nil)) | ||
| 59 | (let ((gravatar-force-default nil)) | ||
| 60 | (should (equal (gravatar--query-string) "r=g"))) | ||
| 61 | (let ((gravatar-force-default t)) | ||
| 62 | (should (equal (gravatar--query-string) "r=g&f=y"))))) | ||
| 63 | |||
| 64 | (ert-deftest gravatar-build-url () | ||
| 65 | "Test `gravatar-build-url'." | ||
| 66 | (let ((gravatar-default-image nil) | ||
| 67 | (gravatar-force-default nil) | ||
| 68 | (gravatar-size nil)) | ||
| 69 | (should (equal (gravatar-build-url "foo") "\ | ||
| 70 | https://www.gravatar.com/avatar/acbd18db4cc2f85cedef654fccc4a4d8?r=g")))) | ||
| 71 | |||
| 34 | ;;; gravatar-tests.el ends here | 72 | ;;; gravatar-tests.el ends here |