1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
| @bp_edit.route('/apply_visual_transform', methods=['POST']) def apply_visual_transform(): if not session.get('is_testuser_account'): return jsonify({'success': False, 'message': 'Feature is still in development.'}), 403 if 'username' not in session: return jsonify({'success': False, 'message': 'Unauthorized. Please log in.'}), 401 request_payload = request.get_json() image_id = request_payload.get('imageId') transform_type = request_payload.get('transformType') params = request_payload.get('params', {}) if not image_id or not transform_type: return jsonify({'success': False, 'message': 'Image ID and transform type are required.'}), 400 application_data = _load_data() original_image = next((img for img in application_data['images'] if img['id'] == image_id and img['uploadedBy'] == session['username']), None) if not original_image: return jsonify({'success': False, 'message': 'Image not found or unauthorized to transform.'}), 404 original_filepath = os.path.join(UPLOAD_FOLDER, original_image['filename']) if not os.path.exists(original_filepath): return jsonify({'success': False, 'message': 'Original image file not found on server.'}), 404 if original_image.get('actual_mimetype') not in ALLOWED_TRANSFORM_MIME_TYPES: return jsonify({'success': False, 'message': f"Transformation not supported for '{original_image.get('actual_mimetype')}' files."}), 400 original_ext = original_image['filename'].rsplit('.', 1)[1].lower() if original_ext not in ALLOWED_IMAGE_EXTENSIONS_FOR_TRANSFORM: return jsonify({'success': False, 'message': f"Transformation not supported for {original_ext.upper()} files."}), 400 try: unique_output_filename = f"transformed_{uuid.uuid4()}.{original_ext}" output_filename_in_db = os.path.join('admin', 'transformed', unique_output_filename) output_filepath = os.path.join(UPLOAD_FOLDER, output_filename_in_db) if transform_type == 'crop': x = str(params.get('x')) y = str(params.get('y')) width = str(params.get('width')) height = str(params.get('height')) command = f"{IMAGEMAGICK_CONVERT_PATH} {original_filepath} -crop {width}x{height}+{x}+{y} {output_filepath}" subprocess.run(command, capture_output=True, text=True, shell=True, check=True) elif transform_type == 'rotate': degrees = str(params.get('degrees')) command = [IMAGEMAGICK_CONVERT_PATH, original_filepath, '-rotate', degrees, output_filepath] subprocess.run(command, capture_output=True, text=True, check=True) elif transform_type == 'saturation': value = str(params.get('value')) command = [IMAGEMAGICK_CONVERT_PATH, original_filepath, '-modulate', f"100,{float(value)*100},100", output_filepath] subprocess.run(command, capture_output=True, text=True, check=True) elif transform_type == 'brightness': value = str(params.get('value')) command = [IMAGEMAGICK_CONVERT_PATH, original_filepath, '-modulate', f"100,100,{float(value)*100}", output_filepath] subprocess.run(command, capture_output=True, text=True, check=True) elif transform_type == 'contrast': value = str(params.get('value')) command = [IMAGEMAGICK_CONVERT_PATH, original_filepath, '-modulate', f"{float(value)*100},{float(value)*100},{float(value)*100}", output_filepath] subprocess.run(command, capture_output=True, text=True, check=True) else: return jsonify({'success': False, 'message': 'Unsupported transformation type.'}), 400 new_image_id = str(uuid.uuid4()) new_image_entry = { 'id': new_image_id, 'filename': output_filename_in_db, 'url': f'/uploads/{output_filename_in_db}', 'title': f"Transformed: {original_image['title']}", 'description': f"Transformed from {original_image['title']} ({transform_type}).", 'timestamp': datetime.now().isoformat(), 'uploadedBy': session['username'], 'uploadedByDisplayId': session['displayId'], 'group': 'Transformed', 'type': 'transformed', 'original_id': original_image['id'], 'actual_mimetype': get_file_mimetype(output_filepath) } application_data['images'].append(new_image_entry) if not any(coll['name'] == 'Transformed' for coll in application_data.get('image_collections', [])): application_data.setdefault('image_collections', []).append({'name': 'Transformed'}) _save_data(application_data) return jsonify({'success': True, 'message': 'Image transformed successfully!', 'newImageUrl': new_image_entry['url'], 'newImageId': new_image_id}), 200 except subprocess.CalledProcessError as e: return jsonify({'success': False, 'message': f'Image transformation failed: {e.stderr.strip()}'}), 500 except Exception as e: return jsonify({'success': False, 'message': f'An unexpected error occurred during transformation: {str(e)}'}), 500
@bp_edit.route('/convert_image', methods=['POST']) def convert_image(): if not session.get('is_testuser_account'): return jsonify({'success': False, 'message': 'Feature is still in development.'}), 403 if 'username' not in session: return jsonify({'success': False, 'message': 'Unauthorized. Please log in.'}), 401 request_payload = request.get_json() image_id = request_payload.get('imageId') target_format = request_payload.get('targetFormat') if not image_id or not target_format: return jsonify({'success': False, 'message': 'Image ID and target format are required.'}), 400 if target_format.lower() not in ALLOWED_MEDIA_EXTENSIONS: return jsonify({'success': False, 'message': 'Target format not allowed.'}), 400 application_data = _load_data() original_image = next((img for img in application_data['images'] if img['id'] == image_id and img['uploadedBy'] == session['username']), None) if not original_image: return jsonify({'success': False, 'message': 'Image not found or unauthorized to convert.'}), 404 original_filepath = os.path.join(UPLOAD_FOLDER, original_image['filename']) if not os.path.exists(original_filepath): return jsonify({'success': False, 'message': 'Original image file not found on server.'}), 404 current_ext = original_image['filename'].rsplit('.', 1)[1].lower() if target_format.lower() == current_ext: return jsonify({'success': False, 'message': f'Image is already in {target_format.upper()} format.'}), 400 try: unique_output_filename = f"converted_{uuid.uuid4()}.{target_format.lower()}" output_filename_in_db = os.path.join('admin', 'converted', unique_output_filename) output_filepath = os.path.join(UPLOAD_FOLDER, output_filename_in_db) command = [IMAGEMAGICK_CONVERT_PATH, original_filepath, output_filepath] subprocess.run(command, capture_output=True, text=True, check=True) new_file_md5 = _calculate_file_md5(output_filepath) if new_file_md5 is None: os.remove(output_filepath) return jsonify({'success': False, 'message': 'Failed to calculate MD5 hash for new file.'}), 500 for img_entry in application_data['images']: if img_entry.get('type') == 'converted' and img_entry.get('original_id') == original_image['id']: existing_converted_filepath = os.path.join(UPLOAD_FOLDER, img_entry['filename']) existing_file_md5 = img_entry.get('md5_hash') if existing_file_md5 is None: existing_file_md5 = _calculate_file_md5(existing_converted_filepath) if existing_file_md5: img_entry['md5_hash'] = existing_file_md5 _save_data(application_data) if existing_file_md5 == new_file_md5: os.remove(output_filepath) return jsonify({'success': False, 'message': 'An identical converted image already exists.'}), 409 new_image_id = str(uuid.uuid4()) new_image_entry = { 'id': new_image_id, 'filename': output_filename_in_db, 'url': f'/uploads/{output_filename_in_db}', 'title': f"Converted: {original_image['title']} to {target_format.upper()}", 'description': f"Converted from {original_image['filename']} to {target_format.upper()}.", 'timestamp': datetime.now().isoformat(), 'uploadedBy': session['username'], 'uploadedByDisplayId': session['displayId'], 'group': 'Converted', 'type': 'converted', 'original_id': original_image['id'], 'actual_mimetype': get_file_mimetype(output_filepath), 'md5_hash': new_file_md5 } application_data['images'].append(new_image_entry) if not any(coll['name'] == 'Converted' for coll in application_data.get('image_collections', [])): application_data.setdefault('image_collections', []).append({'name': 'Converted'}) _save_data(application_data) return jsonify({'success': True, 'message': 'Image converted successfully!', 'newImageUrl': new_image_entry['url'], 'newImageId': new_image_id}), 200 except subprocess.CalledProcessError as e: if os.path.exists(output_filepath): os.remove(output_filepath) return jsonify({'success': False, 'message': f'Image conversion failed: {e.stderr.strip()}'}), 500 except Exception as e: return jsonify({'success': False, 'message': f'An unexpected error occurred during conversion: {str(e)}'}), 500
|