Update dashboard, kb, memory +4 more (+28 ~18 -1)
This commit is contained in:
@@ -30,6 +30,8 @@ class TaskBoardHandler(SimpleHTTPRequestHandler):
|
||||
self.handle_refresh_index()
|
||||
elif self.path == '/api/git-commit':
|
||||
self.handle_git_commit()
|
||||
elif self.path == '/api/pdf':
|
||||
self.handle_pdf_post()
|
||||
else:
|
||||
self.send_error(404)
|
||||
|
||||
@@ -129,6 +131,72 @@ class TaskBoardHandler(SimpleHTTPRequestHandler):
|
||||
except Exception as e:
|
||||
self.send_json({'error': str(e)}, 500)
|
||||
|
||||
def handle_pdf_post(self):
|
||||
"""Convert markdown to PDF (text-based, not image) using venv script."""
|
||||
try:
|
||||
content_length = int(self.headers['Content-Length'])
|
||||
post_data = self.rfile.read(content_length).decode('utf-8')
|
||||
data = json.loads(post_data)
|
||||
|
||||
markdown_content = data.get('markdown', '')
|
||||
filename = data.get('filename', 'document.pdf')
|
||||
|
||||
if not markdown_content:
|
||||
self.send_json({'error': 'No markdown content'}, 400)
|
||||
return
|
||||
|
||||
# Call PDF generator script in venv
|
||||
venv_python = BASE_DIR / 'venv' / 'bin' / 'python3'
|
||||
pdf_script = TOOLS_DIR / 'generate_pdf.py'
|
||||
|
||||
if not venv_python.exists():
|
||||
self.send_json({'error': 'Venv Python not found'}, 500)
|
||||
return
|
||||
|
||||
if not pdf_script.exists():
|
||||
self.send_json({'error': 'PDF generator script not found'}, 500)
|
||||
return
|
||||
|
||||
# Prepare input JSON
|
||||
input_data = json.dumps({
|
||||
'markdown': markdown_content,
|
||||
'filename': filename
|
||||
})
|
||||
|
||||
# Call script with stdin
|
||||
result = subprocess.run(
|
||||
[str(venv_python), str(pdf_script)],
|
||||
input=input_data.encode('utf-8'),
|
||||
capture_output=True,
|
||||
timeout=30
|
||||
)
|
||||
|
||||
if result.returncode != 0:
|
||||
# Error from script
|
||||
error_msg = result.stderr.decode('utf-8', errors='replace')
|
||||
try:
|
||||
error_json = json.loads(error_msg)
|
||||
self.send_json(error_json, 500)
|
||||
except:
|
||||
self.send_json({'error': error_msg}, 500)
|
||||
return
|
||||
|
||||
# PDF bytes from stdout
|
||||
pdf_bytes = result.stdout
|
||||
|
||||
# Send as file download
|
||||
self.send_response(200)
|
||||
self.send_header('Content-Type', 'application/pdf')
|
||||
self.send_header('Content-Disposition', f'attachment; filename="{filename}"')
|
||||
self.send_header('Content-Length', str(len(pdf_bytes)))
|
||||
self.end_headers()
|
||||
self.wfile.write(pdf_bytes)
|
||||
|
||||
except subprocess.TimeoutExpired:
|
||||
self.send_json({'error': 'PDF generation timeout'}, 500)
|
||||
except Exception as e:
|
||||
self.send_json({'error': str(e)}, 500)
|
||||
|
||||
def do_GET(self):
|
||||
if self.path == '/api/status':
|
||||
self.send_json({'status': 'ok', 'time': datetime.now().isoformat()})
|
||||
@@ -193,15 +261,15 @@ class TaskBoardHandler(SimpleHTTPRequestHandler):
|
||||
|
||||
# Parse uncommitted into structured format
|
||||
# Format: XY PATH where XY is 2 chars (index + working tree status)
|
||||
# Examples: "M file" (staged), " M file" (unstaged), "?? file" (untracked)
|
||||
# Examples: "M AGENTS.md" (staged), " M tools.md" (unstaged), "?? file" (untracked)
|
||||
# The format varies: sometimes 1 space after status, sometimes 2
|
||||
uncommitted_parsed = []
|
||||
for line in uncommitted:
|
||||
if len(line) >= 3:
|
||||
status = line[:2].strip()
|
||||
# Path starts at position 3 for most cases, but we use lstrip
|
||||
# to handle edge cases where there's no separator space
|
||||
filepath = line[2:].lstrip().strip()
|
||||
uncommitted_parsed.append({'status': status, 'path': filepath})
|
||||
if len(line) >= 2:
|
||||
status = line[:2].strip() # Get 2 chars and strip whitespace
|
||||
filepath = line[2:].strip() # Get everything after position 2 and strip
|
||||
if filepath: # Only add if filepath is not empty
|
||||
uncommitted_parsed.append({'status': status, 'path': filepath})
|
||||
|
||||
self.send_json({
|
||||
'branch': branch,
|
||||
|
||||
Reference in New Issue
Block a user