From 1e4a661df8b3e07847e9d368f41fa775bf3442a7 Mon Sep 17 00:00:00 2001 From: Dmitry Osipov Date: Mon, 28 Nov 2022 15:33:37 +0100 Subject: Remove double white-space in the reply mode When you start a reply (to a local user or federated), there's one extra white-space after the list of mentioned users: `@user1@host.local @user2@host.federated__` (the underscores represent white-spaces). This PR removes the extra space. --- lisp/mastodon-toot.el | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'lisp/mastodon-toot.el') diff --git a/lisp/mastodon-toot.el b/lisp/mastodon-toot.el index 121a590..c19f8e3 100644 --- a/lisp/mastodon-toot.el +++ b/lisp/mastodon-toot.el @@ -808,10 +808,10 @@ eg. \"user\" -> \"user@local.social \" (when local.social is the domain of the mastodon-instance-url). eg. \"yourusername\" -> \"\" eg. \"feduser@fed.social\" -> \"feduser@fed.social\"." - (cond ((string-match-p "@" acct) (concat "@" acct " ")) ; federated acct + (cond ((string-match-p "@" acct) (concat "@" acct)) ; federated acct ((string= (mastodon-auth--user-acct) acct) "") ; your acct (t (concat "@" acct "@" ; local acct - (cadr (split-string mastodon-instance-url "/" t)) " ")))) + (cadr (split-string mastodon-instance-url "/" t)))))) (defun mastodon-toot--mentions (status) "Extract mentions from STATUS and process them into a string." @@ -821,11 +821,11 @@ eg. \"feduser@fed.social\" -> \"feduser@fed.social\"." (if boosted (alist-get 'mentions (alist-get 'reblog status)) (alist-get 'mentions status)))) - (mapconcat (lambda(x) (mastodon-toot--process-local + (string-trim (mapconcat (lambda(x) (mastodon-toot--process-local (alist-get 'acct x))) ;; reverse does not work on vectors in 24.5 (reverse (append mentions nil)) - ""))) + " ")))) (defun mastodon-toot--get-bounds (regex) "Get bounds of tag or handle before point using REGEX." -- cgit v1.2.3 From 5dddfbe7ca90cfb0026dfadc24f98703f0e6c661 Mon Sep 17 00:00:00 2001 From: Dmitry Osipov Date: Thu, 1 Dec 2022 10:54:10 +0100 Subject: Move mentions concatenation into a function for a reply. --- lisp/mastodon-toot.el | 47 +++++++++++++++++++++++---------------------- test/mastodon-toot-tests.el | 33 +++++++++++++++++++++++++------ 2 files changed, 51 insertions(+), 29 deletions(-) (limited to 'lisp/mastodon-toot.el') diff --git a/lisp/mastodon-toot.el b/lisp/mastodon-toot.el index c19f8e3..c1d3ffa 100644 --- a/lisp/mastodon-toot.el +++ b/lisp/mastodon-toot.el @@ -800,11 +800,19 @@ Buffer-local variable `mastodon-toot-previous-window-config' holds the config." (set-window-configuration (car config)) (goto-char (cadr config))) +(defun mastodon-toot--mentions-to-string (mentions) + "Applies mastodon-toot--process-local function to each mention, +removes empty string (self) from result and joins the sequence with \" \"." + (mapconcat (lambda(mention) mention) + (remove "" (mapcar (lambda(x) (mastodon-toot--process-local x)) + mentions)) + " ")) + (defun mastodon-toot--process-local (acct) "Add domain to local ACCT and replace the curent user name with \"\". Mastodon requires the full user@domain, even in the case of local accts. -eg. \"user\" -> \"user@local.social \" (when local.social is the domain of the +eg. \"user\" -> \"user@local.social\" (when local.social is the domain of the mastodon-instance-url). eg. \"yourusername\" -> \"\" eg. \"feduser@fed.social\" -> \"feduser@fed.social\"." @@ -814,19 +822,17 @@ eg. \"feduser@fed.social\" -> \"feduser@fed.social\"." (cadr (split-string mastodon-instance-url "/" t)))))) (defun mastodon-toot--mentions (status) - "Extract mentions from STATUS and process them into a string." + "Extract mentions (not the reply-to author or booster) from STATUS and process them into a string." (interactive) (let* ((boosted (mastodon-tl--field 'reblog status)) (mentions (if boosted - (alist-get 'mentions (alist-get 'reblog status)) - (alist-get 'mentions status)))) - (string-trim (mapconcat (lambda(x) (mastodon-toot--process-local - (alist-get 'acct x))) - ;; reverse does not work on vectors in 24.5 - (reverse (append mentions nil)) - " ")))) - + (alist-get 'mentions (alist-get 'reblog status)) + (alist-get 'mentions status)))) + ;; reverse does not work on vectors in 24.5 + (mapcar (lambda(x) (alist-get 'acct x)) + (reverse mentions)))) + (defun mastodon-toot--get-bounds (regex) "Get bounds of tag or handle before point using REGEX." ;; needed because # and @ are not part of any existing thing at point @@ -917,26 +923,21 @@ text of the toot being replied to in the compose buffer." (mastodon-toot (when user (if booster (if (and (not (equal user booster)) - (not (string-match booster mentions))) + (not (member booster mentions))) ;; different booster, user and mentions: - (concat (mastodon-toot--process-local user) - ;; "@" booster " " - (mastodon-toot--process-local booster) - mentions) + (mastodon-toot--mentions-to-string (append (list user booster) mentions nil)) ;; booster is either user or in mentions: - (if (not (string-match user mentions)) + (if (not (member user mentions)) ;; user not already in mentions: - (concat (mastodon-toot--process-local user) - mentions) + (mastodon-toot--mentions-to-string (append (list user) mentions nil)) ;; user already in mentions: - mentions)) + (mastodon-toot--mentions-to-string (copy-sequence mentions)))) ;; ELSE no booster: - (if (not (string-match user mentions)) + (if (not (member user mentions)) ;; user not in mentions: - (concat (mastodon-toot--process-local user) - mentions) + (mastodon-toot--mentions-to-string (append (list user) mentions nil)) ;; user in mentions already: - mentions))) + (mastodon-toot--mentions-to-string (copy-sequence mentions))))) id (or base-toot toot)))) diff --git a/test/mastodon-toot-tests.el b/test/mastodon-toot-tests.el index 5d4ef03..69333c0 100644 --- a/test/mastodon-toot-tests.el +++ b/test/mastodon-toot-tests.el @@ -56,21 +56,33 @@ Transfer-Encoding: chunked") (username . "local") (url . "") (acct . "local"))]))) - (defconst mastodon-toot-no-mention '((mentions . []))) +(defconst mastodon-toot--multi-mention-extracted + '("local" "federated@federated.social" "federated@federated.cafe")) + (ert-deftest mastodon-toot--multi-mentions () "Should build a correct mention string from the test toot data. Even the local name \"local\" gets a domain name added." (let ((mastodon-auth--acct-alist '(("https://local.social". "null"))) (mastodon-instance-url "https://local.social")) - (should (string= + (should (equal (mastodon-toot--mentions mastodon-toot--multi-mention) + '("local" "federated@federated.social" "federated@federated.cafe"))))) + +(ert-deftest mastodon-toot--multi-mentions-to-string () + "Should build a correct mention string from the test toot data. + +Even the local name \"local\" gets a domain name added." + (let ((mastodon-auth--acct-alist '(("https://local.social". "null"))) + (mastodon-instance-url "https://local.social")) + (should (string= + (mastodon-toot--mentions-to-string mastodon-toot--multi-mention-extracted) "@local@local.social @federated@federated.social @federated@federated.cafe")))) -(ert-deftest mastodon-toot--multi-mentions-with-name () +(ert-deftest mastodon-toot--multi-mentions-with-name-to-string () "Should build a correct mention string omitting self. Here \"local\" is the user themselves and gets omitted from the @@ -79,15 +91,24 @@ mention string." '(("https://local.social". "local"))) (mastodon-instance-url "https://local.social")) (should (string= - (mastodon-toot--mentions mastodon-toot--multi-mention) + (mastodon-toot--mentions-to-string mastodon-toot--multi-mention-extracted) "@federated@federated.social @federated@federated.cafe")))) +(ert-deftest mastodon-toot--no-mention-to-string () + "Should return and empty string." + (let ((mastodon-auth--acct-alist + '(("https://local.social". "local"))) + (mastodon-instance-url "https://local.social")) + (should (string= + (mastodon-toot--mentions-to-string nil) + "")))) + (ert-deftest mastodon-toot--no-mention () - "Should construct an empty mention string without mentions." + "Should construct an empty mention list without mentions." (let ((mastodon-auth--acct-alist '(("https://local.social". "null"))) (mastodon-instance-url "https://local.social")) - (should (string= (mastodon-toot--mentions mastodon-toot-no-mention) "")))) + (should (equal (mastodon-toot--mentions mastodon-toot-no-mention) nil)))) ;; TODO: test y-or-no-p with mastodon-toot--cancel (ert-deftest mastodon-toot--kill () -- cgit v1.2.3 From 548b10fdfa19df91419b8c4f4b5812f189f7294d Mon Sep 17 00:00:00 2001 From: Dmitry Osipov Date: Thu, 1 Dec 2022 21:21:41 +0100 Subject: Update docstrings to match the current state. --- lisp/mastodon-toot.el | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'lisp/mastodon-toot.el') diff --git a/lisp/mastodon-toot.el b/lisp/mastodon-toot.el index c1d3ffa..feac7b5 100644 --- a/lisp/mastodon-toot.el +++ b/lisp/mastodon-toot.el @@ -802,7 +802,7 @@ Buffer-local variable `mastodon-toot-previous-window-config' holds the config." (defun mastodon-toot--mentions-to-string (mentions) "Applies mastodon-toot--process-local function to each mention, -removes empty string (self) from result and joins the sequence with \" \"." +removes empty string (self) from result and joins the sequence with whitespace \" \"." (mapconcat (lambda(mention) mention) (remove "" (mapcar (lambda(x) (mastodon-toot--process-local x)) mentions)) @@ -811,18 +811,21 @@ removes empty string (self) from result and joins the sequence with \" \"." (defun mastodon-toot--process-local (acct) "Add domain to local ACCT and replace the curent user name with \"\". -Mastodon requires the full user@domain, even in the case of local accts. -eg. \"user\" -> \"user@local.social\" (when local.social is the domain of the +Mastodon requires the full @user@domain, even in the case of local accts. +eg. \"user\" -> \"@user@local.social\" (when local.social is the domain of the mastodon-instance-url). eg. \"yourusername\" -> \"\" -eg. \"feduser@fed.social\" -> \"feduser@fed.social\"." +eg. \"feduser@fed.social\" -> \"@feduser@fed.social\"." (cond ((string-match-p "@" acct) (concat "@" acct)) ; federated acct ((string= (mastodon-auth--user-acct) acct) "") ; your acct (t (concat "@" acct "@" ; local acct (cadr (split-string mastodon-instance-url "/" t)))))) (defun mastodon-toot--mentions (status) - "Extract mentions (not the reply-to author or booster) from STATUS and process them into a string." + "Extract mentions (not the reply-to author or booster) from STATUS. +The mentioned users look like this: +Local user (including the logged in): `username`. +Federated user: `username@host.co`." (interactive) (let* ((boosted (mastodon-tl--field 'reblog status)) (mentions -- cgit v1.2.3 From 8db62b46a141dc862cee6e90afc935964a55b9d4 Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Fri, 2 Dec 2022 11:58:35 +0100 Subject: update comment re completion fetching --- lisp/mastodon-toot.el | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'lisp/mastodon-toot.el') diff --git a/lisp/mastodon-toot.el b/lisp/mastodon-toot.el index 8d8bfc2..a394b00 100644 --- a/lisp/mastodon-toot.el +++ b/lisp/mastodon-toot.el @@ -881,10 +881,8 @@ eg. \"feduser@fed.social\" -> \"feduser@fed.social\"." "Search for a completion prefix from buffer positions START to END. Return a list of candidates. If TAGS, we search for tags, else we search for handles." - ;; FIXME: can we save the first two-letter search then only filter the - ;; resulting list? - ;; (or mastodon-toot-completions - ;; would work if we could null that var upon completion success + ;; we can't save the first two-letter search then only filter the + ;; resulting list, as max results returned is 40. (setq mastodon-toot-completions (if tags (let ((tags-list (mastodon-search--search-tags-query -- cgit v1.2.3 From fabe373dedeae535726434527870e65496044e58 Mon Sep 17 00:00:00 2001 From: Sacha Chua Date: Thu, 8 Dec 2022 09:13:16 -0500 Subject: Use mastodon-toot--count-toot-chars when validating toot length * lisp/mastodon-toot.el (mastodon-toot--send): Use mastodon-toot--count-toot-chars instead of length. --- lisp/mastodon-toot.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lisp/mastodon-toot.el') diff --git a/lisp/mastodon-toot.el b/lisp/mastodon-toot.el index a394b00..c87b3bb 100644 --- a/lisp/mastodon-toot.el +++ b/lisp/mastodon-toot.el @@ -738,7 +738,7 @@ instance to edit a toot." (length mastodon-toot--media-attachment-ids))))) (message "Something is wrong with your uploads. Wait for them to complete or try again.")) ((and mastodon-toot--max-toot-chars - (> (length toot) mastodon-toot--max-toot-chars)) + (> (mastodon-toot--count-toot-chars toot) mastodon-toot--max-toot-chars)) (message "Looks like your toot is longer than that maximum allowed length.")) ((mastodon-toot--empty-p) (message "Empty toot. Cowardly refusing to post this.")) -- cgit v1.2.3 From e494fb8d507311de8452db3e6f111b1e32cc3c4d Mon Sep 17 00:00:00 2001 From: Bas Alberts Date: Thu, 22 Dec 2022 11:01:24 -0500 Subject: fix for custom emoji path traversal --- lisp/mastodon-toot.el | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) (limited to 'lisp/mastodon-toot.el') diff --git a/lisp/mastodon-toot.el b/lisp/mastodon-toot.el index c87b3bb..06c49a3 100644 --- a/lisp/mastodon-toot.el +++ b/lisp/mastodon-toot.el @@ -610,13 +610,19 @@ To use the downloaded emoji, run `mastodon-toot--enable-custom-emoji'." (unless (file-directory-p mastodon-custom-emoji-dir) (make-directory mastodon-custom-emoji-dir nil)) ; no add parent (mapc (lambda (x) - (url-copy-file (alist-get 'url x) - (concat - mastodon-custom-emoji-dir - (alist-get 'shortcode x) - "." - (file-name-extension (alist-get 'url x))) - t)) + (let ((url (alist-get 'url x)) + (shortcode (alist-get 'shortcode x))) + ;; skip anything that contains unexpected characters + (when (and url shortcode + (string-match-p "^[a-zA-Z0-9-_]*$" shortcode) + (string-match-p "^[a-zA-Z]*$" (file-name-extension url))) + (url-copy-file url + (concat + mastodon-custom-emoji-dir + shortcode + "." + (file-name-extension url)) + t)))) custom-emoji) (message "Custom emoji for %s downloaded to %s" mastodon-instance-url -- cgit v1.2.3 From 0114d8a43161ed8bf90e988d9125af4ae6e61165 Mon Sep 17 00:00:00 2001 From: Bas Alberts Date: Thu, 22 Dec 2022 22:43:23 -0500 Subject: further harden custom emoji regex filtering Prevent empty string shortcodes from creating dotfiles inside the custom emoji download dir to prevent e.g. ".envrc" and other such contextual dotfiles from being created in the legitimate download location. --- lisp/mastodon-toot.el | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lisp/mastodon-toot.el') diff --git a/lisp/mastodon-toot.el b/lisp/mastodon-toot.el index 06c49a3..d1e8cbe 100644 --- a/lisp/mastodon-toot.el +++ b/lisp/mastodon-toot.el @@ -614,8 +614,8 @@ To use the downloaded emoji, run `mastodon-toot--enable-custom-emoji'." (shortcode (alist-get 'shortcode x))) ;; skip anything that contains unexpected characters (when (and url shortcode - (string-match-p "^[a-zA-Z0-9-_]*$" shortcode) - (string-match-p "^[a-zA-Z]*$" (file-name-extension url))) + (string-match-p "^[a-zA-Z0-9-_]+$" shortcode) + (string-match-p "^[a-zA-Z]+$" (file-name-extension url))) (url-copy-file url (concat mastodon-custom-emoji-dir -- cgit v1.2.3 From 017f9a8a8986b0cd5bca5d58f398f310048dab09 Mon Sep 17 00:00:00 2001 From: Toke Høiland-Jørgensen Date: Fri, 16 Dec 2022 16:54:06 +0100 Subject: Only add scheduled_at parameter to toot params when non-nil MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Pleroma server software can't handle the scheduled_at parameter being set to anything other than a valid datetime, even an empty value. To work around this, change mastodon-toot--send to only add the parameter to the list of args if its non-nil. Signed-off-by: Toke Høiland-Jørgensen --- lisp/mastodon-toot.el | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) (limited to 'lisp/mastodon-toot.el') diff --git a/lisp/mastodon-toot.el b/lisp/mastodon-toot.el index eab0dfd..c18f751 100644 --- a/lisp/mastodon-toot.el +++ b/lisp/mastodon-toot.el @@ -703,6 +703,8 @@ instance to edit a toot." (interactive) (let* ((edit-p (if mastodon-toot--edit-toot-id t nil)) (toot (mastodon-toot--remove-docs)) + (scheduled mastodon-toot--scheduled-for) + (scheduled-id mastodon-toot--scheduled-id) (endpoint (if edit-p ;; we are sending an edit: @@ -713,14 +715,16 @@ instance to edit a toot." mastodon-toot--content-warning) (read-string "Warning: " mastodon-toot--content-warning-from-reply-or-redraft))) - (args-no-media `(("status" . ,toot) - ("in_reply_to_id" . ,mastodon-toot--reply-to-id) - ("visibility" . ,mastodon-toot--visibility) - ("sensitive" . ,(when mastodon-toot--content-nsfw - (symbol-name t))) - ("spoiler_text" . ,spoiler) - ("language" . ,mastodon-toot--language) - ("scheduled_at" . ,mastodon-toot--scheduled-for))) + (args-no-media (append `(("status" . ,toot) + ("in_reply_to_id" . ,mastodon-toot--reply-to-id) + ("visibility" . ,mastodon-toot--visibility) + ("sensitive" . ,(when mastodon-toot--content-nsfw + (symbol-name t))) + ("spoiler_text" . ,spoiler) + ("language" . ,mastodon-toot--language)) + ; Pleroma instances can't handle null-valued + ; scheduled_at args, so only add if non-nil + (when scheduled `(("scheduled_at" . ,scheduled))))) (args-media (when mastodon-toot--media-attachments (mastodon-http--build-array-params-alist "media_ids[]" @@ -733,9 +737,7 @@ instance to edit a toot." (if mastodon-toot-poll (append args-no-media args-poll) args-no-media))) - (prev-window-config mastodon-toot-previous-window-config) - (scheduled mastodon-toot--scheduled-for) - (scheduled-id mastodon-toot--scheduled-id)) + (prev-window-config mastodon-toot-previous-window-config)) (cond ((and mastodon-toot--media-attachments ;; make sure we have media args ;; and the same num of ids as attachments -- cgit v1.2.3