mirror of
https://github.com/comfyanonymous/ComfyUI.git
synced 2026-01-23 21:00:16 +08:00
Merge f030d2c425 into be518db5a7
This commit is contained in:
commit
2e461ed9cc
@ -377,8 +377,22 @@ class UserManager():
|
|||||||
try:
|
try:
|
||||||
body = await request.read()
|
body = await request.read()
|
||||||
|
|
||||||
with open(path, "wb") as f:
|
# Pretty print JSON files for better source control
|
||||||
f.write(body)
|
if path.lower().endswith('.json'):
|
||||||
|
try:
|
||||||
|
# Parse JSON and re-serialize with indentation
|
||||||
|
json_data = json.loads(body.decode('utf-8'))
|
||||||
|
formatted_json = json.dumps(json_data, indent=2)
|
||||||
|
with open(path, "w", encoding='utf-8') as f:
|
||||||
|
f.write(formatted_json)
|
||||||
|
except (json.JSONDecodeError, UnicodeDecodeError):
|
||||||
|
# If JSON parsing fails, save as-is
|
||||||
|
with open(path, "wb") as f:
|
||||||
|
f.write(body)
|
||||||
|
else:
|
||||||
|
# Non-JSON files are saved as-is
|
||||||
|
with open(path, "wb") as f:
|
||||||
|
f.write(body)
|
||||||
except OSError as e:
|
except OSError as e:
|
||||||
logging.warning(f"Error saving file '{path}': {e}")
|
logging.warning(f"Error saving file '{path}': {e}")
|
||||||
return web.Response(
|
return web.Response(
|
||||||
|
|||||||
@ -521,7 +521,7 @@ class PromptServer():
|
|||||||
buffer.seek(0)
|
buffer.seek(0)
|
||||||
|
|
||||||
return web.Response(body=buffer.read(), content_type=f'image/{image_format}',
|
return web.Response(body=buffer.read(), content_type=f'image/{image_format}',
|
||||||
headers={"Content-Disposition": f"filename=\"{filename}\""})
|
headers={"Content-Disposition": f"attachment; filename=\"{filename}\""})
|
||||||
|
|
||||||
if 'channel' not in request.rel_url.query:
|
if 'channel' not in request.rel_url.query:
|
||||||
channel = 'rgba'
|
channel = 'rgba'
|
||||||
@ -541,7 +541,7 @@ class PromptServer():
|
|||||||
buffer.seek(0)
|
buffer.seek(0)
|
||||||
|
|
||||||
return web.Response(body=buffer.read(), content_type='image/png',
|
return web.Response(body=buffer.read(), content_type='image/png',
|
||||||
headers={"Content-Disposition": f"filename=\"{filename}\""})
|
headers={"Content-Disposition": f"attachment; filename=\"{filename}\""})
|
||||||
|
|
||||||
elif channel == 'a':
|
elif channel == 'a':
|
||||||
with Image.open(file) as img:
|
with Image.open(file) as img:
|
||||||
@ -558,7 +558,7 @@ class PromptServer():
|
|||||||
alpha_buffer.seek(0)
|
alpha_buffer.seek(0)
|
||||||
|
|
||||||
return web.Response(body=alpha_buffer.read(), content_type='image/png',
|
return web.Response(body=alpha_buffer.read(), content_type='image/png',
|
||||||
headers={"Content-Disposition": f"filename=\"{filename}\""})
|
headers={"Content-Disposition": f"attachment; filename=\"{filename}\""})
|
||||||
else:
|
else:
|
||||||
# Get content type from mimetype, defaulting to 'application/octet-stream'
|
# Get content type from mimetype, defaulting to 'application/octet-stream'
|
||||||
content_type = mimetypes.guess_type(filename)[0] or 'application/octet-stream'
|
content_type = mimetypes.guess_type(filename)[0] or 'application/octet-stream'
|
||||||
@ -570,7 +570,7 @@ class PromptServer():
|
|||||||
return web.FileResponse(
|
return web.FileResponse(
|
||||||
file,
|
file,
|
||||||
headers={
|
headers={
|
||||||
"Content-Disposition": f"filename=\"{filename}\"",
|
"Content-Disposition": f"attachment; filename=\"{filename}\"",
|
||||||
"Content-Type": content_type
|
"Content-Type": content_type
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|||||||
@ -287,3 +287,72 @@ async def test_listuserdata_v2_url_encoded_path(aiohttp_client, app, tmp_path):
|
|||||||
assert entry["name"] == "file.txt"
|
assert entry["name"] == "file.txt"
|
||||||
# Ensure the path is correctly decoded and uses forward slash
|
# Ensure the path is correctly decoded and uses forward slash
|
||||||
assert entry["path"] == "my dir/file.txt"
|
assert entry["path"] == "my dir/file.txt"
|
||||||
|
|
||||||
|
|
||||||
|
async def test_post_userdata_json_pretty_print(aiohttp_client, app, tmp_path):
|
||||||
|
"""Test that JSON files are saved with pretty printing (indentation)"""
|
||||||
|
import json
|
||||||
|
|
||||||
|
client = await aiohttp_client(app)
|
||||||
|
|
||||||
|
# Create a compact JSON workflow
|
||||||
|
workflow_data = {
|
||||||
|
"nodes": [
|
||||||
|
{"id": "1", "type": "LoadImage", "inputs": {"image": "test.png"}},
|
||||||
|
{"id": "2", "type": "SaveImage", "inputs": {"images": ["1", 0]}}
|
||||||
|
],
|
||||||
|
"metadata": {"version": "1.0", "author": "test"}
|
||||||
|
}
|
||||||
|
compact_json = json.dumps(workflow_data).encode('utf-8')
|
||||||
|
|
||||||
|
# Save as JSON file
|
||||||
|
resp = await client.post("/userdata/workflow.json", data=compact_json)
|
||||||
|
assert resp.status == 200
|
||||||
|
|
||||||
|
# Read the saved file and verify it's pretty-printed
|
||||||
|
with open(tmp_path / "workflow.json", "r", encoding='utf-8') as f:
|
||||||
|
saved_content = f.read()
|
||||||
|
|
||||||
|
# Verify the file contains indentation (pretty-printed)
|
||||||
|
assert " " in saved_content # Should have 2-space indentation
|
||||||
|
assert "\n" in saved_content # Should have newlines
|
||||||
|
|
||||||
|
# Verify the content is still valid JSON and matches original data
|
||||||
|
saved_data = json.loads(saved_content)
|
||||||
|
assert saved_data == workflow_data
|
||||||
|
|
||||||
|
# Verify it's actually formatted (not compact)
|
||||||
|
# Compact JSON would be much shorter
|
||||||
|
assert len(saved_content) > len(compact_json)
|
||||||
|
|
||||||
|
|
||||||
|
async def test_post_userdata_json_invalid_fallback(aiohttp_client, app, tmp_path):
|
||||||
|
"""Test that invalid JSON is saved as-is without error"""
|
||||||
|
client = await aiohttp_client(app)
|
||||||
|
|
||||||
|
# Create invalid JSON content
|
||||||
|
invalid_json = b'{"invalid": json content}'
|
||||||
|
|
||||||
|
# Save as JSON file - should not fail
|
||||||
|
resp = await client.post("/userdata/invalid.json", data=invalid_json)
|
||||||
|
assert resp.status == 200
|
||||||
|
|
||||||
|
# Verify file was saved as-is
|
||||||
|
with open(tmp_path / "invalid.json", "rb") as f:
|
||||||
|
assert f.read() == invalid_json
|
||||||
|
|
||||||
|
|
||||||
|
async def test_post_userdata_non_json_unchanged(aiohttp_client, app, tmp_path):
|
||||||
|
"""Test that non-JSON files are saved unchanged"""
|
||||||
|
client = await aiohttp_client(app)
|
||||||
|
|
||||||
|
# Create binary content
|
||||||
|
binary_content = b'\x00\x01\x02\x03\x04\x05'
|
||||||
|
|
||||||
|
# Save as non-JSON file
|
||||||
|
resp = await client.post("/userdata/test.bin", data=binary_content)
|
||||||
|
assert resp.status == 200
|
||||||
|
|
||||||
|
# Verify file was saved exactly as-is
|
||||||
|
with open(tmp_path / "test.bin", "rb") as f:
|
||||||
|
assert f.read() == binary_content
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user