Skip to content

Commit 16326b0

Browse files
committed
fix: ci failures (add license headers, rename variable, restore file content)
1 parent 37de5d2 commit 16326b0

File tree

3 files changed

+120
-38
lines changed

3 files changed

+120
-38
lines changed

camel/toolkits/pptx_node_toolkit.py

Lines changed: 46 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,16 @@
1-
1+
# ========= Copyright 2023-2026 @ CAMEL-AI.org. All Rights Reserved. =========
2+
# Licensed under the Apache License, Version 2.0 (the "License");
3+
# you may not use this file except in compliance with the License.
4+
# You may obtain a copy of the License at
5+
#
6+
# http://www.apache.org/licenses/LICENSE-2.0
7+
#
8+
# Unless required by applicable law or agreed to in writing, software
9+
# distributed under the License is distributed on an "AS IS" BASIS,
10+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
# See the License for the specific language governing permissions and
12+
# limitations under the License.
13+
# ========= Copyright 2023-2026 @ CAMEL-AI.org. All Rights Reserved. =========
214
import json
315
import os
416
import subprocess
@@ -15,8 +27,7 @@
1527

1628
@MCPServer()
1729
class PptxNodeToolkit(BaseToolkit):
18-
r"""A toolkit for creating PowerPoint presentations using PptxGenJS (Node.js).
19-
"""
30+
r"""A toolkit for creating PowerPoint presentations using PptxGenJS (Node.js)."""
2031

2132
def __init__(
2233
self,
@@ -56,15 +67,15 @@ def create_presentation(
5667
filename: str,
5768
) -> str:
5869
r"""Create a PowerPoint presentation (PPTX) file using PptxGenJS.
59-
70+
6071
The filename MUST end with ".pptx". If it does not, the toolkit will
6172
automatically append it, but the agent should strive to provide the
6273
correct extension.
6374
6475
Args:
6576
content (str): The content to write to the PPTX file as a JSON
6677
string. It must be a list of dictionaries representing slides.
67-
78+
6879
JSON Schema Example:
6980
[
7081
{
@@ -99,41 +110,41 @@ def create_presentation(
99110
script_path = Path(__file__).parent / "scripts" / "generate_pptx.js"
100111

101112
try:
102-
# Ensure content is a valid JSON string
103-
try:
104-
if not isinstance(content, str):
105-
content_str = json.dumps(content)
106-
else:
107-
# Validate JSON
108-
json_obj = json.loads(content)
109-
content_str = json.dumps(json_obj)
110-
except json.JSONDecodeError:
111-
return "Error: Content must be valid JSON string representing slides."
112-
113-
# Run node script
114-
result = subprocess.run(
115-
["node", str(script_path), str(file_path), content_str],
116-
capture_output=True,
117-
text=True,
118-
check=True
119-
)
120-
121-
# Parse JSON output from script
122-
try:
123-
script_output = json.loads(result.stdout.strip())
124-
if script_output.get("success"):
125-
return f"Presentation created successfully. Path: {script_output.get('path')}, Slides: {script_output.get('slides')}"
126-
else:
127-
return f"Error creating presentation: {script_output.get('error')}"
128-
except json.JSONDecodeError:
129-
return f"Error parsing script output: {result.stdout.strip()}"
113+
# Ensure content is a valid JSON string
114+
try:
115+
if not isinstance(content, str):
116+
content_str = json.dumps(content)
117+
else:
118+
# Validate JSON
119+
json_obj = json.loads(content)
120+
content_str = json.dumps(json_obj)
121+
except json.JSONDecodeError:
122+
return "Error: Content must be valid JSON string representing slides."
123+
124+
# Run node script
125+
result = subprocess.run(
126+
["node", str(script_path), str(file_path), content_str],
127+
capture_output=True,
128+
text=True,
129+
check=True,
130+
)
131+
132+
# Parse JSON output from script
133+
try:
134+
script_output = json.loads(result.stdout.strip())
135+
if script_output.get("success"):
136+
return f"Presentation created successfully. Path: {script_output.get('path')}, Slides: {script_output.get('slides')}"
137+
else:
138+
return f"Error creating presentation: {script_output.get('error')}"
139+
except json.JSONDecodeError:
140+
return f"Error parsing script output: {result.stdout.strip()}"
130141

131142
except subprocess.CalledProcessError as e:
132143
logger.error(f"Error creating presentation: {e.stderr}")
133144
return f"Error creating presentation subprocess: {e.stderr}"
134145
except Exception as e:
135-
logger.error(f"Error creating presentation: {str(e)}")
136-
return f"Error creating presentation: {str(e)}"
146+
logger.error(f"Error creating presentation: {e!s}")
147+
return f"Error creating presentation: {e!s}"
137148

138149
def get_tools(self) -> list[FunctionTool]:
139150
r"""Returns a list of FunctionTool objects representing the

camel/toolkits/scripts/generate_pptx.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,12 @@ try {
2121
}
2222

2323
// Create Presentation
24-
const pres = new PptxGenJS();
24+
const ppt = new PptxGenJS();
2525

2626
// Process slides
2727
if (Array.isArray(slidesData)) {
2828
slidesData.forEach((slideData) => {
29-
const slide = pres.addSlide();
29+
const slide = ppt.addSlide();
3030

3131
// simple layout heuristics based on keys
3232
if (slideData.title) {
@@ -69,7 +69,7 @@ if (Array.isArray(slidesData)) {
6969
}
7070

7171
// Save File
72-
pres.writeFile({ fileName: filename })
72+
ppt.writeFile({ fileName: filename })
7373
.then((fileName) => {
7474
const result = {
7575
success: true,
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
# ========= Copyright 2023-2026 @ CAMEL-AI.org. All Rights Reserved. =========
2+
# Licensed under the Apache License, Version 2.0 (the "License");
3+
# you may not use this file except in compliance with the License.
4+
# You may obtain a copy of the License at
5+
#
6+
# http://www.apache.org/licenses/LICENSE-2.0
7+
#
8+
# Unless required by applicable law or agreed to in writing, software
9+
# distributed under the License is distributed on an "AS IS" BASIS,
10+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
# See the License for the specific language governing permissions and
12+
# limitations under the License.
13+
# ========= Copyright 2023-2026 @ CAMEL-AI.org. All Rights Reserved. =========
14+
import json
15+
import unittest
16+
from unittest.mock import MagicMock, patch
17+
18+
from camel.toolkits.pptx_node_toolkit import PptxNodeToolkit
19+
20+
21+
class TestPptxNodeToolkit(unittest.TestCase):
22+
def setUp(self):
23+
self.toolkit = PptxNodeToolkit()
24+
25+
@patch("subprocess.run")
26+
def test_create_presentation_success(self, mock_subprocess_run):
27+
# Mock successful execution
28+
mock_result = MagicMock()
29+
mock_result.stdout = json.dumps(
30+
{"success": True, "path": "/path/to/test.pptx", "slides": 5}
31+
)
32+
mock_subprocess_run.return_value = mock_result
33+
34+
content = [{"title": "Test Slide"}]
35+
filename = "test_presentation"
36+
37+
result = self.toolkit.create_presentation(content, filename)
38+
39+
expected_call_args = mock_subprocess_run.call_args[0][0]
40+
self.assertEqual(expected_call_args[0], "node")
41+
self.assertTrue(
42+
expected_call_args[2].endswith("test_presentation.pptx")
43+
)
44+
45+
self.assertIn("Presentation created successfully", result)
46+
self.assertIn("/path/to/test.pptx", result)
47+
self.assertIn("Slides: 5", result)
48+
49+
@patch("subprocess.run")
50+
def test_create_presentation_failure(self, mock_subprocess_run):
51+
# Mock failed execution
52+
mock_result = MagicMock()
53+
mock_result.stdout = json.dumps(
54+
{"success": False, "error": "Some error occurred"}
55+
)
56+
mock_subprocess_run.return_value = mock_result
57+
58+
content = [{"title": "Test Slide"}]
59+
filename = "test.pptx"
60+
61+
result = self.toolkit.create_presentation(content, filename)
62+
63+
self.assertIn(
64+
"Error creating presentation: Some error occurred", result
65+
)
66+
67+
def test_create_presentation_invalid_json(self):
68+
content = "Invalid JSON"
69+
filename = "test.pptx"
70+
result = self.toolkit.create_presentation(content, filename)
71+
self.assertIn("Error: Content must be valid JSON", result)

0 commit comments

Comments
 (0)