Update interview_history.py
Browse files- interview_history.py +163 -122
interview_history.py
CHANGED
|
@@ -1,122 +1,163 @@
|
|
| 1 |
-
# PrepGenie/interview_history.py
|
| 2 |
-
"""Handles saving and loading interview history to/from Firestore."""
|
| 3 |
-
|
| 4 |
-
import firebase_admin
|
| 5 |
-
from firebase_admin import firestore
|
| 6 |
-
import datetime
|
| 7 |
-
import json
|
| 8 |
-
|
| 9 |
-
# --- Firestore Client ---
|
| 10 |
-
# Assumes Firebase Admin is initialized in app.py
|
| 11 |
-
try:
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
except Exception as e:
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
|
| 20 |
-
def save_interview_history(user_id, interview_data):
|
| 21 |
-
|
| 22 |
-
|
| 23 |
-
|
| 24 |
-
|
| 25 |
-
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
def load_interview_history(user_id, limit=5):
|
| 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 |
-
# --- History Loading Function for UI ---
|
| 68 |
-
def load_user_history(user_id_state):
|
| 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 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# # PrepGenie/interview_history.py
|
| 2 |
+
# """Handles saving and loading interview history to/from Firestore."""
|
| 3 |
+
|
| 4 |
+
# import firebase_admin
|
| 5 |
+
# from firebase_admin import firestore
|
| 6 |
+
# import datetime
|
| 7 |
+
# import json
|
| 8 |
+
|
| 9 |
+
# # --- Firestore Client ---
|
| 10 |
+
# # Assumes Firebase Admin is initialized in app.py
|
| 11 |
+
# try:
|
| 12 |
+
# db = firestore.client()
|
| 13 |
+
# print("Firestore client for history initialized successfully in interview_history.")
|
| 14 |
+
# FIRESTORE_AVAILABLE = True
|
| 15 |
+
# except Exception as e:
|
| 16 |
+
# print(f"Error initializing Firestore client for history in interview_history: {e}")
|
| 17 |
+
# db = None
|
| 18 |
+
# FIRESTORE_AVAILABLE = False
|
| 19 |
+
|
| 20 |
+
# def save_interview_history(user_id, interview_data):
|
| 21 |
+
# """
|
| 22 |
+
# Saves the mock interview results to Firestore under the user's document.
|
| 23 |
+
# """
|
| 24 |
+
# if not FIRESTORE_AVAILABLE or not db:
|
| 25 |
+
# print("Firestore client not available in interview_history. Cannot save history.")
|
| 26 |
+
# return False
|
| 27 |
+
# if not user_id:
|
| 28 |
+
# print("User ID is required in interview_history to save history.")
|
| 29 |
+
# return False
|
| 30 |
+
|
| 31 |
+
# try:
|
| 32 |
+
# user_ref = db.collection('users').document(user_id)
|
| 33 |
+
# history_ref = user_ref.collection('interview_history')
|
| 34 |
+
# history_ref.add(interview_data)
|
| 35 |
+
# print(f"Interview history saved for user {user_id} in interview_history")
|
| 36 |
+
# return True
|
| 37 |
+
# except Exception as e:
|
| 38 |
+
# print(f"Error saving interview history for user {user_id} in interview_history: {e}")
|
| 39 |
+
# return False
|
| 40 |
+
|
| 41 |
+
# def load_interview_history(user_id, limit=5):
|
| 42 |
+
# """
|
| 43 |
+
# Loads the mock interview history for a specific user from Firestore.
|
| 44 |
+
# """
|
| 45 |
+
# if not FIRESTORE_AVAILABLE or not db:
|
| 46 |
+
# print("Firestore client not available in interview_history. Cannot load history.")
|
| 47 |
+
# return []
|
| 48 |
+
# if not user_id:
|
| 49 |
+
# print("User ID is required in interview_history to load history.")
|
| 50 |
+
# return []
|
| 51 |
+
|
| 52 |
+
# try:
|
| 53 |
+
# history_ref = db.collection('users').document(user_id).collection('interview_history')
|
| 54 |
+
# docs = history_ref.order_by('timestamp', direction=firestore.Query.DESCENDING).limit(limit).stream()
|
| 55 |
+
|
| 56 |
+
# history_list = []
|
| 57 |
+
# for doc in docs:
|
| 58 |
+
# interview_record = doc.to_dict()
|
| 59 |
+
# history_list.append(interview_record)
|
| 60 |
+
|
| 61 |
+
# print(f"Loaded {len(history_list)} interview records for user {user_id} in interview_history")
|
| 62 |
+
# return history_list
|
| 63 |
+
# except Exception as e:
|
| 64 |
+
# print(f"Error loading interview history for user {user_id} in interview_history: {e}")
|
| 65 |
+
# return []
|
| 66 |
+
|
| 67 |
+
# # --- History Loading Function for UI ---
|
| 68 |
+
# def load_user_history(user_id_state):
|
| 69 |
+
# """Function to load and format interview history for display in the UI."""
|
| 70 |
+
# if not FIRESTORE_AVAILABLE:
|
| 71 |
+
# return "History feature is not available (Firestore not initialized)."
|
| 72 |
+
# if not user_id_state:
|
| 73 |
+
# return "Please log in to view your interview history."
|
| 74 |
+
|
| 75 |
+
# try:
|
| 76 |
+
# history_list = load_interview_history(user_id_state, limit=5)
|
| 77 |
+
|
| 78 |
+
# if not history_list:
|
| 79 |
+
# return "No interview history found."
|
| 80 |
+
|
| 81 |
+
# output_text = "**Your Recent Mock Interviews:**\n\n"
|
| 82 |
+
# for idx, record in enumerate(history_list):
|
| 83 |
+
# timestamp = record.get('timestamp', 'Unknown Time')
|
| 84 |
+
# try:
|
| 85 |
+
# if 'Z' in timestamp:
|
| 86 |
+
# dt = datetime.datetime.fromisoformat(timestamp.replace('Z', '+00:00'))
|
| 87 |
+
# else:
|
| 88 |
+
# dt = datetime.datetime.fromisoformat(timestamp)
|
| 89 |
+
# formatted_time = dt.strftime("%Y-%m-%d %H:%M:%S")
|
| 90 |
+
# except Exception as e:
|
| 91 |
+
# print(f"Error parsing timestamp {timestamp} in load_user_history: {e}")
|
| 92 |
+
# formatted_time = timestamp
|
| 93 |
+
|
| 94 |
+
# roles = ", ".join(record.get('selected_roles', ['N/A']))
|
| 95 |
+
# avg_rating = record.get('average_rating', 'N/A')
|
| 96 |
+
# output_text += f"--- **Interview #{len(history_list) - idx} ({formatted_time})** ---\n"
|
| 97 |
+
# output_text += f"**Roles Applied:** {roles}\n"
|
| 98 |
+
# output_text += f"**Average Rating:** {avg_rating:.2f}\n\n"
|
| 99 |
+
|
| 100 |
+
# interactions = record.get('interactions', {})
|
| 101 |
+
# if interactions:
|
| 102 |
+
# output_text += "**Interview Snippets:**\n"
|
| 103 |
+
# count = 0
|
| 104 |
+
# for q_key, a_val in list(interactions.items())[:3]:
|
| 105 |
+
# q_display = q_key.split(':', 1)[1].strip() if ':' in q_key else q_key
|
| 106 |
+
# a_display = a_val.split(':', 1)[1].strip() if ':' in a_val else a_val
|
| 107 |
+
# output_text += f"- **Q:** {q_display[:100]}{'...' if len(q_display) > 100 else ''}\n"
|
| 108 |
+
# output_text += f" **A:** {a_display[:100]}{'...' if len(a_display) > 100 else ''}\n"
|
| 109 |
+
# count += 1
|
| 110 |
+
# if count >= 3:
|
| 111 |
+
# break
|
| 112 |
+
# if len(interactions) > 3:
|
| 113 |
+
# output_text += f"... (and {len(interactions) - 3} more questions)\n"
|
| 114 |
+
# else:
|
| 115 |
+
# output_text += "**Details:** Not available.\n"
|
| 116 |
+
# output_text += "\n---\n\n"
|
| 117 |
+
|
| 118 |
+
# return output_text
|
| 119 |
+
# except Exception as e:
|
| 120 |
+
# error_msg = f"Error loading interview history in load_user_history: {str(e)}"
|
| 121 |
+
# print(error_msg)
|
| 122 |
+
# return error_msg
|
| 123 |
+
|
| 124 |
+
|
| 125 |
+
# interview_history.py
|
| 126 |
+
"""Session-based interview history — no database needed."""
|
| 127 |
+
|
| 128 |
+
def save_interview_history(session_history, interview_data):
|
| 129 |
+
"""Appends a new interview record to the session history list."""
|
| 130 |
+
if session_history is None:
|
| 131 |
+
session_history = []
|
| 132 |
+
session_history.append(interview_data)
|
| 133 |
+
return session_history
|
| 134 |
+
|
| 135 |
+
def format_history_for_display(session_history):
|
| 136 |
+
"""Formats session history for display in the UI."""
|
| 137 |
+
if not session_history:
|
| 138 |
+
return "No interview history yet in this session."
|
| 139 |
+
|
| 140 |
+
output = "**Your Interview History (This Session):**\n\n"
|
| 141 |
+
for idx, record in enumerate(reversed(session_history)):
|
| 142 |
+
roles = ", ".join(record.get("selected_roles", ["N/A"]))
|
| 143 |
+
avg_rating = record.get("average_rating", "N/A")
|
| 144 |
+
timestamp = record.get("timestamp", "Unknown time")
|
| 145 |
+
|
| 146 |
+
output += f"--- **Interview #{len(session_history) - idx} ({timestamp})** ---\n"
|
| 147 |
+
output += f"**Roles:** {roles}\n"
|
| 148 |
+
if isinstance(avg_rating, float):
|
| 149 |
+
output += f"**Average Rating:** {avg_rating:.2f}/10\n\n"
|
| 150 |
+
else:
|
| 151 |
+
output += f"**Average Rating:** {avg_rating}\n\n"
|
| 152 |
+
|
| 153 |
+
interactions = record.get("interactions", {})
|
| 154 |
+
if interactions:
|
| 155 |
+
output += "**Questions & Answers:**\n"
|
| 156 |
+
for q_key, a_val in list(interactions.items()):
|
| 157 |
+
q = q_key.split(":", 1)[1].strip() if ":" in q_key else q_key
|
| 158 |
+
a = a_val.split(":", 1)[1].strip() if ":" in a_val else a_val
|
| 159 |
+
output += f"- **Q:** {q[:120]}{'...' if len(q) > 120 else ''}\n"
|
| 160 |
+
output += f" **A:** {a[:120]}{'...' if len(a) > 120 else ''}\n"
|
| 161 |
+
output += "\n---\n\n"
|
| 162 |
+
|
| 163 |
+
return output
|