AIdeaText commited on
Commit
1fa328e
verified
1 Parent(s): dfab642

Update modules/database/sql_db.py

Browse files
Files changed (1) hide show
  1. modules/database/sql_db.py +247 -128
modules/database/sql_db.py CHANGED
@@ -1,129 +1,248 @@
1
- from .database_init import get_sql_containers
2
- from datetime import datetime, timezone
3
- import logging
4
- import bcrypt
5
- import uuid
6
-
7
- logger = logging.getLogger(__name__)
8
-
9
- def get_user(username, role=None):
10
- user_container, _, _ = get_sql_containers()
11
- try:
12
- query = f"SELECT * FROM c WHERE c.id = '{username}'"
13
- if role:
14
- query += f" AND c.role = '{role}'"
15
- items = list(user_container.query_items(query=query, enable_cross_partition_query=True))
16
- return items[0] if items else None
17
- except Exception as e:
18
- logger.error(f"Error al obtener usuario {username}: {str(e)}")
19
- return None
20
-
21
- def get_admin_user(username):
22
- return get_user(username, role='Administrador')
23
-
24
- def get_student_user(username):
25
- return get_user(username, role='Estudiante')
26
-
27
- def get_teacher_user(username):
28
- return get_user(username, role='Profesor')
29
-
30
- def create_user(username, password, role, additional_info=None):
31
- user_container, _, _ = get_sql_containers()
32
- try:
33
- hashed_password = bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt()).decode('utf-8')
34
- user_data = {
35
- 'id': username,
36
- 'password': hashed_password,
37
- 'role': role,
38
- 'timestamp': datetime.now(timezone.utc).isoformat(),
39
- 'additional_info': additional_info or {}
40
- }
41
- user_container.create_item(body=user_data)
42
- logger.info(f"Usuario {role} creado: {username}")
43
- return True
44
- except Exception as e:
45
- logger.error(f"Error al crear usuario {role}: {str(e)}")
46
- return False
47
-
48
- def create_student_user(username, password, additional_info=None):
49
- return create_user(username, password, 'Estudiante', additional_info)
50
-
51
- def create_teacher_user(username, password, additional_info=None):
52
- return create_user(username, password, 'Profesor', additional_info)
53
-
54
- def create_admin_user(username, password, additional_info=None):
55
- return create_user(username, password, 'Administrador', additional_info)
56
-
57
-
58
- ###########################################################
59
- def update_student_user(username, new_info):
60
- user_container, _, _ = get_sql_containers()
61
- try:
62
- user = get_student_user(username)
63
- if user:
64
- user['additional_info'].update(new_info)
65
- user_container.upsert_item(body=user)
66
- logger.info(f"Informaci贸n del estudiante actualizada: {username}")
67
- return True
68
- else:
69
- logger.warning(f"Intento de actualizar estudiante no existente: {username}")
70
- return False
71
- except Exception as e:
72
- logger.error(f"Error al actualizar informaci贸n del estudiante {username}: {str(e)}")
73
- return False
74
-
75
-
76
- def delete_student_user(username):
77
- user_container, _, _ = get_sql_containers()
78
- try:
79
- user = get_student_user(username)
80
- if user:
81
- user_container.delete_item(item=user['id'], partition_key=username)
82
- logger.info(f"Estudiante eliminado: {username}")
83
- return True
84
- else:
85
- logger.warning(f"Intento de eliminar estudiante no existente: {username}")
86
- return False
87
- except Exception as e:
88
- logger.error(f"Error al eliminar estudiante {username}: {str(e)}")
89
- return False
90
-
91
- def store_application_request(name, lastname, email, institution, current_role, desired_role, reason):
92
- _, application_requests_container, _ = get_sql_containers()
93
- try:
94
- application_request = {
95
- "id": str(uuid.uuid4()),
96
- "name": name,
97
- "lastname": lastname,
98
- "email": email,
99
- "institution": institution,
100
- "current_role": current_role,
101
- "desired_role": desired_role,
102
- "reason": reason,
103
- "requestDate": datetime.utcnow().isoformat()
104
- }
105
- application_requests_container.create_item(body=application_request)
106
- logger.info(f"Solicitud de aplicaci贸n almacenada para el email: {email}")
107
- return True
108
- except Exception as e:
109
- logger.error(f"Error al almacenar la solicitud de aplicaci贸n: {str(e)}")
110
- return False
111
-
112
- def store_student_feedback(username, name, email, feedback):
113
- _, _, user_feedback_container = get_sql_containers()
114
- try:
115
- feedback_item = {
116
- "id": str(uuid.uuid4()),
117
- "username": username,
118
- "name": name,
119
- "email": email,
120
- "feedback": feedback,
121
- "role": "Estudiante",
122
- 'timestamp': datetime.now(timezone.utc).isoformat(),
123
- }
124
- result = user_feedback_container.create_item(body=feedback_item)
125
- logger.info(f"Feedback de estudiante almacenado con ID: {result['id']} para el usuario: {username}")
126
- return True
127
- except Exception as e:
128
- logger.error(f"Error al almacenar el feedback del estudiante {username}: {str(e)}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
129
  return False
 
1
+ from .database_init import get_sql_containers
2
+ from datetime import datetime, timezone
3
+ import logging
4
+ import bcrypt
5
+ import uuid
6
+
7
+ logger = logging.getLogger(__name__)
8
+
9
+ def get_user(username, role=None):
10
+ user_container, _, _ = get_sql_containers()
11
+ try:
12
+ query = f"SELECT * FROM c WHERE c.id = '{username}'"
13
+ if role:
14
+ query += f" AND c.role = '{role}'"
15
+ items = list(user_container.query_items(query=query, enable_cross_partition_query=True))
16
+ return items[0] if items else None
17
+ except Exception as e:
18
+ logger.error(f"Error al obtener usuario {username}: {str(e)}")
19
+ return None
20
+
21
+ def get_admin_user(username):
22
+ return get_user(username, role='Administrador')
23
+
24
+ def get_student_user(username):
25
+ return get_user(username, role='Estudiante')
26
+
27
+ def get_teacher_user(username):
28
+ return get_user(username, role='Profesor')
29
+
30
+ def create_user(username, password, role, additional_info=None):
31
+ user_container, _, _ = get_sql_containers()
32
+ try:
33
+ hashed_password = bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt()).decode('utf-8')
34
+ user_data = {
35
+ 'id': username,
36
+ 'password': hashed_password,
37
+ 'role': role,
38
+ 'timestamp': datetime.now(timezone.utc).isoformat(),
39
+ 'additional_info': additional_info or {}
40
+ }
41
+ user_container.create_item(body=user_data)
42
+ logger.info(f"Usuario {role} creado: {username}")
43
+ return True
44
+ except Exception as e:
45
+ logger.error(f"Error al crear usuario {role}: {str(e)}")
46
+ return False
47
+
48
+ def create_student_user(username, password, additional_info=None):
49
+ return create_user(username, password, 'Estudiante', additional_info)
50
+
51
+ def create_teacher_user(username, password, additional_info=None):
52
+ return create_user(username, password, 'Profesor', additional_info)
53
+
54
+ def create_admin_user(username, password, additional_info=None):
55
+ return create_user(username, password, 'Administrador', additional_info)
56
+
57
+ ############-- Funciones de control del tiempo de sesi贸n ##################
58
+
59
+ def record_login(username):
60
+ """Registra el inicio de sesi贸n de un usuario"""
61
+ try:
62
+ container = get_container("user_sessions")
63
+ if not container:
64
+ return None
65
+
66
+ session_doc = {
67
+ "id": str(uuid.uuid4()),
68
+ "type": "session",
69
+ "username": username,
70
+ "loginTime": datetime.now(timezone.utc).isoformat(),
71
+ "partitionKey": username
72
+ }
73
+
74
+ result = container.create_item(body=session_doc)
75
+ return result['id']
76
+ except Exception as e:
77
+ logger.error(f"Error registrando login: {str(e)}")
78
+ return None
79
+
80
+ def record_logout(username, session_id):
81
+ """Registra el cierre de sesi贸n y calcula la duraci贸n"""
82
+ try:
83
+ container = get_container("user_sessions")
84
+ if not container:
85
+ return False
86
+
87
+ # Obtener la sesi贸n actual
88
+ query = "SELECT * FROM c WHERE c.id = @id AND c.username = @username"
89
+ params = [
90
+ {"name": "@id", "value": session_id},
91
+ {"name": "@username", "value": username}
92
+ ]
93
+
94
+ sessions = list(container.query_items(
95
+ query=query,
96
+ parameters=params,
97
+ enable_cross_partition_query=True
98
+ ))
99
+
100
+ if not sessions:
101
+ return False
102
+
103
+ session = sessions[0]
104
+ login_time = datetime.fromisoformat(session['loginTime'].rstrip('Z'))
105
+ logout_time = datetime.now(timezone.utc)
106
+ duration = int((logout_time - login_time).total_seconds())
107
+
108
+ # Actualizar el documento
109
+ session.update({
110
+ "logoutTime": logout_time.isoformat(),
111
+ "sessionDuration": duration
112
+ })
113
+
114
+ container.upsert_item(body=session)
115
+ return True
116
+ except Exception as e:
117
+ logger.error(f"Error registrando logout: {str(e)}")
118
+ return False
119
+
120
+ def get_recent_sessions(limit=10):
121
+ """Obtiene las sesiones m谩s recientes"""
122
+ try:
123
+ container = get_container("user_sessions")
124
+ if not container:
125
+ return []
126
+
127
+ query = """
128
+ SELECT c.username, c.loginTime, c.logoutTime, c.sessionDuration
129
+ FROM c
130
+ WHERE c.type = 'session'
131
+ AND c.logoutTime != null
132
+ ORDER BY c.loginTime DESC
133
+ OFFSET 0 LIMIT @limit
134
+ """
135
+
136
+ params = [{"name": "@limit", "value": limit}]
137
+
138
+ sessions = container.query_items(
139
+ query=query,
140
+ parameters=params,
141
+ enable_cross_partition_query=True
142
+ )
143
+
144
+ return list(sessions)
145
+ except Exception as e:
146
+ logger.error(f"Error obteniendo sesiones recientes: {str(e)}")
147
+ return []
148
+
149
+ def get_user_total_time(username):
150
+ """Obtiene el tiempo total que un usuario ha pasado en la plataforma"""
151
+ try:
152
+ container = get_container("user_sessions")
153
+ if not container:
154
+ return None
155
+
156
+ query = """
157
+ SELECT VALUE SUM(c.sessionDuration)
158
+ FROM c
159
+ WHERE c.type = 'session'
160
+ AND c.username = @username
161
+ AND c.logoutTime != null
162
+ """
163
+
164
+ params = [{"name": "@username", "value": username}]
165
+
166
+ result = list(container.query_items(
167
+ query=query,
168
+ parameters=params,
169
+ enable_cross_partition_query=True
170
+ ))
171
+
172
+ return result[0] if result else 0
173
+ except Exception as e:
174
+ logger.error(f"Error obteniendo tiempo total: {str(e)}")
175
+ return None
176
+
177
+ ###########################################################
178
+ def update_student_user(username, new_info):
179
+ user_container, _, _ = get_sql_containers()
180
+ try:
181
+ user = get_student_user(username)
182
+ if user:
183
+ user['additional_info'].update(new_info)
184
+ user_container.upsert_item(body=user)
185
+ logger.info(f"Informaci贸n del estudiante actualizada: {username}")
186
+ return True
187
+ else:
188
+ logger.warning(f"Intento de actualizar estudiante no existente: {username}")
189
+ return False
190
+ except Exception as e:
191
+ logger.error(f"Error al actualizar informaci贸n del estudiante {username}: {str(e)}")
192
+ return False
193
+
194
+
195
+ def delete_student_user(username):
196
+ user_container, _, _ = get_sql_containers()
197
+ try:
198
+ user = get_student_user(username)
199
+ if user:
200
+ user_container.delete_item(item=user['id'], partition_key=username)
201
+ logger.info(f"Estudiante eliminado: {username}")
202
+ return True
203
+ else:
204
+ logger.warning(f"Intento de eliminar estudiante no existente: {username}")
205
+ return False
206
+ except Exception as e:
207
+ logger.error(f"Error al eliminar estudiante {username}: {str(e)}")
208
+ return False
209
+
210
+ def store_application_request(name, lastname, email, institution, current_role, desired_role, reason):
211
+ _, application_requests_container, _ = get_sql_containers()
212
+ try:
213
+ application_request = {
214
+ "id": str(uuid.uuid4()),
215
+ "name": name,
216
+ "lastname": lastname,
217
+ "email": email,
218
+ "institution": institution,
219
+ "current_role": current_role,
220
+ "desired_role": desired_role,
221
+ "reason": reason,
222
+ "requestDate": datetime.utcnow().isoformat()
223
+ }
224
+ application_requests_container.create_item(body=application_request)
225
+ logger.info(f"Solicitud de aplicaci贸n almacenada para el email: {email}")
226
+ return True
227
+ except Exception as e:
228
+ logger.error(f"Error al almacenar la solicitud de aplicaci贸n: {str(e)}")
229
+ return False
230
+
231
+ def store_student_feedback(username, name, email, feedback):
232
+ _, _, user_feedback_container = get_sql_containers()
233
+ try:
234
+ feedback_item = {
235
+ "id": str(uuid.uuid4()),
236
+ "username": username,
237
+ "name": name,
238
+ "email": email,
239
+ "feedback": feedback,
240
+ "role": "Estudiante",
241
+ 'timestamp': datetime.now(timezone.utc).isoformat(),
242
+ }
243
+ result = user_feedback_container.create_item(body=feedback_item)
244
+ logger.info(f"Feedback de estudiante almacenado con ID: {result['id']} para el usuario: {username}")
245
+ return True
246
+ except Exception as e:
247
+ logger.error(f"Error al almacenar el feedback del estudiante {username}: {str(e)}")
248
  return False