schema update and case manager addition
This commit is contained in:
parent
172de21f55
commit
c6d0192fa8
107
src/forensictrails/core/case_manager.py
Normal file
107
src/forensictrails/core/case_manager.py
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
import config
|
||||||
|
from db.database import get_db_connection
|
||||||
|
import logging
|
||||||
|
import datetime
|
||||||
|
|
||||||
|
class CaseManager(case_id=None, case_title=None, investigator=None, classification=None, summary=None):
|
||||||
|
def __init__(self, db_path=None, case_id=None, case_title=None, investigator=None, classification=None, summary=None):
|
||||||
|
if db_path is None:
|
||||||
|
db_path = config.database_path
|
||||||
|
self.db_path = db_path
|
||||||
|
self.conn = get_db_connection(self.db_path)
|
||||||
|
self.cursor = self.conn.cursor()
|
||||||
|
logging.debug(f"Connected to database at {self.db_path}")
|
||||||
|
|
||||||
|
self.case_id = case_id
|
||||||
|
self.case_title = case_title
|
||||||
|
self.investigator = investigator
|
||||||
|
self.classification = classification
|
||||||
|
self.summary = summary
|
||||||
|
|
||||||
|
|
||||||
|
def create_case(self, case_id, case_title, investigator, classification=None, summary=None):
|
||||||
|
with self.conn:
|
||||||
|
self.cursor.execute("""
|
||||||
|
INSERT INTO cases (case_id, case_title, investigator, classification, summary, status)
|
||||||
|
VALUES (?, ?, ?, ?, ?, 'active')
|
||||||
|
""", (case_id, case_title, investigator, classification, summary))
|
||||||
|
logging.info(f"Created new case with ID: {case_id}")
|
||||||
|
|
||||||
|
def list_cases(self, status=None, search_term=None):
|
||||||
|
with self.conn:
|
||||||
|
query = "SELECT * FROM cases WHERE 1=1"
|
||||||
|
params = []
|
||||||
|
conditions = []
|
||||||
|
|
||||||
|
if status:
|
||||||
|
query += " AND status = ?"
|
||||||
|
params.append(status)
|
||||||
|
if search_term:
|
||||||
|
query += " AND (case_id LIKE ? OR case_title LIKE ? OR investigator LIKE ?)"
|
||||||
|
like_term = f"%{search_term}%"
|
||||||
|
params.extend([like_term, like_term, like_term])
|
||||||
|
|
||||||
|
query += " ORDER BY created_at DESC"
|
||||||
|
|
||||||
|
self.cursor.execute(query, params)
|
||||||
|
return [dict(row) for row in self.cursor.fetchall()]
|
||||||
|
|
||||||
|
def update_case(self, case_id, **kwargs):
|
||||||
|
allowed_fields = ['case_title', 'investigator', 'classification', 'summary', 'status']
|
||||||
|
updates = {k: v for k, v in kwargs.items() if k in allowed_fields}
|
||||||
|
|
||||||
|
if not updates:
|
||||||
|
logging.warning("No valid fields provided for update.")
|
||||||
|
return
|
||||||
|
|
||||||
|
updates['modified_at'] = datetime.utcnow().isoformat()
|
||||||
|
set_clause = ", ".join([f"{k} = ?" for k in updates.keys()])
|
||||||
|
values = list(updates.values()) + [case_id]
|
||||||
|
|
||||||
|
with self.conn:
|
||||||
|
self.cursor.execute(f"""
|
||||||
|
UPDATE cases
|
||||||
|
SET {set_clause}
|
||||||
|
WHERE case_id = ?
|
||||||
|
""", values)
|
||||||
|
logging.info(f"Updated case with ID: {case_id}")
|
||||||
|
return self.cursor.rowcount > 0
|
||||||
|
|
||||||
|
def close_case(self, case_id):
|
||||||
|
return self.update_case(case_id, status='closed')
|
||||||
|
|
||||||
|
def delete_case(self, case_id):
|
||||||
|
with self.conn:
|
||||||
|
self.cursor.execute("DELETE FROM cases WHERE case_id = ?", (case_id,))
|
||||||
|
logging.info(f"Deleted case with ID: {case_id}")
|
||||||
|
return self.cursor.rowcount > 0
|
||||||
|
|
||||||
|
def archive_case(self, case_id):
|
||||||
|
return self.update_case(case_id, status='archived')
|
||||||
|
|
||||||
|
def export_case_db(self, case_id, export_path):
|
||||||
|
with self.conn:
|
||||||
|
self.cursor.execute("SELECT * FROM cases WHERE case_id = ?", (case_id,))
|
||||||
|
case = self.cursor.fetchone()
|
||||||
|
if not case:
|
||||||
|
logging.error(f"No case found with ID: {case_id}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
with open(export_path, 'w') as f:
|
||||||
|
for key in case.keys():
|
||||||
|
f.write(f"{key}: {case[key]}\n")
|
||||||
|
logging.info(f"Exported case {case_id} to {export_path}")
|
||||||
|
return True
|
||||||
|
|
||||||
|
def import_case_db(self, import_path):
|
||||||
|
with open(import_path, 'r') as f:
|
||||||
|
try:
|
||||||
|
with open(config.database_path, 'w') as db_file:
|
||||||
|
db_file.write(f.read())
|
||||||
|
get_db_connection(config.database_path)
|
||||||
|
logging.info(f"Imported case database from {import_path}")
|
||||||
|
return True
|
||||||
|
except Exception as e:
|
||||||
|
logging.error(f"Failed to import case database: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
@ -1,12 +1,12 @@
|
|||||||
-- Cases table
|
-- Cases table
|
||||||
CREATE TABLE cases (
|
CREATE TABLE cases (
|
||||||
case_id TEXT PRIMARY KEY,
|
case_id TEXT PRIMARY KEY,
|
||||||
title TEXT NOT NULL,
|
case_title TEXT NOT NULL,
|
||||||
date_opened TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
date_opened TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
lead_investigator TEXT NOT NULL,
|
investigator TEXT NOT NULL,
|
||||||
classification TEXT,
|
classification TEXT,
|
||||||
summary TEXT,
|
summary TEXT,
|
||||||
status TEXT DEFAULT 'Active',
|
status TEXT DEFAULT 'active',
|
||||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
modified_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
modified_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||||
);
|
);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user