feat: render briefing in pager (less) — starts at top, scroll down
Output now pipes through less -R so the calendar and summary are always visible at the top. Scroll down for waiting tasks, done, and commits. Press q to get to the interactive prompt. On refresh (r), the pager opens again from the top. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
28
briefing
28
briefing
@@ -7,7 +7,8 @@ Usage: briefing [7|30] [client]
|
|||||||
briefing 7 OHS — 7-day, OHS only
|
briefing 7 OHS — 7-day, OHS only
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import json, sys, subprocess, re, readline, os
|
import json, sys, subprocess, re, readline, os, io
|
||||||
|
from contextlib import redirect_stdout
|
||||||
from datetime import datetime, timezone, timedelta
|
from datetime import datetime, timezone, timedelta
|
||||||
|
|
||||||
API_KEY = "b666180ef00fffd23b9a606a4bd8deddea274d2e69fab975583d3d966fbfafed"
|
API_KEY = "b666180ef00fffd23b9a606a4bd8deddea274d2e69fab975583d3d966fbfafed"
|
||||||
@@ -449,16 +450,22 @@ 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 show_in_pager(content):
|
||||||
|
"""Show content in less, starting at the top. User scrolls down, q to exit."""
|
||||||
|
try:
|
||||||
|
proc = subprocess.Popen(['less', '-R', '-S', '--mouse'], stdin=subprocess.PIPE)
|
||||||
|
proc.communicate(input=content.encode())
|
||||||
|
except (BrokenPipeError, FileNotFoundError):
|
||||||
|
# Fallback: just print if less isn't available
|
||||||
|
print(content)
|
||||||
|
|
||||||
|
|
||||||
def fetch_and_render(range_days, client):
|
def fetch_and_render(range_days, client):
|
||||||
"""Fetch briefing data from API and render it. Returns tasks list."""
|
"""Fetch briefing data from API, render to pager. Returns tasks list."""
|
||||||
url = f"{BASE_URL}/briefing?range={range_days}"
|
url = f"{BASE_URL}/briefing?range={range_days}"
|
||||||
if client:
|
if client:
|
||||||
url += f"&client={client}"
|
url += f"&client={client}"
|
||||||
|
|
||||||
# Clear screen so briefing always starts at top
|
|
||||||
if sys.stdout.isatty():
|
|
||||||
print("\033[2J\033[H", end="", flush=True)
|
|
||||||
|
|
||||||
result = subprocess.run(
|
result = subprocess.run(
|
||||||
["curl", "-s", "-H", f"Authorization: Bearer {API_KEY}", url],
|
["curl", "-s", "-H", f"Authorization: Bearer {API_KEY}", url],
|
||||||
capture_output=True, text=True
|
capture_output=True, text=True
|
||||||
@@ -481,11 +488,20 @@ def fetch_and_render(range_days, client):
|
|||||||
|
|
||||||
raw = data["data"]
|
raw = data["data"]
|
||||||
|
|
||||||
|
# Render to buffer
|
||||||
|
buf = io.StringIO()
|
||||||
|
with redirect_stdout(buf):
|
||||||
render_summary(raw.get('summary', {}), int(range_days))
|
render_summary(raw.get('summary', {}), int(range_days))
|
||||||
render_calendar(raw.get('calendar', {}))
|
render_calendar(raw.get('calendar', {}))
|
||||||
render_tasks(raw.get('tasks', []))
|
render_tasks(raw.get('tasks', []))
|
||||||
render_commits(raw.get('git_commits', {}))
|
render_commits(raw.get('git_commits', {}))
|
||||||
|
|
||||||
|
# Show in pager (starts at top, scroll down for more)
|
||||||
|
if sys.stdout.isatty():
|
||||||
|
show_in_pager(buf.getvalue())
|
||||||
|
else:
|
||||||
|
print(buf.getvalue())
|
||||||
|
|
||||||
return raw.get('tasks', [])
|
return raw.get('tasks', [])
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user