11import urllib
2-
32from flask import Flask , render_template , request , session , redirect , url_for , send_file , jsonify
43import sqlite3
54import json
87import logging
98import matplotlib
109import matplotlib .pyplot as plt
10+ import re
1111from datetime import datetime
1212from io import BytesIO
1313from collections import Counter
2424
2525
2626# Set up logging
27- logging .basicConfig (level = logging .DEBUG )
27+ #logging.basicConfig(level=logging.DEBUG)
28+
29+ log_format = '%(asctime)s %(levelname)s:%(message)s'
30+ logging .basicConfig (level = logging .DEBUG , format = log_format )
31+ logger = logging .getLogger ()
32+
33+ # File handler
34+ file_handler = logging .FileHandler ('/home/jenni/nis2/nis2Env/logs/application.log' )
35+ file_handler .setFormatter (logging .Formatter (log_format ))
36+ logger .addHandler (file_handler )
37+
38+ # Console handler
39+ console_handler = logging .StreamHandler ()
40+ console_handler .setFormatter (logging .Formatter (log_format ))
41+ logger .addHandler (console_handler )
42+
2843
2944# Generate a secret key for the Flask session
3045secret_key = binascii .hexlify (os .urandom (24 )).decode ()
31- print ( secret_key )
46+ logging . info ( f"Secret_key: { secret_key } " )
3247
3348# Initialize Flask app
3449app = Flask (__name__ , static_url_path = '/static' )
3550app .secret_key = secret_key
3651
3752
38- # Database initialisation (**Matches init_db.py)
39- def init_db ():
40- print (sqlite3 .version )
41- conn = sqlite3 .connect ('assessment_results.db' ) # This will create the database file
42- c = conn .cursor ()
43- c .execute ('''
44- CREATE TABLE IF NOT EXISTS results (
45- id INTEGER PRIMARY KEY AUTOINCREMENT,
46- user_id TEXT UNIQUE,
47- total_score INTEGER,
48- compliance_percentage REAL,
49- details TEXT,
50- consent TEXT,
51- timestamp DATETIME DEFAULT CURRENT_TIMESTAMP
52- )
53- ''' )
54- c .execute ('''
55- CREATE TABLE IF NOT EXISTS feedback (
56- id INTEGER PRIMARY KEY AUTOINCREMENT,
57- user_id TEXT,
58- familiarity TEXT,
59- role TEXT,
60- experience TEXT,
61- use_frequently TEXT,
62- complexity TEXT,
63- ease_of_use TEXT,
64- need_support TEXT,
65- integration TEXT,
66- inconsistency TEXT,
67- learn_quickly TEXT,
68- cumbersome TEXT,
69- confidence TEXT,
70- learning_curve TEXT,
71- navigation TEXT,
72- relevance TEXT,
73- comprehensive TEXT,
74- useful_recommendations TEXT,
75- overall_satisfaction TEXT,
76- recommend TEXT,
77- best_feature TEXT,
78- biggest_difficulty TEXT,
79- missing_feature TEXT,
80- additional_comments TEXT,
81- timestamp DATETIME DEFAULT CURRENT_TIMESTAMP
82- )
83- ''' )
84- conn .commit ()
85- conn .close ()
86-
87- init_db ()
88-
89-
9053# Class to handle regulatory assessment tool logic
9154class RegulatoryAssessmentTool :
9255 def __init__ (self ):
56+ logging .debug (f"Running RegulatoryAssessmentTool class" )
57+ endpoint_url = "http://localhost:7200/repositories/NIS2Ontology"
58+
9359
94- endpoint_url = "http://localhost:8080/repositories/NIS2Ontology"
95- username = "admin"
96- password = "hBxGF3PtJMUgNePB"
97-
60+
9861 # Initialize SPARQLWrapper with the endpoint URL
9962 self .sparql = SPARQLWrapper (endpoint_url )
10063 # Mapping of question labels to scores
@@ -133,16 +96,22 @@ def get_answer_definition(self, question_number, answer_label):
13396 FILTER (str(?answerLabel) = '{ answer_label } ')
13497 }}
13598 '''
136- logging .debug (f"Generated SPARQL query for get_answer_definition: { query } " )
99+ # logging.debug(f"Generated SPARQL query for get_answer_definition: {query}")
137100 results = self .run_sparql_query (query )
138101 print ("Leaving... get_answer_definition" )
102+ logging .debug ("Leaving... get_answer_definition" )
139103 if results ['results' ]['bindings' ]:
140104 return results ['results' ]['bindings' ][0 ]['answerDef' ]['value' ]
141105 else :
142106 return None
143107
144108 def get_article_info (self , article_label ):
145109 print ("In... get_article_info" )
110+ logging .debug ("In... get_article_info" )
111+ length_of_list = len (mcq_numbers )
112+
113+ logging .debug (f"Length of MCQ list: { length_of_list } " )
114+
146115 """Fetches information about an article given its label."""
147116 query = f'''
148117 PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
@@ -159,6 +128,8 @@ def get_article_info(self, article_label):
159128 }}
160129 '''
161130 logging .debug (f"Generated SPARQL query for get_article_info: { query } " )
131+ print (f"(P) Generated SPARQL query for get_article_info: { query } " )
132+ logging .debug (f"Length of MCQ list: { length_of_list } " )
162133 results = self .run_sparql_query (query )
163134 return results
164135
@@ -176,6 +147,7 @@ def get_question_score(self, question_label):
176147
177148 def get_question_data (self , mcq_number ):
178149 """Fetches data for a specific question, including the question text, answers, and related article."""
150+ logging .debug ("In... get_question_data" )
179151 print ("In... get_question_data" )
180152 question_data = self .run_sparql_query (f'''
181153 PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
@@ -244,6 +216,7 @@ def get_question_data(self, mcq_number):
244216
245217 def get_recommendation (self , mcq_number ):
246218 """Fetches the recommendation for a given MCQ number."""
219+ logging .debug ("In... get_recommendation" )
247220 print ("In... get_recommendation" )
248221 query = f'''
249222 PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
@@ -259,6 +232,7 @@ def get_recommendation(self, mcq_number):
259232 '''
260233 logging .debug (f"Generated SPARQL query for get_recommendation: { query } " )
261234 results = self .run_sparql_query (query )
235+ logging .debug ("Leaving... get_recommendation" )
262236 print ("Leaving... get_recommendation" )
263237 if results ['results' ]['bindings' ]:
264238 return results ['results' ]['bindings' ][0 ]['recommendation' ]['value' ]
@@ -268,6 +242,7 @@ def get_recommendation(self, mcq_number):
268242 def get_article_label_for_question (self , mcq_number ):
269243 """Fetches the article label related to a specific MCQ number."""
270244 print ("In... get_article_label_for_question" )
245+ logging .debug ("In... get_article_label_for_question" )
271246 query = f'''
272247 PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
273248 PREFIX dct: <http://purl.org/dc/terms/>
@@ -280,7 +255,7 @@ def get_article_label_for_question(self, mcq_number):
280255 skos:definition ?definition .
281256 }}
282257 '''
283- logging .debug (f"Generated SPARQL query for get_article_label_for_question : { query } " )
258+ logging .debug (f"mcq_number : { mcq_number } " )
284259 results = self .run_sparql_query (query )
285260 logging .debug (f"SPARQL query results for get_article_label_for_question: { results } " )
286261
@@ -297,10 +272,9 @@ def get_article_label_for_question(self, mcq_number):
297272 return None
298273
299274# Fetch MCQ numbers
300- import re
301-
302275def fetch_mcq_numbers ():
303276 """Fetches all MCQ numbers from the ontology."""
277+ logging .info ('Fetching the MCQ Numbers' )
304278 tool = RegulatoryAssessmentTool ()
305279 query = '''
306280 PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
@@ -320,12 +294,17 @@ def fetch_mcq_numbers():
320294 mcq_numbers = []
321295 for result in results ['results' ]['bindings' ]:
322296 uri = result ['class' ]['value' ]
297+ logging .debug (f'Processing URI: { uri } ' )
323298 mcq_number_match = re .search (r'MCQ\.(\d+(\.\d+)?)$' , uri )
324299 if mcq_number_match :
325300 mcq_number = mcq_number_match .group (1 )
326301 mcq_numbers .append (mcq_number )
327302 logging .debug (f"Added MCQ number: { mcq_number } " )
328- logging .debug (f"Current MCQ numbers: { mcq_numbers } " )
303+ length_of_list = len (mcq_numbers )
304+ logging .debug (f"Length of MCQ list: { length_of_list } " )
305+ else :
306+ logging .warning (f'No match for URI: { uri } ' )
307+ logging .debug (f'Current MCQ numbers before sorting: { mcq_numbers } ' )
329308
330309 # Sort the MCQ numbers correctly
331310 def sort_key (mcq ):
@@ -358,7 +337,8 @@ def index():
358337
359338 try :
360339 mcq_index = session .get ('mcq_index' , 0 ) # Get mcq_index from session
361- print (f"In def index - mcq_index: { mcq_index } " )
340+ print (f"In index - mcq_index: { mcq_index } " )
341+ logging .debug (f"In index - mcq_index: { mcq_index } " )
362342
363343 data = tool .get_question_data (mcq_numbers [mcq_index ])
364344 return render_template ('index.html' , ** data )
@@ -425,6 +405,7 @@ def submit_answer():
425405
426406 mcq_index = session .get ('mcq_index' , 0 )
427407 print (f"In submit answer (top) - mcq_index: { mcq_index } " )
408+ logging .debug (f"In submit answer (top) - mcq_index: { mcq_index } " )
428409
429410 session ['user_choices' ].append ((mcq_numbers [mcq_index ], choice ))
430411 session ['total_score' ] += int (score )
@@ -453,6 +434,8 @@ def get_next_question():
453434 try :
454435 mcq_index = session .get ('mcq_index' , 0 )
455436 print (f"In get_next_question (top) - mcq_index: { mcq_index } " )
437+ length_of_list = len (mcq_numbers )
438+ logging .debug (f"Length of MCQ list: { length_of_list } " )
456439
457440 data = tool .get_question_data (mcq_numbers [mcq_index ])
458441 question_data = {
@@ -675,6 +658,58 @@ def results():
675658# Define a custom darker pink color
676659darker_pink = colors .HexColor ('#C2185B' )
677660
661+ # Database initialisation (**Matches init_db.py)
662+ def init_db ():
663+ logging .info ('Running init_db' )
664+ logging .info (f'sqlite3.version: { sqlite3 .version } ' )
665+ conn = sqlite3 .connect ('assessment_results.db' ) # This will create the database file
666+ c = conn .cursor ()
667+ c .execute ('''
668+ CREATE TABLE IF NOT EXISTS results (
669+ id INTEGER PRIMARY KEY AUTOINCREMENT,
670+ user_id TEXT UNIQUE,
671+ total_score INTEGER,
672+ compliance_percentage REAL,
673+ details TEXT,
674+ consent TEXT,
675+ timestamp DATETIME DEFAULT CURRENT_TIMESTAMP
676+ )
677+ ''' )
678+ c .execute ('''
679+ CREATE TABLE IF NOT EXISTS feedback (
680+ id INTEGER PRIMARY KEY AUTOINCREMENT,
681+ user_id TEXT,
682+ familiarity TEXT,
683+ role TEXT,
684+ experience TEXT,
685+ use_frequently TEXT,
686+ complexity TEXT,
687+ ease_of_use TEXT,
688+ need_support TEXT,
689+ integration TEXT,
690+ inconsistency TEXT,
691+ learn_quickly TEXT,
692+ cumbersome TEXT,
693+ confidence TEXT,
694+ learning_curve TEXT,
695+ navigation TEXT,
696+ relevance TEXT,
697+ comprehensive TEXT,
698+ useful_recommendations TEXT,
699+ overall_satisfaction TEXT,
700+ recommend TEXT,
701+ best_feature TEXT,
702+ biggest_difficulty TEXT,
703+ missing_feature TEXT,
704+ additional_comments TEXT,
705+ timestamp DATETIME DEFAULT CURRENT_TIMESTAMP
706+ )
707+ ''' )
708+ conn .commit ()
709+ conn .close ()
710+
711+ init_db ()
712+
678713@app .route ('/download_report' )
679714def download_report ():
680715 """Route to generate and download the assessment report as a PDF."""
0 commit comments