]> git.rmz.io Git - dotfiles.git/commitdiff
bin/org-agenda: introduce script to list upcoming org todos
authorSamir Benmendil <me@rmz.io>
Tue, 31 Oct 2023 21:57:24 +0000 (21:57 +0000)
committerSamir Benmendil <me@rmz.io>
Tue, 31 Oct 2023 23:08:51 +0000 (23:08 +0000)
bin/org-agenda [new file with mode: 0755]

diff --git a/bin/org-agenda b/bin/org-agenda
new file mode 100755 (executable)
index 0000000..a39a449
--- /dev/null
@@ -0,0 +1,91 @@
+#!/bin/python
+
+from glob import glob
+from os import path, get_terminal_size
+import orgparse
+from datetime import date
+
+# TODO: read org location from config
+org_glob = '~/org/**.org'
+org_todos = ['TODO', 'WAITING', 'NEXT']
+org_dones = ['DONE', 'CANCELLED']
+
+
+def org_is_archived(root):
+    return "ARCHIVE" in root.tags
+
+
+def org_is_overdue(node, end=None):
+    if not node.scheduled:
+        return False
+
+    if node.todo in org_dones:
+        return False
+
+    if node.closed:
+        return False
+
+    if end is None:
+        end = orgparse.date.OrgDate(date.today())
+
+    r = orgparse.date.OrgDate(0, end)
+    return node.scheduled.has_overlap(r)
+
+
+def org_is_scheduled(node: orgparse.node, start=None, end=None):
+    if not node.scheduled:
+        return False
+
+    if node.todo in org_dones:
+        return False
+
+    if start is None and end is None:
+        return True
+
+    if start is None:
+        start = orgparse.date.OrgDate(0)
+
+    if end is None:
+        end = start
+
+    r = orgparse.date.OrgDate(start, end)
+    return node.scheduled.has_overlap(r)
+
+
+def format_tags(tags):
+    if not tags:
+        return ""
+    return "".join([":{}:".format(t) for t in tags])
+
+
+def print_node(node):
+    [f, _] = path.splitext(path.basename(n.env.filename))
+    [cols, rows] = get_terminal_size()
+    wf = 12
+    wh = min(50, cols - wf)
+    wt = cols - wf - wh
+    print("{:<{wf}}{:<{wh}}{:>{wt}}".format(f+":", "{} {}".format(n.todo, n.heading)[:wh], format_tags(n.tags),
+            wf=wf, wh=wh, wt=wt))
+
+
+nodes_today = []
+nodes_overdue = []
+nodes_done_today = []
+#TODO nodes_deadline
+for org_file in glob(path.expanduser(org_glob)):
+    with open(org_file) as f:
+        env = orgparse.node.OrgEnv(todos=org_todos, dones=org_dones, filename=org_file)
+        root = orgparse.load(f, env=env)
+        # print(root.env.all_todo_keys)
+        for node in root[1:]:
+            if org_is_archived(node):
+                continue
+            if org_is_overdue(node, date.today()):
+                nodes_overdue.append(node)
+            elif org_is_scheduled(node, date.today()):
+                nodes_today.append(node)
+
+for n in nodes_overdue:
+    print_node(n)
+for n in nodes_today:
+    print_node(n)