fix of the file upload
This commit is contained in:
+9
-11
@@ -5392,7 +5392,6 @@ def upload_item():
|
|||||||
error_count = 0
|
error_count = 0
|
||||||
skipped_count = 0
|
skipped_count = 0
|
||||||
|
|
||||||
# Create a structured log entry for upload session
|
|
||||||
upload_session_id = str(uuid.uuid4())[:8]
|
upload_session_id = str(uuid.uuid4())[:8]
|
||||||
app.logger.info(f"Starting image upload session {upload_session_id} - Files: {len(images)}, User: {encrypt_text(username)}")
|
app.logger.info(f"Starting image upload session {upload_session_id} - Files: {len(images)}, User: {encrypt_text(username)}")
|
||||||
|
|
||||||
@@ -5410,7 +5409,6 @@ def upload_item():
|
|||||||
app.logger.info(f"{image_log_prefix} Processing: {image.filename}")
|
app.logger.info(f"{image_log_prefix} Processing: {image.filename}")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# 1. Validation
|
|
||||||
is_allowed, error_message = allowed_file(image.filename, image, max_size_mb=cfg.IMAGE_MAX_UPLOAD_MB)
|
is_allowed, error_message = allowed_file(image.filename, image, max_size_mb=cfg.IMAGE_MAX_UPLOAD_MB)
|
||||||
if not is_allowed:
|
if not is_allowed:
|
||||||
app.logger.warning(f"{image_log_prefix} Validation failed: {error_message}")
|
app.logger.warning(f"{image_log_prefix} Validation failed: {error_message}")
|
||||||
@@ -5421,29 +5419,29 @@ def upload_item():
|
|||||||
|
|
||||||
secure_name = secure_filename(image.filename)
|
secure_name = secure_filename(image.filename)
|
||||||
|
|
||||||
# 2. Read directly into memory (Bypasses OS-level file quirks and iOS temp-file bugs)
|
image.seek(0)
|
||||||
|
|
||||||
image_bytes = image.read()
|
image_bytes = image.read()
|
||||||
|
|
||||||
# 3. Process, standardize, and optimize using Pillow in-memory
|
if not image_bytes:
|
||||||
|
app.logger.error(f"{image_log_prefix} Failed to read image (0 bytes).")
|
||||||
|
error_count += 1
|
||||||
|
continue
|
||||||
|
|
||||||
optimized_io = io.BytesIO()
|
optimized_io = io.BytesIO()
|
||||||
with Image.open(io.BytesIO(image_bytes)) as img:
|
with Image.open(io.BytesIO(image_bytes)) as img:
|
||||||
# Ensure safe color mode
|
|
||||||
if img.mode not in ('RGB', 'RGBA'):
|
if img.mode not in ('RGB', 'RGBA'):
|
||||||
img = img.convert('RGBA')
|
img = img.convert('RGBA')
|
||||||
|
|
||||||
# Standardize dimensions (e.g., max width 500px)
|
|
||||||
max_width = 500
|
max_width = 500
|
||||||
if img.width > max_width:
|
if img.width > max_width:
|
||||||
ratio = max_width / img.width
|
ratio = max_width / img.width
|
||||||
new_size = (max_width, int(img.height * ratio))
|
new_size = (max_width, int(img.height * ratio))
|
||||||
img = img.resize(new_size, Image.Resampling.LANCZOS)
|
img = img.resize(new_size, Image.Resampling.LANCZOS)
|
||||||
|
|
||||||
# Export as WebP to a memory buffer
|
|
||||||
# (WebP naturally handles transparency, drastically reduces size, and bypasses PNG signature corruption)
|
|
||||||
img.save(optimized_io, format='WEBP', quality=85, optimize=True)
|
img.save(optimized_io, format='WEBP', quality=85, optimize=True)
|
||||||
|
|
||||||
optimized_io.seek(0)
|
optimized_io.seek(0)
|
||||||
|
|
||||||
new_filename = f"{uuid.uuid4().hex}_{int(time.time())}.webp"
|
new_filename = f"{uuid.uuid4().hex}_{int(time.time())}.webp"
|
||||||
|
|
||||||
file_id = fs.put(
|
file_id = fs.put(
|
||||||
@@ -5456,9 +5454,9 @@ def upload_item():
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
image_filenames.append(file_id)
|
image_filenames.append(new_filename)
|
||||||
processed_count += 1
|
|
||||||
|
|
||||||
|
processed_count += 1
|
||||||
final_size_kb = len(optimized_io.getvalue()) / 1024
|
final_size_kb = len(optimized_io.getvalue()) / 1024
|
||||||
app.logger.info(
|
app.logger.info(
|
||||||
f"{image_log_prefix} Saved to GridFS as {new_filename} | ID: {file_id} | Size: {final_size_kb:.1f}KB")
|
f"{image_log_prefix} Saved to GridFS as {new_filename} | ID: {file_id} | Size: {final_size_kb:.1f}KB")
|
||||||
|
|||||||
Reference in New Issue
Block a user