Skip to content

chore: added docstring #6

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ A Docker image has not been created for this project because it requires access
- Check the current firewall status to ensure security.
- A dedicated website monitoring page for tracking uptime and performance.
- Track and save total network data sent/received in the database for data usage monitoring.
- Improve website monitor, save data in database with timestamp to show the history of the website.

## Learnings 📖

Expand Down
23 changes: 1 addition & 22 deletions app.py
Original file line number Diff line number Diff line change
@@ -1,29 +1,8 @@
import os
import time
import datetime
import threading
from src.config import app, db
from src.config import app
from src import routes
from src.utils import get_system_info_for_db
from src.models import SystemInformation, ApplicationGeneralSettings
from sqlalchemy.exc import SQLAlchemyError
from src.logger import logger
from src.thread_process import monitor_settings, start_website_monitoring

def register_routes():
app.register_blueprint(routes.dashboard_bp)
app.register_blueprint(routes.settings_bp)
app.register_blueprint(routes.system_health_bp)
app.register_blueprint(routes.cpu_info_bp)
app.register_blueprint(routes.disk_info_bp)
app.register_blueprint(routes.memory_info_bp)
app.register_blueprint(routes.network_info_bp)
app.register_blueprint(routes.speedtest_bp)
app.register_blueprint(routes.process_bp)


if __name__ == "__main__":
register_routes()

# background thread to monitor system settings changes
# monitor_settings() # Starts monitoring for system logging changes
Expand Down
5 changes: 3 additions & 2 deletions src/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,12 @@
def server_start():
logger.info("Server started")



# 403 forbidden
@app.errorhandler(403)
def forbidden(e):
"""
This function is called when a user tries to access a resource that they are not allowed to access.
"""
return render_template("error/403.html"), 403

# not found page
Expand Down
3 changes: 1 addition & 2 deletions src/logger.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@


# Create a logs directory if it doesn't exist
if not os.path.exists('logs'):
os.makedirs('logs')
os.makedirs('logs', exist_ok=True)

# Log Formatter with datetime, log level, and message
formatter = logging.Formatter(
Expand Down
8 changes: 4 additions & 4 deletions src/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from src.models.dashboard_netowrk import DashboardNetworkSettings
from src.models.user_dashboard_settings import UserDashboardSettings
from src.models.page_toggle_settings import PageToggleSettings
from src.models.application_general_settings import ApplicationGeneralSettings
from src.models.application_general_settings import GeneralSettings
from src.models.smtp_configuration import SMTPSettings
from src.models.network_speed_test_result import NetworkSpeedTestResult
from src.models.system_information import SystemInformation
Expand Down Expand Up @@ -52,9 +52,9 @@
db.session.commit()

# Initialize default user_dashboard_settings
general_settings = ApplicationGeneralSettings.query.first()
general_settings = GeneralSettings.query.first()
if not general_settings:
db.session.add(ApplicationGeneralSettings())
db.session.add(GeneralSettings())
db.session.commit()


Expand All @@ -63,7 +63,7 @@
def inject_settings():
if current_user.is_anonymous:
return dict(user_dashboard_settings=None, card_settings=None, page_toggles_settings=None, general_settings=None)
general_settings = ApplicationGeneralSettings.query.first()
general_settings = GeneralSettings.query.first()
card_settings = UserCardSettings.query.filter_by(user_id=current_user.id).first()
user_dashboard_settings = UserDashboardSettings.query.filter_by(
user_id=current_user.id
Expand Down
12 changes: 11 additions & 1 deletion src/models/application_general_settings.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
from src.config import db

class ApplicationGeneralSettings(db.Model):
class GeneralSettings(db.Model):
"""
General settings model for the application
---
Properties:
- id: int
- enable_alerts: if email alerts are enabled
- timezone: the timezone of the system
- enable_cache: if caching is enabled
- is_logging_system_info: if system info is logged
"""
__tablename__ = 'general_settings'

id = db.Column(db.Integer, primary_key=True)
Expand Down
11 changes: 11 additions & 0 deletions src/models/dashboard_netowrk.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,17 @@


class DashboardNetworkSettings(db.Model):
"""
Dashboard network settings model for the application
---
Properties:
- id: int
- name: the name of the dashboard
- description: the description of the dashboard
- ip_address: the IP address of the dashboard
- port: the port of the dashboard
- link: the link to the dashboard
"""
__tablename__ = "DashboardGroup"
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(50), unique=True, nullable=False)
Expand Down
19 changes: 18 additions & 1 deletion src/models/monitored_website.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,32 @@


class MonitoredWebsite(db.Model):
"""
Monitored website model for the application
---
Properties:
- id: int
- name: the name of the website
- ping_interval: the interval in seconds to ping the website
- is_ping_active: if the website should be pinged
- email_address: the email address to send alerts to
- ping_status: the status of the website
- ping_status_code: the status code of the website
- last_ping_time: the last time the website was pinged
- email_alerts_enabled: if email alerts are enabled
"""
__tablename__ = 'monitored_websites'

id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(255), nullable=False)
ping_interval = db.Column(db.Integer, nullable=False) # in seconds
is_ping_active = db.Column(db.Boolean, default=True) # True: ping the site, False: do not ping
email_alerts_enabled = db.Column(db.Boolean, default=False)
email_address = db.Column(db.String(255), nullable=True)
ping_status = db.Column(db.String(50), nullable=True) # Stores 'UP' or 'DOWN'
ping_status_code = db.Column(db.Integer, nullable=True)
last_ping_time = db.Column(db.DateTime, nullable=True)
email_alerts_enabled = db.Column(db.Boolean, default=False)


def __repr__(self):
return f'<Website {self.name} - Ping Every {self.ping_interval}s>'
10 changes: 10 additions & 0 deletions src/models/network_speed_test_result.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,16 @@
from src.config import db

class NetworkSpeedTestResult(db.Model):
"""
Network speed test result model for the application
---
Properties:
- id: int
- download_speed: the download speed
- upload_speed: the upload speed
- ping: the ping
- timestamp: the timestamp of the speed test
"""
__tablename__ = "network_speed_test_result"
id = db.Column(db.Integer, primary_key=True)
download_speed = db.Column(db.String(50))
Expand Down
13 changes: 13 additions & 0 deletions src/models/page_toggle_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,19 @@
from src.config import db

class PageToggleSettings(db.Model):
"""
Page toggle settings model for the application
---
Properties:
- id: int
- user_id: the user id
- is_cpu_info_enabled: if CPU info is enabled
- is_memory_info_enabled: if memory info is enabled
- is_disk_info_enabled: if disk info is enabled
- is_network_info_enabled: if network info is enabled
- is_process_info_enabled: if process info is enabled
- is_dashboard_network_enabled: if the dashboard network is enabled
"""
__tablename__ = 'feature_toggle_settings'

id = db.Column(db.Integer, primary_key=True)
Expand Down
11 changes: 11 additions & 0 deletions src/models/smtp_configuration.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
from src.config import db

class SMTPSettings(db.Model):
"""
SMTP settings model for the application
---
Properties:
- id: int
- username: the username for the SMTP server
- password: the password for the SMTP server
- smtp_server: the SMTP server
- smtp_port: the SMTP port
- email_from: the email address to send from
"""
__tablename__ = "smtp_settings"
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(150), unique=True, nullable=False)
Expand Down
12 changes: 12 additions & 0 deletions src/models/system_information.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,18 @@


class SystemInformation(db.Model):
"""
System information model for the application
---
Properties:
- id: int
- cpu_percent: the CPU percentage
- memory_percent: the memory percentage
- battery_percent: the battery percentage
- network_sent: the network sent
- network_received: the network received
- timestamp: the timestamp of the system information
"""
__tablename__ = "system_information"
id = db.Column(db.Integer, primary_key=True)
cpu_percent = db.Column(db.Float, nullable=False)
Expand Down
19 changes: 19 additions & 0 deletions src/models/user_card_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,25 @@


class UserCardSettings(db.Model):
"""
User card settings model for the application
---
Properties:
- id: int
- user_id: the user id
- is_user_card_enabled: if the user card is enabled
- is_server_card_enabled: if the server card is enabled
- is_battery_card_enabled: if the battery card is enabled
- is_cpu_core_card_enabled: if the CPU core card is enabled
- is_cpu_usage_card_enabled: if the CPU usage card is enabled
- is_cpu_temp_card_enabled: if the CPU temp card is enabled
- is_dashboard_memory_card_enabled: if the dashboard memory card is enabled
- is_memory_usage_card_enabled: if the memory usage card is enabled
- is_disk_usage_card_enabled: if the disk usage card is enabled
- is_system_uptime_card_enabled: if the system uptime card is enabled
- is_network_statistic_card_enabled: if the network statistic card is enabled
- is_speedtest_enabled: if speedtests are enabled
"""
__tablename__ = "user_card_settings"

id = db.Column(db.Integer, primary_key=True)
Expand Down
13 changes: 12 additions & 1 deletion src/models/user_dashboard_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,22 @@
from src.config import db

class UserDashboardSettings(db.Model):
"""
User dashboard settings model for the application
---
Properties:
- id: int
- user_id: the user id
- speedtest_cooldown: the cooldown for speedtests
- number_of_speedtests: the number of speedtests
- refresh_interval: the refresh interval for the dashboard
"""
__tablename__ = 'user_dashboard_settings'

id = db.Column(db.Integer, primary_key=True)
user_id = db.Column(db.Integer, db.ForeignKey('users.id'))
speedtest_cooldown = db.Column(db.Integer, default=60)
number_of_speedtests = db.Column(db.Integer, default=1)
refresh_interval = db.Column(db.Integer, default=0)

bytes_to_megabytes = db.Column(db.Integer, default=1000)

12 changes: 12 additions & 0 deletions src/models/user_profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,18 @@
from src.config import db

class UserProfile(db.Model, UserMixin):
"""
User profile model for the application
---
Properties:
- id: int
- username: the username
- email: the email
- password: the password
- user_level: the user level
- receive_email_alerts: if the user receives email alerts
- profession: the profession of the user
"""
__tablename__ = 'users'

id = db.Column(db.Integer, primary_key=True)
Expand Down
4 changes: 2 additions & 2 deletions src/routes/other.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from flask import render_template, request, jsonify, flash, blueprints, redirect, url_for
from flask_login import login_required, current_user

from src.models import UserCardSettings, UserDashboardSettings, ApplicationGeneralSettings
from src.models import UserCardSettings, UserDashboardSettings, GeneralSettings
from src.config import app, db
from src.routes.helper import get_email_addresses
from src.scripts.email_me import send_smtp_email
Expand Down Expand Up @@ -74,7 +74,7 @@ def send_email_page():
flash("Please contact your administrator for more information.", "danger")
return render_template("error/403.html")
receiver_email = get_email_addresses(user_level='admin', receive_email_alerts=True)
general_settings = ApplicationGeneralSettings.query.first()
general_settings = GeneralSettings.query.first()
if general_settings:
enable_alerts = general_settings.enable_alerts
if request.method == "POST":
Expand Down
4 changes: 2 additions & 2 deletions src/routes/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from flask import render_template, request, flash, blueprints, redirect, url_for

from src.config import app, db
from src.models import UserCardSettings, UserDashboardSettings, UserProfile, ApplicationGeneralSettings, PageToggleSettings
from src.models import UserCardSettings, UserDashboardSettings, UserProfile, GeneralSettings, PageToggleSettings
from flask_login import login_required, current_user
from src.utils import render_template_from_file, ROOT_DIR
from src.scripts.email_me import send_smtp_email
Expand All @@ -28,7 +28,7 @@ def user_settings():
@login_required
def general_settings():
# Retrieve user-specific settings from DB
general_settings = ApplicationGeneralSettings.query.filter_by().first()
general_settings = GeneralSettings.query.filter_by().first()

# Store the current state of the 'enable_alerts' setting
current_alert_status = general_settings.enable_alerts
Expand Down
43 changes: 42 additions & 1 deletion src/routes/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import datetime
from flask import render_template, redirect, url_for, request, blueprints, flash, blueprints
from flask_login import login_required, current_user
from werkzeug.security import generate_password_hash
from werkzeug.security import generate_password_hash, check_password_hash

from src.config import app, db
from src.models import UserProfile, UserDashboardSettings, UserCardSettings, PageToggleSettings
Expand Down Expand Up @@ -141,3 +141,44 @@ def delete_user(username):

flash(f'User {username} has been deleted successfully!', 'success')
return redirect(url_for('view_users'))

# View Profile Route
@app.route('/profile', methods=['GET'])
@login_required
def view_profile():
"""
This route displays the user's profile information.
"""
user = current_user # Get the currently logged-in user
return render_template('users/view_profile.html', user=user)

# Change Password Route
@app.route('/change_password', methods=['GET', 'POST'])
@login_required
def change_password():
"""
This route allows users to change their password.
"""
if request.method == 'POST':
old_password = request.form['old_password']
new_password = request.form['new_password']
confirm_password = request.form['confirm_password']

# Check if the old password is correct
if not check_password_hash(current_user.password, old_password):
flash('Old password is incorrect.', 'danger')
return redirect(url_for('change_password'))

# Check if the new password matches the confirmation
if new_password != confirm_password:
flash('New passwords do not match.', 'danger')
return redirect(url_for('change_password'))

# Update the user's password
current_user.password = generate_password_hash(new_password)
db.session.commit()

flash('Password changed successfully!', 'success')
return redirect(url_for('view_profile'))

return render_template('users/change_password.html')
Loading