Skip to content

Commit 68791e7

Browse files
author
GlissemanTV
committed
add edtiting function
1 parent d7cc64e commit 68791e7

File tree

3 files changed

+366
-3
lines changed

3 files changed

+366
-3
lines changed

LLM_Export/docker/mcpo/tools/file_export_mcp.py

Lines changed: 122 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
from reportlab.lib.enums import TA_LEFT
4444
from reportlab.lib.units import mm
4545

46-
SCRIPT_VERSION = "0.7.0"
46+
SCRIPT_VERSION = "0.8.0-alpha"
4747

4848
URL = os.getenv('OWUI_URL')
4949
TOKEN = os.getenv('JWT_SECRET')
@@ -1454,6 +1454,127 @@ def add_auto_sized_review_comment(cell, text, author="AI Reviewer"):
14541454
comment.height = height
14551455
cell.comment = comment
14561456

1457+
@mcp.tool()
1458+
def edit_document(
1459+
file_id: str,
1460+
file_name: str,
1461+
edits: list[tuple[int | str, str]]
1462+
) -> dict:
1463+
"""
1464+
Edits an existing document of various types (docx, xlsx, pptx).
1465+
The index must be an integer for docx and pptx, or a cell reference for xlsx.
1466+
The text is the new content to replace the original.
1467+
Returns a markdown hyperlink for downloading the edited document.
1468+
"""
1469+
temp_folder = f"/app/temp/{uuid.uuid4()}"
1470+
os.makedirs(temp_folder, exist_ok=True)
1471+
1472+
try:
1473+
user_file = download_file(file_id)
1474+
if isinstance(user_file, dict) and "error" in user_file:
1475+
return json.dumps(user_file, indent=4, ensure_ascii=False)
1476+
1477+
file_extension = os.path.splitext(file_name)[1].lower()
1478+
file_type = file_extension.lstrip('.')
1479+
1480+
edited_path = None
1481+
response = None
1482+
1483+
if file_type == "docx":
1484+
try:
1485+
doc = Document(user_file)
1486+
paragraphs = list(doc.paragraphs)
1487+
1488+
for index, new_text in edits:
1489+
if isinstance(index, int) and 0 <= index < len(paragraphs):
1490+
para = paragraphs[index]
1491+
para.clear()
1492+
para.add_run(new_text)
1493+
edited_path = os.path.join(
1494+
temp_folder, f"{os.path.splitext(file_name)[0]}_edited.docx"
1495+
)
1496+
doc.save(edited_path)
1497+
response = upload_file(
1498+
file_path=edited_path,
1499+
filename=f"{os.path.splitext(file_name)[0]}_edited",
1500+
file_type="docx"
1501+
)
1502+
except Exception as e:
1503+
raise Exception(f"Error during DOCX editing: {e}")
1504+
1505+
elif file_type == "xlsx":
1506+
try:
1507+
wb = load_workbook(user_file)
1508+
ws = wb.active
1509+
1510+
for index, new_text in edits:
1511+
try:
1512+
if isinstance(index, str) and re.match(r"^[A-Z]+[0-9]+$", index.strip().upper()):
1513+
cell_ref = index.strip().upper()
1514+
elif isinstance(index, int):
1515+
cell_ref = f"A{index+1}"
1516+
else:
1517+
cell_ref = "A1"
1518+
1519+
cell = ws[cell_ref]
1520+
cell.value = new_text
1521+
except Exception:
1522+
fallback_cell = ws["A1"]
1523+
fallback_cell.value = new_text
1524+
1525+
edited_path = os.path.join(
1526+
temp_folder, f"{os.path.splitext(file_name)[0]}_edited.xlsx"
1527+
)
1528+
wb.save(edited_path)
1529+
response = upload_file(
1530+
file_path=edited_path,
1531+
filename=f"{os.path.splitext(file_name)[0]}_edited",
1532+
file_type="xlsx"
1533+
)
1534+
except Exception as e:
1535+
raise Exception(f"Error during XLSX editing: {e}")
1536+
1537+
elif file_type == "pptx":
1538+
try:
1539+
prs = Presentation(user_file)
1540+
1541+
for index, new_text in edits:
1542+
if isinstance(index, int) and 0 <= index < len(prs.slides):
1543+
slide = prs.slides[index]
1544+
for shape in slide.shapes:
1545+
if hasattr(shape, "text_frame") and shape.text_frame:
1546+
shape.text_frame.clear()
1547+
p = shape.text_frame.add_paragraph()
1548+
p.text = new_text
1549+
break
1550+
1551+
edited_path = os.path.join(
1552+
temp_folder, f"{os.path.splitext(file_name)[0]}_edited.pptx"
1553+
)
1554+
prs.save(edited_path)
1555+
response = upload_file(
1556+
file_path=edited_path,
1557+
filename=f"{os.path.splitext(file_name)[0]}_edited",
1558+
file_type="pptx"
1559+
)
1560+
except Exception as e:
1561+
raise Exception(f"Error during PPTX editing: {e}")
1562+
1563+
else:
1564+
raise Exception(f"File type not supported: {file_type}")
1565+
1566+
shutil.rmtree(temp_folder, ignore_errors=True)
1567+
1568+
return response
1569+
1570+
except Exception as e:
1571+
shutil.rmtree(temp_folder, ignore_errors=True)
1572+
return json.dumps(
1573+
{"error": {"message": str(e)}},
1574+
indent=4,
1575+
ensure_ascii=False
1576+
)
1577+
14571578
@mcp.tool(
14581579
name="review_document",
14591580
title="Review and comment on various document types",

LLM_Export/docker/sse_http/tools/file_export_mcp.py

Lines changed: 122 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
from starlette.routing import Route, Mount
5454
from starlette.responses import Response, JSONResponse
5555

56-
SCRIPT_VERSION = "0.7.0"
56+
SCRIPT_VERSION = "0.8.0-alpha"
5757

5858
URL = os.getenv('OWUI_URL')
5959
TOKEN = os.getenv('JWT_SECRET')
@@ -1464,6 +1464,127 @@ def add_auto_sized_review_comment(cell, text, author="AI Reviewer"):
14641464
comment.height = height
14651465
cell.comment = comment
14661466

1467+
@mcp.tool()
1468+
def edit_document(
1469+
file_id: str,
1470+
file_name: str,
1471+
edits: list[tuple[int | str, str]]
1472+
) -> dict:
1473+
"""
1474+
Edits an existing document of various types (docx, xlsx, pptx).
1475+
The index must be an integer for docx and pptx, or a cell reference for xlsx.
1476+
The text is the new content to replace the original.
1477+
Returns a markdown hyperlink for downloading the edited document.
1478+
"""
1479+
temp_folder = f"/app/temp/{uuid.uuid4()}"
1480+
os.makedirs(temp_folder, exist_ok=True)
1481+
1482+
try:
1483+
user_file = download_file(file_id)
1484+
if isinstance(user_file, dict) and "error" in user_file:
1485+
return json.dumps(user_file, indent=4, ensure_ascii=False)
1486+
1487+
file_extension = os.path.splitext(file_name)[1].lower()
1488+
file_type = file_extension.lstrip('.')
1489+
1490+
edited_path = None
1491+
response = None
1492+
1493+
if file_type == "docx":
1494+
try:
1495+
doc = Document(user_file)
1496+
paragraphs = list(doc.paragraphs)
1497+
1498+
for index, new_text in edits:
1499+
if isinstance(index, int) and 0 <= index < len(paragraphs):
1500+
para = paragraphs[index]
1501+
para.clear()
1502+
para.add_run(new_text)
1503+
edited_path = os.path.join(
1504+
temp_folder, f"{os.path.splitext(file_name)[0]}_edited.docx"
1505+
)
1506+
doc.save(edited_path)
1507+
response = upload_file(
1508+
file_path=edited_path,
1509+
filename=f"{os.path.splitext(file_name)[0]}_edited",
1510+
file_type="docx"
1511+
)
1512+
except Exception as e:
1513+
raise Exception(f"Error during DOCX editing: {e}")
1514+
1515+
elif file_type == "xlsx":
1516+
try:
1517+
wb = load_workbook(user_file)
1518+
ws = wb.active
1519+
1520+
for index, new_text in edits:
1521+
try:
1522+
if isinstance(index, str) and re.match(r"^[A-Z]+[0-9]+$", index.strip().upper()):
1523+
cell_ref = index.strip().upper()
1524+
elif isinstance(index, int):
1525+
cell_ref = f"A{index+1}"
1526+
else:
1527+
cell_ref = "A1"
1528+
1529+
cell = ws[cell_ref]
1530+
cell.value = new_text
1531+
except Exception:
1532+
fallback_cell = ws["A1"]
1533+
fallback_cell.value = new_text
1534+
1535+
edited_path = os.path.join(
1536+
temp_folder, f"{os.path.splitext(file_name)[0]}_edited.xlsx"
1537+
)
1538+
wb.save(edited_path)
1539+
response = upload_file(
1540+
file_path=edited_path,
1541+
filename=f"{os.path.splitext(file_name)[0]}_edited",
1542+
file_type="xlsx"
1543+
)
1544+
except Exception as e:
1545+
raise Exception(f"Error during XLSX editing: {e}")
1546+
1547+
elif file_type == "pptx":
1548+
try:
1549+
prs = Presentation(user_file)
1550+
1551+
for index, new_text in edits:
1552+
if isinstance(index, int) and 0 <= index < len(prs.slides):
1553+
slide = prs.slides[index]
1554+
for shape in slide.shapes:
1555+
if hasattr(shape, "text_frame") and shape.text_frame:
1556+
shape.text_frame.clear()
1557+
p = shape.text_frame.add_paragraph()
1558+
p.text = new_text
1559+
break
1560+
1561+
edited_path = os.path.join(
1562+
temp_folder, f"{os.path.splitext(file_name)[0]}_edited.pptx"
1563+
)
1564+
prs.save(edited_path)
1565+
response = upload_file(
1566+
file_path=edited_path,
1567+
filename=f"{os.path.splitext(file_name)[0]}_edited",
1568+
file_type="pptx"
1569+
)
1570+
except Exception as e:
1571+
raise Exception(f"Error during PPTX editing: {e}")
1572+
1573+
else:
1574+
raise Exception(f"File type not supported: {file_type}")
1575+
1576+
shutil.rmtree(temp_folder, ignore_errors=True)
1577+
1578+
return response
1579+
1580+
except Exception as e:
1581+
shutil.rmtree(temp_folder, ignore_errors=True)
1582+
return json.dumps(
1583+
{"error": {"message": str(e)}},
1584+
indent=4,
1585+
ensure_ascii=False
1586+
)
1587+
14671588
@mcp.tool(
14681589
name="review_document",
14691590
title="Review and comment on various document types",

0 commit comments

Comments
 (0)