import os import asyncio from io import BytesIO from datetime import datetime from nio import AsyncClient, UploadResponse, RoomSendResponse async def send_order(pdf_path: str, analysis: dict, room_id: str, name: str, comment: str = ""): """ Sends a print order summary + PDF to the specified Matrix room. """ matrix_user = os.environ.get("MATRIX_USER") matrix_pass = os.environ.get("MATRIX_PASS") homeserver = os.environ.get("MATRIX_HOMESERVER", "http://einszwovier.local:8008") if not matrix_user or not matrix_pass: raise RuntimeError("Missing MATRIX_USER or MATRIX_PASS in environment") client = AsyncClient(homeserver, matrix_user) try: login_resp = await client.login(matrix_pass) if getattr(login_resp, "access_token", None) is None: raise RuntimeError(f"Failed to login to Matrix: {login_resp}") # Determine if document is color or B&W has_color = analysis['total_area_color'] > 0 color_marker = "Farbe" if has_color else "SW" # Generate new filename: ISO timestamp, name, price, color marker # Format: YYYY-MM-DDTHHMM_Name_PriceEUR_ColorMarker.pdf timestamp = datetime.now().strftime("%Y-%m-%dT%H%M") # Sanitize name for filename (remove special chars, limit length) safe_name = "".join(c for c in name if c.isalnum() or c in (' ', '-', '_')).strip() safe_name = safe_name.replace(' ', '_')[:30] # Max 30 chars # Use underscore instead of decimal point/comma for price price_str = f"{analysis['grand_total']:.2f}".replace('.', '_') new_filename = f"{timestamp}_{safe_name}_{price_str}EUR_{color_marker}.pdf" # Build condensed German summary - focus on key info summary_lines = [ "=== NEUER DRUCKAUFTRAG ===", "", f"Name: {name}", f"Preis: {analysis['grand_total']:.2f} EUR", ] # Add comment prominently if provided if comment.strip(): summary_lines.extend([ "", f"Kommentar:", f"{comment.strip()}", ]) # Add compact breakdown summary_lines.extend([ "", "Details:", ]) if analysis['total_area_black'] > 0: summary_lines.append( f" - S/W: {analysis['total_area_black']:.2f} m2 -> {analysis['total_cost_black']:.2f} EUR" ) if analysis['total_area_color'] > 0: summary_lines.append( f" - Farbe: {analysis['total_area_color']:.2f} m2 -> {analysis['total_cost_color']:.2f} EUR" ) # Add page count summary total_pages = len(analysis['pages']) color_pages = sum(1 for p in analysis['pages'] if p['is_color']) bw_pages = total_pages - color_pages summary_lines.append(f" - Seiten: {total_pages} gesamt ({bw_pages} S/W, {color_pages} Farbe)") # Optional: Add detailed page breakdown for small documents if total_pages <= 5: # Only show details for small documents summary_lines.append("") summary_lines.append("Seiten:") for page in analysis["pages"]: seitenart = "Farbe" if page["is_color"] else "S/W" summary_lines.append( f" - S.{page['page']}: {page['width_m']*1000:.0f}x{page['height_m']*1000:.0f}mm, {seitenart}, {page['cost']:.2f} EUR" ) summary_text = "\n".join(summary_lines) # Send summary message text_resp = await client.room_send( room_id=room_id, message_type="m.room.message", content={"msgtype": "m.text", "body": summary_text}, ) if not (isinstance(text_resp, RoomSendResponse) and text_resp.event_id): raise RuntimeError(f"Failed to send order summary: {text_resp}") # Upload PDF with new filename with open(pdf_path, "rb") as f: pdf_bytes = f.read() upload_resp, upload_err = await client.upload( data_provider=BytesIO(pdf_bytes), content_type="application/pdf", filename=new_filename, # Use generated filename filesize=len(pdf_bytes), ) if upload_err or not (isinstance(upload_resp, UploadResponse) and upload_resp.content_uri): raise RuntimeError(f"Failed to upload PDF: {upload_err or upload_resp}") # Send PDF as file message file_resp = await client.room_send( room_id=room_id, message_type="m.room.message", content={ "msgtype": "m.file", "body": new_filename, # Display new filename "url": upload_resp.content_uri, }, ) if not (isinstance(file_resp, RoomSendResponse) and file_resp.event_id): raise RuntimeError(f"Failed to send PDF message: {file_resp}") print(f"✅ Order sent to room {room_id} as {new_filename}") finally: await client.logout() await client.close() def send_order_sync(pdf_path: str, analysis: dict, room_id: str, name: str, comment: str = ""): asyncio.run(send_order(pdf_path, analysis, room_id, name, comment))