Skip to content

Instantly share code, notes, and snippets.

@skeeto
Last active August 29, 2015 14:18
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save skeeto/71c35808b210350212a6 to your computer and use it in GitHub Desktop.
Save skeeto/71c35808b210350212a6 to your computer and use it in GitHub Desktop.
thebutton-mode
;;; thebutton.el --- display r/thebutton's status on the modeline
;; This is free and unencumbered software released into the public domain.
;;; Commentary:
;; Unfortunately the URL's hash changes regularly, so you may need to
;; update `thebutton-url' to the new when first start the mode.
;; Dependency: https://github.com/ahyatt/emacs-websocket
;;; Code:
(require 'json)
(require 'websocket)
(defvar thebutton-url "http://www.reddit.com/r/thebutton"
"URL of the main subreddit.")
(defvar thebutton-interval 0.11
"Period in seconds at which the mode line is updated.")
(defvar thebutton-timer nil
"Time object used to update the mode line.")
(defvar thebutton-ws nil
"Websocket object connection to reddit.")
(defvar thebutton--regex
"wss://wss.redditmedia.com/thebutton\\?h=[0-9a-z]+&e=[0-9]+"
"Matches the current websocket URL from the subreddit.")
(defvar thebutton--string ""
"Current mode line text (dynamic variable needed for mode line API).")
(defvar thebutton--finish nil
"Epoch time when the timer will hit zero.")
(defun thebutton--get-url ()
"Fetch the current websocket URL."
(save-match-data
(with-current-buffer (url-retrieve-synchronously thebutton-url t t)
(when (re-search-forward thebutton--regex nil t)
(match-string 0)))))
(defun thebutton--handler ()
"Handles events from the timer."
(when (and thebutton-mode thebutton--finish)
(setf thebutton--string
(format " %.2f" (- thebutton--finish (float-time)))))
(force-mode-line-update 'all))
(defun thebutton--on-message (_ f)
"Handles updates from the websocket."
(let* ((json-object-type 'plist)
(json-key-type 'keyword)
(json (json-read-from-string (websocket-frame-payload f)))
(payload (plist-get json :payload))
(seconds-left (plist-get payload :seconds_left)))
(setf thebutton--finish (+ (float-time) seconds-left))))
(define-minor-mode thebutton-mode
"Display the current countdown for r/thebutton in the mode line."
:global t
(when thebutton-timer
(cancel-timer thebutton-timer)
(setf thebutton-timer nil))
(when thebutton-ws
(websocket-close thebutton-ws)
(setf thebutton-ws nil))
(unless (member 'thebutton--string global-mode-string)
(setf global-mode-string (nconc global-mode-string `(thebutton--string))))
(if (not thebutton-mode)
(setf thebutton--string ""
thebutton-timer nil
thebutton--finish nil)
(setf thebutton-timer
(run-at-time t thebutton-interval #'thebutton--handler)
thebutton-ws
(websocket-open
(thebutton--get-url) :on-message #'thebutton--on-message))))
;;; thebutton.el ends here
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment