chore(users): grfn -> aspen
Change-Id: I6c6847fac56f0a9a1a2209792e00a3aec5e672b9 Reviewed-on: https://cl.tvl.fyi/c/depot/+/10809 Autosubmit: aspen <root@gws.fyi> Reviewed-by: sterni <sternenseemann@systemli.org> Tested-by: BuildkiteCI Reviewed-by: lukegb <lukegb@tvl.fyi>
This commit is contained in:
parent
0ba476a426
commit
82ecd61f5c
478 changed files with 75 additions and 77 deletions
181
users/aspen/emacs.d/org-gcal.el
Normal file
181
users/aspen/emacs.d/org-gcal.el
Normal file
|
@ -0,0 +1,181 @@
|
|||
;;; -*- lexical-binding: t; -*-
|
||||
|
||||
(require 'aio)
|
||||
(require 'parse-time)
|
||||
|
||||
(setq-local lexical-binding t)
|
||||
(setq plstore-cache-passphrase-for-symmetric-encryption t)
|
||||
|
||||
(defvar gcal-client-id)
|
||||
(defvar gcal-client-secret)
|
||||
|
||||
(defvar google-calendar-readonly-scope
|
||||
"https://www.googleapis.com/auth/calendar.readonly")
|
||||
|
||||
(defvar events-file "/home/grfn/notes/events.org")
|
||||
|
||||
(defun google--get-token (scope client-id client-secret)
|
||||
(oauth2-auth-and-store
|
||||
"https://accounts.google.com/o/oauth2/v2/auth"
|
||||
"https://oauth2.googleapis.com/token"
|
||||
scope
|
||||
client-id
|
||||
client-secret))
|
||||
|
||||
(cl-defun google--request (url &key method params scope)
|
||||
(let ((p (aio-promise))
|
||||
(auth-token (google--get-token scope gcal-client-id gcal-client-secret)))
|
||||
(oauth2-refresh-access auth-token)
|
||||
(oauth2-url-retrieve
|
||||
auth-token
|
||||
url
|
||||
(lambda (&rest _)
|
||||
(goto-char (point-min))
|
||||
(re-search-forward "^$")
|
||||
(let ((resp (json-parse-buffer :object-type 'alist)))
|
||||
(aio-resolve p (lambda () resp))))
|
||||
nil
|
||||
(or method "GET")
|
||||
params)
|
||||
p))
|
||||
|
||||
(cl-defun list-events (&key min-time max-time)
|
||||
(google--request
|
||||
(concat
|
||||
"https://www.googleapis.com/calendar/v3/calendars/griffin@urbint.com/events"
|
||||
"?timeMin=" (format-time-string "%Y-%m-%dT%T%z" min-time)
|
||||
"&timeMax=" (format-time-string "%Y-%m-%dT%T%z" max-time))
|
||||
:scope google-calendar-readonly-scope))
|
||||
|
||||
|
||||
(defun last-week-events ()
|
||||
(list-events :min-time (time-subtract
|
||||
(current-time)
|
||||
(seconds-to-time
|
||||
(* 60 60 24 7)))
|
||||
:max-time (current-time)))
|
||||
|
||||
(defun next-week-events ()
|
||||
(list-events :min-time (current-time)
|
||||
:max-time (time-add
|
||||
(current-time)
|
||||
(seconds-to-time
|
||||
(* 60 60 24 7)))))
|
||||
|
||||
(defun attending-event? (event)
|
||||
(let* ((attendees (append (alist-get 'attendees event) nil))
|
||||
(self (--find (alist-get 'self it) attendees)))
|
||||
(equal "accepted" (alist-get 'responseStatus self))))
|
||||
|
||||
(defun event->org-headline (event level)
|
||||
(cl-flet ((make-time
|
||||
(key)
|
||||
(when-let ((raw-time (->> event (alist-get key) (alist-get 'dateTime))))
|
||||
(format-time-string
|
||||
(org-time-stamp-format t)
|
||||
(parse-iso8601-time-string raw-time)))))
|
||||
(if-let ((start-time (make-time 'start))
|
||||
(end-time (make-time 'end)))
|
||||
(s-format
|
||||
"${headline} [[${htmlLink}][${summary}]] :event:
|
||||
${startTime}--${endTime}
|
||||
:PROPERTIES:
|
||||
${location-prop}
|
||||
:EVENT: ${htmlLink}
|
||||
:END:
|
||||
|
||||
${description}"
|
||||
(function
|
||||
(lambda (k m)
|
||||
(or (alist-get (intern k) m)
|
||||
(format "key not found: %s" k))))
|
||||
(append
|
||||
event
|
||||
`((headline . ,(make-string level ?*))
|
||||
(startTime . ,start-time)
|
||||
(endTime . ,end-time)
|
||||
(location-prop
|
||||
. ,(if-let ((location (alist-get 'location event)))
|
||||
(s-lex-format ":LOCATION: ${location}")
|
||||
"")))))
|
||||
"")))
|
||||
|
||||
(comment
|
||||
(alist-get 'foo nil)
|
||||
)
|
||||
|
||||
(defun write-events (events)
|
||||
(with-current-buffer (find-file-noselect events-file)
|
||||
(save-mark-and-excursion
|
||||
(save-restriction
|
||||
(widen)
|
||||
(erase-buffer)
|
||||
(goto-char (point-min))
|
||||
(insert "#+TITLE: Events")
|
||||
(newline) (newline)
|
||||
(prog1
|
||||
(loop for event in (append events nil)
|
||||
when (attending-event? event)
|
||||
do
|
||||
(insert (event->org-headline event 1))
|
||||
(newline)
|
||||
sum 1)
|
||||
(org-align-tags t))))))
|
||||
|
||||
(defun +grfn/sync-events ()
|
||||
(interactive)
|
||||
(let* ((events (alist-get 'items (aio-wait-for (next-week-events))))
|
||||
(num-written (write-events events)))
|
||||
(message "Successfully wrote %d events" num-written)))
|
||||
|
||||
(comment
|
||||
((kind . "calendar#event")
|
||||
(etag . "\"3174776941020000\"")
|
||||
(id . "SNIP")
|
||||
(status . "confirmed")
|
||||
(htmlLink . "https://www.google.com/calendar/event?eid=SNIP")
|
||||
(created . "2020-04-01T13:30:09.000Z")
|
||||
(updated . "2020-04-20T13:14:30.510Z")
|
||||
(summary . "SNIP")
|
||||
(description . "SNIP")
|
||||
(location . "SNIP")
|
||||
(creator
|
||||
(email . "griffin@urbint.com")
|
||||
(self . t))
|
||||
(organizer
|
||||
(email . "griffin@urbint.com")
|
||||
(self . t))
|
||||
(start
|
||||
(dateTime . "2020-04-01T12:00:00-04:00")
|
||||
(timeZone . "America/New_York"))
|
||||
(end
|
||||
(dateTime . "2020-04-01T12:30:00-04:00")
|
||||
(timeZone . "America/New_York"))
|
||||
(recurrence .
|
||||
["RRULE:FREQ=WEEKLY;UNTIL=20200408T035959Z;BYDAY=WE"])
|
||||
(iCalUID . "SNIP")
|
||||
(sequence . 0)
|
||||
(attendees .
|
||||
[((email . "griffin@urbint.com")
|
||||
(organizer . t)
|
||||
(self . t)
|
||||
(responseStatus . "accepted"))
|
||||
((email . "SNIP")
|
||||
(displayName . "SNIP")
|
||||
(responseStatus . "needsAction"))])
|
||||
(extendedProperties
|
||||
(private
|
||||
(origRecurringId . "309q48kc1dihsvbi13pnlimb5a"))
|
||||
(shared
|
||||
(origRecurringId . "309q48kc1dihsvbi13pnlimb5a")))
|
||||
(reminders
|
||||
(useDefault . t)))
|
||||
|
||||
(require 'icalendar)
|
||||
|
||||
(icalendar--convert-recurring-to-diary
|
||||
nil
|
||||
"RRULE:FREQ=WEEKLY;UNTIL=20200408T035959Z;BYDAY=WE"
|
||||
)
|
||||
|
||||
)
|
Loading…
Add table
Add a link
Reference in a new issue