|
|
|
@ -0,0 +1,328 @@
|
|
|
|
|
import csv
|
|
|
|
|
import codecs
|
|
|
|
|
import time
|
|
|
|
|
import os
|
|
|
|
|
import numpy as np #importing the python libraries
|
|
|
|
|
from PyQt5.QtCore import QFile
|
|
|
|
|
from PyQt5.QtCore import QFileInfo
|
|
|
|
|
from PyQt5.QtCore import QPoint
|
|
|
|
|
from PyQt5.QtCore import QRect
|
|
|
|
|
from PyQt5.QtCore import QSettings
|
|
|
|
|
from PyQt5.QtCore import QSize
|
|
|
|
|
from PyQt5.QtCore import Qt
|
|
|
|
|
from PyQt5.QtCore import QTextStream
|
|
|
|
|
from PyQt5.QtCore import QProcess
|
|
|
|
|
from PyQt5.QtCore import QDir
|
|
|
|
|
from PyQt5.QtGui import QIcon
|
|
|
|
|
from PyQt5.QtGui import QFont
|
|
|
|
|
from PyQt5.QtWidgets import QAction
|
|
|
|
|
from PyQt5.QtWidgets import QApplication
|
|
|
|
|
from PyQt5.QtWidgets import QMainWindow
|
|
|
|
|
from PyQt5.QtWidgets import QTableWidget
|
|
|
|
|
from PyQt5.QtWidgets import QTableWidgetItem
|
|
|
|
|
from PyQt5.QtWidgets import QComboBox
|
|
|
|
|
from PyQt5.QtWidgets import QAbstractItemView
|
|
|
|
|
import matplotlib.pyplot as plt;
|
|
|
|
|
#importing the pyqt5 and matplotlib libraries on project
|
|
|
|
|
plt.rcdefaults()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class Homepage(QMainWindow):
|
|
|
|
|
def __init__(self):
|
|
|
|
|
super(Homepage, self).__init__()
|
|
|
|
|
|
|
|
|
|
self.path = QDir('C:/Speedtest_Save')
|
|
|
|
|
if not QDir.exists(self.path):
|
|
|
|
|
print("Folder is not Exisiting! Please Wait till it create New.......") #if the folder doesn't exist it throws error message
|
|
|
|
|
dir = QDir()
|
|
|
|
|
newfolder = 'C:/SpeedTest_Save' #Creating the new folder
|
|
|
|
|
dir.mkpath(newfolder)
|
|
|
|
|
self.myfile = 'C:/SpeedTest_Save' + '/Speedtest_results.csv' #saving the file
|
|
|
|
|
self.isChanged = False
|
|
|
|
|
self.setStyleSheet(design(self))
|
|
|
|
|
self.speedtestExec = "C:/Users/jagan/speedtest-cli.exe" #executable file path for the speedtest
|
|
|
|
|
|
|
|
|
|
self.cmd = ''
|
|
|
|
|
print("Cmd started")
|
|
|
|
|
self.list = []
|
|
|
|
|
print("list started")
|
|
|
|
|
self.date = ""
|
|
|
|
|
print("date started")
|
|
|
|
|
self.time = ""
|
|
|
|
|
print("time started")
|
|
|
|
|
self.download = ""
|
|
|
|
|
print("download started")
|
|
|
|
|
self.upload = ""
|
|
|
|
|
print("upload started")
|
|
|
|
|
self.ping = ""
|
|
|
|
|
print("Ping started")
|
|
|
|
|
self.server = ""
|
|
|
|
|
print("Server started")
|
|
|
|
|
self.process = QProcess(self)
|
|
|
|
|
print("Process Started")
|
|
|
|
|
|
|
|
|
|
self.process.started.connect(lambda: self.showMessage("Speed Test Has Been Started")) #showing the test messages
|
|
|
|
|
print("Test Started")
|
|
|
|
|
|
|
|
|
|
print("Test Completed")
|
|
|
|
|
self.process.finished.connect(self.processFinished)
|
|
|
|
|
self.process.readyRead.connect(self.processOut)
|
|
|
|
|
|
|
|
|
|
self.tableview = QTableWidget()
|
|
|
|
|
print("Table creation success")
|
|
|
|
|
self.tableview.setColumnCount(6)
|
|
|
|
|
print("Process Started")
|
|
|
|
|
self.setHeaders()
|
|
|
|
|
print("Process Started for the headers")
|
|
|
|
|
self.tableview.verticalHeader().setVisible(False)
|
|
|
|
|
print("Process Started")
|
|
|
|
|
self.tableview.horizontalHeader().setVisible(False)
|
|
|
|
|
print("Process Started")
|
|
|
|
|
self.tableview.setSelectionBehavior(QAbstractItemView.SelectRows)
|
|
|
|
|
print("Process Started")
|
|
|
|
|
self.setCentralWidget(self.tableview)
|
|
|
|
|
self.setWindowIcon(QIcon.fromTheme('network'))
|
|
|
|
|
self.toolbarcreation()
|
|
|
|
|
self.createStatusBar()
|
|
|
|
|
|
|
|
|
|
self.readSettings()
|
|
|
|
|
print("read setting started")
|
|
|
|
|
|
|
|
|
|
self.combofillbox()
|
|
|
|
|
self.title = "frame"
|
|
|
|
|
self.setMinimumSize(440, 220)
|
|
|
|
|
|
|
|
|
|
def displaychartdownload(self): #Ploting the download graph
|
|
|
|
|
data = []
|
|
|
|
|
for row in range(self.tableview.rowCount()):
|
|
|
|
|
data.append(float(self.tableview.item(row, 2).text()))
|
|
|
|
|
print(data)
|
|
|
|
|
performance = data
|
|
|
|
|
y_pos = np.arange(len(performance))
|
|
|
|
|
plt.bar(y_pos, performance, align='center', alpha=0.5)
|
|
|
|
|
plt.xticks(y_pos, "")
|
|
|
|
|
plt.ylabel('Mbit/s')
|
|
|
|
|
plt.title('Speed Test Chart - Download')
|
|
|
|
|
plt.show()
|
|
|
|
|
|
|
|
|
|
def displaychartupload(self): #plotting the upload chart
|
|
|
|
|
plt.rcParams['toolbar'] = 'None'
|
|
|
|
|
data = []
|
|
|
|
|
for row in range(self.tableview.rowCount()):
|
|
|
|
|
data.append(float(self.tableview.item(row, 3).text()))
|
|
|
|
|
print(data)
|
|
|
|
|
performance = data
|
|
|
|
|
y_pos = np.arange(len(performance))
|
|
|
|
|
plt.bar(y_pos, performance, align='center', alpha=0.5)
|
|
|
|
|
plt.xticks(y_pos, "")
|
|
|
|
|
plt.ylabel('Mbit/s')
|
|
|
|
|
plt.title('Speed Test Chart - Upload')
|
|
|
|
|
plt.tight_layout()
|
|
|
|
|
plt.show()
|
|
|
|
|
|
|
|
|
|
def combofillbox(self): #creating a toolbar function
|
|
|
|
|
plt.rcParams['toolbar'] = 'None'
|
|
|
|
|
cmd = self.speedtestExec + " --list" #speedtest executable file
|
|
|
|
|
serverlist = []
|
|
|
|
|
myprocess = QProcess()
|
|
|
|
|
myprocess.start(cmd)
|
|
|
|
|
myprocess.waitForFinished(-1)
|
|
|
|
|
output = str(myprocess.readAll(), encoding='utf8').rstrip()
|
|
|
|
|
serverlist.append(output)
|
|
|
|
|
out = ','.join(serverlist)
|
|
|
|
|
out = out.partition("Retrieving speedtest.net configuration...")[2] #Retreieving the speedtest configurations
|
|
|
|
|
out = out.partition('\n')[2]
|
|
|
|
|
mylist = out.rsplit('\n')
|
|
|
|
|
self.combo.addItem("auto")
|
|
|
|
|
self.combo.addItems(mylist)
|
|
|
|
|
self.combo.setCurrentIndex(1)
|
|
|
|
|
|
|
|
|
|
def setHeaders(self): #setting width of the column
|
|
|
|
|
self.tableview.horizontalHeader().setVisible(False)
|
|
|
|
|
font = QFont()
|
|
|
|
|
font.setPointSize(8)
|
|
|
|
|
self.tableview.horizontalHeader().setFont(font) #setting the table view
|
|
|
|
|
self.tableview.setColumnWidth(0, 80)
|
|
|
|
|
self.tableview.setColumnWidth(1, 60)
|
|
|
|
|
self.tableview.setColumnWidth(2, 70)
|
|
|
|
|
self.tableview.setColumnWidth(3, 60)
|
|
|
|
|
self.tableview.setColumnWidth(4, 60)
|
|
|
|
|
self.tableview.setColumnWidth(5, 100)
|
|
|
|
|
self.tableview.setHorizontalHeaderItem(0, QTableWidgetItem("Date"))
|
|
|
|
|
self.tableview.setHorizontalHeaderItem(1, QTableWidgetItem("Time"))
|
|
|
|
|
self.tableview.setHorizontalHeaderItem(2, QTableWidgetItem("Download"))
|
|
|
|
|
self.tableview.setHorizontalHeaderItem(3, QTableWidgetItem("Upload"))
|
|
|
|
|
self.tableview.setHorizontalHeaderItem(4, QTableWidgetItem("Ping"))
|
|
|
|
|
self.tableview.setHorizontalHeaderItem(5, QTableWidgetItem("Server"))
|
|
|
|
|
|
|
|
|
|
def showMessage(self, message): #displaying the status bar message
|
|
|
|
|
self.statusBar().showMessage(message)
|
|
|
|
|
|
|
|
|
|
def closeEvent(self, event): #saving the Output file on CSV
|
|
|
|
|
self.writeSettings()
|
|
|
|
|
if self.isChanged == True:
|
|
|
|
|
self.createCSV()
|
|
|
|
|
event.accept()
|
|
|
|
|
|
|
|
|
|
def createActions(self):
|
|
|
|
|
root = QFileInfo(__file__).absolutePath()
|
|
|
|
|
|
|
|
|
|
def toolbarcreation(self): #creating the frames
|
|
|
|
|
self.tb = self.addToolBar("File")
|
|
|
|
|
self.title = "PyQt5 Frame"
|
|
|
|
|
self.tb.setMovable(False)
|
|
|
|
|
self.testAct = QAction(QIcon.fromTheme('media-playback-start'), "Start", self,
|
|
|
|
|
statusTip="Speed Test Has Been Started",
|
|
|
|
|
triggered=self.startTest)
|
|
|
|
|
self.tb.addAction(self.testAct)
|
|
|
|
|
self.combo = QComboBox()
|
|
|
|
|
self.combo.setFixedWidth(400)
|
|
|
|
|
self.tb.addWidget(self.combo)
|
|
|
|
|
self.chartActD = QAction(QIcon.fromTheme('chart'), "Graph For Download Speed", self,
|
|
|
|
|
statusTip="show Chart",
|
|
|
|
|
triggered=self.displaychartdownload)
|
|
|
|
|
self.tb.addAction(self.chartActD)
|
|
|
|
|
self.chartActU = QAction(QIcon.fromTheme('chart'), "Graph for Upload Speed", self,
|
|
|
|
|
statusTip="show Chart",
|
|
|
|
|
triggered=self.displaychartupload)
|
|
|
|
|
self.tb.addAction(self.chartActU)
|
|
|
|
|
|
|
|
|
|
def startTest(self): #Starting the speedtest
|
|
|
|
|
self.started = time.time()
|
|
|
|
|
self.list = []
|
|
|
|
|
self.date = ""
|
|
|
|
|
self.time = ""
|
|
|
|
|
self.download = ""
|
|
|
|
|
self.upload = ""
|
|
|
|
|
self.ping = ""
|
|
|
|
|
self.server = ""
|
|
|
|
|
if self.combo.currentText() == "automatic_server":
|
|
|
|
|
print("automatic_server Started")
|
|
|
|
|
self.cmd = self.speedtestExec
|
|
|
|
|
else:
|
|
|
|
|
myserver = self.combo.currentText().partition(")")[0]
|
|
|
|
|
self.cmd = self.speedtestExec + " --server " + myserver
|
|
|
|
|
print("Speed Test started *** " + self.cmd)
|
|
|
|
|
if QFile.exists(self.speedtestExec):
|
|
|
|
|
self.process.start(self.cmd)
|
|
|
|
|
else:
|
|
|
|
|
self.showMessage("Connection to the server is not reachable")
|
|
|
|
|
|
|
|
|
|
def createStatusBar(self):
|
|
|
|
|
self.showMessage("Ready") #Alert Message
|
|
|
|
|
|
|
|
|
|
def readSettings(self): #read settings
|
|
|
|
|
settings = QSettings("cambria", "SpeedTest") #Font selection
|
|
|
|
|
pos = settings.value("pos", QPoint(200, 200))
|
|
|
|
|
size = settings.value("size", QSize(400, 400))
|
|
|
|
|
self.resize(size)
|
|
|
|
|
self.move(pos)
|
|
|
|
|
|
|
|
|
|
def writeSettings(self): #write settings
|
|
|
|
|
settings = QSettings("cambria", "SpeedTest")
|
|
|
|
|
settings.setValue("pos", self.pos())
|
|
|
|
|
settings.setValue("size", self.size())
|
|
|
|
|
|
|
|
|
|
def addRow(self): #adding the row and setting its date and time
|
|
|
|
|
row = self.tableview.rowCount()
|
|
|
|
|
newItem = QTableWidgetItem(time.strftime('%d.%m.%Y'))
|
|
|
|
|
self.tableview.insertRow(row)
|
|
|
|
|
self.tableview.horizontalHeader().setStretchLastSection(True)
|
|
|
|
|
column = 0
|
|
|
|
|
self.tableview.setItem(row, column, newItem)
|
|
|
|
|
newItem = QTableWidgetItem(time.strftime('%H:%M'))
|
|
|
|
|
column = 1
|
|
|
|
|
self.tableview.setItem(row, column, newItem)
|
|
|
|
|
newItem = QTableWidgetItem(self.download)
|
|
|
|
|
column = 2
|
|
|
|
|
self.tableview.setItem(row, column, newItem)
|
|
|
|
|
newItem = QTableWidgetItem(self.upload)
|
|
|
|
|
column = 3
|
|
|
|
|
self.tableview.setItem(row, column, newItem)
|
|
|
|
|
newItem = QTableWidgetItem(self.ping)
|
|
|
|
|
column = 4
|
|
|
|
|
self.tableview.setItem(row, column, newItem)
|
|
|
|
|
newItem = QTableWidgetItem(self.server)
|
|
|
|
|
column = 5
|
|
|
|
|
self.tableview.setItem(row, column, newItem)
|
|
|
|
|
self.isChanged = True
|
|
|
|
|
last = self.tableview.rowCount() - 1
|
|
|
|
|
self.tableview.selectRow(last)
|
|
|
|
|
self.ended = time.time() - self.started
|
|
|
|
|
m, s = divmod(time.time() - self.started, 60)
|
|
|
|
|
h, m = divmod(m, 60)
|
|
|
|
|
time_str = "%02d:%02d" % (m, s)
|
|
|
|
|
print('Operation completed in', time_str)
|
|
|
|
|
self.tableview.resizeRowsToContents()
|
|
|
|
|
self.showMessage('Speed Test completed in ' + time_str)
|
|
|
|
|
|
|
|
|
|
def processOut(self):
|
|
|
|
|
try:
|
|
|
|
|
output = str(self.process.readAll(), encoding='utf8').rstrip()
|
|
|
|
|
except Error:
|
|
|
|
|
output = str(self.process.readAll()).rstrip()
|
|
|
|
|
self.list.append(output)
|
|
|
|
|
|
|
|
|
|
def processFinished(self):
|
|
|
|
|
out = ','.join(self.list)
|
|
|
|
|
self.download = out.partition("Download: ")[2]
|
|
|
|
|
self.download = self.download.partition(' Mbit/s')[0]
|
|
|
|
|
|
|
|
|
|
self.upload = out.partition("Upload: ")[2]
|
|
|
|
|
self.upload = self.upload.partition(' Mbit/s')[0]
|
|
|
|
|
|
|
|
|
|
self.ping = out.partition("km]: ")[2]
|
|
|
|
|
self.ping = self.ping.partition(' ms')[0]
|
|
|
|
|
self.ping = self.ping.partition('.')[0]
|
|
|
|
|
|
|
|
|
|
self.server = out.partition("Hosted by ")[2]
|
|
|
|
|
self.server = self.server.partition(' [')[0]
|
|
|
|
|
|
|
|
|
|
self.addRow()
|
|
|
|
|
|
|
|
|
|
def createCSV(self): #Saving and writting the data in CSV
|
|
|
|
|
with open(self.myfile, 'w') as stream:
|
|
|
|
|
print("saving", self.myfile)
|
|
|
|
|
writer = csv.writer(stream, delimiter='\t')
|
|
|
|
|
for row in range(self.tableview.rowCount()):
|
|
|
|
|
rowdata = []
|
|
|
|
|
for column in range(self.tableview.columnCount()):
|
|
|
|
|
item = self.tableview.item(row, column)
|
|
|
|
|
if item is not None:
|
|
|
|
|
rowdata.append(item.text())
|
|
|
|
|
else:
|
|
|
|
|
rowdata.append('')
|
|
|
|
|
writer.writerow(rowdata)
|
|
|
|
|
self.isChanged = False
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def design(self): #Designing the font and background
|
|
|
|
|
self.title = "PyQt5 Frame"
|
|
|
|
|
return """
|
|
|
|
|
QTableWidget
|
|
|
|
|
{
|
|
|
|
|
border: 1px solid grey;
|
|
|
|
|
border-radius: 0px;
|
|
|
|
|
font-family: arial;
|
|
|
|
|
font-size: 10pt;
|
|
|
|
|
background-color: #ebebeb;
|
|
|
|
|
selection-color: violet
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
QTableWidget::item:selected
|
|
|
|
|
{
|
|
|
|
|
color: #F4F4F4;
|
|
|
|
|
background: qlineargradient(x1:0, y1:0, x1:2, y1:2, stop:0 #bfc3fb, stop:1 #324864);
|
|
|
|
|
}
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
|
import sys
|
|
|
|
|
|
|
|
|
|
app = QApplication(sys.argv)
|
|
|
|
|
|
|
|
|
|
mainWin = Homepage()
|
|
|
|
|
mainWin.show()
|
|
|
|
|
sys.exit(app.exec_())
|