]> code.delx.au - gnu-emacs-elpa/blob - packages/excorporate/excorporate-org.el
05d11fb60bdfd7aa88ba2d820c5db8b96e4b7469
[gnu-emacs-elpa] / packages / excorporate / excorporate-org.el
1 ;;; excorporate-org.el --- Exchange Org Mode view -*- lexical-binding: t -*-
2
3 ;; Copyright (C) 2016 Free Software Foundation, Inc.
4
5 ;; Author: Thomas Fitzsimmons <fitzsim@fitzsim.org>
6 ;; Keywords: calendar
7
8 ;; This program is free software: you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation, either version 3 of the License, or
11 ;; (at your option) any later version.
12
13 ;; This program is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ;; GNU General Public License for more details.
17
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with this program. If not, see <http://www.gnu.org/licenses/>.
20
21 ;;; Commentary:
22
23 ;; Use the Org Mode to display daily meetings.
24
25 ;;; Code:
26
27 (require 'org)
28 (require 'excorporate)
29
30 (defvar excorporate-org-buffer-name "*Excorporate*"
31 "The buffer into which Org Mode output is inserted.")
32
33 (defun exco-org-initialize-buffer ()
34 "Add initial text to the destination buffer."
35 (with-current-buffer (get-buffer-create excorporate-org-buffer-name)
36 (setq buffer-read-only t)
37 (setq buffer-file-name excorporate-org-buffer-name)
38 (org-mode)
39 (use-local-map (copy-keymap org-mode-map))
40 (local-set-key "q" 'quit-window)
41 (display-buffer (current-buffer))
42 (let ((inhibit-read-only t))
43 (delete-region (point-min) (point-max))
44 (goto-char 1)
45 (insert "# Updated...\n"))))
46
47 (defun exco-org-format-headline (identifier)
48 "Format an Org headline using IDENTIFIER."
49 (format "* Calendar (%s)\n" identifier))
50
51 (defun exco-org-insert-meeting-headline (subject start-time end-time)
52 "Insert and schedule a meeting.
53 SUBJECT is the meeting's subject, START-TIME and END-TIME are the
54 meeting's start and end times in the same format as is returned
55 by `current-time'."
56 (let* ((now (current-time))
57 (keyword (if (time-less-p now end-time)
58 "TODO"
59 "DONE")))
60 (insert (format "** %s %s\n" keyword subject))
61 (org-schedule nil (format-time-string "<%Y-%m-%d %a %H:%M>"
62 start-time))
63 (forward-line -1)
64 (end-of-line)
65 (insert "--" (format-time-string "<%Y-%m-%d %a %H:%M>" end-time))
66 (forward-line)
67 (org-insert-time-stamp (current-time) t t "+ Retrieved " "\n")))
68
69 (defun exco-org-insert-invitees (invitees)
70 "Parse and insert a list of invitees, INVITEES."
71 (dolist (invitee invitees)
72 (insert (format " + %s\n" invitee))))
73
74 (defun exco-org-insert-headline (identifier month day year)
75 "Insert Org headline for IDENTIFIER on date MONTH DAY YEAR."
76 (with-current-buffer (get-buffer-create excorporate-org-buffer-name)
77 (let ((inhibit-read-only t))
78 (insert (exco-org-format-headline identifier))
79 (org-insert-time-stamp (encode-time 0 0 0 day month year)
80 nil t " + Date " "\n"))))
81
82 (defun exco-org-insert-meeting (subject start end location
83 main-invitees optional-invitees)
84 "Insert a scheduled meeting.
85 SUBJECT is a string, the subject of the meeting. START is the
86 meeting start time in Emacs internal date time format, and END is
87 the end of the meeting in the same format. LOCATION is a string
88 representing the location. MAIN-INVITEES and OPTIONAL-INVITEES
89 are the requested participants."
90 (exco-org-insert-meeting-headline subject start end)
91 (insert (format "+ Duration: %d minutes\n"
92 (round (/ (float-time (time-subtract end start)) 60.0))))
93 (insert (format "+ Location: %s\n" location))
94 (when main-invitees
95 (insert "+ Invitees:\n")
96 (exco-org-insert-invitees main-invitees))
97 (when optional-invitees
98 (insert "+ Optional invitees:\n")
99 (exco-org-insert-invitees optional-invitees)))
100
101 (defun exco-org-insert-meetings (identifier response)
102 "Insert the connection IDENTIFIER's meetings from RESPONSE."
103 (with-current-buffer (get-buffer-create excorporate-org-buffer-name)
104 (let ((inhibit-read-only t)
105 (name-regexp (concat "\\" (exco-org-format-headline identifier))))
106 (goto-char 1)
107 (end-of-line)
108 (insert (format "%s..." identifier))
109 (goto-char (point-max))
110 (re-search-backward name-regexp nil)
111 (forward-line 2)
112 (org-insert-time-stamp (current-time) t t " + Last checked " "\n")
113 (exco-calendar-item-iterate response #'exco-org-insert-meeting)
114 (re-search-backward name-regexp nil)
115 (if (save-excursion (org-goto-first-child))
116 (org-sort-entries t ?s)
117 (forward-line 3)
118 (insert "`♘")))))
119
120 (defun exco-org-finalize-buffer ()
121 "Finalize text in buffer after all connections have responded."
122 (with-current-buffer (get-buffer-create excorporate-org-buffer-name)
123 ;; Sort top-level entries alphabetically.
124 (let ((inhibit-read-only t))
125 (goto-char (point-min))
126 (end-of-line)
127 (insert "done.")
128 (org-sort-entries t ?a))))
129
130 ;;;###autoload
131 (defun exco-org-show-day (month day year)
132 "Show meetings for the date specified by MONTH DAY YEAR."
133 (exco-connection-iterate #'exco-org-initialize-buffer
134 (lambda (identifier callback)
135 (exco-org-insert-headline identifier
136 month day year)
137 (exco-get-meetings-for-day identifier
138 month day year
139 callback))
140 #'exco-org-insert-meetings
141 #'exco-org-finalize-buffer))
142
143 (provide 'excorporate-org)
144
145 ;;; excorporate-org.el ends here