@bangdao-ai/zentao-mcp 1.1.1 → 1.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
Binary file
|
package/src/zentao_nexus.py
CHANGED
|
@@ -167,67 +167,68 @@ class ZenTaoAPIClient:
|
|
|
167
167
|
'User-Agent': 'Python-ZenTao-Client/1.0'
|
|
168
168
|
}
|
|
169
169
|
|
|
170
|
-
#
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
170
|
+
# 打印请求信息(仅在非静默模式下)
|
|
171
|
+
if not self.silent:
|
|
172
|
+
print("\n" + "=" * 80)
|
|
173
|
+
print("【禅道API请求信息】")
|
|
174
|
+
print("=" * 80)
|
|
175
|
+
print(f"API URL: {api_url}")
|
|
176
|
+
print(f"\n【Headers】")
|
|
177
|
+
for key, value in headers.items():
|
|
178
|
+
print(f" {key}: {value}")
|
|
179
|
+
|
|
180
|
+
print(f"\n【Token生成信息】")
|
|
181
|
+
print(f" code: {self.code}")
|
|
182
|
+
print(f" key: {self.key[:10]}...{self.key[-10:] if len(self.key) > 20 else self.key}") # 只显示部分key,保护隐私
|
|
183
|
+
print(f" time: {current_timestamp}")
|
|
184
|
+
print(f" token生成公式: md5(code + key + time)")
|
|
185
|
+
print(f" token生成字符串: {self.code}{self.key}{current_timestamp}")
|
|
186
|
+
print(f" token: {token}")
|
|
187
|
+
|
|
188
|
+
print(f"\n【URL参数】")
|
|
189
|
+
for key, value in url_params.items():
|
|
190
|
+
print(f" {key}: {value}")
|
|
191
|
+
|
|
192
|
+
# 处理form_data用于显示
|
|
193
|
+
display_form_data = form_data
|
|
194
|
+
if isinstance(form_data, dict):
|
|
195
|
+
# 检查是否有数组类型的值
|
|
196
|
+
processed_data = []
|
|
197
|
+
for key, value in form_data.items():
|
|
198
|
+
if isinstance(value, (list, tuple)):
|
|
199
|
+
for item in value:
|
|
200
|
+
processed_data.append((key, str(item)))
|
|
201
|
+
else:
|
|
202
|
+
processed_data.append((key, str(value)))
|
|
203
|
+
display_form_data = processed_data
|
|
204
|
+
|
|
205
|
+
if display_form_data:
|
|
206
|
+
print(f"\n【Body (form-data)】")
|
|
207
|
+
if isinstance(display_form_data, list):
|
|
208
|
+
for item in display_form_data:
|
|
209
|
+
if isinstance(item, tuple):
|
|
210
|
+
key, value = item
|
|
211
|
+
# 如果是文件,只显示文件名
|
|
212
|
+
if hasattr(value, 'read'):
|
|
213
|
+
print(f" {key}: <文件对象>")
|
|
214
|
+
else:
|
|
215
|
+
print(f" {key}: {value}")
|
|
213
216
|
else:
|
|
214
|
-
print(f" {
|
|
217
|
+
print(f" {item}")
|
|
218
|
+
elif isinstance(display_form_data, dict):
|
|
219
|
+
for key, value in display_form_data.items():
|
|
220
|
+
print(f" {key}: {value}")
|
|
221
|
+
|
|
222
|
+
if files:
|
|
223
|
+
print(f"\n【Files】")
|
|
224
|
+
for key, file_info in files.items():
|
|
225
|
+
if isinstance(file_info, tuple):
|
|
226
|
+
filename = file_info[0] if len(file_info) > 0 else "unknown"
|
|
227
|
+
print(f" {key}: {filename}")
|
|
215
228
|
else:
|
|
216
|
-
print(f" {
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
print(f" {key}: {value}")
|
|
220
|
-
|
|
221
|
-
if files:
|
|
222
|
-
print(f"\n【Files】")
|
|
223
|
-
for key, file_info in files.items():
|
|
224
|
-
if isinstance(file_info, tuple):
|
|
225
|
-
filename = file_info[0] if len(file_info) > 0 else "unknown"
|
|
226
|
-
print(f" {key}: {filename}")
|
|
227
|
-
else:
|
|
228
|
-
print(f" {key}: {file_info}")
|
|
229
|
-
|
|
230
|
-
print("=" * 80)
|
|
229
|
+
print(f" {key}: {file_info}")
|
|
230
|
+
|
|
231
|
+
print("=" * 80)
|
|
231
232
|
|
|
232
233
|
try:
|
|
233
234
|
if files:
|
|
@@ -252,24 +253,33 @@ class ZenTaoAPIClient:
|
|
|
252
253
|
else:
|
|
253
254
|
response = requests.post(api_url, params=url_params, headers=headers, timeout=30)
|
|
254
255
|
|
|
255
|
-
#
|
|
256
|
-
print("\n【禅道API响应信息】")
|
|
257
|
-
print("=" * 80)
|
|
258
|
-
print(f"状态码: {response.status_code}")
|
|
259
|
-
print(f"响应Headers:")
|
|
260
|
-
for key, value in response.headers.items():
|
|
261
|
-
print(f" {key}: {value}")
|
|
262
|
-
|
|
256
|
+
# 处理响应
|
|
263
257
|
try:
|
|
264
258
|
response_json = response.json()
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
259
|
+
# 打印响应信息(仅在非静默模式下)
|
|
260
|
+
if not self.silent:
|
|
261
|
+
print("\n【禅道API响应信息】")
|
|
262
|
+
print("=" * 80)
|
|
263
|
+
print(f"状态码: {response.status_code}")
|
|
264
|
+
print(f"响应Headers:")
|
|
265
|
+
for key, value in response.headers.items():
|
|
266
|
+
print(f" {key}: {value}")
|
|
267
|
+
print(f"\n响应Body (JSON):")
|
|
268
|
+
print(json.dumps(response_json, ensure_ascii=False, indent=2))
|
|
269
|
+
print("=" * 80 + "\n")
|
|
268
270
|
return response_json
|
|
269
271
|
except json.JSONDecodeError:
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
272
|
+
# 打印响应信息(仅在非静默模式下)
|
|
273
|
+
if not self.silent:
|
|
274
|
+
print("\n【禅道API响应信息】")
|
|
275
|
+
print("=" * 80)
|
|
276
|
+
print(f"状态码: {response.status_code}")
|
|
277
|
+
print(f"响应Headers:")
|
|
278
|
+
for key, value in response.headers.items():
|
|
279
|
+
print(f" {key}: {value}")
|
|
280
|
+
print(f"\n响应Body (非JSON):")
|
|
281
|
+
print(response.text[:1000]) # 只显示前1000个字符
|
|
282
|
+
print("=" * 80 + "\n")
|
|
273
283
|
return {
|
|
274
284
|
"status": 0,
|
|
275
285
|
"message": "fail",
|
|
@@ -278,9 +288,11 @@ class ZenTaoAPIClient:
|
|
|
278
288
|
"raw_response": response.text
|
|
279
289
|
}
|
|
280
290
|
except requests.exceptions.RequestException as e:
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
291
|
+
# 打印异常信息(仅在非静默模式下)
|
|
292
|
+
if not self.silent:
|
|
293
|
+
print(f"\n【请求异常】")
|
|
294
|
+
print(f"错误信息: {str(e)}")
|
|
295
|
+
print("=" * 80 + "\n")
|
|
284
296
|
return {
|
|
285
297
|
"status": 0,
|
|
286
298
|
"message": "fail",
|