stoof
This commit is contained in:
@@ -99,11 +99,12 @@
|
|||||||
|
|
||||||
(setq org-todo-keywords
|
(setq org-todo-keywords
|
||||||
'((sequence "ALRT(a)" "EASY(e)" "PROG(p)" "NEXT(n)"
|
'((sequence "ALRT(a)" "EASY(e)" "PROG(p)" "NEXT(n)"
|
||||||
"TODO(t)" "|" "DONE(d)")))
|
"TODO(t)" "WAIT(w)" "|" "DONE(d)")))
|
||||||
|
|
||||||
(setq org-todo-keyword-faces
|
(setq org-todo-keyword-faces
|
||||||
'(("ALRT" . (:foreground "Red" :weight bold))
|
'(("ALRT" . (:foreground "Red" :weight bold))
|
||||||
("TODO" . (:foreground "Orange" :weight bold))
|
("TODO" . (:foreground "Orange" :weight bold))
|
||||||
|
("WAIT" . (:foreground "SlateBlue" :weight bold))
|
||||||
("PROG" . (:foreground "DodgerBlue" :weight bold))
|
("PROG" . (:foreground "DodgerBlue" :weight bold))
|
||||||
("NEXT" . (:foreground "Purple" :weight bold))
|
("NEXT" . (:foreground "Purple" :weight bold))
|
||||||
("EASY" . (:foreground "MediumSeaGreen" :weight bold))
|
("EASY" . (:foreground "MediumSeaGreen" :weight bold))
|
||||||
@@ -119,7 +120,7 @@
|
|||||||
((org-agenda-overriding-header "🚨 Urgent / Interruptions")))
|
((org-agenda-overriding-header "🚨 Urgent / Interruptions")))
|
||||||
|
|
||||||
(tags "+TODO=\"EASY\""
|
(tags "+TODO=\"EASY\""
|
||||||
((org-agenda-overriding-header "🍃 Quick Tasks (≤15 min)")))
|
((org-agenda-overriding-header "🍃 Quick Tasks")))
|
||||||
|
|
||||||
(tags "+TODO=\"PROG\""
|
(tags "+TODO=\"PROG\""
|
||||||
((org-agenda-overriding-header "🚧 In Progress")))
|
((org-agenda-overriding-header "🚧 In Progress")))
|
||||||
@@ -127,6 +128,9 @@
|
|||||||
(tags "+TODO=\"NEXT\""
|
(tags "+TODO=\"NEXT\""
|
||||||
((org-agenda-overriding-header "▶ Next Actions")))
|
((org-agenda-overriding-header "▶ Next Actions")))
|
||||||
|
|
||||||
|
(tags "+TODO=\"WAIT\""
|
||||||
|
((org-agenda-overriding-header "⏳ Pending / Blocked")))
|
||||||
|
|
||||||
(tags "+TODO=\"TODO\""
|
(tags "+TODO=\"TODO\""
|
||||||
((org-agenda-overriding-header "📝 Backlog / To Plan")))
|
((org-agenda-overriding-header "📝 Backlog / To Plan")))
|
||||||
|
|
||||||
|
|||||||
87
.local/bin/jira2emacs.py
Executable file
87
.local/bin/jira2emacs.py
Executable file
@@ -0,0 +1,87 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import requests
|
||||||
|
import urllib.parse
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
|
||||||
|
# Config stuff
|
||||||
|
TOKEN = "NDQ0ODE5ODQ5NDU0OkwyY36wdY9DAvXsBr1M4bMjFmp6"
|
||||||
|
JIRA_URL = "https://jira.atg-corp.com"
|
||||||
|
TICKET_FILTER = 'project = "IS" AND status in (Open, "In Progress", Blocked, "Waiting for Customer", Stalled) AND assignee in (currentUser())'
|
||||||
|
TODO_FILE = os.path.expanduser("~/sync/org/agenda/work.org")
|
||||||
|
|
||||||
|
encoded_jql = urllib.parse.quote(TICKET_FILTER)
|
||||||
|
headers = {"Authorization": f"Bearer {TOKEN}", "Content-Type": "application/json"}
|
||||||
|
|
||||||
|
# Request stuff
|
||||||
|
response = requests.get(
|
||||||
|
f"{JIRA_URL}/rest/api/2/search?jql={encoded_jql}", headers=headers
|
||||||
|
)
|
||||||
|
response.raise_for_status()
|
||||||
|
issues = response.json().get("issues", [])
|
||||||
|
|
||||||
|
with open(TODO_FILE, "r", encoding="utf-8") as f:
|
||||||
|
lines = f.readlines()
|
||||||
|
file_content = "".join(lines)
|
||||||
|
|
||||||
|
# Aggregate issues
|
||||||
|
new_entries = []
|
||||||
|
for issue in issues:
|
||||||
|
key = issue["key"]
|
||||||
|
# Check if this issue already exists in the file
|
||||||
|
if f"[{key}]" in file_content:
|
||||||
|
continue
|
||||||
|
|
||||||
|
summary = issue["fields"]["summary"]
|
||||||
|
url = f"{JIRA_URL}/browse/{key}"
|
||||||
|
description = issue["fields"].get("description", "")
|
||||||
|
|
||||||
|
entry = f"** TODO [{key}] {summary}\n"
|
||||||
|
entry += " :PROPERTIES:\n"
|
||||||
|
entry += f" :LINK: {url}\n"
|
||||||
|
entry += " :END:\n"
|
||||||
|
|
||||||
|
if description:
|
||||||
|
# Indent each line of the description to maintain Org-mode structure.
|
||||||
|
desc_lines = description.splitlines()
|
||||||
|
indented_desc = "\n".join(" " + line for line in desc_lines)
|
||||||
|
entry += indented_desc + "\n"
|
||||||
|
|
||||||
|
new_entries.append(entry)
|
||||||
|
|
||||||
|
if not new_entries:
|
||||||
|
print("No new issues to add.")
|
||||||
|
exit(0)
|
||||||
|
|
||||||
|
new_file_lines = []
|
||||||
|
inbox_found = False
|
||||||
|
i = 0
|
||||||
|
|
||||||
|
while i < len(lines):
|
||||||
|
line = lines[i]
|
||||||
|
new_file_lines.append(line)
|
||||||
|
# Look for the "* Inbox" heading exactly.
|
||||||
|
if re.match(r"^\*+\s+Inbox\b", line.strip(), re.IGNORECASE):
|
||||||
|
inbox_found = True
|
||||||
|
i += 1
|
||||||
|
# Copy over any existing child lines under Inbox.
|
||||||
|
while i < len(lines) and (
|
||||||
|
lines[i].startswith("**")
|
||||||
|
or (lines[i].strip() and not lines[i].startswith("* "))
|
||||||
|
):
|
||||||
|
new_file_lines.append(lines[i])
|
||||||
|
i += 1
|
||||||
|
# Insert our new JIRA entries here.
|
||||||
|
new_file_lines.extend(new_entries)
|
||||||
|
# Append the rest of the file.
|
||||||
|
new_file_lines.extend(lines[i:])
|
||||||
|
break
|
||||||
|
i += 1
|
||||||
|
|
||||||
|
if not inbox_found:
|
||||||
|
print("Couldn't find '* Inbox' heading in the file.")
|
||||||
|
else:
|
||||||
|
with open(TODO_FILE, "w", encoding="utf-8") as f:
|
||||||
|
f.writelines(new_file_lines)
|
||||||
|
print(f"Appended {len(new_entries)} new JIRA issues under '* Inbox' in {TODO_FILE}")
|
||||||
Reference in New Issue
Block a user