aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.org13
-rw-r--r--lisp/mastodon-async.el83
-rw-r--r--lisp/mastodon-notifications.el6
-rw-r--r--lisp/mastodon.el5
4 files changed, 73 insertions, 34 deletions
diff --git a/README.org b/README.org
index b51644b..6da0f4b 100644
--- a/README.org
+++ b/README.org
@@ -9,8 +9,8 @@ It adds the following features:
| | display relationship (follows you/followed by you) on profiles |
| | display toots/follows/followers counts on profiles |
| | links and tags in profiles are tab stops like in posts |
-| =R=, =a=, =r= | view/accept/reject follow requests |
-| =v= | view your favorited toots |
+| =R=, =a=, =r= | view/accept/reject follow requests |
+| =v= | view your favorited toots |
| =i= | (un)pin toots, display pinned toots on profiles |
| =S-C-P= | jump to your profile |
| Timelines: | |
@@ -33,7 +33,13 @@ The minimum Emacs version is now 25.1. But if you are running an older version i
I did this for my own use and to learn more Elisp. If the code is terrible, feel free to improve or replace it. It surely still contains errors, I'm only weeding them out as I find them.
-** NB: dependency:
+** live-updating timelines
+
+(code adapted from https://github.com/alexjgriffith/mastodon-future.el).
+
+Works for federated, local, and home timelines and for notifications. It's pretty necro, so use at your own risk. Not a super high priority for me, but some people dig it. The command prefix is =mastodon-async--stream=
+
+** NB: dependency
This version depends on the library =request= (for uploading attachments). You can install it from MELPA, or https://github.com/tkf/emacs-request.
@@ -53,7 +59,6 @@ I might add a few more features if the ones I added turn out to work ok. Possibl
- mention all thread participants in replies
- handle newlines in toots better, for poetry, etc.
- improve async.
-- perhaps integrate live timeline updates from https://github.com/alexjgriffith/mastodon-future.el, and add live updates for notifcations and home timeline.
It looks like 2-factor auth was never completed in the original repo. It's not a priority for me, auth ain't my thing. If you want to hack on it, its on the develop branch in the original repo.
diff --git a/lisp/mastodon-async.el b/lisp/mastodon-async.el
index ffd8ab6..1be88ae 100644
--- a/lisp/mastodon-async.el
+++ b/lisp/mastodon-async.el
@@ -31,6 +31,8 @@
(require 'json)
+(autoload 'mastodon-notifications--timeline "mastodon-notifications")
+
(defgroup mastodon-async nil
"An async module for mastodon streams."
:prefix "mastodon-async-"
@@ -86,19 +88,19 @@
;; The output can be passed to notifications
;; need an alternate process-queue-string function
(defun mastodon-async--stream-notifications ()
- "Open a stream of Home."
+ "Open a stream of user notifications."
(interactive)
(mastodon-async--mastodon
"user"
"home"
"notifications"
- 'mastodon-async--process-queue-string))
+ 'mastodon-async--process-queue-string-notifications))
;; this will stream both home AND notifications.
;; need to workout how to filter "user" stream
;; and split it
(defun mastodon-async--stream-home ()
- "Open a stream of Home."
+ "Open a stream of the home timeline."
(interactive)
(mastodon-async--mastodon
"user"
@@ -132,7 +134,7 @@
Then Start an async mastodon stream at ENDPOINT filtering toots
using FILTER.
Argument TIMELINE a specific target, such as federated or home.
-Argument NAME the center portion of the buffer name for *mastodon-async-buffer and *mastodon-async-queueu."
+Argument NAME the center portion of the buffer name for *mastodon-async-buffer and *mastodon-async-queue."
(let ((buffer (mastodon-async--start-process
endpoint filter name)))
(with-current-buffer buffer
@@ -141,7 +143,7 @@ Argument NAME the center portion of the buffer name for *mastodon-async-buffer a
(goto-char 1))))
(defun mastodon-async--get (url callback)
- "An async get targeted at URL with a CALLBACK."
+ "An async GET request to URL with CALLBACK."
(let ((url-request-method "GET")
(url-request-extra-headers
`(("Authorization" .
@@ -174,16 +176,16 @@ is not known when `mastodon-async--setup-buffer' is called."
"Adds local variables to HTTP-BUFFER.
NAME is used to generate the display buffer and the queue."
- (let ((queue-name(concat " *mastodon-async-queue-" name "-"
+ (let ((queue-name (concat " *mastodon-async-queue-" name "-"
mastodon-instance-url "*"))
- (buffer-name(concat "*mastodon-async-display-" name "-"
+ (buffer-name (concat "*mastodon-async-display-" name "-"
mastodon-instance-url "*")))
(mastodon-async--set-local-variables http-buffer http-buffer
buffer-name queue-name)))
(defun mastodon-async--setup-queue (http-buffer name)
"Sets up the buffer for the async queue."
- (let ((queue-name(concat " *mastodon-async-queue-" name "-"
+ (let ((queue-name (concat " *mastodon-async-queue-" name "-"
mastodon-instance-url "*"))
(buffer-name(concat "*mastodon-async-display-" name "-"
mastodon-instance-url "*")))
@@ -194,15 +196,18 @@ NAME is used to generate the display buffer and the queue."
(defun mastodon-async--setup-buffer (http-buffer name endpoint)
"Sets up the buffer timeline like `mastodon-tl--init'.
-HTTP-BUFFER the name of the http-buffer, if unknow set to
-NAME is the given name of the stream, like local for public?local
-ENPOINT is the specific endpoint for a stream and timeline"
+HTTP-BUFFER the name of the http-buffer, if unknown, set to...
+NAME is the name of the stream for the buffer name.
+ENPOINT is the endpoint for the stream and timeline."
(let ((queue-name (concat " *mastodon-async-queue-" name "-"
mastodon-instance-url "*"))
(buffer-name (concat "*mastodon-async-display-" name "-"
mastodon-instance-url "*"))
- ;; if user stream, we need "timelines/home" not "timelines/user"
- (endpoint (if (equal endpoint "user") "home" endpoint)))
+ ;; if user stream, we need "timelines/home" not "timelines/user"
+ ;; if notifs, we need "notifications" not "timelines/notifications"
+ (endpoint (if (equal name "notifications") "notifications"
+ (if (equal name "home") "timelines/home"
+ (format "timelines/%s" endpoint)))))
(mastodon-async--set-local-variables buffer-name http-buffer
buffer-name queue-name)
;; Similar to timeline init.
@@ -210,16 +215,22 @@ ENPOINT is the specific endpoint for a stream and timeline"
(setq inhibit-read-only t) ; for home timeline?
(make-local-variable 'mastodon-tl--enable-relative-timestamps)
(make-local-variable 'mastodon-tl--display-media-p)
- (message (mastodon-http--api (format "timelines/%s" endpoint)))
- (mastodon-tl--timeline (mastodon-http--get-json
- (mastodon-http--api
- (format "timelines/%s" endpoint))))
+ (message (mastodon-http--api endpoint))
+ (if (equal name "notifications")
+ (mastodon-notifications--timeline
+ (mastodon-http--get-json
+ (mastodon-http--api "notifications")))
+ (mastodon-tl--timeline (mastodon-http--get-json
+ (mastodon-http--api endpoint))))
(mastodon-mode)
(setq mastodon-tl--buffer-spec
- `(buffer-name ,buffer-name
- endpoint ,(format "timelines/%s" endpoint)
- update-function
- ,'mastodon-tl--timeline))
+ `(buffer-name
+ ,buffer-name
+ endpoint ,endpoint
+ update-function
+ ,(if (equal name "notifications")
+ 'mastodon-notifications--timeline
+ 'mastodon-tl--timeline)))
(setq-local mastodon-tl--enable-relative-timestamps nil)
(setq-local mastodon-tl--display-media-p t)
(current-buffer))))
@@ -254,7 +265,7 @@ Filter the toots using FILTER."
(funcall filter queue-string))))))))
(defun mastodon-async--process-queue-string (string)
- "Parse the output STRING of the queue buffer."
+ "Parse the output STRING of the queue buffer, returning only update events."
(let* ((split-strings (split-string string "\n" t))
(event-type (replace-regexp-in-string
"^event: " ""
@@ -266,6 +277,20 @@ Filter the toots using FILTER."
;; for now return nil if malformed using `ignore-errors'
(ignore-errors (json-read-from-string data)))))
+(defun mastodon-async--process-queue-string-notifications (string)
+ "Parse the output STRING of the queue buffer, returning only notification events."
+ ;; NB notification events in screams include follow requests
+ (let* ((split-strings (split-string string "\n" t))
+ (event-type (replace-regexp-in-string
+ "^event: " ""
+ (car split-strings)))
+ (data (replace-regexp-in-string
+ "^data: " "" (cadr split-strings))))
+ (when (equal "notification" event-type)
+ ;; in some casses the data is not fully formed
+ ;; for now return nil if malformed using `ignore-errors'
+ (ignore-errors (json-read-from-string data)))))
+
(defun mastodon-async--process-queue-local-string (string)
"Use STRING to limit the public endpoint to displaying local steams only."
(let ((json (mastodon-async--process-queue-string string)))
@@ -280,8 +305,8 @@ Filter the toots using FILTER."
(cdr (assoc 'acct (cdr (assoc 'account json)))))))
(defun mastodon-async--output-toot (toot)
- "Process TOOT and prepend it to the async user facing buffer."
- (if (not(bufferp (get-buffer mastodon-async--buffer)))
+ "Process TOOT and prepend it to the async user-facing buffer."
+ (if (not (bufferp (get-buffer mastodon-async--buffer)))
(mastodon-async--stop-http)
(when toot
(with-current-buffer mastodon-async--buffer
@@ -290,8 +315,12 @@ Filter the toots using FILTER."
(previous (point))
(mastodon-tl--enable-relative-timestamps t)
(mastodon-tl--display-media-p t))
- (goto-char (point-min))
- (mastodon-tl--timeline (list toot))
+ (goto-char (point-min))
+ (if (equal (buffer-name)
+ (concat "*mastodon-async-display-notifications-"
+ mastodon-instance-url "*"))
+ (mastodon-notifications--timeline (list toot))
+ (mastodon-tl--timeline (list toot)))
(if (equal previous 1)
(goto-char 1)
(goto-char (+ previous (- (point-max) old-max)))))))))
@@ -305,7 +334,7 @@ Full messages are seperated by two newlines"
(goto-char (max-char))
(insert (decode-coding-string string 'utf-8))
(goto-char 0)
- (let((next(re-search-forward "\n\n" nil t)))
+ (let ((next (re-search-forward "\n\n" nil t)))
(when next
(let ((return-string (buffer-substring 1 next))
(inhibit-read-only t))
diff --git a/lisp/mastodon-notifications.el b/lisp/mastodon-notifications.el
index d40815a..4bf30f1 100644
--- a/lisp/mastodon-notifications.el
+++ b/lisp/mastodon-notifications.el
@@ -140,11 +140,11 @@
(defun mastodon-notifications--get ()
"Display NOTIFICATIONS in buffer."
(interactive)
+ (message "Loading your nofications...")
(mastodon-tl--init
- "*mastodon-notifications*"
"notifications"
- 'mastodon-notifications--timeline)
- (message "Loading your nofications..."))
+ "notifications"
+ 'mastodon-notifications--timeline))
(provide 'mastodon-notifications)
;;; mastodon-notifications.el ends here
diff --git a/lisp/mastodon.el b/lisp/mastodon.el
index 6096c55..4d0b940 100644
--- a/lisp/mastodon.el
+++ b/lisp/mastodon.el
@@ -72,6 +72,7 @@
(autoload 'mastodon-async--stream-federated "mastodon-async")
(autoload 'mastodon-async--stream-local "mastodon-async")
(autoload 'mastodon-async--stream-home "mastodon-async")
+(autoload 'mastodon-async--stream-notifications "mastodon-async")
(defgroup mastodon nil
"Interface with Mastodon."
@@ -139,6 +140,10 @@ Use. e.g. \"%c\" for your locale's date and time format."
(define-key map (kbd "i") #'mastodon-toot--pin-toot-toggle)
(define-key map (kbd "v") #'mastodon-profile--view-favourites)
(define-key map (kbd "R") #'mastodon-profile--view-follow-requests)
+ (define-key map (kbd "C-c h") #'mastodon-async--stream-home)
+ (define-key map (kbd "C-c f") #'mastodon-async--stream-federated)
+ (define-key map (kbd "C-c l") #'mastodon-async--stream-local)
+ (define-key map (kbd "C-c n") #'mastodon-async--stream-notifications)
map)
"Keymap for `mastodon-mode'.")