PyBitmessage/src/bitmessageqt/networkstatus.py

246 lines
9.7 KiB
Python
Raw Normal View History

"""
src/bitmessageqt/networkstatus.py
=================================
"""
import time
from PyQt4 import QtCore, QtGui
import knownnodes
2016-03-16 18:27:12 +00:00
import l10n
import network.stats
import shared
2016-03-16 18:27:12 +00:00
import widgets
from inventory import Inventory
from network import BMConnectionPool
from retranslateui import RetranslateMixin
from tr import _translate
from uisignaler import UISignaler
2016-03-16 18:27:12 +00:00
class NetworkStatus(QtGui.QWidget, RetranslateMixin):
"""Network status tab"""
2016-03-16 18:27:12 +00:00
def __init__(self, parent=None):
super(NetworkStatus, self).__init__(parent)
widgets.load('networkstatus.ui', self)
header = self.tableWidgetConnectionCount.horizontalHeader()
header.setResizeMode(QtGui.QHeaderView.ResizeToContents)
# Somehow this value was 5 when I tested
if header.sortIndicatorSection() > 4:
header.setSortIndicator(0, QtCore.Qt.AscendingOrder)
self.startup = time.localtime()
self.labelStartupTime.setText(_translate("networkstatus", "Since startup on %1").arg(
l10n.formatTimestamp(self.startup)))
2016-03-16 18:27:12 +00:00
self.UISignalThread = UISignaler.get()
# pylint: disable=no-member
2016-03-16 18:27:12 +00:00
QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL(
"updateNumberOfMessagesProcessed()"), self.updateNumberOfMessagesProcessed)
QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL(
"updateNumberOfPubkeysProcessed()"), self.updateNumberOfPubkeysProcessed)
QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL(
"updateNumberOfBroadcastsProcessed()"), self.updateNumberOfBroadcastsProcessed)
QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL(
"updateNetworkStatusTab(PyQt_PyObject,PyQt_PyObject,PyQt_PyObject)"), self.updateNetworkStatusTab)
2016-03-16 18:27:12 +00:00
self.timer = QtCore.QTimer()
QtCore.QObject.connect(self.timer, QtCore.SIGNAL("timeout()"), self.runEveryTwoSeconds)
# pylint: enable=no-member
def startUpdate(self):
"""Start a timer to update counters every 2 seconds"""
Inventory().numberOfInventoryLookupsPerformed = 0
self.runEveryTwoSeconds()
self.timer.start(2000) # milliseconds
def stopUpdate(self):
"""Stop counter update timer"""
self.timer.stop()
2016-03-16 18:27:12 +00:00
2016-03-17 18:03:17 +00:00
def formatBytes(self, num):
"""Format bytes nicely (SI prefixes)"""
# pylint: disable=no-self-use
for x in [
_translate(
"networkstatus",
"byte(s)",
None,
QtCore.QCoreApplication.CodecForTr,
num),
"kB",
"MB",
"GB",
]:
2016-03-17 18:03:17 +00:00
if num < 1000.0:
return "%3.0f %s" % (num, x)
num /= 1000.0
return "%3.0f %s" % (num, 'TB')
def formatByteRate(self, num):
"""Format transfer speed in kB/s"""
# pylint: disable=no-self-use
2016-03-17 18:03:17 +00:00
num /= 1000
return "%4.0f kB" % num
def updateNumberOfObjectsToBeSynced(self):
"""Update the counter for number of objects to be synced"""
self.labelSyncStatus.setText(
_translate(
"networkstatus",
"Object(s) to be synced: %n",
None,
QtCore.QCoreApplication.CodecForTr,
network.stats.pendingDownload() +
network.stats.pendingUpload()))
2016-03-17 18:03:17 +00:00
2016-03-16 18:27:12 +00:00
def updateNumberOfMessagesProcessed(self):
"""Update the counter for number of processed messages"""
self.updateNumberOfObjectsToBeSynced()
self.labelMessageCount.setText(
_translate(
"networkstatus",
"Processed %n person-to-person message(s).",
None,
QtCore.QCoreApplication.CodecForTr,
shared.numberOfMessagesProcessed))
2016-03-16 18:27:12 +00:00
def updateNumberOfBroadcastsProcessed(self):
"""Update the counter for the number of processed broadcasts"""
self.updateNumberOfObjectsToBeSynced()
self.labelBroadcastCount.setText(
_translate(
"networkstatus",
"Processed %n broadcast message(s).",
None,
QtCore.QCoreApplication.CodecForTr,
shared.numberOfBroadcastsProcessed))
2016-03-16 18:27:12 +00:00
def updateNumberOfPubkeysProcessed(self):
"""Update the counter for the number of processed pubkeys"""
self.updateNumberOfObjectsToBeSynced()
self.labelPubkeyCount.setText(
_translate(
"networkstatus",
"Processed %n public key(s).",
None,
QtCore.QCoreApplication.CodecForTr,
shared.numberOfPubkeysProcessed))
2016-03-16 18:27:12 +00:00
def updateNumberOfBytes(self):
"""
This function is run every two seconds, so we divide the rate of bytes
sent and received by 2.
"""
self.labelBytesRecvCount.setText(
_translate(
"networkstatus",
"Down: %1/s Total: %2").arg(
self.formatByteRate(network.stats.downloadSpeed()),
self.formatBytes(network.stats.receivedBytes())))
self.labelBytesSentCount.setText(
_translate(
"networkstatus", "Up: %1/s Total: %2").arg(
self.formatByteRate(network.stats.uploadSpeed()),
self.formatBytes(network.stats.sentBytes())))
2016-03-16 18:27:12 +00:00
def updateNetworkStatusTab(self, outbound, add, destination):
"""Add or remove an entry to the list of connected peers"""
# pylint: disable=too-many-branches,undefined-variable
if outbound:
try:
c = BMConnectionPool().outboundConnections[destination]
except KeyError:
if add:
return
else:
try:
c = BMConnectionPool().inboundConnections[destination]
except KeyError:
try:
c = BMConnectionPool().inboundConnections[destination.host]
except KeyError:
if add:
return
2016-03-16 18:27:12 +00:00
self.tableWidgetConnectionCount.setUpdatesEnabled(False)
self.tableWidgetConnectionCount.setSortingEnabled(False)
if add:
2016-03-16 18:27:12 +00:00
self.tableWidgetConnectionCount.insertRow(0)
self.tableWidgetConnectionCount.setItem(
0, 0,
QtGui.QTableWidgetItem("%s:%i" % (destination.host, destination.port))
)
self.tableWidgetConnectionCount.setItem(
0, 2,
QtGui.QTableWidgetItem("%s" % (c.userAgent))
)
self.tableWidgetConnectionCount.setItem(
0, 3,
QtGui.QTableWidgetItem("%s" % (c.tlsVersion))
)
self.tableWidgetConnectionCount.setItem(
0, 4,
QtGui.QTableWidgetItem("%s" % (",".join(map(str, c.streams))))
)
try:
# .. todo:: FIXME: hard coded stream no
rating = "%.1f" % (knownnodes.knownNodes[1][destination]['rating'])
except KeyError:
rating = "-"
self.tableWidgetConnectionCount.setItem(
0, 1,
QtGui.QTableWidgetItem("%s" % (rating))
)
if outbound:
brush = QtGui.QBrush(QtGui.QColor("yellow"), QtCore.Qt.SolidPattern)
2016-03-16 18:27:12 +00:00
else:
brush = QtGui.QBrush(QtGui.QColor("green"), QtCore.Qt.SolidPattern)
for j in range(1):
self.tableWidgetConnectionCount.item(0, j).setBackground(brush)
self.tableWidgetConnectionCount.item(0, 0).setData(QtCore.Qt.UserRole, destination)
self.tableWidgetConnectionCount.item(0, 1).setData(QtCore.Qt.UserRole, outbound)
else:
if len(BMConnectionPool().inboundConnections) == 0:
self.window().setStatusIcon('yellow')
for i in range(self.tableWidgetConnectionCount.rowCount()):
if self.tableWidgetConnectionCount.item(i, 0).data(QtCore.Qt.UserRole).toPyObject() != destination:
continue
if self.tableWidgetConnectionCount.item(i, 1).data(QtCore.Qt.UserRole).toPyObject() == outbound:
self.tableWidgetConnectionCount.removeRow(i)
break
self.tableWidgetConnectionCount.setUpdatesEnabled(True)
self.tableWidgetConnectionCount.setSortingEnabled(True)
self.labelTotalConnections.setText(
_translate(
"networkstatus", "Total Connections: %1").arg(
str(self.tableWidgetConnectionCount.rowCount())))
# FYI: The 'singlelistener' thread sets the icon color to green when it
# receives an incoming connection, meaning that the user's firewall is
# configured correctly.
if self.tableWidgetConnectionCount.rowCount() and shared.statusIconColor == 'red':
2016-03-16 18:27:12 +00:00
self.window().setStatusIcon('yellow')
elif self.tableWidgetConnectionCount.rowCount() == 0 and shared.statusIconColor != "red":
2016-03-16 18:27:12 +00:00
self.window().setStatusIcon('red')
# timer driven
def runEveryTwoSeconds(self):
"""Updates counters, runs every 2 seconds if the timer is running"""
self.labelLookupsPerSecond.setText(_translate("networkstatus", "Inventory lookups per second: %1").arg(
str(Inventory().numberOfInventoryLookupsPerformed / 2)))
Inventory().numberOfInventoryLookupsPerformed = 0
2016-03-16 18:27:12 +00:00
self.updateNumberOfBytes()
self.updateNumberOfObjectsToBeSynced()
def retranslateUi(self):
super(NetworkStatus, self).retranslateUi()
self.labelStartupTime.setText(_translate("networkstatus", "Since startup on %1").arg(
l10n.formatTimestamp(self.startup)))