about summary refs log tree commit diff
path: root/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-search.el
diff options
context:
space:
mode:
Diffstat (limited to 'configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-search.el')
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-search.el418
1 files changed, 418 insertions, 0 deletions
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-search.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-search.el
new file mode 100644
index 000000000000..2bea54ccc996
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-search.el
@@ -0,0 +1,418 @@
+;;; slack-search.el ---                              -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2016  南優也
+
+;; Author: 南優也 <yuyaminami@minamiyuunari-no-MacBook-Pro.local>
+;; Keywords:
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'eieio)
+(require 'slack-room)
+(require 'slack-request)
+
+(defface slack-search-result-message-header-face
+  '((t (:weight bold :height 1.1 :underline t)))
+  "Face used to search message header."
+  :group 'slack)
+;; (:inherit (markdown-code-face font-lock-constant-face))
+(defface slack-search-result-message-username-face
+  '((t (:inherit slack-message-output-header :underline nil)))
+  ""
+  :group 'slack)
+
+(defclass slack-search-paging ()
+  ((count :initarg :count :type number)
+   (total :initarg :total :type number)
+   (page :initarg :page :type number)
+   (pages :initarg :pages :type number)))
+
+(defclass slack-search-result (slack-room)
+  ((query :initarg :query :type string)
+   (sort :initarg :sort :type string)
+   (sort-dir :initarg :sort-dir :type string)
+   (total :initarg :total :type number)
+   (matches :initarg :matches :initform nil :type (or null list))
+   (paging :initarg :paging :type slack-search-paging)))
+
+(defclass slack-file-search-result (slack-search-result) ())
+
+(defclass slack-search-message ()
+  ((message :initarg :message :type slack-message)
+
+   (channel :initarg :channel :type slack-search-message-channel)
+   (user :initarg :user :type string)
+   (username :initarg :username :type string)
+   (permalink :initarg :permalink :type string)
+
+   (previous-2 :initarg :previous-2 :type (or null slack-search-message-around-message) :initform nil)
+   (previous :initarg :previous :type (or null slack-search-message-around-message) :initform nil)
+   (next :initarg :next :type (or null slack-search-message-around-message) :initform nil)
+   (next-2 :initarg :next-2 :type (or null slack-search-message-around-message) :initform nil)))
+
+(defclass slack-search-message-channel ()
+  ((id :initarg :id :type string)
+   (name :initarg :name :type string)))
+
+(defclass slack-search-message-around-message ()
+  ((user :initarg :user :type string)
+   (username :initarg :username :type string)
+   (text :initarg :text :type string)
+   (ts :initarg :ts :type string)
+   (type :initarg :type :type string)))
+
+(defmethod slack-merge ((this slack-search-result) other)
+  (oset this query (oref other query))
+  (oset this sort (oref other sort))
+  (oset this sort-dir (oref other sort-dir))
+  (oset this total (oref other total))
+  (oset this matches (append (oref this matches) (oref other matches)))
+  (oset this paging (oref other paging)))
+
+(defmethod slack-message-to-string ((this slack-search-message) team)
+  (with-slots (channel username) this
+    (let* ((room (slack-room-find (oref channel id) team))
+           (header (propertize (format "%s%s"
+                                       (if (slack-channel-p room)
+                                           "#" "@")
+                                       (slack-room-name room))
+                               'face 'slack-search-result-message-header-face)))
+      (propertize (format "%s\n%s"
+                          header
+                          (slack-message-to-string (oref this message) team))
+                  'ts (slack-ts this)))))
+
+(defmethod slack-ts ((this slack-search-message))
+  (slack-ts (oref this message)))
+
+(defmethod slack-search-has-next-page-p ((this slack-search-result))
+  (slack-search-paging-next-page (oref this paging)))
+
+(defmethod slack-search-paging-next-page ((this slack-search-paging))
+  (with-slots (pages page) this
+    (unless (< pages (1+ page))
+      (1+ page))))
+
+(defun slack-search-create-message-channel (payload)
+  (and payload
+       (make-instance 'slack-search-message-channel
+                      :id (plist-get payload :id)
+                      :name (plist-get payload :name))))
+
+(defun slack-search-create-around-message (payload)
+  (and payload
+       (make-instance 'slack-search-message-around-message
+                      :user (plist-get payload :user)
+                      :username (plist-get payload :username)
+                      :text (plist-get payload :text)
+                      :ts (plist-get payload :ts)
+                      :type (plist-get payload :type))))
+
+(defun slack-search-create-message (payload team)
+  (setq payload (append payload nil))
+  (let* ((channel (slack-search-create-message-channel
+                   (plist-get payload :channel)))
+         (previous-2 (slack-search-create-around-message
+                      (plist-get payload :previous_2)))
+         (previous (slack-search-create-around-message
+                    (plist-get payload :previous)))
+         (next (slack-search-create-around-message
+                (plist-get payload :next)))
+         (next-2 (slack-search-create-around-message
+                  (plist-get payload :next_2)))
+         (room (slack-room-find (oref channel id) team)))
+
+    (unless (< 0 (length (plist-get payload :user)))
+      (plist-put payload :user nil)
+      (plist-put payload :subtype "bot_message"))
+
+    (make-instance 'slack-search-message
+                   :message (slack-message-create payload team :room room)
+                   :channel channel
+                   :previous-2 previous-2
+                   :previous previous
+                   :next next
+                   :next-2 next-2)))
+
+(defun slack-search-create-paging (payload)
+  (and payload
+       (make-instance 'slack-search-paging
+                      :count (plist-get payload :count)
+                      :total (plist-get payload :total)
+                      :page (plist-get payload :page)
+                      :pages (plist-get payload :pages))))
+
+(defun slack-search-create-result (payload sort sort-dir team)
+  (let* ((messages (plist-get payload :messages))
+         (matches (mapcar #'(lambda (e) (slack-search-create-message e team))
+                          (plist-get messages :matches)))
+         (paging (slack-search-create-paging
+                  (plist-get messages :paging))))
+    (make-instance 'slack-search-result
+                   :query (plist-get payload :query)
+                   :total (plist-get messages :total)
+                   :paging paging
+                   :matches matches
+                   :sort sort
+                   :sort-dir sort-dir)))
+
+(defun slack-search-create-file-result (payload sort sort-dir)
+  (let* ((files (plist-get payload :files))
+         (matches (mapcar #'slack-file-create
+                          (plist-get files :matches)))
+         (paging (slack-search-create-paging
+                  (plist-get files :paging))))
+    (make-instance 'slack-search-result
+                   :query (plist-get payload :query)
+                   :total (plist-get files :total)
+                   :paging paging
+                   :matches matches
+                   :sort sort
+                   :sort-dir sort-dir)))
+
+(defun slack-search-query-params ()
+  (let ((team (slack-team-select))
+        (query (read-from-minibuffer "Query: "))
+        (sort (funcall slack-completing-read-function "Sort: " `("score" "timestamp")
+                       nil t))
+        (sort-dir (funcall slack-completing-read-function "Direction: " `("desc" "asc")
+                           nil t)))
+    (list team query sort sort-dir)))
+
+(defun slack-search-from-messages ()
+  (interactive)
+  (cl-destructuring-bind (team query sort sort-dir) (slack-search-query-params)
+    (let ((instance (make-instance 'slack-search-result
+                                   :sort sort
+                                   :sort-dir sort-dir
+                                   :query query)))
+      (cl-labels
+          ((after-success ()
+                          (let ((buffer (slack-create-search-result-buffer instance team)))
+                            (slack-buffer-display buffer))))
+        (slack-search-request instance #'after-success team)))))
+
+(defun slack-search-from-files ()
+  (interactive)
+  (cl-destructuring-bind (team query sort sort-dir) (slack-search-query-params)
+    (let ((instance (make-instance 'slack-file-search-result
+                                   :sort sort
+                                   :sort-dir sort-dir
+                                   :query query)))
+      (cl-labels
+          ((after-success ()
+                          (let ((buffer (slack-create-search-result-buffer instance team)))
+                            (slack-buffer-display buffer))))
+        (slack-search-request instance #'after-success team)))))
+
+(defmethod slack-search-request-url ((_this slack-search-result))
+  "https://slack.com/api/search.messages")
+
+(defmethod slack-search-request-url ((_this slack-file-search-result))
+  "https://slack.com/api/search.files")
+
+(cl-defmethod slack-search-request ((this slack-search-result)
+                                    after-success team &optional (page 1))
+  (cl-labels
+      ((on-success (&key data &allow-other-keys)
+                   (slack-request-handle-error
+                    (data "slack-search-request")
+                    (let ((search-result
+                           (if (slack-file-search-result-p this)
+                               (slack-search-create-file-result data
+                                                                (oref this sort)
+                                                                (oref this sort-dir))
+                             (slack-search-create-result data
+                                                         (oref this sort)
+                                                         (oref this sort-dir)
+                                                         team))))
+                      (slack-merge this search-result)
+                      (funcall after-success)))))
+    (with-slots (query sort sort-dir) this
+      (if (< 0 (length query))
+          (slack-request
+           (slack-request-create
+            (slack-search-request-url this)
+            team
+            :type "POST"
+            :params (list (cons "query" query)
+                          (cons "sort" sort)
+                          (cons "sort_dir" sort-dir)
+                          (cons "page" (number-to-string page)))
+            :success #'on-success))))))
+
+;; (defun slack-search-alist (team)
+;;   (with-slots (search-results) team
+;;     (cl-loop for s in search-results
+;;              collect (cons (slack-room-buffer-name s) s))))
+
+;; (defun slack-search-select ()
+;;   (interactive)
+;;   (let* ((team (slack-team-select))
+;;          (alist (slack-search-alist team)))
+;;     (slack-select-from-list
+;;         (alist "Select Search: ")
+;;         (funcall slack-buffer-function (slack-buffer-create selected team)))))
+
+;; protocols
+;; (defmethod slack-room-sorted-messages ((room slack-search-result))
+;;   (copy-sequence (oref room messages)))
+
+;; (defmethod slack-room-update-last-read ((room slack-search-result) msg)
+;;   (if (not (slot-exists-p msg 'info))
+;;       (progn
+;;         (oset room last-read (oref msg ts))
+;;         (oset room last-channel-id ""))
+;;     (with-slots (ts info) msg
+;;       (with-slots (channel-id) info
+;;         (when (slack-room-update-last-read-p room ts)
+;;           (oset room last-read ts)
+;;           (oset room last-channel-id channel-id))))))
+
+;; (defmethod slack-search-get-index ((_search-result slack-file-search-result)
+;;                                    messages last-read &optional _last-chanel-id)
+;;   (cl-loop for i from 0 upto (1- (length messages))
+;;            for m = (nth i messages)
+;;            if (string= (oref m ts) last-read)
+;;            return i))
+
+;; (defmethod slack-search-get-index ((_search-result slack-search-result)
+;;                                    messages last-read &optional last-channel-id)
+;;   (cl-loop for i from 0 upto (1- (length messages))
+;;            for m = (nth i messages)
+;;            if (and (string= (oref m ts) last-read)
+;;                    (string= (oref (oref m info) channel-id)
+;;                             last-channel-id))
+;;            return i))
+
+;; (defmethod slack-room-latest-messages ((room slack-search-result) messages)
+;;   (with-slots (type last-read last-channel-id) room
+;;     (let* ((r-messages (reverse messages))
+;;            (nth (slack-search-get-index room r-messages
+;;                                         last-read last-channel-id)))
+;;       (if nth
+;;           (nreverse
+;;            (nthcdr (1+ nth) r-messages))
+;;         (copy-sequence messages)))))
+
+;; (defmethod slack-room-prev-messages ((room slack-file-search-result) oldest)
+;;   (let* ((messages (reverse (oref room messages)))
+;;          (nth (slack-search-get-index room messages oldest)))
+;;     (if nth
+;;         (nreverse (nthcdr (1+ nth) messages)))))
+
+;; (defmethod slack-room-prev-messages ((room slack-search-result) param)
+;;   (let* ((oldest (car param))
+;;          (channel-id (cdr param))
+;;          (messages (reverse (oref room messages)))
+;;          (nth (slack-search-get-index room messages
+;;                                       oldest channel-id)))
+;;     (if nth
+;;         (nreverse (nthcdr (1+ nth) messages)))))
+
+;; (defmethod slack-message-equal ((m slack-search-message) n)
+;;   (with-slots ((m-info info) (m-ts ts)) m
+;;     (with-slots ((m-channel-id channel-id)) m-info
+;;       (with-slots ((n-info info) (n-ts ts)) n
+;;         (with-slots ((n-channel-id channel-id)) n-info
+;;           (and (string= m-channel-id n-channel-id)
+;;                (string= m-ts n-ts)))))))
+
+;; (defmethod slack-room-buffer-name ((room slack-search-result))
+;;   (with-slots (query sort sort-dir team-id type) room
+;;     (let ((team (slack-team-find team-id)))
+;;       (format "%s - %s Query: %s Sort: %s Order: %s"
+;;               (oref team name)
+;;               (eieio-object-class room)
+;;               query sort sort-dir))))
+
+;; (defmethod slack-message-to-string ((message slack-search-message) team)
+;;   (with-slots (info text username) message
+;;     (with-slots (channel-id permalink) info
+;;       (let* ((header (format "%s" username))
+;;              (channel (slack-room-find channel-id team))
+;;              (body (slack-message-unescape-string
+;;                     (format "%s\n\n------------\nChanel: %s\nPermalink: %s"
+;;                             text
+;;                             (slack-room-name channel)
+;;                             permalink)
+;;                     team)))
+;;         (slack-message-put-header-property header)
+;;         (slack-message-put-text-property body)
+;;         (format "%s\n%s\n" header body)))))
+
+;; (defmethod slack-room-set-prev-messages ((room slack-search-result) prev)
+;;   (slack-room-set-messages room (nreverse
+;;                                  (nconc (nreverse prev) (oref room messages)))))
+
+;; (defmethod slack-room-set-messages ((room slack-search-result) messages)
+;;   (let ((msgs (nreverse messages)))
+;;     (oset room messages msgs)
+;;     (oset room latest (car (last msgs)))
+;;     (oset room oldest (car msgs))))
+
+;; (cl-defmethod slack-room-history-request ((room slack-search-result) team
+;;                                           &key
+;;                                           oldest after-success async)
+;;   (cl-labels
+;;       ((on-history
+;;         (&key data &allow-other-keys)
+;;         (slack-request-handle-error
+;;          (data "slack-room-history")
+;;          (let* ((matches (cl-case (eieio-object-class room)
+;;                            ('slack-search-result (plist-get data :messages))
+;;                            ('slack-file-search-result (plist-get data :files))))
+;;                 (messages (cl-loop
+;;                            for match in (plist-get matches :matches)
+;;                            collect (slack-search-create-message room match))))
+;;            (oset room current-page
+;;                  (plist-get (plist-get matches :paging) :page))
+;;            (if oldest
+;;                (slack-room-set-prev-messages room messages)
+;;              (slack-room-reset-last-read room)
+;;              (slack-room-set-messages room messages))
+;;            (if after-success
+;;                (funcall after-success))))))
+;;     (let* ((current-page (oref room current-page))
+;;            (total-page (oref room total-page))
+;;            (next-page (if oldest
+;;                           (1+ current-page)
+;;                         1)))
+;;       (with-slots (query sort sort-dir) room
+;;         (cl-case (eieio-object-class room)
+;;           ('slack-search-result
+;;            (slack-search-request-message team
+;;                                          query
+;;                                          sort
+;;                                          sort-dir
+;;                                          #'on-history
+;;                                          next-page
+;;                                          async))
+;;           ('slack-file-search-result
+;;            (slack-search-request-file team
+;;                                       query
+;;                                       sort
+;;                                       sort-dir
+;;                                       #'on-history
+;;                                       next-page
+;;                                       async)))))))
+
+(provide 'slack-search)
+;;; slack-search.el ends here