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