diff --git a/src/bitmessageqt/messageview.py b/src/bitmessageqt/messageview.py index 4d2e768d..45f3a79a 100644 --- a/src/bitmessageqt/messageview.py +++ b/src/bitmessageqt/messageview.py @@ -1,17 +1,22 @@ +""" +src/bitmessageqt/messageview.py +=============================== + +""" + from PyQt4 import QtCore, QtGui -import multiprocessing -import Queue -from urlparse import urlparse -from safehtmlparser import * +from safehtmlparser import SafeHTMLParser + class MessageView(QtGui.QTextBrowser): + """Message content viewer class, can switch between plaintext and HTML""" MODE_PLAIN = 0 MODE_HTML = 1 - - def __init__(self, parent = 0): + + def __init__(self, parent=0): super(MessageView, self).__init__(parent) - self.mode = MessageView.MODE_PLAIN + self.mode = MessageView.MODE_PLAIN self.html = None self.setOpenExternalLinks(False) self.setOpenLinks(False) @@ -25,12 +30,14 @@ class MessageView(QtGui.QTextBrowser): self.setWrappingWidth() def resizeEvent(self, event): + """View resize event handler""" super(MessageView, self).resizeEvent(event) self.setWrappingWidth(event.size().width()) - + def mousePressEvent(self, event): - #text = textCursor.block().text() - if event.button() == QtCore.Qt.LeftButton and self.html and self.html.has_html and self.cursorForPosition(event.pos()).block().blockNumber() == 0: + """Mouse press button event handler""" + if event.button() == QtCore.Qt.LeftButton and self.html and self.html.has_html and self.cursorForPosition( + event.pos()).block().blockNumber() == 0: if self.mode == MessageView.MODE_PLAIN: self.showHTML() else: @@ -39,19 +46,24 @@ class MessageView(QtGui.QTextBrowser): super(MessageView, self).mousePressEvent(event) def wheelEvent(self, event): + """Mouse wheel scroll event handler""" # super will actually automatically take care of zooming super(MessageView, self).wheelEvent(event) - if (QtGui.QApplication.queryKeyboardModifiers() & QtCore.Qt.ControlModifier) == QtCore.Qt.ControlModifier and event.orientation() == QtCore.Qt.Vertical: + if (QtGui.QApplication.queryKeyboardModifiers() & + QtCore.Qt.ControlModifier) == QtCore.Qt.ControlModifier and event.orientation() == QtCore.Qt.Vertical: zoom = self.currentFont().pointSize() * 100 / self.defaultFontPointSize - QtGui.QApplication.activeWindow().statusBar().showMessage(QtGui.QApplication.translate("MainWindow", "Zoom level %1%").arg(str(zoom))) + QtGui.QApplication.activeWindow().statusBar().showMessage( + QtGui.QApplication.translate("MainWindow", "Zoom level %1%").arg(str(zoom))) def setWrappingWidth(self, width=None): + """Set word-wrapping width""" self.setLineWrapMode(QtGui.QTextEdit.FixedPixelWidth) if width is None: width = self.width() self.setLineWrapColumnOrWidth(width) def confirmURL(self, link): + """Show a dialog requesting URL opening confirmation""" if link.scheme() == "mailto": window = QtGui.QApplication.activeWindow() window.ui.lineEditTo.setText(link.path()) @@ -68,35 +80,39 @@ class MessageView(QtGui.QTextBrowser): ) window.ui.textEditMessage.setFocus() return - reply = QtGui.QMessageBox.warning(self, - QtGui.QApplication.translate("MessageView", "Follow external link"), - QtGui.QApplication.translate("MessageView", "The link \"%1\" will open in a browser. It may be a security risk, it could de-anonymise you or download malicious data. Are you sure?").arg(unicode(link.toString())), - QtGui.QMessageBox.Yes, QtGui.QMessageBox.No) + reply = QtGui.QMessageBox.warning( + self, + QtGui.QApplication.translate( + "MessageView", + "Follow external link"), + QtGui.QApplication.translate( + "MessageView", + "The link \"%1\" will open in a browser. It may be a security risk, it could de-anonymise you" + " or download malicious data. Are you sure?").arg(unicode(link.toString())), + QtGui.QMessageBox.Yes, + QtGui.QMessageBox.No) if reply == QtGui.QMessageBox.Yes: QtGui.QDesktopServices.openUrl(link) - def loadResource (self, restype, name): - if restype == QtGui.QTextDocument.ImageResource and name.scheme() == "bmmsg": - pass -# QImage correctImage; -# lookup the correct QImage from a cache -# return QVariant::fromValue(correctImage); -# elif restype == QtGui.QTextDocument.HtmlResource: -# elif restype == QtGui.QTextDocument.ImageResource: -# elif restype == QtGui.QTextDocument.StyleSheetResource: -# elif restype == QtGui.QTextDocument.UserResource: - else: - pass -# by default, this will interpret it as a local file -# QtGui.QTextBrowser.loadResource(restype, name) + def loadResource(self, restype, name): + """ + Callback for loading referenced objects, such as an image. For security reasons at the moment doesn't do + anything) + """ + pass def lazyRender(self): + """ + Partially render a message. This is to avoid UI freezing when loading huge messages. It continues loading as + you scroll down. + """ if self.rendering: return self.rendering = True position = self.verticalScrollBar().value() cursor = QtGui.QTextCursor(self.document()) - while self.outpos < len(self.out) and self.verticalScrollBar().value() >= self.document().size().height() - 2 * self.size().height(): + while self.outpos < len(self.out) and self.verticalScrollBar().value( + ) >= self.document().size().height() - 2 * self.size().height(): startpos = self.outpos self.outpos += 10240 # find next end of tag @@ -108,27 +124,33 @@ class MessageView(QtGui.QTextBrowser): cursor.insertHtml(QtCore.QString(self.out[startpos:self.outpos])) self.verticalScrollBar().setValue(position) self.rendering = False - + def showPlain(self): + """Render message as plain text.""" self.mode = MessageView.MODE_PLAIN out = self.html.raw if self.html.has_html: - out = "
" + unicode(QtGui.QApplication.translate("MessageView", "HTML detected, click here to display")) + "

" + out + out = "
" + unicode( + QtGui.QApplication.translate( + "MessageView", "HTML detected, click here to display")) + "

" + out self.out = out self.outpos = 0 self.setHtml("") self.lazyRender() def showHTML(self): + """Render message as HTML""" self.mode = MessageView.MODE_HTML out = self.html.sanitised - out = "
" + unicode(QtGui.QApplication.translate("MessageView", "Click here to disable HTML")) + "

" + out + out = "
" + unicode( + QtGui.QApplication.translate("MessageView", "Click here to disable HTML")) + "

" + out self.out = out self.outpos = 0 self.setHtml("") self.lazyRender() def setContent(self, data): + """Set message content from argument""" self.html = SafeHTMLParser() self.html.reset() self.html.reset_safe() diff --git a/src/bitmessageqt/networkstatus.py b/src/bitmessageqt/networkstatus.py index 3691d5b3..3d6e6618 100644 --- a/src/bitmessageqt/networkstatus.py +++ b/src/bitmessageqt/networkstatus.py @@ -1,20 +1,27 @@ -from PyQt4 import QtCore, QtGui -import time -import shared +""" +src/bitmessageqt/networkstatus.py +================================= + +""" + +import time + +from PyQt4 import QtCore, QtGui -from tr import _translate -from inventory import Inventory import knownnodes import l10n import network.stats -from retranslateui import RetranslateMixin -from uisignaler import UISignaler +import shared import widgets - +from inventory import Inventory from network.connectionpool import BMConnectionPool +from retranslateui import RetranslateMixin +from tr import _translate +from uisignaler import UISignaler class NetworkStatus(QtGui.QWidget, RetranslateMixin): + """Network status tab""" def __init__(self, parent=None): super(NetworkStatus, self).__init__(parent) widgets.load('networkstatus.ui', self) @@ -29,8 +36,9 @@ class NetworkStatus(QtGui.QWidget, RetranslateMixin): self.startup = time.localtime() self.labelStartupTime.setText(_translate("networkstatus", "Since startup on %1").arg( l10n.formatTimestamp(self.startup))) - + self.UISignalThread = UISignaler.get() + # pylint: disable=no-member QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL( "updateNumberOfMessagesProcessed()"), self.updateNumberOfMessagesProcessed) QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL( @@ -42,57 +50,108 @@ class NetworkStatus(QtGui.QWidget, RetranslateMixin): self.timer = QtCore.QTimer() - QtCore.QObject.connect( - self.timer, QtCore.SIGNAL("timeout()"), self.runEveryTwoSeconds) + 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() def formatBytes(self, num): - for x in [_translate("networkstatus", "byte(s)", None, QtCore.QCoreApplication.CodecForTr, num), "kB", "MB", "GB"]: + """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", + ]: 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 num /= 1000 return "%4.0f kB" % num - + def updateNumberOfObjectsToBeSynced(self): - self.labelSyncStatus.setText(_translate("networkstatus", "Object(s) to be synced: %n", None, QtCore.QCoreApplication.CodecForTr, network.stats.pendingDownload() + network.stats.pendingUpload())) + """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())) 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)) + self.labelMessageCount.setText( + _translate( + "networkstatus", + "Processed %n person-to-person message(s).", + None, + QtCore.QCoreApplication.CodecForTr, + shared.numberOfMessagesProcessed)) 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)) + self.labelBroadcastCount.setText( + _translate( + "networkstatus", + "Processed %n broadcast message(s).", + None, + QtCore.QCoreApplication.CodecForTr, + shared.numberOfBroadcastsProcessed)) 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)) + self.labelPubkeyCount.setText( + _translate( + "networkstatus", + "Processed %n public key(s).", + None, + QtCore.QCoreApplication.CodecForTr, + shared.numberOfPubkeysProcessed)) 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()))) + 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()))) 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] @@ -111,33 +170,39 @@ class NetworkStatus(QtGui.QWidget, RetranslateMixin): self.tableWidgetConnectionCount.setUpdatesEnabled(False) self.tableWidgetConnectionCount.setSortingEnabled(False) + if add: self.tableWidgetConnectionCount.insertRow(0) - self.tableWidgetConnectionCount.setItem(0, 0, + self.tableWidgetConnectionCount.setItem( + 0, 0, QtGui.QTableWidgetItem("%s:%i" % (destination.host, destination.port)) - ) - self.tableWidgetConnectionCount.setItem(0, 2, + ) + self.tableWidgetConnectionCount.setItem( + 0, 2, QtGui.QTableWidgetItem("%s" % (c.userAgent)) - ) - self.tableWidgetConnectionCount.setItem(0, 3, + ) + self.tableWidgetConnectionCount.setItem( + 0, 3, QtGui.QTableWidgetItem("%s" % (c.tlsVersion)) - ) - self.tableWidgetConnectionCount.setItem(0, 4, - QtGui.QTableWidgetItem("%s" % (",".join(map(str,c.streams)))) - ) + ) + self.tableWidgetConnectionCount.setItem( + 0, 4, + QtGui.QTableWidgetItem("%s" % (",".join(map(str, c.streams)))) + ) try: - # FIXME hard coded stream no + # .. todo:: FIXME: hard coded stream no rating = "%.1f" % (knownnodes.knownNodes[1][destination]['rating']) except KeyError: rating = "-" - self.tableWidgetConnectionCount.setItem(0, 1, + self.tableWidgetConnectionCount.setItem( + 0, 1, QtGui.QTableWidgetItem("%s" % (rating)) - ) + ) if outbound: brush = QtGui.QBrush(QtGui.QColor("yellow"), QtCore.Qt.SolidPattern) else: brush = QtGui.QBrush(QtGui.QColor("green"), QtCore.Qt.SolidPattern) - for j in (range(1)): + 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) @@ -148,11 +213,16 @@ class NetworkStatus(QtGui.QWidget, RetranslateMixin): 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. + 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': self.window().setStatusIcon('yellow') elif self.tableWidgetConnectionCount.rowCount() == 0 and shared.statusIconColor != "red": @@ -160,8 +230,9 @@ class NetworkStatus(QtGui.QWidget, RetranslateMixin): # timer driven def runEveryTwoSeconds(self): - self.labelLookupsPerSecond.setText(_translate( - "networkstatus", "Inventory lookups per second: %1").arg(str(Inventory().numberOfInventoryLookupsPerformed/2))) + """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 self.updateNumberOfBytes() self.updateNumberOfObjectsToBeSynced() diff --git a/src/class_singleWorker.py b/src/class_singleWorker.py index d51e124a..575a909e 100644 --- a/src/class_singleWorker.py +++ b/src/class_singleWorker.py @@ -1,40 +1,41 @@ +""" +src/class_singleWorker.py +========================= +""" +# pylint: disable=protected-access,too-many-branches,too-many-statements,no-self-use,too-many-lines,too-many-locals + from __future__ import division -import time -import threading import hashlib -from struct import pack -# used when the API must execute an outside program -from subprocess import call # nosec +import threading +import time from binascii import hexlify, unhexlify +from struct import pack +from subprocess import call # nosec -import tr +import defaults +import helper_inbox +import helper_msgcoding +import helper_random +import highlevelcrypto import l10n +import proofofwork import protocol import queues -import state import shared -import defaults -import highlevelcrypto -import proofofwork -import helper_inbox -import helper_random -import helper_msgcoding +import state +import tr +from addresses import calculateInventoryHash, decodeAddress, decodeVarint, encodeVarint from bmconfigparser import BMConfigParser from debug import logger -from inventory import Inventory -from addresses import ( - decodeAddress, encodeVarint, decodeVarint, calculateInventoryHash -) -# from helper_generic import addDataPadding +from helper_sql import sqlExecute, sqlQuery from helper_threading import StoppableThread -from helper_sql import sqlQuery, sqlExecute +from inventory import Inventory -# This thread, of which there is only one, does the heavy lifting: -# calculating POWs. - def sizeof_fmt(num, suffix='h/s'): + """Format hashes per seconds nicely (SI prefix)""" + for unit in ['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z']: if abs(num) < 1000.0: return "%3.1f%s%s" % (num, unit, suffix) @@ -43,14 +44,16 @@ def sizeof_fmt(num, suffix='h/s'): class singleWorker(threading.Thread, StoppableThread): + """Thread for performing PoW""" def __init__(self): - # QThread.__init__(self, parent) threading.Thread.__init__(self, name="singleWorker") self.initStop() proofofwork.init() def stopThread(self): + """Signal through the queue that the thread should be stopped""" + try: queues.workerQueue.put(("stopThread", "data")) except: @@ -58,6 +61,7 @@ class singleWorker(threading.Thread, StoppableThread): super(singleWorker, self).stopThread() def run(self): + # pylint: disable=attribute-defined-outside-init while not state.sqlReady and state.shutdown == 0: self.stop.wait(2) @@ -96,12 +100,12 @@ class singleWorker(threading.Thread, StoppableThread): '''SELECT ackdata FROM sent WHERE status = 'msgsent' ''') for row in queryreturn: ackdata, = row - logger.info('Watching for ackdata ' + hexlify(ackdata)) + logger.info('Watching for ackdata %s', hexlify(ackdata)) shared.ackdataForWhichImWatching[ackdata] = 0 # Fix legacy (headerless) watched ackdata to include header - for oldack in shared.ackdataForWhichImWatching.keys(): - if (len(oldack) == 32): + for oldack in shared.ackdataForWhichImWatching: + if len(oldack) == 32: # attach legacy header, always constant (msg/1/1) newack = '\x00\x00\x00\x02\x01\x01' + oldack shared.ackdataForWhichImWatching[newack] = 0 @@ -226,19 +230,9 @@ class singleWorker(threading.Thread, StoppableThread): # inventoryHash = calculateInventoryHash(payload) return payload - # This function also broadcasts out the pubkey message - # once it is done with the POW def doPOWForMyV2Pubkey(self, adressHash): + """ This function also broadcasts out the pubkey message once it is done with the POW""" # Look up my stream number based on my address hash - """configSections = shared.config.addresses() - for addressInKeysFile in configSections: - if addressInKeysFile != 'bitmessagesettings': - status, addressVersionNumber, streamNumber, \ - hashFromThisParticularAddress = \ - decodeAddress(addressInKeysFile) - if hash == hashFromThisParticularAddress: - myAddress = addressInKeysFile - break""" myAddress = shared.myAddressesByHash[adressHash] # status _, addressVersionNumber, streamNumber, adressHash = decodeAddress(myAddress) @@ -289,11 +283,12 @@ class singleWorker(threading.Thread, StoppableThread): # before this finished. pass - # If this isn't a chan address, this function assembles the pubkey data, - # does the necessary POW and sends it out. If it *is* a chan then it - # assembles the pubkey and stores is in the pubkey table so that we can - # send messages to "ourselves". def sendOutOrStoreMyV3Pubkey(self, adressHash): + """ + If this isn't a chan address, this function assembles the pubkey data, does the necessary POW and sends it out. + If it *is* a chan then it assembles the pubkey and stores is in the pubkey table so that we can send messages + to "ourselves". + """ try: myAddress = shared.myAddressesByHash[adressHash] except: @@ -357,7 +352,7 @@ class singleWorker(threading.Thread, StoppableThread): Inventory()[inventoryHash] = ( objectType, streamNumber, payload, embeddedTime, '') - logger.info('broadcasting inv with hash: ' + hexlify(inventoryHash)) + logger.info('broadcasting inv with hash: %s', hexlify(inventoryHash)) queues.invQueue.put((streamNumber, inventoryHash)) queues.UISignalQueue.put(('updateStatusBar', '')) @@ -370,9 +365,12 @@ class singleWorker(threading.Thread, StoppableThread): # before this finished. pass - # If this isn't a chan address, this function assembles - # the pubkey data, does the necessary POW and sends it out. def sendOutOrStoreMyV4Pubkey(self, myAddress): + """ + It doesn't send directly anymore. It put is to a queue for another thread to send at an appropriate time, + whereas in the past it directly appended it to the outgoing buffer, I think. Same with all the other methods in + this class. + """ if not BMConfigParser().has_section(myAddress): # The address has been deleted. return @@ -444,7 +442,7 @@ class singleWorker(threading.Thread, StoppableThread): doubleHashOfAddressData[32:] ) - logger.info('broadcasting inv with hash: ' + hexlify(inventoryHash)) + logger.info('broadcasting inv with hash: %s', hexlify(inventoryHash)) queues.invQueue.put((streamNumber, inventoryHash)) queues.UISignalQueue.put(('updateStatusBar', '')) @@ -459,6 +457,7 @@ class singleWorker(threading.Thread, StoppableThread): ) def sendBroadcast(self): + """Send a broadcast-type object (assemble the object, perform PoW and put it to the inv announcement queue)""" # Reset just in case sqlExecute( '''UPDATE sent SET status='broadcastqueued' ''' @@ -627,6 +626,8 @@ class singleWorker(threading.Thread, StoppableThread): ) def sendMsg(self): + """Send a message-type object (assemble the object, perform PoW and put it to the inv announcement queue)""" + # pylint: disable=too-many-nested-blocks # Reset just in case sqlExecute( '''UPDATE sent SET status='msgqueued' ''' @@ -740,10 +741,8 @@ class singleWorker(threading.Thread, StoppableThread): # object associated with the tag for this toAddress. if toAddressVersionNumber >= 4: doubleHashOfToAddressData = hashlib.sha512( - hashlib.sha512(encodeVarint( - toAddressVersionNumber) + - encodeVarint(toStreamNumber) + - toRipe + hashlib.sha512( + encodeVarint(toAddressVersionNumber) + encodeVarint(toStreamNumber) + toRipe ).digest() ).digest() # The first half of the sha512 hash. @@ -834,7 +833,7 @@ class singleWorker(threading.Thread, StoppableThread): queryreturn = sqlQuery( 'SELECT transmitdata FROM pubkeys WHERE address=?', toaddress) - for row in queryreturn: + for row in queryreturn: # pylint: disable=redefined-outer-name pubkeyPayload, = row # The pubkey message is stored with the following items @@ -939,40 +938,43 @@ class singleWorker(threading.Thread, StoppableThread): requiredAverageProofOfWorkNonceTrialsPerByte, requiredPayloadLengthExtraBytes ) - queues.UISignalQueue.put(( - 'updateSentItemStatusByAckdata', ( - ackdata, - tr._translate( - "MainWindow", - "Doing work necessary to send message.\n" - "Receiver\'s required difficulty: %1" - " and %2" - ).arg(str(float( - requiredAverageProofOfWorkNonceTrialsPerByte) / - defaults.networkDefaultProofOfWorkNonceTrialsPerByte - )).arg(str(float( - requiredPayloadLengthExtraBytes) / - defaults.networkDefaultPayloadLengthExtraBytes - ))))) + + queues.UISignalQueue.put( + ( + 'updateSentItemStatusByAckdata', + ( + ackdata, + tr._translate( + "MainWindow", + "Doing work necessary to send message.\n" + "Receiver\'s required difficulty: %1" + " and %2" + ).arg( + str( + float(requiredAverageProofOfWorkNonceTrialsPerByte) / + defaults.networkDefaultProofOfWorkNonceTrialsPerByte + ) + ).arg( + str( + float(requiredPayloadLengthExtraBytes) / + defaults.networkDefaultPayloadLengthExtraBytes + ) + ) + ) + ) + ) + if status != 'forcepow': - if (requiredAverageProofOfWorkNonceTrialsPerByte - > BMConfigParser().getint( - 'bitmessagesettings', - 'maxacceptablenoncetrialsperbyte' - ) and - BMConfigParser().getint( - 'bitmessagesettings', - 'maxacceptablenoncetrialsperbyte' - ) != 0) or ( - requiredPayloadLengthExtraBytes - > BMConfigParser().getint( - 'bitmessagesettings', - 'maxacceptablepayloadlengthextrabytes' - ) and - BMConfigParser().getint( - 'bitmessagesettings', - 'maxacceptablepayloadlengthextrabytes' - ) != 0): + maxacceptablenoncetrialsperbyte = BMConfigParser().getint( + 'bitmessagesettings', 'maxacceptablenoncetrialsperbyte') + maxacceptablepayloadlengthextrabytes = BMConfigParser().getint( + 'bitmessagesettings', 'maxacceptablepayloadlengthextrabytes') + cond1 = maxacceptablenoncetrialsperbyte and \ + requiredAverageProofOfWorkNonceTrialsPerByte > maxacceptablenoncetrialsperbyte + cond2 = maxacceptablepayloadlengthextrabytes and \ + requiredPayloadLengthExtraBytes > maxacceptablepayloadlengthextrabytes + + if cond1 or cond2: # The demanded difficulty is more than # we are willing to do. sqlExecute( @@ -988,19 +990,15 @@ class singleWorker(threading.Thread, StoppableThread): " the recipient (%1 and %2) is" " more difficult than you are" " willing to do. %3" - ).arg(str(float( - requiredAverageProofOfWorkNonceTrialsPerByte) - / defaults.networkDefaultProofOfWorkNonceTrialsPerByte - )).arg(str(float( - requiredPayloadLengthExtraBytes) - / defaults.networkDefaultPayloadLengthExtraBytes - )).arg(l10n.formatTimestamp())) - )) + ).arg(str(float(requiredAverageProofOfWorkNonceTrialsPerByte) / + defaults.networkDefaultProofOfWorkNonceTrialsPerByte)).arg( + str(float(requiredPayloadLengthExtraBytes) / + defaults.networkDefaultPayloadLengthExtraBytes)).arg( + l10n.formatTimestamp())))) continue else: # if we are sending a message to ourselves or a chan.. logger.info('Sending a message.') - logger.debug( - 'First 150 characters of message: %r', message[:150]) + logger.debug('First 150 characters of message: %r', message[:150]) behaviorBitfield = protocol.getBitfield(fromaddress) try: @@ -1199,16 +1197,14 @@ class singleWorker(threading.Thread, StoppableThread): Inventory()[inventoryHash] = ( objectType, toStreamNumber, encryptedPayload, embeddedTime, '') if BMConfigParser().has_section(toaddress) or \ - not protocol.checkBitfield( - behaviorBitfield, protocol.BITFIELD_DOESACK): + not protocol.checkBitfield(behaviorBitfield, protocol.BITFIELD_DOESACK): queues.UISignalQueue.put(( 'updateSentItemStatusByAckdata', ( ackdata, tr._translate( "MainWindow", "Message sent. Sent at %1" - ).arg(l10n.formatTimestamp())) - )) + ).arg(l10n.formatTimestamp())))) else: # not sending to a chan or one of my addresses queues.UISignalQueue.put(( @@ -1229,8 +1225,7 @@ class singleWorker(threading.Thread, StoppableThread): # Update the sent message in the sent table with the # necessary information. if BMConfigParser().has_section(toaddress) or \ - not protocol.checkBitfield( - behaviorBitfield, protocol.BITFIELD_DOESACK): + not protocol.checkBitfield(behaviorBitfield, protocol.BITFIELD_DOESACK): newStatus = 'msgsentnoackexpected' else: newStatus = 'msgsent' @@ -1270,6 +1265,7 @@ class singleWorker(threading.Thread, StoppableThread): call([apiNotifyPath, "newMessage"]) def requestPubKey(self, toAddress): + """Send a getpubkey object""" toStatus, addressVersionNumber, streamNumber, ripe = decodeAddress( toAddress) if toStatus != 'success': @@ -1286,7 +1282,7 @@ class singleWorker(threading.Thread, StoppableThread): ''' LIMIT 1''', toAddress ) - if len(queryReturn) == 0: + if not queryReturn: logger.critical( 'BUG: Why are we requesting the pubkey for %s' ' if there are no messages in the sent folder' @@ -1389,16 +1385,14 @@ class singleWorker(threading.Thread, StoppableThread): ).arg(l10n.formatTimestamp())) )) - def generateFullAckMessage(self, ackdata, toStreamNumber, TTL): - # It might be perfectly fine to just use the same TTL for - # the ackdata that we use for the message. But I would rather - # it be more difficult for attackers to associate ackData with - # the associated msg object. However, users would want the TTL - # of the acknowledgement to be about the same as they set - # for the message itself. So let's set the TTL of the - # acknowledgement to be in one of three 'buckets': 1 hour, 7 - # days, or 28 days, whichever is relatively close to what the - # user specified. + def generateFullAckMessage(self, ackdata, _, TTL): + """ + It might be perfectly fine to just use the same TTL for the ackdata that we use for the message. But I would + rather it be more difficult for attackers to associate ackData with the associated msg object. However, users + would want the TTL of the acknowledgement to be about the same as they set for the message itself. So let's set + the TTL of the acknowledgement to be in one of three 'buckets': 1 hour, 7 days, or 28 days, whichever is + relatively close to what the user specified. + """ if TTL < 24 * 60 * 60: # 1 day TTL = 24 * 60 * 60 # 1 day elif TTL < 7 * 24 * 60 * 60: # 1 week