From 4f1158c1445daae4e5e0bbba2215c5c4b8109b15 Mon Sep 17 00:00:00 2001 From: Andreas Knuth Date: Fri, 29 Nov 2024 17:10:20 +0100 Subject: [PATCH] nur noch eine Tabelle Deck --- deck_endpoints.py | 179 ++++++++++++++++++++++++++-------------------- 1 file changed, 103 insertions(+), 76 deletions(-) diff --git a/deck_endpoints.py b/deck_endpoints.py index a5c2fe9..fa10c07 100644 --- a/deck_endpoints.py +++ b/deck_endpoints.py @@ -18,7 +18,7 @@ def get_db_connection(): conn.row_factory = sqlite3.Row return conn -# Erstellen der Tabellen, falls sie nicht existieren +# Erstellen der Tabelle Deck, falls sie nicht existiert def init_db(): conn = get_db_connection() cursor = conn.cursor() @@ -26,21 +26,13 @@ def init_db(): cursor.execute(''' CREATE TABLE IF NOT EXISTS Deck ( id INTEGER PRIMARY KEY AUTOINCREMENT, - deckname TEXT UNIQUE NOT NULL - ) - ''') - # Tabelle Image erstellen - cursor.execute(''' - CREATE TABLE IF NOT EXISTS Image ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - deckid INTEGER, + deckname TEXT NOT NULL, bildname TEXT, iconindex INTEGER, x1 REAL, x2 REAL, y1 REAL, - y2 REAL, - FOREIGN KEY(deckid) REFERENCES Deck(id) + y2 REAL ) ''') conn.commit() @@ -48,7 +40,7 @@ def init_db(): def clean_debug_directories(): """ - Löscht alle Verzeichnisse unter 'debug_images', die keinen Eintrag in der Image-Tabelle haben. + Löscht alle Verzeichnisse unter 'debug_images', die keinen Eintrag in der Deck-Tabelle mit bildname haben. """ debug_base_dir = 'debug_images' if not os.path.exists(debug_base_dir): @@ -58,7 +50,7 @@ def clean_debug_directories(): try: conn = get_db_connection() cursor = conn.cursor() - cursor.execute('SELECT DISTINCT bildname FROM Image') + cursor.execute('SELECT DISTINCT bildname FROM Deck WHERE bildname IS NOT NULL') bildnames = {row['bildname'] for row in cursor.fetchall()} conn.close() except sqlite3.Error as e: @@ -98,65 +90,68 @@ def create_deck(): conn = get_db_connection() cursor = conn.cursor() try: + # Ein neuer Eintrag für das Deck ohne Bilddaten cursor.execute('INSERT INTO Deck (deckname) VALUES (?)', (deckname,)) conn.commit() deck_id = cursor.lastrowid conn.close() return jsonify({'status': 'success', 'deck_id': deck_id}), 201 - except sqlite3.IntegrityError: + except sqlite3.Error as e: conn.close() - return jsonify({'error': 'Deckname already exists'}), 400 + logger.error(f"Datenbankfehler beim Erstellen des Decks: {e}") + return jsonify({'error': 'Database error', 'details': str(e)}), 500 @deck_bp.route('/api/decks', methods=['GET']) def get_decks(): conn = get_db_connection() cursor = conn.cursor() - decks = cursor.execute('SELECT * FROM Deck').fetchall() - deck_list = [] - for deck in decks: - deck_id = deck['id'] - deck_name = deck['deckname'] - # Alle Images für dieses Deck abrufen - images = cursor.execute(''' - SELECT - bildname AS name, - iconindex, - x1, - x2, - y1, - y2 - FROM Image - WHERE deckid = ? - ''', (deck_id,)).fetchall() - images_list = [dict(image) for image in images] - # Deck mit Namen und zugehörigen Images hinzufügen - deck_dict = { - 'name': deck_name, - 'images': images_list - } - deck_list.append(deck_dict) + # Alle Einträge abrufen + entries = cursor.execute('SELECT * FROM Deck').fetchall() conn.close() + + decks = {} + for entry in entries: + deckname = entry['deckname'] + if deckname not in decks: + decks[deckname] = { + 'name': deckname, + 'images': [] + } + if entry['bildname']: + image = { + 'name': entry['bildname'], + 'iconindex': entry['iconindex'], + 'x1': entry['x1'], + 'x2': entry['x2'], + 'y1': entry['y1'], + 'y2': entry['y2'] + } + decks[deckname]['images'].append(image) + + deck_list = list(decks.values()) return jsonify(deck_list) - @deck_bp.route('/api/decks/', methods=['DELETE']) def delete_deck(deckname): conn = get_db_connection() cursor = conn.cursor() - # Zuerst die Images löschen, die zu diesem Deck gehören - cursor.execute('SELECT id FROM Deck WHERE deckname = ?', (deckname,)) - deck = cursor.fetchone() - if deck: - deck_id = deck['id'] - cursor.execute('DELETE FROM Image WHERE deckid = ?', (deck_id,)) - # Dann das Deck löschen - cursor.execute('DELETE FROM Deck WHERE id = ?', (deck_id,)) + try: + # Überprüfen, ob das Deck existiert + cursor.execute('SELECT COUNT(*) as count FROM Deck WHERE deckname = ?', (deckname,)) + result = cursor.fetchone() + if result['count'] == 0: + conn.close() + return jsonify({'error': 'Deck not found'}), 404 + + # Löschen aller Einträge mit dem gegebenen deckname + cursor.execute('DELETE FROM Deck WHERE deckname = ?', (deckname,)) conn.commit() conn.close() return jsonify({'status': 'success'}), 200 - else: + except sqlite3.Error as e: conn.close() - return jsonify({'error': 'Deck not found'}), 404 + logger.error(f"Datenbankfehler beim Löschen des Decks '{deckname}': {e}") + return jsonify({'error': 'Database error', 'details': str(e)}), 500 # ------ # Image - POST, GET, DELETE @@ -186,20 +181,24 @@ def update_image(): cursor = conn.cursor() try: - # Deck-ID anhand des Decknamens abrufen - cursor.execute('SELECT id FROM Deck WHERE deckname = ?', (deckname,)) - deck = cursor.fetchone() - if not deck: + # Überprüfen, ob das Deck existiert + cursor.execute('SELECT COUNT(*) as count FROM Deck WHERE deckname = ?', (deckname,)) + result = cursor.fetchone() + if result['count'] == 0: + conn.close() return jsonify({'error': 'Deck not found'}), 404 - deck_id = deck['id'] + # 1. Lösche alle Einträge für das Deck ohne bildname + cursor.execute('DELETE FROM Deck WHERE deckname = ? AND bildname IS NULL', (deckname,)) + inserted_image_ids = [] - # Durch jede Box iterieren und einen Eintrag in der Image-Tabelle erstellen + # 2. Füge neue Image-Einträge hinzu for index, box in enumerate(boxes): # Überprüfen, ob alle erforderlichen Koordinaten vorhanden sind box_fields = ['x1', 'x2', 'y1', 'y2'] if not all(field in box for field in box_fields): + conn.close() return jsonify({'error': 'Missing fields in one of the boxes'}), 400 x1 = box['x1'] @@ -207,13 +206,13 @@ def update_image(): y1 = box['y1'] y2 = box['y2'] - # Setzen des iconindex auf den aktuellen Index der Box + # Setzen des iconindex auf den aktuellen Index der Box iconindex = index cursor.execute(''' - INSERT INTO Image (deckid, bildname, iconindex, x1, x2, y1, y2) + INSERT INTO Deck (deckname, bildname, iconindex, x1, x2, y1, y2) VALUES (?, ?, ?, ?, ?, ?, ?) - ''', (deck_id, bildname, iconindex, x1, x2, y1, y2)) + ''', (deckname, bildname, iconindex, x1, x2, y1, y2)) inserted_image_ids.append(cursor.lastrowid) conn.commit() @@ -221,6 +220,7 @@ def update_image(): except sqlite3.Error as e: conn.rollback() + logger.error(f"Datenbankfehler beim Aktualisieren der Images für Deck '{deckname}': {e}") return jsonify({'error': 'Database error', 'details': str(e)}), 500 finally: @@ -229,7 +229,8 @@ def update_image(): @deck_bp.route('/api/decks/image/', methods=['GET']) def get_images_by_bildname(bildname): conn = get_db_connection() - images = conn.execute('SELECT * FROM Image WHERE bildname = ?', (bildname,)).fetchall() + cursor = conn.cursor() + images = cursor.execute('SELECT * FROM Deck WHERE bildname = ?', (bildname,)).fetchall() conn.close() image_list = [dict(image) for image in images] return jsonify(image_list) @@ -237,7 +238,8 @@ def get_images_by_bildname(bildname): @deck_bp.route('/api/decks/image/', methods=['DELETE']) def delete_images_by_bildname(bildname): """ - Löscht alle Einträge in der Image-Tabelle für den gegebenen bildname. + Löscht alle Einträge in der Deck-Tabelle für den gegebenen bildname. + Falls es das letzte Image für ein Deck ist, wird ein neuer Deck-Eintrag erstellt. Optional: Löscht das zugehörige Debug-Verzeichnis, wenn keine weiteren Einträge bestehen. """ try: @@ -249,22 +251,41 @@ def delete_images_by_bildname(bildname): conn = get_db_connection() cursor = conn.cursor() - # Überprüfen, ob es Einträge mit dem bildname gibt - cursor.execute('SELECT COUNT(*) as count FROM Image WHERE bildname = ?', (bildname,)) - result = cursor.fetchone() - count = result['count'] if result else 0 + # Start einer Transaktion + conn.execute('BEGIN') - if count == 0: + # Schritt 1: Identifizieren der betroffenen Decks + cursor.execute('SELECT DISTINCT deckname FROM Deck WHERE bildname = ?', (bildname,)) + affected_decks = {row['deckname'] for row in cursor.fetchall()} + + if not affected_decks: conn.close() return jsonify({'error': 'No entries found for the given image name'}), 404 - # Löschen der Einträge - cursor.execute('DELETE FROM Image WHERE bildname = ?', (bildname,)) - conn.commit() - conn.close() + # Schritt 2: Löschen der Image-Einträge + cursor.execute('DELETE FROM Deck WHERE bildname = ?', (bildname,)) + logger.info(f"Alle Einträge für bildname '{bildname}' wurden gelöscht.") - # Optional: Löschen des Debug-Verzeichnisses, wenn keine weiteren Einträge bestehen - # Überprüfen, ob das Verzeichnis existiert + # Schritt 3: Überprüfen und Wiederherstellen der Deck-Einträge + for deckname in affected_decks: + # Überprüfen, ob noch andere Image-Einträge für dieses Deck existieren + cursor.execute('SELECT COUNT(*) as count FROM Deck WHERE deckname = ? AND bildname IS NOT NULL', (deckname,)) + result = cursor.fetchone() + image_count = result['count'] if result else 0 + + if image_count == 0: + # Überprüfen, ob bereits ein Deck-Eintrag existiert + cursor.execute('SELECT COUNT(*) as count FROM Deck WHERE deckname = ? AND bildname IS NULL', (deckname,)) + deck_entry = cursor.fetchone() + if deck_entry['count'] == 0: + # Ein neuer Deck-Eintrag wird erstellt + cursor.execute('INSERT INTO Deck (deckname) VALUES (?)', (deckname,)) + logger.info(f"Neuer Deck-Eintrag für '{deckname}' erstellt, da keine weiteren Images vorhanden sind.") + + # Commit der Transaktion + conn.commit() + + # Schritt 4: Optionales Löschen des Debug-Verzeichnisses debug_dir = os.path.join('debug_images', bildname) if os.path.exists(debug_dir): try: @@ -272,8 +293,7 @@ def delete_images_by_bildname(bildname): logger.info(f"Debug-Verzeichnis gelöscht: {debug_dir}") except Exception as e: logger.error(f"Fehler beim Löschen des Debug-Verzeichnisses '{debug_dir}': {e}") - # Sie können entscheiden, ob Sie einen Fehler zurückgeben oder nicht - # Hier geben wir eine Warnung zurück, aber setzen die Anfrage als erfolgreich fort + # Eine Warnung wird zurückgegeben, aber die Anfrage wird als erfolgreich betrachtet return jsonify({ 'status': 'success', 'message': 'Database entries deleted, but failed to delete debug directory.', @@ -283,15 +303,22 @@ def delete_images_by_bildname(bildname): return jsonify({'status': 'success', 'message': f'All entries for image "{bildname}" have been deleted.'}), 200 except sqlite3.Error as e: - logger.error(f"Fehler beim Löschen der Image-Einträge für '{bildname}': {e}") + # Rollback der Transaktion bei einem Datenbankfehler + conn.rollback() + logger.error(f"Datenbankfehler beim Löschen der Image-Einträge für '{bildname}': {e}") return jsonify({'error': 'Database error', 'details': str(e)}), 500 except Exception as e: + # Rollback der Transaktion bei einem unerwarteten Fehler + conn.rollback() logger.error(f"Unerwarteter Fehler beim Löschen der Image-Einträge für '{bildname}': {e}") return jsonify({'error': 'Failed to delete image entries', 'details': str(e)}), 500 + finally: + conn.close() + # Sicherstellen, dass die Datenbank existiert if not os.path.exists(DATABASE): init_db() -clean_debug_directories() \ No newline at end of file +clean_debug_directories()