File size: 8,913 Bytes
ee00155
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
import sqlite3
import datetime
import os

DB_NAME = os.path.join(os.path.dirname(__file__), 'database.db')

def get_db_connection():
    try:
        conn = sqlite3.connect(DB_NAME)
        conn.row_factory = sqlite3.Row
        return conn
    except sqlite3.Error as e:
        print(f"Database error: {e}")
        return None

def init_db():
    conn = get_db_connection()
    if conn:
        try:
            conn.execute('''
                CREATE TABLE IF NOT EXISTS history (
                    id INTEGER PRIMARY KEY AUTOINCREMENT,
                    filename TEXT NOT NULL,
                    prediction TEXT NOT NULL,
                    confidence REAL NOT NULL,
                    fake_probability REAL NOT NULL,
                    real_probability REAL NOT NULL,
                    timestamp DATETIME DEFAULT CURRENT_TIMESTAMP
                )
            ''')
            conn.commit()
            print("✅ Database initialized successfully.")
        except sqlite3.Error as e:
            print(f"Error initializing database: {e}")
        
        # Migration: Add image_path, notes, tags if not exists
        try:
            conn.execute('ALTER TABLE history ADD COLUMN image_path TEXT')
            print("✅ Added image_path column.")
        except sqlite3.Error:
            pass # Column likely exists

        try:
            conn.execute('ALTER TABLE history ADD COLUMN notes TEXT')
            print("✅ Added notes column.")
        except sqlite3.Error:
            pass

        try:
            conn.execute('ALTER TABLE history ADD COLUMN tags TEXT')
            print("✅ Added tags column.")
        except sqlite3.Error:
            pass

        try:
            conn.execute('ALTER TABLE history ADD COLUMN session_id TEXT')
            print("✅ Added session_id column.")
        except sqlite3.Error:
            pass
        
        # Create feedback table for user feedback on predictions
        try:
            conn.execute('''
                CREATE TABLE IF NOT EXISTS feedback (
                    id INTEGER PRIMARY KEY AUTOINCREMENT,
                    scan_id INTEGER NOT NULL,
                    user_feedback TEXT NOT NULL,
                    predicted_label TEXT NOT NULL,
                    actual_label TEXT,
                    image_path TEXT,
                    confidence REAL,
                    timestamp DATETIME DEFAULT CURRENT_TIMESTAMP,
                    FOREIGN KEY (scan_id) REFERENCES history(id)
                )
            ''')
            conn.commit()
            print("✅ Feedback table initialized successfully.")
        except sqlite3.Error as e:
            print(f"Error initializing feedback table: {e}")
            
        finally:
            conn.close()

def add_scan(filename, prediction, confidence, fake_prob, real_prob, image_path="", session_id=None):
    conn = get_db_connection()
    if conn:
        try:
            cursor = conn.execute('''
                INSERT INTO history (filename, prediction, confidence, fake_probability, real_probability, image_path, session_id)
                VALUES (?, ?, ?, ?, ?, ?, ?)
            ''', (filename, prediction, confidence, fake_prob, real_prob, image_path, session_id))
            conn.commit()
            scan_id = cursor.lastrowid
            return scan_id
        except sqlite3.Error as e:
            print(f"Error adding scan: {e}")
            return None
        finally:
            conn.close()
    return None

def get_history(session_id=None):
    conn = get_db_connection()
    if conn:
        try:
            query = 'SELECT * FROM history'
            params = []
            if session_id:
                query += ' WHERE session_id = ? OR session_id IS NULL' # Allow seeing public/legacy items if desired, or strictly session specific
                # Strict session isolation:
                query = 'SELECT * FROM history WHERE session_id = ?'
                params = [session_id]
            else:
                # If no session_id provided (legacy behavior), maybe show all or none?
                # Let's show only items with NULL session_id to avoid leaking user data
                query = 'SELECT * FROM history WHERE session_id IS NULL'
            
            query += ' ORDER BY timestamp DESC'
            cursor = conn.execute(query, params)
            history = [dict(row) for row in cursor.fetchall()]
            return history
        except sqlite3.Error as e:
            print(f"Error retrieving history: {e}")
            return []
        finally:
            conn.close()
    return []

def clear_history(session_id=None):
    conn = get_db_connection()
    if conn:
        try:
            if session_id:
                conn.execute('DELETE FROM history WHERE session_id = ?', (session_id,))
            else:
                conn.execute('DELETE FROM history WHERE session_id IS NULL')
            conn.commit()
            return True
        except sqlite3.Error as e:
            print(f"Error clearing history: {e}")
            return False
        finally:
            conn.close()
    return False

def delete_scan(scan_id, session_id=None):
    conn = get_db_connection()
    if conn:
        try:
            if session_id:
                conn.execute('DELETE FROM history WHERE id = ? AND session_id = ?', (scan_id, session_id))
            else:
                conn.execute('DELETE FROM history WHERE id = ? AND session_id IS NULL', (scan_id,))
            conn.commit()
            return True
        except sqlite3.Error as e:
            print(f"Error deleting scan: {e}")
            return False
        finally:
            conn.close()
    return False

def update_scan(scan_id, data):
    conn = get_db_connection()
    if conn:
        try:
            fields = []
            values = []
            if 'notes' in data:
                fields.append("notes = ?")
                values.append(data['notes'])
            if 'tags' in data:
                fields.append("tags = ?")
                values.append(data['tags'])
            
            if not fields:
                return True
                
            values.append(scan_id)
            query = f"UPDATE history SET {', '.join(fields)} WHERE id = ?"
            conn.execute(query, tuple(values))
            conn.commit()
            return True
        except sqlite3.Error as e:
            print(f"Error updating scan: {e}")
            return False
        finally:
            conn.close()
    return False

def add_feedback(scan_id, is_correct, predicted_label, actual_label=None, image_path=None, confidence=None):
    """Record user feedback on a prediction"""
    conn = get_db_connection()
    if conn:
        try:
            user_feedback = 'correct' if is_correct else 'incorrect'
            conn.execute('''
                INSERT INTO feedback (scan_id, user_feedback, predicted_label, actual_label, image_path, confidence)
                VALUES (?, ?, ?, ?, ?, ?)
            ''', (scan_id, user_feedback, predicted_label, actual_label, image_path, confidence))
            conn.commit()
            return True
        except sqlite3.Error as e:
            print(f"Error adding feedback: {e}")
            return False
        finally:
            conn.close()
    return False

def get_incorrect_predictions():
    """Get all incorrect predictions for model retraining"""
    conn = get_db_connection()
    if conn:
        try:
            cursor = conn.execute('''
                SELECT f.*, h.filename 
                FROM feedback f
                LEFT JOIN history h ON f.scan_id = h.id
                WHERE f.user_feedback = 'incorrect'
                ORDER BY f.timestamp DESC
            ''')
            incorrect = [dict(row) for row in cursor.fetchall()]
            return incorrect
        except sqlite3.Error as e:
            print(f"Error retrieving incorrect predictions: {e}")
            return []
        finally:
            conn.close()
    return []

def get_feedback_stats():
    """Get statistics on user feedback"""
    conn = get_db_connection()
    if conn:
        try:
            cursor = conn.execute('''
                SELECT 
                    COUNT(*) as total_feedback,
                    SUM(CASE WHEN user_feedback = 'correct' THEN 1 ELSE 0 END) as correct_count,
                    SUM(CASE WHEN user_feedback = 'incorrect' THEN 1 ELSE 0 END) as incorrect_count
                FROM feedback
            ''')
            stats = dict(cursor.fetchone())
            return stats
        except sqlite3.Error as e:
            print(f"Error retrieving feedback stats: {e}")
            return {'total_feedback': 0, 'correct_count': 0, 'incorrect_count': 0}
        finally:
            conn.close()
    return {'total_feedback': 0, 'correct_count': 0, 'incorrect_count': 0}

# Initialize DB on module load
init_db()