first implementations of database and logging utilities.
This commit is contained in:
		
							parent
							
								
									4e6dff930d
								
							
						
					
					
						commit
						172de21f55
					
				
							
								
								
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@ -166,4 +166,6 @@ cython_debug/
 | 
				
			|||||||
#  be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
 | 
					#  be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
 | 
				
			||||||
#  and can be added to the global gitignore or merged into this file.  For a more nuclear
 | 
					#  and can be added to the global gitignore or merged into this file.  For a more nuclear
 | 
				
			||||||
#  option (not recommended) you can uncomment the following to ignore the entire idea folder.
 | 
					#  option (not recommended) you can uncomment the following to ignore the entire idea folder.
 | 
				
			||||||
#.idea/
 | 
					#.idea/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					forensic_trails.db
 | 
				
			||||||
							
								
								
									
										7
									
								
								config.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								config.json
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,7 @@
 | 
				
			|||||||
 | 
					{
 | 
				
			||||||
 | 
					    "database_path": "forensic_trails.db",
 | 
				
			||||||
 | 
					    "database_schema_version": 1,
 | 
				
			||||||
 | 
					    "database_template": "schema.sql",
 | 
				
			||||||
 | 
					    "log_path": "forensic_trails.log",
 | 
				
			||||||
 | 
					    "log_level": "DEBUG"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -8,9 +8,9 @@ version = "0.1.0"
 | 
				
			|||||||
description = "Forensic Investigation Documentation System"
 | 
					description = "Forensic Investigation Documentation System"
 | 
				
			||||||
readme = "README.md"
 | 
					readme = "README.md"
 | 
				
			||||||
requires-python = ">=3.12"
 | 
					requires-python = ">=3.12"
 | 
				
			||||||
license = {text = "MIT"}  # Change as needed
 | 
					license = {text = "BSD 3-Clause"}
 | 
				
			||||||
authors = [
 | 
					authors = [
 | 
				
			||||||
    {name = "Your Name", email = "your.email@example.com"}
 | 
					    {name = "Overcuriousity", email = "overcuriousity@posteo.org"}
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
classifiers = [
 | 
					classifiers = [
 | 
				
			||||||
    "Development Status :: 3 - Alpha",
 | 
					    "Development Status :: 3 - Alpha",
 | 
				
			||||||
@ -26,6 +26,7 @@ dependencies = [
 | 
				
			|||||||
    "Pillow>=10.0.0",
 | 
					    "Pillow>=10.0.0",
 | 
				
			||||||
    "cryptography>=41.0.0",
 | 
					    "cryptography>=41.0.0",
 | 
				
			||||||
    "pyinstaller>=6.0.0",
 | 
					    "pyinstaller>=6.0.0",
 | 
				
			||||||
 | 
					    "logging>=0.4.9.6",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[project.optional-dependencies]
 | 
					[project.optional-dependencies]
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										6
									
								
								run.py
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								run.py
									
									
									
									
									
								
							@ -1,4 +1,4 @@
 | 
				
			|||||||
import forensic_trails
 | 
					from src.forensictrails.__main__ import main
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def run():
 | 
					if __name__ == "__main__":
 | 
				
			||||||
    forensic_trails.main()
 | 
					    main()
 | 
				
			||||||
@ -1,24 +1,33 @@
 | 
				
			|||||||
"""Entry point for ForensicTrails application."""
 | 
					"""Entry point for ForensicTrails application."""
 | 
				
			||||||
import sys
 | 
					import sys
 | 
				
			||||||
 | 
					import logging
 | 
				
			||||||
from PyQt6.QtWidgets import QApplication
 | 
					from PyQt6.QtWidgets import QApplication
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from .db.database import initialize_database
 | 
				
			||||||
 | 
					from .utils.logging import setup_logging
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def main():
 | 
					def main():
 | 
				
			||||||
    """Main entry point for the application."""
 | 
					    """Main entry point for the application."""
 | 
				
			||||||
 | 
					    setup_logging()
 | 
				
			||||||
 | 
					    logging.info("Starting ForensicTrails application")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    initialize_database()
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Create Qt application
 | 
				
			||||||
    app = QApplication(sys.argv)
 | 
					    app = QApplication(sys.argv)
 | 
				
			||||||
    app.setApplicationName("ForensicTrails")
 | 
					    app.setApplicationName("ForensicTrails")
 | 
				
			||||||
    app.setOrganizationName("Your Organization")
 | 
					    app.setOrganizationName("ForensicTrails")
 | 
				
			||||||
 | 
					    app.setApplicationVersion("0.1.0")
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    # TODO: Create and show main window
 | 
					    # TODO: Create and show main window
 | 
				
			||||||
    # from forensictrails.gui.main_window import MainWindow
 | 
					    # from .gui.main_window import MainWindow
 | 
				
			||||||
    # window = MainWindow()
 | 
					    # window = MainWindow()
 | 
				
			||||||
    # window.show()
 | 
					    # window.show()
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    print("ForensicTrails - Forensic Investigation Documentation System")
 | 
					    # For now, just exit immediately since we have no GUI yet
 | 
				
			||||||
    print("Application starting...")
 | 
					    logging.debug("No GUI yet - exiting...")
 | 
				
			||||||
    
 | 
					    return 0
 | 
				
			||||||
    sys.exit(app.exec())
 | 
					    # sys.exit(app.exec())
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
if __name__ == "__main__":
 | 
					if __name__ == "__main__":
 | 
				
			||||||
    main()
 | 
					    sys.exit(main())
 | 
				
			||||||
							
								
								
									
										45
									
								
								src/forensictrails/db/database.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								src/forensictrails/db/database.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,45 @@
 | 
				
			|||||||
 | 
					import sqlite3
 | 
				
			||||||
 | 
					import logging
 | 
				
			||||||
 | 
					from pathlib import Path
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from ..utils.config import config
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def get_db_connection(db_path=None):
 | 
				
			||||||
 | 
					    if db_path is None:
 | 
				
			||||||
 | 
					        db_path = create_db_if_not_exists()
 | 
				
			||||||
 | 
					    conn = sqlite3.connect(db_path)
 | 
				
			||||||
 | 
					    conn.row_factory = sqlite3.Row
 | 
				
			||||||
 | 
					    return conn
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def create_db_if_not_exists(db_path=None, schema_path=None):
 | 
				
			||||||
 | 
					    if db_path is None:
 | 
				
			||||||
 | 
					        db_path = config.database_path
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    if schema_path is None:
 | 
				
			||||||
 | 
					        schema_path = Path(__file__).parent / config.database_template
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    conn = get_db_connection(db_path)
 | 
				
			||||||
 | 
					    cursor = conn.cursor()
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    with open(schema_path, 'r') as f:
 | 
				
			||||||
 | 
					        schema = f.read()
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    cursor.executescript(schema)
 | 
				
			||||||
 | 
					    conn.commit()
 | 
				
			||||||
 | 
					    conn.close()
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					def initialize_database(db_path=None):
 | 
				
			||||||
 | 
					    if db_path is None:
 | 
				
			||||||
 | 
					        db_path = config.database_path
 | 
				
			||||||
 | 
					    get_db_connection(db_path)
 | 
				
			||||||
 | 
					    if config.log_level == 'DEBUG':
 | 
				
			||||||
 | 
					        show_db_schema(db_path)
 | 
				
			||||||
 | 
					    logging.info(f"Database initialized at {db_path}")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					def show_db_schema(db_path):
 | 
				
			||||||
 | 
					    conn = get_db_connection(db_path)
 | 
				
			||||||
 | 
					    cursor = conn.cursor()
 | 
				
			||||||
 | 
					    logging.debug("Displaying database schema:")
 | 
				
			||||||
 | 
					    for row in cursor.execute("SELECT name, sql FROM sqlite_master WHERE type='table';"):
 | 
				
			||||||
 | 
					        logging.debug(f"Table: {row['name']}\nSQL: {row['sql']}\n")
 | 
				
			||||||
 | 
					    conn.close()
 | 
				
			||||||
							
								
								
									
										20
									
								
								src/forensictrails/utils/config.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								src/forensictrails/utils/config.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,20 @@
 | 
				
			|||||||
 | 
					import json
 | 
				
			||||||
 | 
					import os
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Config:
 | 
				
			||||||
 | 
					    def __init__(self, config_filepath='config.json'):
 | 
				
			||||||
 | 
					        config_data = self._load_config(config_filepath)
 | 
				
			||||||
 | 
					        self.database_template = config_data.get('database_template', 'schema.sql')
 | 
				
			||||||
 | 
					        self.database_path = config_data.get('database_path', 'forensic_trails.db')
 | 
				
			||||||
 | 
					        self.database_schema_version = config_data.get('database_schema_version', 1)
 | 
				
			||||||
 | 
					        self.log_path = config_data.get('log_path', 'forensic_trails.log')
 | 
				
			||||||
 | 
					        self.log_level = config_data.get('log_level', 'DEBUG')
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    def _load_config(self, config_filepath):
 | 
				
			||||||
 | 
					        if os.path.exists(config_filepath):
 | 
				
			||||||
 | 
					            with open(config_filepath, 'r') as f:
 | 
				
			||||||
 | 
					                return json.load(f)
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            return {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					config = Config()
 | 
				
			||||||
							
								
								
									
										31
									
								
								src/forensictrails/utils/logging.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								src/forensictrails/utils/logging.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,31 @@
 | 
				
			|||||||
 | 
					import logging
 | 
				
			||||||
 | 
					from pathlib import Path
 | 
				
			||||||
 | 
					from ..utils.config import config
 | 
				
			||||||
 | 
					import sys
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def setup_logging(log_path=None):
 | 
				
			||||||
 | 
					    if log_path is None:
 | 
				
			||||||
 | 
					        log_path = config.log_path
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    log_file = Path(log_path)
 | 
				
			||||||
 | 
					    log_file.parent.mkdir(parents=True, exist_ok=True)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    logger = logging.getLogger()
 | 
				
			||||||
 | 
					    logger.setLevel(config.log_level)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    formatter = logging.Formatter(
 | 
				
			||||||
 | 
					        '%(asctime)s - %(name)s - %(levelname)s - %(message)s',
 | 
				
			||||||
 | 
					        datefmt='%Y-%m-%d %H:%M:%S'
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    file_handler = logging.FileHandler(log_file)
 | 
				
			||||||
 | 
					    file_handler.setLevel(config.log_level)
 | 
				
			||||||
 | 
					    file_handler.setFormatter(formatter)
 | 
				
			||||||
 | 
					    logger.addHandler(file_handler)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    stream_handler = logging.StreamHandler(sys.stdout)
 | 
				
			||||||
 | 
					    stream_handler.setLevel(config.log_level)
 | 
				
			||||||
 | 
					    stream_handler.setFormatter(formatter)
 | 
				
			||||||
 | 
					    logger.addHandler(stream_handler)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user