my-emacs-d/elpa/slack-20160928.2036/slack-reminder.el

265 lines
9.7 KiB
EmacsLisp

;;; slack-reminder.el --- -*- lexical-binding: t; -*-
;; Copyright (C) 2016 南優也
;; Author: 南優也 <yuyaminami@minamiyuuya-no-MacBook.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-team)
(defconst slack-reminder-list-url "https://slack.com/api/reminders.list")
(defconst slack-reminder-add-url "https://slack.com/api/reminders.add")
(defconst slack-reminder-delete-url "https://slack.com/api/reminders.delete")
(defconst slack-reminder-complete-url "https://slack.com/api/reminders.complete")
(defconst slack-reminder-info-url "https://slack.com/api/reminders.info")
(defclass slack-reminder-base ()
((id :initarg :id :type string)
(creator :initarg :creator :type string)
(user :initarg :user :type string)
(text :initarg :text :type string)))
(defclass slack-recurring-reminder (slack-reminder-base)
())
(defclass slack-reminder (slack-reminder-base)
((time :initarg :time :type integer)
(complete-ts :initarg :complete_ts :type integer)))
(defmethod slack-reminder-user ((r slack-reminder-base) team)
(slack-user-find (oref r user) team))
(defmethod slack-reminder-creator ((r slack-reminder-base) team)
(slack-user-find (oref r creator) team))
(defmethod slack-team-add-reminder ((team slack-team) reminder)
(with-slots (reminders) team
(cl-pushnew reminder reminders
:test #'(lambda (a b) (string= (oref a id) (oref b id))))))
(defmethod slack-reminder-completedp ((r slack-reminder))
(not (eq 0 (oref r complete-ts))))
(defmethod slack-reminder-completedp ((_r slack-recurring-reminder))
nil)
(defun slack-reminder-create (payload)
(let ((klass (if (eq :json-false (plist-get payload :recurring))
'slack-reminder
'slack-recurring-reminder)))
(apply #'make-instance klass
(slack-collect-slots klass payload))))
(defun slack-reminder-add ()
(interactive)
(let* ((team (slack-team-select))
(user (slack-select-from-list
((slack-user-names team) "Select Target User: ")))
(time (read-from-minibuffer
"Time (Ex. \"in 15 minutes,\" or \"every Thursday\"): "))
(text (read-from-minibuffer "Text: ")))
(cl-labels
((on-reminder-add (&key data &allow-other-keys)
(slack-request-handle-error
(data "slack-reminder-add")
(let ((reminder (slack-reminder-create
(slack-decode
(plist-get data :reminder)))))
(slack-team-add-reminder team reminder)
(message "Reminder Created!")))))
(slack-request
slack-reminder-add-url
team
:sync nil
:params (list (cons "text" text)
(cons "time" time)
(and user (cons "user" (plist-get user :id))))
:success #'on-reminder-add))))
(defmethod slack-reminder-to-body ((r slack-reminder))
(with-slots (text time complete-ts) r
(let ((time-str (format "Remind At: %s"
(slack-message-time-to-string
(number-to-string time))))
(completed (format "Completed: %s"
(if (eq complete-ts 0)
"Not Yet"
(slack-message-time-to-string
(number-to-string complete-ts))))))
(format "%s\n%s\n\n%s" time-str completed text))))
(defmethod slack-reminder-to-body ((r slack-recurring-reminder))
(oref r text))
(defmethod slack-reminder-to-string ((r slack-reminder-base) team)
(with-slots (creator user) r
(let* ((header (slack-message-put-header-property
(format "From: %s To: %s"
(slack-user-name creator team)
(slack-user-name user team))))
(body (slack-reminder-to-body r)))
(format "%s\n%s\n\n" header body))))
(defmethod slack-create-reminder-buffer ((team slack-team))
(let* ((buf-name "*Slack - Reminders*")
(buf (get-buffer-create buf-name)))
(with-current-buffer buf
(setq buffer-read-only nil)
(erase-buffer)
(goto-char (point-min))
(with-slots (reminders) team
(cl-loop for reminder in reminders
do (insert (slack-reminder-to-string reminder team))))
(setq buffer-read-only t))
buf))
(defmethod slack-reminder-sort-key ((r slack-reminder))
(oref r time))
(defmethod slack-reminder-sort-key ((r slack-recurring-reminder))
0)
(defun slack-reminder-sort (team)
(with-slots (reminders) team
(setq reminders
(cl-sort reminders #'<
:key #'(lambda (r) (slack-reminder-sort-key r))))))
(defun slack-reminder-list ()
(interactive)
(let ((team (slack-team-select)))
(cl-labels
((on-reminder-list
(&key data &allow-other-keys)
(slack-request-handle-error
(data "slack-reminder-list")
(oset team reminders
(cl-loop
for payload in (slack-decode
(append (plist-get data :reminders)
nil))
collect (slack-reminder-create payload)))
(slack-reminder-sort team)
(if (< 0 (length (oref team reminders)))
(funcall
slack-buffer-function
(slack-create-reminder-buffer team))
(message "No Reminders!")))))
(slack-request
slack-reminder-list-url
team
:sync nil
:success #'on-reminder-list))))
(defmethod slack-reminders-alist ((team slack-team) &optional filter)
(cl-labels ((text (r)
(with-slots (creator user text) r
(format "Creator: %s Target: %s Content: %s"
(slack-user-name creator team)
(slack-user-name user team)
text))))
(with-slots (reminders) team
(mapcar #'(lambda (r) (cons (text r) r))
(if filter
(cl-remove-if-not #'(lambda (r) (funcall filter r))
reminders)
reminders)))))
(defmethod slack-team-delete-reminder ((team slack-team) r)
(with-slots (reminders) team
(setq reminders
(cl-remove-if #'(lambda (e)
(string= (oref e id) (oref r id)))
reminders))))
(defun slack-reminder-select (team &optional filter)
(slack-select-from-list
((slack-reminders-alist team filter) "Select: ")))
(defun slack-reminder-delete ()
(interactive)
(let* ((team (slack-team-select))
(reminder (slack-reminder-select team)))
(cl-labels
((on-reminder-delete (&key data &allow-other-keys)
(slack-request-handle-error
(data "slack-reminder-delete")
(slack-team-delete-reminder team reminder)
(message "Reminder Deleted!"))))
(slack-request
slack-reminder-delete-url
team
:sync nil
:params (list (cons "reminder" (oref reminder id)))
:success #'on-reminder-delete))))
(defmethod slack-reminder-info ((r slack-reminder-base) team callback)
(cl-labels
((on-reminder-info (&key data &allow-other-keys)
(slack-request-handle-error
(data "slack-reminder-info")
(let ((reminder (slack-reminder-create
(plist-get (slack-decode data)
:reminder))))
(funcall callback reminder)))))
(slack-request
slack-reminder-info-url
team
:sync nil
:params (list (cons "reminder" (oref r id)))
:success #'on-reminder-info)))
(defmethod slack-reminder-refresh ((r slack-reminder-base) team)
(slack-reminder-info
r team
#'(lambda (reminder)
(with-slots (reminders) team
(setq reminders
(cl-remove-if #'(lambda (e) (string= (oref e id)
(oref reminder id)))
reminders))
(push reminder reminders))
(message "Reminder Updated!"))))
(defun slack-reminder-complete ()
(interactive)
(let* ((team (slack-team-select))
(reminder (slack-reminder-select
team
#'(lambda (r)
(not (slack-reminder-completedp r))))))
(cl-labels
((on-reminder-complete (&key data &allow-other-keys)
(slack-request-handle-error
(data "slack-reminder-complete")
(slack-reminder-refresh reminder team))))
(slack-request
slack-reminder-complete-url
team
:sync nil
:params (list (cons "reminder" (oref reminder id)))
:success #'on-reminder-complete))))
(provide 'slack-reminder)
;;; slack-reminder.el ends here