From fefb9593383a8a65b49a0ee033ea043b80c546da Mon Sep 17 00:00:00 2001 From: Peter Surda Date: Thu, 15 Dec 2016 16:11:29 +0100 Subject: [PATCH] Notify if C PoW missing - Linux users often don't know that the C PoW is available and complain it's slow. This will try to build it, and adds availability notification in the status bar - also, the updateStatusBar signal now allows emphasised notifications, which will remain visible for a longer period of time and also reappear if a status change happened in the meantime --- src/bitmessageqt/__init__.py | 17 ++++- src/bitmessageqt/statusbar.py | 38 ++++++++++++ src/proofofwork.py | 106 ++++++++++++++++++++++---------- src/translations/bitmessage.pro | 1 + 4 files changed, 125 insertions(+), 37 deletions(-) create mode 100644 src/bitmessageqt/statusbar.py diff --git a/src/bitmessageqt/__init__.py b/src/bitmessageqt/__init__.py index a4e101c0..37c52917 100644 --- a/src/bitmessageqt/__init__.py +++ b/src/bitmessageqt/__init__.py @@ -76,6 +76,7 @@ from class_objectHashHolder import objectHashHolder from class_singleWorker import singleWorker from helper_generic import powQueueSize, invQueueSize from proofofwork import getPowType +from statusbar import BMStatusBar def _translate(context, text, disambiguation = None, encoding = None, number = None): if number is None: @@ -703,6 +704,7 @@ class MyForm(settingsmixin.SMainWindow): # Put the colored icon on the status bar # self.pushButtonStatusIcon.setIcon(QIcon(":/newPrefix/images/yellowicon.png")) + self.setStatusBar(BMStatusBar()) self.statusbar = self.statusBar() self.pushButtonStatusIcon = QtGui.QPushButton(self) @@ -3927,10 +3929,19 @@ class MyForm(settingsmixin.SMainWindow): self.rerenderComboBoxSendFromBroadcast() def updateStatusBar(self, data): - if data != "": - logger.info('Status bar: ' + data) + if type(data) is tuple or type(data) is list: + option = data[1] + message = data[0] + else: + option = 0 + message = data + if message != "": + logger.info('Status bar: ' + message) - self.statusBar().showMessage(data, 10000) + if option == 1: + self.statusBar().addImportant(message) + else: + self.statusBar().showMessage(message, 10000) def initSettings(self): QtCore.QCoreApplication.setOrganizationName("PyBitmessage") diff --git a/src/bitmessageqt/statusbar.py b/src/bitmessageqt/statusbar.py new file mode 100644 index 00000000..65a5acfb --- /dev/null +++ b/src/bitmessageqt/statusbar.py @@ -0,0 +1,38 @@ +from PyQt4 import QtCore, QtGui +from Queue import Queue +from time import time + +class BMStatusBar(QtGui.QStatusBar): + duration = 10000 + deleteAfter = 60 + + def __init__(self, parent=None): + super(BMStatusBar, self).__init__(parent) + self.important = [] + self.timer = self.startTimer(BMStatusBar.duration) + self.iterator = 0 + + def timerEvent(self, event): + while len(self.important) > 0: + self.iterator += 1 + try: + if time() > self.important[self.iterator][1] + BMStatusBar.deleteAfter: + del self.important[self.iterator] + self.iterator -= 1 + continue + except IndexError: + self.iterator = -1 + continue + super(BMStatusBar, self).showMessage(self.important[self.iterator][0], 0) + break + + def addImportant(self, message): + self.important.append([message, time()]) + self.iterator = len(self.important) - 2 + self.timerEvent(None) + + def showMessage(self, message, timeout=0): + super(BMStatusBar, self).showMessage(message, timeout) + + def clearMessage(self): + super(BMStatusBar, self).clearMessage() diff --git a/src/proofofwork.py b/src/proofofwork.py index 701f34ba..4bb02fd7 100644 --- a/src/proofofwork.py +++ b/src/proofofwork.py @@ -3,6 +3,7 @@ #from multiprocessing import Pool, cpu_count import hashlib from struct import unpack, pack +from subprocess import call import sys import time from debug import logger @@ -12,6 +13,8 @@ import tr import os import ctypes +bitmsglib = 'bitmsghash.so' + def _set_idle(): if 'linux' in sys.platform: import os @@ -109,7 +112,7 @@ def _doGPUPoW(target, initialHash): #print "{} - value {} < {}".format(nonce, trialValue, target) if trialValue > target: deviceNames = ", ".join(gpu.name for gpu in openclpow.enabledGpus) - shared.UISignalQueue.put(('updateStatusBar', tr._translate("MainWindow",'Your GPU(s) did not calculate correctly, disabling OpenCL. Please report to the developers.'))) + shared.UISignalQueue.put(('updateStatusBar', (tr._translate("MainWindow",'Your GPU(s) did not calculate correctly, disabling OpenCL. Please report to the developers.'), 1))) logger.error("Your GPUs (%s) did not calculate correctly, disabling OpenCL. Please report to the developers.", deviceNames) openclpow.enabledGpus = [] raise Exception("GPU did not calculate correctly.") @@ -150,6 +153,37 @@ def getPowType(): return "C" return "python" +def notifyBuild(tried=False): + global bmpow + + if bmpow: + shared.UISignalQueue.put(('updateStatusBar', (tr._translate("proofofwork", "C PoW module built successfully."), 1))) + elif tried: + shared.UISignalQueue.put(('updateStatusBar', (tr._translate("proofofwork", "Failed to build C PoW module. Please build it manually."), 1))) + else: + shared.UISignalQueue.put(('updateStatusBar', (tr._translate("proofofwork", "C PoW module unavailable. Please build it."), 1))) + +def buildCPoW(): + global bmpow + + if bmpow is not None: + return + if shared.frozen is not None: + notifyBuild(False) + return + if sys.platform in ["win32", "win64"]: + notifyBuild(False) + return + try: + call(["make", "-C", os.path.join(shared.codePath(), "bitmsghash")]) + if os.path.exists(os.path.join(shared.codePath(), "bitmsghash", "bitmsghash.so")): + init() + notifyBuild(True) + else: + notifyBuild(True) + except: + notifyBuild(True) + def run(target, initialHash): if shared.shutdown != 0: raise @@ -194,45 +228,49 @@ def run(target, initialHash): pass #fallback # init -bitmsglib = 'bitmsghash.so' -if "win32" == sys.platform: - if ctypes.sizeof(ctypes.c_voidp) == 4: - bitmsglib = 'bitmsghash32.dll' - else: - bitmsglib = 'bitmsghash64.dll' - try: - # MSVS - bso = ctypes.WinDLL(os.path.join(shared.codePath(), "bitmsghash", bitmsglib)) - logger.info("Loaded C PoW DLL (stdcall) %s", bitmsglib) - bmpow = bso.BitmessagePOW - bmpow.restype = ctypes.c_ulonglong - _doCPoW(2**63, "") - logger.info("Successfully tested C PoW DLL (stdcall) %s", bitmsglib) - except: - logger.error("C PoW test fail.", exc_info=True) +def init(): + global bitmsglib, bso, bmpow + if "win32" == sys.platform: + if ctypes.sizeof(ctypes.c_voidp) == 4: + bitmsglib = 'bitmsghash32.dll' + else: + bitmsglib = 'bitmsghash64.dll' try: - # MinGW - bso = ctypes.CDLL(os.path.join(shared.codePath(), "bitmsghash", bitmsglib)) - logger.info("Loaded C PoW DLL (cdecl) %s", bitmsglib) + # MSVS + bso = ctypes.WinDLL(os.path.join(shared.codePath(), "bitmsghash", bitmsglib)) + logger.info("Loaded C PoW DLL (stdcall) %s", bitmsglib) bmpow = bso.BitmessagePOW bmpow.restype = ctypes.c_ulonglong _doCPoW(2**63, "") - logger.info("Successfully tested C PoW DLL (cdecl) %s", bitmsglib) + logger.info("Successfully tested C PoW DLL (stdcall) %s", bitmsglib) except: logger.error("C PoW test fail.", exc_info=True) + try: + # MinGW + bso = ctypes.CDLL(os.path.join(shared.codePath(), "bitmsghash", bitmsglib)) + logger.info("Loaded C PoW DLL (cdecl) %s", bitmsglib) + bmpow = bso.BitmessagePOW + bmpow.restype = ctypes.c_ulonglong + _doCPoW(2**63, "") + logger.info("Successfully tested C PoW DLL (cdecl) %s", bitmsglib) + except: + logger.error("C PoW test fail.", exc_info=True) + bso = None + else: + try: + bso = ctypes.CDLL(os.path.join(shared.codePath(), "bitmsghash", bitmsglib)) + logger.info("Loaded C PoW DLL %s", bitmsglib) + except: bso = None -else: - try: - bso = ctypes.CDLL(os.path.join(shared.codePath(), "bitmsghash", bitmsglib)) - logger.info("Loaded C PoW DLL %s", bitmsglib) - except: - bso = None -if bso: - try: - bmpow = bso.BitmessagePOW - bmpow.restype = ctypes.c_ulonglong - except: + if bso: + try: + bmpow = bso.BitmessagePOW + bmpow.restype = ctypes.c_ulonglong + except: + bmpow = None + else: bmpow = None -else: - bmpow = None +init() +if bmpow is None: + buildCPoW() diff --git a/src/translations/bitmessage.pro b/src/translations/bitmessage.pro index c8081610..22044d46 100644 --- a/src/translations/bitmessage.pro +++ b/src/translations/bitmessage.pro @@ -16,6 +16,7 @@ SOURCES = ../addresses.py\ ../helper_msgcoding.py\ ../helper_sent.py\ ../helper_startup.py\ + ../proofofwork.py\ ../shared.py\ ../upnp.py\ ../bitmessageqt/__init__.py\