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
This commit is contained in:
Peter Šurda 2016-12-15 16:11:29 +01:00
parent 9d9052dda2
commit fefb959338
Signed by: PeterSurda
GPG Key ID: 0C5F50C0B5F37D87
4 changed files with 125 additions and 37 deletions

View File

@ -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")

View File

@ -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()

View File

@ -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()

View File

@ -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\