Improving my elisp by building an API to my YOURLS shortener
Table of Contents
Until recently I was well-served by now-derelict url-shortener which worked well. It’s a cool library – very general, supporting a variety of shortening options. But when it broke, it was annoyingly complex to fix. Plus, I needed the excuse to sharpen my elisp skills a bit. The result is below. I learned a lot of good things (big thanks to the Reddit emacs community), including:
- Using defcustom to create customs groups for use in emacs’ nice customization tooling
- Utilizing url-build-query-string to build my… well, you know. And using backtick
`
with it to work with my customized variables. - Using
url-retrieve-synchronously
with its returned buffer (a distinctly emacsy way of doing things) instead of attemptingurl-retrieve
with its asynchronous callback function to make time my friend rather than a complication - Utilizing
with-current-buffer
,buffer-string
,string-match
, andreplace-regexp-in-string
to trim the full response down to my desired result.
The result is just a couple of short functions that do what I (and perhaps anyone else using a YOURLS instance) need. No logging, no error messages, no trying to allow for other shorteners, no worry about people using other operating systems, no testing suite, no support provisions – just about one screen of code, that’s it. Fun and done.
(defcustom yourls-signature nil "The YOURLS-given signature code"
:group 'yourls)
(defcustom yourls-url nil "The base URL of yourls-api.php"
:group 'yourls)
(defun tsa/yourls-get-short (url)
(let* ((querys (url-build-query-string `(("signature" ,yourls-signature)
("action" "shorturl")
("format" "json")
("url" ,url))))
(final-url (concat yourls-url "/?" querys))
(url-request-method "GET")
(retrieved (url-retrieve-synchronously final-url)))
(with-current-buffer retrieved
(let* ((s (buffer-string))
(shortened (when (string-match "\"shorturl\":\"\\([^\"]*\\)\""
s)
(replace-regexp-in-string "\\\\" "" (match-string 1 s)))))
shortened))))
(defun tsa/yourls-shorten-at-point ()
"Shorten the URL at point with your YOURLS install"
(interactive)
(let ((url-bounds (bounds-of-thing-at-point 'url)))
(when url-bounds
(let ((url (tsa/yourls-get-short (thing-at-point 'url))))
(when url
(save-restriction
(narrow-to-region (car url-bounds) (cdr url-bounds))
(delete-region (point-min) (point-max))
(insert url)))))))