Global imports.

This commit is contained in:
Dmitri Bogomolov 2020-07-10 18:53:35 +03:00
parent 16a11775e8
commit 525aa099f3
Signed by untrusted user: g1itch
GPG Key ID: 720A756F18DEED13
82 changed files with 1404 additions and 1323 deletions

View File

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

View File

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

View File

@ -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()
@ -744,11 +756,12 @@ class MyForm(settingsmixin.SMainWindow):
# 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))
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(
@ -813,7 +826,8 @@ class MyForm(settingsmixin.SMainWindow):
TTL = 3600
elif TTL > 28 * 24 * 60 * 60: # 28 days
TTL = 28 * 24 * 60 * 60
self.ui.horizontalSliderTTL.setSliderPosition((TTL - 3600) ** (1/3.199))
self.ui.horizontalSliderTTL.setSliderPosition(
(TTL - 3600) ** (1 / 3.199))
self.updateHumanFriendlyTTLDescription(TTL)
QtCore.QObject.connect(self.ui.horizontalSliderTTL, QtCore.SIGNAL(
@ -879,15 +893,18 @@ class MyForm(settingsmixin.SMainWindow):
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))
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,12 +1972,20 @@ 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()
@ -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,16 +2166,19 @@ 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(
@ -2144,18 +2241,34 @@ class MyForm(settingsmixin.SMainWindow):
"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,14 +2378,20 @@ 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.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(
@ -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
@ -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()

View File

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

View File

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

View File

@ -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(
self.setError(_translate(
"AddressValidator",
"Although the Bitmessage address you "
"entered was valid, it doesn't match the chan name."))
"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(
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."))
"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)

View File

@ -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,8 +757,6 @@ class Ui_MainWindow(object):
self.updateNetworkSwitchMenuLabel()
import bitmessage_icons_rc
if __name__ == "__main__":
import sys
@ -785,4 +766,3 @@ if __name__ == "__main__":
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())

View File

@ -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):
@ -28,27 +28,33 @@ class Blacklist(QtGui.QWidget, RetranslateMixin):
# 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))
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=?'''
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,34 +121,36 @@ 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=?''',
sqlExecute(
'UPDATE blacklist SET label=? WHERE address=?',
str(item.text()), str(addressitem.text()))
else:
sqlExecute('''UPDATE whitelist SET label=? WHERE address=?''',
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.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.tableWidgetBlacklist.setContextMenuPolicy(
@ -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)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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,
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,
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,
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(
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(network.stats.uploadSpeed()),
self.formatBytes(network.stats.sentBytes())))
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':
# 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 self.tableWidgetConnectionCount.rowCount() == 0 and state.statusIconColor != "red":
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,8 +214,7 @@ class NetworkStatus(QtGui.QWidget, RetranslateMixin):
def retranslateUi(self):
"""Conventional Qt Designer method for dynamic l10n"""
super(NetworkStatus, self).retranslateUi()
self.labelTotalConnections.setText(
_translate(
self.labelTotalConnections.setText(_translate(
"networkstatus", "Total Connections: %1").arg(
str(self.tableWidgetConnectionCount.rowCount())))
self.labelStartupTime.setText(_translate(

View File

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

View File

@ -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):
@ -13,6 +14,8 @@ class RetranslateMixin(object):
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())
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())
getattr(self, attr).verticalHeaderItem(i).setText(
getattr(defaults, attr).verticalHeaderItem(i).text())

View File

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

View File

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

View File

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

View File

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

View File

@ -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]'

View File

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

View File

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

View File

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

View File

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

View File

@ -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',

View File

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

View File

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

View File

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

View File

@ -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 . import helper_sql, helper_startup, paths, queues, state
from .addresses import encodeAddress
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 .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:

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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
NoneType = type(None)

View File

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

View File

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

View File

@ -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 . import defaults, helper_random, paths, state
from .bmconfigparser import BMConfigParser
else:
import defaults
import helper_random
import paths
import 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

View File

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

View File

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

View File

@ -5,7 +5,7 @@ import logging
import os
import time
from bmconfigparser import BMConfigParser
from .bmconfigparser import BMConfigParser
logger = logging.getLogger('default')

View File

@ -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 six.moves import queue
from . import helper_random
else:
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):

View File

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

View File

@ -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__ = [

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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)))
elif tried:
queues.UISignalQueue.put(
(
queues.UISignalQueue.put((
'updateStatusBar', (
tr._translate(
_translate("proofofwork", "C PoW module built successfully."),
1)
))
elif tried:
queues.UISignalQueue.put((
'updateStatusBar', (
_translate(
"proofofwork",
"Failed to build C PoW module. Please build it manually."
),
1
)
)
)
"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:

View File

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

View File

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

View File

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

View File

@ -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 = {}

View File

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

View File

@ -8,7 +8,7 @@ import atexit
import os
import sys
import state
from . import state
try:
import fcntl # @UnresolvedImport

View File

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

View File

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

View File

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

View File

@ -3,11 +3,7 @@ Translating text
"""
import os
import sys
if sys.version_info[0] == 3:
from . import state
else:
import state
class translateClass:

View File

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