From 94046d6f392844a44053afc9e6ad3a71e38f011f Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Tue, 25 Nov 2014 22:50:03 +0000 Subject: Implement commenting on anything. --- sx-interaction.el | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) (limited to 'sx-interaction.el') diff --git a/sx-interaction.el b/sx-interaction.el index a9203bd..ad65736 100644 --- a/sx-interaction.el +++ b/sx-interaction.el @@ -106,5 +106,78 @@ changes." ;; Display the changes in `data'. (sx--maybe-update-display)))) + +;;; Commenting +(defun sx-comment (data text) + "Post a comment on DATA given by TEXT. +DATA can be a question, an answer, or a comment. Interactively, +it is guessed from context at point. +If DATA is a comment, the comment is posted as a reply to it. + +TEXT is a string. Interactively, it is read from the minibufer." + (interactive + (list (sx--data-here) 'query)) + (sx-assoc-let data + ;; Get the comment text + (when (eq text 'query) + (setq text (read-string + "Comment text:" + (when .comment_id + (sx--user-@name .author)))) + (while (< (string-width text) 15) + (message "Comments must have more than 15 characters.") + (setq text (read-string "Comment text:" text)))) + ;; If non-interactive, `text' could be anything. + (unless (stringp text) + (error "Comment body must be a string")) + ;; And post + (let ((result + (sx-method-call 'posts + :id (or .post_id .answer_id .question_id) + :submethod "comments/add" + :auth 'warn + :url-method "POST" + :filter sx-browse-filter + :site .site + :keywords `((body ,text))))) + ;; The api returns the new DATA. + (when (> (length result) 0) + (sx--add-comment-to-object + (elt result 0) + (if .post_id + (sx--get-post .post_type .site .post_id) + data)) + ;; Display the changes in `data'. + (sx--maybe-update-display))))) + +(defun sx--get-post (type site id) + "Find in the database a post identified by TYPE, SITE and ID. +TYPE is `question' or `answer'. +SITE is a string. +ID is an integer." + (let ((db (cons sx-question-mode--data + sx-question-list--dataset)))) + (setq db + (cl-case type + (question db) + (answer + (cl-map 'list (lambda (x) (cdr (assoc 'answers x))) + db)))) + (car (cl-member-if + (lambda (x) (sx-assoc-let x + (and (eq .id id) (eq .site site)))) + db))) + +(defun sx--add-comment-to-object (comment object) + "Add COMMENT to OBJECT's `comments' property. +OBJECT can be a question or an answer." + (let ((com-cell (assoc 'comments object)) + (count-cel (assoc 'comment_count object))) + (setcdr + com-cell + (cl-map 'vector #'identity + (cdr cell) (list comment))) + (cl-incf (cdr count-cell)))) + (provide 'sx-interaction) ;;; sx-interaction.el ends here -- cgit v1.2.3 From cbac35d3cb4d8da99034806e22518f023b4883ff Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Tue, 25 Nov 2014 23:59:16 +0000 Subject: new sx--get-post bug --- sx-interaction.el | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'sx-interaction.el') diff --git a/sx-interaction.el b/sx-interaction.el index ad65736..a5b25d1 100644 --- a/sx-interaction.el +++ b/sx-interaction.el @@ -156,27 +156,27 @@ TYPE is `question' or `answer'. SITE is a string. ID is an integer." (let ((db (cons sx-question-mode--data - sx-question-list--dataset)))) - (setq db - (cl-case type - (question db) - (answer - (cl-map 'list (lambda (x) (cdr (assoc 'answers x))) - db)))) - (car (cl-member-if - (lambda (x) (sx-assoc-let x - (and (eq .id id) (eq .site site)))) - db))) + sx-question-list--dataset))) + (setq db + (cl-case type + (question db) + (answer + (cl-map 'list (lambda (x) (cdr (assoc 'answers x))) + db)))) + (car (cl-member-if + (lambda (x) (sx-assoc-let x + (and (eq .id id) (eq .site site)))) + db)))) (defun sx--add-comment-to-object (comment object) "Add COMMENT to OBJECT's `comments' property. OBJECT can be a question or an answer." (let ((com-cell (assoc 'comments object)) - (count-cel (assoc 'comment_count object))) + (count-cell (assoc 'comment_count object))) (setcdr com-cell (cl-map 'vector #'identity - (cdr cell) (list comment))) + (cdr com-cell) (list comment))) (cl-incf (cdr count-cell)))) (provide 'sx-interaction) -- cgit v1.2.3 From 26f140c4a9b4aa4a76586cd9f4531afbbdfb5f42 Mon Sep 17 00:00:00 2001 From: Artur Malabarba Date: Wed, 26 Nov 2014 00:47:46 +0000 Subject: Several bug fixes to commenting logic. --- sx-interaction.el | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) (limited to 'sx-interaction.el') diff --git a/sx-interaction.el b/sx-interaction.el index a5b25d1..404fb56 100644 --- a/sx-interaction.el +++ b/sx-interaction.el @@ -121,12 +121,11 @@ TEXT is a string. Interactively, it is read from the minibufer." ;; Get the comment text (when (eq text 'query) (setq text (read-string - "Comment text:" + "Comment text: " (when .comment_id - (sx--user-@name .author)))) + (sx--user-@name .owner)))) (while (< (string-width text) 15) - (message "Comments must have more than 15 characters.") - (setq text (read-string "Comment text:" text)))) + (setq text (read-string "Comment text (at least 15 characters): " text)))) ;; If non-interactive, `text' could be anything. (unless (stringp text) (error "Comment body must be a string")) @@ -158,14 +157,15 @@ ID is an integer." (let ((db (cons sx-question-mode--data sx-question-list--dataset))) (setq db - (cl-case type - (question db) - (answer - (cl-map 'list (lambda (x) (cdr (assoc 'answers x))) - db)))) + (cond + ((string= type "question") db) + ((string= type "answer") + (apply #'cl-map 'list #'identity + (mapcar (lambda (x) (cdr (assoc 'answers x))) db))))) (car (cl-member-if (lambda (x) (sx-assoc-let x - (and (eq .id id) (eq .site site)))) + (and (equal (or .answer_id .question_id) id) + (equal .site site)))) db)))) (defun sx--add-comment-to-object (comment object) @@ -173,11 +173,18 @@ ID is an integer." OBJECT can be a question or an answer." (let ((com-cell (assoc 'comments object)) (count-cell (assoc 'comment_count object))) - (setcdr - com-cell - (cl-map 'vector #'identity - (cdr com-cell) (list comment))) - (cl-incf (cdr count-cell)))) + (if com-cell + (progn + (setcdr + com-cell + (apply #'vector + (append + (cl-map 'list #'identity + (cdr com-cell)) + (list comment))))) + ;; No previous comments, add it manually. + (setcdr object (cons (car object) (cdr object))) + (setcar object `(comments . [,comment]))))) (provide 'sx-interaction) ;;; sx-interaction.el ends here -- cgit v1.2.3