Skip to content

Commit 006d616

Browse files
feat: email sending script added for process kill
1 parent 6209230 commit 006d616

27 files changed

Lines changed: 640 additions & 93 deletions

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ chmod +x install_miniconda.sh && sudo ./install_miniconda.sh
5656
- Responsive design that works on mobile, tablet, and desktop.
5757
- Update itself to the latest version.
5858
- Easy download and installation using a bash script.
59+
- Logged user and admin user will get the notification if the user kill some process manully on dashbaord.
5960

6061

6162
## Product Screenshots 📸

requirements.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@ psutil==5.9.5
33
gunicorn
44
flask-sqlalchemy
55
flask-login
6-
flask-session
6+
flask-session
7+
python-dotenv

src/models.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ def __repr__(self):
1818
f"<SpeedTestResult {self.download_speed}, {self.upload_speed}, {self.ping}>"
1919
)
2020

21-
2221
class DashboardSettings(db.Model):
2322
__tablename__ = "DashboardSettings"
2423
id = db.Column(db.Integer, primary_key=True)
@@ -84,10 +83,18 @@ def __repr__(self):
8483
class User(db.Model, UserMixin):
8584
id = db.Column(db.Integer, primary_key=True)
8685
username = db.Column(db.String(150), unique=True, nullable=False)
86+
email = db.Column(db.String(150), unique=True, nullable=False)
8787
password = db.Column(db.String(150), nullable=False)
8888
user_level = db.Column(db.String(50), nullable=False, default='user')
8989

9090

91+
class EmailPassword(db.Model):
92+
__tablename__ = "EmailPassword"
93+
id = db.Column(db.Integer, primary_key=True)
94+
email = db.Column(db.String(150), unique=True, nullable=False)
95+
password = db.Column(db.String(150), nullable=False)
96+
97+
9198
with app.app_context():
9299
print("Creating tables")
93100
db.create_all()
@@ -101,14 +108,17 @@ class User(db.Model, UserMixin):
101108
# Create admin user if not exists
102109
if not User.query.filter_by(username='admin').first():
103110
hashed_password = generate_password_hash('adminpassword')
104-
admin_user = User(username='admin', password=hashed_password, user_level='admin')
111+
admin_user = User(username='admin', email="codeperfectplus@gmail.com", password=hashed_password, user_level='admin')
112+
105113
db.session.add(admin_user)
106114
db.session.commit()
107115

108116
# create a user if not exists
109117
if not User.query.filter_by(username='user').first():
110118
hashed_password = generate_password_hash('userpassword')
111-
user = User(username='user', password=hashed_password, user_level='user')
119+
user = User(username='user', email="test@mail.com",
120+
password=hashed_password, user_level='user')
121+
112122
db.session.add(user)
113123
db.session.commit()
114124

src/routes/auth.py

Lines changed: 68 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22
from flask_login import LoginManager, UserMixin, login_user, login_required, logout_user, current_user
33
from flask_sqlalchemy import SQLAlchemy
44
from werkzeug.security import generate_password_hash, check_password_hash
5+
from src.scripts.email_me import send_email
56

67
from src.config import app, db
7-
from src.models import User
8+
from src.models import User, EmailPassword
89

910
auth_bp = blueprints.Blueprint('auth', __name__)
1011

@@ -28,7 +29,7 @@ def login():
2829
if user and check_password_hash(user.password, password):
2930
login_user(user)
3031
return redirect(url_for('dashboard'))
31-
flash('Invalid username or password')
32+
flash('Invalid username or password', 'danger')
3233
return render_template('login.html')
3334

3435
@app.route('/signup', methods=['GET', 'POST'])
@@ -88,3 +89,68 @@ def logout():
8889
# return redirect(url_for('login'))
8990
# return f(*args, **kwargs)
9091
# return decorated_function
92+
93+
@app.route('/user/<username>', methods=['GET', 'POST'])
94+
@login_required
95+
def change_user_settings(username):
96+
user = User.query.filter_by(username=username).first_or_404()
97+
98+
if request.method == 'POST':
99+
new_username = request.form['username']
100+
new_user_level = request.form['user_level']
101+
102+
# Update user details
103+
user.username = new_username
104+
user.user_level = new_user_level
105+
db.session.commit()
106+
107+
flash('User settings updated successfully!', 'success')
108+
return redirect(url_for('change_user_settings', username=user.username))
109+
110+
return render_template('change_user.html', user=user)
111+
112+
113+
@app.route("/update-email-password", methods=["GET", "POST"])
114+
@login_required
115+
def update_email_password():
116+
email_password = EmailPassword.query.first()
117+
118+
if request.method == "POST":
119+
new_email = request.form.get("email")
120+
new_password = request.form.get("password")
121+
122+
if new_email:
123+
email_password.email = new_email
124+
if new_password:
125+
email_password.password = new_password
126+
127+
db.session.commit()
128+
flash("Email and password updated successfully!", "success")
129+
return redirect(url_for("update_email_password"))
130+
131+
return render_template("update_email_password.html", email_password=email_password)
132+
133+
@app.route("/send_email", methods=["GET", "POST"])
134+
@login_required
135+
def send_email_page():
136+
if request.method == "POST":
137+
receiver_email = request.form.get("receiver_email")
138+
subject = request.form.get("subject")
139+
body = request.form.get("body")
140+
attachment = request.files.get("attachment")
141+
142+
# Save attachment if any
143+
attachment_path = None
144+
if attachment:
145+
attachment_path = f"/tmp/{attachment.filename}"
146+
attachment.save(attachment_path)
147+
148+
try:
149+
send_email(receiver_email, subject, body, attachment_path)
150+
flash("Email sent successfully!", "success")
151+
except Exception as e:
152+
flash(f"Failed to send email: {str(e)}", "danger")
153+
154+
return redirect(url_for('send_email_page'))
155+
156+
return render_template("send_email.html")

src/routes/cpu_info.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
import psutil
22
from flask import render_template, blueprints, flash
33

4+
from flask_login import login_required
5+
46
from src.config import app
57
from src.utils import get_cpu_core_count, get_cpu_frequency, cpu_usage_percent, get_cpu_temp, get_cached_value
68
from src.models import DashboardSettings
79

810
cpu_info_bp = blueprints.Blueprint("cpu_usage", __name__)
911

1012
@app.route("/cpu_usage")
13+
@login_required
1114
def cpu_usage():
1215
settings = DashboardSettings.query.first()
1316
if not settings.is_cpu_info_enabled:

src/routes/disk_info.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
import psutil
22

33
from flask import render_template, blueprints, flash
4-
4+
from flask_login import login_required
55
from src.config import app
66
from src.utils import get_cached_value, get_disk_free, get_disk_total, get_disk_used, get_disk_usage_percent
77
from src.models import DashboardSettings
88

99
disk_info_bp = blueprints.Blueprint("disk_usage", __name__)
1010

1111
@app.route("/disk_usage")
12+
@login_required
1213
def disk_usage():
1314
settings = DashboardSettings.query.first()
1415
if not settings.is_disk_info_enabled:

src/routes/homepage.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import datetime
2-
from flask import render_template, blueprints, session
2+
from flask import render_template, blueprints
3+
from flask_login import login_required
34

45
from src.config import app
56
from src.models import SpeedTestResult, DashboardSettings, SystemInfo
@@ -8,6 +9,7 @@
89
homepage_bp = blueprints.Blueprint("homepage", __name__)
910

1011
@app.route("/")
12+
@login_required
1113
def dashboard():
1214
settings = DashboardSettings.query.first()
1315
SPEEDTEST_COOLDOWN_IN_HOURS = settings.speedtest_cooldown

src/routes/memory_info.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import psutil
22
from flask import render_template, blueprints, flash
3+
from flask_login import login_required
34

45
from src.config import app
56
from src.utils import get_cached_value, get_memory_percent, get_memory_available, get_memory_used, get_swap_memory_info
@@ -9,6 +10,7 @@
910

1011

1112
@app.route("/memory_usage")
13+
@login_required
1214
def memory_usage():
1315
settings = DashboardSettings.query.first()
1416
if not settings.is_memory_info_enabled:

src/routes/network_info.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
import psutil
22
from flask import render_template, blueprints, flash
3-
3+
from flask_login import login_required
44
from src.config import app
55
from src.utils import get_established_connections
66
from src.models import DashboardSettings
77

88
network_info_bp = blueprints.Blueprint("network_stats", __name__)
99

1010
@app.route("/network_stats")
11+
@login_required
1112
def network_stats():
1213
settings = DashboardSettings.query.first()
1314
if not settings.is_network_info_enabled:

src/routes/process.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from src.config import app
55
from src.utils import get_top_processes
66
from src.models import DashboardSettings
7+
from src.scripts.email_me import send_email
78

89
process_bp = blueprints.Blueprint("process", __name__)
910

@@ -31,6 +32,10 @@ def process():
3132
try:
3233
os.kill(int(pid_to_kill), 9) # Sends a SIGKILL signal
3334
flash(f"Process '{process_name}' (PID {pid_to_kill}) killed successfully.", "success")
35+
receiver_email = current_user.email
36+
subject = f"Process '{process_name}' (PID {pid_to_kill}) killed successfully."
37+
body = f"Process '{process_name}' (PID {pid_to_kill}) was killed successfully by {current_user.username}."
38+
send_email(receiver_email, subject, body)
3439
except Exception as e:
3540
flash(f"Failed to kill process '{process_name}' (PID {pid_to_kill}). Error: {e}", "danger")
3641
return redirect(url_for("process")) # Refresh the page after killing process

0 commit comments

Comments
 (0)