1- from flask import Flask , render_template , request , flash
2- from flask_sqlalchemy import SQLAlchemy
1+ from flask import render_template , request , flash
32import os
43import psutil
54import datetime
65import subprocess
7-
8- app = Flask (__name__ )
9-
10- # Configure the SQLite database
11- app .config ['SQLALCHEMY_DATABASE_URI' ] = 'sqlite:///speedtest_results.db'
12- app .config ['SQLALCHEMY_TRACK_MODIFICATIONS' ] = False
13- app .config ['SECRET_KEY' ] = 'secret'
14-
15- # Initialize the database
16- db = SQLAlchemy (app )
17-
18- # Define the model for storing speed test results
19- class SpeedTestResult (db .Model ):
20- id = db .Column (db .Integer , primary_key = True )
21- download_speed = db .Column (db .String (50 ))
22- upload_speed = db .Column (db .String (50 ))
23- ping = db .Column (db .String (50 ))
24- timestamp = db .Column (db .DateTime , default = datetime .datetime .now ())
25-
26- def __repr__ (self ):
27- return f'<SpeedTestResult { self .download_speed } , { self .upload_speed } , { self .ping } >'
28-
29- class DashoardSettings (db .Model ):
30- id = db .Column (db .Integer , primary_key = True )
31- speedtest_cooldown = db .Column (db .Integer , default = 1 )
32- number_of_speedtests = db .Column (db .Integer , default = 1 )
33- timezone = db .Column (db .String (50 ), default = 'Asia/Kolkata' )
34-
35- def __repr__ (self ):
36- return f'<DashboardSettings { self .speedtest_cooldown } , { self .timezone } , { self .number_of_speedtests } >'
37-
38- class SystemInfo (db .Model ):
39- id = db .Column (db .Integer , primary_key = True )
40- username = db .Column (db .String (50 ))
41- cpu_percent = db .Column (db .Float )
42- memory_percent = db .Column (db .Float )
43- disk_usage = db .Column (db .Float )
44- battery_percent = db .Column (db .Float )
45- cpu_core = db .Column (db .Integer )
46- boot_time = db .Column (db .String (50 ))
47- network_sent = db .Column (db .Float )
48- network_received = db .Column (db .Float )
49- process_count = db .Column (db .Integer )
50- swap_memory = db .Column (db .Float )
51- uptime = db .Column (db .String (50 ))
52- ipv4_connections = db .Column (db .String (50 ))
53- dashboard_memory_usage = db .Column (db .String (50 ))
54- timestamp = db .Column (db .DateTime , default = datetime .datetime .now ())
55-
56- def __repr__ (self ):
57- return f'<SystemInfo { self .username } , { self .cpu_percent } , { self .memory_percent } , { self .disk_usage } , { self .battery_percent } , { self .cpu_core } , { self .boot_time } , { self .network_sent } , { self .network_received } , { self .process_count } , { self .swap_memory } , { self .uptime } , { self .ipv4_connections } , { self .ipv6_connections } , { self .dashboard_memory_usage } >'
6+ from src .config import app , db
7+ from src .models import SpeedTestResult , DashoardSettings , SystemInfo
8+ from src .utils import (
9+ datetimeformat ,
10+ run_speedtest ,
11+ get_system_info
12+ )
5813
5914# initialize the database
6015with app .app_context ():
@@ -64,100 +19,11 @@ def __repr__(self):
6419 db .session .add (DashoardSettings ())
6520 db .session .commit ()
6621
67- def change_up_time_format (uptime ):
68- uptime_seconds = uptime .total_seconds ()
69- days = int (uptime_seconds // (24 * 3600 ))
70- uptime_seconds %= (24 * 3600 )
71- hours = int (uptime_seconds // 3600 )
72- uptime_seconds %= 3600
73- minutes = int (uptime_seconds // 60 )
74- return f"{ days } days, { hours } hours, { minutes } minutes"
75-
76- def run_speedtest ():
77- try :
78- result = subprocess .run (['speedtest-cli' ], capture_output = True , text = True , check = True )
79- output_lines = result .stdout .splitlines ()
80- download_speed , upload_speed , ping = None , None , None
81-
82- for line in output_lines :
83- if "Download:" in line :
84- download_speed = line .split ("Download: " )[1 ]
85- elif "Upload:" in line :
86- upload_speed = line .split ("Upload: " )[1 ]
87- elif "Ping:" in line :
88- ping = line .split ("Ping: " )[1 ]
89-
90- return {"download_speed" : download_speed , "upload_speed" : upload_speed , "ping" : ping ,
91- "status" : "Success" }
92-
93- except subprocess .CalledProcessError as e :
94- error = {"status" : "Error" , "message" : e .stderr }
95- return error
96-
97- except Exception as e :
98- error = {"status" : "Error" , "message" : str (e )}
99- return error
100-
101- def datetimeformat (value , format = '%Y-%m-%d %H:%M:%S' ):
102- return value .strftime (format )
103-
104-
105- def get_flask_memory_usage ():
106- """
107- Returns the memory usage of the current Flask application in MB.
108- """
109- pid = os .getpid ()
110- process = psutil .Process (pid )
111- memory_info = process .memory_info ()
112- memory_in_mb = memory_info .rss / (1024 ** 2 )
113- return f"{ round (memory_in_mb )} MB"
114-
115- def get_system_info ():
116- print ("Getting system information..." )
117- ipv4_dict , ipv6_dict = get_established_connections ()
118- info = {
119- 'username' : os .getlogin (),
120- 'cpu_percent' : round (psutil .cpu_percent (interval = 1 ), 2 ),
121- 'memory_percent' : round (psutil .virtual_memory ().percent , 2 ),
122- 'disk_usage' : round (psutil .disk_usage ('/' ).percent , 2 ),
123- 'battery_percent' : round (psutil .sensors_battery ().percent ) if psutil .sensors_battery () else "N/A" ,
124- 'cpu_core' : psutil .cpu_count (),
125- 'boot_time' : datetime .datetime .fromtimestamp (psutil .boot_time ()).strftime ("%Y-%m-%d %H:%M:%S" ),
126- 'network_sent' : round (psutil .net_io_counters ().bytes_sent / (1024 ** 2 ), 2 ), # In MB
127- 'network_received' : round (psutil .net_io_counters ().bytes_recv / (1024 ** 2 ), 2 ), # In MB
128- 'process_count' : len (psutil .pids ()),
129- 'swap_memory' : psutil .swap_memory ().percent ,
130- 'uptime' : change_up_time_format (datetime .datetime .now () - datetime .datetime .fromtimestamp (psutil .boot_time ())),
131- 'ipv4_connections' : ipv4_dict ,
132- 'dashboard_memory_usage' : get_flask_memory_usage (),
133- 'timestamp' : datetime .datetime .now ()
134- }
135- with app .app_context ():
136- db .session .add (SystemInfo (** info ))
137- db .session .commit ()
138- return info
139-
140- def get_established_connections ():
141- connections = psutil .net_connections ()
142- ipv4_dict = set ()
143- ipv6_dict = set ()
144-
145- for conn in connections :
146- if conn .status == 'ESTABLISHED' :
147- if '.' in conn .laddr .ip :
148- ipv4_dict .add (conn .laddr .ip )
149- elif ':' in conn .laddr .ip :
150- ipv6_dict .add (conn .laddr .ip )
151-
152- ipv4_dict = [ip for ip in ipv4_dict if ip .startswith ('192.168' )]
153- return ipv4_dict [0 ] if ipv4_dict else "N/A" , ipv6_dict
154-
15522@app .route ('/' )
15623def dashboard ():
157- results = {}
15824 settings = DashoardSettings .query .first ()
15925 SPEEDTEST_COOLDOWN_IN_HOURS = settings .speedtest_cooldown
160- system_info = get_system_info ()
26+ system_info = get_system_info (SystemInfo = SystemInfo )
16127
16228 # Fetch the last speedtest result
16329 n_hour_ago = datetime .datetime .now () - datetime .timedelta (hours = SPEEDTEST_COOLDOWN_IN_HOURS )
@@ -270,7 +136,7 @@ def network_stats():
270136
271137@app .route ('/system_health' )
272138def system_health ():
273- system_info = get_system_info ()
139+ system_info = get_system_info (SystemInfo = SystemInfo )
274140 return render_template ('system_health.html' , system_info = system_info )
275141
276142if __name__ == '__main__' :
0 commit comments