Commit 5ccf0322242c

Vincent Demeester <vincent@sbr.pm>
2020-01-31 13:49:25
Remove org-todoist
Signed-off-by: Vincent Demeester <vincent@sbr.pm>
1 parent 94db715
Changed files (1)
lisp/org-todoist.el
@@ -1,236 +0,0 @@
-;;; org-todoist.el --- Org sync with Todoist -*- lexical-binding: t -*-
-
-;; Version: 0.0.1
-;; Author: Andrea Orru <andrea@orru.io>
-;; Keywords: org, todoist
-;; Package-Requires: ((emacs "24") (request-deferred "0.3.0"))
-;; URL: https://github.com/AndreaOrru/org-todoist.el
-
-;; This file is distributed under the terms of the BSD 2-Clause license.
-
-;;; Commentary:
-;;
-
-;;; Code:
-
-(require 'json)
-(require 'org)
-(require 'parse-time)
-(require 'request-deferred)
-(require 'seq)
-
-(defgroup org-todoist nil
-  "Org sync with Todoist."
-  :tag "org todoist"
-  :group 'org)
-
-(defcustom org-todoist-api-token nil
-  "API Token for authentication."
-  :group 'org-todoist
-  :type 'string)
-
-(defcustom org-todoist-file "~/org/todo.org"
-  "."
-  :group 'org-todoist
-  :type 'string)
-
-(defconst org-todoist-url "https://beta.todoist.com/API/v8/")
-
-(defun org-todoist--json-read ()
-  "Internal JSON reading function."
-  (let ((json-object-type 'plist))
-    (goto-char (point-min))
-    (re-search-forward "[\\[{]" nil t)
-    (beginning-of-line)
-    (delete-region (point-min) (point))
-    (goto-char (point-min))
-    (json-read)))
-
-(defun org-todoist--project-tasks (project tasks)
-  "Given a list of TASKS, return only the ones in PROJECT."
-  (seq-filter
-   (lambda (task)
-     (= (alist-get 'id project)
-        (alist-get 'project_id task)))
-   tasks))
-
-(defun org-todoist--format-date (date-string)
-  "Given a DATE-STRING, return it in Org format."
-  (let* ((date  (parse-time-string date-string))
-         (day   (nth 3 date))
-         (month (nth 4 date))
-         (year  (nth 5 date)))
-    (format-time-string "%Y-%m-%d %a"
-                        (encode-time 0 0 0 day month year))))
-
-(defun org-todoist--format-project (project)
-  "Given a PROJECT, return its Org representation."
-  (concat "* "
-          (alist-get 'name project)
-          "\n   :PROPERTIES:"
-          (format "\n   :ID: %s" (alist-get 'id project))
-          "\n   :END:\n"))
-
-(defun org-todoist--format-task (task labels)
-  "Given a TASK, return its Org representation."
-  ;; (if (eq (length (alist-get 'labels_id task)) 3)
-  ;;     (message "has labels %s" (alist-get 'labels_id task)))
-  ;; (when (> (length (alist-get 'label_ids task)) 0)
-  ;;   (message "labels %s" labels)
-  ;;   (message "filtered label %s" (seq-filter (true) labels))
-  ;;   (message "labels %s" labels)
-  ;;   (message "fooo"))
-  (concat "** "
-          (if (eq (alist-get 'completed task) :json-false)
-              "TODO "
-            "DONE ")
-          (pcase (alist-get 'priority task)
-            (4 "[#A] ")
-            (3 "[#B] ")
-            (2 "[#C] ")
-            (_ ""))
-          (alist-get 'content task)
-          (when (alist-get 'due task)
-            (format "\n   SCHEDULED: <%s>"
-                    (org-todoist--format-date
-                     (alist-get 'date (alist-get 'due task)))))
-          "\n   :PROPERTIES:"
-          (format "\n   :ID: %s" (alist-get 'id task))
-          "\n   :END:\n"
-          ))
-
-(defun org-todoist--generate-task (hl project)
-  "Generate task given HL (Org headline) and current PROJECT."
-  `((id         . ,(org-element-property :ID hl))
-    (project_id . ,(string-to-number (org-element-property :ID project)))
-    (content    . ,(org-element-property :raw-value hl))
-    (completed  . ,(if (string= (org-element-property :todo-keyword hl) "TODO")
-                       :json-false
-                     t))))
-
-(defun org-todoist--parse-tasks ()
-  "Return tasks as defined in the Org file."
-  (let ((ast (with-temp-buffer
-               (insert-file-contents org-todoist-file)
-               (org-mode)
-               (org-element-parse-buffer)))
-        (current-project nil)
-        (tasks nil))
-    (progn
-      (org-element-map ast 'headline
-        (lambda (hl)
-          (if (= (org-element-property :level hl) 1)
-              (setq current-project hl)
-            (add-to-list 'tasks (org-todoist--generate-task hl current-project)))))
-     tasks)))
-
-(defun org-todoist--new-tasks ()
-  "Return new tasks defined in the Org file."
-  (let ((tasks (org-todoist--parse-tasks)))
-    (seq-filter
-     (lambda (task) (not (alist-get 'id task)))
-     tasks)))
-
-(defun org-todoist--tasks-to-close ()
-  "Return tasks to be closed, defined in the Org file."
-  (let ((tasks (org-todoist--parse-tasks)))
-    (seq-filter
-     (lambda (task)
-       (and (alist-get 'id task)
-            (not (eq (alist-get 'completed task) :json-false))))
-     tasks)))
-
-(defun org-todoist--close-tasks ()
-  "Close all DONE tasks in the Org file."
-  (deferred:$
-    (deferred:loop (org-todoist--tasks-to-close)
-      (lambda (task)
-        (deferred:$
-          (request-deferred
-           (concat org-todoist-url (format "tasks/%s/close"
-                                           (alist-get 'id task)))
-           :type "POST"
-           :headers `(("Authorization" . ,(format "Bearer %s" org-todoist-api-token)))
-           :parser 'json-read)
-
-          (deferred:nextc it
-            (lambda ()
-              (message "Closed tasks."))))))))
-
-(defun org-todoist--create-new-tasks ()
-  "Upload the Org file to Todoist."
-  (interactive)
-  (deferred:$
-    (deferred:loop (org-todoist--new-tasks)
-      (lambda (task)
-        (deferred:$
-          (request-deferred
-           (concat org-todoist-url "tasks")
-           :type "POST"
-           :data (json-encode
-                  `(("content"    . ,(alist-get 'content task))
-                    ("project_id" . ,(alist-get 'project_id task))))
-           :headers `(("Authorization" . ,(format "Bearer %s" org-todoist-api-token))
-                      ("Content-Type"  . "application/json"))
-           :parser 'org-todoist--json-read)
-
-          (deferred:nextc it
-            (lambda ()
-              (message "Created tasks."))))))))
-
-(defun org-todoist-download ()
-  "Download remote Todoist data into the Org file."
-  (interactive)
-  (deferred:$
-    (deferred:parallel
-      (lambda ()
-        (request-deferred
-         (concat org-todoist-url "projects")
-         :headers `(("Authorization" . ,(format "Bearer %s" org-todoist-api-token)))
-         :parser 'json-read))
-      (lambda ()
-        (request-deferred
-         (concat org-todoist-url "labels")
-         :headers `(("Authorization" . ,(format "Bearer %s" org-todoist-api-token)))
-         :parser 'json-read))
-      (lambda ()
-        (request-deferred
-         (concat org-todoist-url "tasks")
-         :headers `(("Authorization" . ,(format "Bearer %s" org-todoist-api-token)))
-         :parser 'json-read)))
-
-    (deferred:nextc it
-      (lambda (responses)
-        (let ((projects (request-response-data (nth 0 responses)))
-	      (labels (request-response-data (nth 1 responses)))
-              (tasks    (request-response-data (nth 2 responses))))
-          (with-current-buffer (find-file-noselect org-todoist-file)
-            (save-excursion
-              (erase-buffer)
-              (insert
-               (mapconcat (lambda (project)
-                            (concat (org-todoist--format-project project)
-                                    (mapconcat (lambda (task)
-                                                 (org-todoist--format-task task labels))
-                                               (org-todoist--project-tasks project tasks)
-                                               "")))
-                          projects
-                          ""))
-              (save-buffer)
-              (org-shifttab 0))))))
-
-    (deferred:nextc it
-      (lambda ()
-        (message "Downloaded tasks.")))))
-
-(defun org-todoist-sync ()
-  "Sync the Org file to Todoist."
-  (interactive)
-  (deferred:$
-    (deferred:next     (lambda() (org-todoist--create-new-tasks)))
-    (deferred:nextc it (lambda() (org-todoist--close-tasks)))
-    (deferred:nextc it (lambda() (org-todoist-download)))
-    (deferred:nextc it (lambda() (message "Synced.")))))
-
-(provide 'org-todoist)
-;;; org-todoist.el ends here