add page
This commit is contained in:
parent
2d69d919a6
commit
a6d498bda0
3 changed files with 271 additions and 18 deletions
77
mailer.py
77
mailer.py
|
|
@ -1,6 +1,7 @@
|
||||||
import os
|
import os
|
||||||
import asyncio
|
import asyncio
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
|
from datetime import datetime
|
||||||
from nio import AsyncClient, UploadResponse, RoomSendResponse
|
from nio import AsyncClient, UploadResponse, RoomSendResponse
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -22,27 +23,67 @@ async def send_order(pdf_path: str, analysis: dict, room_id: str, name: str, com
|
||||||
if getattr(login_resp, "access_token", None) is None:
|
if getattr(login_resp, "access_token", None) is None:
|
||||||
raise RuntimeError(f"Failed to login to Matrix: {login_resp}")
|
raise RuntimeError(f"Failed to login to Matrix: {login_resp}")
|
||||||
|
|
||||||
# Build German summary text
|
# 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 = [
|
summary_lines = [
|
||||||
f"📄 Datei: {analysis['filename']}",
|
"=== NEUER DRUCKAUFTRAG ===",
|
||||||
f"👤 Name: {name}",
|
|
||||||
"",
|
"",
|
||||||
f"💰 Gesamtkosten: {analysis['grand_total']:.2f} €",
|
f"Name: {name}",
|
||||||
f" - S/W: {analysis['total_area_black']:.2f} m² = {analysis['total_cost_black']:.2f} €",
|
f"Preis: {analysis['grand_total']:.2f} EUR",
|
||||||
f" - Farbe: {analysis['total_area_color']:.2f} m² = {analysis['total_cost_color']:.2f} €",
|
|
||||||
"",
|
|
||||||
"📝 Seitenübersicht:"
|
|
||||||
]
|
]
|
||||||
|
|
||||||
for page in analysis["pages"]:
|
# Add comment prominently if provided
|
||||||
seitenart = "Farbe" if page["is_color"] else "S/W"
|
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(
|
summary_lines.append(
|
||||||
f"Seite {page['page']}: {page['width_m']*1000:.0f}×{page['height_m']*1000:.0f} mm, "
|
f" - S/W: {analysis['total_area_black']:.2f} m2 -> {analysis['total_cost_black']:.2f} EUR"
|
||||||
f"{seitenart}, Kosten {page['cost']:.2f} €"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if comment.strip():
|
if analysis['total_area_color'] > 0:
|
||||||
summary_lines.append("\n💬 Nutzerkommentar:\n" + comment.strip())
|
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)
|
summary_text = "\n".join(summary_lines)
|
||||||
|
|
||||||
|
|
@ -55,14 +96,14 @@ async def send_order(pdf_path: str, analysis: dict, room_id: str, name: str, com
|
||||||
if not (isinstance(text_resp, RoomSendResponse) and text_resp.event_id):
|
if not (isinstance(text_resp, RoomSendResponse) and text_resp.event_id):
|
||||||
raise RuntimeError(f"Failed to send order summary: {text_resp}")
|
raise RuntimeError(f"Failed to send order summary: {text_resp}")
|
||||||
|
|
||||||
# Upload PDF
|
# Upload PDF with new filename
|
||||||
with open(pdf_path, "rb") as f:
|
with open(pdf_path, "rb") as f:
|
||||||
pdf_bytes = f.read()
|
pdf_bytes = f.read()
|
||||||
|
|
||||||
upload_resp, upload_err = await client.upload(
|
upload_resp, upload_err = await client.upload(
|
||||||
data_provider=BytesIO(pdf_bytes),
|
data_provider=BytesIO(pdf_bytes),
|
||||||
content_type="application/pdf",
|
content_type="application/pdf",
|
||||||
filename=os.path.basename(pdf_path),
|
filename=new_filename, # Use generated filename
|
||||||
filesize=len(pdf_bytes),
|
filesize=len(pdf_bytes),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -75,14 +116,14 @@ async def send_order(pdf_path: str, analysis: dict, room_id: str, name: str, com
|
||||||
message_type="m.room.message",
|
message_type="m.room.message",
|
||||||
content={
|
content={
|
||||||
"msgtype": "m.file",
|
"msgtype": "m.file",
|
||||||
"body": os.path.basename(pdf_path),
|
"body": new_filename, # Display new filename
|
||||||
"url": upload_resp.content_uri,
|
"url": upload_resp.content_uri,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
if not (isinstance(file_resp, RoomSendResponse) and file_resp.event_id):
|
if not (isinstance(file_resp, RoomSendResponse) and file_resp.event_id):
|
||||||
raise RuntimeError(f"Failed to send PDF message: {file_resp}")
|
raise RuntimeError(f"Failed to send PDF message: {file_resp}")
|
||||||
|
|
||||||
print(f"✅ Text summary and PDF sent to room {room_id}")
|
print(f"✅ Order sent to room {room_id} as {new_filename}")
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
await client.logout()
|
await client.logout()
|
||||||
|
|
|
||||||
151
preview_message_format.py
Normal file
151
preview_message_format.py
Normal file
|
|
@ -0,0 +1,151 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Preview the new Matrix message format
|
||||||
|
"""
|
||||||
|
|
||||||
|
def preview_message():
|
||||||
|
# Sample data
|
||||||
|
name = "Anna Schmidt"
|
||||||
|
comment = "Bitte auf mattem Papier drucken. Danke!"
|
||||||
|
analysis = {
|
||||||
|
'filename': 'presentation.pdf',
|
||||||
|
'grand_total': 12.50,
|
||||||
|
'total_area_black': 1.5,
|
||||||
|
'total_cost_black': 6.0,
|
||||||
|
'total_area_color': 1.3,
|
||||||
|
'total_cost_color': 6.5,
|
||||||
|
'pages': [
|
||||||
|
{'page': 1, 'width_m': 0.21, 'height_m': 0.297, 'is_color': False, 'cost': 2.0},
|
||||||
|
{'page': 2, 'width_m': 0.21, 'height_m': 0.297, 'is_color': True, 'cost': 2.5},
|
||||||
|
{'page': 3, 'width_m': 0.21, 'height_m': 0.297, 'is_color': False, 'cost': 2.0},
|
||||||
|
{'page': 4, 'width_m': 0.21, 'height_m': 0.297, 'is_color': True, 'cost': 2.5},
|
||||||
|
{'page': 5, 'width_m': 0.21, 'height_m': 0.297, 'is_color': False, 'cost': 2.0},
|
||||||
|
{'page': 6, 'width_m': 0.21, 'height_m': 0.297, 'is_color': True, 'cost': 1.5},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
# Generate filename preview
|
||||||
|
from datetime import datetime
|
||||||
|
timestamp = datetime.now().strftime("%Y-%m-%dT%H%M")
|
||||||
|
safe_name = "".join(c for c in name if c.isalnum() or c in (' ', '-', '_')).strip()
|
||||||
|
safe_name = safe_name.replace(' ', '_')[:30]
|
||||||
|
has_color = analysis['total_area_color'] > 0
|
||||||
|
color_marker = "Farbe" if has_color else "SW"
|
||||||
|
price_str = f"{analysis['grand_total']:.2f}".replace('.', '_')
|
||||||
|
new_filename = f"{timestamp}_{safe_name}_{price_str}EUR_{color_marker}.pdf"
|
||||||
|
|
||||||
|
# Generate message
|
||||||
|
summary_lines = [
|
||||||
|
"=== NEUER DRUCKAUFTRAG ===",
|
||||||
|
"",
|
||||||
|
f"Name: {name}",
|
||||||
|
f"Preis: {analysis['grand_total']:.2f} EUR",
|
||||||
|
]
|
||||||
|
|
||||||
|
if comment.strip():
|
||||||
|
summary_lines.extend([
|
||||||
|
"",
|
||||||
|
f"Kommentar:",
|
||||||
|
f"{comment.strip()}",
|
||||||
|
])
|
||||||
|
|
||||||
|
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"
|
||||||
|
)
|
||||||
|
|
||||||
|
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)")
|
||||||
|
|
||||||
|
# Only show page details for <= 5 pages
|
||||||
|
if total_pages <= 5:
|
||||||
|
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"
|
||||||
|
)
|
||||||
|
|
||||||
|
print("=" * 60)
|
||||||
|
print("NEW FILENAME:")
|
||||||
|
print("=" * 60)
|
||||||
|
print(new_filename)
|
||||||
|
print()
|
||||||
|
print("=" * 60)
|
||||||
|
print("MESSAGE PREVIEW:")
|
||||||
|
print("=" * 60)
|
||||||
|
print("\n".join(summary_lines))
|
||||||
|
print()
|
||||||
|
print("=" * 60)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
print("\n📝 SMALL DOCUMENT EXAMPLE (5 pages, with details):\n")
|
||||||
|
preview_message()
|
||||||
|
|
||||||
|
print("\n\n📚 LARGE DOCUMENT EXAMPLE (6+ pages, no details):\n")
|
||||||
|
# Simulate larger document
|
||||||
|
import random
|
||||||
|
name = "Max Mustermann"
|
||||||
|
comment = ""
|
||||||
|
analysis = {
|
||||||
|
'filename': 'thesis.pdf',
|
||||||
|
'grand_total': 45.80,
|
||||||
|
'total_area_black': 8.5,
|
||||||
|
'total_cost_black': 34.0,
|
||||||
|
'total_area_color': 2.36,
|
||||||
|
'total_cost_color': 11.8,
|
||||||
|
'pages': [{'page': i, 'width_m': 0.21, 'height_m': 0.297,
|
||||||
|
'is_color': i % 3 == 0, 'cost': 5.0 if i % 3 == 0 else 4.0}
|
||||||
|
for i in range(1, 11)]
|
||||||
|
}
|
||||||
|
|
||||||
|
from datetime import datetime
|
||||||
|
timestamp = datetime.now().strftime("%Y-%m-%dT%H%M")
|
||||||
|
safe_name = "Max_Mustermann"
|
||||||
|
has_color = analysis['total_area_color'] > 0
|
||||||
|
color_marker = "Farbe" if has_color else "SW"
|
||||||
|
price_str = f"{analysis['grand_total']:.2f}".replace('.', '_')
|
||||||
|
new_filename = f"{timestamp}_{safe_name}_{price_str}EUR_{color_marker}.pdf"
|
||||||
|
|
||||||
|
summary_lines = [
|
||||||
|
"=== NEUER DRUCKAUFTRAG ===",
|
||||||
|
"",
|
||||||
|
f"Name: {name}",
|
||||||
|
f"Preis: {analysis['grand_total']:.2f} EUR",
|
||||||
|
"",
|
||||||
|
"Details:",
|
||||||
|
f" - S/W: {analysis['total_area_black']:.2f} m2 -> {analysis['total_cost_black']:.2f} EUR",
|
||||||
|
f" - Farbe: {analysis['total_area_color']:.2f} m2 -> {analysis['total_cost_color']:.2f} EUR",
|
||||||
|
]
|
||||||
|
|
||||||
|
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)")
|
||||||
|
|
||||||
|
print("=" * 60)
|
||||||
|
print("NEW FILENAME:")
|
||||||
|
print("=" * 60)
|
||||||
|
print(new_filename)
|
||||||
|
print()
|
||||||
|
print("=" * 60)
|
||||||
|
print("MESSAGE PREVIEW:")
|
||||||
|
print("=" * 60)
|
||||||
|
print("\n".join(summary_lines))
|
||||||
|
print("\n(Page details omitted for documents > 5 pages)")
|
||||||
|
print()
|
||||||
|
print("=" * 60)
|
||||||
61
test_matrix_connection.py
Normal file
61
test_matrix_connection.py
Normal file
|
|
@ -0,0 +1,61 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Test Matrix connection from host machine perspective
|
||||||
|
"""
|
||||||
|
import asyncio
|
||||||
|
import os
|
||||||
|
from nio import AsyncClient
|
||||||
|
|
||||||
|
|
||||||
|
async def test_connection(homeserver_url: str):
|
||||||
|
"""Test connection to Matrix homeserver"""
|
||||||
|
print(f"\n🔍 Testing connection to: {homeserver_url}")
|
||||||
|
|
||||||
|
matrix_user = os.environ.get("MATRIX_USER", "@einszwovier:einszwovier.local")
|
||||||
|
matrix_pass = os.environ.get("MATRIX_PASS", "einszwo4")
|
||||||
|
|
||||||
|
client = AsyncClient(homeserver_url, matrix_user)
|
||||||
|
|
||||||
|
try:
|
||||||
|
print(f" User: {matrix_user}")
|
||||||
|
print(f" Attempting login...")
|
||||||
|
|
||||||
|
resp = await client.login(matrix_pass)
|
||||||
|
|
||||||
|
if hasattr(resp, 'access_token'):
|
||||||
|
print(f" ✅ SUCCESS! Logged in as {matrix_user}")
|
||||||
|
print(f" Device ID: {resp.device_id}")
|
||||||
|
await client.logout()
|
||||||
|
else:
|
||||||
|
print(f" ❌ FAILED: {resp}")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f" ❌ ERROR: {e}")
|
||||||
|
finally:
|
||||||
|
await client.close()
|
||||||
|
|
||||||
|
|
||||||
|
async def main():
|
||||||
|
print("=" * 60)
|
||||||
|
print("Matrix Connection Test")
|
||||||
|
print("=" * 60)
|
||||||
|
|
||||||
|
# Test different homeserver URLs
|
||||||
|
test_urls = [
|
||||||
|
"http://localhost:8008",
|
||||||
|
"http://127.0.0.1:8008",
|
||||||
|
"http://einszwovier.local:8008",
|
||||||
|
]
|
||||||
|
|
||||||
|
for url in test_urls:
|
||||||
|
await test_connection(url)
|
||||||
|
|
||||||
|
print("\n" + "=" * 60)
|
||||||
|
print("Recommendation:")
|
||||||
|
print("If localhost/127.0.0.1 works but einszwovier.local fails,")
|
||||||
|
print("configure Element to use: http://localhost:8008")
|
||||||
|
print("=" * 60)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
asyncio.run(main())
|
||||||
Loading…
Add table
Add a link
Reference in a new issue