From b607c4e800235312350b56f7e845a56fe6b29248 Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Sun, 11 Sep 2022 14:40:22 +0200 Subject: docstrings autoloads local funs --- lisp/mastodon-toot.el | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/lisp/mastodon-toot.el b/lisp/mastodon-toot.el index 2f58bfb..f1d4343 100644 --- a/lisp/mastodon-toot.el +++ b/lisp/mastodon-toot.el @@ -50,6 +50,8 @@ (defvar mastodon-instance-url) (defvar mastodon-tl--buffer-spec) (defvar mastodon-tl--enable-proportional-fonts) +(defvar mastodon-profile-account-settings) + (autoload 'mastodon-auth--user-acct "mastodon-auth") (autoload 'mastodon-http--api "mastodon-http") (autoload 'mastodon-http--delete "mastodon-http") @@ -196,13 +198,17 @@ send.") nil t))) (mastodon-profile--update-preference "privacy" vis :source))) -(defun mastodon-toot--get-max-toot-chars (&optional no-toot) - "Fetch max_toot_chars from `mastodon-instance-url' asynchronously." +(defun mastodon-toot--get-max-toot-chars (&optional _no-toot) + "Fetch max_toot_chars from `mastodon-instance-url' asynchronously. +NO-TOOT means we are not calling from a toot buffer." (mastodon-http--get-json-async - (mastodon-http--api "instance") 'mastodon-toot--get-max-toot-chars-callback 'no-toot)) + (mastodon-http--api "instance") + 'mastodon-toot--get-max-toot-chars-callback 'no-toot)) -(defun mastodon-toot--get-max-toot-chars-callback (json-response &optional no-toot) - "Set max_toot_chars returned in JSON-RESPONSE and display in new toot buffer." +(defun mastodon-toot--get-max-toot-chars-callback (json-response + &optional no-toot) + "Set max_toot_chars returned in JSON-RESPONSE and display in new toot buffer. +NO-TOOT means we are not calling from a toot buffer." (let ((max-chars (or (alist-get 'max_toot_chars json-response) @@ -1066,16 +1072,15 @@ REPLY-JSON is the full JSON of the toot being replied to." (list 'invisible (not mastodon-toot--content-warning) 'face 'mastodon-cw-face))))) -(defun mastodon-toot-save-toot-text (&rest _args) +(defun mastodon-toot--save-toot-text (&rest _args) "Save the current toot text in `mastodon-toot-current-toot-text'. Added to `after-change-functions' in new toot buffers." - (interactive) (let ((text (mastodon-toot--remove-docs))) (unless (string-empty-p text) (setq mastodon-toot-current-toot-text text)))) (defun mastodon-toot-open-draft-toot () - "Prompt for a draft toot and open a new compose buffer containing the draft." + "Prompt for a draft and compose a toot with it." (interactive) (if mastodon-toot-draft-toots-list (let ((text (completing-read "Select draft toot: " @@ -1165,7 +1170,7 @@ a draft into the buffer." (mastodon-toot--update-status-fields) ;; draft toot text saving: (setq mastodon-toot-current-toot-text nil) - (push #'mastodon-toot-save-toot-text after-change-functions) + (push #'mastodon-toot--save-toot-text after-change-functions) (when initial-text (insert initial-text)))) -- cgit v1.2.3 From 16acbea70362310985667a6eb65b60863f97448a Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Sun, 11 Sep 2022 14:40:32 +0200 Subject: prompt to save draft on toot cancel --- lisp/mastodon-toot.el | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/lisp/mastodon-toot.el b/lisp/mastodon-toot.el index f1d4343..79a99ad 100644 --- a/lisp/mastodon-toot.el +++ b/lisp/mastodon-toot.el @@ -465,26 +465,32 @@ REPLY-ID, TOOT-VISIBILITY, and TOOT-CW of deleted toot are preseved." (mastodon-toot-set-cw toot-cw) (mastodon-toot--update-status-fields)))) -(defun mastodon-toot--kill (&optional cancel) - "Kill `mastodon-toot-mode' buffer and window. -CANCEL means the toot was not sent, so we save the toot text as a draft." +(defun mastodon-toot--kill () + "Kill `mastodon-toot-mode' buffer and window." (with-current-buffer (get-buffer "*new toot*") - (unless (eq mastodon-toot-current-toot-text nil) - (when cancel - (cl-pushnew mastodon-toot-current-toot-text - mastodon-toot-draft-toots-list :test 'equal))) - ;; prevent some weird bug when cancelling a non-empty toot: - (delete #'mastodon-toot-save-toot-text after-change-functions) + ;; FIXME: prevent some weird bug when cancelling a non-empty toot: + (delete #'mastodon-toot--save-toot-text after-change-functions) (kill-buffer-and-window))) (defun mastodon-toot--cancel () "Kill new-toot buffer/window. Does not POST content to Mastodon. -Toot text is saved as a draft." +If toot is not empty, prompt to save text as a draft." (interactive) (if (mastodon-toot-empty-p) - (mastodon-toot--kill :cancel) - (when (y-or-n-p "Discard draft toot? (text will be saved)") - (mastodon-toot--kill :cancel)))) + (mastodon-toot--kill) + (when (y-or-n-p "Save draft toot?") + (mastodon-toot-save-draft)) + (mastodon-toot--kill))) + +(defun mastodon-toot-save-draft () + "Save the current compose toot text as a draft. +Pushes `mastodon-toot-current-toot-text' to +`mastodon-toot-draft-toots-list'." + (interactive) + (unless (eq mastodon-toot-current-toot-text nil) + (cl-pushnew mastodon-toot-current-toot-text + mastodon-toot-draft-toots-list :test 'equal) + (message "Draft saved!"))) (defun mastodon-toot-empty-p (&optional text-only) "Return t if no text or attachments have been added to the compose buffer. -- cgit v1.2.3 From 160aefb2fe03f101f9f137abe8da4f81eed5f7a5 Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Sun, 11 Sep 2022 16:48:56 +0200 Subject: readme re draft toots cmds --- README.org | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.org b/README.org index 3700e6f..157e342 100644 --- a/README.org +++ b/README.org @@ -205,6 +205,14 @@ You can download and use your instance's custom emoji | =C-c C-e= | add emoji (if =emojify= installed) | |---------+----------------------------------| +**** draft toots + +- Compose buffer text is saved as you type, kept in =mastodon-toot-current-toot-text=. +- =mastodon-toot-save-draft=: save the current toot as a draft. +- =mastodon-toot-open-draft-toot=: Open a compose buffer and insert one of your draft toots. +- =mastodon-toot-delete-draft-toot=: Delete a draft toot. +- =mastodon-toot-delete-all-drafts=: Delete all your drafts. + *** Other commands and account settings: - =mastodon-url-lookup=: Attempt to load URL in =mastodon.el=. URL may be the one at point or provided in the minibuffer. Should also work if =mastodon.el= is not yet loaded. -- cgit v1.2.3 From 2d905fe0b92745eff1c6ba1c24f614e951bf5e46 Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Mon, 12 Sep 2022 17:41:25 +0200 Subject: store metadata fields in a normal alist --- lisp/mastodon-profile.el | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lisp/mastodon-profile.el b/lisp/mastodon-profile.el index 012e357..38aceae 100644 --- a/lisp/mastodon-profile.el +++ b/lisp/mastodon-profile.el @@ -406,11 +406,11 @@ This endpoint only holds a few preferences. For others, see (defun mastodon-profile--fields-get (account) "Fetch the fields vector (aka profile metadata) from profile of ACCOUNT. -Returns a list of lists." +Returns an alist." (let ((fields (mastodon-profile--account-field account 'fields))) (when fields (mapcar (lambda (el) - (list (alist-get 'name el) + (cons (alist-get 'name el) (alist-get 'value el))) fields)))) @@ -424,7 +424,7 @@ Returns a list of lists." (concat (format "_ %s " (car field)) (make-string (- (+ 1 left-width) (length (car field))) ?_) - (format " :: %s" (cadr field))) + (format " :: %s" (cdr field))) field)) ; hack to make links tabstops fields ""))) -- cgit v1.2.3 From 05c0ac8f288280a88864db73a5ccf5af553c6d06 Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Mon, 12 Sep 2022 19:07:27 +0200 Subject: indentation and stale TODOs --- lisp/mastodon-http.el | 74 +++++++++++++++++++++++++------------------------- lisp/mastodon-media.el | 5 ++-- 2 files changed, 39 insertions(+), 40 deletions(-) diff --git a/lisp/mastodon-http.el b/lisp/mastodon-http.el index 086dcec..a3a0a95 100644 --- a/lisp/mastodon-http.el +++ b/lisp/mastodon-http.el @@ -262,43 +262,43 @@ item uploaded, and `mastodon-toot--update-status-fields' is run." (let* ((file (file-name-nondirectory filename)) (request-backend 'curl)) (request - url - :type "POST" - :params `(("description" . ,caption)) - :files `(("file" . (,file :file ,filename - :mime-type "multipart/form-data"))) - :parser 'json-read - :headers `(("Authorization" . ,(concat "Bearer " - (mastodon-auth--access-token)))) - :sync nil - :success (cl-function - (lambda (&key data &allow-other-keys) - (when data - (push (alist-get 'id data) - mastodon-toot--media-attachment-ids) ; add ID to list - (message "%s file %s with id %S and caption '%s' uploaded!" - (capitalize (alist-get 'type data)) - file - (alist-get 'id data) - (alist-get 'description data)) - (mastodon-toot--update-status-fields)))) - :error (cl-function - (lambda (&key error-thrown &allow-other-keys) - (cond - ;; handle curl errors first (eg 26, can't read file/path) - ;; because the '=' test below fails for them - ;; they have the form (error . error message 24) - ((not (proper-list-p error-thrown)) ; not dotted list - (message "Got error: %s. Shit went south." (cdr error-thrown))) - ;; handle mastodon api errors - ;; they have the form (error http 401) - ((= (car (last error-thrown)) 401) - (message "Got error: %s Unauthorized: The access token is invalid" error-thrown)) - ((= (car (last error-thrown)) 422) - (message "Got error: %s Unprocessable entity: file or file type is unsupported or invalid" error-thrown)) - (t - (message "Got error: %s Shit went south" - error-thrown)))))))) + url + :type "POST" + :params `(("description" . ,caption)) + :files `(("file" . (,file :file ,filename + :mime-type "multipart/form-data"))) + :parser 'json-read + :headers `(("Authorization" . ,(concat "Bearer " + (mastodon-auth--access-token)))) + :sync nil + :success (cl-function + (lambda (&key data &allow-other-keys) + (when data + (push (alist-get 'id data) + mastodon-toot--media-attachment-ids) ; add ID to list + (message "%s file %s with id %S and caption '%s' uploaded!" + (capitalize (alist-get 'type data)) + file + (alist-get 'id data) + (alist-get 'description data)) + (mastodon-toot--update-status-fields)))) + :error (cl-function + (lambda (&key error-thrown &allow-other-keys) + (cond + ;; handle curl errors first (eg 26, can't read file/path) + ;; because the '=' test below fails for them + ;; they have the form (error . error message 24) + ((not (proper-list-p error-thrown)) ; not dotted list + (message "Got error: %s. Shit went south." (cdr error-thrown))) + ;; handle mastodon api errors + ;; they have the form (error http 401) + ((= (car (last error-thrown)) 401) + (message "Got error: %s Unauthorized: The access token is invalid" error-thrown)) + ((= (car (last error-thrown)) 422) + (message "Got error: %s Unprocessable entity: file or file type is unsupported or invalid" error-thrown)) + (t + (message "Got error: %s Shit went south" + error-thrown)))))))) (provide 'mastodon-http) ;;; mastodon-http.el ends here diff --git a/lisp/mastodon-media.el b/lisp/mastodon-media.el index ace15b2..9715a6c 100644 --- a/lisp/mastodon-media.el +++ b/lisp/mastodon-media.el @@ -186,7 +186,6 @@ with the image." MEDIA-TYPE is a symbol and either 'avatar or 'media-link. START is the position where we start loading the image. REGION-LENGTH is the range from start to propertize." - ;; TODO: Cache the avatars (let ((image-options (when (or (image-type-available-p 'imagemagick) (image-transforms-p)) ; inbuilt scaling in 27.1 (cond @@ -196,8 +195,8 @@ REGION-LENGTH is the range from start to propertize." `(:max-height ,mastodon-media--preview-max-height)))))) (let ((buffer (current-buffer)) (marker (copy-marker start)) - ;; Keep url.el from spamming us with messages about connecting to hosts: - (url-show-status nil)) + ;; Keep url.el from spamming us with messages about connecting to hosts: + (url-show-status nil)) (condition-case nil ;; catch any errors in url-retrieve so as to not abort ;; whatever called us -- cgit v1.2.3 From cef2ed2bbb6aca680e40db4b14572227f3843eeb Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Mon, 12 Sep 2022 19:16:52 +0200 Subject: macro declare debug body for auth req --- lisp/mastodon-http.el | 1 + 1 file changed, 1 insertion(+) diff --git a/lisp/mastodon-http.el b/lisp/mastodon-http.el index a3a0a95..a8b3650 100644 --- a/lisp/mastodon-http.el +++ b/lisp/mastodon-http.el @@ -100,6 +100,7 @@ Message status and JSON error from RESPONSE if unsuccessful." (defmacro mastodon-http--authorized-request (method body &optional unauthenticated-p) "Make a METHOD type request using BODY, with Mastodon authorization. Unless UNAUTHENTICATED-P is non-nil." + (declare (debug 'body)) `(let ((url-request-method ,method) (url-request-extra-headers (unless ,unauthenticated-p -- cgit v1.2.3 From 2d761c8244f0627ea11c443adc92838e78080c87 Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Mon, 12 Sep 2022 21:42:58 +0200 Subject: add Cask dep persist --- Cask | 1 + 1 file changed, 1 insertion(+) diff --git a/Cask b/Cask index 3f7825f..a960f81 100644 --- a/Cask +++ b/Cask @@ -6,6 +6,7 @@ (depends-on "request" "0.3.0") (depends-on "seq") +(depends-on "persist") (development (depends-on "ert-runner") -- cgit v1.2.3 From 67edae65cd6815d7258b9c72d2a3a88e903dd252 Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Mon, 12 Sep 2022 22:02:11 +0200 Subject: fix spoiler text and indent tl-tests --- test/mastodon-tl-tests.el | 115 +++++++++++++++++++++++--------------------- test/mastodon-toot-tests.el | 2 +- 2 files changed, 60 insertions(+), 57 deletions(-) diff --git a/test/mastodon-tl-tests.el b/test/mastodon-tl-tests.el index a569c89..bb5d00f 100644 --- a/test/mastodon-tl-tests.el +++ b/test/mastodon-tl-tests.el @@ -206,10 +206,10 @@ a string or a numeric." (weeks (n) (* n (days 7))) (years (n) (* n (days 365))) (format-seconds-since (seconds) - (let ((timestamp (time-subtract (current-time) (seconds-to-time seconds)))) - (mastodon-tl--relative-time-description timestamp))) + (let ((timestamp (time-subtract (current-time) (seconds-to-time seconds)))) + (mastodon-tl--relative-time-description timestamp))) (check (seconds expected) - (should (string= (format-seconds-since seconds) expected)))) + (should (string= (format-seconds-since seconds) expected)))) (check 1 "less than a minute ago") (check 59 "less than a minute ago") (check 60 "one minute ago") @@ -245,33 +245,33 @@ a string or a numeric." (weeks (n) (* n (days 7))) (years (n) (* n (days 365.25))) (next-update (seconds-ago) - (let* ((timestamp (time-subtract current-time - (seconds-to-time seconds-ago)))) - (cdr (mastodon-tl--relative-time-details timestamp current-time)))) + (let* ((timestamp (time-subtract current-time + (seconds-to-time seconds-ago)))) + (cdr (mastodon-tl--relative-time-details timestamp current-time)))) (check (seconds-ago) - (let* ((timestamp (time-subtract current-time (seconds-to-time seconds-ago))) - (at-now (mastodon-tl--relative-time-description timestamp current-time)) - (at-one-second-before (mastodon-tl--relative-time-description - timestamp - (time-subtract (next-update seconds-ago) - (seconds-to-time 1)))) - (at-result (mastodon-tl--relative-time-description - timestamp - (next-update seconds-ago)))) - (when nil ;; change to t to debug test failures - (prin1 (format "\nFor %s: %s / %s" - seconds-ago - (time-to-seconds - (time-subtract (next-update seconds-ago) - timestamp)) - (round - (time-to-seconds - (time-subtract (next-update seconds-ago) - current-time)))))) - ;; a second earlier the description is the same as at current time - (should (string= at-now at-one-second-before)) - ;; but at the result time it is different - (should-not (string= at-one-second-before at-result))))) + (let* ((timestamp (time-subtract current-time (seconds-to-time seconds-ago))) + (at-now (mastodon-tl--relative-time-description timestamp current-time)) + (at-one-second-before (mastodon-tl--relative-time-description + timestamp + (time-subtract (next-update seconds-ago) + (seconds-to-time 1)))) + (at-result (mastodon-tl--relative-time-description + timestamp + (next-update seconds-ago)))) + (when nil ;; change to t to debug test failures + (prin1 (format "\nFor %s: %s / %s" + seconds-ago + (time-to-seconds + (time-subtract (next-update seconds-ago) + timestamp)) + (round + (time-to-seconds + (time-subtract (next-update seconds-ago) + current-time)))))) + ;; a second earlier the description is the same as at current time + (should (string= at-now at-one-second-before)) + ;; but at the result time it is different + (should-not (string= at-one-second-before at-result))))) (check 0) (check 1) (check 59) @@ -309,10 +309,10 @@ a string or a numeric." (let ((byline (mastodon-tl--byline mastodon-tl-test-base-toot 'mastodon-tl--byline-author 'mastodon-tl--byline-boosted)) - (handle-location 20)) + (handle-location 20)) (should (string= (substring-no-properties - byline) - "Account 42 (@acct42@example.space) 2999-99-99 00:11:22 + byline) + "Account 42 (@acct42@example.space) 2999-99-99 00:11:22 ------------ ")) (should (eq (get-text-property handle-location 'mastodon-tab-stop byline) @@ -407,19 +407,19 @@ a string or a numeric." (mock (format-time-string mastodon-toot-timestamp-format '(3 4)) => "original time") (let ((byline (mastodon-tl--byline toot - 'mastodon-tl--byline-author - 'mastodon-tl--byline-boosted)) - (handle1-location 20) - (handle2-location 65)) + 'mastodon-tl--byline-author + 'mastodon-tl--byline-boosted)) + (handle1-location 20) + (handle2-location 65)) (should (string= (substring-no-properties byline) - "Account 42 (@acct42@example.space) + "Account 42 (@acct42@example.space) Boosted Account 43 (@acct43@example.space) original time ------------ ")) (should (eq (get-text-property handle1-location 'mastodon-tab-stop byline) 'user-handle)) (should (equal (get-text-property handle1-location 'help-echo byline) - "Browse user profile of @acct42@example.space")) + "Browse user profile of @acct42@example.space")) (should (eq (get-text-property handle2-location 'mastodon-tab-stop byline) 'user-handle)) (should (equal (get-text-property handle2-location 'help-echo byline) @@ -819,13 +819,13 @@ constant." (let ((now (current-time)) markers) (cl-labels ((insert-timestamp (n) - (insert (format "\nSome text before timestamp %s:" n)) - (insert (propertize - (format "timestamp #%s" n) - 'timestamp (time-subtract now (seconds-to-time (* 60 n))) - 'display (format "unset %s" n))) - (push (copy-marker (point)) markers) - (insert " some more text."))) + (insert (format "\nSome text before timestamp %s:" n)) + (insert (propertize + (format "timestamp #%s" n) + 'timestamp (time-subtract now (seconds-to-time (* 60 n))) + 'display (format "unset %s" n))) + (push (copy-marker (point)) markers) + (insert " some more text."))) (with-temp-buffer (cl-dotimes (n 12) (insert-timestamp (+ n 2))) (setq markers (nreverse markers)) @@ -883,6 +883,9 @@ constant." (insert "some text before\n") (setq toot-start (point)) (with-mock + (mock (mastodon-profile--get-preferences-pref + 'reading:expand:spoilers) + => :json-false) (stub create-image => '(image "fake data")) (stub shr-render-region => nil) ;; Travis's Emacs doesn't have libxml (insert @@ -892,7 +895,7 @@ constant." (add-text-properties toot-start toot-end (list 'toot-json normal-toot-with-spoiler - 'toot-id (cdr (assoc 'id normal-toot-with-spoiler)))) + 'toot-id (cdr (assoc 'id normal-toot-with-spoiler)))) (goto-char toot-start) ;; (should (eq t (looking-at "This is the spoiler warning text"))) @@ -964,28 +967,28 @@ constant." (ert-deftest mastodon-tl--extract-hashtag-from-url-mastodon-link () "Should extract the hashtag from a tags url." (should (equal (mastodon-tl--extract-hashtag-from-url - "https://example.org/tags/foo" - "https://example.org") - "foo"))) + "https://example.org/tags/foo" + "https://example.org") + "foo"))) (ert-deftest mastodon-tl--extract-hashtag-from-url-other-link () "Should extract the hashtag from a tag url." (should (equal (mastodon-tl--extract-hashtag-from-url - "https://example.org/tag/foo" - "https://example.org") - "foo"))) + "https://example.org/tag/foo" + "https://example.org") + "foo"))) (ert-deftest mastodon-tl--extract-hashtag-from-url-wrong-instance () "Should not find a tag when the instance doesn't match." (should (null (mastodon-tl--extract-hashtag-from-url - "https://example.org/tags/foo" - "https://other.example.org")))) + "https://example.org/tags/foo" + "https://other.example.org")))) (ert-deftest mastodon-tl--extract-hashtag-from-url-not-tag () "Should not find a hashtag when not a tag url" (should (null (mastodon-tl--extract-hashtag-from-url - "https://example.org/@userid" - "https://example.org")))) + "https://example.org/@userid" + "https://example.org")))) (ert-deftest mastodon-tl--userhandles () "Should recognise userhandles in a toot and add the required properties to it." diff --git a/test/mastodon-toot-tests.el b/test/mastodon-toot-tests.el index 0c31029..5b95cdc 100644 --- a/test/mastodon-toot-tests.el +++ b/test/mastodon-toot-tests.el @@ -89,7 +89,7 @@ mention string." (mastodon-instance-url "https://local.social")) (should (string= (mastodon-toot--mentions mastodon-toot-no-mention) "")))) -;; TODO: test y-or-no-p with matodon-toot--cancel +;; TODO: test y-or-no-p with mastodon-toot--cancel (ert-deftest mastodon-toot--kill () "Should kill the buffer when cancelling the toot." (with-mock -- cgit v1.2.3 From 4c254408ed54dbe7a579b3e2cd6be6f26b56d346 Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Mon, 12 Sep 2022 22:02:26 +0200 Subject: fix toot--kill test --- lisp/mastodon-toot.el | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/lisp/mastodon-toot.el b/lisp/mastodon-toot.el index 2f58bfb..5ec58dd 100644 --- a/lisp/mastodon-toot.el +++ b/lisp/mastodon-toot.el @@ -462,14 +462,13 @@ REPLY-ID, TOOT-VISIBILITY, and TOOT-CW of deleted toot are preseved." (defun mastodon-toot--kill (&optional cancel) "Kill `mastodon-toot-mode' buffer and window. CANCEL means the toot was not sent, so we save the toot text as a draft." - (with-current-buffer (get-buffer "*new toot*") - (unless (eq mastodon-toot-current-toot-text nil) - (when cancel - (cl-pushnew mastodon-toot-current-toot-text - mastodon-toot-draft-toots-list :test 'equal))) - ;; prevent some weird bug when cancelling a non-empty toot: - (delete #'mastodon-toot-save-toot-text after-change-functions) - (kill-buffer-and-window))) + (unless (eq mastodon-toot-current-toot-text nil) + (when cancel + (cl-pushnew mastodon-toot-current-toot-text + mastodon-toot-draft-toots-list :test 'equal))) + ;; prevent some weird bug when cancelling a non-empty toot: + (delete #'mastodon-toot-save-toot-text after-change-functions) + (kill-buffer-and-window)) (defun mastodon-toot--cancel () "Kill new-toot buffer/window. Does not POST content to Mastodon. -- cgit v1.2.3 From d73436bd148a8c73c6a63eb65c4026b3dbfa0591 Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Mon, 12 Sep 2022 22:36:58 +0200 Subject: add mock to fix author buffer test and notifs-get --- test/mastodon-notifications-tests.el | 5 ++++- test/mastodon-profile-tests.el | 2 ++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/test/mastodon-notifications-tests.el b/test/mastodon-notifications-tests.el index f5cc4c5..7c87933 100644 --- a/test/mastodon-notifications-tests.el +++ b/test/mastodon-notifications-tests.el @@ -187,7 +187,10 @@ "Ensure get request format for notifictions is accurate." (let ((mastodon-instance-url "https://instance.url")) (with-mock - (mock (mastodon-http--get-json "https://instance.url/api/v1/notifications" )) + (mock (mastodon-http--get-json "https://instance.url/api/v1/notifications")) + (mock (mastodon-profile-fetch-server-account-settings) + => '(max_toot_chars 1312 privacy "public" display_name "Eugen" discoverable t locked :json-false bot :json-false sensitive :json-false language "")) + (mastodon-notifications--get)))) (defun mastodon-notifications--test-type (fun sample) diff --git a/test/mastodon-profile-tests.el b/test/mastodon-profile-tests.el index 817e386..640afb7 100644 --- a/test/mastodon-profile-tests.el +++ b/test/mastodon-profile-tests.el @@ -246,6 +246,8 @@ content generation in the function under test." (mock (shr-render-region * *) => nil) ;; Don't perform the actual update call at the end. ;;(mock (mastodon-tl--timeline *)) + (mock (mastodon-profile-fetch-server-account-settings) + => '(max_toot_chars 1312 privacy "public" display_name "Eugen" discoverable t locked :json-false bot :json-false sensitive :json-false language "")) (let ((mastodon-tl--show-avatars t) (mastodon-tl--display-media-p t) -- cgit v1.2.3 From 179f001697703ec88651a181d18212d17f2b6dd8 Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Mon, 12 Sep 2022 21:34:19 +0200 Subject: factor out http--build-query-string for use PATCH reqs also --- lisp/mastodon-http.el | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/lisp/mastodon-http.el b/lisp/mastodon-http.el index a8b3650..f73fd6b 100644 --- a/lisp/mastodon-http.el +++ b/lisp/mastodon-http.el @@ -73,7 +73,7 @@ "Retrieve URL asynchronously. This is a thin abstraction over the system -`url-retrieve-synchronously`. Depending on which version of this +`url-retrieve-synchronously'. Depending on which version of this is available we will call it with or without a timeout." (if (< (cdr (func-arity 'url-retrieve-synchronously)) 4) (url-retrieve-synchronously url) @@ -108,6 +108,18 @@ Unless UNAUTHENTICATED-P is non-nil." (concat "Bearer " (mastodon-auth--access-token))))))) ,body)) +(defun mastodon-http--build-query-string (args) + "Build a request query string from ARGS." + ;; (url-build-query-string args nil)) + ;; url-build-query-string adds 'nil' to empty params so lets stay with our + ;; own: + (mapconcat (lambda (arg) + (concat (url-hexify-string (car arg)) + "=" + (url-hexify-string (cdr arg)))) + args + "&")) + (defun mastodon-http--post (url args headers &optional unauthenticated-p) "POST synchronously to URL with ARGS and HEADERS. @@ -116,12 +128,7 @@ Authorization header is included by default unless UNAUTHENTICATED-P is non-nil. "POST" (let ((url-request-data (when args - (mapconcat (lambda (arg) - (concat (url-hexify-string (car arg)) - "=" - (url-hexify-string (cdr arg)))) - args - "&"))) + (mastodon-http--build-query-string args))) (url-request-extra-headers (append url-request-extra-headers ; auth set in macro ;; pleroma compat: @@ -216,7 +223,9 @@ Optionally specify the PARAMS to send." Optionally specify the PARAMS to send." (mastodon-http--authorized-request "PATCH" - (let ((url (mastodon-http--append-query-string base-url params))) + (let ((url + (concat base-url "?" + (mastodon-http--build-query-string params)))) (mastodon-http--url-retrieve-synchronously url)))) ;; Asynchronous functions @@ -245,12 +254,7 @@ Authorization header is included by default unless UNAUTHENTICED-P is non-nil." (let ((request-timeout 5) (url-request-data (when args - (mapconcat (lambda (arg) - (concat (url-hexify-string (car arg)) - "=" - (url-hexify-string (cdr arg)))) - args - "&")))) + (mastodon-http--build-query-string args)))) (with-temp-buffer (url-retrieve url callback cbargs))))) -- cgit v1.2.3 From eaaf0b5f5c466d1e998b22f3ae91fc66c50434d8 Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Mon, 12 Sep 2022 21:35:34 +0200 Subject: remove unused --append-query-string --- lisp/mastodon-http.el | 7 ------- 1 file changed, 7 deletions(-) diff --git a/lisp/mastodon-http.el b/lisp/mastodon-http.el index f73fd6b..f32ccd4 100644 --- a/lisp/mastodon-http.el +++ b/lisp/mastodon-http.el @@ -173,13 +173,6 @@ Pass response buffer to CALLBACK function." (with-temp-buffer (mastodon-http--url-retrieve-synchronously url)))) -(defun mastodon-http--append-query-string (url params) - "Append PARAMS to URL as query strings and return it. - -PARAMS should be an alist as required by `url-build-query-string'." - (let ((query-string (url-build-query-string params))) - (concat url "?" query-string))) - ;; search functions: (defun mastodon-http--process-json-search () "Process JSON returned by a search query to the server." -- cgit v1.2.3 From caa5fdc35c50839a12da60f883f94e55af3a1c8b Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Mon, 12 Sep 2022 21:40:22 +0200 Subject: format profile preference params to match toot-send ones --- lisp/mastodon-profile.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/mastodon-profile.el b/lisp/mastodon-profile.el index 38aceae..ff729f0 100644 --- a/lisp/mastodon-profile.el +++ b/lisp/mastodon-profile.el @@ -274,7 +274,7 @@ Both args are strings. SOURCE means that the preference is in the 'source' part of the account JSON." (let* ((url (mastodon-http--api "accounts/update_credentials")) (pref-formatted (if source (concat "source[" pref "]") pref)) - (response (mastodon-http--patch url `((,pref-formatted ,val))))) + (response (mastodon-http--patch url `((,pref-formatted . ,val))))) (mastodon-http--triage response (lambda () (mastodon-profile-fetch-server-account-settings) -- cgit v1.2.3 From 26897d591e96493b2e724a1fe48928e635bad29b Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Tue, 13 Sep 2022 10:13:59 +0200 Subject: proper-list-p test in --process-link to handle meta fields --- lisp/mastodon-tl.el | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lisp/mastodon-tl.el b/lisp/mastodon-tl.el index 8e75705..1df8bae 100644 --- a/lisp/mastodon-tl.el +++ b/lisp/mastodon-tl.el @@ -647,7 +647,9 @@ START and END are the boundaries of the link in the toot." keymap (help-echo (get-text-property start 'help-echo)) extra-properties - (toot-url (mastodon-tl--field 'url toot)) + ;; handle calling this on non-toots, e.g. for profiles: + (toot-url (when (proper-list-p toot) + (mastodon-tl--field 'url toot))) (toot-url (when toot-url (url-generic-parse-url toot-url))) (toot-instance-url (if toot-url (concat (url-type toot-url) "://" -- cgit v1.2.3 From 154d984a7af43b5e0caa9f3df7ca49f0def1dab1 Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Tue, 13 Sep 2022 10:36:32 +0200 Subject: reload thread on delete toot --- lisp/mastodon-tl.el | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lisp/mastodon-tl.el b/lisp/mastodon-tl.el index 1df8bae..4726d29 100644 --- a/lisp/mastodon-tl.el +++ b/lisp/mastodon-tl.el @@ -1702,7 +1702,13 @@ For use after e.g. deleting a toot." (mastodon-notifications--get)) ((equal (mastodon-tl--buffer-name) (concat "*mastodon-" (mastodon-auth--get-account-name) "-statuses*")) - (mastodon-profile--my-profile)))) + (mastodon-profile--my-profile)) + ((save-match-data + (string-match + "statuses/\\(?2:[[:digit:]]+\\)/context" + (mastodon-tl--get-endpoint)) + (mastodon-tl--thread + (match-string 2 (mastodon-tl--get-endpoint))))))) (defun mastodon-tl--more () "Append older toots to timeline, asynchronously." -- cgit v1.2.3 From 2bf81965326040e99b2cc2ba9f1850d1c9868160 Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Tue, 13 Sep 2022 13:00:41 +0200 Subject: another proper-list-p test --- lisp/mastodon-tl.el | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lisp/mastodon-tl.el b/lisp/mastodon-tl.el index 4726d29..158ba5f 100644 --- a/lisp/mastodon-tl.el +++ b/lisp/mastodon-tl.el @@ -668,8 +668,10 @@ START and END are the boundaries of the link in the toot." (;; User handles: maybe-userhandle ;; this fails on mentions in profile notes: - (let ((maybe-userid (mastodon-tl--extract-userid-toot - toot maybe-userhandle))) + (let ((maybe-userid + (when (proper-list-p toot) + (mastodon-tl--extract-userid-toot + toot maybe-userhandle)))) (setq mastodon-tab-stop-type 'user-handle keymap mastodon-tl--link-keymap help-echo (concat "Browse user profile of " maybe-userhandle) -- cgit v1.2.3 From bfc45ff25df938891c317466c3200a86d0585081 Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Mon, 19 Sep 2022 12:04:42 +0200 Subject: add persist dep to mastodon.el file explicitly --- lisp/mastodon.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/mastodon.el b/lisp/mastodon.el index 72043cf..bc624d9 100644 --- a/lisp/mastodon.el +++ b/lisp/mastodon.el @@ -5,7 +5,7 @@ ;; Author: Johnson Denen ;; Maintainer: Marty Hiatt ;; Version: 1.0.0 -;; Package-Requires: ((emacs "27.1") (request "0.3.0")) +;; Package-Requires: ((emacs "27.1") (request "0.3.0") (persist "0.4")) ;; Homepage: https://codeberg.org/martianh/mastodon.el ;; This file is not part of GNU Emacs. -- cgit v1.2.3 From 9420b5ee57eeab7a62297cbf56c37f979c46a02b Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Tue, 20 Sep 2022 14:44:22 +0200 Subject: FIX getting of 'parent-toot properties in mastodon-toot--reply --- lisp/mastodon-toot.el | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lisp/mastodon-toot.el b/lisp/mastodon-toot.el index 79a99ad..076405c 100644 --- a/lisp/mastodon-toot.el +++ b/lisp/mastodon-toot.el @@ -774,7 +774,9 @@ Customize `mastodon-toot-display-orig-in-reply-buffer' to display text of the toot being replied to in the compose buffer." (interactive) (let* ((toot (mastodon-tl--property 'toot-json)) - (parent (mastodon-tl--property 'parent-toot)) ; for new notifs handling + ;; NB: we cannot use mastodon-tl--property for 'parent-toot + ;; because if it doesn't have one, it is fetched from next toot! + (parent (get-text-property (point) 'parent-toot)) ; for new notifs handling (id (mastodon-tl--as-string (mastodon-tl--field 'id (or parent toot)))) (account (mastodon-tl--field 'account toot)) -- cgit v1.2.3 From 020c8efaa235e67aaa07284beae84dd9134fbc90 Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Tue, 20 Sep 2022 14:44:22 +0200 Subject: FIX getting of 'parent-toot properties in mastodon-toot--reply --- lisp/mastodon-toot.el | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lisp/mastodon-toot.el b/lisp/mastodon-toot.el index 076405c..172839c 100644 --- a/lisp/mastodon-toot.el +++ b/lisp/mastodon-toot.el @@ -774,9 +774,7 @@ Customize `mastodon-toot-display-orig-in-reply-buffer' to display text of the toot being replied to in the compose buffer." (interactive) (let* ((toot (mastodon-tl--property 'toot-json)) - ;; NB: we cannot use mastodon-tl--property for 'parent-toot - ;; because if it doesn't have one, it is fetched from next toot! - (parent (get-text-property (point) 'parent-toot)) ; for new notifs handling + (parent (mastodon-tl--field 'parent-toot toot)) ; for new notifs handling (id (mastodon-tl--as-string (mastodon-tl--field 'id (or parent toot)))) (account (mastodon-tl--field 'account toot)) -- cgit v1.2.3 From 0798cf6822733929d571973d2189377ef0a9f849 Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Wed, 21 Sep 2022 16:20:14 +0200 Subject: handle empty relationships vector in make-buffer-for can be empty when doing url-lookup on a mention --- lisp/mastodon-profile.el | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/lisp/mastodon-profile.el b/lisp/mastodon-profile.el index ff729f0..054f6e5 100644 --- a/lisp/mastodon-profile.el +++ b/lisp/mastodon-profile.el @@ -461,10 +461,12 @@ Returns an alist." (mastodon-profile--account-field account 'statuses_count))) (relationships (mastodon-profile--relationships-get id)) - (followed-by-you (alist-get 'following - (aref relationships 0))) - (follows-you (alist-get 'followed_by - (aref relationships 0))) + (followed-by-you (when (not (seq-empty-p relationships)) + (alist-get 'following + (aref relationships 0)))) + (follows-you (when (not (seq-empty-p relationships)) + (alist-get 'followed_by + (aref relationships 0)))) (followsp (or (equal follows-you 't) (equal followed-by-you 't))) (fields (mastodon-profile--fields-get account)) (pinned (mastodon-profile--get-statuses-pinned account))) -- cgit v1.2.3 From c0a267f55f701ef5d7c080e931eb773752f254b5 Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Sat, 15 Oct 2022 22:09:43 +0200 Subject: add emacs 27 to woodpecker --- .woodpecker.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.woodpecker.yml b/.woodpecker.yml index 53952ec..f86e1a4 100644 --- a/.woodpecker.yml +++ b/.woodpecker.yml @@ -2,6 +2,13 @@ pipeline: build: image: silex/emacs:cask commands: + - emacs --version + - cask install + - cask emacs -batch -l test/ert-helper.el -f ert-run-tests-batch-and-exit + build: + image: silex/emacs:27 + commands: + - emacs --version - cask install - cask emacs -batch -l test/ert-helper.el -f ert-run-tests-batch-and-exit -- cgit v1.2.3 From 7dc15fc0966dc048d96aaf9342195dc35dc7ab02 Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Sat, 15 Oct 2022 22:25:43 +0200 Subject: separate pipline names + only CI on main/develop --- .woodpecker.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.woodpecker.yml b/.woodpecker.yml index f86e1a4..df4f222 100644 --- a/.woodpecker.yml +++ b/.woodpecker.yml @@ -1,14 +1,15 @@ pipeline: - build: + current: image: silex/emacs:cask commands: - emacs --version - cask install - cask emacs -batch -l test/ert-helper.el -f ert-run-tests-batch-and-exit - build: - image: silex/emacs:27 + last: + image: silex/emacs:27.1-ci-cask commands: - emacs --version - cask install - cask emacs -batch -l test/ert-helper.el -f ert-run-tests-batch-and-exit ++branches: [ main, develop ] -- cgit v1.2.3 From f324c1cbf71137efa1bd3976c5b56c0ec7f24f47 Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Sat, 15 Oct 2022 22:37:44 +0200 Subject: woodpecker 27 not 27.1 --- .woodpecker.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.woodpecker.yml b/.woodpecker.yml index df4f222..ba2c7b5 100644 --- a/.woodpecker.yml +++ b/.woodpecker.yml @@ -6,7 +6,7 @@ pipeline: - cask install - cask emacs -batch -l test/ert-helper.el -f ert-run-tests-batch-and-exit last: - image: silex/emacs:27.1-ci-cask + image: silex/emacs:27-ci-cask commands: - emacs --version - cask install -- cgit v1.2.3 From e07ccef99359230a88b33360e1a5657a6bf49b33 Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Thu, 27 Oct 2022 12:53:03 +0200 Subject: FIX fetching parent toot in --reply, for notifs --- lisp/mastodon-toot.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/mastodon-toot.el b/lisp/mastodon-toot.el index 172839c..79a99ad 100644 --- a/lisp/mastodon-toot.el +++ b/lisp/mastodon-toot.el @@ -774,7 +774,7 @@ Customize `mastodon-toot-display-orig-in-reply-buffer' to display text of the toot being replied to in the compose buffer." (interactive) (let* ((toot (mastodon-tl--property 'toot-json)) - (parent (mastodon-tl--field 'parent-toot toot)) ; for new notifs handling + (parent (mastodon-tl--property 'parent-toot)) ; for new notifs handling (id (mastodon-tl--as-string (mastodon-tl--field 'id (or parent toot)))) (account (mastodon-tl--field 'account toot)) -- cgit v1.2.3 From 0b7c807612e64fbdb539c39399a1301f3de374ce Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Sat, 29 Oct 2022 12:20:04 +0200 Subject: t = yes, :json-false = no, in instance description display --- lisp/mastodon-tl.el | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/lisp/mastodon-tl.el b/lisp/mastodon-tl.el index 158ba5f..ce5d745 100644 --- a/lisp/mastodon-tl.el +++ b/lisp/mastodon-tl.el @@ -1498,17 +1498,24 @@ IND is the optional indentation level to print at." (mastodon-tl--print-json-keys (cdr el) (if ind (+ ind 4) 4))) (t - (when ind (indent-to ind)) - (insert (mastodon-tl--format-key el pad) - " " - (mastodon-tl--newline-if-long el) - ;; only send strings straight to --render-text - ;; this makes hyperlinks work: - (if (not (stringp (cdr el))) - (mastodon-tl--render-text - (prin1-to-string (cdr el))) - (mastodon-tl--render-text (cdr el))) - "\n"))))))) + ;; basic handling of raw booleans: + (let ((val (cond ((equal (cdr el) ':json-false) + "no") + ((equal (cdr el) 't) + "yes") + (t + (cdr el))))) + (when ind (indent-to ind)) + (insert (mastodon-tl--format-key el pad) + " " + (mastodon-tl--newline-if-long el) + ;; only send strings straight to --render-text + ;; this makes hyperlinks work: + (if (not (stringp val)) + (mastodon-tl--render-text + (prin1-to-string val)) + (mastodon-tl--render-text val)) + "\n")))))))) (defun mastodon-tl--print-instance-rules-or-fields (alist) "Print ALIST of instance rules or contact account fields." -- cgit v1.2.3 From 7b5b03b43f1287462775807f3bc4015473ad38c0 Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Sat, 29 Oct 2022 12:20:25 +0200 Subject: get instance from account/url, so it works for ppl on own instance --- lisp/mastodon-tl.el | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/lisp/mastodon-tl.el b/lisp/mastodon-tl.el index ce5d745..130b01f 100644 --- a/lisp/mastodon-tl.el +++ b/lisp/mastodon-tl.el @@ -1414,13 +1414,12 @@ INSTANCE is an instance domain name." (reblog (alist-get 'reblog toot)) (account (or (alist-get 'account reblog) (alist-get 'account toot))) - (acct (alist-get 'acct account)) + (url (alist-get 'url account)) (username (alist-get 'username account)) - (instance - (concat "https://" - (or instance - (string-remove-prefix (concat username "@") - acct)))) + (instance (if instance + (concat "https://" instance) + (string-remove-suffix (concat "/@" username) + url))) (response (mastodon-http--get-json (if user (mastodon-http--api "instance") -- cgit v1.2.3 From 50bd192c33e018ca207fe6734597786b2c17fc3c Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Sat, 29 Oct 2022 12:34:37 +0200 Subject: Revert "FIX getting of 'parent-toot properties in mastodon-toot--reply" this FIXes the FIX and the other FIX so that it should finally be FIXXXED This reverts commit 020c8efaa235e67aaa07284beae84dd9134fbc90. --- lisp/mastodon-toot.el | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lisp/mastodon-toot.el b/lisp/mastodon-toot.el index 79a99ad..a96bdbf 100644 --- a/lisp/mastodon-toot.el +++ b/lisp/mastodon-toot.el @@ -774,7 +774,10 @@ Customize `mastodon-toot-display-orig-in-reply-buffer' to display text of the toot being replied to in the compose buffer." (interactive) (let* ((toot (mastodon-tl--property 'toot-json)) - (parent (mastodon-tl--property 'parent-toot)) ; for new notifs handling + ;; NB: we cannot use mastodon-tl--property for 'parent-toot + ;; because if it doesn't have one, it is fetched from next toot! + ;; we also cannot use --field because we need to get a different property first + (parent (get-text-property (point) 'parent-toot)) ; for new notifs handling (id (mastodon-tl--as-string (mastodon-tl--field 'id (or parent toot)))) (account (mastodon-tl--field 'account toot)) -- cgit v1.2.3