From 631d11c523db261c8a4817a9752bcfe1eb23dbb1 Mon Sep 17 00:00:00 2001 From: sumn2u Date: Tue, 11 Jun 2024 10:23:57 -0500 Subject: [PATCH] clear storage information on exit --- client/src/MainLayout/index.jsx | 19 +++++++++++++++-- client/src/utils/get-data-from-server.js | 15 +++++++++++++- server/app.py | 26 ++++++++++++++++++++++++ server/db/database/imageInfo.csv | 2 -- server/db/database/polygonInfo.csv | 1 - server/db/db_handler.py | 12 +++++++++++ server/tests/test_app.py | 6 +++++- 7 files changed, 74 insertions(+), 7 deletions(-) diff --git a/client/src/MainLayout/index.jsx b/client/src/MainLayout/index.jsx index 0199c24..048eee1 100644 --- a/client/src/MainLayout/index.jsx +++ b/client/src/MainLayout/index.jsx @@ -25,6 +25,8 @@ import {withHotKeys} from "react-hotkeys" import {Save, ExitToApp} from "@mui/icons-material" import capitalize from "lodash/capitalize" import { useTranslation } from "react-i18next" +import { clear_db } from "../utils/get-data-from-server" +import { useSnackbar} from "../SnackbarContext/index.jsx" const emptyArr = [] const theme = createTheme() @@ -55,6 +57,7 @@ export const MainLayout = ({ enabledRegionProps, }) => { const settings = useSettings() + const { showSnackbar } = useSnackbar(); const { t } = useTranslation(); const memoizedActionFns = useRef({}) const action = (type, ...params) => { @@ -98,10 +101,22 @@ export const MainLayout = ({ } }, []) - const logout = () => { - settings.changeSetting('settings', null) + const reloadApp = () => { + settings.changeSetting('settings', null); window.location.reload(); } + + const logout = async () => { + try { + const response = await clear_db(); + showSnackbar(response.message, 'success'); + await new Promise(resolve => setTimeout(resolve, 500)); // Wait for 500 milliseconds + } catch (error) { + showSnackbar(error.message, 'error'); + } + reloadApp() + }; + const canvas = ( { reject(error?.response); // Reject with error data }); }); - }; \ No newline at end of file + }; + + +export const clear_db = () => { + return new Promise((resolve, reject) => { + axios.post(`${import.meta.env.VITE_SERVER_URL}/clearSession`) + .then(response => { + resolve(response.data); + }) + .catch(error => { + reject(error?.response); // Reject with error data + }); + }) +} \ No newline at end of file diff --git a/server/app.py b/server/app.py index 83bb776..1b8bdcf 100644 --- a/server/app.py +++ b/server/app.py @@ -15,6 +15,7 @@ from PIL import Image, ImageDraw import os import traceback +import shutil from dotenv import load_dotenv app = Flask(__name__) @@ -214,6 +215,31 @@ def images_name(): print('Error:', e) return jsonify({'error': str(e)}), 500 + +def clear_upload_folder(): + try: + for root, dirs, files in os.walk(UPLOAD_FOLDER): + for file in files: + file_path = os.path.join(root, file) + os.remove(file_path) + for dir in dirs: + dir_path = os.path.join(root, dir) + shutil.rmtree(dir_path) + except Exception as e: + print(f"Error clearing upload folder: {str(e)}") + + +@app.route('/clearSession', methods=['POST']) +@cross_origin(origin=client_url, headers=['Content-Type']) +def clear_session(): + try: + dbModule.clear_db() + clear_upload_folder() + return jsonify({"message": "Database cleared successfully."}), 200 + + except Exception as e: + return jsonify({"status": "error", "message": str(e)}), 500 + @app.route('/download_configuration', methods=['POST']) @cross_origin(origin=client_url, headers=['Content-Type']) def download_configuration(): diff --git a/server/db/database/imageInfo.csv b/server/db/database/imageInfo.csv index d1f52e3..237625f 100644 --- a/server/db/database/imageInfo.csv +++ b/server/db/database/imageInfo.csv @@ -1,3 +1 @@ image-name,selected-classes,comment,image-original-height,image-original-width,image-src,processed -['orange'],['Apple'],[''],[249],[320],['http://127.0.0.1:5000/uploads/orange.png'],[1] -['orange'],['Apple'],[''],[249],[320],['http://127.0.0.1:5000/uploads/orange.png'],[1] diff --git a/server/db/database/polygonInfo.csv b/server/db/database/polygonInfo.csv index e3e198d..31c2047 100644 --- a/server/db/database/polygonInfo.csv +++ b/server/db/database/polygonInfo.csv @@ -1,2 +1 @@ region-id,image-src,class,comment,tags,points -9937965146177845,http://127.0.0.1:5000/uploads/orange.png,Orange,,,0.6928366035182679-0.6305818673883626;0.7265307848443843-0.5372124492557511;0.7465367050067659-0.37483085250338294;0.6759895128552098-0.2313937753721245;0.4727714817320704-0.12178619756427606;0.3032476319350474-0.2124492557510149;0.21585334912043302-0.4059539918809202;0.21058863328822733-0.5656292286874154;0.25902401894451965-0.6752368064952639;0.33167709742895807-0.7415426251691475;0.5296304127198918-0.7564276048714479 diff --git a/server/db/db_handler.py b/server/db/db_handler.py index d9fe93e..1f1715c 100644 --- a/server/db/db_handler.py +++ b/server/db/db_handler.py @@ -240,6 +240,18 @@ def createCategories(self, labels): create_categories(labels) + def clear_db(self): + # Clear CSV files + empty_images_info = pd.DataFrame(columns=['image-name', 'selected-classes', 'comment', 'image-original-height', 'image-original-width', 'image-src', 'processed']) + empty_circle_regions = pd.DataFrame(columns=['region-id', 'image-src', 'class', 'comment', 'tags', 'rx', 'ry', 'rw', 'rh']) + empty_box_regions = pd.DataFrame(columns=['region-id', 'image-src', 'class', 'comment', 'tags', 'x', 'y', 'w', 'h']) + empty_polygon_regions = pd.DataFrame(columns=['region-id', 'image-src', 'class', 'comment', 'tags', 'points']) + + empty_images_info.to_csv(imageInfoName, index=False) + empty_circle_regions.to_csv(circleRegionInfo, index=False) + empty_box_regions.to_csv(boxRegionInfo, index=False) + empty_polygon_regions.to_csv(polygonInfo, index=False) + def __str__(self): return 'database' diff --git a/server/tests/test_app.py b/server/tests/test_app.py index 0c2be14..b080859 100644 --- a/server/tests/test_app.py +++ b/server/tests/test_app.py @@ -72,7 +72,11 @@ def test_save_annotate_info_failure(self): self.assertEqual(response.status_code, 500) self.assertIn(b'Failed to save annotation data', response.data) - + def test_clear_session_success(self): + response = self.app.post('/clearSession') + data = json.loads(response.data.decode('utf-8')) + self.assertEqual(response.status_code, 200) + self.assertEqual(data['message'], 'Database cleared successfully.') def test_images_name_no_image_name(self): response = self.app.post('/imagesName', data=json.dumps({}), content_type='application/json')