Global imports.
This commit is contained in:
parent
16a11775e8
commit
525aa099f3
32
src/api.py
32
src/api.py
|
@ -72,28 +72,24 @@ from binascii import hexlify, unhexlify
|
|||
from SimpleXMLRPCServer import SimpleXMLRPCRequestHandler, SimpleXMLRPCServer
|
||||
from struct import pack
|
||||
|
||||
import defaults
|
||||
import helper_inbox
|
||||
import helper_sent
|
||||
import network.stats
|
||||
import proofofwork
|
||||
import queues
|
||||
import shared
|
||||
import shutdown
|
||||
import state
|
||||
from addresses import (
|
||||
from . import (
|
||||
defaults, helper_inbox, helper_sent, proofofwork, queues, shared, shutdown,
|
||||
state
|
||||
)
|
||||
from .addresses import (
|
||||
addBMIfNotPresent,
|
||||
calculateInventoryHash,
|
||||
decodeAddress,
|
||||
decodeVarint,
|
||||
varintDecodeError
|
||||
)
|
||||
from bmconfigparser import BMConfigParser
|
||||
from debug import logger
|
||||
from helper_sql import SqlBulkExecute, sqlExecute, sqlQuery, sqlStoredProcedure
|
||||
from inventory import Inventory
|
||||
from network.threads import StoppableThread
|
||||
from version import softwareVersion
|
||||
from .bmconfigparser import BMConfigParser
|
||||
from .debug import logger
|
||||
from .helper_sql import SqlBulkExecute, sqlExecute, sqlQuery, sqlStoredProcedure
|
||||
from .inventory import Inventory
|
||||
from .network import stats
|
||||
from .network.threads import StoppableThread
|
||||
from .version import softwareVersion
|
||||
|
||||
try: # TODO: write tests for XML vulnerabilities
|
||||
from defusedxml.xmlrpc import monkey_patch
|
||||
|
@ -1392,7 +1388,7 @@ class BMRPCDispatcher(object):
|
|||
or "connectedAndReceivingIncomingConnections".
|
||||
"""
|
||||
|
||||
connections_num = len(network.stats.connectedHostsList())
|
||||
connections_num = len(stats.connectedHostsList())
|
||||
if connections_num == 0:
|
||||
networkStatus = 'notConnected'
|
||||
elif state.clientHasReceivedIncomingConnections:
|
||||
|
@ -1404,7 +1400,7 @@ class BMRPCDispatcher(object):
|
|||
'numberOfMessagesProcessed': state.numberOfMessagesProcessed,
|
||||
'numberOfBroadcastsProcessed': state.numberOfBroadcastsProcessed,
|
||||
'numberOfPubkeysProcessed': state.numberOfPubkeysProcessed,
|
||||
'pendingDownload': network.stats.pendingDownload(),
|
||||
'pendingDownload': stats.pendingDownload(),
|
||||
'networkStatus': networkStatus,
|
||||
'softwareName': 'PyBitmessage',
|
||||
'softwareVersion': softwareVersion
|
||||
|
|
|
@ -12,13 +12,7 @@ The PyBitmessage startup script
|
|||
import os
|
||||
import sys
|
||||
|
||||
try:
|
||||
import pathmagic
|
||||
except ImportError:
|
||||
from pybitmessage import pathmagic
|
||||
app_dir = pathmagic.setup()
|
||||
|
||||
import depends
|
||||
from . import depends
|
||||
depends.check_dependencies()
|
||||
|
||||
import ctypes
|
||||
|
@ -32,28 +26,28 @@ import time
|
|||
import traceback
|
||||
from struct import pack
|
||||
|
||||
import defaults
|
||||
import shared
|
||||
import shutdown
|
||||
import state
|
||||
from bmconfigparser import BMConfigParser
|
||||
from debug import logger # this should go before any threads
|
||||
from helper_startup import (
|
||||
from . import defaults, shared, shutdown, state
|
||||
from .bmconfigparser import BMConfigParser
|
||||
from .debug import logger # this should go before any threads
|
||||
from .helper_startup import (
|
||||
adjustHalfOpenConnectionsLimit, start_proxyconfig)
|
||||
from inventory import Inventory
|
||||
from .inventory import Inventory
|
||||
# Network objects and threads
|
||||
from network import (
|
||||
from .network import (
|
||||
BMConnectionPool, Dandelion, AddrThread, AnnounceThread, BMNetworkThread,
|
||||
InvThread, ReceiveQueueThread, DownloadThread, UploadThread
|
||||
)
|
||||
from network.knownnodes import readKnownNodes
|
||||
from singleinstance import singleinstance
|
||||
from .network.knownnodes import readKnownNodes
|
||||
from .singleinstance import singleinstance
|
||||
# Synchronous threads
|
||||
from threads import (
|
||||
from .threads import (
|
||||
set_thread_name, printLock,
|
||||
addressGenerator, objectProcessor, singleCleaner, singleWorker, sqlThread)
|
||||
|
||||
|
||||
app_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
|
||||
def _fixSocket():
|
||||
if sys.platform.startswith('linux'):
|
||||
socket.SO_BINDTODEVICE = 25
|
||||
|
@ -272,14 +266,14 @@ class Main(object):
|
|||
# SMTP delivery thread
|
||||
if daemon and config.safeGet(
|
||||
'bitmessagesettings', 'smtpdeliver', '') != '':
|
||||
from class_smtpDeliver import smtpDeliver
|
||||
from .class_smtpDeliver import smtpDeliver
|
||||
smtpDeliveryThread = smtpDeliver()
|
||||
smtpDeliveryThread.start()
|
||||
|
||||
# SMTP daemon thread
|
||||
if daemon and config.safeGetBoolean(
|
||||
'bitmessagesettings', 'smtpd'):
|
||||
from class_smtpServer import smtpServer
|
||||
from .class_smtpServer import smtpServer
|
||||
smtpServerThread = smtpServer()
|
||||
smtpServerThread.start()
|
||||
|
||||
|
@ -304,7 +298,7 @@ class Main(object):
|
|||
|
||||
# API is also objproc dependent
|
||||
if config.safeGetBoolean('bitmessagesettings', 'apienabled'):
|
||||
import api # pylint: disable=relative-import
|
||||
from . import api
|
||||
singleAPIThread = api.singleAPI()
|
||||
# close the main program even if there are threads left
|
||||
singleAPIThread.daemon = True
|
||||
|
@ -339,7 +333,7 @@ class Main(object):
|
|||
state.uploadThread.start()
|
||||
|
||||
if config.safeGetBoolean('bitmessagesettings', 'upnp'):
|
||||
import upnp
|
||||
from . import upnp
|
||||
upnpThread = upnp.uPnPThread()
|
||||
upnpThread.start()
|
||||
else:
|
||||
|
@ -351,10 +345,10 @@ class Main(object):
|
|||
if not depends.check_curses():
|
||||
sys.exit()
|
||||
print('Running with curses')
|
||||
import bitmessagecurses
|
||||
from . import bitmessagecurses
|
||||
bitmessagecurses.runwrapper()
|
||||
else:
|
||||
import bitmessageqt
|
||||
from . import bitmessageqt
|
||||
bitmessageqt.run()
|
||||
else:
|
||||
config.remove_option('bitmessagesettings', 'dontconnect')
|
||||
|
@ -370,8 +364,7 @@ class Main(object):
|
|||
elif not state.enableGUI:
|
||||
state.enableGUI = True
|
||||
try:
|
||||
# pylint: disable=relative-import
|
||||
from tests import core as test_core
|
||||
from .tests import core as test_core
|
||||
except ImportError:
|
||||
self.stop()
|
||||
return
|
||||
|
|
|
@ -4,6 +4,7 @@ PyQt based UI for bitmessage, the main module
|
|||
|
||||
import hashlib
|
||||
import locale
|
||||
import logging
|
||||
import os
|
||||
import random
|
||||
import string
|
||||
|
@ -18,53 +19,50 @@ from sqlite3 import register_adapter
|
|||
from PyQt4 import QtCore, QtGui
|
||||
from PyQt4.QtNetwork import QLocalSocket, QLocalServer
|
||||
|
||||
import shared
|
||||
import state
|
||||
from debug import logger
|
||||
from tr import _translate
|
||||
from addresses import decodeAddress, addBMIfNotPresent
|
||||
from bitmessageui import Ui_MainWindow
|
||||
from bmconfigparser import BMConfigParser
|
||||
import namecoin
|
||||
from messageview import MessageView
|
||||
from migrationwizard import Ui_MigrationWizard
|
||||
from foldertree import (
|
||||
from pybitmessage import (
|
||||
helper_addressbook, helper_search, helper_sent, l10n, namecoin, paths,
|
||||
queues, shared, shutdown, state)
|
||||
from pybitmessage.addresses import decodeAddress, addBMIfNotPresent
|
||||
from pybitmessage.bmconfigparser import BMConfigParser
|
||||
from pybitmessage.debug import logger
|
||||
from pybitmessage.helper_ackPayload import genAckPayload
|
||||
from pybitmessage.helper_sql import (
|
||||
sqlQuery, sqlExecute, sqlExecuteChunked, sqlStoredProcedure)
|
||||
from pybitmessage.network.stats import pendingDownload, pendingUpload
|
||||
from pybitmessage.proofofwork import getPowType
|
||||
from pybitmessage.tr import _translate
|
||||
|
||||
# This is needed for tray icon
|
||||
import .bitmessage_icons_rc # noqa:F401 pylint: disable=unused-import
|
||||
from . import dialogs, settingsmixin, sound, support
|
||||
from .account import (
|
||||
accountClass, AccountColor, BMAccount, GatewayAccount,
|
||||
getSortedAccounts, getSortedSubscriptions, MailchuckAccount)
|
||||
from .bitmessageui import Ui_MainWindow
|
||||
from .foldertree import (
|
||||
AccountMixin, Ui_FolderWidget, Ui_AddressWidget, Ui_SubscriptionWidget,
|
||||
MessageList_AddressWidget, MessageList_SubjectWidget,
|
||||
Ui_AddressBookWidgetItemLabel, Ui_AddressBookWidgetItemAddress,
|
||||
MessageList_TimeWidget)
|
||||
import settingsmixin
|
||||
import support
|
||||
from helper_sql import sqlQuery, sqlExecute, sqlExecuteChunked, sqlStoredProcedure
|
||||
import helper_addressbook
|
||||
import helper_search
|
||||
import l10n
|
||||
from utils import str_broadcast_subscribers, avatarize
|
||||
from account import (
|
||||
getSortedAccounts, getSortedSubscriptions, accountClass, BMAccount,
|
||||
GatewayAccount, MailchuckAccount, AccountColor)
|
||||
import dialogs
|
||||
from network.stats import pendingDownload, pendingUpload
|
||||
from uisignaler import UISignaler
|
||||
import paths
|
||||
from proofofwork import getPowType
|
||||
import queues
|
||||
import shutdown
|
||||
from statusbar import BMStatusBar
|
||||
import sound
|
||||
# This is needed for tray icon
|
||||
import bitmessage_icons_rc # noqa:F401 pylint: disable=unused-import
|
||||
import helper_sent
|
||||
from .messageview import MessageView
|
||||
from .statusbar import BMStatusBar
|
||||
from .uisignaler import UISignaler
|
||||
from .utils import str_broadcast_subscribers, avatarize
|
||||
|
||||
try:
|
||||
from plugins.plugin import get_plugin, get_plugins
|
||||
from pybitmessage.plugins.plugin import get_plugin, get_plugins
|
||||
except ImportError:
|
||||
get_plugins = False
|
||||
|
||||
|
||||
logger = logging.getLogger('default')
|
||||
|
||||
|
||||
# TODO: rewrite
|
||||
def powQueueSize():
|
||||
"""Returns the size of queues.workerQueue including current unfinished work"""
|
||||
"""
|
||||
Returns the size of queues.workerQueue including current unfinished work
|
||||
"""
|
||||
queue_len = queues.workerQueue.qsize()
|
||||
for thread in threading.enumerate():
|
||||
try:
|
||||
|
@ -435,7 +433,6 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
if treeWidget.isSortingEnabled():
|
||||
treeWidget.setSortingEnabled(False)
|
||||
|
||||
widgets = {}
|
||||
i = 0
|
||||
while i < treeWidget.topLevelItemCount():
|
||||
widget = treeWidget.topLevelItem(i)
|
||||
|
@ -453,7 +450,8 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
while j < widget.childCount():
|
||||
subwidget = widget.child(j)
|
||||
try:
|
||||
subwidget.setUnreadCount(db[toAddress][subwidget.folderName]['count'])
|
||||
subwidget.setUnreadCount(
|
||||
db[toAddress][subwidget.folderName]['count'])
|
||||
unread += db[toAddress][subwidget.folderName]['count']
|
||||
db[toAddress].pop(subwidget.folderName, None)
|
||||
except:
|
||||
|
@ -467,7 +465,8 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
j = 0
|
||||
for f, c in db[toAddress].iteritems():
|
||||
try:
|
||||
subwidget = Ui_FolderWidget(widget, j, toAddress, f, c['count'])
|
||||
subwidget = Ui_FolderWidget(
|
||||
widget, j, toAddress, f, c['count'])
|
||||
except KeyError:
|
||||
subwidget = Ui_FolderWidget(widget, j, toAddress, f, 0)
|
||||
j += 1
|
||||
|
@ -477,12 +476,18 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
|
||||
i = 0
|
||||
for toAddress in db:
|
||||
widget = Ui_SubscriptionWidget(treeWidget, i, toAddress, db[toAddress]["inbox"]['count'], db[toAddress]["inbox"]['label'], db[toAddress]["inbox"]['enabled'])
|
||||
widget = Ui_SubscriptionWidget(
|
||||
treeWidget, i, toAddress,
|
||||
db[toAddress]["inbox"]['count'],
|
||||
db[toAddress]["inbox"]['label'],
|
||||
db[toAddress]["inbox"]['enabled'])
|
||||
j = 0
|
||||
unread = 0
|
||||
for folder in folders:
|
||||
try:
|
||||
subwidget = Ui_FolderWidget(widget, j, toAddress, folder, db[toAddress][folder]['count'])
|
||||
subwidget = Ui_FolderWidget(
|
||||
widget, j, toAddress, folder,
|
||||
db[toAddress][folder]['count'])
|
||||
unread += db[toAddress][folder]['count']
|
||||
except KeyError:
|
||||
subwidget = Ui_FolderWidget(widget, j, toAddress, folder, 0)
|
||||
|
@ -518,8 +523,8 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
toAddress, 'enabled')
|
||||
isChan = BMConfigParser().safeGetBoolean(
|
||||
toAddress, 'chan')
|
||||
isMaillinglist = BMConfigParser().safeGetBoolean(
|
||||
toAddress, 'mailinglist')
|
||||
# isMaillinglist = BMConfigParser().safeGetBoolean(
|
||||
# toAddress, 'mailinglist')
|
||||
|
||||
if treeWidget == self.ui.treeWidgetYourIdentities:
|
||||
if isChan:
|
||||
|
@ -536,7 +541,9 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
|
||||
# get number of (unread) messages
|
||||
total = 0
|
||||
queryreturn = sqlQuery('SELECT toaddress, folder, count(msgid) as cnt FROM inbox WHERE read = 0 GROUP BY toaddress, folder')
|
||||
queryreturn = sqlQuery(
|
||||
'SELECT toaddress, folder, count(msgid) as cnt FROM inbox'
|
||||
' WHERE read = 0 GROUP BY toaddress, folder')
|
||||
for row in queryreturn:
|
||||
toaddress, folder, cnt = row
|
||||
total += cnt
|
||||
|
@ -553,7 +560,6 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
if treeWidget.isSortingEnabled():
|
||||
treeWidget.setSortingEnabled(False)
|
||||
|
||||
widgets = {}
|
||||
i = 0
|
||||
while i < treeWidget.topLevelItemCount():
|
||||
widget = treeWidget.topLevelItem(i)
|
||||
|
@ -586,7 +592,7 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
if len(db[toAddress]) > 0:
|
||||
j = 0
|
||||
for f, c in db[toAddress].iteritems():
|
||||
if toAddress is not None and tab == 'messages' and folder == "new":
|
||||
if toAddress and tab == 'messages' and folder == "new":
|
||||
continue
|
||||
subwidget = Ui_FolderWidget(widget, j, toAddress, f, c)
|
||||
if subwidget.folderName not in ("new", "trash", "sent"):
|
||||
|
@ -598,13 +604,16 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
|
||||
i = 0
|
||||
for toAddress in db:
|
||||
widget = Ui_AddressWidget(treeWidget, i, toAddress, db[toAddress]["inbox"], enabled[toAddress])
|
||||
widget = Ui_AddressWidget(
|
||||
treeWidget, i, toAddress,
|
||||
db[toAddress]["inbox"], enabled[toAddress])
|
||||
j = 0
|
||||
unread = 0
|
||||
for folder in folders:
|
||||
if toAddress is not None and tab == 'messages' and folder == "new":
|
||||
if toAddress and tab == 'messages' and folder == "new":
|
||||
continue
|
||||
subwidget = Ui_FolderWidget(widget, j, toAddress, folder, db[toAddress][folder])
|
||||
subwidget = Ui_FolderWidget(
|
||||
widget, j, toAddress, folder, db[toAddress][folder])
|
||||
if subwidget.folderName not in ("new", "trash", "sent"):
|
||||
unread += db[toAddress][folder]
|
||||
j += 1
|
||||
|
@ -632,10 +641,13 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
addressInKeysFile)
|
||||
if addressVersionNumber == 1:
|
||||
displayMsg = _translate(
|
||||
"MainWindow", "One of your addresses, %1, is an old version 1 address. Version 1 addresses are no longer supported. "
|
||||
+ "May we delete it now?").arg(addressInKeysFile)
|
||||
"MainWindow",
|
||||
"One of your addresses, %1, is an old version 1 address."
|
||||
" Version 1 addresses are no longer supported."
|
||||
" May we delete it now?").arg(addressInKeysFile)
|
||||
reply = QtGui.QMessageBox.question(
|
||||
self, 'Message', displayMsg, QtGui.QMessageBox.Yes, QtGui.QMessageBox.No)
|
||||
self, 'Message', displayMsg,
|
||||
QtGui.QMessageBox.Yes, QtGui.QMessageBox.No)
|
||||
if reply == QtGui.QMessageBox.Yes:
|
||||
BMConfigParser().remove_section(addressInKeysFile)
|
||||
BMConfigParser().save()
|
||||
|
@ -743,13 +755,14 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
self.unreadCount = 0
|
||||
|
||||
# Set the icon sizes for the identicons
|
||||
identicon_size = 3*7
|
||||
self.ui.tableWidgetInbox.setIconSize(QtCore.QSize(identicon_size, identicon_size))
|
||||
self.ui.treeWidgetChans.setIconSize(QtCore.QSize(identicon_size, identicon_size))
|
||||
self.ui.treeWidgetYourIdentities.setIconSize(QtCore.QSize(identicon_size, identicon_size))
|
||||
self.ui.treeWidgetSubscriptions.setIconSize(QtCore.QSize(identicon_size, identicon_size))
|
||||
self.ui.tableWidgetAddressBook.setIconSize(QtCore.QSize(identicon_size, identicon_size))
|
||||
|
||||
identicon_size = 3 * 7
|
||||
for widget in (
|
||||
self.ui.tableWidgetInbox, self.ui.treeWidgetChans,
|
||||
self.ui.treeWidgetYourIdentities, self.ui.treeWidgetSubscriptions,
|
||||
self.ui.tableWidgetAddressBook
|
||||
):
|
||||
widget.setIconSize(QtCore.QSize(identicon_size, identicon_size))
|
||||
|
||||
self.UISignalThread = UISignaler.get()
|
||||
QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL(
|
||||
"writeNewAddressToTable(PyQt_PyObject,PyQt_PyObject,PyQt_PyObject)"), self.writeNewAddressToTable)
|
||||
|
@ -809,13 +822,14 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
|
||||
# Put the TTL slider in the correct spot
|
||||
TTL = BMConfigParser().getint('bitmessagesettings', 'ttl')
|
||||
if TTL < 3600: # an hour
|
||||
if TTL < 3600: # an hour
|
||||
TTL = 3600
|
||||
elif TTL > 28*24*60*60: # 28 days
|
||||
TTL = 28*24*60*60
|
||||
self.ui.horizontalSliderTTL.setSliderPosition((TTL - 3600) ** (1/3.199))
|
||||
elif TTL > 28 * 24 * 60 * 60: # 28 days
|
||||
TTL = 28 * 24 * 60 * 60
|
||||
self.ui.horizontalSliderTTL.setSliderPosition(
|
||||
(TTL - 3600) ** (1 / 3.199))
|
||||
self.updateHumanFriendlyTTLDescription(TTL)
|
||||
|
||||
|
||||
QtCore.QObject.connect(self.ui.horizontalSliderTTL, QtCore.SIGNAL(
|
||||
"valueChanged(int)"), self.updateTTL)
|
||||
|
||||
|
@ -873,21 +887,24 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
BMConfigParser().save()
|
||||
|
||||
def updateHumanFriendlyTTLDescription(self, TTL):
|
||||
numberOfHours = int(round(TTL / (60*60)))
|
||||
numberOfHours = int(round(TTL / (60 * 60)))
|
||||
font = QtGui.QFont()
|
||||
stylesheet = ""
|
||||
|
||||
if numberOfHours < 48:
|
||||
self.ui.labelHumanFriendlyTTLDescription.setText(
|
||||
_translate("MainWindow", "%n hour(s)", None, QtCore.QCoreApplication.CodecForTr, numberOfHours) +
|
||||
", " +
|
||||
_translate("MainWindow", "not recommended for chans", None, QtCore.QCoreApplication.CodecForTr)
|
||||
)
|
||||
_translate(
|
||||
"MainWindow", "%n hour(s)", None, numberOfHours
|
||||
) + ", "
|
||||
+ _translate(
|
||||
"MainWindow", "not recommended for chans")
|
||||
)
|
||||
stylesheet = "QLabel { color : red; }"
|
||||
font.setBold(True)
|
||||
else:
|
||||
numberOfDays = int(round(TTL / (24*60*60)))
|
||||
self.ui.labelHumanFriendlyTTLDescription.setText(_translate("MainWindow", "%n day(s)", None, QtCore.QCoreApplication.CodecForTr, numberOfDays))
|
||||
numberOfDays = int(round(TTL / (24 * 60 * 60)))
|
||||
self.ui.labelHumanFriendlyTTLDescription.setText(_translate(
|
||||
"MainWindow", "%n day(s)", None, numberOfDays))
|
||||
font.setBold(False)
|
||||
self.ui.labelHumanFriendlyTTLDescription.setStyleSheet(stylesheet)
|
||||
self.ui.labelHumanFriendlyTTLDescription.setFont(font)
|
||||
|
@ -900,7 +917,8 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
else:
|
||||
self.show()
|
||||
self.setWindowState(
|
||||
self.windowState() & ~QtCore.Qt.WindowMinimized | QtCore.Qt.WindowActive)
|
||||
self.windowState()
|
||||
& ~QtCore.Qt.WindowMinimized | QtCore.Qt.WindowActive)
|
||||
self.raise_()
|
||||
self.activateWindow()
|
||||
|
||||
|
@ -1449,6 +1467,7 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
self._player = QtGui.QSound.play
|
||||
|
||||
if not get_plugins:
|
||||
self._theme_player = None
|
||||
return
|
||||
|
||||
_plugin = get_plugin('notification.message')
|
||||
|
@ -1557,36 +1576,77 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
# may manage your keys by editing the keys.dat file stored in
|
||||
# the same directory as this program. It is important that you
|
||||
# back up this file.', QMessageBox.Ok)
|
||||
reply = QtGui.QMessageBox.information(self, 'keys.dat?', _translate(
|
||||
"MainWindow", "You may manage your keys by editing the keys.dat file stored in the same directory as this program. It is important that you back up this file."), QtGui.QMessageBox.Ok)
|
||||
reply = QtGui.QMessageBox.information(
|
||||
self, 'keys.dat?', _translate(
|
||||
"MainWindow",
|
||||
"You may manage your keys by editing the keys.dat"
|
||||
" file stored in the same directory as this program."
|
||||
" It is important that you back up this file."
|
||||
), QtGui.QMessageBox.Ok)
|
||||
|
||||
else:
|
||||
QtGui.QMessageBox.information(self, 'keys.dat?', _translate(
|
||||
"MainWindow", "You may manage your keys by editing the keys.dat file stored in\n %1 \nIt is important that you back up this file.").arg(state.appdata), QtGui.QMessageBox.Ok)
|
||||
elif sys.platform == 'win32' or sys.platform == 'win64':
|
||||
QtGui.QMessageBox.information(
|
||||
self, 'keys.dat?', _translate(
|
||||
"MainWindow",
|
||||
"You may manage your keys by editing the keys.dat"
|
||||
" file stored in\n %1 \nIt is important that"
|
||||
" you back up this file.").arg(state.appdata),
|
||||
QtGui.QMessageBox.Ok)
|
||||
elif sys.platform.startswith('win'):
|
||||
if state.appdata == '':
|
||||
reply = QtGui.QMessageBox.question(self, _translate("MainWindow", "Open keys.dat?"), _translate(
|
||||
"MainWindow", "You may manage your keys by editing the keys.dat file stored in the same directory as this program. It is important that you back up this file. Would you like to open the file now? (Be sure to close Bitmessage before making any changes.)"), QtGui.QMessageBox.Yes, QtGui.QMessageBox.No)
|
||||
reply = QtGui.QMessageBox.question(
|
||||
self, _translate("MainWindow", "Open keys.dat?"),
|
||||
_translate(
|
||||
"MainWindow",
|
||||
"You may manage your keys by editing the keys.dat"
|
||||
" file stored in the same directory as this program."
|
||||
" It is important that you back up this file."
|
||||
" Would you like to open the file now?"
|
||||
" (Be sure to close Bitmessage before making"
|
||||
" any changes.)"), QtGui.QMessageBox.Yes,
|
||||
QtGui.QMessageBox.No)
|
||||
else:
|
||||
reply = QtGui.QMessageBox.question(self, _translate("MainWindow", "Open keys.dat?"), _translate(
|
||||
"MainWindow", "You may manage your keys by editing the keys.dat file stored in\n %1 \nIt is important that you back up this file. Would you like to open the file now? (Be sure to close Bitmessage before making any changes.)").arg(state.appdata), QtGui.QMessageBox.Yes, QtGui.QMessageBox.No)
|
||||
reply = QtGui.QMessageBox.question(
|
||||
self, _translate("MainWindow", "Open keys.dat?"),
|
||||
_translate(
|
||||
"MainWindow",
|
||||
"You may manage your keys by editing the keys.dat"
|
||||
" file stored in\n %1 \nIt is important that"
|
||||
" you back up this file. Would you like to open"
|
||||
" the file now? (Be sure to close Bitmessage before"
|
||||
" making any changes.)").arg(state.appdata),
|
||||
QtGui.QMessageBox.Yes, QtGui.QMessageBox.No)
|
||||
if reply == QtGui.QMessageBox.Yes:
|
||||
openKeysFile()
|
||||
|
||||
# menu button 'delete all treshed messages'
|
||||
def click_actionDeleteAllTrashedMessages(self):
|
||||
if QtGui.QMessageBox.question(self, _translate("MainWindow", "Delete trash?"), _translate("MainWindow", "Are you sure you want to delete all trashed messages?"), QtGui.QMessageBox.Yes, QtGui.QMessageBox.No) == QtGui.QMessageBox.No:
|
||||
if QtGui.QMessageBox.question(
|
||||
self, _translate("MainWindow", "Delete trash?"),
|
||||
_translate(
|
||||
"MainWindow",
|
||||
"Are you sure you want to delete all trashed messages?"
|
||||
), QtGui.QMessageBox.Yes, QtGui.QMessageBox.No
|
||||
) == QtGui.QMessageBox.No:
|
||||
return
|
||||
sqlStoredProcedure('deleteandvacuume')
|
||||
self.rerenderTabTreeMessages()
|
||||
self.rerenderTabTreeSubscriptions()
|
||||
self.rerenderTabTreeChans()
|
||||
if self.getCurrentFolder(self.ui.treeWidgetYourIdentities) == "trash":
|
||||
self.loadMessagelist(self.ui.tableWidgetInbox, self.getCurrentAccount(self.ui.treeWidgetYourIdentities), "trash")
|
||||
self.loadMessagelist(
|
||||
self.ui.tableWidgetInbox,
|
||||
self.getCurrentAccount(self.ui.treeWidgetYourIdentities),
|
||||
"trash")
|
||||
elif self.getCurrentFolder(self.ui.treeWidgetSubscriptions) == "trash":
|
||||
self.loadMessagelist(self.ui.tableWidgetInboxSubscriptions, self.getCurrentAccount(self.ui.treeWidgetSubscriptions), "trash")
|
||||
self.loadMessagelist(
|
||||
self.ui.tableWidgetInboxSubscriptions,
|
||||
self.getCurrentAccount(self.ui.treeWidgetSubscriptions),
|
||||
"trash")
|
||||
elif self.getCurrentFolder(self.ui.treeWidgetChans) == "trash":
|
||||
self.loadMessagelist(self.ui.tableWidgetInboxChans, self.getCurrentAccount(self.ui.treeWidgetChans), "trash")
|
||||
self.loadMessagelist(
|
||||
self.ui.tableWidgetInboxChans,
|
||||
self.getCurrentAccount(self.ui.treeWidgetChans), "trash")
|
||||
|
||||
# menu button 'regenerate deterministic addresses'
|
||||
def click_actionRegenerateDeterministicAddresses(self):
|
||||
|
@ -1653,13 +1713,6 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
else:
|
||||
self._firstrun = False
|
||||
|
||||
def showMigrationWizard(self, level):
|
||||
self.migrationWizardInstance = Ui_MigrationWizard(["a"])
|
||||
if self.migrationWizardInstance.exec_():
|
||||
pass
|
||||
else:
|
||||
pass
|
||||
|
||||
def changeEvent(self, event):
|
||||
if event.type() == QtCore.QEvent.LanguageChange:
|
||||
self.ui.retranslateUi(self)
|
||||
|
@ -1672,7 +1725,9 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
self.ui.blackwhitelist.init_blacklist_popup_menu(False)
|
||||
if event.type() == QtCore.QEvent.WindowStateChange:
|
||||
if self.windowState() & QtCore.Qt.WindowMinimized:
|
||||
if BMConfigParser().getboolean('bitmessagesettings', 'minimizetotray') and not 'darwin' in sys.platform:
|
||||
if BMConfigParser().getboolean(
|
||||
'bitmessagesettings', 'minimizetotray'
|
||||
) and 'darwin' not in sys.platform:
|
||||
QtCore.QTimer.singleShot(0, self.appIndicatorHide)
|
||||
elif event.oldState() & QtCore.Qt.WindowMinimized:
|
||||
# The window state has just been changed to
|
||||
|
@ -1788,7 +1843,8 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
painter.setPen(
|
||||
QtGui.QPen(QtGui.QColor(255, 0, 0), QtCore.Qt.SolidPattern))
|
||||
painter.setFont(font)
|
||||
painter.drawText(24-rect.right()-marginX, -rect.top()+marginY, txt)
|
||||
painter.drawText(
|
||||
24 - rect.right() - marginX, - rect.top() + marginY, txt)
|
||||
painter.end()
|
||||
return QtGui.QIcon(pixmap)
|
||||
|
||||
|
@ -1804,7 +1860,8 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
|
||||
def findInboxUnreadCount(self, count=None):
|
||||
if count is None:
|
||||
queryreturn = sqlQuery('''SELECT count(*) from inbox WHERE folder='inbox' and read=0''')
|
||||
queryreturn = sqlQuery(
|
||||
"SELECT count(*) from inbox WHERE folder='inbox' and read=0")
|
||||
cnt = 0
|
||||
for row in queryreturn:
|
||||
cnt, = row
|
||||
|
@ -1834,7 +1891,11 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
sent.item(i, 3).setToolTip(textToDisplay)
|
||||
try:
|
||||
newlinePosition = textToDisplay.indexOf('\n')
|
||||
except: # If someone misses adding a "_translate" to a string before passing it to this function, this function won't receive a qstring which will cause an exception.
|
||||
# If someone misses adding a "_translate" to a string
|
||||
# before passing it to this function, this function
|
||||
# won't receive a qstring which will cause an exception.
|
||||
# ? why textToDisplay isn't unicode
|
||||
except AttributeError:
|
||||
newlinePosition = 0
|
||||
if newlinePosition > 1:
|
||||
sent.item(i, 3).setText(
|
||||
|
@ -1862,7 +1923,11 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
sent.item(i, 3).setToolTip(textToDisplay)
|
||||
try:
|
||||
newlinePosition = textToDisplay.indexOf('\n')
|
||||
except: # If someone misses adding a "_translate" to a string before passing it to this function, this function won't receive a qstring which will cause an exception.
|
||||
# If someone misses adding a "_translate" to a string
|
||||
# before passing it to this function, this function
|
||||
# won't receive a qstring which will cause an exception.
|
||||
# ? why textToDisplay isn't unicode
|
||||
except AttributeError:
|
||||
newlinePosition = 0
|
||||
if newlinePosition > 1:
|
||||
sent.item(i, 3).setText(
|
||||
|
@ -1898,8 +1963,7 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
"MainWindow",
|
||||
"New version of PyBitmessage is available: %1. Download it"
|
||||
" from https://github.com/Bitmessage/PyBitmessage/releases/latest"
|
||||
).arg(self.notifiedNewVersion)
|
||||
)
|
||||
).arg(self.notifiedNewVersion))
|
||||
|
||||
def displayAlert(self, title, text, exitAfterUserClicksOk):
|
||||
self.updateStatusBar(text)
|
||||
|
@ -1908,17 +1972,25 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
os._exit(0)
|
||||
|
||||
def rerenderMessagelistFromLabels(self):
|
||||
for messagelist in (self.ui.tableWidgetInbox, self.ui.tableWidgetInboxChans, self.ui.tableWidgetInboxSubscriptions):
|
||||
for messagelist in (
|
||||
self.ui.tableWidgetInbox,
|
||||
self.ui.tableWidgetInboxChans,
|
||||
self.ui.tableWidgetInboxSubscriptions
|
||||
):
|
||||
for i in range(messagelist.rowCount()):
|
||||
messagelist.item(i, 1).setLabel()
|
||||
|
||||
def rerenderMessagelistToLabels(self):
|
||||
for messagelist in (self.ui.tableWidgetInbox, self.ui.tableWidgetInboxChans, self.ui.tableWidgetInboxSubscriptions):
|
||||
for messagelist in (
|
||||
self.ui.tableWidgetInbox,
|
||||
self.ui.tableWidgetInboxChans,
|
||||
self.ui.tableWidgetInboxSubscriptions
|
||||
):
|
||||
for i in range(messagelist.rowCount()):
|
||||
messagelist.item(i, 0).setLabel()
|
||||
|
||||
def rerenderAddressBook(self):
|
||||
def addRow (address, label, type):
|
||||
def addRow(address, label, type):
|
||||
self.ui.tableWidgetAddressBook.insertRow(0)
|
||||
newItem = Ui_AddressBookWidgetItemLabel(address, unicode(label, 'utf-8'), type)
|
||||
self.ui.tableWidgetAddressBook.setItem(0, 0, newItem)
|
||||
|
@ -1931,26 +2003,27 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
oldRows[item.address] = [item.label, item.type, i]
|
||||
|
||||
if self.ui.tableWidgetAddressBook.rowCount() == 0:
|
||||
self.ui.tableWidgetAddressBook.horizontalHeader().setSortIndicator(0, QtCore.Qt.AscendingOrder)
|
||||
self.ui.tableWidgetAddressBook.horizontalHeader().setSortIndicator(
|
||||
0, QtCore.Qt.AscendingOrder)
|
||||
if self.ui.tableWidgetAddressBook.isSortingEnabled():
|
||||
self.ui.tableWidgetAddressBook.setSortingEnabled(False)
|
||||
|
||||
newRows = {}
|
||||
# subscriptions
|
||||
queryreturn = sqlQuery('SELECT label, address FROM subscriptions WHERE enabled = 1')
|
||||
for row in queryreturn:
|
||||
label, address = row
|
||||
for label, address in sqlQuery(
|
||||
'SELECT label, address FROM subscriptions WHERE enabled = 1'):
|
||||
newRows[address] = [label, AccountMixin.SUBSCRIPTION]
|
||||
# chans
|
||||
addresses = getSortedAccounts()
|
||||
for address in addresses:
|
||||
account = accountClass(address)
|
||||
if (account.type == AccountMixin.CHAN and BMConfigParser().safeGetBoolean(address, 'enabled')):
|
||||
if (
|
||||
account.type == AccountMixin.CHAN
|
||||
and BMConfigParser().safeGetBoolean(address, 'enabled')
|
||||
):
|
||||
newRows[address] = [account.getLabel(), AccountMixin.CHAN]
|
||||
# normal accounts
|
||||
queryreturn = sqlQuery('SELECT * FROM addressbook')
|
||||
for row in queryreturn:
|
||||
label, address = row
|
||||
for label, address in sqlQuery('SELECT label, address FROM addressbook'):
|
||||
newRows[address] = [label, AccountMixin.NORMAL]
|
||||
|
||||
completerList = []
|
||||
|
@ -1976,11 +2049,17 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
self.rerenderTabTreeSubscriptions()
|
||||
|
||||
def click_pushButtonTTL(self):
|
||||
QtGui.QMessageBox.information(self, 'Time To Live', _translate(
|
||||
"MainWindow", """The TTL, or Time-To-Live is the length of time that the network will hold the message.
|
||||
The recipient must get it during this time. If your Bitmessage client does not hear an acknowledgement, it
|
||||
will resend the message automatically. The longer the Time-To-Live, the
|
||||
more work your computer must do to send the message. A Time-To-Live of four or five days is often appropriate."""), QtGui.QMessageBox.Ok)
|
||||
QtGui.QMessageBox.information(
|
||||
self, 'Time To Live', _translate(
|
||||
"MainWindow",
|
||||
"The TTL, or Time-To-Live is the length of time that"
|
||||
" the network will hold the message. The recipient must"
|
||||
" get it during this time. If your Bitmessage client does"
|
||||
" not hear an acknowledgement, it will resend the message"
|
||||
" automatically. The longer the Time-To-Live, the more"
|
||||
" work your computer must do to send the message. A"
|
||||
" Time-To-Live of four or five days is often appropriate."
|
||||
), QtWidgets.QMessageBox.Ok)
|
||||
|
||||
def click_pushButtonClear(self):
|
||||
self.ui.lineEditSubject.setText("")
|
||||
|
@ -1989,7 +2068,9 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
self.ui.comboBoxSendFrom.setCurrentIndex(0)
|
||||
|
||||
def click_pushButtonSend(self):
|
||||
encoding = 3 if QtGui.QApplication.queryKeyboardModifiers() & QtCore.Qt.ShiftModifier else 2
|
||||
encoding = (
|
||||
3 if QtGui.QApplication.queryKeyboardModifiers()
|
||||
& QtCore.Qt.ShiftModifier else 2)
|
||||
|
||||
self.statusbar.clearMessage()
|
||||
|
||||
|
@ -2013,14 +2094,13 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
subject = str(self.ui.lineEditSubjectBroadcast.text().toUtf8())
|
||||
message = str(
|
||||
self.ui.textEditMessageBroadcast.document().toPlainText().toUtf8())
|
||||
"""
|
||||
The whole network message must fit in 2^18 bytes.
|
||||
Let's assume 500 bytes of overhead. If someone wants to get that
|
||||
too an exact number you are welcome to but I think that it would
|
||||
be a better use of time to support message continuation so that
|
||||
users can send messages of any length.
|
||||
"""
|
||||
if len(message) > (2 ** 18 - 500):
|
||||
|
||||
# The whole network message must fit in 2^18 bytes.
|
||||
# Let's assume 500 bytes of overhead. If someone wants to get that
|
||||
# too an exact number you are welcome to but I think that it would
|
||||
# be a better use of time to support message continuation so that
|
||||
# users can send messages of any length.
|
||||
if len(message) > 2 ** 18 - 500:
|
||||
QtGui.QMessageBox.about(
|
||||
self, _translate("MainWindow", "Message too long"),
|
||||
_translate(
|
||||
|
@ -2053,18 +2133,32 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
subject = acct.subject
|
||||
toAddress = acct.toAddress
|
||||
else:
|
||||
if QtGui.QMessageBox.question(self, "Sending an email?", _translate("MainWindow",
|
||||
"You are trying to send an email instead of a bitmessage. This requires registering with a gateway. Attempt to register?"),
|
||||
QtGui.QMessageBox.Yes|QtGui.QMessageBox.No) != QtGui.QMessageBox.Yes:
|
||||
if QtGui.QMessageBox.question(
|
||||
self, "Sending an email?",
|
||||
_translate(
|
||||
"MainWindow",
|
||||
"You are trying to send an email"
|
||||
" instead of a bitmessage. This"
|
||||
" requires registering with a"
|
||||
" gateway. Attempt to register?"
|
||||
), QtWidgets.QMessageBox.Yes
|
||||
| QtWidgets.QMessageBox.No
|
||||
) != QtWidgets.QMessageBox.Yes:
|
||||
continue
|
||||
email = acct.getLabel()
|
||||
if email[-14:] != "@mailchuck.com": #attempt register
|
||||
# attempt register
|
||||
if email[-14:] != "@mailchuck.com":
|
||||
# 12 character random email address
|
||||
email = ''.join(random.SystemRandom().choice(string.ascii_lowercase) for _ in range(12)) + "@mailchuck.com"
|
||||
email = u''.join(
|
||||
random.SystemRandom().choice(
|
||||
string.ascii_lowercase
|
||||
) for _ in range(12)
|
||||
) + "@mailchuck.com"
|
||||
acct = MailchuckAccount(fromAddress)
|
||||
acct.register(email)
|
||||
BMConfigParser().set(fromAddress, 'label', email)
|
||||
BMConfigParser().set(fromAddress, 'gateway', 'mailchuck')
|
||||
BMConfigParser().set(
|
||||
fromAddress, 'gateway', 'mailchuck')
|
||||
BMConfigParser().save()
|
||||
self.updateStatusBar(_translate(
|
||||
"MainWindow",
|
||||
|
@ -2072,35 +2166,38 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
" an email gateway. Sending registration"
|
||||
" now as %1, please wait for the registration"
|
||||
" to be processed before retrying sending."
|
||||
).arg(email)
|
||||
)
|
||||
).arg(email))
|
||||
return
|
||||
status, addressVersionNumber, streamNumber = decodeAddress(toAddress)[:3]
|
||||
status, addressVersionNumber, streamNumber = \
|
||||
decodeAddress(toAddress)[:3]
|
||||
if status != 'success':
|
||||
try:
|
||||
toAddress = unicode(toAddress, 'utf-8', 'ignore')
|
||||
except:
|
||||
pass
|
||||
logger.error('Error: Could not decode recipient address ' + toAddress + ':' + status)
|
||||
except UnicodeDecodeError:
|
||||
logger.warning(
|
||||
"Failed decoding toAddress ):", exc_info=True)
|
||||
logger.error(
|
||||
'Error: Could not decode recipient address %s: %s',
|
||||
toAddress_value, status)
|
||||
|
||||
if status == 'missingbm':
|
||||
self.updateStatusBar(_translate(
|
||||
"MainWindow",
|
||||
"Error: Bitmessage addresses start with"
|
||||
" BM- Please check the recipient address %1"
|
||||
).arg(toAddress))
|
||||
).arg(toAddress))
|
||||
elif status == 'checksumfailed':
|
||||
self.updateStatusBar(_translate(
|
||||
"MainWindow",
|
||||
"Error: The recipient address %1 is not"
|
||||
" typed or copied correctly. Please check it."
|
||||
).arg(toAddress))
|
||||
).arg(toAddress))
|
||||
elif status == 'invalidcharacters':
|
||||
self.updateStatusBar(_translate(
|
||||
"MainWindow",
|
||||
"Error: The recipient address %1 contains"
|
||||
" invalid characters. Please check it."
|
||||
).arg(toAddress))
|
||||
).arg(toAddress))
|
||||
elif status == 'versiontoohigh':
|
||||
self.updateStatusBar(_translate(
|
||||
"MainWindow",
|
||||
|
@ -2108,7 +2205,7 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
" %1 is too high. Either you need to upgrade"
|
||||
" your Bitmessage software or your"
|
||||
" acquaintance is being clever."
|
||||
).arg(toAddress))
|
||||
).arg(toAddress))
|
||||
elif status == 'ripetooshort':
|
||||
self.updateStatusBar(_translate(
|
||||
"MainWindow",
|
||||
|
@ -2116,7 +2213,7 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
" address %1 is too short. There might be"
|
||||
" something wrong with the software of"
|
||||
" your acquaintance."
|
||||
).arg(toAddress))
|
||||
).arg(toAddress))
|
||||
elif status == 'ripetoolong':
|
||||
self.updateStatusBar(_translate(
|
||||
"MainWindow",
|
||||
|
@ -2124,7 +2221,7 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
" address %1 is too long. There might be"
|
||||
" something wrong with the software of"
|
||||
" your acquaintance."
|
||||
).arg(toAddress))
|
||||
).arg(toAddress))
|
||||
elif status == 'varintmalformed':
|
||||
self.updateStatusBar(_translate(
|
||||
"MainWindow",
|
||||
|
@ -2132,30 +2229,46 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
" address %1 is malformed. There might be"
|
||||
" something wrong with the software of"
|
||||
" your acquaintance."
|
||||
).arg(toAddress))
|
||||
).arg(toAddress))
|
||||
else:
|
||||
self.updateStatusBar(_translate(
|
||||
"MainWindow",
|
||||
"Error: Something is wrong with the"
|
||||
" recipient address %1."
|
||||
).arg(toAddress))
|
||||
).arg(toAddress))
|
||||
elif fromAddress == '':
|
||||
self.updateStatusBar(_translate(
|
||||
"MainWindow",
|
||||
"Error: You must specify a From address. If you"
|
||||
" don\'t have one, go to the"
|
||||
" \'Your Identities\' tab.")
|
||||
)
|
||||
" \'Your Identities\' tab."))
|
||||
else:
|
||||
toAddress = addBMIfNotPresent(toAddress)
|
||||
|
||||
if addressVersionNumber > 4 or addressVersionNumber <= 1:
|
||||
QtGui.QMessageBox.about(self, _translate("MainWindow", "Address version number"), _translate(
|
||||
"MainWindow", "Concerning the address %1, Bitmessage cannot understand address version numbers of %2. Perhaps upgrade Bitmessage to the latest version.").arg(toAddress).arg(str(addressVersionNumber)))
|
||||
QtGui.QMessageBox.about(
|
||||
self,
|
||||
_translate(
|
||||
"MainWindow", "Address version number"),
|
||||
_translate(
|
||||
"MainWindow",
|
||||
"Concerning the address %1, Bitmessage"
|
||||
" cannot understand address version"
|
||||
" numbers of %2. Perhaps upgrade"
|
||||
" Bitmessage to the latest version."
|
||||
).arg(toAddress, addressVersionNumber))
|
||||
continue
|
||||
if streamNumber > 1 or streamNumber == 0:
|
||||
QtGui.QMessageBox.about(self, _translate("MainWindow", "Stream number"), _translate(
|
||||
"MainWindow", "Concerning the address %1, Bitmessage cannot handle stream numbers of %2. Perhaps upgrade Bitmessage to the latest version.").arg(toAddress).arg(str(streamNumber)))
|
||||
QtGui.QMessageBox.about(
|
||||
self,
|
||||
_translate("MainWindow", "Stream number"),
|
||||
_translate(
|
||||
"MainWindow",
|
||||
"Concerning the address %1, Bitmessage"
|
||||
" cannot handle stream numbers of %2."
|
||||
" Perhaps upgrade Bitmessage to the"
|
||||
" latest version."
|
||||
).format(toAddress, streamNumber))
|
||||
continue
|
||||
self.statusbar.clearMessage()
|
||||
if state.statusIconColor == 'red':
|
||||
|
@ -2251,7 +2364,8 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
self.updateStatusBar(_translate(
|
||||
"MainWindow", "Fetched address from namecoin identity."))
|
||||
|
||||
def setBroadcastEnablementDependingOnWhetherThisIsAMailingListAddress(self, address):
|
||||
def setBroadcastEnablementDependingOnWhetherThisIsAMailingListAddress(
|
||||
self, address):
|
||||
# If this is a chan then don't let people broadcast because no one
|
||||
# should subscribe to chan addresses.
|
||||
self.ui.tabWidgetSend.setCurrentIndex(
|
||||
|
@ -2264,15 +2378,21 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
def rerenderComboBoxSendFrom(self):
|
||||
self.ui.comboBoxSendFrom.clear()
|
||||
for addressInKeysFile in getSortedAccounts():
|
||||
# I realize that this is poor programming practice but I don't care.
|
||||
# It's easier for others to read.
|
||||
isEnabled = BMConfigParser().getboolean(
|
||||
addressInKeysFile, 'enabled') # I realize that this is poor programming practice but I don't care. It's easier for others to read.
|
||||
isMaillinglist = BMConfigParser().safeGetBoolean(addressInKeysFile, 'mailinglist')
|
||||
addressInKeysFile, 'enabled')
|
||||
isMaillinglist = BMConfigParser().safeGetBoolean(
|
||||
addressInKeysFile, 'mailinglist')
|
||||
if isEnabled and not isMaillinglist:
|
||||
label = unicode(BMConfigParser().get(addressInKeysFile, 'label'), 'utf-8', 'ignore').strip()
|
||||
label = unicode(
|
||||
BMConfigParser().get(addressInKeysFile, 'label'),
|
||||
'utf-8', 'ignore').strip()
|
||||
if label == "":
|
||||
label = addressInKeysFile
|
||||
self.ui.comboBoxSendFrom.addItem(avatarize(addressInKeysFile), label, addressInKeysFile)
|
||||
# self.ui.comboBoxSendFrom.model().sort(1, Qt.AscendingOrder)
|
||||
self.ui.comboBoxSendFrom.addItem(
|
||||
avatarize(addressInKeysFile), label, addressInKeysFile)
|
||||
# self.ui.comboBoxSendFrom.model().sort(1, Qt.AscendingOrder)
|
||||
for i in range(self.ui.comboBoxSendFrom.count()):
|
||||
address = str(self.ui.comboBoxSendFrom.itemData(
|
||||
i, QtCore.Qt.UserRole).toString())
|
||||
|
@ -2288,14 +2408,19 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
def rerenderComboBoxSendFromBroadcast(self):
|
||||
self.ui.comboBoxSendFromBroadcast.clear()
|
||||
for addressInKeysFile in getSortedAccounts():
|
||||
# I realize that this is poor programming practice but I don't care.
|
||||
# It's easier for others to read.
|
||||
isEnabled = BMConfigParser().getboolean(
|
||||
addressInKeysFile, 'enabled') # I realize that this is poor programming practice but I don't care. It's easier for others to read.
|
||||
addressInKeysFile, 'enabled')
|
||||
isChan = BMConfigParser().safeGetBoolean(addressInKeysFile, 'chan')
|
||||
if isEnabled and not isChan:
|
||||
label = unicode(BMConfigParser().get(addressInKeysFile, 'label'), 'utf-8', 'ignore').strip()
|
||||
label = unicode(
|
||||
BMConfigParser().get(addressInKeysFile, 'label'),
|
||||
'utf-8', 'ignore').strip()
|
||||
if label == "":
|
||||
label = addressInKeysFile
|
||||
self.ui.comboBoxSendFromBroadcast.addItem(avatarize(addressInKeysFile), label, addressInKeysFile)
|
||||
self.ui.comboBoxSendFromBroadcast.addItem(
|
||||
avatarize(addressInKeysFile), label, addressInKeysFile)
|
||||
for i in range(self.ui.comboBoxSendFromBroadcast.count()):
|
||||
address = str(self.ui.comboBoxSendFromBroadcast.itemData(
|
||||
i, QtCore.Qt.UserRole).toString())
|
||||
|
@ -2303,7 +2428,7 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
i, AccountColor(address).accountColor(),
|
||||
QtCore.Qt.ForegroundRole)
|
||||
self.ui.comboBoxSendFromBroadcast.insertItem(0, '', '')
|
||||
if(self.ui.comboBoxSendFromBroadcast.count() == 2):
|
||||
if self.ui.comboBoxSendFromBroadcast.count() == 2:
|
||||
self.ui.comboBoxSendFromBroadcast.setCurrentIndex(1)
|
||||
else:
|
||||
self.ui.comboBoxSendFromBroadcast.setCurrentIndex(0)
|
||||
|
@ -2454,9 +2579,10 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
# and such, but it must also be checked here.
|
||||
if shared.isAddressInMySubscriptionsList(address):
|
||||
return
|
||||
# Add to database (perhaps this should be separated from the MyForm class)
|
||||
# Add to database
|
||||
# (perhaps this should be separated from the MyForm class)
|
||||
sqlExecute(
|
||||
'''INSERT INTO subscriptions VALUES (?,?,?)''',
|
||||
'INSERT INTO subscriptions VALUES (?,?,?)',
|
||||
label, address, True
|
||||
)
|
||||
self.rerenderMessagelistFromLabels()
|
||||
|
@ -2572,11 +2698,11 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
msgids = []
|
||||
for i in range(0, idCount):
|
||||
msgids.append(tableWidget.item(i, 3).data())
|
||||
for col in xrange(tableWidget.columnCount()):
|
||||
for col in range(tableWidget.columnCount()):
|
||||
tableWidget.item(i, col).setUnread(False)
|
||||
|
||||
markread = sqlExecuteChunked(
|
||||
"UPDATE inbox SET read = 1 WHERE msgid IN({0}) AND read=0",
|
||||
'UPDATE inbox SET read = 1 WHERE msgid IN({0}) AND read=0',
|
||||
idCount, *msgids
|
||||
)
|
||||
|
||||
|
@ -2626,21 +2752,20 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
waitForSync = False
|
||||
|
||||
# C PoW currently doesn't support interrupting and OpenCL is untested
|
||||
if getPowType() == "python" and (powQueueSize() > 0 or pendingUpload() > 0):
|
||||
if getPowType() == "python" and (
|
||||
powQueueSize() > 0 or pendingUpload() > 0):
|
||||
reply = QtGui.QMessageBox.question(
|
||||
self, _translate("MainWindow", "Proof of work pending"),
|
||||
_translate(
|
||||
"MainWindow",
|
||||
"%n object(s) pending proof of work", None,
|
||||
QtCore.QCoreApplication.CodecForTr, powQueueSize()
|
||||
) + ", " +
|
||||
_translate(
|
||||
"%n object(s) pending proof of work", None, powQueueSize()
|
||||
) + ", "
|
||||
+ _translate(
|
||||
"MainWindow",
|
||||
"%n object(s) waiting to be distributed", None,
|
||||
QtCore.QCoreApplication.CodecForTr, pendingUpload()
|
||||
) + "\n\n" +
|
||||
_translate(
|
||||
"MainWindow", "Wait until these tasks finish?"),
|
||||
pendingUpload()
|
||||
) + "\n\n"
|
||||
+ _translate("MainWindow", "Wait until these tasks finish?"),
|
||||
QtGui.QMessageBox.Yes | QtGui.QMessageBox.No
|
||||
| QtGui.QMessageBox.Cancel, QtGui.QMessageBox.Cancel)
|
||||
if reply == QtGui.QMessageBox.No:
|
||||
|
@ -2656,17 +2781,16 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
"Bitmessage hasn't synchronised with the network,"
|
||||
" %n object(s) to be downloaded. If you quit now,"
|
||||
" it may cause delivery delays. Wait until the"
|
||||
" synchronisation finishes?", None,
|
||||
QtCore.QCoreApplication.CodecForTr, pendingDownload()
|
||||
),
|
||||
QtGui.QMessageBox.Yes | QtGui.QMessageBox.No
|
||||
" synchronisation finishes?", None, pendingDownload()
|
||||
), QtGui.QMessageBox.Yes | QtGui.QMessageBox.No
|
||||
| QtGui.QMessageBox.Cancel, QtGui.QMessageBox.Cancel)
|
||||
if reply == QtGui.QMessageBox.Yes:
|
||||
self.wait = waitForSync = True
|
||||
elif reply == QtGui.QMessageBox.Cancel:
|
||||
return
|
||||
|
||||
if state.statusIconColor == 'red' and not BMConfigParser().safeGetBoolean(
|
||||
if state.statusIconColor == 'red' \
|
||||
and not BMConfigParser().safeGetBoolean(
|
||||
'bitmessagesettings', 'dontconnect'):
|
||||
reply = QtGui.QMessageBox.question(
|
||||
self, _translate("MainWindow", "Not connected"),
|
||||
|
@ -2675,8 +2799,7 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
"Bitmessage isn't connected to the network. If you"
|
||||
" quit now, it may cause delivery delays. Wait until"
|
||||
" connected and the synchronisation finishes?"
|
||||
),
|
||||
QtGui.QMessageBox.Yes | QtGui.QMessageBox.No
|
||||
), QtGui.QMessageBox.Yes | QtGui.QMessageBox.No
|
||||
| QtGui.QMessageBox.Cancel, QtGui.QMessageBox.Cancel)
|
||||
if reply == QtGui.QMessageBox.Yes:
|
||||
waitForConnection = True
|
||||
|
@ -2722,8 +2845,9 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
if curWorkerQueue > 0:
|
||||
self.updateStatusBar(_translate(
|
||||
"MainWindow", "Waiting for PoW to finish... %1%"
|
||||
).arg(50 * (maxWorkerQueue - curWorkerQueue) /
|
||||
maxWorkerQueue))
|
||||
).arg(
|
||||
50 * (maxWorkerQueue - curWorkerQueue) / maxWorkerQueue)
|
||||
)
|
||||
time.sleep(0.5)
|
||||
QtCore.QCoreApplication.processEvents(
|
||||
QtCore.QEventLoop.AllEvents, 1000
|
||||
|
@ -2816,21 +2940,28 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
if not msgid:
|
||||
return
|
||||
queryreturn = sqlQuery(
|
||||
'''select message from inbox where msgid=?''', msgid)
|
||||
if queryreturn != []:
|
||||
for row in queryreturn:
|
||||
messageText, = row
|
||||
'SELECT message FROM inbox WHERE msgid=?', msgid)
|
||||
try:
|
||||
lines = queryreturn[-1][0].split('\n')
|
||||
except IndexError:
|
||||
lines = ''
|
||||
|
||||
lines = messageText.split('\n')
|
||||
totalLines = len(lines)
|
||||
for i in xrange(totalLines):
|
||||
for i in range(totalLines):
|
||||
if 'Message ostensibly from ' in lines[i]:
|
||||
lines[i] = '<p style="font-size: 12px; color: grey;">%s</span></p>' % (
|
||||
lines[i])
|
||||
elif lines[i] == '------------------------------------------------------':
|
||||
lines[i] = (
|
||||
'<p style="font-size: 12px; color: grey;">%s</span></p>'
|
||||
% (lines[i])
|
||||
elif (
|
||||
lines[i]
|
||||
== '------------------------------------------------------'
|
||||
):
|
||||
lines[i] = '<hr>'
|
||||
elif lines[i] == '' and (i+1) < totalLines and \
|
||||
lines[i+1] != '------------------------------------------------------':
|
||||
elif (
|
||||
lines[i] == '' and (i+1) < totalLines
|
||||
and lines[i+1]
|
||||
!= '------------------------------------------------------'
|
||||
):
|
||||
lines[i] = '<br><br>'
|
||||
content = ' '.join(lines) # To keep the whitespace between lines
|
||||
content = shared.fixPotentiallyInvalidUTF8Data(content)
|
||||
|
@ -2861,18 +2992,14 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
)
|
||||
|
||||
self.propagateUnreadCount()
|
||||
# tableWidget.selectRow(currentRow + 1)
|
||||
# This doesn't de-select the last message if you try to mark it
|
||||
# unread, but that doesn't interfere. Might not be necessary.
|
||||
# We could also select upwards, but then our problem would be
|
||||
# with the topmost message.
|
||||
# tableWidget.clearSelection() manages to mark the message
|
||||
# as read again.
|
||||
|
||||
# Format predefined text on message reply.
|
||||
def quoted_text(self, message):
|
||||
if not BMConfigParser().safeGetBoolean('bitmessagesettings', 'replybelow'):
|
||||
return '\n\n------------------------------------------------------\n' + message
|
||||
if not BMConfigParser().safeGetBoolean(
|
||||
'bitmessagesettings', 'replybelow'):
|
||||
return (
|
||||
'\n\n------------------------------------------------------\n'
|
||||
+ message)
|
||||
|
||||
quoteWrapper = textwrap.TextWrapper(
|
||||
replace_whitespace=False, initial_indent='> ',
|
||||
|
@ -2938,8 +3065,8 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
currentInboxRow, column_from).address
|
||||
msgid = tableWidget.item(currentInboxRow, 3).data()
|
||||
queryreturn = sqlQuery(
|
||||
"SELECT message FROM inbox WHERE msgid=?", msgid
|
||||
) or sqlQuery("SELECT message FROM sent WHERE ackdata=?", msgid)
|
||||
'SELECT message FROM inbox WHERE msgid=?', msgid
|
||||
) or sqlQuery('SELECT message FROM sent WHERE ackdata=?', msgid)
|
||||
if queryreturn != []:
|
||||
for row in queryreturn:
|
||||
messageAtCurrentInboxRow, = row
|
||||
|
@ -2957,7 +3084,7 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
self.ui.tabWidgetSend.setCurrentIndex(
|
||||
self.ui.tabWidgetSend.indexOf(self.ui.sendDirect)
|
||||
)
|
||||
# toAddressAtCurrentInboxRow = fromAddressAtCurrentInboxRow
|
||||
# toAddressAtCurrentInboxRow = fromAddressAtCurrentInboxRow
|
||||
elif not BMConfigParser().has_section(toAddressAtCurrentInboxRow):
|
||||
QtGui.QMessageBox.information(
|
||||
self, _translate("MainWindow", "Address is gone"),
|
||||
|
@ -3053,18 +3180,19 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
recipientAddress = tableWidget.item(
|
||||
currentInboxRow, 0).data(QtCore.Qt.UserRole)
|
||||
# Let's make sure that it isn't already in the address book
|
||||
queryreturn = sqlQuery('''select * from blacklist where address=?''',
|
||||
addressAtCurrentInboxRow)
|
||||
queryreturn = sqlQuery(
|
||||
'SELECT * FROM blacklist WHERE address=?', addressAtCurrentInboxRow)
|
||||
if queryreturn == []:
|
||||
label = "\"" + tableWidget.item(currentInboxRow, 2).subject + "\" in " + BMConfigParser().get(recipientAddress, "label")
|
||||
sqlExecute('''INSERT INTO blacklist VALUES (?,?, ?)''',
|
||||
label,
|
||||
addressAtCurrentInboxRow, True)
|
||||
label = "\"" + tableWidget.item(
|
||||
currentInboxRow, 2).subject + "\" in " + BMConfigParser().get(
|
||||
recipientAddress, "label")
|
||||
sqlExecute(
|
||||
'INSERT INTO blacklist VALUES (?,?, ?)',
|
||||
label, addressAtCurrentInboxRow, True)
|
||||
self.ui.blackwhitelist.rerenderBlackWhiteList()
|
||||
self.updateStatusBar(_translate(
|
||||
"MainWindow",
|
||||
"Entry added to the blacklist. Edit the label to your liking.")
|
||||
)
|
||||
"Entry added to the blacklist. Edit the label to your liking."))
|
||||
else:
|
||||
self.updateStatusBar(_translate(
|
||||
"MainWindow",
|
||||
|
@ -3169,14 +3297,17 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
# Retrieve the message data out of the SQL database
|
||||
msgid = tableWidget.item(currentInboxRow, 3).data()
|
||||
queryreturn = sqlQuery(
|
||||
'''select message from inbox where msgid=?''', msgid)
|
||||
'SELECT message FROM inbox WHERE msgid=?', msgid)
|
||||
if queryreturn != []:
|
||||
for row in queryreturn:
|
||||
message, = row
|
||||
|
||||
defaultFilename = "".join(x for x in subjectAtCurrentInboxRow if x.isalnum()) + '.txt'
|
||||
filename = QtGui.QFileDialog.getSaveFileName(self, _translate("MainWindow","Save As..."), defaultFilename, "Text files (*.txt);;All files (*.*)")
|
||||
if filename == '':
|
||||
defaultFilename = "".join(
|
||||
x for x in subjectAtCurrentInboxRow if x.isalnum()) + '.txt'
|
||||
filename = QtGui.QFileDialog.getSaveFileName(
|
||||
self, _translate("MainWindow", "Save As..."), defaultFilename,
|
||||
"Text files (*.txt);;All files (*.*)")
|
||||
if not filename:
|
||||
return
|
||||
try:
|
||||
f = open(filename, 'w')
|
||||
|
@ -3188,11 +3319,13 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
|
||||
# Send item on the Sent tab to trash
|
||||
def on_action_SentTrash(self):
|
||||
currentRow = 0
|
||||
tableWidget = self.getCurrentMessagelist()
|
||||
if not tableWidget:
|
||||
return
|
||||
folder = self.getCurrentFolder()
|
||||
shifted = QtGui.QApplication.queryKeyboardModifiers() & QtCore.Qt.ShiftModifier
|
||||
shifted = (QtGui.QApplication.queryKeyboardModifiers()
|
||||
& QtCore.Qt.ShiftModifier)
|
||||
while tableWidget.selectedIndexes() != []:
|
||||
currentRow = tableWidget.selectedIndexes()[0].row()
|
||||
ackdataToTrash = tableWidget.item(currentRow, 3).data()
|
||||
|
@ -3215,13 +3348,17 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
currentRow, 0).data(QtCore.Qt.UserRole)
|
||||
toRipe = decodeAddress(addressAtCurrentRow)[3]
|
||||
sqlExecute(
|
||||
'''UPDATE sent SET status='forcepow' WHERE toripe=? AND status='toodifficult' and folder='sent' ''',
|
||||
"UPDATE sent SET status='forcepow'"
|
||||
" WHERE toripe=? AND status='toodifficult' and folder='sent'",
|
||||
toRipe)
|
||||
queryreturn = sqlQuery('''select ackdata FROM sent WHERE status='forcepow' ''')
|
||||
queryreturn = sqlQuery(
|
||||
"SELECT ackdata FROM sent WHERE status='forcepow'")
|
||||
for row in queryreturn:
|
||||
ackdata, = row
|
||||
queues.UISignalQueue.put(('updateSentItemStatusByAckdata', (
|
||||
ackdata, 'Overriding maximum-difficulty setting. Work queued.')))
|
||||
queues.UISignalQueue.put((
|
||||
'updateSentItemStatusByAckdata',
|
||||
(ackdata, 'Overriding maximum-difficulty setting. Work queued.')
|
||||
))
|
||||
queues.workerQueue.put(('sendmessage', ''))
|
||||
|
||||
def on_action_SentClipboard(self):
|
||||
|
@ -3663,10 +3800,8 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
if not os.path.exists(state.appdata + 'avatars/'):
|
||||
os.makedirs(state.appdata + 'avatars/')
|
||||
hash = hashlib.md5(addBMIfNotPresent(addressAtCurrentRow)).hexdigest()
|
||||
extensions = [
|
||||
'PNG', 'GIF', 'JPG', 'JPEG', 'SVG', 'BMP', 'MNG', 'PBM',
|
||||
'PGM', 'PPM', 'TIFF', 'XBM', 'XPM', 'TGA']
|
||||
|
||||
# http://pyqt.sourceforge.net/Docs/PyQt4/qimagereader.html#supportedImageFormats
|
||||
names = {
|
||||
'BMP': 'Windows Bitmap',
|
||||
'GIF': 'Graphic Interchange Format',
|
||||
|
@ -3685,7 +3820,7 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
filters = []
|
||||
all_images_filter = []
|
||||
current_files = []
|
||||
for ext in extensions:
|
||||
for ext in names:
|
||||
filters += [names[ext] + ' (*.' + ext.lower() + ')']
|
||||
all_images_filter += ['*.' + ext.lower()]
|
||||
upper = state.appdata + 'avatars/' + hash + '.' + ext.upper()
|
||||
|
@ -3799,16 +3934,22 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
currentItem = self.getCurrentItem()
|
||||
self.popMenuYourIdentities = QtGui.QMenu(self)
|
||||
if isinstance(currentItem, Ui_AddressWidget):
|
||||
self.popMenuYourIdentities.addAction(self.actionNewYourIdentities)
|
||||
self.popMenuYourIdentities.addAction(
|
||||
self.actionNewYourIdentities)
|
||||
self.popMenuYourIdentities.addSeparator()
|
||||
self.popMenuYourIdentities.addAction(self.actionClipboardYourIdentities)
|
||||
self.popMenuYourIdentities.addAction(
|
||||
self.actionClipboardYourIdentities)
|
||||
self.popMenuYourIdentities.addSeparator()
|
||||
if currentItem.isEnabled:
|
||||
self.popMenuYourIdentities.addAction(self.actionDisableYourIdentities)
|
||||
self.popMenuYourIdentities.addAction(
|
||||
self.actionDisableYourIdentities)
|
||||
else:
|
||||
self.popMenuYourIdentities.addAction(self.actionEnableYourIdentities)
|
||||
self.popMenuYourIdentities.addAction(self.actionSetAvatarYourIdentities)
|
||||
self.popMenuYourIdentities.addAction(self.actionSpecialAddressBehaviorYourIdentities)
|
||||
self.popMenuYourIdentities.addAction(
|
||||
self.actionEnableYourIdentities)
|
||||
self.popMenuYourIdentities.addAction(
|
||||
self.actionSetAvatarYourIdentities)
|
||||
self.popMenuYourIdentities.addAction(
|
||||
self.actionSpecialAddressBehaviorYourIdentities)
|
||||
self.popMenuYourIdentities.addAction(self.actionEmailGateway)
|
||||
self.popMenuYourIdentities.addSeparator()
|
||||
if currentItem.type != AccountMixin.ALL:
|
||||
|
@ -3912,7 +4053,8 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
# menu option (Force Send) if it is.
|
||||
if currentRow >= 0:
|
||||
ackData = self.ui.tableWidgetInbox.item(currentRow, 3).data()
|
||||
queryreturn = sqlQuery('''SELECT status FROM sent where ackdata=?''', ackData)
|
||||
queryreturn = sqlQuery(
|
||||
'SELECT status FROM sent where ackdata=?', ackData)
|
||||
for row in queryreturn:
|
||||
status, = row
|
||||
if status == 'toodifficult':
|
||||
|
@ -3996,7 +4138,9 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
self.rerenderMessagelistFromLabels()
|
||||
if item.type != AccountMixin.SUBSCRIPTION:
|
||||
self.rerenderMessagelistToLabels()
|
||||
if item.type in (AccountMixin.NORMAL, AccountMixin.CHAN, AccountMixin.SUBSCRIPTION):
|
||||
if item.type in (
|
||||
AccountMixin.NORMAL, AccountMixin.CHAN, AccountMixin.SUBSCRIPTION
|
||||
):
|
||||
self.rerenderAddressBook()
|
||||
self.recurDepth -= 1
|
||||
|
||||
|
@ -4009,7 +4153,7 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
folder = self.getCurrentFolder()
|
||||
if msgid:
|
||||
queryreturn = sqlQuery(
|
||||
'''SELECT message FROM %s WHERE %s=?''' % (
|
||||
'SELECT message FROM %s WHERE %s=?' % (
|
||||
('sent', 'ackdata') if folder == 'sent'
|
||||
else ('inbox', 'msgid')
|
||||
), msgid
|
||||
|
@ -4032,7 +4176,7 @@ class MyForm(settingsmixin.SMainWindow):
|
|||
self.updateUnreadStatus(tableWidget, currentRow, msgid)
|
||||
# propagate
|
||||
if folder != 'sent' and sqlExecute(
|
||||
'''UPDATE inbox SET read=1 WHERE msgid=? AND read=0''',
|
||||
'UPDATE inbox SET read=1 WHERE msgid=? AND read=0',
|
||||
msgid
|
||||
) > 0:
|
||||
self.propagateUnreadCount()
|
||||
|
@ -4188,12 +4332,6 @@ def run():
|
|||
if myapp._firstrun:
|
||||
myapp.showConnectDialog() # ask the user if we may connect
|
||||
|
||||
# try:
|
||||
# if BMConfigParser().get('bitmessagesettings', 'mailchuck') < 1:
|
||||
# myapp.showMigrationWizard(BMConfigParser().get('bitmessagesettings', 'mailchuck'))
|
||||
# except:
|
||||
# myapp.showMigrationWizard(0)
|
||||
|
||||
# only show after wizards and connect dialogs have completed
|
||||
if not BMConfigParser().getboolean('bitmessagesettings', 'startintray'):
|
||||
myapp.show()
|
||||
|
|
|
@ -1,10 +1,6 @@
|
|||
# pylint: disable=too-many-instance-attributes,attribute-defined-outside-init
|
||||
"""
|
||||
account.py
|
||||
==========
|
||||
|
||||
Account related functions.
|
||||
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import
|
||||
|
@ -14,13 +10,12 @@ import re
|
|||
import sys
|
||||
import time
|
||||
|
||||
from PyQt4 import QtGui
|
||||
|
||||
import queues
|
||||
from addresses import decodeAddress
|
||||
from bmconfigparser import BMConfigParser
|
||||
from helper_ackPayload import genAckPayload
|
||||
from helper_sql import sqlQuery, sqlExecute
|
||||
from pybitmessage import queues
|
||||
from pybitmessage.addresses import decodeAddress
|
||||
from pybitmessage.bmconfigparser import BMConfigParser
|
||||
from pybitmessage.helper_ackPayload import genAckPayload
|
||||
from pybitmessage.helper_sql import sqlQuery, sqlExecute
|
||||
from pybitmessage.tr import _translate
|
||||
from .foldertree import AccountMixin
|
||||
from .utils import str_broadcast_subscribers
|
||||
|
||||
|
@ -292,7 +287,7 @@ class MailchuckAccount(GatewayAccount):
|
|||
|
||||
self.toAddress = self.registrationAddress
|
||||
self.subject = "config"
|
||||
self.message = QtGui.QApplication.translate(
|
||||
self.message = _translate(
|
||||
"Mailchuck",
|
||||
"""# You can use this to configure your email gateway account
|
||||
# Uncomment the setting you want to use
|
||||
|
|
|
@ -1,22 +1,26 @@
|
|||
"""
|
||||
Dialogs that work with BM address.
|
||||
"""
|
||||
# pylint: disable=attribute-defined-outside-init,too-few-public-methods,relative-import
|
||||
# pylint: disable=too-few-public-methods
|
||||
# https://github.com/PyCQA/pylint/issues/471
|
||||
|
||||
import hashlib
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
import queues
|
||||
import widgets
|
||||
from account import AccountMixin, GatewayAccount, MailchuckAccount, accountClass, getSortedAccounts
|
||||
from addresses import addBMIfNotPresent, decodeAddress, encodeVarint
|
||||
from inventory import Inventory
|
||||
from tr import _translate
|
||||
from pybitmessage import queues
|
||||
from pybitmessage.addresses import (
|
||||
addBMIfNotPresent, decodeAddress, encodeVarint)
|
||||
from pybitmessage.inventory import Inventory
|
||||
from pybitmessage.tr import _translate
|
||||
from . import widgets
|
||||
from .account import (
|
||||
accountClass, AccountMixin, GatewayAccount, getSortedAccounts,
|
||||
MailchuckAccount)
|
||||
|
||||
|
||||
class AddressCheckMixin(object):
|
||||
"""Base address validation class for QT UI"""
|
||||
"""Base address validation class for Qt UI"""
|
||||
|
||||
def __init__(self):
|
||||
self.valid = False
|
||||
|
@ -28,12 +32,12 @@ class AddressCheckMixin(object):
|
|||
def _onSuccess(self, addressVersion, streamNumber, ripe):
|
||||
pass
|
||||
|
||||
def addressChanged(self, QString):
|
||||
def addressChanged(self, address):
|
||||
"""
|
||||
Address validation callback, performs validation and gives feedback
|
||||
"""
|
||||
status, addressVersion, streamNumber, ripe = decodeAddress(
|
||||
str(QString))
|
||||
str(address))
|
||||
self.valid = status == 'success'
|
||||
if self.valid:
|
||||
self.labelAddressCheck.setText(
|
||||
|
@ -84,9 +88,10 @@ class AddressDataDialog(QtGui.QDialog, AddressCheckMixin):
|
|||
def __init__(self, parent):
|
||||
super(AddressDataDialog, self).__init__(parent)
|
||||
self.parent = parent
|
||||
self.data = None
|
||||
|
||||
def accept(self):
|
||||
"""Callback for QDIalog accepting value"""
|
||||
"""Callback for QDialog accepting value"""
|
||||
if self.valid:
|
||||
self.data = (
|
||||
addBMIfNotPresent(str(self.lineEditAddress.text())),
|
||||
|
@ -180,6 +185,7 @@ class NewSubscriptionDialog(AddressDataDialog):
|
|||
super(NewSubscriptionDialog, self).__init__(parent)
|
||||
widgets.load('newsubscriptiondialog.ui', self)
|
||||
AddressCheckMixin.__init__(self)
|
||||
self.recent = []
|
||||
|
||||
def _onSuccess(self, addressVersion, streamNumber, ripe):
|
||||
if addressVersion <= 3:
|
||||
|
@ -256,7 +262,8 @@ class SpecialAddressBehaviorDialog(QtGui.QDialog):
|
|||
self.radioButtonBehaviorMailingList.click()
|
||||
else:
|
||||
self.radioButtonBehaveNormalAddress.click()
|
||||
mailingListName = config.safeGet(self.address, 'mailinglistname', '')
|
||||
mailingListName = config.safeGet(
|
||||
self.address, 'mailinglistname', '')
|
||||
self.lineEditMailingListName.setText(
|
||||
unicode(mailingListName, 'utf-8')
|
||||
)
|
||||
|
@ -297,6 +304,7 @@ class EmailGatewayDialog(QtGui.QDialog):
|
|||
widgets.load('emailgateway.ui', self)
|
||||
self.parent = parent
|
||||
self.config = config
|
||||
self.data = None
|
||||
if account:
|
||||
self.acct = account
|
||||
self.setWindowTitle(_translate(
|
||||
|
|
|
@ -1,29 +1,26 @@
|
|||
"""
|
||||
Address validator module.
|
||||
The validator for address and passphrase QLineEdits
|
||||
used in `.dialogs.NewChanDialog`.
|
||||
"""
|
||||
# pylint: disable=too-many-branches,too-many-arguments
|
||||
# pylint: disable=too-many-arguments
|
||||
|
||||
from PyQt4 import QtGui
|
||||
from Queue import Empty
|
||||
from six.moves import queue
|
||||
|
||||
from account import getSortedAccounts
|
||||
from addresses import decodeAddress, addBMIfNotPresent
|
||||
from queues import apiAddressGeneratorReturnQueue, addressGeneratorQueue
|
||||
from tr import _translate
|
||||
from utils import str_chan
|
||||
from pybitmessage.addresses import addBMIfNotPresent, decodeAddress
|
||||
from pybitmessage.queues import (
|
||||
addressGeneratorQueue, apiAddressGeneratorReturnQueue)
|
||||
from pybitmessage.tr import _translate
|
||||
from .account import getSortedAccounts
|
||||
from .utils import str_chan
|
||||
|
||||
|
||||
class AddressPassPhraseValidatorMixin(object):
|
||||
"""Bitmessage address or passphrase validator class for Qt UI"""
|
||||
def setParams(
|
||||
self,
|
||||
passPhraseObject=None,
|
||||
addressObject=None,
|
||||
feedBackObject=None,
|
||||
buttonBox=None,
|
||||
addressMandatory=True,
|
||||
self, passPhraseObject=None, addressObject=None,
|
||||
feedBackObject=None, buttonBox=None, addressMandatory=True
|
||||
):
|
||||
"""Initialisation"""
|
||||
self.addressObject = addressObject
|
||||
self.passPhraseObject = passPhraseObject
|
||||
self.feedBackObject = feedBackObject
|
||||
|
@ -75,8 +72,9 @@ class AddressPassPhraseValidatorMixin(object):
|
|||
|
||||
while True:
|
||||
try:
|
||||
addressGeneratorReturnValue = apiAddressGeneratorReturnQueue.get(False)
|
||||
except Empty:
|
||||
addressGeneratorReturnValue = \
|
||||
apiAddressGeneratorReturnQueue.get(False)
|
||||
except queue.Empty:
|
||||
if gotOne:
|
||||
break
|
||||
else:
|
||||
|
@ -85,16 +83,18 @@ class AddressPassPhraseValidatorMixin(object):
|
|||
gotOne = True
|
||||
|
||||
if not addressGeneratorReturnValue:
|
||||
self.setError(_translate("AddressValidator", "Address already present as one of your identities."))
|
||||
self.setError(_translate(
|
||||
"AddressValidator",
|
||||
"Address already present as one of your identities."))
|
||||
return (QtGui.QValidator.Intermediate, 0)
|
||||
if addressGeneratorReturnValue[0] == 'chan name does not match address':
|
||||
self.setError(
|
||||
_translate(
|
||||
"AddressValidator",
|
||||
"Although the Bitmessage address you "
|
||||
"entered was valid, it doesn't match the chan name."))
|
||||
self.setError(_translate(
|
||||
"AddressValidator",
|
||||
"Although the Bitmessage address you entered was valid,"
|
||||
" it doesn\'t match the chan name."))
|
||||
return (QtGui.QValidator.Intermediate, 0)
|
||||
self.setOK(_translate("MainWindow", "Passphrase and address appear to be valid."))
|
||||
self.setOK(_translate(
|
||||
"MainWindow", "Passphrase and address appear to be valid."))
|
||||
|
||||
def returnValid(self):
|
||||
"""Return the value of whether the validation was successful"""
|
||||
|
@ -119,29 +119,32 @@ class AddressPassPhraseValidatorMixin(object):
|
|||
|
||||
# no chan name
|
||||
if passPhrase is None:
|
||||
self.setError(_translate("AddressValidator", "Chan name/passphrase needed. You didn't enter a chan name."))
|
||||
self.setError(_translate(
|
||||
"AddressValidator",
|
||||
"Chan name/passphrase needed. You didn't enter a chan name."))
|
||||
return (QtGui.QValidator.Intermediate, pos)
|
||||
|
||||
if self.addressMandatory or address is not None:
|
||||
# check if address already exists:
|
||||
if address in getSortedAccounts():
|
||||
self.setError(_translate("AddressValidator", "Address already present as one of your identities."))
|
||||
self.setError(_translate(
|
||||
"AddressValidator",
|
||||
"Address already present as one of your identities."))
|
||||
return (QtGui.QValidator.Intermediate, pos)
|
||||
|
||||
# version too high
|
||||
if decodeAddress(address)[0] == 'versiontoohigh':
|
||||
self.setError(
|
||||
_translate(
|
||||
"AddressValidator",
|
||||
"Address too new. Although that Bitmessage"
|
||||
" address might be valid, its version number"
|
||||
" is too new for us to handle. Perhaps you need"
|
||||
" to upgrade Bitmessage."))
|
||||
self.setError(_translate(
|
||||
"AddressValidator",
|
||||
"Address too new. Although that Bitmessage address"
|
||||
" might be valid, its version number is too new for us"
|
||||
" to handle. Perhaps you need to upgrade Bitmessage."))
|
||||
return (QtGui.QValidator.Intermediate, pos)
|
||||
|
||||
# invalid
|
||||
if decodeAddress(address)[0] != 'success':
|
||||
self.setError(_translate("AddressValidator", "The Bitmessage address is not valid."))
|
||||
self.setError(_translate(
|
||||
"AddressValidator", "The Bitmessage address is not valid."))
|
||||
return (QtGui.QValidator.Intermediate, pos)
|
||||
|
||||
# this just disables the OK button without changing the feedback text
|
||||
|
@ -151,7 +154,10 @@ class AddressPassPhraseValidatorMixin(object):
|
|||
|
||||
# check through generator
|
||||
if address is None:
|
||||
addressGeneratorQueue.put(('createChan', 4, 1, str_chan + ' ' + str(passPhrase), passPhrase, False))
|
||||
addressGeneratorQueue.put((
|
||||
'createChan', 4, 1,
|
||||
str_chan + ' ' + str(passPhrase), passPhrase, False
|
||||
))
|
||||
else:
|
||||
addressGeneratorQueue.put(
|
||||
('joinChan', addBMIfNotPresent(address),
|
||||
|
@ -168,13 +174,22 @@ class AddressPassPhraseValidatorMixin(object):
|
|||
|
||||
class AddressValidator(QtGui.QValidator, AddressPassPhraseValidatorMixin):
|
||||
"""AddressValidator class for Qt UI"""
|
||||
def __init__(self, parent=None, passPhraseObject=None, feedBackObject=None, buttonBox=None, addressMandatory=True):
|
||||
def __init__(
|
||||
self, parent=None, passPhraseObject=None, feedBackObject=None,
|
||||
buttonBox=None, addressMandatory=True
|
||||
):
|
||||
super(AddressValidator, self).__init__(parent)
|
||||
self.setParams(passPhraseObject, parent, feedBackObject, buttonBox, addressMandatory)
|
||||
self.setParams(
|
||||
passPhraseObject, parent, feedBackObject, buttonBox,
|
||||
addressMandatory)
|
||||
|
||||
|
||||
class PassPhraseValidator(QtGui.QValidator, AddressPassPhraseValidatorMixin):
|
||||
"""PassPhraseValidator class for Qt UI"""
|
||||
def __init__(self, parent=None, addressObject=None, feedBackObject=None, buttonBox=None, addressMandatory=False):
|
||||
def __init__(
|
||||
self, parent=None, addressObject=None, feedBackObject=None,
|
||||
buttonBox=None, addressMandatory=False
|
||||
):
|
||||
super(PassPhraseValidator, self).__init__(parent)
|
||||
self.setParams(parent, addressObject, feedBackObject, buttonBox, addressMandatory)
|
||||
self.setParams(
|
||||
parent, addressObject, feedBackObject, buttonBox, addressMandatory)
|
||||
|
|
|
@ -1,20 +1,16 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Form implementation generated from reading ui file 'bitmessageui.ui'
|
||||
#
|
||||
# Created: Mon Mar 23 22:18:07 2015
|
||||
# by: PyQt4 UI code generator 4.10.4
|
||||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
# pylint: skip-file
|
||||
# flake8: noqa
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
from bmconfigparser import BMConfigParser
|
||||
from foldertree import AddressBookCompleter
|
||||
from messageview import MessageView
|
||||
from messagecompose import MessageCompose
|
||||
import settingsmixin
|
||||
from networkstatus import NetworkStatus
|
||||
from blacklist import Blacklist
|
||||
|
||||
from pybitmessage.bmconfigparser import BMConfigParser
|
||||
from pybitmessage.tr import _translate
|
||||
from . import settingsmixin, bitmessage_icons_rc
|
||||
from .blacklist import Blacklist
|
||||
from .foldertree import AddressBookCompleter
|
||||
from .messageview import MessageView
|
||||
from .messagecompose import MessageCompose
|
||||
from .networkstatus import NetworkStatus
|
||||
|
||||
try:
|
||||
_fromUtf8 = QtCore.QString.fromUtf8
|
||||
|
@ -22,19 +18,6 @@ except AttributeError:
|
|||
def _fromUtf8(s):
|
||||
return s
|
||||
|
||||
try:
|
||||
_encoding = QtGui.QApplication.UnicodeUTF8
|
||||
def _translate(context, text, disambig, encoding = QtCore.QCoreApplication.CodecForTr, n = None):
|
||||
if n is None:
|
||||
return QtGui.QApplication.translate(context, text, disambig, _encoding)
|
||||
else:
|
||||
return QtGui.QApplication.translate(context, text, disambig, _encoding, n)
|
||||
except AttributeError:
|
||||
def _translate(context, text, disambig, encoding = QtCore.QCoreApplication.CodecForTr, n = None):
|
||||
if n is None:
|
||||
return QtGui.QApplication.translate(context, text, disambig)
|
||||
else:
|
||||
return QtGui.QApplication.translate(context, text, disambig, QtCore.QCoreApplication.CodecForTr, n)
|
||||
|
||||
class Ui_MainWindow(object):
|
||||
def setupUi(self, MainWindow):
|
||||
|
@ -774,15 +757,12 @@ class Ui_MainWindow(object):
|
|||
self.updateNetworkSwitchMenuLabel()
|
||||
|
||||
|
||||
import bitmessage_icons_rc
|
||||
|
||||
if __name__ == "__main__":
|
||||
import sys
|
||||
|
||||
|
||||
app = QtGui.QApplication(sys.argv)
|
||||
MainWindow = settingsmixin.SMainWindow()
|
||||
ui = Ui_MainWindow()
|
||||
ui.setupUi(MainWindow)
|
||||
MainWindow.show()
|
||||
sys.exit(app.exec_())
|
||||
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
import widgets
|
||||
from addresses import addBMIfNotPresent
|
||||
from bmconfigparser import BMConfigParser
|
||||
from dialogs import AddAddressDialog
|
||||
from helper_sql import sqlExecute, sqlQuery
|
||||
from queues import UISignalQueue
|
||||
from retranslateui import RetranslateMixin
|
||||
from tr import _translate
|
||||
from uisignaler import UISignaler
|
||||
from utils import avatarize
|
||||
from pybitmessage.addresses import addBMIfNotPresent
|
||||
from pybitmessage.bmconfigparser import BMConfigParser
|
||||
from pybitmessage.helper_sql import sqlExecute, sqlQuery
|
||||
from pybitmessage.queues import UISignalQueue
|
||||
from pybitmessage.tr import _translate
|
||||
from . import widgets
|
||||
from .dialogs import AddAddressDialog
|
||||
from .retranslateui import RetranslateMixin
|
||||
from .uisignaler import UISignaler
|
||||
from .utils import avatarize
|
||||
|
||||
|
||||
class Blacklist(QtGui.QWidget, RetranslateMixin):
|
||||
|
@ -22,33 +22,39 @@ class Blacklist(QtGui.QWidget, RetranslateMixin):
|
|||
QtCore.QObject.connect(self.radioButtonWhitelist, QtCore.SIGNAL(
|
||||
"clicked()"), self.click_radioButtonWhitelist)
|
||||
QtCore.QObject.connect(self.pushButtonAddBlacklist, QtCore.SIGNAL(
|
||||
"clicked()"), self.click_pushButtonAddBlacklist)
|
||||
"clicked()"), self.click_pushButtonAddBlacklist)
|
||||
|
||||
self.init_blacklist_popup_menu()
|
||||
|
||||
# Initialize blacklist
|
||||
QtCore.QObject.connect(self.tableWidgetBlacklist, QtCore.SIGNAL(
|
||||
"itemChanged(QTableWidgetItem *)"), self.tableWidgetBlacklistItemChanged)
|
||||
"itemChanged(QTableWidgetItem *)"),
|
||||
self.tableWidgetBlacklistItemChanged)
|
||||
|
||||
# Set the icon sizes for the identicons
|
||||
identicon_size = 3*7
|
||||
self.tableWidgetBlacklist.setIconSize(QtCore.QSize(identicon_size, identicon_size))
|
||||
identicon_size = 3 * 7
|
||||
self.tableWidgetBlacklist.setIconSize(QtCore.QSize(
|
||||
identicon_size, identicon_size))
|
||||
|
||||
self.UISignalThread = UISignaler.get()
|
||||
QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL(
|
||||
"rerenderBlackWhiteList()"), self.rerenderBlackWhiteList)
|
||||
|
||||
def click_radioButtonBlacklist(self):
|
||||
if BMConfigParser().get('bitmessagesettings', 'blackwhitelist') == 'white':
|
||||
BMConfigParser().set('bitmessagesettings', 'blackwhitelist', 'black')
|
||||
if BMConfigParser().get(
|
||||
'bitmessagesettings', 'blackwhitelist') == 'white':
|
||||
BMConfigParser().set(
|
||||
'bitmessagesettings', 'blackwhitelist', 'black')
|
||||
BMConfigParser().save()
|
||||
# self.tableWidgetBlacklist.clearContents()
|
||||
self.tableWidgetBlacklist.setRowCount(0)
|
||||
self.rerenderBlackWhiteList()
|
||||
|
||||
def click_radioButtonWhitelist(self):
|
||||
if BMConfigParser().get('bitmessagesettings', 'blackwhitelist') == 'black':
|
||||
BMConfigParser().set('bitmessagesettings', 'blackwhitelist', 'white')
|
||||
if BMConfigParser().get(
|
||||
'bitmessagesettings', 'blackwhitelist') == 'black':
|
||||
BMConfigParser().set(
|
||||
'bitmessagesettings', 'blackwhitelist', 'white')
|
||||
BMConfigParser().save()
|
||||
# self.tableWidgetBlacklist.clearContents()
|
||||
self.tableWidgetBlacklist.setRowCount(0)
|
||||
|
@ -65,16 +71,18 @@ class Blacklist(QtGui.QWidget, RetranslateMixin):
|
|||
# address book. The user cannot add it again or else it will
|
||||
# cause problems when updating and deleting the entry.
|
||||
t = (address,)
|
||||
if BMConfigParser().get('bitmessagesettings', 'blackwhitelist') == 'black':
|
||||
sql = '''select * from blacklist where address=?'''
|
||||
if BMConfigParser().get(
|
||||
'bitmessagesettings', 'blackwhitelist') == 'black':
|
||||
sql = 'SELECT * FROM blacklist WHERE address=?'
|
||||
else:
|
||||
sql = '''select * from whitelist where address=?'''
|
||||
queryreturn = sqlQuery(sql,*t)
|
||||
sql = 'SELECT * FROM whitelist WHERE address=?'
|
||||
queryreturn = sqlQuery(sql, *t)
|
||||
if queryreturn == []:
|
||||
self.tableWidgetBlacklist.setSortingEnabled(False)
|
||||
self.tableWidgetBlacklist.insertRow(0)
|
||||
newItem = QtGui.QTableWidgetItem(unicode(
|
||||
self.NewBlacklistDialogInstance.lineEditLabel.text().toUtf8(), 'utf-8'))
|
||||
self.NewBlacklistDialogInstance.lineEditLabel.text(
|
||||
).toUtf8(), 'utf-8'))
|
||||
newItem.setIcon(avatarize(address))
|
||||
self.tableWidgetBlacklist.setItem(0, 0, newItem)
|
||||
newItem = QtGui.QTableWidgetItem(address)
|
||||
|
@ -82,11 +90,14 @@ class Blacklist(QtGui.QWidget, RetranslateMixin):
|
|||
QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
|
||||
self.tableWidgetBlacklist.setItem(0, 1, newItem)
|
||||
self.tableWidgetBlacklist.setSortingEnabled(True)
|
||||
t = (str(self.NewBlacklistDialogInstance.lineEditLabel.text().toUtf8()), address, True)
|
||||
if BMConfigParser().get('bitmessagesettings', 'blackwhitelist') == 'black':
|
||||
sql = '''INSERT INTO blacklist VALUES (?,?,?)'''
|
||||
t = (str(
|
||||
self.NewBlacklistDialogInstance.lineEditLabel.text(
|
||||
).toUtf8()), address, True)
|
||||
if BMConfigParser().get(
|
||||
'bitmessagesettings', 'blackwhitelist') == 'black':
|
||||
sql = 'INSERT INTO blacklist VALUES (?,?,?)'
|
||||
else:
|
||||
sql = '''INSERT INTO whitelist VALUES (?,?,?)'''
|
||||
sql = 'INSERT INTO whitelist VALUES (?,?,?)'
|
||||
sqlExecute(sql, *t)
|
||||
else:
|
||||
UISignalQueue.put((
|
||||
|
@ -110,42 +121,44 @@ class Blacklist(QtGui.QWidget, RetranslateMixin):
|
|||
addressitem = self.tableWidgetBlacklist.item(item.row(), 1)
|
||||
if isinstance(addressitem, QtGui.QTableWidgetItem):
|
||||
if self.radioButtonBlacklist.isChecked():
|
||||
sqlExecute('''UPDATE blacklist SET label=? WHERE address=?''',
|
||||
str(item.text()), str(addressitem.text()))
|
||||
sqlExecute(
|
||||
'UPDATE blacklist SET label=? WHERE address=?',
|
||||
str(item.text()), str(addressitem.text()))
|
||||
else:
|
||||
sqlExecute('''UPDATE whitelist SET label=? WHERE address=?''',
|
||||
str(item.text()), str(addressitem.text()))
|
||||
sqlExecute(
|
||||
'UPDATE whitelist SET label=? WHERE address=?',
|
||||
str(item.text()), str(addressitem.text()))
|
||||
|
||||
def init_blacklist_popup_menu(self, connectSignal=True):
|
||||
# Popup menu for the Blacklist page
|
||||
self.blacklistContextMenuToolbar = QtGui.QToolBar()
|
||||
# Actions
|
||||
self.actionBlacklistNew = self.blacklistContextMenuToolbar.addAction(
|
||||
_translate(
|
||||
self.actionBlacklistNew = \
|
||||
self.blacklistContextMenuToolbar.addAction(_translate(
|
||||
"MainWindow", "Add new entry"), self.on_action_BlacklistNew)
|
||||
self.actionBlacklistDelete = self.blacklistContextMenuToolbar.addAction(
|
||||
_translate(
|
||||
self.actionBlacklistDelete = \
|
||||
self.blacklistContextMenuToolbar.addAction(_translate(
|
||||
"MainWindow", "Delete"), self.on_action_BlacklistDelete)
|
||||
self.actionBlacklistClipboard = self.blacklistContextMenuToolbar.addAction(
|
||||
_translate(
|
||||
self.actionBlacklistClipboard = \
|
||||
self.blacklistContextMenuToolbar.addAction(_translate(
|
||||
"MainWindow", "Copy address to clipboard"),
|
||||
self.on_action_BlacklistClipboard)
|
||||
self.actionBlacklistEnable = self.blacklistContextMenuToolbar.addAction(
|
||||
_translate(
|
||||
self.on_action_BlacklistClipboard)
|
||||
self.actionBlacklistEnable = \
|
||||
self.blacklistContextMenuToolbar.addAction(_translate(
|
||||
"MainWindow", "Enable"), self.on_action_BlacklistEnable)
|
||||
self.actionBlacklistDisable = self.blacklistContextMenuToolbar.addAction(
|
||||
_translate(
|
||||
self.actionBlacklistDisable = \
|
||||
self.blacklistContextMenuToolbar.addAction(_translate(
|
||||
"MainWindow", "Disable"), self.on_action_BlacklistDisable)
|
||||
self.actionBlacklistSetAvatar = self.blacklistContextMenuToolbar.addAction(
|
||||
_translate(
|
||||
self.actionBlacklistSetAvatar = \
|
||||
self.blacklistContextMenuToolbar.addAction(_translate(
|
||||
"MainWindow", "Set avatar..."),
|
||||
self.on_action_BlacklistSetAvatar)
|
||||
self.on_action_BlacklistSetAvatar)
|
||||
self.tableWidgetBlacklist.setContextMenuPolicy(
|
||||
QtCore.Qt.CustomContextMenu)
|
||||
if connectSignal:
|
||||
self.connect(self.tableWidgetBlacklist, QtCore.SIGNAL(
|
||||
'customContextMenuRequested(const QPoint&)'),
|
||||
self.on_context_menuBlacklist)
|
||||
self.on_context_menuBlacklist)
|
||||
self.popMenuBlacklist = QtGui.QMenu(self)
|
||||
# self.popMenuBlacklist.addAction( self.actionBlacklistNew )
|
||||
self.popMenuBlacklist.addAction(self.actionBlacklistDelete)
|
||||
|
@ -158,16 +171,21 @@ class Blacklist(QtGui.QWidget, RetranslateMixin):
|
|||
|
||||
def rerenderBlackWhiteList(self):
|
||||
tabs = self.parent().parent()
|
||||
if BMConfigParser().get('bitmessagesettings', 'blackwhitelist') == 'black':
|
||||
tabs.setTabText(tabs.indexOf(self), _translate('blacklist', 'Blacklist'))
|
||||
if BMConfigParser().get(
|
||||
'bitmessagesettings', 'blackwhitelist') == 'black':
|
||||
tabs.setTabText(
|
||||
tabs.indexOf(self), _translate('blacklist', 'Blacklist'))
|
||||
else:
|
||||
tabs.setTabText(tabs.indexOf(self), _translate('blacklist', 'Whitelist'))
|
||||
tabs.setTabText(
|
||||
tabs.indexOf(self), _translate('blacklist', 'Whitelist'))
|
||||
self.tableWidgetBlacklist.setRowCount(0)
|
||||
listType = BMConfigParser().get('bitmessagesettings', 'blackwhitelist')
|
||||
if listType == 'black':
|
||||
queryreturn = sqlQuery('''SELECT label, address, enabled FROM blacklist''')
|
||||
queryreturn = sqlQuery(
|
||||
'SELECT label, address, enabled FROM blacklist')
|
||||
else:
|
||||
queryreturn = sqlQuery('''SELECT label, address, enabled FROM whitelist''')
|
||||
queryreturn = sqlQuery(
|
||||
'SELECT label, address, enabled FROM whitelist')
|
||||
self.tableWidgetBlacklist.setSortingEnabled(False)
|
||||
for row in queryreturn:
|
||||
label, address, enabled = row
|
||||
|
@ -195,13 +213,14 @@ class Blacklist(QtGui.QWidget, RetranslateMixin):
|
|||
currentRow, 0).text().toUtf8()
|
||||
addressAtCurrentRow = self.tableWidgetBlacklist.item(
|
||||
currentRow, 1).text()
|
||||
if BMConfigParser().get('bitmessagesettings', 'blackwhitelist') == 'black':
|
||||
if BMConfigParser().get(
|
||||
'bitmessagesettings', 'blackwhitelist') == 'black':
|
||||
sqlExecute(
|
||||
'''DELETE FROM blacklist WHERE label=? AND address=?''',
|
||||
'DELETE FROM blacklist WHERE label=? AND address=?',
|
||||
str(labelAtCurrentRow), str(addressAtCurrentRow))
|
||||
else:
|
||||
sqlExecute(
|
||||
'''DELETE FROM whitelist WHERE label=? AND address=?''',
|
||||
'DELETE FROM whitelist WHERE label=? AND address=?',
|
||||
str(labelAtCurrentRow), str(addressAtCurrentRow))
|
||||
self.tableWidgetBlacklist.removeRow(currentRow)
|
||||
|
||||
|
@ -220,17 +239,18 @@ class Blacklist(QtGui.QWidget, RetranslateMixin):
|
|||
currentRow = self.tableWidgetBlacklist.currentRow()
|
||||
addressAtCurrentRow = self.tableWidgetBlacklist.item(
|
||||
currentRow, 1).text()
|
||||
self.tableWidgetBlacklist.item(
|
||||
currentRow, 0).setTextColor(QtGui.QApplication.palette().text().color())
|
||||
self.tableWidgetBlacklist.item(
|
||||
currentRow, 1).setTextColor(QtGui.QApplication.palette().text().color())
|
||||
if BMConfigParser().get('bitmessagesettings', 'blackwhitelist') == 'black':
|
||||
self.tableWidgetBlacklist.item(currentRow, 0).setTextColor(
|
||||
QtGui.QApplication.palette().text().color())
|
||||
self.tableWidgetBlacklist.item(currentRow, 1).setTextColor(
|
||||
QtGui.QApplication.palette().text().color())
|
||||
if BMConfigParser().get(
|
||||
'bitmessagesettings', 'blackwhitelist') == 'black':
|
||||
sqlExecute(
|
||||
'''UPDATE blacklist SET enabled=1 WHERE address=?''',
|
||||
'UPDATE blacklist SET enabled=1 WHERE address=?',
|
||||
str(addressAtCurrentRow))
|
||||
else:
|
||||
sqlExecute(
|
||||
'''UPDATE whitelist SET enabled=1 WHERE address=?''',
|
||||
'UPDATE whitelist SET enabled=1 WHERE address=?',
|
||||
str(addressAtCurrentRow))
|
||||
|
||||
def on_action_BlacklistDisable(self):
|
||||
|
@ -241,12 +261,15 @@ class Blacklist(QtGui.QWidget, RetranslateMixin):
|
|||
currentRow, 0).setTextColor(QtGui.QColor(128, 128, 128))
|
||||
self.tableWidgetBlacklist.item(
|
||||
currentRow, 1).setTextColor(QtGui.QColor(128, 128, 128))
|
||||
if BMConfigParser().get('bitmessagesettings', 'blackwhitelist') == 'black':
|
||||
if BMConfigParser().get(
|
||||
'bitmessagesettings', 'blackwhitelist') == 'black':
|
||||
sqlExecute(
|
||||
'''UPDATE blacklist SET enabled=0 WHERE address=?''', str(addressAtCurrentRow))
|
||||
'UPDATE blacklist SET enabled=0 WHERE address=?',
|
||||
str(addressAtCurrentRow))
|
||||
else:
|
||||
sqlExecute(
|
||||
'''UPDATE whitelist SET enabled=0 WHERE address=?''', str(addressAtCurrentRow))
|
||||
'UPDATE whitelist SET enabled=0 WHERE address=?',
|
||||
str(addressAtCurrentRow))
|
||||
|
||||
def on_action_BlacklistSetAvatar(self):
|
||||
self.window().on_action_SetAvatar(self.tableWidgetBlacklist)
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
"""
|
||||
Custom dialog classes
|
||||
All dialogs are available in this module.
|
||||
"""
|
||||
# pylint: disable=too-few-public-methods
|
||||
from PyQt4 import QtGui
|
||||
|
||||
import paths
|
||||
import widgets
|
||||
from address_dialogs import (
|
||||
from pybitmessage import paths
|
||||
from pybitmessage.tr import _translate
|
||||
from pybitmessage.version import softwareVersion
|
||||
from .address_dialogs import (
|
||||
AddAddressDialog, EmailGatewayDialog, NewAddressDialog,
|
||||
NewSubscriptionDialog, RegenerateAddressesDialog,
|
||||
SpecialAddressBehaviorDialog
|
||||
)
|
||||
from newchandialog import NewChanDialog
|
||||
from settings import SettingsDialog
|
||||
from tr import _translate
|
||||
from version import softwareVersion
|
||||
from . import widgets
|
||||
from .newchandialog import NewChanDialog
|
||||
from .settings import SettingsDialog
|
||||
|
||||
|
||||
__all__ = [
|
||||
|
@ -26,7 +26,7 @@ __all__ = [
|
|||
|
||||
|
||||
class AboutDialog(QtGui.QDialog):
|
||||
"""The `About` dialog"""
|
||||
"""The "About" dialog"""
|
||||
def __init__(self, parent=None):
|
||||
super(AboutDialog, self).__init__(parent)
|
||||
widgets.load('about.ui', self)
|
||||
|
@ -45,7 +45,7 @@ class AboutDialog(QtGui.QDialog):
|
|||
try:
|
||||
self.label_2.setText(
|
||||
self.label_2.text().replace(
|
||||
'2020', str(last_commit.get('time').year)
|
||||
'2021', str(last_commit.get('time').year)
|
||||
))
|
||||
except AttributeError:
|
||||
pass
|
||||
|
@ -54,7 +54,7 @@ class AboutDialog(QtGui.QDialog):
|
|||
|
||||
|
||||
class IconGlossaryDialog(QtGui.QDialog):
|
||||
"""The `Icon Glossary` dialog, explaining the status icon colors"""
|
||||
"""The "Icon Glossary" dialog, explaining the status icon colors"""
|
||||
def __init__(self, parent=None, config=None):
|
||||
super(IconGlossaryDialog, self).__init__(parent)
|
||||
widgets.load('iconglossary.ui', self)
|
||||
|
@ -70,7 +70,7 @@ class IconGlossaryDialog(QtGui.QDialog):
|
|||
|
||||
|
||||
class HelpDialog(QtGui.QDialog):
|
||||
"""The `Help` dialog"""
|
||||
"""The "Help" dialog"""
|
||||
def __init__(self, parent=None):
|
||||
super(HelpDialog, self).__init__(parent)
|
||||
widgets.load('help.ui', self)
|
||||
|
@ -78,7 +78,7 @@ class HelpDialog(QtGui.QDialog):
|
|||
|
||||
|
||||
class ConnectDialog(QtGui.QDialog):
|
||||
"""The `Connect` dialog"""
|
||||
"""The "Connect" dialog"""
|
||||
def __init__(self, parent=None):
|
||||
super(ConnectDialog, self).__init__(parent)
|
||||
widgets.load('connect.ui', self)
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
"""
|
||||
Folder tree and messagelist widgets definitions.
|
||||
"""
|
||||
# pylint: disable=too-many-arguments,bad-super-call
|
||||
# pylint: disable=too-many-arguments
|
||||
# pylint: disable=attribute-defined-outside-init
|
||||
|
||||
from cgi import escape
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from bmconfigparser import BMConfigParser
|
||||
from helper_sql import sqlExecute, sqlQuery
|
||||
from settingsmixin import SettingsMixin
|
||||
from tr import _translate
|
||||
from utils import avatarize
|
||||
from pybitmessage.bmconfigparser import BMConfigParser
|
||||
from pybitmessage.helper_sql import sqlExecute, sqlQuery
|
||||
from pybitmessage.tr import _translate
|
||||
from .settingsmixin import SettingsMixin
|
||||
from .utils import avatarize
|
||||
|
||||
# for pylupdate
|
||||
_translate("MainWindow", "inbox")
|
||||
|
@ -33,29 +33,29 @@ class AccountMixin(object):
|
|||
BROADCAST = 5
|
||||
|
||||
def accountColor(self):
|
||||
"""QT UI color for an account"""
|
||||
"""Qt UI color for an account"""
|
||||
if not self.isEnabled:
|
||||
return QtGui.QColor(128, 128, 128)
|
||||
elif self.type == self.CHAN:
|
||||
return QtGui.QColor(216, 119, 0)
|
||||
elif self.type in [self.MAILINGLIST, self.SUBSCRIPTION]:
|
||||
elif self.type in (self.MAILINGLIST, self.SUBSCRIPTION):
|
||||
return QtGui.QColor(137, 4, 177)
|
||||
return QtGui.QApplication.palette().text().color()
|
||||
|
||||
def folderColor(self):
|
||||
"""QT UI color for a folder"""
|
||||
"""Qt UI color for a folder"""
|
||||
if not self.parent().isEnabled:
|
||||
return QtGui.QColor(128, 128, 128)
|
||||
return QtGui.QApplication.palette().text().color()
|
||||
|
||||
def accountBrush(self):
|
||||
"""Account brush (for QT UI)"""
|
||||
"""Account brush (for Qt UI)"""
|
||||
brush = QtGui.QBrush(self.accountColor())
|
||||
brush.setStyle(QtCore.Qt.NoBrush)
|
||||
return brush
|
||||
|
||||
def folderBrush(self):
|
||||
"""Folder brush (for QT UI)"""
|
||||
"""Folder brush (for Qt UI)"""
|
||||
brush = QtGui.QBrush(self.folderColor())
|
||||
brush.setStyle(QtCore.Qt.NoBrush)
|
||||
return brush
|
||||
|
@ -87,7 +87,7 @@ class AccountMixin(object):
|
|||
self.emitDataChanged()
|
||||
|
||||
def setEnabled(self, enabled):
|
||||
"""Set account enabled (QT UI)"""
|
||||
"""Set account enabled (Qt UI)"""
|
||||
self.isEnabled = enabled
|
||||
try:
|
||||
self.setExpanded(enabled)
|
||||
|
@ -101,7 +101,7 @@ class AccountMixin(object):
|
|||
self.emitDataChanged()
|
||||
|
||||
def setType(self):
|
||||
"""Set account type (QT UI)"""
|
||||
"""Set account type (Qt UI)"""
|
||||
self.setFlags(self.flags() | QtCore.Qt.ItemIsEditable)
|
||||
if self.address is None:
|
||||
self.type = self.ALL
|
||||
|
@ -111,15 +111,15 @@ class AccountMixin(object):
|
|||
elif BMConfigParser().safeGetBoolean(self.address, 'mailinglist'):
|
||||
self.type = self.MAILINGLIST
|
||||
elif sqlQuery(
|
||||
'''select label from subscriptions where address=?''', self.address):
|
||||
'SELECT label FROM subscriptions WHERE address=?', self.address
|
||||
):
|
||||
self.type = AccountMixin.SUBSCRIPTION
|
||||
else:
|
||||
self.type = self.NORMAL
|
||||
|
||||
def defaultLabel(self):
|
||||
"""Default label (in case no label is set manually)"""
|
||||
queryreturn = None
|
||||
retval = None
|
||||
queryreturn = retval = None
|
||||
if self.type in (
|
||||
AccountMixin.NORMAL,
|
||||
AccountMixin.CHAN, AccountMixin.MAILINGLIST):
|
||||
|
@ -128,15 +128,14 @@ class AccountMixin(object):
|
|||
BMConfigParser().get(self.address, 'label'), 'utf-8')
|
||||
except Exception:
|
||||
queryreturn = sqlQuery(
|
||||
'''select label from addressbook where address=?''', self.address)
|
||||
'SELECT label FROM addressbook WHERE address=?',
|
||||
self.address)
|
||||
elif self.type == AccountMixin.SUBSCRIPTION:
|
||||
queryreturn = sqlQuery(
|
||||
'''select label from subscriptions where address=?''', self.address)
|
||||
if queryreturn is not None:
|
||||
if queryreturn != []:
|
||||
for row in queryreturn:
|
||||
retval, = row
|
||||
retval = unicode(retval, 'utf-8')
|
||||
'SELECT label FROM subscriptions WHERE address=?',
|
||||
self.address)
|
||||
if queryreturn:
|
||||
retval = unicode(queryreturn[-1][0], 'utf-8')
|
||||
elif self.address is None or self.type == AccountMixin.ALL:
|
||||
return unicode(
|
||||
str(_translate("MainWindow", "All accounts")), 'utf-8')
|
||||
|
@ -157,7 +156,7 @@ class BMTreeWidgetItem(QtGui.QTreeWidgetItem, AccountMixin):
|
|||
return " (" + str(self.unreadCount) + ")" if unreadCount else ""
|
||||
|
||||
def data(self, column, role):
|
||||
"""Override internal QT method for returning object data"""
|
||||
"""Override internal Qt method for returning object data"""
|
||||
if column == 0:
|
||||
if role == QtCore.Qt.DisplayRole:
|
||||
return self._getLabel() + self._getAddressBracket(
|
||||
|
@ -190,11 +189,11 @@ class Ui_FolderWidget(BMTreeWidgetItem):
|
|||
return _translate("MainWindow", self.folderName)
|
||||
|
||||
def setFolderName(self, fname):
|
||||
"""Set folder name (for QT UI)"""
|
||||
"""Set folder name (for Qt UI)"""
|
||||
self.folderName = str(fname)
|
||||
|
||||
def data(self, column, role):
|
||||
"""Override internal QT method for returning object data"""
|
||||
"""Override internal Qt method for returning object data"""
|
||||
if column == 0 and role == QtCore.Qt.ForegroundRole:
|
||||
return self.folderBrush()
|
||||
return super(Ui_FolderWidget, self).data(column, role)
|
||||
|
@ -221,7 +220,8 @@ class Ui_FolderWidget(BMTreeWidgetItem):
|
|||
|
||||
class Ui_AddressWidget(BMTreeWidgetItem, SettingsMixin):
|
||||
"""Item in the account/folder tree representing an account"""
|
||||
def __init__(self, parent, pos=0, address=None, unreadCount=0, enabled=True):
|
||||
def __init__(
|
||||
self, parent, pos=0, address=None, unreadCount=0, enabled=True):
|
||||
super(Ui_AddressWidget, self).__init__(
|
||||
parent, pos, address, unreadCount)
|
||||
self.setEnabled(enabled)
|
||||
|
@ -250,7 +250,7 @@ class Ui_AddressWidget(BMTreeWidgetItem, SettingsMixin):
|
|||
return ret
|
||||
|
||||
def data(self, column, role):
|
||||
"""Override internal QT method for returning object data"""
|
||||
"""Override internal Qt method for returning object data"""
|
||||
if column == 0:
|
||||
if role == QtCore.Qt.DecorationRole:
|
||||
return avatarize(
|
||||
|
@ -260,7 +260,10 @@ class Ui_AddressWidget(BMTreeWidgetItem, SettingsMixin):
|
|||
return super(Ui_AddressWidget, self).data(column, role)
|
||||
|
||||
def setData(self, column, role, value):
|
||||
"""Save account label (if you edit in the the UI, this will be triggered and will save it to keys.dat)"""
|
||||
"""
|
||||
Save account label (if you edit in the the UI, this will be
|
||||
triggered and will save it to keys.dat)
|
||||
"""
|
||||
if role == QtCore.Qt.EditRole \
|
||||
and self.type != AccountMixin.SUBSCRIPTION:
|
||||
BMConfigParser().set(
|
||||
|
@ -273,7 +276,7 @@ class Ui_AddressWidget(BMTreeWidgetItem, SettingsMixin):
|
|||
return super(Ui_AddressWidget, self).setData(column, role, value)
|
||||
|
||||
def setAddress(self, address):
|
||||
"""Set address to object (for QT UI)"""
|
||||
"""Set address to object (for Qt UI)"""
|
||||
super(Ui_AddressWidget, self).setAddress(address)
|
||||
self.setData(0, QtCore.Qt.UserRole, self.address)
|
||||
|
||||
|
@ -295,19 +298,21 @@ class Ui_AddressWidget(BMTreeWidgetItem, SettingsMixin):
|
|||
if self._getSortRank() < other._getSortRank() else reverse
|
||||
)
|
||||
|
||||
return super(QtGui.QTreeWidgetItem, self).__lt__(other)
|
||||
return super(Ui_AddressWidget, self).__lt__(other)
|
||||
|
||||
|
||||
class Ui_SubscriptionWidget(Ui_AddressWidget):
|
||||
"""Special treating of subscription addresses"""
|
||||
# pylint: disable=unused-argument
|
||||
def __init__(self, parent, pos=0, address="", unreadCount=0, label="", enabled=True):
|
||||
def __init__(
|
||||
self, parent, pos=0, address="", unreadCount=0, label="", enabled=True
|
||||
):
|
||||
super(Ui_SubscriptionWidget, self).__init__(
|
||||
parent, pos, address, unreadCount, enabled)
|
||||
|
||||
def _getLabel(self):
|
||||
queryreturn = sqlQuery(
|
||||
'''select label from subscriptions where address=?''', self.address)
|
||||
'SELECT label FROM subscriptions WHERE address=?', self.address)
|
||||
if queryreturn != []:
|
||||
for row in queryreturn:
|
||||
retval, = row
|
||||
|
@ -328,7 +333,7 @@ class Ui_SubscriptionWidget(Ui_AddressWidget):
|
|||
else:
|
||||
label = unicode(value, 'utf-8', 'ignore')
|
||||
sqlExecute(
|
||||
'''UPDATE subscriptions SET label=? WHERE address=?''',
|
||||
'UPDATE subscriptions SET label=? WHERE address=?',
|
||||
label, self.address)
|
||||
return super(Ui_SubscriptionWidget, self).setData(column, role, value)
|
||||
|
||||
|
@ -354,7 +359,7 @@ class BMTableWidgetItem(QtGui.QTableWidgetItem, SettingsMixin):
|
|||
self.unread = unread
|
||||
|
||||
def data(self, role):
|
||||
"""Return object data (QT UI)"""
|
||||
"""Return object data (Qt UI)"""
|
||||
if role in (
|
||||
QtCore.Qt.DisplayRole, QtCore.Qt.EditRole, QtCore.Qt.ToolTipRole
|
||||
):
|
||||
|
@ -378,7 +383,7 @@ class BMAddressWidget(BMTableWidgetItem, AccountMixin):
|
|||
return self.label
|
||||
|
||||
def data(self, role):
|
||||
"""Return object data (QT UI)"""
|
||||
"""Return object data (Qt UI)"""
|
||||
if role == QtCore.Qt.ToolTipRole:
|
||||
return self.label + " (" + self.address + ")"
|
||||
elif role == QtCore.Qt.DecorationRole:
|
||||
|
@ -412,10 +417,12 @@ class MessageList_AddressWidget(BMAddressWidget):
|
|||
'utf-8', 'ignore')
|
||||
except:
|
||||
queryreturn = sqlQuery(
|
||||
'''select label from addressbook where address=?''', self.address)
|
||||
'SELECT label FROM addressbook WHERE address=?',
|
||||
self.address)
|
||||
elif self.type == AccountMixin.SUBSCRIPTION:
|
||||
queryreturn = sqlQuery(
|
||||
'''select label from subscriptions where address=?''', self.address)
|
||||
'SELECT label FROM subscriptions WHERE address=?',
|
||||
self.address)
|
||||
if queryreturn:
|
||||
for row in queryreturn:
|
||||
newLabel = unicode(row[0], 'utf-8', 'ignore')
|
||||
|
@ -423,7 +430,7 @@ class MessageList_AddressWidget(BMAddressWidget):
|
|||
self.label = newLabel
|
||||
|
||||
def data(self, role):
|
||||
"""Return object data (QT UI)"""
|
||||
"""Return object data (Qt UI)"""
|
||||
if role == QtCore.Qt.UserRole:
|
||||
return self.address
|
||||
return super(MessageList_AddressWidget, self).data(role)
|
||||
|
@ -438,7 +445,7 @@ class MessageList_AddressWidget(BMAddressWidget):
|
|||
def __lt__(self, other):
|
||||
if isinstance(other, MessageList_AddressWidget):
|
||||
return self.label.lower() < other.label.lower()
|
||||
return super(QtGui.QTableWidgetItem, self).__lt__(other)
|
||||
return super(MessageList_AddressWidget, self).__lt__(other)
|
||||
|
||||
|
||||
class MessageList_SubjectWidget(BMTableWidgetItem):
|
||||
|
@ -452,7 +459,7 @@ class MessageList_SubjectWidget(BMTableWidgetItem):
|
|||
self.subject = subject
|
||||
|
||||
def data(self, role):
|
||||
"""Return object data (QT UI)"""
|
||||
"""Return object data (Qt UI)"""
|
||||
if role == QtCore.Qt.UserRole:
|
||||
return self.subject
|
||||
if role == QtCore.Qt.ToolTipRole:
|
||||
|
@ -463,7 +470,7 @@ class MessageList_SubjectWidget(BMTableWidgetItem):
|
|||
def __lt__(self, other):
|
||||
if isinstance(other, MessageList_SubjectWidget):
|
||||
return self.label.lower() < other.label.lower()
|
||||
return super(QtGui.QTableWidgetItem, self).__lt__(other)
|
||||
return super(MessageList_SubjectWidget, self).__lt__(other)
|
||||
|
||||
|
||||
# In order for the time columns on the Inbox and Sent tabs to be sorted
|
||||
|
@ -525,9 +532,13 @@ class Ui_AddressBookWidgetItem(BMAddressWidget):
|
|||
BMConfigParser().set(self.address, 'label', self.label)
|
||||
BMConfigParser().save()
|
||||
except:
|
||||
sqlExecute('''UPDATE addressbook set label=? WHERE address=?''', self.label, self.address)
|
||||
sqlExecute(
|
||||
'UPDATE addressbook set label=? WHERE address=?',
|
||||
self.label, self.address)
|
||||
elif self.type == AccountMixin.SUBSCRIPTION:
|
||||
sqlExecute('''UPDATE subscriptions set label=? WHERE address=?''', self.label, self.address)
|
||||
sqlExecute(
|
||||
'UPDATE subscriptions set label=? WHERE address=?',
|
||||
self.label, self.address)
|
||||
else:
|
||||
pass
|
||||
return super(Ui_AddressBookWidgetItem, self).setData(role, value)
|
||||
|
@ -577,7 +588,8 @@ class AddressBookCompleter(QtGui.QCompleter):
|
|||
super(AddressBookCompleter, self).__init__()
|
||||
self.cursorPos = -1
|
||||
|
||||
def onCursorPositionChanged(self, oldPos, newPos): # pylint: disable=unused-argument
|
||||
def onCursorPositionChanged(self, oldPos, newPos):
|
||||
# pylint: disable=unused-argument
|
||||
"""Callback for cursor position change"""
|
||||
if oldPos != self.cursorPos:
|
||||
self.cursorPos = -1
|
||||
|
|
|
@ -1,30 +1,32 @@
|
|||
"""Language Box Module for Locale Settings"""
|
||||
# pylint: disable=too-few-public-methods,bad-continuation
|
||||
"""LanguageBox widget is for selecting UI language"""
|
||||
|
||||
import glob
|
||||
import os
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
import paths
|
||||
from bmconfigparser import BMConfigParser
|
||||
from pybitmessage import paths
|
||||
from pybitmessage.bmconfigparser import BMConfigParser
|
||||
from pybitmessage.tr import _translate
|
||||
|
||||
|
||||
# pylint: disable=too-few-public-methods
|
||||
class LanguageBox(QtGui.QComboBox):
|
||||
"""LanguageBox class for Qt UI"""
|
||||
"""A subclass of `QtWidgets.QComboBox` for selecting language"""
|
||||
languageName = {
|
||||
"system": "System Settings", "eo": "Esperanto",
|
||||
"en_pirate": "Pirate English"
|
||||
}
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super(QtGui.QComboBox, self).__init__(parent)
|
||||
super(LanguageBox, self).__init__(parent)
|
||||
self.populate()
|
||||
|
||||
def populate(self):
|
||||
"""Populates drop down list with all available languages."""
|
||||
self.clear()
|
||||
localesPath = os.path.join(paths.codePath(), 'translations')
|
||||
self.addItem(QtGui.QApplication.translate(
|
||||
self.addItem(_translate(
|
||||
"settingsDialog", "System Settings", "system"), "system")
|
||||
self.setCurrentIndex(0)
|
||||
self.setInsertPolicy(QtGui.QComboBox.InsertAlphabetically)
|
||||
|
@ -42,7 +44,7 @@ class LanguageBox(QtGui.QComboBox):
|
|||
locale.nativeLanguageName() or localeShort, localeShort)
|
||||
|
||||
configuredLocale = BMConfigParser().safeGet(
|
||||
'bitmessagesettings', 'userlocale', "system")
|
||||
'bitmessagesettings', 'userlocale', 'system')
|
||||
for i in range(self.count()):
|
||||
if self.itemData(i) == configuredLocale:
|
||||
self.setCurrentIndex(i)
|
||||
|
|
|
@ -1,33 +1,36 @@
|
|||
"""
|
||||
Message editor with a wheel zoom functionality
|
||||
"""
|
||||
# pylint: disable=bad-continuation
|
||||
"""The MessageCompose class definition"""
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from pybitmessage.tr import _translate
|
||||
|
||||
|
||||
class MessageCompose(QtGui.QTextEdit):
|
||||
"""Editor class with wheel zoom functionality"""
|
||||
def __init__(self, parent=0):
|
||||
def __init__(self, parent=None):
|
||||
super(MessageCompose, self).__init__(parent)
|
||||
# we'll deal with this later when we have a new message format
|
||||
self.setAcceptRichText(False)
|
||||
self.defaultFontPointSize = self.currentFont().pointSize()
|
||||
|
||||
def wheelEvent(self, event):
|
||||
"""Mouse wheel scroll event handler"""
|
||||
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
|
||||
):
|
||||
if event.delta() > 0:
|
||||
self.zoomIn(1)
|
||||
else:
|
||||
self.zoomOut(1)
|
||||
zoom = self.currentFont().pointSize() * 100 / self.defaultFontPointSize
|
||||
QtGui.QApplication.activeWindow().statusBar().showMessage(
|
||||
QtGui.QApplication.translate("MainWindow", "Zoom level %1%").arg(
|
||||
str(zoom)
|
||||
)
|
||||
)
|
||||
_translate("MainWindow", "Zoom level %1%").arg(str(
|
||||
# zoom percentage
|
||||
self.currentFont().pointSize() * 100
|
||||
/ self.defaultFontPointSize
|
||||
)))
|
||||
else:
|
||||
# in QTextEdit, super does not zoom, only scroll
|
||||
super(MessageCompose, self).wheelEvent(event)
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
"""
|
||||
Custom message viewer with support for switching between HTML and plain
|
||||
text rendering, HTML sanitization, lazy rendering (as you scroll down),
|
||||
zoom and URL click warning popup
|
||||
|
||||
zoom and URL click warning popup.
|
||||
"""
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from safehtmlparser import SafeHTMLParser
|
||||
from tr import _translate
|
||||
from pybitmessage.tr import _translate
|
||||
from .safehtmlparser import SafeHTMLParser
|
||||
|
||||
|
||||
class MessageView(QtGui.QTextBrowser):
|
||||
|
@ -16,7 +15,7 @@ class MessageView(QtGui.QTextBrowser):
|
|||
MODE_PLAIN = 0
|
||||
MODE_HTML = 1
|
||||
|
||||
def __init__(self, parent=0):
|
||||
def __init__(self, parent=None):
|
||||
super(MessageView, self).__init__(parent)
|
||||
self.mode = MessageView.MODE_PLAIN
|
||||
self.html = None
|
||||
|
@ -38,8 +37,11 @@ class MessageView(QtGui.QTextBrowser):
|
|||
|
||||
def mousePressEvent(self, event):
|
||||
"""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 (
|
||||
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:
|
||||
|
@ -61,9 +63,7 @@ class MessageView(QtGui.QTextBrowser):
|
|||
def setWrappingWidth(self, width=None):
|
||||
"""Set word-wrapping width"""
|
||||
self.setLineWrapMode(QtGui.QTextEdit.FixedPixelWidth)
|
||||
if width is None:
|
||||
width = self.width()
|
||||
self.setLineWrapColumnOrWidth(width)
|
||||
self.setLineWrapColumnOrWidth(width or self.width())
|
||||
|
||||
def confirmURL(self, link):
|
||||
"""Show a dialog requesting URL opening confirmation"""
|
||||
|
@ -84,14 +84,13 @@ class MessageView(QtGui.QTextBrowser):
|
|||
window.ui.textEditMessage.setFocus()
|
||||
return
|
||||
reply = QtGui.QMessageBox.warning(
|
||||
self,
|
||||
QtGui.QApplication.translate(
|
||||
self, _translate("MessageView", "Follow external link"),
|
||||
_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())),
|
||||
"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:
|
||||
|
@ -99,15 +98,15 @@ class MessageView(QtGui.QTextBrowser):
|
|||
|
||||
def loadResource(self, restype, name):
|
||||
"""
|
||||
Callback for loading referenced objects, such as an image. For security reasons at the moment doesn't do
|
||||
anything)
|
||||
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.
|
||||
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
|
||||
|
@ -123,7 +122,8 @@ class MessageView(QtGui.QTextBrowser):
|
|||
pos = self.out.find(">", self.outpos)
|
||||
if pos > self.outpos:
|
||||
self.outpos = pos + 1
|
||||
cursor.movePosition(QtGui.QTextCursor.End, QtGui.QTextCursor.MoveAnchor)
|
||||
cursor.movePosition(
|
||||
QtGui.QTextCursor.End, QtGui.QTextCursor.MoveAnchor)
|
||||
cursor.insertHtml(QtCore.QString(self.out[startpos:self.outpos]))
|
||||
self.verticalScrollBar().setValue(position)
|
||||
self.rendering = False
|
||||
|
@ -133,9 +133,11 @@ class MessageView(QtGui.QTextBrowser):
|
|||
self.mode = MessageView.MODE_PLAIN
|
||||
out = self.html.raw
|
||||
if self.html.has_html:
|
||||
out = "<div align=\"center\" style=\"text-decoration: underline;\"><b>" + unicode(
|
||||
QtGui.QApplication.translate(
|
||||
"MessageView", "HTML detected, click here to display")) + "</b></div><br/>" + out
|
||||
out = (
|
||||
'<div align="center" style="text-decoration: underline;"><b>'
|
||||
+ _translate(
|
||||
"MessageView", "HTML detected, click here to display"
|
||||
) + '</b></div><br/>' + out)
|
||||
self.out = out
|
||||
self.outpos = 0
|
||||
self.setHtml("")
|
||||
|
@ -145,9 +147,10 @@ class MessageView(QtGui.QTextBrowser):
|
|||
"""Render message as HTML"""
|
||||
self.mode = MessageView.MODE_HTML
|
||||
out = self.html.sanitised
|
||||
out = "<div align=\"center\" style=\"text-decoration: underline;\"><b>" + unicode(
|
||||
QtGui.QApplication.translate("MessageView", "Click here to disable HTML")) + "</b></div><br/>" + out
|
||||
self.out = out
|
||||
self.out = (
|
||||
'<div align="center" style="text-decoration: underline;"><b>'
|
||||
+ _translate("MessageView", "Click here to disable HTML")
|
||||
+ '</b></div><br/>' + self.html.sanitised)
|
||||
self.outpos = 0
|
||||
self.setHtml("")
|
||||
self.lazyRender()
|
||||
|
|
|
@ -6,15 +6,13 @@ import time
|
|||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
import l10n
|
||||
import network.stats
|
||||
import state
|
||||
import widgets
|
||||
from inventory import Inventory
|
||||
from network import BMConnectionPool, knownnodes
|
||||
from retranslateui import RetranslateMixin
|
||||
from tr import _translate
|
||||
from uisignaler import UISignaler
|
||||
from pybitmessage import l10n, state
|
||||
from pybitmessage.inventory import Inventory
|
||||
from pybitmessage.network import BMConnectionPool, knownnodes, stats
|
||||
from pybitmessage.tr import _translate
|
||||
from . import widgets
|
||||
from .retranslateui import RetranslateMixin
|
||||
from .uisignaler import UISignaler
|
||||
|
||||
|
||||
class NetworkStatus(QtGui.QWidget, RetranslateMixin):
|
||||
|
@ -58,20 +56,15 @@ class NetworkStatus(QtGui.QWidget, RetranslateMixin):
|
|||
"""Stop counter update timer"""
|
||||
self.timer.stop()
|
||||
|
||||
@staticmethod
|
||||
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",
|
||||
]:
|
||||
for x in (
|
||||
_translate("networkstatus", "byte(s)", None, num),
|
||||
_translate("networkstatus", "kB"),
|
||||
_translate("networkstatus", "MB"),
|
||||
_translate("networkstatus", "GB")
|
||||
):
|
||||
if num < 1000.0:
|
||||
return "%3.0f %s" % (num, x)
|
||||
num /= 1000.0
|
||||
|
@ -85,64 +78,44 @@ class NetworkStatus(QtGui.QWidget, RetranslateMixin):
|
|||
|
||||
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()))
|
||||
self.labelSyncStatus.setText(_translate(
|
||||
"networkstatus", "Object(s) to be synced: %n", None,
|
||||
stats.pendingDownload() + 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,
|
||||
state.numberOfMessagesProcessed))
|
||||
self.labelMessageCount.setText(_translate(
|
||||
"networkstatus", "Processed %n person-to-person message(s).", None,
|
||||
state.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,
|
||||
state.numberOfBroadcastsProcessed))
|
||||
self.labelBroadcastCount.setText(_translate(
|
||||
"networkstatus", "Processed %n broadcast message(s).", None,
|
||||
state.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,
|
||||
state.numberOfPubkeysProcessed))
|
||||
self.labelPubkeyCount.setText(_translate(
|
||||
"networkstatus", "Processed %n public key(s).", None,
|
||||
state.numberOfPubkeysProcessed))
|
||||
|
||||
def updateNumberOfBytes(self):
|
||||
"""
|
||||
This function is run every two seconds, so we divide the rate of bytes
|
||||
sent and received by 2.
|
||||
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(stats.downloadSpeed()),
|
||||
self.formatBytes(stats.receivedBytes())))
|
||||
self.labelBytesSentCount.setText(_translate(
|
||||
"networkstatus", "Up: %1/s Total: %2").arg(
|
||||
self.formatByteRate(stats.uploadSpeed()),
|
||||
self.formatBytes(stats.sentBytes())))
|
||||
|
||||
def updateNetworkStatusTab(self, outbound, add, destination):
|
||||
"""Add or remove an entry to the list of connected peers"""
|
||||
|
@ -170,7 +143,8 @@ class NetworkStatus(QtGui.QWidget, RetranslateMixin):
|
|||
self.tableWidgetConnectionCount.insertRow(0)
|
||||
self.tableWidgetConnectionCount.setItem(
|
||||
0, 0,
|
||||
QtGui.QTableWidgetItem("%s:%i" % (destination.host, destination.port))
|
||||
QtGui.QTableWidgetItem("%s:%i" % (
|
||||
destination.host, destination.port))
|
||||
)
|
||||
self.tableWidgetConnectionCount.setItem(
|
||||
0, 2,
|
||||
|
@ -186,7 +160,8 @@ class NetworkStatus(QtGui.QWidget, RetranslateMixin):
|
|||
)
|
||||
try:
|
||||
# .. todo:: FIXME: hard coded stream no
|
||||
rating = "%.1f" % (knownnodes.knownNodes[1][destination]['rating'])
|
||||
rating = "%.1f" % (
|
||||
knownnodes.knownNodes[1][destination]['rating'])
|
||||
except KeyError:
|
||||
rating = "-"
|
||||
self.tableWidgetConnectionCount.setItem(
|
||||
|
@ -217,18 +192,20 @@ class NetworkStatus(QtGui.QWidget, RetranslateMixin):
|
|||
_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 state.statusIconColor == 'red':
|
||||
self.window().setStatusIcon('yellow')
|
||||
elif self.tableWidgetConnectionCount.rowCount() == 0 and state.statusIconColor != "red":
|
||||
# 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():
|
||||
if state.statusIconColor == 'red':
|
||||
self.window().setStatusIcon('yellow')
|
||||
elif state.statusIconColor != "red":
|
||||
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(
|
||||
self.labelLookupsPerSecond.setText(_translate(
|
||||
"networkstatus", "Inventory lookups per second: %1").arg(
|
||||
str(Inventory().numberOfInventoryLookupsPerformed / 2)))
|
||||
Inventory().numberOfInventoryLookupsPerformed = 0
|
||||
self.updateNumberOfBytes()
|
||||
|
@ -237,10 +214,9 @@ class NetworkStatus(QtGui.QWidget, RetranslateMixin):
|
|||
def retranslateUi(self):
|
||||
"""Conventional Qt Designer method for dynamic l10n"""
|
||||
super(NetworkStatus, self).retranslateUi()
|
||||
self.labelTotalConnections.setText(
|
||||
_translate(
|
||||
"networkstatus", "Total Connections: %1").arg(
|
||||
str(self.tableWidgetConnectionCount.rowCount())))
|
||||
self.labelTotalConnections.setText(_translate(
|
||||
"networkstatus", "Total Connections: %1").arg(
|
||||
str(self.tableWidgetConnectionCount.rowCount())))
|
||||
self.labelStartupTime.setText(_translate(
|
||||
"networkstatus", "Since startup on %1"
|
||||
).arg(l10n.formatTimestamp(self.startup)))
|
||||
|
|
|
@ -1,40 +1,30 @@
|
|||
"""
|
||||
src/bitmessageqt/newchandialog.py
|
||||
=================================
|
||||
|
||||
NewChanDialog class definition
|
||||
"""
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
import widgets
|
||||
from addresses import addBMIfNotPresent
|
||||
from addressvalidator import AddressValidator, PassPhraseValidator
|
||||
from queues import (
|
||||
from pybitmessage.addresses import addBMIfNotPresent
|
||||
from pybitmessage.queues import (
|
||||
addressGeneratorQueue, apiAddressGeneratorReturnQueue, UISignalQueue)
|
||||
from tr import _translate
|
||||
from utils import str_chan
|
||||
from pybitmessage.tr import _translate
|
||||
from . import widgets
|
||||
from .addressvalidator import AddressValidator, PassPhraseValidator
|
||||
from .utils import str_chan
|
||||
|
||||
|
||||
class NewChanDialog(QtGui.QDialog):
|
||||
"""The `New Chan` dialog"""
|
||||
"""The "New Chan" dialog"""
|
||||
def __init__(self, parent=None):
|
||||
super(NewChanDialog, self).__init__(parent)
|
||||
widgets.load('newchandialog.ui', self)
|
||||
self.parent = parent
|
||||
self.chanAddress.setValidator(
|
||||
AddressValidator(
|
||||
self.chanAddress,
|
||||
self.chanPassPhrase,
|
||||
self.validatorFeedback,
|
||||
self.buttonBox,
|
||||
False))
|
||||
self.chanPassPhrase.setValidator(
|
||||
PassPhraseValidator(
|
||||
self.chanPassPhrase,
|
||||
self.chanAddress,
|
||||
self.validatorFeedback,
|
||||
self.buttonBox,
|
||||
False))
|
||||
self.chanAddress.setValidator(AddressValidator(
|
||||
self.chanAddress, self.chanPassPhrase, self.validatorFeedback,
|
||||
self.buttonBox, False))
|
||||
self.chanPassPhrase.setValidator(PassPhraseValidator(
|
||||
self.chanPassPhrase, self.chanAddress, self.validatorFeedback,
|
||||
self.buttonBox, False))
|
||||
|
||||
self.timer = QtCore.QTimer()
|
||||
QtCore.QObject.connect( # pylint: disable=no-member
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
from os import path
|
||||
|
||||
from PyQt4 import QtGui
|
||||
from debug import logger
|
||||
import widgets
|
||||
|
||||
from . import widgets
|
||||
|
||||
|
||||
class RetranslateMixin(object):
|
||||
def retranslateUi(self):
|
||||
|
@ -12,7 +13,9 @@ class RetranslateMixin(object):
|
|||
if callable(setTextMethod):
|
||||
getattr(self, attr).setText(getattr(defaults, attr).text())
|
||||
elif isinstance(value, QtGui.QTableWidget):
|
||||
for i in range (value.columnCount()):
|
||||
getattr(self, attr).horizontalHeaderItem(i).setText(getattr(defaults, attr).horizontalHeaderItem(i).text())
|
||||
for i in range (value.rowCount()):
|
||||
getattr(self, attr).verticalHeaderItem(i).setText(getattr(defaults, attr).verticalHeaderItem(i).text())
|
||||
for i in range(value.columnCount()):
|
||||
getattr(self, attr).horizontalHeaderItem(i).setText(
|
||||
getattr(defaults, attr).horizontalHeaderItem(i).text())
|
||||
for i in range(value.rowCount()):
|
||||
getattr(self, attr).verticalHeaderItem(i).setText(
|
||||
getattr(defaults, attr).verticalHeaderItem(i).text())
|
||||
|
|
|
@ -8,20 +8,15 @@ import tempfile
|
|||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
import debug
|
||||
import defaults
|
||||
import namecoin
|
||||
import openclpow
|
||||
import paths
|
||||
import queues
|
||||
import state
|
||||
import widgets
|
||||
from bmconfigparser import BMConfigParser
|
||||
from helper_sql import sqlExecute, sqlStoredProcedure
|
||||
from helper_startup import start_proxyconfig
|
||||
from network import knownnodes, AnnounceThread
|
||||
from network.asyncore_pollchoose import set_rates
|
||||
from tr import _translate
|
||||
from pybitmessage import (
|
||||
debug, defaults, namecoin, openclpow, paths, queues, state)
|
||||
from pybitmessage.bmconfigparser import BMConfigParser
|
||||
from pybitmessage.helper_sql import sqlExecute, sqlStoredProcedure
|
||||
from pybitmessage.helper_startup import start_proxyconfig
|
||||
from pybitmessage.network import knownnodes, AnnounceThread
|
||||
from pybitmessage.network.asyncore_pollchoose import set_rates
|
||||
from pybitmessage.tr import _translate
|
||||
from . import widgets
|
||||
|
||||
|
||||
def getSOCKSProxyType(config):
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# pylint: disable=unused-argument
|
||||
"""Status bar Module"""
|
||||
"""BMStatusBar class definition"""
|
||||
|
||||
from time import time
|
||||
|
||||
from PyQt4 import QtGui
|
||||
|
||||
|
||||
|
@ -16,21 +16,26 @@ class BMStatusBar(QtGui.QStatusBar):
|
|||
self.timer = self.startTimer(BMStatusBar.duration)
|
||||
self.iterator = 0
|
||||
|
||||
def timerEvent(self, event):
|
||||
"""an event handler which allows to queue and prioritise messages to
|
||||
def timerEvent(self, event): # pylint: disable=unused-argument
|
||||
"""
|
||||
An event handler which allows to queue and prioritise messages to
|
||||
show in the status bar, for example if many messages come very quickly
|
||||
after one another, it adds delays and so on"""
|
||||
after one another, it adds delays and so on.
|
||||
"""
|
||||
while len(self.important) > 0:
|
||||
self.iterator += 1
|
||||
try:
|
||||
if time() > self.important[self.iterator][1] + BMStatusBar.deleteAfter:
|
||||
if (
|
||||
self.important[self.iterator][1]
|
||||
+ BMStatusBar.deleteAfter < time()
|
||||
):
|
||||
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)
|
||||
self.showMessage(self.important[self.iterator][0], 0)
|
||||
break
|
||||
|
||||
def addImportant(self, message):
|
||||
|
|
|
@ -1,29 +1,25 @@
|
|||
"""Composing support request message functions."""
|
||||
# pylint: disable=no-member
|
||||
|
||||
import ctypes
|
||||
import os
|
||||
import ssl
|
||||
import sys
|
||||
import time
|
||||
|
||||
from PyQt4 import QtCore
|
||||
|
||||
import account
|
||||
import defaults
|
||||
import network.stats
|
||||
import paths
|
||||
import proofofwork
|
||||
import queues
|
||||
import state
|
||||
from bmconfigparser import BMConfigParser
|
||||
from foldertree import AccountMixin
|
||||
from helper_sql import sqlExecute, sqlQuery
|
||||
from l10n import getTranslationLanguage
|
||||
from openclpow import openclEnabled
|
||||
from pyelliptic.openssl import OpenSSL
|
||||
from settings import getSOCKSProxyType
|
||||
from version import softwareVersion
|
||||
from tr import _translate
|
||||
from pybitmessage import defaults, paths, proofofwork, queues, state
|
||||
from pybitmessage.bmconfigparser import BMConfigParser
|
||||
from pybitmessage.helper_sql import sqlExecute, sqlQuery
|
||||
from pybitmessage.l10n import getTranslationLanguage
|
||||
from pybitmessage.network import stats
|
||||
from pybitmessage.openclpow import openclEnabled
|
||||
from pybitmessage.pyelliptic.openssl import OpenSSL
|
||||
from pybitmessage.tr import _translate
|
||||
from pybitmessage.version import softwareVersion
|
||||
from . import account
|
||||
from .foldertree import AccountMixin
|
||||
from .settings import getSOCKSProxyType
|
||||
|
||||
|
||||
# this is BM support address going to Peter Surda
|
||||
|
@ -31,7 +27,7 @@ OLD_SUPPORT_ADDRESS = 'BM-2cTkCtMYkrSPwFTpgcBrMrf5d8oZwvMZWK'
|
|||
SUPPORT_ADDRESS = 'BM-2cUdgkDDAahwPAU6oD2A7DnjqZz3hgY832'
|
||||
SUPPORT_LABEL = _translate("Support", "PyBitmessage support")
|
||||
SUPPORT_MY_LABEL = _translate("Support", "My new address")
|
||||
SUPPORT_SUBJECT = 'Support request'
|
||||
SUPPORT_SUBJECT = _translate("Support", "Support request")
|
||||
SUPPORT_MESSAGE = _translate("Support", '''
|
||||
You can use this message to send a report to one of the PyBitmessage core \
|
||||
developers regarding PyBitmessage or the mailchuck.com email service. \
|
||||
|
@ -67,8 +63,12 @@ Connected hosts: {}
|
|||
|
||||
|
||||
def checkAddressBook(myapp):
|
||||
"""
|
||||
Add "PyBitmessage support" address to address book, remove old one if found.
|
||||
"""
|
||||
sqlExecute('DELETE from addressbook WHERE address=?', OLD_SUPPORT_ADDRESS)
|
||||
queryreturn = sqlQuery('SELECT * FROM addressbook WHERE address=?', SUPPORT_ADDRESS)
|
||||
queryreturn = sqlQuery(
|
||||
'SELECT * FROM addressbook WHERE address=?', SUPPORT_ADDRESS)
|
||||
if queryreturn == []:
|
||||
sqlExecute(
|
||||
'INSERT INTO addressbook VALUES (?,?)',
|
||||
|
@ -77,14 +77,17 @@ def checkAddressBook(myapp):
|
|||
|
||||
|
||||
def checkHasNormalAddress():
|
||||
"""Returns first enabled normal address or False if not found."""
|
||||
for address in account.getSortedAccounts():
|
||||
acct = account.accountClass(address)
|
||||
if acct.type == AccountMixin.NORMAL and BMConfigParser().safeGetBoolean(address, 'enabled'):
|
||||
if acct.type == AccountMixin.NORMAL and BMConfigParser().safeGetBoolean(
|
||||
address, 'enabled'):
|
||||
return address
|
||||
return False
|
||||
|
||||
|
||||
def createAddressIfNeeded(myapp):
|
||||
"""Checks if user has any anabled normal address, creates new one if no."""
|
||||
if not checkHasNormalAddress():
|
||||
queues.addressGeneratorQueue.put((
|
||||
'createRandomAddress', 4, 1,
|
||||
|
@ -100,6 +103,9 @@ def createAddressIfNeeded(myapp):
|
|||
|
||||
|
||||
def createSupportMessage(myapp):
|
||||
"""
|
||||
Prepare the support request message and switch to tab "Send"
|
||||
"""
|
||||
checkAddressBook(myapp)
|
||||
address = createAddressIfNeeded(myapp)
|
||||
if state.shutdown:
|
||||
|
@ -119,15 +125,12 @@ def createSupportMessage(myapp):
|
|||
if commit:
|
||||
version += " GIT " + commit
|
||||
|
||||
os = sys.platform
|
||||
if os == "win32":
|
||||
windowsversion = sys.getwindowsversion()
|
||||
os = "Windows " + str(windowsversion[0]) + "." + str(windowsversion[1])
|
||||
if sys.platform.startswith("win"):
|
||||
# pylint: disable=no-member
|
||||
osname = "Windows %s.%s" % sys.getwindowsversion()[:2]
|
||||
else:
|
||||
try:
|
||||
from os import uname
|
||||
unixversion = uname()
|
||||
os = unixversion[0] + " " + unixversion[2]
|
||||
osname = '{0} {2}'.format(*os.uname())
|
||||
except:
|
||||
pass
|
||||
architecture = "32" if ctypes.sizeof(ctypes.c_voidp) == 4 else "64"
|
||||
|
@ -139,15 +142,15 @@ def createSupportMessage(myapp):
|
|||
frozen = "N/A"
|
||||
if paths.frozen:
|
||||
frozen = paths.frozen
|
||||
portablemode = "True" if state.appdata == paths.lookupExeFolder() else "False"
|
||||
portablemode = str(state.appdata == paths.lookupExeFolder())
|
||||
cpow = "True" if proofofwork.bmpow else "False"
|
||||
openclpow = str(
|
||||
BMConfigParser().safeGet('bitmessagesettings', 'opencl')
|
||||
) if openclEnabled() else "None"
|
||||
locale = getTranslationLanguage()
|
||||
socks = getSOCKSProxyType(BMConfigParser()) or "N/A"
|
||||
upnp = BMConfigParser().safeGet('bitmessagesettings', 'upnp', "N/A")
|
||||
connectedhosts = len(network.stats.connectedHostsList())
|
||||
socks = getSOCKSProxyType(BMConfigParser()) or 'N/A'
|
||||
upnp = BMConfigParser().safeGet('bitmessagesettings', 'upnp', 'N/A')
|
||||
connectedhosts = len(stats.connectedHostsList())
|
||||
|
||||
myapp.ui.textEditMessage.setText(unicode(SUPPORT_MESSAGE, 'utf-8').format(
|
||||
version, os, architecture, pythonversion, opensslversion, frozen,
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
|
||||
from PyQt4.QtCore import QThread, SIGNAL
|
||||
import sys
|
||||
|
||||
import queues
|
||||
from PyQt4.QtCore import QThread, SIGNAL
|
||||
|
||||
from pybitmessage import queues
|
||||
|
||||
|
||||
class UISignaler(QThread):
|
||||
|
|
|
@ -3,9 +3,9 @@ import os
|
|||
|
||||
from PyQt4 import QtGui
|
||||
|
||||
import state
|
||||
from addresses import addBMIfNotPresent
|
||||
from bmconfigparser import BMConfigParser
|
||||
from pybitmessage import state
|
||||
from pybitmessage.addresses import addBMIfNotPresent
|
||||
from pybitmessage.bmconfigparser import BMConfigParser
|
||||
|
||||
str_broadcast_subscribers = '[Broadcast subscribers]'
|
||||
str_chan = '[chan]'
|
||||
|
|
|
@ -1,13 +1,18 @@
|
|||
from PyQt4 import uic
|
||||
|
||||
import os.path
|
||||
import paths
|
||||
import sys
|
||||
|
||||
from PyQt4 import uic
|
||||
|
||||
from pybitmessage import paths
|
||||
|
||||
|
||||
def resource_path(resFile):
|
||||
baseDir = paths.codePath()
|
||||
for subDir in ["ui", "bitmessageqt"]:
|
||||
if os.path.isdir(os.path.join(baseDir, subDir)) and os.path.isfile(os.path.join(baseDir, subDir, resFile)):
|
||||
return os.path.join(baseDir, subDir, resFile)
|
||||
for subDir in ("ui", "bitmessageqt"):
|
||||
path = os.path.join(baseDir, subDir, resFile)
|
||||
if os.path.isfile(path):
|
||||
return path
|
||||
|
||||
|
||||
def load(resFile, widget):
|
||||
uic.loadUi(resource_path(resFile), widget)
|
||||
|
|
|
@ -10,8 +10,8 @@ from datetime import datetime
|
|||
from six import string_types
|
||||
from six.moves import configparser
|
||||
|
||||
import state
|
||||
from singleton import Singleton
|
||||
from . import state
|
||||
from .singleton import Singleton
|
||||
|
||||
SafeConfigParser = configparser.SafeConfigParser
|
||||
|
||||
|
|
|
@ -5,18 +5,14 @@ import hashlib
|
|||
import time
|
||||
from binascii import hexlify
|
||||
|
||||
import defaults
|
||||
import highlevelcrypto
|
||||
import queues
|
||||
import shared
|
||||
import state
|
||||
import tr
|
||||
from addresses import decodeAddress, encodeAddress, encodeVarint
|
||||
from bmconfigparser import BMConfigParser
|
||||
from fallback import RIPEMD160Hash
|
||||
from network import StoppableThread
|
||||
from pyelliptic import arithmetic
|
||||
from pyelliptic.openssl import OpenSSL
|
||||
from . import defaults, highlevelcrypto, queues, shared, state
|
||||
from .addresses import decodeAddress, encodeAddress, encodeVarint
|
||||
from .bmconfigparser import BMConfigParser
|
||||
from .fallback import RIPEMD160Hash
|
||||
from .network import StoppableThread
|
||||
from .pyelliptic import arithmetic
|
||||
from .pyelliptic.openssl import OpenSSL
|
||||
from .tr import _translate
|
||||
|
||||
|
||||
class addressGenerator(StoppableThread):
|
||||
|
@ -120,7 +116,7 @@ class addressGenerator(StoppableThread):
|
|||
if command == 'createRandomAddress':
|
||||
queues.UISignalQueue.put((
|
||||
'updateStatusBar',
|
||||
tr._translate(
|
||||
_translate(
|
||||
"MainWindow", "Generating one new address")
|
||||
))
|
||||
# This next section is a little bit strange. We're going
|
||||
|
@ -199,7 +195,7 @@ class addressGenerator(StoppableThread):
|
|||
|
||||
queues.UISignalQueue.put((
|
||||
'updateStatusBar',
|
||||
tr._translate(
|
||||
_translate(
|
||||
"MainWindow",
|
||||
"Done generating address. Doing work necessary"
|
||||
" to broadcast it...")
|
||||
|
@ -214,9 +210,10 @@ class addressGenerator(StoppableThread):
|
|||
queues.workerQueue.put((
|
||||
'sendOutOrStoreMyV4Pubkey', address))
|
||||
|
||||
elif command == 'createDeterministicAddresses' \
|
||||
or command == 'getDeterministicAddress' \
|
||||
or command == 'createChan' or command == 'joinChan':
|
||||
elif command in (
|
||||
'createDeterministicAddresses', 'getDeterministicAddress',
|
||||
'createChan', 'joinChan'
|
||||
):
|
||||
if not deterministicPassphrase:
|
||||
self.logger.warning(
|
||||
'You are creating deterministic'
|
||||
|
@ -225,7 +222,7 @@ class addressGenerator(StoppableThread):
|
|||
if command == 'createDeterministicAddresses':
|
||||
queues.UISignalQueue.put((
|
||||
'updateStatusBar',
|
||||
tr._translate(
|
||||
_translate(
|
||||
"MainWindow",
|
||||
"Generating %1 new addresses."
|
||||
).arg(str(numberOfAddressesToMake))
|
||||
|
@ -248,12 +245,12 @@ class addressGenerator(StoppableThread):
|
|||
while True:
|
||||
numberOfAddressesWeHadToMakeBeforeWeFoundOneWithTheCorrectRipePrefix += 1
|
||||
potentialPrivSigningKey = hashlib.sha512(
|
||||
deterministicPassphrase +
|
||||
encodeVarint(signingKeyNonce)
|
||||
deterministicPassphrase
|
||||
+ encodeVarint(signingKeyNonce)
|
||||
).digest()[:32]
|
||||
potentialPrivEncryptionKey = hashlib.sha512(
|
||||
deterministicPassphrase +
|
||||
encodeVarint(encryptionKeyNonce)
|
||||
deterministicPassphrase
|
||||
+ encodeVarint(encryptionKeyNonce)
|
||||
).digest()[:32]
|
||||
potentialPubSigningKey = highlevelcrypto.pointMult(
|
||||
potentialPrivSigningKey)
|
||||
|
@ -330,7 +327,7 @@ class addressGenerator(StoppableThread):
|
|||
)
|
||||
queues.UISignalQueue.put((
|
||||
'updateStatusBar',
|
||||
tr._translate(
|
||||
_translate(
|
||||
"MainWindow",
|
||||
"%1 is already in 'Your Identities'."
|
||||
" Not adding it again."
|
||||
|
@ -369,8 +366,8 @@ class addressGenerator(StoppableThread):
|
|||
hexlify(potentialPrivEncryptionKey))
|
||||
shared.myAddressesByHash[ripe] = address
|
||||
tag = hashlib.sha512(hashlib.sha512(
|
||||
encodeVarint(addressVersionNumber) +
|
||||
encodeVarint(streamNumber) + ripe
|
||||
encodeVarint(addressVersionNumber)
|
||||
+ encodeVarint(streamNumber) + ripe
|
||||
).digest()).digest()[32:]
|
||||
shared.myAddressesByTag[tag] = address
|
||||
if addressVersionNumber == 3:
|
||||
|
@ -384,7 +381,7 @@ class addressGenerator(StoppableThread):
|
|||
'sendOutOrStoreMyV4Pubkey', address))
|
||||
queues.UISignalQueue.put((
|
||||
'updateStatusBar',
|
||||
tr._translate(
|
||||
_translate(
|
||||
"MainWindow", "Done generating address")
|
||||
))
|
||||
elif saveAddressToDisk and not live \
|
||||
|
@ -401,6 +398,6 @@ class addressGenerator(StoppableThread):
|
|||
queues.apiAddressGeneratorReturnQueue.put(address)
|
||||
else:
|
||||
raise Exception(
|
||||
"Error in the addressGenerator thread. Thread was" +
|
||||
" given a command it could not understand: " + command)
|
||||
"Error in the addressGenerator thread. Thread was"
|
||||
+ " given a command it could not understand: " + command)
|
||||
queues.addressGeneratorQueue.task_done()
|
||||
|
|
|
@ -12,27 +12,20 @@ import time
|
|||
from binascii import hexlify
|
||||
from subprocess import call # nosec
|
||||
|
||||
import helper_bitcoin
|
||||
import helper_inbox
|
||||
import helper_msgcoding
|
||||
import helper_sent
|
||||
import highlevelcrypto
|
||||
import l10n
|
||||
import protocol
|
||||
import queues
|
||||
import shared
|
||||
import state
|
||||
import tr
|
||||
from addresses import (
|
||||
from . import (
|
||||
helper_bitcoin, helper_inbox, helper_msgcoding, helper_sent,
|
||||
highlevelcrypto, l10n, protocol, queues, shared, state
|
||||
)
|
||||
from .addresses import (
|
||||
calculateInventoryHash, decodeAddress, decodeVarint,
|
||||
encodeAddress, encodeVarint, varintDecodeError
|
||||
)
|
||||
from bmconfigparser import BMConfigParser
|
||||
from fallback import RIPEMD160Hash
|
||||
from helper_sql import sql_ready, SqlBulkExecute, sqlExecute, sqlQuery
|
||||
from network import bmproto, knownnodes
|
||||
from network.node import Peer
|
||||
# pylint: disable=too-many-locals, too-many-return-statements, too-many-branches, too-many-statements
|
||||
from .bmconfigparser import BMConfigParser
|
||||
from .fallback import RIPEMD160Hash
|
||||
from .helper_sql import sql_ready, SqlBulkExecute, sqlExecute, sqlQuery
|
||||
from .network import bmproto, knownnodes
|
||||
from .network.node import Peer
|
||||
from .tr import _translate
|
||||
|
||||
logger = logging.getLogger('default')
|
||||
|
||||
|
@ -150,7 +143,7 @@ class objectProcessor(threading.Thread):
|
|||
'updateSentItemStatusByAckdata',
|
||||
(
|
||||
data[readPosition:],
|
||||
tr._translate(
|
||||
_translate(
|
||||
"MainWindow",
|
||||
"Acknowledgement of the message received %1"
|
||||
).arg(l10n.formatTimestamp())
|
||||
|
@ -763,10 +756,10 @@ class objectProcessor(threading.Thread):
|
|||
# Don't send ACK if invalid, blacklisted senders, invisible
|
||||
# messages, disabled or chan
|
||||
if (
|
||||
self.ackDataHasAValidHeader(ackData) and not blockMessage and
|
||||
messageEncodingType != 0 and
|
||||
not BMConfigParser().safeGetBoolean(toAddress, 'dontsendack') and
|
||||
not BMConfigParser().safeGetBoolean(toAddress, 'chan')
|
||||
self.ackDataHasAValidHeader(ackData) and not blockMessage
|
||||
and messageEncodingType != 0
|
||||
and not BMConfigParser().safeGetBoolean(toAddress, 'dontsendack')
|
||||
and not BMConfigParser().safeGetBoolean(toAddress, 'chan')
|
||||
):
|
||||
self._ack_obj.send_data(ackData[24:])
|
||||
|
||||
|
@ -934,8 +927,8 @@ class objectProcessor(threading.Thread):
|
|||
return
|
||||
elif broadcastVersion == 5:
|
||||
calculatedTag = hashlib.sha512(hashlib.sha512(
|
||||
encodeVarint(sendersAddressVersion) +
|
||||
encodeVarint(sendersStream) + calculatedRipe
|
||||
encodeVarint(sendersAddressVersion)
|
||||
+ encodeVarint(sendersStream) + calculatedRipe
|
||||
).digest()).digest()[32:]
|
||||
if calculatedTag != embeddedTag:
|
||||
logger.debug(
|
||||
|
|
|
@ -23,13 +23,12 @@ import gc
|
|||
import os
|
||||
import time
|
||||
|
||||
import queues
|
||||
import state
|
||||
import tr
|
||||
from bmconfigparser import BMConfigParser
|
||||
from helper_sql import sqlExecute, sqlQuery
|
||||
from inventory import Inventory
|
||||
from network import BMConnectionPool, knownnodes, StoppableThread
|
||||
from . import queues, state
|
||||
from .bmconfigparser import BMConfigParser
|
||||
from .helper_sql import sqlExecute, sqlQuery
|
||||
from .inventory import Inventory
|
||||
from .network import BMConnectionPool, knownnodes, StoppableThread
|
||||
from .tr import _translate
|
||||
|
||||
|
||||
#: Equals 4 weeks. You could make this longer if you want
|
||||
|
@ -121,7 +120,6 @@ class singleCleaner(StoppableThread):
|
|||
# while writing it to disk
|
||||
knownnodes.cleanupKnownNodes()
|
||||
except Exception as err:
|
||||
# pylint: disable=protected-access
|
||||
if "Errno 28" in str(err):
|
||||
self.logger.fatal(
|
||||
'(while writing knownnodes to disk)'
|
||||
|
@ -129,8 +127,8 @@ class singleCleaner(StoppableThread):
|
|||
)
|
||||
queues.UISignalQueue.put((
|
||||
'alert',
|
||||
(tr._translate("MainWindow", "Disk full"),
|
||||
tr._translate(
|
||||
(_translate("MainWindow", "Disk full"),
|
||||
_translate(
|
||||
"MainWindow",
|
||||
'Alert: Your disk or data storage volume'
|
||||
' is full. Bitmessage will now exit.'),
|
||||
|
@ -179,8 +177,8 @@ class singleCleaner(StoppableThread):
|
|||
'Doing work necessary to again attempt to request a public key...'
|
||||
))
|
||||
sqlExecute(
|
||||
'''UPDATE sent SET status='msgqueued' WHERE toaddress=? AND folder='sent' ''',
|
||||
address)
|
||||
"UPDATE sent SET status='msgqueued'"
|
||||
" WHERE toaddress=? AND folder='sent'", address)
|
||||
queues.workerQueue.put(('sendmessage', ''))
|
||||
|
||||
def resendMsg(self, ackdata):
|
||||
|
@ -190,8 +188,8 @@ class singleCleaner(StoppableThread):
|
|||
' to our msg. Sending again.'
|
||||
)
|
||||
sqlExecute(
|
||||
'''UPDATE sent SET status='msgqueued' WHERE ackdata=? AND folder='sent' ''',
|
||||
ackdata)
|
||||
"UPDATE sent SET status='msgqueued'"
|
||||
" WHERE ackdata=? AND folder='sent'", ackdata)
|
||||
queues.workerQueue.put(('sendmessage', ''))
|
||||
queues.UISignalQueue.put((
|
||||
'updateStatusBar',
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
"""
|
||||
Thread for performing PoW
|
||||
"""
|
||||
# pylint: disable=protected-access,too-many-branches,too-many-statements
|
||||
# pylint: disable=too-many-branches,too-many-statements
|
||||
# pylint: disable=no-self-use,too-many-lines,too-many-locals
|
||||
|
||||
from __future__ import division
|
||||
|
@ -12,26 +12,18 @@ from binascii import hexlify, unhexlify
|
|||
from struct import pack
|
||||
from subprocess import call # nosec
|
||||
|
||||
import defaults
|
||||
import helper_inbox
|
||||
import helper_msgcoding
|
||||
import helper_random
|
||||
import helper_sql
|
||||
import highlevelcrypto
|
||||
import l10n
|
||||
import proofofwork
|
||||
import protocol
|
||||
import queues
|
||||
import shared
|
||||
import state
|
||||
import tr
|
||||
from addresses import (
|
||||
from . import (
|
||||
defaults, helper_inbox, helper_msgcoding, helper_random, helper_sql,
|
||||
highlevelcrypto, l10n, proofofwork, protocol, queues, shared, state
|
||||
)
|
||||
from .addresses import (
|
||||
calculateInventoryHash, decodeAddress, decodeVarint, encodeVarint
|
||||
)
|
||||
from bmconfigparser import BMConfigParser
|
||||
from helper_sql import sqlExecute, sqlQuery
|
||||
from inventory import Inventory
|
||||
from network import knownnodes, StoppableThread
|
||||
from .bmconfigparser import BMConfigParser
|
||||
from .helper_sql import sqlExecute, sqlQuery
|
||||
from .inventory import Inventory
|
||||
from .network import knownnodes, StoppableThread
|
||||
from .tr import _translate
|
||||
|
||||
|
||||
def sizeof_fmt(num, suffix='h/s'):
|
||||
|
@ -81,8 +73,8 @@ class singleWorker(StoppableThread):
|
|||
state.neededPubkeys[toAddress] = 0
|
||||
elif toAddressVersionNumber >= 4:
|
||||
doubleHashOfAddressData = hashlib.sha512(hashlib.sha512(
|
||||
encodeVarint(toAddressVersionNumber) +
|
||||
encodeVarint(toStreamNumber) + toRipe
|
||||
encodeVarint(toAddressVersionNumber)
|
||||
+ encodeVarint(toStreamNumber) + toRipe
|
||||
).digest()).digest()
|
||||
# Note that this is the first half of the sha512 hash.
|
||||
privEncryptionKey = doubleHashOfAddressData[:32]
|
||||
|
@ -220,11 +212,11 @@ class singleWorker(StoppableThread):
|
|||
log_time=False):
|
||||
target = 2 ** 64 / (
|
||||
defaults.networkDefaultProofOfWorkNonceTrialsPerByte * (
|
||||
len(payload) + 8 +
|
||||
defaults.networkDefaultPayloadLengthExtraBytes + ((
|
||||
len(payload) + 8
|
||||
+ defaults.networkDefaultPayloadLengthExtraBytes + ((
|
||||
TTL * (
|
||||
len(payload) + 8 +
|
||||
defaults.networkDefaultPayloadLengthExtraBytes
|
||||
len(payload) + 8
|
||||
+ defaults.networkDefaultPayloadLengthExtraBytes
|
||||
)) / (2 ** 16))
|
||||
))
|
||||
initialHash = hashlib.sha512(payload).digest()
|
||||
|
@ -249,8 +241,10 @@ class singleWorker(StoppableThread):
|
|||
return payload
|
||||
|
||||
def doPOWForMyV2Pubkey(self, adressHash):
|
||||
""" This function also broadcasts out the pubkey
|
||||
message once it is done with the POW"""
|
||||
"""
|
||||
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
|
||||
myAddress = shared.myAddressesByHash[adressHash]
|
||||
# status
|
||||
|
@ -306,9 +300,10 @@ class singleWorker(StoppableThread):
|
|||
|
||||
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".
|
||||
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]
|
||||
|
@ -389,9 +384,10 @@ class singleWorker(StoppableThread):
|
|||
|
||||
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.
|
||||
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.
|
||||
|
@ -438,8 +434,8 @@ class singleWorker(StoppableThread):
|
|||
# know which pubkey object to try to decrypt
|
||||
# when they want to send a message.
|
||||
doubleHashOfAddressData = hashlib.sha512(hashlib.sha512(
|
||||
encodeVarint(addressVersionNumber) +
|
||||
encodeVarint(streamNumber) + addressHash
|
||||
encodeVarint(addressVersionNumber)
|
||||
+ encodeVarint(streamNumber) + addressHash
|
||||
).digest()).digest()
|
||||
payload += doubleHashOfAddressData[32:] # the tag
|
||||
signature = highlevelcrypto.sign(
|
||||
|
@ -518,7 +514,10 @@ class singleWorker(StoppableThread):
|
|||
queues.invQueue.put((streamNumber, inventoryHash))
|
||||
|
||||
def sendBroadcast(self):
|
||||
"""Send a broadcast-type object (assemble the object, perform PoW and put it to the inv announcement queue)"""
|
||||
"""
|
||||
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' '''
|
||||
|
@ -550,7 +549,7 @@ class singleWorker(StoppableThread):
|
|||
queues.UISignalQueue.put((
|
||||
'updateSentItemStatusByAckdata', (
|
||||
ackdata,
|
||||
tr._translate(
|
||||
_translate(
|
||||
"MainWindow",
|
||||
"Error! Could not find sender address"
|
||||
" (your address) in the keys.dat file."))
|
||||
|
@ -588,8 +587,8 @@ class singleWorker(StoppableThread):
|
|||
payload += encodeVarint(streamNumber)
|
||||
if addressVersionNumber >= 4:
|
||||
doubleHashOfAddressData = hashlib.sha512(hashlib.sha512(
|
||||
encodeVarint(addressVersionNumber) +
|
||||
encodeVarint(streamNumber) + ripe
|
||||
encodeVarint(addressVersionNumber)
|
||||
+ encodeVarint(streamNumber) + ripe
|
||||
).digest()).digest()
|
||||
tag = doubleHashOfAddressData[32:]
|
||||
payload += tag
|
||||
|
@ -628,8 +627,8 @@ class singleWorker(StoppableThread):
|
|||
# Internet connections and being stored on the disk of 3rd parties.
|
||||
if addressVersionNumber <= 3:
|
||||
privEncryptionKey = hashlib.sha512(
|
||||
encodeVarint(addressVersionNumber) +
|
||||
encodeVarint(streamNumber) + ripe
|
||||
encodeVarint(addressVersionNumber)
|
||||
+ encodeVarint(streamNumber) + ripe
|
||||
).digest()[:32]
|
||||
else:
|
||||
privEncryptionKey = doubleHashOfAddressData[:32]
|
||||
|
@ -641,7 +640,7 @@ class singleWorker(StoppableThread):
|
|||
queues.UISignalQueue.put((
|
||||
'updateSentItemStatusByAckdata', (
|
||||
ackdata,
|
||||
tr._translate(
|
||||
_translate(
|
||||
"MainWindow",
|
||||
"Doing work necessary to send broadcast..."))
|
||||
))
|
||||
|
@ -674,7 +673,7 @@ class singleWorker(StoppableThread):
|
|||
queues.UISignalQueue.put((
|
||||
'updateSentItemStatusByAckdata', (
|
||||
ackdata,
|
||||
tr._translate(
|
||||
_translate(
|
||||
"MainWindow",
|
||||
"Broadcast sent on %1"
|
||||
).arg(l10n.formatTimestamp()))
|
||||
|
@ -689,7 +688,10 @@ class singleWorker(StoppableThread):
|
|||
)
|
||||
|
||||
def sendMsg(self):
|
||||
"""Send a message-type object (assemble the object, perform PoW and put it to the inv announcement queue)"""
|
||||
"""
|
||||
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(
|
||||
|
@ -770,8 +772,8 @@ class singleWorker(StoppableThread):
|
|||
toTag = ''
|
||||
else:
|
||||
toTag = hashlib.sha512(hashlib.sha512(
|
||||
encodeVarint(toAddressVersionNumber) +
|
||||
encodeVarint(toStreamNumber) + toRipe
|
||||
encodeVarint(toAddressVersionNumber)
|
||||
+ encodeVarint(toStreamNumber) + toRipe
|
||||
).digest()).digest()[32:]
|
||||
if toaddress in state.neededPubkeys or \
|
||||
toTag in state.neededPubkeys:
|
||||
|
@ -786,7 +788,7 @@ class singleWorker(StoppableThread):
|
|||
queues.UISignalQueue.put((
|
||||
'updateSentItemStatusByToAddress', (
|
||||
toaddress,
|
||||
tr._translate(
|
||||
_translate(
|
||||
"MainWindow",
|
||||
"Encryption key was requested earlier."))
|
||||
))
|
||||
|
@ -808,7 +810,8 @@ class singleWorker(StoppableThread):
|
|||
if toAddressVersionNumber >= 4:
|
||||
doubleHashOfToAddressData = hashlib.sha512(
|
||||
hashlib.sha512(
|
||||
encodeVarint(toAddressVersionNumber) + encodeVarint(toStreamNumber) + toRipe
|
||||
encodeVarint(toAddressVersionNumber)
|
||||
+ encodeVarint(toStreamNumber) + toRipe
|
||||
).digest()
|
||||
).digest()
|
||||
# The first half of the sha512 hash.
|
||||
|
@ -859,7 +862,7 @@ class singleWorker(StoppableThread):
|
|||
queues.UISignalQueue.put((
|
||||
'updateSentItemStatusByToAddress', (
|
||||
toaddress,
|
||||
tr._translate(
|
||||
_translate(
|
||||
"MainWindow",
|
||||
"Sending a request for the"
|
||||
" recipient\'s encryption key."))
|
||||
|
@ -884,7 +887,7 @@ class singleWorker(StoppableThread):
|
|||
queues.UISignalQueue.put((
|
||||
'updateSentItemStatusByAckdata', (
|
||||
ackdata,
|
||||
tr._translate(
|
||||
_translate(
|
||||
"MainWindow",
|
||||
"Looking up the receiver\'s public key"))
|
||||
))
|
||||
|
@ -942,7 +945,7 @@ class singleWorker(StoppableThread):
|
|||
queues.UISignalQueue.put((
|
||||
'updateSentItemStatusByAckdata', (
|
||||
ackdata,
|
||||
tr._translate(
|
||||
_translate(
|
||||
"MainWindow",
|
||||
"Problem: Destination is a mobile"
|
||||
" device who requests that the"
|
||||
|
@ -973,7 +976,7 @@ class singleWorker(StoppableThread):
|
|||
queues.UISignalQueue.put((
|
||||
'updateSentItemStatusByAckdata', (
|
||||
ackdata,
|
||||
tr._translate(
|
||||
_translate(
|
||||
"MainWindow",
|
||||
"Doing work necessary to send message.\n"
|
||||
"There is no required difficulty for"
|
||||
|
@ -1011,7 +1014,7 @@ class singleWorker(StoppableThread):
|
|||
'updateSentItemStatusByAckdata',
|
||||
(
|
||||
ackdata,
|
||||
tr._translate(
|
||||
_translate(
|
||||
"MainWindow",
|
||||
"Doing work necessary to send message.\n"
|
||||
"Receiver\'s required difficulty: %1"
|
||||
|
@ -1051,7 +1054,7 @@ class singleWorker(StoppableThread):
|
|||
queues.UISignalQueue.put((
|
||||
'updateSentItemStatusByAckdata', (
|
||||
ackdata,
|
||||
tr._translate(
|
||||
_translate(
|
||||
"MainWindow",
|
||||
"Problem: The work demanded by"
|
||||
" the recipient (%1 and %2) is"
|
||||
|
@ -1076,7 +1079,7 @@ class singleWorker(StoppableThread):
|
|||
queues.UISignalQueue.put((
|
||||
'updateSentItemStatusByAckdata', (
|
||||
ackdata,
|
||||
tr._translate(
|
||||
_translate(
|
||||
"MainWindow",
|
||||
"Problem: You are trying to send a"
|
||||
" message to yourself or a chan but your"
|
||||
|
@ -1101,7 +1104,7 @@ class singleWorker(StoppableThread):
|
|||
queues.UISignalQueue.put((
|
||||
'updateSentItemStatusByAckdata', (
|
||||
ackdata,
|
||||
tr._translate(
|
||||
_translate(
|
||||
"MainWindow",
|
||||
"Doing work necessary to send message."))
|
||||
))
|
||||
|
@ -1124,7 +1127,7 @@ class singleWorker(StoppableThread):
|
|||
queues.UISignalQueue.put((
|
||||
'updateSentItemStatusByAckdata', (
|
||||
ackdata,
|
||||
tr._translate(
|
||||
_translate(
|
||||
"MainWindow",
|
||||
"Error! Could not find sender address"
|
||||
" (your address) in the keys.dat file."))
|
||||
|
@ -1200,7 +1203,7 @@ class singleWorker(StoppableThread):
|
|||
queues.UISignalQueue.put((
|
||||
'updateSentItemStatusByAckdata', (
|
||||
ackdata,
|
||||
tr._translate(
|
||||
_translate(
|
||||
"MainWindow",
|
||||
"Problem: The recipient\'s encryption key is"
|
||||
" no good. Could not encrypt message. %1"
|
||||
|
@ -1214,20 +1217,20 @@ class singleWorker(StoppableThread):
|
|||
encryptedPayload += encodeVarint(toStreamNumber) + encrypted
|
||||
target = 2 ** 64 / (
|
||||
requiredAverageProofOfWorkNonceTrialsPerByte * (
|
||||
len(encryptedPayload) + 8 +
|
||||
requiredPayloadLengthExtraBytes + ((
|
||||
len(encryptedPayload) + 8
|
||||
+ requiredPayloadLengthExtraBytes + ((
|
||||
TTL * (
|
||||
len(encryptedPayload) + 8 +
|
||||
requiredPayloadLengthExtraBytes
|
||||
len(encryptedPayload) + 8
|
||||
+ requiredPayloadLengthExtraBytes
|
||||
)) / (2 ** 16))
|
||||
))
|
||||
self.logger.info(
|
||||
'(For msg message) Doing proof of work. Total required'
|
||||
' difficulty: %f. Required small message difficulty: %f.',
|
||||
float(requiredAverageProofOfWorkNonceTrialsPerByte) /
|
||||
defaults.networkDefaultProofOfWorkNonceTrialsPerByte,
|
||||
float(requiredPayloadLengthExtraBytes) /
|
||||
defaults.networkDefaultPayloadLengthExtraBytes
|
||||
float(requiredAverageProofOfWorkNonceTrialsPerByte)
|
||||
/ defaults.networkDefaultProofOfWorkNonceTrialsPerByte,
|
||||
float(requiredPayloadLengthExtraBytes)
|
||||
/ defaults.networkDefaultPayloadLengthExtraBytes
|
||||
)
|
||||
|
||||
powStartTime = time.time()
|
||||
|
@ -1269,7 +1272,7 @@ class singleWorker(StoppableThread):
|
|||
queues.UISignalQueue.put((
|
||||
'updateSentItemStatusByAckdata', (
|
||||
ackdata,
|
||||
tr._translate(
|
||||
_translate(
|
||||
"MainWindow",
|
||||
"Message sent. Sent at %1"
|
||||
).arg(l10n.formatTimestamp()))))
|
||||
|
@ -1278,7 +1281,7 @@ class singleWorker(StoppableThread):
|
|||
queues.UISignalQueue.put((
|
||||
'updateSentItemStatusByAckdata', (
|
||||
ackdata,
|
||||
tr._translate(
|
||||
_translate(
|
||||
"MainWindow",
|
||||
"Message sent. Waiting for acknowledgement."
|
||||
" Sent on %1"
|
||||
|
@ -1369,13 +1372,13 @@ class singleWorker(StoppableThread):
|
|||
|
||||
# Note that this is the first half of the sha512 hash.
|
||||
privEncryptionKey = hashlib.sha512(hashlib.sha512(
|
||||
encodeVarint(addressVersionNumber) +
|
||||
encodeVarint(streamNumber) + ripe
|
||||
encodeVarint(addressVersionNumber)
|
||||
+ encodeVarint(streamNumber) + ripe
|
||||
).digest()).digest()[:32]
|
||||
# Note that this is the second half of the sha512 hash.
|
||||
tag = hashlib.sha512(hashlib.sha512(
|
||||
encodeVarint(addressVersionNumber) +
|
||||
encodeVarint(streamNumber) + ripe
|
||||
encodeVarint(addressVersionNumber)
|
||||
+ encodeVarint(streamNumber) + ripe
|
||||
).digest()).digest()[32:]
|
||||
if tag not in state.neededPubkeys:
|
||||
# We'll need this for when we receive a pubkey reply:
|
||||
|
@ -1412,7 +1415,7 @@ class singleWorker(StoppableThread):
|
|||
queues.UISignalQueue.put((
|
||||
'updateSentItemStatusByToAddress', (
|
||||
toAddress,
|
||||
tr._translate(
|
||||
_translate(
|
||||
"MainWindow",
|
||||
"Doing work necessary to request encryption key."))
|
||||
))
|
||||
|
@ -1437,7 +1440,7 @@ class singleWorker(StoppableThread):
|
|||
|
||||
queues.UISignalQueue.put((
|
||||
'updateStatusBar',
|
||||
tr._translate(
|
||||
_translate(
|
||||
"MainWindow",
|
||||
"Broadcasting the public key request. This program will"
|
||||
" auto-retry if they are offline.")
|
||||
|
@ -1445,7 +1448,7 @@ class singleWorker(StoppableThread):
|
|||
queues.UISignalQueue.put((
|
||||
'updateSentItemStatusByToAddress', (
|
||||
toAddress,
|
||||
tr._translate(
|
||||
_translate(
|
||||
"MainWindow",
|
||||
"Sending public key request. Waiting for reply."
|
||||
" Requested at %1"
|
||||
|
|
|
@ -8,10 +8,9 @@ import urlparse
|
|||
from email.header import Header
|
||||
from email.mime.text import MIMEText
|
||||
|
||||
import queues
|
||||
import state
|
||||
from bmconfigparser import BMConfigParser
|
||||
from network.threads import StoppableThread
|
||||
from . import queues, state
|
||||
from .bmconfigparser import BMConfigParser
|
||||
from .network.threads import StoppableThread
|
||||
|
||||
SMTPDOMAIN = "bmaddr.lan"
|
||||
|
||||
|
|
|
@ -13,13 +13,13 @@ import time
|
|||
from email.header import decode_header
|
||||
from email.parser import Parser
|
||||
|
||||
import queues
|
||||
from addresses import decodeAddress
|
||||
from bmconfigparser import BMConfigParser
|
||||
from helper_ackPayload import genAckPayload
|
||||
from helper_sql import sqlExecute
|
||||
from network.threads import StoppableThread
|
||||
from version import softwareVersion
|
||||
from . import queues
|
||||
from .addresses import decodeAddress
|
||||
from .bmconfigparser import BMConfigParser
|
||||
from .helper_ackPayload import genAckPayload
|
||||
from .helper_sql import sqlExecute
|
||||
from .network.threads import StoppableThread
|
||||
from .version import softwareVersion
|
||||
|
||||
SMTPDOMAIN = "bmaddr.lan"
|
||||
LISTENPORT = 8425
|
||||
|
|
|
@ -9,28 +9,12 @@ import sys
|
|||
import threading
|
||||
import time
|
||||
|
||||
if sys.version_info[0] == 3:
|
||||
from . import helper_sql
|
||||
from . import helper_startup
|
||||
from . import paths
|
||||
from . import queues
|
||||
from . import state
|
||||
from . import tr
|
||||
from .bmconfigparser import BMConfigParser
|
||||
from .debug import logger
|
||||
# pylint: disable=attribute-defined-outside-init,protected-access
|
||||
from .addresses import encodeAddress
|
||||
else:
|
||||
import helper_sql
|
||||
import helper_startup
|
||||
import paths
|
||||
import queues
|
||||
import state
|
||||
import tr
|
||||
from bmconfigparser import BMConfigParser
|
||||
from debug import logger
|
||||
# pylint: disable=attribute-defined-outside-init,protected-access
|
||||
from addresses import encodeAddress
|
||||
from . import helper_sql, helper_startup, paths, queues, state
|
||||
from .addresses import encodeAddress
|
||||
from .bmconfigparser import BMConfigParser
|
||||
from .debug import logger
|
||||
from .tr import _translate
|
||||
# pylint: disable=attribute-defined-outside-init
|
||||
|
||||
|
||||
class sqlThread(threading.Thread):
|
||||
|
@ -450,16 +434,15 @@ class sqlThread(threading.Thread):
|
|||
except Exception as err:
|
||||
if str(err) == 'database or disk is full':
|
||||
logger.fatal(
|
||||
'(While null value test) Alert: Your disk or data storage volume is full.'
|
||||
' sqlThread will now exit.')
|
||||
'(While null value test) Alert: Your disk or data storage'
|
||||
' volume is full. sqlThread will now exit.')
|
||||
queues.UISignalQueue.put((
|
||||
'alert', (
|
||||
tr._translate(
|
||||
_translate("MainWindow", "Disk full"),
|
||||
_translate(
|
||||
"MainWindow",
|
||||
"Disk full"),
|
||||
tr._translate(
|
||||
"MainWindow",
|
||||
'Alert: Your disk or data storage volume is full. Bitmessage will now exit.'),
|
||||
"Alert: Your disk or data storage volume is full."
|
||||
" Bitmessage will now exit."),
|
||||
True)))
|
||||
os._exit(0)
|
||||
else:
|
||||
|
@ -480,16 +463,15 @@ class sqlThread(threading.Thread):
|
|||
except Exception as err:
|
||||
if str(err) == 'database or disk is full':
|
||||
logger.fatal(
|
||||
'(While VACUUM) Alert: Your disk or data storage volume is full.'
|
||||
' sqlThread will now exit.')
|
||||
'(While VACUUM) Alert: Your disk or data storage'
|
||||
' volume is full. sqlThread will now exit.')
|
||||
queues.UISignalQueue.put((
|
||||
'alert', (
|
||||
tr._translate(
|
||||
_translate("MainWindow", "Disk full"),
|
||||
_translate(
|
||||
"MainWindow",
|
||||
"Disk full"),
|
||||
tr._translate(
|
||||
"MainWindow",
|
||||
'Alert: Your disk or data storage volume is full. Bitmessage will now exit.'),
|
||||
"Alert: Your disk or data storage volume"
|
||||
" is full. Bitmessage will now exit."),
|
||||
True)))
|
||||
os._exit(0)
|
||||
item = '''update settings set value=? WHERE key='lastvacuumtime';'''
|
||||
|
@ -510,12 +492,11 @@ class sqlThread(threading.Thread):
|
|||
' sqlThread will now exit.')
|
||||
queues.UISignalQueue.put((
|
||||
'alert', (
|
||||
tr._translate(
|
||||
_translate("MainWindow", "Disk full"),
|
||||
_translate(
|
||||
"MainWindow",
|
||||
"Disk full"),
|
||||
tr._translate(
|
||||
"MainWindow",
|
||||
'Alert: Your disk or data storage volume is full. Bitmessage will now exit.'),
|
||||
"Alert: Your disk or data storage volume"
|
||||
" is full. Bitmessage will now exit."),
|
||||
True)))
|
||||
os._exit(0)
|
||||
elif item == 'exit':
|
||||
|
@ -535,12 +516,11 @@ class sqlThread(threading.Thread):
|
|||
' sqlThread will now exit.')
|
||||
queues.UISignalQueue.put((
|
||||
'alert', (
|
||||
tr._translate(
|
||||
_translate("MainWindow", "Disk full"),
|
||||
_translate(
|
||||
"MainWindow",
|
||||
"Disk full"),
|
||||
tr._translate(
|
||||
"MainWindow",
|
||||
'Alert: Your disk or data storage volume is full. Bitmessage will now exit.'),
|
||||
"Alert: Your disk or data storage volume"
|
||||
" is full. Bitmessage will now exit."),
|
||||
True)))
|
||||
os._exit(0)
|
||||
self.conn.close()
|
||||
|
@ -561,12 +541,11 @@ class sqlThread(threading.Thread):
|
|||
' sqlThread will now exit.')
|
||||
queues.UISignalQueue.put((
|
||||
'alert', (
|
||||
tr._translate(
|
||||
_translate("MainWindow", "Disk full"),
|
||||
_translate(
|
||||
"MainWindow",
|
||||
"Disk full"),
|
||||
tr._translate(
|
||||
"MainWindow",
|
||||
'Alert: Your disk or data storage volume is full. Bitmessage will now exit.'),
|
||||
"Alert: Your disk or data storage volume"
|
||||
" is full. Bitmessage will now exit."),
|
||||
True)))
|
||||
os._exit(0)
|
||||
self.conn.close()
|
||||
|
@ -588,12 +567,11 @@ class sqlThread(threading.Thread):
|
|||
' sqlThread will now exit.')
|
||||
queues.UISignalQueue.put((
|
||||
'alert', (
|
||||
tr._translate(
|
||||
_translate("MainWindow", "Disk full"),
|
||||
_translate(
|
||||
"MainWindow",
|
||||
"Disk full"),
|
||||
tr._translate(
|
||||
"MainWindow",
|
||||
'Alert: Your disk or data storage volume is full. Bitmessage will now exit.'),
|
||||
"Alert: Your disk or data storage volume"
|
||||
" is full. Bitmessage will now exit."),
|
||||
True)))
|
||||
os._exit(0)
|
||||
else:
|
||||
|
@ -609,12 +587,11 @@ class sqlThread(threading.Thread):
|
|||
' sqlThread will now exit.')
|
||||
queues.UISignalQueue.put((
|
||||
'alert', (
|
||||
tr._translate(
|
||||
_translate("MainWindow", "Disk full"),
|
||||
_translate(
|
||||
"MainWindow",
|
||||
"Disk full"),
|
||||
tr._translate(
|
||||
"MainWindow",
|
||||
'Alert: Your disk or data storage volume is full. Bitmessage will now exit.'),
|
||||
"Alert: Your disk or data storage volume"
|
||||
" is full. Bitmessage will now exit."),
|
||||
True)))
|
||||
os._exit(0)
|
||||
else:
|
||||
|
|
23
src/debug.py
23
src/debug.py
|
@ -28,33 +28,21 @@ Use:
|
|||
>>> import logging
|
||||
>>> logger = logging.getLogger('default')
|
||||
|
||||
The old form: ``from debug import logger`` is also may be used,
|
||||
The old form: ``from .debug import logger`` is also may be used,
|
||||
but only in the top level modules.
|
||||
|
||||
Logging is thread-safe so you don't have to worry about locks,
|
||||
just import and log.
|
||||
"""
|
||||
|
||||
# import ConfigParser
|
||||
import sys
|
||||
if sys.version_info[0] == 3:
|
||||
# python 3
|
||||
import configparser as ConfigParser
|
||||
else:
|
||||
# python 2
|
||||
import ConfigParser
|
||||
|
||||
import logging
|
||||
import logging.config
|
||||
import os
|
||||
import sys
|
||||
|
||||
if sys.version_info[0] == 3:
|
||||
from . import helper_startup
|
||||
from . import state
|
||||
else:
|
||||
import helper_startup
|
||||
import state
|
||||
from six.moves import configparser
|
||||
|
||||
from . import helper_startup, state
|
||||
|
||||
helper_startup.loadConfig()
|
||||
|
||||
|
@ -86,7 +74,7 @@ def configureLogging():
|
|||
False,
|
||||
'Loaded logger configuration from %s' % logging_config
|
||||
)
|
||||
except (OSError, ConfigParser.NoSectionError, KeyError):
|
||||
except (OSError, configparser.NoSectionError, KeyError):
|
||||
if os.path.isfile(logging_config):
|
||||
fail_msg = \
|
||||
'Failed to load logger configuration from %s, using default' \
|
||||
|
@ -161,7 +149,6 @@ def resetLogging():
|
|||
|
||||
|
||||
# !
|
||||
|
||||
preconfigured, msg = configureLogging()
|
||||
logger = logging.getLogger('default')
|
||||
if msg:
|
||||
|
|
|
@ -5,9 +5,8 @@ This module is for generating ack payload
|
|||
from binascii import hexlify
|
||||
from struct import pack
|
||||
|
||||
import helper_random
|
||||
import highlevelcrypto
|
||||
from addresses import encodeVarint
|
||||
from . import helper_random, highlevelcrypto
|
||||
from .addresses import encodeVarint
|
||||
|
||||
|
||||
def genAckPayload(streamNumber=1, stealthLevel=0):
|
||||
|
|
|
@ -4,8 +4,8 @@ Calculates bitcoin and testnet address from pubkey
|
|||
|
||||
import hashlib
|
||||
|
||||
from debug import logger
|
||||
from pyelliptic import arithmetic
|
||||
from .debug import logger
|
||||
from .pyelliptic import arithmetic
|
||||
|
||||
|
||||
def calculateBitcoinAddressFromPubkey(pubkey):
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
"""Helper Inbox performs inbox messages related operations"""
|
||||
|
||||
import queues
|
||||
from helper_sql import sqlExecute, sqlQuery
|
||||
from . import queues
|
||||
from .helper_sql import sqlExecute, sqlQuery
|
||||
|
||||
|
||||
def insert(t):
|
||||
|
|
|
@ -5,10 +5,10 @@ Message encoding end decoding functions
|
|||
import string
|
||||
import zlib
|
||||
|
||||
import messagetypes
|
||||
from bmconfigparser import BMConfigParser
|
||||
from debug import logger
|
||||
from tr import _translate
|
||||
from . import messagetypes
|
||||
from .bmconfigparser import BMConfigParser
|
||||
from .debug import logger
|
||||
from .tr import _translate
|
||||
|
||||
try:
|
||||
import msgpack
|
||||
|
@ -16,7 +16,7 @@ except ImportError:
|
|||
try:
|
||||
import umsgpack as msgpack
|
||||
except ImportError:
|
||||
import fallback.umsgpack.umsgpack as msgpack
|
||||
from .fallback.umsgpack import umsgpack as msgpack
|
||||
|
||||
BITMESSAGE_ENCODING_IGNORE = 0
|
||||
BITMESSAGE_ENCODING_TRIVIAL = 1
|
||||
|
@ -103,8 +103,8 @@ class MsgDecode(object):
|
|||
while len(tmp) <= BMConfigParser().safeGetInt("zlib", "maxsize"):
|
||||
try:
|
||||
got = dc.decompress(
|
||||
data, BMConfigParser().safeGetInt("zlib", "maxsize") +
|
||||
1 - len(tmp))
|
||||
data, BMConfigParser().safeGetInt("zlib", "maxsize")
|
||||
+ 1 - len(tmp))
|
||||
# EOF
|
||||
if got == "":
|
||||
break
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
"""Convenience functions for random operations. Not suitable for security / cryptography operations."""
|
||||
"""
|
||||
Convenience functions for random operations.
|
||||
Not suitable for security / cryptography operations.
|
||||
"""
|
||||
|
||||
import os
|
||||
import random
|
||||
import sys
|
||||
if sys.version_info[0] == 3:
|
||||
from .pyelliptic.openssl import OpenSSL
|
||||
else:
|
||||
from pyelliptic.openssl import OpenSSL
|
||||
|
||||
from .pyelliptic.openssl import OpenSSL
|
||||
|
||||
NoneType = type(None)
|
||||
|
||||
|
|
|
@ -3,8 +3,8 @@ Additional SQL helper for searching messages.
|
|||
Used by :mod:`.bitmessageqt`.
|
||||
"""
|
||||
|
||||
from helper_sql import sqlQuery
|
||||
from tr import _translate
|
||||
from .helper_sql import sqlQuery
|
||||
from .tr import _translate
|
||||
|
||||
|
||||
def search_sql(
|
||||
|
|
|
@ -4,10 +4,11 @@ Insert values into sent table
|
|||
|
||||
import time
|
||||
import uuid
|
||||
from addresses import decodeAddress
|
||||
from bmconfigparser import BMConfigParser
|
||||
from helper_ackPayload import genAckPayload
|
||||
from helper_sql import sqlExecute
|
||||
|
||||
from .addresses import decodeAddress
|
||||
from .bmconfigparser import BMConfigParser
|
||||
from .helper_ackPayload import genAckPayload
|
||||
from .helper_sql import sqlExecute
|
||||
|
||||
|
||||
# pylint: disable=too-many-arguments
|
||||
|
|
|
@ -10,22 +10,11 @@ import sys
|
|||
import time
|
||||
from distutils.version import StrictVersion
|
||||
|
||||
import sys
|
||||
if sys.version_info[0] == 3:
|
||||
from . import defaults
|
||||
from . import helper_random
|
||||
from . import paths
|
||||
from . import state
|
||||
from .bmconfigparser import BMConfigParser
|
||||
else:
|
||||
import defaults
|
||||
import helper_random
|
||||
import paths
|
||||
import state
|
||||
from bmconfigparser import BMConfigParser
|
||||
from . import defaults, helper_random, paths, state
|
||||
from .bmconfigparser import BMConfigParser
|
||||
|
||||
try:
|
||||
from plugins.plugin import get_plugin
|
||||
from .plugins.plugin import get_plugin
|
||||
except ImportError:
|
||||
get_plugin = None
|
||||
|
||||
|
@ -180,8 +169,9 @@ def updateConfig():
|
|||
# acts as a salt
|
||||
config.set(
|
||||
'bitmessagesettings', 'identiconsuffix', ''.join(
|
||||
helper_random.randomchoice("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz")
|
||||
for x in range(12)
|
||||
helper_random.randomchoice(
|
||||
"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
|
||||
) for x in range(12)
|
||||
)
|
||||
) # a twelve character pseudo-password to salt the identicons
|
||||
|
||||
|
@ -249,14 +239,15 @@ def updateConfig():
|
|||
'bitmessagesettings', 'maxacceptablenoncetrialsperbyte') == 0:
|
||||
config.set(
|
||||
'bitmessagesettings', 'maxacceptablenoncetrialsperbyte',
|
||||
str(defaults.ridiculousDifficulty *
|
||||
defaults.networkDefaultProofOfWorkNonceTrialsPerByte)
|
||||
str(defaults.ridiculousDifficulty
|
||||
* defaults.networkDefaultProofOfWorkNonceTrialsPerByte)
|
||||
)
|
||||
if config.safeGetInt('bitmessagesettings', 'maxacceptablepayloadlengthextrabytes') == 0:
|
||||
if config.safeGetInt(
|
||||
'bitmessagesettings', 'maxacceptablepayloadlengthextrabytes') == 0:
|
||||
config.set(
|
||||
'bitmessagesettings', 'maxacceptablepayloadlengthextrabytes',
|
||||
str(defaults.ridiculousDifficulty *
|
||||
defaults.networkDefaultPayloadLengthExtraBytes)
|
||||
str(defaults.ridiculousDifficulty
|
||||
* defaults.networkDefaultPayloadLengthExtraBytes)
|
||||
)
|
||||
|
||||
if not config.has_option('bitmessagesettings', 'onionhostname'):
|
||||
|
@ -298,8 +289,8 @@ def adjustHalfOpenConnectionsLimit():
|
|||
# connections at a time.
|
||||
VER_THIS = StrictVersion(platform.version())
|
||||
is_limited = (
|
||||
StrictVersion("5.1.2600") <= VER_THIS and
|
||||
StrictVersion("6.0.6000") >= VER_THIS
|
||||
StrictVersion("5.1.2600") <= VER_THIS
|
||||
and StrictVersion("6.0.6000") >= VER_THIS
|
||||
)
|
||||
except ValueError:
|
||||
pass
|
||||
|
|
|
@ -9,10 +9,10 @@ High level cryptographic functions based on `.pyelliptic` OpenSSL bindings.
|
|||
|
||||
from binascii import hexlify
|
||||
|
||||
import pyelliptic
|
||||
from bmconfigparser import BMConfigParser
|
||||
from pyelliptic import OpenSSL
|
||||
from pyelliptic import arithmetic as a
|
||||
from . import pyelliptic
|
||||
from .bmconfigparser import BMConfigParser
|
||||
from .pyelliptic import OpenSSL
|
||||
from .pyelliptic import arithmetic as a
|
||||
|
||||
|
||||
def makeCryptor(privkey):
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
# TODO make this dynamic, and watch out for frozen, like with messagetypes
|
||||
import storage.filesystem
|
||||
import storage.sqlite
|
||||
from bmconfigparser import BMConfigParser
|
||||
from singleton import Singleton
|
||||
from .bmconfigparser import BMConfigParser
|
||||
from .singleton import Singleton
|
||||
|
||||
|
||||
@Singleton
|
||||
|
|
|
@ -5,7 +5,7 @@ import logging
|
|||
import os
|
||||
import time
|
||||
|
||||
from bmconfigparser import BMConfigParser
|
||||
from .bmconfigparser import BMConfigParser
|
||||
|
||||
logger = logging.getLogger('default')
|
||||
|
||||
|
|
|
@ -3,21 +3,14 @@ A queue with multiple internal subqueues.
|
|||
Elements are added into a random subqueue, and retrieval rotates
|
||||
"""
|
||||
|
||||
import sys
|
||||
if sys.version_info[0] == 3:
|
||||
import queue as Queue
|
||||
else:
|
||||
import Queue
|
||||
|
||||
from collections import deque
|
||||
|
||||
if sys.version_info[0] == 3:
|
||||
from . import helper_random
|
||||
else:
|
||||
import helper_random
|
||||
from six.moves import queue
|
||||
|
||||
from . import helper_random
|
||||
|
||||
|
||||
class MultiQueue(Queue.Queue):
|
||||
class MultiQueue(queue.Queue):
|
||||
"""A base queue class"""
|
||||
# pylint: disable=redefined-builtin,attribute-defined-outside-init
|
||||
defaultQueueCount = 10
|
||||
|
@ -27,7 +20,7 @@ class MultiQueue(Queue.Queue):
|
|||
self.queueCount = MultiQueue.defaultQueueCount
|
||||
else:
|
||||
self.queueCount = count
|
||||
Queue.Queue.__init__(self, maxsize)
|
||||
queue.Queue.__init__(self, maxsize)
|
||||
|
||||
# Initialize the queue representation
|
||||
def _init(self, maxsize):
|
||||
|
@ -42,7 +35,8 @@ class MultiQueue(Queue.Queue):
|
|||
# Put a new item in the queue
|
||||
def _put(self, item):
|
||||
# self.queue.append(item)
|
||||
self.queues[helper_random.randomrandrange(self.queueCount)].append((item))
|
||||
self.queues[helper_random.randomrandrange(self.queueCount)].append(
|
||||
(item))
|
||||
|
||||
# Get an item from the queue
|
||||
def _get(self):
|
||||
|
|
|
@ -10,11 +10,11 @@ import os
|
|||
import socket
|
||||
import sys
|
||||
|
||||
import defaults
|
||||
import tr # translate
|
||||
from addresses import decodeAddress
|
||||
from bmconfigparser import BMConfigParser
|
||||
from debug import logger
|
||||
from . import defaults
|
||||
from .addresses import decodeAddress
|
||||
from .bmconfigparser import BMConfigParser
|
||||
from .debug import logger
|
||||
from .tr import _translate
|
||||
|
||||
|
||||
configSection = "bitmessagesettings"
|
||||
|
@ -92,7 +92,7 @@ class namecoinConnection(object):
|
|||
res = self.callRPC("data", ["getValue", string])
|
||||
res = res["reply"]
|
||||
if not res:
|
||||
return (tr._translate(
|
||||
return (_translate(
|
||||
"MainWindow", 'The name %1 was not found.'
|
||||
).arg(unicode(string)), None)
|
||||
else:
|
||||
|
@ -103,16 +103,16 @@ class namecoinConnection(object):
|
|||
errmsg = exc.error["message"]
|
||||
else:
|
||||
errmsg = exc.error
|
||||
return (tr._translate(
|
||||
return (_translate(
|
||||
"MainWindow", 'The namecoin query failed (%1)'
|
||||
).arg(unicode(errmsg)), None)
|
||||
except AssertionError:
|
||||
return (tr._translate(
|
||||
return (_translate(
|
||||
"MainWindow", 'Unknown namecoin interface type: %1'
|
||||
).arg(unicode(self.nmctype)), None)
|
||||
except Exception:
|
||||
logger.exception("Namecoin query exception")
|
||||
return (tr._translate(
|
||||
return (_translate(
|
||||
"MainWindow", 'The namecoin query failed.'), None)
|
||||
|
||||
try:
|
||||
|
@ -130,7 +130,7 @@ class namecoinConnection(object):
|
|||
return (
|
||||
None, "%s <%s>" % (display_name, res)
|
||||
) if valid else (
|
||||
tr._translate(
|
||||
_translate(
|
||||
"MainWindow",
|
||||
'The name %1 has no associated Bitmessage address.'
|
||||
).arg(unicode(string)), None)
|
||||
|
@ -159,7 +159,7 @@ class namecoinConnection(object):
|
|||
versStr = "0.%d.%d.%d" % (v1, v2, v3)
|
||||
message = (
|
||||
'success',
|
||||
tr._translate(
|
||||
_translate(
|
||||
"MainWindow",
|
||||
'Success! Namecoind version %1 running.').arg(
|
||||
unicode(versStr)))
|
||||
|
@ -168,14 +168,13 @@ class namecoinConnection(object):
|
|||
res = self.callRPC("data", ["status"])
|
||||
prefix = "Plugin data running"
|
||||
if ("reply" in res) and res["reply"][:len(prefix)] == prefix:
|
||||
return ('success', tr._translate("MainWindow", 'Success! NMControll is up and running.'))
|
||||
return ('success', _translate("MainWindow", 'Success! NMControll is up and running.'))
|
||||
|
||||
logger.error("Unexpected nmcontrol reply: %s", res)
|
||||
message = ('failed', tr._translate("MainWindow", 'Couldn\'t understand NMControl.'))
|
||||
message = ('failed', _translate("MainWindow", 'Couldn\'t understand NMControl.'))
|
||||
|
||||
else:
|
||||
print ("Unsupported Namecoin type")
|
||||
sys.exit(1)
|
||||
sys.exit("Unsupported Namecoin type")
|
||||
|
||||
return message
|
||||
|
||||
|
@ -183,7 +182,7 @@ class namecoinConnection(object):
|
|||
logger.info("Namecoin connection test failure")
|
||||
return (
|
||||
'failed',
|
||||
tr._translate(
|
||||
_translate(
|
||||
"MainWindow", "The connection to namecoin failed.")
|
||||
)
|
||||
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
"""
|
||||
Network subsystem packages
|
||||
"""
|
||||
from addrthread import AddrThread
|
||||
from announcethread import AnnounceThread
|
||||
from connectionpool import BMConnectionPool
|
||||
from dandelion import Dandelion
|
||||
from downloadthread import DownloadThread
|
||||
from invthread import InvThread
|
||||
from networkthread import BMNetworkThread
|
||||
from receivequeuethread import ReceiveQueueThread
|
||||
from threads import StoppableThread
|
||||
from uploadthread import UploadThread
|
||||
from .addrthread import AddrThread
|
||||
from .announcethread import AnnounceThread
|
||||
from .connectionpool import BMConnectionPool
|
||||
from .dandelion import Dandelion
|
||||
from .downloadthread import DownloadThread
|
||||
from .invthread import InvThread
|
||||
from .networkthread import BMNetworkThread
|
||||
from .receivequeuethread import ReceiveQueueThread
|
||||
from .threads import StoppableThread
|
||||
from .uploadthread import UploadThread
|
||||
|
||||
|
||||
__all__ = [
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
"""
|
||||
Announce addresses as they are received from other hosts
|
||||
"""
|
||||
import Queue
|
||||
from six.moves import queue
|
||||
|
||||
import state
|
||||
from helper_random import randomshuffle
|
||||
from network.assemble import assemble_addr
|
||||
from network.connectionpool import BMConnectionPool
|
||||
from queues import addrQueue
|
||||
from threads import StoppableThread
|
||||
from pybitmessage import state
|
||||
from pybitmessage.helper_random import randomshuffle
|
||||
from pybitmessage.queues import addrQueue
|
||||
from .assemble import assemble_addr
|
||||
from .connectionpool import BMConnectionPool
|
||||
from .threads import StoppableThread
|
||||
|
||||
|
||||
class AddrThread(StoppableThread):
|
||||
|
@ -22,7 +22,7 @@ class AddrThread(StoppableThread):
|
|||
try:
|
||||
data = addrQueue.get(False)
|
||||
chunk.append(data)
|
||||
except Queue.Empty:
|
||||
except queue.Empty:
|
||||
break
|
||||
|
||||
if chunk:
|
||||
|
|
|
@ -5,9 +5,9 @@ import socket
|
|||
import threading
|
||||
import time
|
||||
|
||||
import network.asyncore_pollchoose as asyncore
|
||||
import state
|
||||
from threads import BusyError, nonBlocking
|
||||
from pybitmessage import state
|
||||
from . import asyncore_pollchoose as asyncore
|
||||
from .threads import BusyError, nonBlocking
|
||||
|
||||
|
||||
class ProcessingError(Exception):
|
||||
|
|
|
@ -3,12 +3,12 @@ Announce myself (node address)
|
|||
"""
|
||||
import time
|
||||
|
||||
import state
|
||||
from bmconfigparser import BMConfigParser
|
||||
from network.assemble import assemble_addr
|
||||
from network.connectionpool import BMConnectionPool
|
||||
from node import Peer
|
||||
from threads import StoppableThread
|
||||
from pybitmessage import state
|
||||
from pybitmessage.bmconfigparser import BMConfigParser
|
||||
from .assemble import assemble_addr
|
||||
from .connectionpool import BMConnectionPool
|
||||
from .node import Peer
|
||||
from .threads import StoppableThread
|
||||
|
||||
|
||||
class AnnounceThread(StoppableThread):
|
||||
|
|
|
@ -3,10 +3,10 @@ Create bitmessage protocol command packets
|
|||
"""
|
||||
import struct
|
||||
|
||||
import addresses
|
||||
from network.constants import MAX_ADDR_COUNT
|
||||
from network.node import Peer
|
||||
from protocol import CreatePacket, encodeHost
|
||||
from pybitmessage import addresses
|
||||
from pybitmessage.protocol import CreatePacket, encodeHost
|
||||
from .constants import MAX_ADDR_COUNT
|
||||
from .node import Peer
|
||||
|
||||
|
||||
def assemble_addr(peerList):
|
||||
|
|
|
@ -19,7 +19,7 @@ from errno import (
|
|||
)
|
||||
from threading import current_thread
|
||||
|
||||
import helper_random
|
||||
from pybitmessage import helper_random
|
||||
|
||||
try:
|
||||
from errno import WSAEWOULDBLOCK
|
||||
|
|
|
@ -4,11 +4,10 @@ BMObject and it's exceptions.
|
|||
import logging
|
||||
import time
|
||||
|
||||
import protocol
|
||||
import state
|
||||
from addresses import calculateInventoryHash
|
||||
from inventory import Inventory
|
||||
from network.dandelion import Dandelion
|
||||
from pybitmessage import protocol, state
|
||||
from pybitmessage.addresses import calculateInventoryHash
|
||||
from pybitmessage.inventory import Inventory
|
||||
from .dandelion import Dandelion
|
||||
|
||||
logger = logging.getLogger('default')
|
||||
|
||||
|
|
|
@ -10,29 +10,26 @@ import struct
|
|||
import time
|
||||
from binascii import hexlify
|
||||
|
||||
import addresses
|
||||
import connectionpool
|
||||
import knownnodes
|
||||
import protocol
|
||||
import state
|
||||
from bmconfigparser import BMConfigParser
|
||||
from inventory import Inventory
|
||||
from network.advanceddispatcher import AdvancedDispatcher
|
||||
from network.bmobject import (
|
||||
from pybitmessage import addresses, protocol, state
|
||||
from pybitmessage.bmconfigparser import BMConfigParser
|
||||
from pybitmessage.inventory import Inventory
|
||||
from pybitmessage.queues import invQueue, objectProcessorQueue, portCheckerQueue
|
||||
from . import connectionpool, knownnodes
|
||||
from .advanceddispatcher import AdvancedDispatcher
|
||||
from .bmobject import (
|
||||
BMObject, BMObjectAlreadyHaveError, BMObjectExpiredError,
|
||||
BMObjectInsufficientPOWError, BMObjectInvalidDataError,
|
||||
BMObjectInvalidError, BMObjectUnwantedStreamError
|
||||
)
|
||||
from network.constants import (
|
||||
from .constants import (
|
||||
ADDRESS_ALIVE, MAX_MESSAGE_SIZE, MAX_OBJECT_COUNT,
|
||||
MAX_OBJECT_PAYLOAD_SIZE, MAX_TIME_OFFSET
|
||||
)
|
||||
from network.dandelion import Dandelion
|
||||
from network.proxy import ProxyError
|
||||
from node import Node, Peer
|
||||
from objectracker import ObjectTracker, missingObjects
|
||||
from queues import invQueue, objectProcessorQueue, portCheckerQueue
|
||||
from randomtrackingdict import RandomTrackingDict
|
||||
from .dandelion import Dandelion
|
||||
from .proxy import ProxyError
|
||||
from .node import Node, Peer
|
||||
from .objectracker import ObjectTracker, missingObjects
|
||||
from .randomtrackingdict import RandomTrackingDict
|
||||
|
||||
logger = logging.getLogger('default')
|
||||
|
||||
|
|
|
@ -5,11 +5,10 @@ Select which node to connect to
|
|||
import logging
|
||||
import random # nosec
|
||||
|
||||
import knownnodes
|
||||
import protocol
|
||||
import state
|
||||
from bmconfigparser import BMConfigParser
|
||||
from queues import Queue, portCheckerQueue
|
||||
from pybitmessage import protocol, state
|
||||
from pybitmessage.bmconfigparser import BMConfigParser
|
||||
from pybitmessage.queues import queue, portCheckerQueue
|
||||
from .knownnodes import knownNodes
|
||||
|
||||
logger = logging.getLogger('default')
|
||||
|
||||
|
@ -37,16 +36,16 @@ def chooseConnection(stream):
|
|||
retval = portCheckerQueue.get(False)
|
||||
portCheckerQueue.task_done()
|
||||
return retval
|
||||
except Queue.Empty:
|
||||
except queue.Empty:
|
||||
pass
|
||||
# with a probability of 0.5, connect to a discovered peer
|
||||
if random.choice((False, True)) and not haveOnion:
|
||||
# discovered peers are already filtered by allowed streams
|
||||
return getDiscoveredPeer()
|
||||
for _ in range(50):
|
||||
peer = random.choice(knownnodes.knownNodes[stream].keys())
|
||||
peer = random.choice(knownNodes[stream].keys())
|
||||
try:
|
||||
peer_info = knownnodes.knownNodes[stream][peer]
|
||||
peer_info = knownNodes[stream][peer]
|
||||
if peer_info.get('self'):
|
||||
continue
|
||||
rating = peer_info["rating"]
|
||||
|
|
|
@ -9,15 +9,13 @@ import sys
|
|||
import time
|
||||
|
||||
import asyncore_pollchoose as asyncore
|
||||
import helper_random
|
||||
import knownnodes
|
||||
import protocol
|
||||
import state
|
||||
from bmconfigparser import BMConfigParser
|
||||
from pybitmessage import helper_random, protocol, state
|
||||
from pybitmessage.bmconfigparser import BMConfigParser
|
||||
from pybitmessage.singleton import Singleton
|
||||
from connectionchooser import chooseConnection
|
||||
from node import Peer
|
||||
from proxy import Proxy
|
||||
from singleton import Singleton
|
||||
from tcp import (
|
||||
bootstrap, Socks4aBMConnection, Socks5BMConnection,
|
||||
TCPConnection, TCPServer)
|
||||
|
|
|
@ -7,10 +7,10 @@ from random import choice, expovariate, sample
|
|||
from threading import RLock
|
||||
from time import time
|
||||
|
||||
import connectionpool
|
||||
import state
|
||||
from queues import invQueue
|
||||
from singleton import Singleton
|
||||
from pybitmessage import state
|
||||
from pybitmessage.queues import invQueue
|
||||
from pybitmessage.singleton import Singleton
|
||||
from .connectionpool import BMConnectionPool
|
||||
|
||||
# randomise routes after 600 seconds
|
||||
REASSIGN_INTERVAL = 600
|
||||
|
@ -185,12 +185,10 @@ class Dandelion: # pylint: disable=old-style-class
|
|||
try:
|
||||
# random two connections
|
||||
self.stem = sample(
|
||||
connectionpool.BMConnectionPool(
|
||||
).outboundConnections.values(), MAX_STEMS)
|
||||
BMConnectionPool().outboundConnections.values(), MAX_STEMS)
|
||||
# not enough stems available
|
||||
except ValueError:
|
||||
self.stem = connectionpool.BMConnectionPool(
|
||||
).outboundConnections.values()
|
||||
self.stem = BMConnectionPool().outboundConnections.values()
|
||||
self.nodeMap = {}
|
||||
# hashMap stays to cater for pending stems
|
||||
self.refresh = time() + REASSIGN_INTERVAL
|
||||
|
|
|
@ -3,14 +3,12 @@
|
|||
"""
|
||||
import time
|
||||
|
||||
import addresses
|
||||
import helper_random
|
||||
import protocol
|
||||
from dandelion import Dandelion
|
||||
from inventory import Inventory
|
||||
from network.connectionpool import BMConnectionPool
|
||||
from objectracker import missingObjects
|
||||
from threads import StoppableThread
|
||||
from pybitmessage import addresses, helper_random, protocol
|
||||
from pybitmessage.inventory import Inventory
|
||||
from .connectionpool import BMConnectionPool
|
||||
from .dandelion import Dandelion
|
||||
from .objectracker import missingObjects
|
||||
from .threads import StoppableThread
|
||||
|
||||
|
||||
class DownloadThread(StoppableThread):
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
"""
|
||||
Thread to send inv annoucements
|
||||
"""
|
||||
import Queue
|
||||
|
||||
import random
|
||||
from time import time
|
||||
|
||||
import addresses
|
||||
import protocol
|
||||
import state
|
||||
from network.connectionpool import BMConnectionPool
|
||||
from network.dandelion import Dandelion
|
||||
from queues import invQueue
|
||||
from threads import StoppableThread
|
||||
from six.moves import queue
|
||||
|
||||
from pybitmessage import addresses, protocol, state
|
||||
from pybitmessage.queues import invQueue
|
||||
from .connectionpool import BMConnectionPool
|
||||
from .dandelion import Dandelion
|
||||
from .threads import StoppableThread
|
||||
|
||||
|
||||
def handleExpiredDandelion(expired):
|
||||
|
@ -59,7 +59,7 @@ class InvThread(StoppableThread):
|
|||
# locally generated
|
||||
if len(data) == 2 or data[2] is None:
|
||||
self.handleLocallyGenerated(data[0], data[1])
|
||||
except Queue.Empty:
|
||||
except queue.Empty:
|
||||
break
|
||||
|
||||
if chunk:
|
||||
|
|
|
@ -15,9 +15,9 @@ try:
|
|||
except ImportError:
|
||||
from collections import Iterable
|
||||
|
||||
import state
|
||||
from bmconfigparser import BMConfigParser
|
||||
from network.node import Peer
|
||||
from pybitmessage import state
|
||||
from pybitmessage.bmconfigparser import BMConfigParser
|
||||
from .node import Peer
|
||||
|
||||
state.Peer = Peer
|
||||
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
"""
|
||||
A thread to handle network concerns
|
||||
"""
|
||||
import network.asyncore_pollchoose as asyncore
|
||||
import state
|
||||
from network.connectionpool import BMConnectionPool
|
||||
from queues import excQueue
|
||||
from threads import StoppableThread
|
||||
|
||||
from pybitmessage import state
|
||||
from pybitmessage.queues import excQueue
|
||||
from . import asyncore_pollchoose as asyncore
|
||||
from .connectionpool import BMConnectionPool
|
||||
from .threads import StoppableThread
|
||||
|
||||
|
||||
class BMNetworkThread(StoppableThread):
|
||||
|
|
|
@ -4,9 +4,9 @@ Module for tracking objects
|
|||
import time
|
||||
from threading import RLock
|
||||
|
||||
import network.connectionpool
|
||||
from network.dandelion import Dandelion
|
||||
from randomtrackingdict import RandomTrackingDict
|
||||
from .connectionpool import BMConnectionPool
|
||||
from .dandelion import Dandelion
|
||||
from .randomtrackingdict import RandomTrackingDict
|
||||
|
||||
haveBloom = False
|
||||
|
||||
|
@ -100,15 +100,15 @@ class ObjectTracker(object):
|
|||
|
||||
def handleReceivedObject(self, streamNumber, hashid):
|
||||
"""Handling received object"""
|
||||
for i in network.connectionpool.BMConnectionPool().connections():
|
||||
for i in BMConnectionPool().connections():
|
||||
if not i.fullyEstablished:
|
||||
continue
|
||||
try:
|
||||
del i.objectsNewToMe[hashid]
|
||||
except KeyError:
|
||||
if streamNumber in i.streams and (
|
||||
not Dandelion().hasHash(hashid) or
|
||||
Dandelion().objectChildStem(hashid) == i):
|
||||
not Dandelion().hasHash(hashid)
|
||||
or Dandelion().objectChildStem(hashid) == i):
|
||||
with i.objectsNewToThemLock:
|
||||
i.objectsNewToThem[hashid] = time.time()
|
||||
# update stream number,
|
||||
|
|
|
@ -6,10 +6,10 @@ import logging
|
|||
import socket
|
||||
import time
|
||||
|
||||
import asyncore_pollchoose as asyncore
|
||||
from advanceddispatcher import AdvancedDispatcher
|
||||
from bmconfigparser import BMConfigParser
|
||||
from node import Peer
|
||||
from pybitmessage.bmconfigparser import BMConfigParser
|
||||
from . import asyncore_pollchoose as asyncore
|
||||
from .advanceddispatcher import AdvancedDispatcher
|
||||
from .node import Peer
|
||||
|
||||
logger = logging.getLogger('default')
|
||||
|
||||
|
|
|
@ -2,14 +2,15 @@
|
|||
Process data incoming from network
|
||||
"""
|
||||
import errno
|
||||
import Queue
|
||||
import socket
|
||||
|
||||
import state
|
||||
from network.advanceddispatcher import UnknownStateError
|
||||
from network.connectionpool import BMConnectionPool
|
||||
from queues import receiveDataQueue
|
||||
from threads import StoppableThread
|
||||
from six.moves import queue
|
||||
|
||||
from pybitmessage import state
|
||||
from pybitmessage.queues import receiveDataQueue
|
||||
from .advanceddispatcher import UnknownStateError
|
||||
from .connectionpool import BMConnectionPool
|
||||
from .threads import StoppableThread
|
||||
|
||||
|
||||
class ReceiveQueueThread(StoppableThread):
|
||||
|
@ -22,7 +23,7 @@ class ReceiveQueueThread(StoppableThread):
|
|||
while not self._stopped and state.shutdown == 0:
|
||||
try:
|
||||
dest = receiveDataQueue.get(block=True, timeout=1)
|
||||
except Queue.Empty:
|
||||
except queue.Empty:
|
||||
continue
|
||||
|
||||
if self._stopped or state.shutdown:
|
||||
|
|
|
@ -6,7 +6,7 @@ import logging
|
|||
import socket
|
||||
import struct
|
||||
|
||||
from proxy import GeneralProxyError, Proxy, ProxyError
|
||||
from .proxy import GeneralProxyError, Proxy, ProxyError
|
||||
|
||||
logger = logging.getLogger('default')
|
||||
|
||||
|
|
|
@ -7,8 +7,8 @@ import logging
|
|||
import socket
|
||||
import struct
|
||||
|
||||
from node import Peer
|
||||
from proxy import GeneralProxyError, Proxy, ProxyError
|
||||
from .node import Peer
|
||||
from .proxy import GeneralProxyError, Proxy, ProxyError
|
||||
|
||||
logger = logging.getLogger('default')
|
||||
|
||||
|
|
|
@ -3,9 +3,9 @@ Network statistics
|
|||
"""
|
||||
import time
|
||||
|
||||
import asyncore_pollchoose as asyncore
|
||||
from network.connectionpool import BMConnectionPool
|
||||
from objectracker import missingObjects
|
||||
from . import asyncore_pollchoose as asyncore
|
||||
from .connectionpool import BMConnectionPool
|
||||
from .objectracker import missingObjects
|
||||
|
||||
|
||||
lastReceivedTimestamp = time.time()
|
||||
|
|
|
@ -2,35 +2,32 @@
|
|||
TCP protocol handler
|
||||
"""
|
||||
# pylint: disable=too-many-ancestors
|
||||
import l10n
|
||||
|
||||
import logging
|
||||
import math
|
||||
import random
|
||||
import socket
|
||||
import time
|
||||
|
||||
import addresses
|
||||
import asyncore_pollchoose as asyncore
|
||||
import connectionpool
|
||||
import helper_random
|
||||
import knownnodes
|
||||
import protocol
|
||||
import state
|
||||
from bmconfigparser import BMConfigParser
|
||||
from helper_random import randomBytes
|
||||
from inventory import Inventory
|
||||
from network.advanceddispatcher import AdvancedDispatcher
|
||||
from network.assemble import assemble_addr
|
||||
from network.bmproto import BMProto
|
||||
from network.constants import MAX_OBJECT_COUNT
|
||||
from network.dandelion import Dandelion
|
||||
from network.objectracker import ObjectTracker
|
||||
from network.socks4a import Socks4aConnection
|
||||
from network.socks5 import Socks5Connection
|
||||
from network.tls import TLSDispatcher
|
||||
from node import Peer
|
||||
from queues import invQueue, receiveDataQueue, UISignalQueue
|
||||
from tr import _translate
|
||||
from pybitmessage import addresses, helper_random, l10n, protocol, state
|
||||
from pybitmessage.bmconfigparser import BMConfigParser
|
||||
from pybitmessage.helper_random import randomBytes
|
||||
from pybitmessage.inventory import Inventory
|
||||
from pybitmessage.queues import invQueue, receiveDataQueue, UISignalQueue
|
||||
from pybitmessage.tr import _translate
|
||||
from . import asyncore_pollchoose as asyncore
|
||||
from . import connectionpool, knownnodes
|
||||
from .advanceddispatcher import AdvancedDispatcher
|
||||
from .assemble import assemble_addr
|
||||
from .bmproto import BMProto
|
||||
from .constants import MAX_OBJECT_COUNT
|
||||
from .dandelion import Dandelion
|
||||
from .objectracker import ObjectTracker
|
||||
from .socks4a import Socks4aConnection
|
||||
from .socks5 import Socks5Connection
|
||||
from .tls import TLSDispatcher
|
||||
from .node import Peer
|
||||
|
||||
|
||||
logger = logging.getLogger('default')
|
||||
|
||||
|
|
|
@ -7,10 +7,10 @@ import socket
|
|||
import ssl
|
||||
import sys
|
||||
|
||||
import network.asyncore_pollchoose as asyncore
|
||||
import paths
|
||||
from network.advanceddispatcher import AdvancedDispatcher
|
||||
from queues import receiveDataQueue
|
||||
from pybitmessage import paths
|
||||
from pybitmessage.queues import receiveDataQueue
|
||||
from . import asyncore_pollchoose as asyncore
|
||||
from .advanceddispatcher import AdvancedDispatcher
|
||||
|
||||
logger = logging.getLogger('default')
|
||||
|
||||
|
|
|
@ -5,13 +5,13 @@ import logging
|
|||
import socket
|
||||
import time
|
||||
|
||||
import protocol
|
||||
import state
|
||||
from bmproto import BMProto
|
||||
from constants import MAX_TIME_OFFSET
|
||||
from node import Peer
|
||||
from objectracker import ObjectTracker
|
||||
from queues import receiveDataQueue
|
||||
from pybitmessage import protocol, state
|
||||
from pybitmessage.queues import receiveDataQueue
|
||||
from .bmproto import BMProto
|
||||
from .constants import MAX_TIME_OFFSET
|
||||
from .node import Peer
|
||||
from .objectracker import ObjectTracker
|
||||
|
||||
|
||||
logger = logging.getLogger('default')
|
||||
|
||||
|
|
|
@ -3,13 +3,12 @@
|
|||
"""
|
||||
import time
|
||||
|
||||
import helper_random
|
||||
import protocol
|
||||
from inventory import Inventory
|
||||
from network.connectionpool import BMConnectionPool
|
||||
from network.dandelion import Dandelion
|
||||
from randomtrackingdict import RandomTrackingDict
|
||||
from threads import StoppableThread
|
||||
from pybitmessage import helper_random, protocol
|
||||
from pybitmessage.inventory import Inventory
|
||||
from .connectionpool import BMConnectionPool
|
||||
from .dandelion import Dandelion
|
||||
from .randomtrackingdict import RandomTrackingDict
|
||||
from .threads import StoppableThread
|
||||
|
||||
|
||||
class UploadThread(StoppableThread):
|
||||
|
|
|
@ -5,9 +5,9 @@ import logging
|
|||
import os
|
||||
from struct import pack
|
||||
|
||||
import paths
|
||||
from bmconfigparser import BMConfigParser
|
||||
from state import shutdown
|
||||
from . import paths
|
||||
from .bmconfigparser import BMConfigParser
|
||||
from .state import shutdown
|
||||
|
||||
try:
|
||||
import numpy
|
||||
|
|
|
@ -11,13 +11,10 @@ import time
|
|||
from struct import pack, unpack
|
||||
from subprocess import call
|
||||
|
||||
import openclpow
|
||||
import paths
|
||||
import queues
|
||||
import state
|
||||
import tr
|
||||
from bmconfigparser import BMConfigParser
|
||||
from debug import logger
|
||||
from . import openclpow, paths, queues, state
|
||||
from .bmconfigparser import BMConfigParser
|
||||
from .debug import logger
|
||||
from .tr import _translate
|
||||
|
||||
bitmsglib = 'bitmsghash.so'
|
||||
bmpow = None
|
||||
|
@ -34,8 +31,10 @@ def _set_idle():
|
|||
import win32process
|
||||
import win32con
|
||||
pid = win32api.GetCurrentProcessId()
|
||||
handle = win32api.OpenProcess(win32con.PROCESS_ALL_ACCESS, True, pid)
|
||||
win32process.SetPriorityClass(handle, win32process.IDLE_PRIORITY_CLASS)
|
||||
handle = win32api.OpenProcess(
|
||||
win32con.PROCESS_ALL_ACCESS, True, pid)
|
||||
win32process.SetPriorityClass(
|
||||
handle, win32process.IDLE_PRIORITY_CLASS)
|
||||
except:
|
||||
# Windows 64-bit
|
||||
pass
|
||||
|
@ -82,7 +81,8 @@ def _doFastPoW(target, initialHash):
|
|||
pool = Pool(processes=pool_size)
|
||||
result = []
|
||||
for i in range(pool_size):
|
||||
result.append(pool.apply_async(_pool_worker, args=(i, initialHash, target, pool_size)))
|
||||
result.append(pool.apply_async(
|
||||
_pool_worker, args=(i, initialHash, target, pool_size)))
|
||||
|
||||
while True:
|
||||
if state.shutdown > 0:
|
||||
|
@ -115,35 +115,39 @@ def _doCPoW(target, initialHash):
|
|||
out_m = ctypes.c_ulonglong(m)
|
||||
logger.debug("C PoW start")
|
||||
nonce = bmpow(out_h, out_m)
|
||||
trialValue, = unpack('>Q', hashlib.sha512(hashlib.sha512(pack('>Q', nonce) + initialHash).digest()).digest()[0:8])
|
||||
trialValue = unpack(
|
||||
'>Q', hashlib.sha512(hashlib.sha512(
|
||||
pack('>Q', nonce) + initialHash).digest()).digest()[0:8])
|
||||
if state.shutdown != 0:
|
||||
raise StopIteration("Interrupted")
|
||||
logger.debug("C PoW done")
|
||||
return [trialValue, nonce]
|
||||
return trialValue, nonce
|
||||
|
||||
|
||||
def _doGPUPoW(target, initialHash):
|
||||
logger.debug("GPU PoW start")
|
||||
nonce = openclpow.do_opencl_pow(initialHash.encode("hex"), target)
|
||||
trialValue, = unpack('>Q', hashlib.sha512(hashlib.sha512(pack('>Q', nonce) + initialHash).digest()).digest()[0:8])
|
||||
trialValue = unpack(
|
||||
'>Q', hashlib.sha512(hashlib.sha512(
|
||||
pack('>Q', nonce) + initialHash).digest()).digest()[0:8])
|
||||
if trialValue > target:
|
||||
deviceNames = ", ".join(gpu.name for gpu in openclpow.enabledGpus)
|
||||
queues.UISignalQueue.put((
|
||||
'updateStatusBar', (
|
||||
tr._translate(
|
||||
_translate(
|
||||
"MainWindow",
|
||||
'Your GPU(s) did not calculate correctly, disabling OpenCL. Please report to the developers.'
|
||||
),
|
||||
1)))
|
||||
"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)
|
||||
'Your GPUs (%s) did not calculate correctly, disabling OpenCL.'
|
||||
' Please report to the developers.', deviceNames)
|
||||
openclpow.enabledGpus = []
|
||||
raise Exception("GPU did not calculate correctly.")
|
||||
if state.shutdown != 0:
|
||||
raise StopIteration("Interrupted")
|
||||
logger.debug("GPU PoW done")
|
||||
return [trialValue, nonce]
|
||||
return trialValue, nonce
|
||||
|
||||
|
||||
def estimate(difficulty, format=False): # pylint: disable=redefined-builtin
|
||||
|
@ -189,26 +193,30 @@ def getPowType():
|
|||
|
||||
|
||||
def notifyBuild(tried=False):
|
||||
"""Notify the user of the success or otherwise of building the PoW C module"""
|
||||
|
||||
"""
|
||||
Notify the user of the success or otherwise of building the PoW C module
|
||||
"""
|
||||
if bmpow:
|
||||
queues.UISignalQueue.put(('updateStatusBar', (tr._translate(
|
||||
"proofofwork", "C PoW module built successfully."), 1)))
|
||||
queues.UISignalQueue.put((
|
||||
'updateStatusBar', (
|
||||
_translate("proofofwork", "C PoW module built successfully."),
|
||||
1)
|
||||
))
|
||||
elif tried:
|
||||
queues.UISignalQueue.put(
|
||||
(
|
||||
'updateStatusBar', (
|
||||
tr._translate(
|
||||
"proofofwork",
|
||||
"Failed to build C PoW module. Please build it manually."
|
||||
),
|
||||
1
|
||||
)
|
||||
)
|
||||
)
|
||||
queues.UISignalQueue.put((
|
||||
'updateStatusBar', (
|
||||
_translate(
|
||||
"proofofwork",
|
||||
"Failed to build C PoW module. Please build it manually."),
|
||||
1)
|
||||
))
|
||||
else:
|
||||
queues.UISignalQueue.put(('updateStatusBar', (tr._translate(
|
||||
"proofofwork", "C PoW module unavailable. Please build it."), 1)))
|
||||
queues.UISignalQueue.put((
|
||||
'updateStatusBar', (
|
||||
_translate(
|
||||
"proofofwork", "C PoW module unavailable. Please build it."
|
||||
), 1)
|
||||
))
|
||||
|
||||
|
||||
def buildCPoW():
|
||||
|
@ -224,11 +232,15 @@ def buildCPoW():
|
|||
try:
|
||||
if "bsd" in sys.platform:
|
||||
# BSD make
|
||||
call(["make", "-C", os.path.join(paths.codePath(), "bitmsghash"), '-f', 'Makefile.bsd'])
|
||||
call([
|
||||
"make", "-C", os.path.join(paths.codePath(), "bitmsghash"),
|
||||
'-f', 'Makefile.bsd'
|
||||
])
|
||||
else:
|
||||
# GNU make
|
||||
call(["make", "-C", os.path.join(paths.codePath(), "bitmsghash")])
|
||||
if os.path.exists(os.path.join(paths.codePath(), "bitmsghash", "bitmsghash.so")):
|
||||
if os.path.exists(
|
||||
os.path.join(paths.codePath(), "bitmsghash", "bitmsghash.so")):
|
||||
init()
|
||||
notifyBuild(True)
|
||||
else:
|
||||
|
@ -298,7 +310,8 @@ def init():
|
|||
bitmsglib = 'bitmsghash64.dll'
|
||||
try:
|
||||
# MSVS
|
||||
bso = ctypes.WinDLL(os.path.join(paths.codePath(), "bitmsghash", bitmsglib))
|
||||
bso = ctypes.WinDLL(
|
||||
os.path.join(paths.codePath(), "bitmsghash", bitmsglib))
|
||||
logger.info("Loaded C PoW DLL (stdcall) %s", bitmsglib)
|
||||
bmpow = bso.BitmessagePOW
|
||||
bmpow.restype = ctypes.c_ulonglong
|
||||
|
@ -307,21 +320,24 @@ def init():
|
|||
except ValueError:
|
||||
try:
|
||||
# MinGW
|
||||
bso = ctypes.CDLL(os.path.join(paths.codePath(), "bitmsghash", bitmsglib))
|
||||
bso = ctypes.CDLL(
|
||||
os.path.join(paths.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 Exception as e:
|
||||
logger.error("Error: %s", e, exc_info=True)
|
||||
logger.info(
|
||||
"Successfully tested C PoW DLL (cdecl) %s", bitmsglib)
|
||||
except Exception:
|
||||
logger.error("C PoW test fail.", exc_info=True)
|
||||
bso = None
|
||||
except Exception as e:
|
||||
logger.error("Error: %s", e, exc_info=True)
|
||||
bso = None
|
||||
else:
|
||||
try:
|
||||
bso = ctypes.CDLL(os.path.join(paths.codePath(), "bitmsghash", bitmsglib))
|
||||
bso = ctypes.CDLL(
|
||||
os.path.join(paths.codePath(), "bitmsghash", bitmsglib))
|
||||
except OSError:
|
||||
import glob
|
||||
try:
|
||||
|
|
|
@ -13,16 +13,14 @@ import time
|
|||
from binascii import hexlify
|
||||
from struct import Struct, pack, unpack
|
||||
|
||||
import defaults
|
||||
import highlevelcrypto
|
||||
import state
|
||||
from addresses import (
|
||||
from . import defaults, highlevelcrypto, state
|
||||
from .addresses import (
|
||||
encodeVarint, decodeVarint, decodeAddress, varintDecodeError)
|
||||
from bmconfigparser import BMConfigParser
|
||||
from debug import logger
|
||||
from fallback import RIPEMD160Hash
|
||||
from helper_sql import sqlExecute
|
||||
from version import softwareVersion
|
||||
from .bmconfigparser import BMConfigParser
|
||||
from .debug import logger
|
||||
from .fallback import RIPEMD160Hash
|
||||
from .helper_sql import sqlExecute
|
||||
from .version import softwareVersion
|
||||
|
||||
# Service flags
|
||||
#: This is a normal network node
|
||||
|
|
|
@ -2,24 +2,19 @@
|
|||
|
||||
import threading
|
||||
import time
|
||||
try:
|
||||
import queue as Queue
|
||||
except ImportError:
|
||||
import Queue
|
||||
|
||||
try:
|
||||
from multiqueue import MultiQueue
|
||||
except ImportError:
|
||||
from .multiqueue import MultiQueue
|
||||
from six.moves import queue
|
||||
|
||||
from .multiqueue import MultiQueue
|
||||
|
||||
|
||||
class ObjectProcessorQueue(Queue.Queue):
|
||||
class ObjectProcessorQueue(queue.Queue):
|
||||
"""Special queue class using lock for `.threads.objectProcessor`"""
|
||||
|
||||
maxSize = 32000000
|
||||
|
||||
def __init__(self):
|
||||
Queue.Queue.__init__(self)
|
||||
queue.Queue.__init__(self)
|
||||
self.sizeLock = threading.Lock()
|
||||
#: in Bytes. We maintain this to prevent nodes from flooding us
|
||||
#: with objects which take up too much memory. If this gets
|
||||
|
@ -31,27 +26,27 @@ class ObjectProcessorQueue(Queue.Queue):
|
|||
time.sleep(1)
|
||||
with self.sizeLock:
|
||||
self.curSize += len(item[1])
|
||||
Queue.Queue.put(self, item, block, timeout)
|
||||
queue.Queue.put(self, item, block, timeout)
|
||||
|
||||
def get(self, block=True, timeout=None):
|
||||
item = Queue.Queue.get(self, block, timeout)
|
||||
item = queue.Queue.get(self, block, timeout)
|
||||
with self.sizeLock:
|
||||
self.curSize -= len(item[1])
|
||||
return item
|
||||
|
||||
|
||||
workerQueue = Queue.Queue()
|
||||
UISignalQueue = Queue.Queue()
|
||||
addressGeneratorQueue = Queue.Queue()
|
||||
workerQueue = queue.Queue()
|
||||
UISignalQueue = queue.Queue()
|
||||
addressGeneratorQueue = queue.Queue()
|
||||
#: `.network.ReceiveQueueThread` instances dump objects they hear
|
||||
#: on the network into this queue to be processed.
|
||||
objectProcessorQueue = ObjectProcessorQueue()
|
||||
invQueue = MultiQueue()
|
||||
addrQueue = MultiQueue()
|
||||
portCheckerQueue = Queue.Queue()
|
||||
receiveDataQueue = Queue.Queue()
|
||||
portCheckerQueue = queue.Queue()
|
||||
receiveDataQueue = queue.Queue()
|
||||
#: The address generator thread uses this queue to get information back
|
||||
#: to the API thread.
|
||||
apiAddressGeneratorReturnQueue = Queue.Queue()
|
||||
apiAddressGeneratorReturnQueue = queue.Queue()
|
||||
#: for exceptions
|
||||
excQueue = Queue.Queue()
|
||||
excQueue = queue.Queue()
|
||||
|
|
|
@ -4,7 +4,7 @@ Track randomize ordered dict
|
|||
from threading import RLock
|
||||
from time import time
|
||||
|
||||
import helper_random
|
||||
from . import helper_random
|
||||
|
||||
|
||||
class RandomTrackingDict(object):
|
||||
|
|
|
@ -16,14 +16,12 @@ import sys
|
|||
from binascii import hexlify
|
||||
|
||||
# Project imports.
|
||||
import highlevelcrypto
|
||||
import state
|
||||
from addresses import decodeAddress, encodeVarint
|
||||
from bmconfigparser import BMConfigParser
|
||||
from debug import logger
|
||||
from helper_sql import sqlQuery
|
||||
|
||||
from pyelliptic import arithmetic
|
||||
from . import highlevelcrypto, state
|
||||
from .addresses import decodeAddress, encodeVarint
|
||||
from .bmconfigparser import BMConfigParser
|
||||
from .debug import logger
|
||||
from .helper_sql import sqlQuery
|
||||
from .pyelliptic import arithmetic
|
||||
|
||||
|
||||
myECCryptorObjects = {}
|
||||
|
|
|
@ -4,13 +4,13 @@ import Queue
|
|||
import threading
|
||||
import time
|
||||
|
||||
import state
|
||||
from debug import logger
|
||||
from helper_sql import sqlQuery, sqlStoredProcedure
|
||||
from inventory import Inventory
|
||||
from network import StoppableThread
|
||||
from network.knownnodes import saveKnownNodes
|
||||
from queues import (
|
||||
from . import state
|
||||
from .debug import logger
|
||||
from .helper_sql import sqlQuery, sqlStoredProcedure
|
||||
from .inventory import Inventory
|
||||
from .network import StoppableThread
|
||||
from .network.knownnodes import saveKnownNodes
|
||||
from .queues import (
|
||||
addressGeneratorQueue, objectProcessorQueue, UISignalQueue, workerQueue)
|
||||
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ import atexit
|
|||
import os
|
||||
import sys
|
||||
|
||||
import state
|
||||
from . import state
|
||||
|
||||
try:
|
||||
import fcntl # @UnresolvedImport
|
||||
|
|
|
@ -8,7 +8,7 @@ from binascii import hexlify, unhexlify
|
|||
from os import listdir, makedirs, path, remove, rmdir
|
||||
from threading import RLock
|
||||
|
||||
from paths import lookupAppdataFolder
|
||||
from pybitmessage.paths import lookupAppdataFolder
|
||||
from storage import InventoryItem, InventoryStorage
|
||||
|
||||
logger = logging.getLogger('default')
|
||||
|
|
|
@ -5,7 +5,8 @@ import sqlite3
|
|||
import time
|
||||
from threading import RLock
|
||||
|
||||
from helper_sql import SqlBulkExecute, sqlExecute, sqlQuery
|
||||
|
||||
from pybitmessage.helper_sql import SqlBulkExecute, sqlExecute, sqlQuery
|
||||
from storage import InventoryItem, InventoryStorage
|
||||
|
||||
|
||||
|
|
|
@ -15,11 +15,11 @@ There are also other threads in the `.network` package.
|
|||
|
||||
import threading
|
||||
|
||||
from class_addressGenerator import addressGenerator
|
||||
from class_objectProcessor import objectProcessor
|
||||
from class_singleCleaner import singleCleaner
|
||||
from class_singleWorker import singleWorker
|
||||
from class_sqlThread import sqlThread
|
||||
from .class_addressGenerator import addressGenerator
|
||||
from .class_objectProcessor import objectProcessor
|
||||
from .class_singleCleaner import singleCleaner
|
||||
from .class_singleWorker import singleWorker
|
||||
from .class_sqlThread import sqlThread
|
||||
|
||||
try:
|
||||
import prctl
|
||||
|
|
|
@ -3,11 +3,7 @@ Translating text
|
|||
"""
|
||||
import os
|
||||
|
||||
import sys
|
||||
if sys.version_info[0] == 3:
|
||||
from . import state
|
||||
else:
|
||||
import state
|
||||
from . import state
|
||||
|
||||
|
||||
class translateClass:
|
||||
|
|
33
src/upnp.py
33
src/upnp.py
|
@ -1,4 +1,4 @@
|
|||
# pylint: disable=too-many-statements,too-many-branches,protected-access,no-self-use
|
||||
# pylint: disable=too-many-statements,too-many-branches,no-self-use
|
||||
"""
|
||||
Complete UPnP port forwarding implementation in separate thread.
|
||||
Reference: http://mattscodecave.com/posts/using-python-and-upnp-to-forward-a-port
|
||||
|
@ -12,13 +12,12 @@ from random import randint
|
|||
from urlparse import urlparse
|
||||
from xml.dom.minidom import Document, parseString
|
||||
|
||||
import queues
|
||||
import state
|
||||
import tr
|
||||
from bmconfigparser import BMConfigParser
|
||||
from debug import logger
|
||||
from network import BMConnectionPool, knownnodes, StoppableThread
|
||||
from network.node import Peer
|
||||
from . import queues, state
|
||||
from .bmconfigparser import BMConfigParser
|
||||
from .debug import logger
|
||||
from .network import BMConnectionPool, knownnodes, StoppableThread
|
||||
from .network.node import Peer
|
||||
from .tr import _translate
|
||||
|
||||
|
||||
def createRequestXML(service, action, arguments=None):
|
||||
|
@ -269,14 +268,19 @@ class uPnPThread(StoppableThread):
|
|||
with knownnodes.knownNodesLock:
|
||||
knownnodes.addKnownNode(
|
||||
1, self_peer, is_self=True)
|
||||
queues.UISignalQueue.put(('updateStatusBar', tr._translate(
|
||||
"MainWindow", 'UPnP port mapping established on port %1'
|
||||
).arg(str(self.extPort))))
|
||||
queues.UISignalQueue.put((
|
||||
'updateStatusBar',
|
||||
_translate(
|
||||
"MainWindow",
|
||||
"UPnP port mapping established on port %1"
|
||||
).arg(str(self.extPort))
|
||||
))
|
||||
break
|
||||
except socket.timeout:
|
||||
pass
|
||||
except:
|
||||
logger.error("Failure running UPnP router search.", exc_info=True)
|
||||
logger.error(
|
||||
'Failure running UPnP router search.', exc_info=True)
|
||||
for router in self.routers:
|
||||
if router.extPort is None:
|
||||
self.createPortMapping(router)
|
||||
|
@ -294,7 +298,10 @@ class uPnPThread(StoppableThread):
|
|||
deleted = True
|
||||
self.deletePortMapping(router)
|
||||
if deleted:
|
||||
queues.UISignalQueue.put(('updateStatusBar', tr._translate("MainWindow", 'UPnP port mapping removed')))
|
||||
queues.UISignalQueue.put((
|
||||
'updateStatusBar',
|
||||
_translate("MainWindow", "UPnP port mapping removed")
|
||||
))
|
||||
logger.debug("UPnP thread done")
|
||||
|
||||
def getLocalIP(self):
|
||||
|
|
Reference in New Issue
Block a user