diff --git a/client/src/ImageUpload/index.jsx b/client/src/ImageUpload/index.jsx
index e82f6e2..231470a 100644
--- a/client/src/ImageUpload/index.jsx
+++ b/client/src/ImageUpload/index.jsx
@@ -81,23 +81,36 @@ const ImageUpload = ({ onImageUpload, settingsImages }) => {
}
};
- const deleteImage = async (filename) => {
+ const deleteImage = async (filename, isNotFound = false) => {
try {
- const response = await axios.delete(`${config.SERVER_URL}/uploads/${filename}`);
- showSnackbar(response.data.message, 'success');
-
- // Update the state to remove the deleted image
- const updatedImages = images.filter((image) => image.filename !== filename);
- setImages(updatedImages);
- onImageUpload(updatedImages);
- } catch (error) {
- if (error?.response?.data) {
- showSnackbar(error.response.data.message, 'error');
- } else {
- showSnackbar(t("error.server_connection"), 'error');
+ if (isNotFound) {
+ const updatedImages = images.filter((image) => image.filename !== filename);
+ setImages(updatedImages);
+ onImageUpload(updatedImages);
+ } else {
+ const response = await axios.delete(`${config.SERVER_URL}/uploads/${filename}`);
+ showSnackbar(response.data.message, 'success');
+
+ // Update the state to remove the deleted image
+ const updatedImages = images.filter((image) => image.filename !== filename);
+ setImages(updatedImages);
+ onImageUpload(updatedImages);
+ }
+ } catch (error) {
+ if (error?.response?.data) {
+ showSnackbar(error.response.data.message, 'error');
+ } else {
+ showSnackbar(t("error.server_connection"), 'error');
+ }
+ console.error('Error deleting image:', error);
}
- console.error('Error deleting image:', error);
- }
+ };
+
+ const handleImageError = (index) => {
+ const updatedImages = [...images];
+ updatedImages[index].isNotFound = true;
+ setImages(updatedImages);
+ showSnackbar(t("error.image_not_found"), 'error');
};
const handleRemoveImage = (index) => {
@@ -110,7 +123,7 @@ const ImageUpload = ({ onImageUpload, settingsImages }) => {
}
}
if (imageToRemove && imageToRemove.filename) {
- deleteImage(imageToRemove.filename);
+ deleteImage(imageToRemove.filename, imageToRemove.isNotFound);
} else {
console.error('Error deleting image: imageToRemove or imageToRemove.filename is undefined');
}
@@ -178,6 +191,7 @@ const ImageUpload = ({ onImageUpload, settingsImages }) => {
handleImageError(index)}
style={{
width: '100px',
height: '100px',
diff --git a/client/src/Localization/translation-de-DE.js b/client/src/Localization/translation-de-DE.js
index dc73e58..d965b7f 100644
--- a/client/src/Localization/translation-de-DE.js
+++ b/client/src/Localization/translation-de-DE.js
@@ -78,7 +78,8 @@ const translationDeDE = {
"hide_region": "Region ausblenden",
"show_region": "Region anzeigen",
"expand_selection": "Auswahl erweitern",
- "collapse_selection": "Auswahl verkleinern"
+ "collapse_selection": "Auswahl verkleinern",
+ "error.image_not_found": "Bild nicht gefunden",
};
export default translationDeDE;
diff --git a/client/src/Localization/translation-en-EN.js b/client/src/Localization/translation-en-EN.js
index 160254a..2828725 100644
--- a/client/src/Localization/translation-en-EN.js
+++ b/client/src/Localization/translation-en-EN.js
@@ -80,6 +80,7 @@ const translationEnEN = {
"show_region": "Show region",
"expand_selection": "Expand selection",
"collapse_selection": "Collapse selection",
+ "error.image_not_found": "Image not found",
};
export default translationEnEN;
diff --git a/client/src/SnackbarContext/index.jsx b/client/src/SnackbarContext/index.jsx
index 4a70eae..f416e64 100644
--- a/client/src/SnackbarContext/index.jsx
+++ b/client/src/SnackbarContext/index.jsx
@@ -1,39 +1,43 @@
import { createContext, useState, useContext } from 'react';
import Snackbar from '@mui/material/Snackbar';
import Alert from '@mui/material/Alert';
-
+import { Box } from '@mui/material';
const SnackbarContext = createContext({
- open: false,
- message: '',
- severity: 'info',
- handleClose: () => {},
+ showSnackbar: () => {},
});
export const SnackbarProvider = ({ children }) => {
- const [open, setOpen] = useState(false);
- const [message, setMessage] = useState('');
- const [severity, setSeverity] = useState('info');
+ const [messages, setMessages] = useState([]);
- const handleClose = () => {
- setOpen(false);
+ const showSnackbar = (message, severity = 'info') => {
+ setMessages((prevMessages) => [
+ ...prevMessages,
+ { id: new Date().getTime(), message, severity },
+ ]);
};
- const showSnackbar = (message, newSeverity = 'info') => {
- setMessage(message);
- setSeverity(newSeverity);
- setOpen(true);
+ const handleClose = (index) => {
+ setMessages((prevMessages) => prevMessages.filter((msg, idx) => idx !== index));
};
return (
-
-
-
- {message}
-
-
+
+
+ {messages.map((msg, index) => (
+
+ handleClose(index)} severity={msg.severity}>
+ {msg.message}
+
+
+ ))}
+
{children}
);
diff --git a/server/app.py b/server/app.py
index b50818b..56628b2 100644
--- a/server/app.py
+++ b/server/app.py
@@ -98,7 +98,11 @@ def upload_file():
@app.route('/uploads/', methods=['GET'])
def uploaded_file(filename):
- return send_from_directory(app.config['UPLOAD_FOLDER'], filename)
+ file_path = os.path.join(app.config['UPLOAD_FOLDER'], filename)
+ if os.path.exists(file_path):
+ return send_from_directory(app.config['UPLOAD_FOLDER'], filename)
+ else:
+ return jsonify({"status": "error", "message": "File not found"}), 404
@app.route('/uploads/', methods=['DELETE'])
def delete_file(filename):
@@ -698,6 +702,11 @@ def get_images_info():
print('Error:', e)
return jsonify({'error': str(e)}), 500
+@app.errorhandler(404)
+def not_found(error):
+ return jsonify({"status": "error", "message": "Resource not found"}), 404
+
+
@app.route('/', methods=['GET'])
def main():
return '''
diff --git a/server/tests/test_app.py b/server/tests/test_app.py
index 9b0019a..99d7955 100644
--- a/server/tests/test_app.py
+++ b/server/tests/test_app.py
@@ -1,4 +1,5 @@
import unittest
+from unittest.mock import patch
# import os
import json
from io import BytesIO
@@ -42,6 +43,14 @@ def test_images_name(self):
self.assertEqual(response.status_code, 200)
self.assertIn(b'configuration', response.data)
+ def test_uploaded_file_not_found(self):
+ with patch('os.path.exists') as mock_exists:
+ mock_exists.return_value = False
+ response = self.app.get('/uploads/example.png')
+ self.assertEqual(response.status_code, 404)
+ data = response.get_json()
+ self.assertEqual(data['status'], 'error')
+ self.assertEqual(data['message'], 'File not found')
# def test_save_annotate_info_success(self):
# annotate_data = {