feat: add refresh command to interactive mode
Type 'r' in the interactive prompt to re-fetch and re-render the full briefing without exiting. Refactored main() to separate fetch/render from the interactive loop. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
93
briefing
93
briefing
@@ -449,15 +449,46 @@ def show_task_detail(nid):
|
|||||||
print(f"\n {DIM}URL: https://teacup.nodie.co.za/?sn={node.get('nodesid')}{RESET}")
|
print(f"\n {DIM}URL: https://teacup.nodie.co.za/?sn={node.get('nodesid')}{RESET}")
|
||||||
|
|
||||||
|
|
||||||
def interactive_mode(tasks):
|
def fetch_and_render(range_days, client):
|
||||||
"""Interactive prompt — type a task number to see details."""
|
"""Fetch briefing data from API and render it. Returns tasks list."""
|
||||||
# Build lookup
|
url = f"{BASE_URL}/briefing?range={range_days}"
|
||||||
task_ids = set()
|
if client:
|
||||||
for t in tasks:
|
url += f"&client={client}"
|
||||||
task_ids.add(str(t['nodesid']))
|
|
||||||
|
|
||||||
|
result = subprocess.run(
|
||||||
|
["curl", "-s", "-H", f"Authorization: Bearer {API_KEY}", url],
|
||||||
|
capture_output=True, text=True
|
||||||
|
)
|
||||||
|
|
||||||
|
if not result.stdout.strip():
|
||||||
|
print(f"{RED}Empty response from API{RESET}")
|
||||||
|
return []
|
||||||
|
|
||||||
|
try:
|
||||||
|
data = json.loads(result.stdout)
|
||||||
|
except json.JSONDecodeError:
|
||||||
|
print(f"{RED}Invalid JSON response{RESET}")
|
||||||
|
print(result.stdout[:500])
|
||||||
|
return []
|
||||||
|
|
||||||
|
if not data.get("success"):
|
||||||
|
print(f"{RED}API error: {data.get('message', 'Unknown')}{RESET}")
|
||||||
|
return []
|
||||||
|
|
||||||
|
raw = data["data"]
|
||||||
|
|
||||||
|
render_summary(raw.get('summary', {}), int(range_days))
|
||||||
|
render_calendar(raw.get('calendar', {}))
|
||||||
|
render_tasks(raw.get('tasks', []))
|
||||||
|
render_commits(raw.get('git_commits', {}))
|
||||||
|
|
||||||
|
return raw.get('tasks', [])
|
||||||
|
|
||||||
|
|
||||||
|
def interactive_mode(tasks, range_days, client):
|
||||||
|
"""Interactive prompt — type a task number for details, 'r' to refresh."""
|
||||||
print(f"\n{BOLD}{CYAN}{'─' * 60}{RESET}")
|
print(f"\n{BOLD}{CYAN}{'─' * 60}{RESET}")
|
||||||
print(f"{DIM}Type a task number for details, or 'q' to quit{RESET}")
|
print(f"{DIM}Commands: task number | r = refresh | q = quit{RESET}")
|
||||||
print(f"{BOLD}{CYAN}{'─' * 60}{RESET}")
|
print(f"{BOLD}{CYAN}{'─' * 60}{RESET}")
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
@@ -470,13 +501,22 @@ def interactive_mode(tasks):
|
|||||||
if not inp or inp.lower() in ('q', 'quit', 'exit'):
|
if not inp or inp.lower() in ('q', 'quit', 'exit'):
|
||||||
break
|
break
|
||||||
|
|
||||||
|
# Refresh
|
||||||
|
if inp.lower() in ('r', 'refresh'):
|
||||||
|
print(f"\n{DIM}Refreshing...{RESET}\n")
|
||||||
|
tasks = fetch_and_render(range_days, client)
|
||||||
|
print(f"\n{BOLD}{CYAN}{'─' * 60}{RESET}")
|
||||||
|
print(f"{DIM}Commands: task number | r = refresh | q = quit{RESET}")
|
||||||
|
print(f"{BOLD}{CYAN}{'─' * 60}{RESET}")
|
||||||
|
continue
|
||||||
|
|
||||||
# Strip # prefix if present
|
# Strip # prefix if present
|
||||||
inp = inp.lstrip('#')
|
inp = inp.lstrip('#')
|
||||||
|
|
||||||
if inp.isdigit():
|
if inp.isdigit():
|
||||||
show_task_detail(int(inp))
|
show_task_detail(int(inp))
|
||||||
else:
|
else:
|
||||||
print(f" {DIM}Enter a task number (e.g. 3047) or 'q' to quit{RESET}")
|
print(f" {DIM}Commands: task number | r = refresh | q = quit{RESET}")
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
@@ -489,42 +529,11 @@ def main():
|
|||||||
if args:
|
if args:
|
||||||
client = args[0]
|
client = args[0]
|
||||||
|
|
||||||
url = f"{BASE_URL}/briefing?range={range_days}"
|
tasks = fetch_and_render(range_days, client)
|
||||||
if client:
|
|
||||||
url += f"&client={client}"
|
|
||||||
|
|
||||||
result = subprocess.run(
|
|
||||||
["curl", "-s", "-H", f"Authorization: Bearer {API_KEY}", url],
|
|
||||||
capture_output=True, text=True
|
|
||||||
)
|
|
||||||
|
|
||||||
if not result.stdout.strip():
|
|
||||||
print(f"{RED}Empty response from API{RESET}")
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
try:
|
|
||||||
data = json.loads(result.stdout)
|
|
||||||
except json.JSONDecodeError:
|
|
||||||
print(f"{RED}Invalid JSON response{RESET}")
|
|
||||||
print(result.stdout[:500])
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
if not data.get("success"):
|
|
||||||
print(f"{RED}API error: {data.get('message', 'Unknown')}{RESET}")
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
raw = data["data"]
|
|
||||||
|
|
||||||
# Render from raw JSON data
|
|
||||||
render_summary(raw.get('summary', {}), int(range_days))
|
|
||||||
render_calendar(raw.get('calendar', {}))
|
|
||||||
render_tasks(raw.get('tasks', []))
|
|
||||||
render_commits(raw.get('git_commits', {}))
|
|
||||||
|
|
||||||
# Interactive mode
|
# Interactive mode
|
||||||
tasks = raw.get('tasks', [])
|
if sys.stdin.isatty():
|
||||||
if tasks and sys.stdin.isatty():
|
interactive_mode(tasks, range_days, client)
|
||||||
interactive_mode(tasks)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
Reference in New Issue
Block a user