From 986db284946638674b10d6cd41ad4a62c49bad5f Mon Sep 17 00:00:00 2001 From: Kobe Date: Thu, 29 May 2025 23:02:30 +0200 Subject: [PATCH] user update logs --- routes/__pycache__/main.cpython-313.pyc | Bin 45250 -> 45582 bytes routes/main.py | 137 ++++++++++-------- .../__pycache__/event_logger.cpython-313.pyc | Bin 5383 -> 5171 bytes utils/event_logger.py | 5 +- 4 files changed, 77 insertions(+), 65 deletions(-) diff --git a/routes/__pycache__/main.cpython-313.pyc b/routes/__pycache__/main.cpython-313.pyc index 27887f2a7b906b9ed45f66ff5c41dc4f78ecd86f..78e2e9f883fb80ee1b5766b7ff626b838e4da3f1 100644 GIT binary patch delta 4951 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 delta 4740 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 BX(a#v diff --git a/routes/main.py b/routes/main.py index 47fa755..e63c796 100644 --- a/routes/main.py +++ b/routes/main.py @@ -2,6 +2,7 @@ from flask import render_template, Blueprint, redirect, url_for, request, flash, from flask_login import current_user, login_required from models import User, db, Room, RoomFile, RoomMemberPermission, SiteSettings, Event from routes.auth import require_password_change +from utils.event_logger import log_event import os from werkzeug.utils import secure_filename from sqlalchemy import func, case, literal_column, text @@ -273,65 +274,66 @@ def init_routes(main_bp): logger.debug(f"Profile form submitted with data: {request.form}") logger.debug(f"Files in request: {request.files}") - # Handle profile picture removal - if 'remove_picture' in request.form: - logger.debug("Removing profile picture") - if current_user.profile_picture: - # Delete the old profile picture file - old_picture_path = os.path.join(UPLOAD_FOLDER, current_user.profile_picture) - if os.path.exists(old_picture_path): - os.remove(old_picture_path) - current_user.profile_picture = None - db.session.commit() - flash('Profile picture removed successfully!', 'success') - return redirect(url_for('main.profile')) - - new_email = request.form.get('email') - logger.debug(f"New email: {new_email}") - # Check if the new email is already used by another user - if new_email != current_user.email: - existing_user = User.query.filter_by(email=new_email).first() - if existing_user: - flash('A user with this email already exists.', 'error') - return render_template('profile/profile.html') - # Handle profile picture upload - file = request.files.get('profile_picture') - if file and file.filename: - logger.debug(f"Uploading new profile picture: {file.filename}") - filename = secure_filename(file.filename) - file_path = os.path.join(UPLOAD_FOLDER, filename) - file.save(file_path) - current_user.profile_picture = filename - # Update user information - current_user.username = request.form.get('first_name') - current_user.last_name = request.form.get('last_name') - current_user.email = new_email - current_user.phone = request.form.get('phone') - current_user.company = request.form.get('company') - current_user.position = request.form.get('position') - current_user.notes = request.form.get('notes') - - logger.debug(f"Updated user data: username={current_user.username}, last_name={current_user.last_name}, email={current_user.email}") - - # Handle password change if provided - new_password = request.form.get('new_password') - confirm_password = request.form.get('confirm_password') - if new_password: - if not confirm_password: - flash('Please confirm your new password.', 'error') - return render_template('profile/profile.html') - if new_password != confirm_password: - flash('Passwords do not match.', 'error') - return render_template('profile/profile.html') - current_user.set_password(new_password) - flash('Password updated successfully.', 'success') - elif confirm_password: - flash('Please enter a new password.', 'error') - return render_template('profile/profile.html') try: - db.session.commit() - logger.debug("Profile changes committed to database") - # Log profile update event + # Handle profile picture removal + if 'remove_picture' in request.form: + logger.debug("Removing profile picture") + if current_user.profile_picture: + # Delete the old profile picture file + old_picture_path = os.path.join(UPLOAD_FOLDER, current_user.profile_picture) + if os.path.exists(old_picture_path): + os.remove(old_picture_path) + current_user.profile_picture = None + db.session.commit() + flash('Profile picture removed successfully!', 'success') + return redirect(url_for('main.profile')) + + new_email = request.form.get('email') + logger.debug(f"New email: {new_email}") + # Check if the new email is already used by another user + if new_email != current_user.email: + existing_user = User.query.filter_by(email=new_email).first() + if existing_user: + flash('A user with this email already exists.', 'error') + return render_template('profile/profile.html') + + # Handle profile picture upload + file = request.files.get('profile_picture') + if file and file.filename: + logger.debug(f"Uploading new profile picture: {file.filename}") + filename = secure_filename(file.filename) + file_path = os.path.join(UPLOAD_FOLDER, filename) + file.save(file_path) + current_user.profile_picture = filename + + # Update user information + current_user.username = request.form.get('first_name') + current_user.last_name = request.form.get('last_name') + current_user.email = new_email + current_user.phone = request.form.get('phone') + current_user.company = request.form.get('company') + current_user.position = request.form.get('position') + current_user.notes = request.form.get('notes') + + logger.debug(f"Updated user data: username={current_user.username}, last_name={current_user.last_name}, email={current_user.email}") + + # Handle password change if provided + new_password = request.form.get('new_password') + confirm_password = request.form.get('confirm_password') + if new_password: + if not confirm_password: + flash('Please confirm your new password.', 'error') + return render_template('profile/profile.html') + if new_password != confirm_password: + flash('Passwords do not match.', 'error') + return render_template('profile/profile.html') + current_user.set_password(new_password) + flash('Password updated successfully.', 'success') + elif confirm_password: + flash('Please enter a new password.', 'error') + return render_template('profile/profile.html') + + # Create event details event_details = { 'user_id': current_user.id, 'email': current_user.email, @@ -357,15 +359,26 @@ def init_routes(main_bp): 'password_changed': bool(new_password) } } - logger.debug(f"Creating profile update event with details: {event_details}") + logger.debug(f"Preparing to create profile update event with details: {event_details}") + + # Create the event event = log_event('user_update', event_details, current_user.id) - logger.debug(f"Event created successfully with ID: {event.id}") + logger.debug("Event object created and added to session") + + # Commit all changes + db.session.commit() + logger.debug("Profile changes and event committed to database successfully") + flash('Profile updated successfully!', 'success') + return redirect(url_for('main.dashboard')) + except Exception as e: - logger.error(f"Error updating profile or logging event: {str(e)}") + logger.error(f"Error updating profile: {str(e)}") + logger.error(f"Full error details: {str(e.__class__.__name__)}: {str(e)}") db.session.rollback() flash('An error occurred while updating your profile.', 'error') - return redirect(url_for('main.dashboard')) + return render_template('profile/profile.html') + return render_template('profile/profile.html') @main_bp.route('/starred') diff --git a/utils/__pycache__/event_logger.cpython-313.pyc b/utils/__pycache__/event_logger.cpython-313.pyc index 77fedbc714bcdeb5e9c9e2af7118bbbdc8fd1122..d89842b51347c616a6d5cc79a72828eb3517c985 100644 GIT binary patch delta 802 zcmZ`$&ubGw6rSD9n$3^h{EkhawN)d_$@x2sNdT?Ogy!XvF?|bjf%F))awyCO4 z0?YRrnzG&1f+PHSZC|k5tsTdV%HK=KrX0=hj9o89ZFj{6t z$*R`psDbRWH16kj?TxTQUn(0-3y2-rKw?KSEyhF2yz?;VxnP?vzM{+sKK?~njC@tJ zhwl6CcIebcCA01c-g9q#as@Yu$R9ZRht?H!dqWmw?Y9|$m#Zfx-4}A?ZO*Buq&3GO zJt3_nWIfgT?3fU;M}X0hO0`;CWM1$Y0w#=$P|9L>>6tUE;(}?gVz+3M9RoDYUwHdk zP1jRl`Z$Df7qh{^;`m_S^=i$6Hay*+WLn0O#c+Tufks6WK!Z|j1Po|nmc81%q=w{^ z0B86ebyi67j=D910{>4V>}0@?h2r@iZNHoWf0Xxo#)M>R+T#%-!vKJuhKcs{%9p); z@@ar`(AyNyzk92~SXVHO1C9_qc}eP$RBl%LNp26yv&!?Fn{l# zfL?roXE_{6N2=B>hM(LWE5m*n*37UHhHqaJmPEh%8Opg^jmkpJ7-tvxkHEMR6SOCT k8zjcl!N36s+WDDwVfI752pB{+o4@e?)V>vC}M`GBh(S_`9VMFR<>Yd4>x^nt6H&pr0LJN)^od;ss zL=jz}LHm70k1lHpiYk;Q4P7SQzRV+jn_256YL^8W$bl}>WYa=Cp%XgnMMKhbWmQM5 zG~7*vjfz?-C=9wp1i__M&cH>gnk?fEkTgHp+6)m7!551Izp>sn^$<&DaIeFOTWp7u zw2iaDm=X^CNdL#HrsE++CZm;s21#@jhlD_>He0OyLipwKk^t#fpb)2c!dvzR<1lew z!yoN8nV!r!N1O>1Tj{6C#gR`KI2oQpBQ$=cQjsH?NU6u~s+)}gVol(~>bp!24%9rq zN|`Kh@sy6}&nmtIqO>5|GNKJ2dgT>Bl$Fx^!O^5TznoCU&=jt(9rJfE!n3v`K#onA pcBbW>{&Z}+Ip?`n^ku`d*~q List[Event]: