Fixed: Style and lint violations for three more of the worst violatin… #1264

Merged
coffeedogs merged 3 commits from codeQ-2805 into v0.6 2018-06-26 15:21:22 +02:00
3 changed files with 462 additions and 243 deletions
Showing only changes of commit 759b760977 - Show all commits

View File

@ -1,26 +1,58 @@
from PyQt4 import QtCore, QtGui # pylint: disable=too-many-instance-attributes,attribute-defined-outside-init
"""
account.py
==========
import queues Account related functions.
"""
from __future__ import absolute_import
import inspect
import re import re
import sys import sys
import inspect
from helper_sql import *
from helper_ackPayload import genAckPayload
from addresses import decodeAddress
from bmconfigparser import BMConfigParser
from foldertree import AccountMixin
from pyelliptic.openssl import OpenSSL
from utils import str_broadcast_subscribers
import time import time
from PyQt4 import QtGui
import queues
from addresses import decodeAddress
from bmconfigparser import BMConfigParser
from helper_ackPayload import genAckPayload
from helper_sql import sqlQuery, sqlExecute
from .foldertree import AccountMixin
from .utils import str_broadcast_subscribers
def getSortedAccounts(): def getSortedAccounts():
"""Get a sorted list of configSections"""
configSections = BMConfigParser().addresses() configSections = BMConfigParser().addresses()
configSections.sort(cmp = configSections.sort(
lambda x,y: cmp(unicode(BMConfigParser().get(x, 'label'), 'utf-8').lower(), unicode(BMConfigParser().get(y, 'label'), 'utf-8').lower()) cmp=lambda x, y: cmp(
) unicode(
BMConfigParser().get(
x,
'label'),
'utf-8').lower(),
unicode(
BMConfigParser().get(
y,
'label'),
'utf-8').lower()))
return configSections return configSections
def getSortedSubscriptions(count=False): def getSortedSubscriptions(count=False):
"""
Actually return a grouped dictionary rather than a sorted list
:param count: Whether to count messages for each fromaddress in the inbox
:type count: bool, default False
:retuns: dict keys are addresses, values are dicts containing settings
:rtype: dict, default {}
"""
queryreturn = sqlQuery('SELECT label, address, enabled FROM subscriptions ORDER BY label COLLATE NOCASE ASC') queryreturn = sqlQuery('SELECT label, address, enabled FROM subscriptions ORDER BY label COLLATE NOCASE ASC')
ret = {} ret = {}
for row in queryreturn: for row in queryreturn:
@ -37,7 +69,7 @@ def getSortedSubscriptions(count = False):
GROUP BY inbox.fromaddress, folder''', str_broadcast_subscribers) GROUP BY inbox.fromaddress, folder''', str_broadcast_subscribers)
for row in queryreturn: for row in queryreturn:
address, folder, cnt = row address, folder, cnt = row
if not folder in ret[address]: if folder not in ret[address]:
ret[address][folder] = { ret[address][folder] = {
'label': ret[address]['inbox']['label'], 'label': ret[address]['inbox']['label'],
'enabled': ret[address]['inbox']['enabled'] 'enabled': ret[address]['inbox']['enabled']
@ -45,9 +77,11 @@ def getSortedSubscriptions(count = False):
ret[address][folder]['count'] = cnt ret[address][folder]['count'] = cnt
return ret return ret
def accountClass(address): def accountClass(address):
"""Return a BMAccount for the address"""
if not BMConfigParser().has_section(address): if not BMConfigParser().has_section(address):
# FIXME: This BROADCAST section makes no sense # .. todo:: This BROADCAST section makes no sense
if address == str_broadcast_subscribers: if address == str_broadcast_subscribers:
subscription = BroadcastAccount(address) subscription = BroadcastAccount(address)
if subscription.type != AccountMixin.BROADCAST: if subscription.type != AccountMixin.BROADCAST:
@ -60,8 +94,7 @@ def accountClass(address):
return subscription return subscription
try: try:
gateway = BMConfigParser().get(address, "gateway") gateway = BMConfigParser().get(address, "gateway")
for name, cls in inspect.getmembers(sys.modules[__name__], inspect.isclass): for _, cls in inspect.getmembers(sys.modules[__name__], inspect.isclass):
# obj = g(address)
if issubclass(cls, GatewayAccount) and cls.gatewayName == gateway: if issubclass(cls, GatewayAccount) and cls.gatewayName == gateway:
return cls(address) return cls(address)
# general gateway # general gateway
@ -71,11 +104,14 @@ def accountClass(address):
# no gateway # no gateway
return BMAccount(address) return BMAccount(address)
class AccountColor(AccountMixin):
def __init__(self, address, type = None): class AccountColor(AccountMixin): # pylint: disable=too-few-public-methods
"""Set the type of account"""
def __init__(self, address, address_type=None):
self.isEnabled = True self.isEnabled = True
self.address = address self.address = address
if type is None: if address_type is None:
if address is None: if address is None:
self.type = AccountMixin.ALL self.type = AccountMixin.ALL
elif BMConfigParser().safeGetBoolean(self.address, 'mailinglist'): elif BMConfigParser().safeGetBoolean(self.address, 'mailinglist'):
@ -88,10 +124,12 @@ class AccountColor(AccountMixin):
else: else:
self.type = AccountMixin.NORMAL self.type = AccountMixin.NORMAL
else: else:
self.type = type self.type = address_type
class BMAccount(object): class BMAccount(object):
"""Encapsulate a Bitmessage account"""
def __init__(self, address=None): def __init__(self, address=None):
self.address = address self.address = address
self.type = AccountMixin.NORMAL self.type = AccountMixin.NORMAL
@ -109,6 +147,7 @@ class BMAccount(object):
self.type = AccountMixin.SUBSCRIPTION self.type = AccountMixin.SUBSCRIPTION
def getLabel(self, address=None): def getLabel(self, address=None):
"""Get a label for this bitmessage account"""
if address is None: if address is None:
address = self.address address = self.address
label = address label = address
@ -128,6 +167,8 @@ class BMAccount(object):
return label return label
def parseMessage(self, toAddress, fromAddress, subject, message): def parseMessage(self, toAddress, fromAddress, subject, message):
"""Set metadata and address labels on self"""
self.toAddress = toAddress self.toAddress = toAddress
self.fromAddress = fromAddress self.fromAddress = fromAddress
if isinstance(subject, unicode): if isinstance(subject, unicode):
@ -140,7 +181,9 @@ class BMAccount(object):
class NoAccount(BMAccount): class NoAccount(BMAccount):
def __init__(self, address = None): """Override the __init__ method on a BMAccount"""
def __init__(self, address=None): # pylint: disable=super-init-not-called
self.address = address self.address = address
self.type = AccountMixin.NORMAL self.type = AccountMixin.NORMAL
@ -151,25 +194,32 @@ class NoAccount(BMAccount):
class SubscriptionAccount(BMAccount): class SubscriptionAccount(BMAccount):
"""Encapsulate a subscription account"""
pass pass
class BroadcastAccount(BMAccount): class BroadcastAccount(BMAccount):
"""Encapsulate a broadcast account"""
pass pass
class GatewayAccount(BMAccount): class GatewayAccount(BMAccount):
"""Encapsulate a gateway account"""
gatewayName = None gatewayName = None
ALL_OK = 0 ALL_OK = 0
REGISTRATION_DENIED = 1 REGISTRATION_DENIED = 1
def __init__(self, address): def __init__(self, address):
super(GatewayAccount, self).__init__(address) super(GatewayAccount, self).__init__(address)
def send(self): def send(self):
"""Override the send method for gateway accounts"""
# pylint: disable=unused-variable
status, addressVersionNumber, streamNumber, ripe = decodeAddress(self.toAddress) status, addressVersionNumber, streamNumber, ripe = decodeAddress(self.toAddress)
stealthLevel = BMConfigParser().safeGetInt('bitmessagesettings', 'ackstealthlevel') stealthLevel = BMConfigParser().safeGetInt('bitmessagesettings', 'ackstealthlevel')
ackdata = genAckPayload(streamNumber, stealthLevel) ackdata = genAckPayload(streamNumber, stealthLevel)
t = ()
sqlExecute( sqlExecute(
'''INSERT INTO sent VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)''', '''INSERT INTO sent VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)''',
'', '',
@ -186,33 +236,37 @@ class GatewayAccount(BMAccount):
0, # retryNumber 0, # retryNumber
'sent', # folder 'sent', # folder
2, # encodingtype 2, # encodingtype
min(BMConfigParser().getint('bitmessagesettings', 'ttl'), 86400 * 2) # not necessary to have a TTL higher than 2 days # not necessary to have a TTL higher than 2 days
min(BMConfigParser().getint('bitmessagesettings', 'ttl'), 86400 * 2)
) )
queues.workerQueue.put(('sendmessage', self.toAddress)) queues.workerQueue.put(('sendmessage', self.toAddress))
def parseMessage(self, toAddress, fromAddress, subject, message):
super(GatewayAccount, self).parseMessage(toAddress, fromAddress, subject, message)
class MailchuckAccount(GatewayAccount): class MailchuckAccount(GatewayAccount):
"""Encapsulate a particular kind of gateway account"""
# set "gateway" in keys.dat to this # set "gateway" in keys.dat to this
gatewayName = "mailchuck" gatewayName = "mailchuck"
registrationAddress = "BM-2cVYYrhaY5Gbi3KqrX9Eae2NRNrkfrhCSA" registrationAddress = "BM-2cVYYrhaY5Gbi3KqrX9Eae2NRNrkfrhCSA"
unregistrationAddress = "BM-2cVMAHTRjZHCTPMue75XBK5Tco175DtJ9J" unregistrationAddress = "BM-2cVMAHTRjZHCTPMue75XBK5Tco175DtJ9J"
relayAddress = "BM-2cWim8aZwUNqxzjMxstnUMtVEUQJeezstf" relayAddress = "BM-2cWim8aZwUNqxzjMxstnUMtVEUQJeezstf"
regExpIncoming = re.compile("(.*)MAILCHUCK-FROM::(\S+) \| (.*)") regExpIncoming = re.compile(r"(.*)MAILCHUCK-FROM::(\S+) \| (.*)")
regExpOutgoing = re.compile("(\S+) (.*)") regExpOutgoing = re.compile(r"(\S+) (.*)")
def __init__(self, address): def __init__(self, address):
super(MailchuckAccount, self).__init__(address) super(MailchuckAccount, self).__init__(address)
self.feedback = self.ALL_OK self.feedback = self.ALL_OK
def createMessage(self, toAddress, fromAddress, subject, message): def createMessage(self, toAddress, fromAddress, subject, message):
"""createMessage specific to a MailchuckAccount"""
self.subject = toAddress + " " + subject self.subject = toAddress + " " + subject
self.toAddress = self.relayAddress self.toAddress = self.relayAddress
self.fromAddress = fromAddress self.fromAddress = fromAddress
self.message = message self.message = message
def register(self, email): def register(self, email):
"""register specific to a MailchuckAccount"""
self.toAddress = self.registrationAddress self.toAddress = self.registrationAddress
self.subject = email self.subject = email
self.message = "" self.message = ""
@ -220,6 +274,7 @@ class MailchuckAccount(GatewayAccount):
self.send() self.send()
def unregister(self): def unregister(self):
"""unregister specific to a MailchuckAccount"""
self.toAddress = self.unregistrationAddress self.toAddress = self.unregistrationAddress
self.subject = "" self.subject = ""
self.message = "" self.message = ""
@ -227,6 +282,7 @@ class MailchuckAccount(GatewayAccount):
self.send() self.send()
def status(self): def status(self):
"""status specific to a MailchuckAccount"""
self.toAddress = self.registrationAddress self.toAddress = self.registrationAddress
self.subject = "status" self.subject = "status"
self.message = "" self.message = ""
@ -234,9 +290,13 @@ class MailchuckAccount(GatewayAccount):
self.send() self.send()
def settings(self): def settings(self):
"""settings specific to a MailchuckAccount"""
self.toAddress = self.registrationAddress self.toAddress = self.registrationAddress
self.subject = "config" self.subject = "config"
self.message = QtGui.QApplication.translate("Mailchuck", """# You can use this to configure your email gateway account self.message = QtGui.QApplication.translate(
"Mailchuck",
"""# You can use this to configure your email gateway account
# Uncomment the setting you want to use # Uncomment the setting you want to use
# Here are the options: # Here are the options:
# #
@ -279,10 +339,12 @@ class MailchuckAccount(GatewayAccount):
self.fromAddress = self.address self.fromAddress = self.address
def parseMessage(self, toAddress, fromAddress, subject, message): def parseMessage(self, toAddress, fromAddress, subject, message):
"""parseMessage specific to a MailchuckAccount"""
super(MailchuckAccount, self).parseMessage(toAddress, fromAddress, subject, message) super(MailchuckAccount, self).parseMessage(toAddress, fromAddress, subject, message)
if fromAddress == self.relayAddress: if fromAddress == self.relayAddress:
matches = self.regExpIncoming.search(subject) matches = self.regExpIncoming.search(subject)
if not matches is None: if matches is not None:
self.subject = "" self.subject = ""
if not matches.group(1) is None: if not matches.group(1) is None:
self.subject += matches.group(1) self.subject += matches.group(1)
@ -293,7 +355,7 @@ class MailchuckAccount(GatewayAccount):
self.fromAddress = matches.group(2) self.fromAddress = matches.group(2)
if toAddress == self.relayAddress: if toAddress == self.relayAddress:
matches = self.regExpOutgoing.search(subject) matches = self.regExpOutgoing.search(subject)
if not matches is None: if matches is not None:
if not matches.group(2) is None: if not matches.group(2) is None:
self.subject = matches.group(2) self.subject = matches.group(2)
if not matches.group(1) is None: if not matches.group(1) is None:

View File

@ -1,15 +1,23 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# pylint: disable=too-many-instance-attributes,too-many-locals,too-many-statements,attribute-defined-outside-init
"""
Form implementation generated from reading ui file 'settings.ui'
# Form implementation generated from reading ui file 'settings.ui' Created: Thu Dec 25 23:21:20 2014
# by: PyQt4 UI code generator 4.10.3
# Created: Thu Dec 25 23:21:20 2014
# by: PyQt4 UI code generator 4.10.3 WARNING! All changes made in this file will be lost!
# """
# WARNING! All changes made in this file will be lost!
from __future__ import absolute_import
from sys import platform
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from languagebox import LanguageBox
from sys import platform from . import bitmessage_icons_rc # pylint: disable=unused-import
from .languagebox import LanguageBox
try: try:
_fromUtf8 = QtCore.QString.fromUtf8 _fromUtf8 = QtCore.QString.fromUtf8
@ -19,14 +27,20 @@ except AttributeError:
g1itch commented 2018-06-26 15:58:58 +02:00 (Migrated from github.com)
Review

This imports are breaking bundled usage

This imports are breaking bundled usage
PeterSurda commented 2018-06-26 16:08:44 +02:00 (Migrated from github.com)
Review

You mean the frozen mode?

You mean the frozen mode?
try: try:
_encoding = QtGui.QApplication.UnicodeUTF8 _encoding = QtGui.QApplication.UnicodeUTF8
def _translate(context, text, disambig): def _translate(context, text, disambig):
return QtGui.QApplication.translate(context, text, disambig, _encoding) return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError: except AttributeError:
def _translate(context, text, disambig): def _translate(context, text, disambig):
return QtGui.QApplication.translate(context, text, disambig) return QtGui.QApplication.translate(context, text, disambig)
class Ui_settingsDialog(object): class Ui_settingsDialog(object):
"""Encapsulate a UI settings dialog object"""
def setupUi(self, settingsDialog): def setupUi(self, settingsDialog):
"""Set up the UI"""
settingsDialog.setObjectName(_fromUtf8("settingsDialog")) settingsDialog.setObjectName(_fromUtf8("settingsDialog"))
settingsDialog.resize(521, 413) settingsDialog.resize(521, 413)
self.gridLayout = QtGui.QGridLayout(settingsDialog) self.gridLayout = QtGui.QGridLayout(settingsDialog)
@ -64,7 +78,8 @@ class Ui_settingsDialog(object):
self.formLayout.setWidget(1, QtGui.QFormLayout.SpanningRole, self.groupBoxTray) self.formLayout.setWidget(1, QtGui.QFormLayout.SpanningRole, self.groupBoxTray)
self.checkBoxHideTrayConnectionNotifications = QtGui.QCheckBox(self.tabUserInterface) self.checkBoxHideTrayConnectionNotifications = QtGui.QCheckBox(self.tabUserInterface)
self.checkBoxHideTrayConnectionNotifications.setChecked(False) self.checkBoxHideTrayConnectionNotifications.setChecked(False)
self.checkBoxHideTrayConnectionNotifications.setObjectName(_fromUtf8("checkBoxHideTrayConnectionNotifications")) self.checkBoxHideTrayConnectionNotifications.setObjectName(
_fromUtf8("checkBoxHideTrayConnectionNotifications"))
self.formLayout.setWidget(2, QtGui.QFormLayout.LabelRole, self.checkBoxHideTrayConnectionNotifications) self.formLayout.setWidget(2, QtGui.QFormLayout.LabelRole, self.checkBoxHideTrayConnectionNotifications)
self.checkBoxShowTrayNotifications = QtGui.QCheckBox(self.tabUserInterface) self.checkBoxShowTrayNotifications = QtGui.QCheckBox(self.tabUserInterface)
self.checkBoxShowTrayNotifications.setObjectName(_fromUtf8("checkBoxShowTrayNotifications")) self.checkBoxShowTrayNotifications.setObjectName(_fromUtf8("checkBoxShowTrayNotifications"))
@ -96,7 +111,7 @@ class Ui_settingsDialog(object):
self.formLayout_2.setObjectName(_fromUtf8("formLayout_2")) self.formLayout_2.setObjectName(_fromUtf8("formLayout_2"))
self.languageComboBox = LanguageBox(self.groupBox) self.languageComboBox = LanguageBox(self.groupBox)
self.languageComboBox.setMinimumSize(QtCore.QSize(100, 0)) self.languageComboBox.setMinimumSize(QtCore.QSize(100, 0))
self.languageComboBox.setObjectName(_fromUtf8("languageComboBox")) self.languageComboBox.setObjectName(_fromUtf8("languageComboBox")) # pylint: disable=not-callable
self.formLayout_2.setWidget(0, QtGui.QFormLayout.LabelRole, self.languageComboBox) self.formLayout_2.setWidget(0, QtGui.QFormLayout.LabelRole, self.languageComboBox)
self.formLayout.setWidget(9, QtGui.QFormLayout.FieldRole, self.groupBox) self.formLayout.setWidget(9, QtGui.QFormLayout.FieldRole, self.groupBox)
self.tabWidgetSettings.addTab(self.tabUserInterface, _fromUtf8("")) self.tabWidgetSettings.addTab(self.tabUserInterface, _fromUtf8(""))
@ -108,8 +123,6 @@ class Ui_settingsDialog(object):
self.groupBox1.setObjectName(_fromUtf8("groupBox1")) self.groupBox1.setObjectName(_fromUtf8("groupBox1"))
self.gridLayout_3 = QtGui.QGridLayout(self.groupBox1) self.gridLayout_3 = QtGui.QGridLayout(self.groupBox1)
self.gridLayout_3.setObjectName(_fromUtf8("gridLayout_3")) self.gridLayout_3.setObjectName(_fromUtf8("gridLayout_3"))
#spacerItem = QtGui.QSpacerItem(125, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
#self.gridLayout_3.addItem(spacerItem, 0, 0, 1, 1)
self.label = QtGui.QLabel(self.groupBox1) self.label = QtGui.QLabel(self.groupBox1)
self.label.setObjectName(_fromUtf8("label")) self.label.setObjectName(_fromUtf8("label"))
self.gridLayout_3.addWidget(self.label, 0, 0, 1, 1, QtCore.Qt.AlignRight) self.gridLayout_3.addWidget(self.label, 0, 0, 1, 1, QtCore.Qt.AlignRight)
@ -165,7 +178,8 @@ class Ui_settingsDialog(object):
self.lineEditMaxOutboundConnections.setSizePolicy(sizePolicy) self.lineEditMaxOutboundConnections.setSizePolicy(sizePolicy)
self.lineEditMaxOutboundConnections.setMaximumSize(QtCore.QSize(60, 16777215)) self.lineEditMaxOutboundConnections.setMaximumSize(QtCore.QSize(60, 16777215))
self.lineEditMaxOutboundConnections.setObjectName(_fromUtf8("lineEditMaxOutboundConnections")) self.lineEditMaxOutboundConnections.setObjectName(_fromUtf8("lineEditMaxOutboundConnections"))
self.lineEditMaxOutboundConnections.setValidator(QtGui.QIntValidator(0, 8, self.lineEditMaxOutboundConnections)) self.lineEditMaxOutboundConnections.setValidator(
QtGui.QIntValidator(0, 8, self.lineEditMaxOutboundConnections))
self.gridLayout_9.addWidget(self.lineEditMaxOutboundConnections, 2, 2, 1, 1) self.gridLayout_9.addWidget(self.lineEditMaxOutboundConnections, 2, 2, 1, 1)
self.gridLayout_4.addWidget(self.groupBox_3, 2, 0, 1, 1) self.gridLayout_4.addWidget(self.groupBox_3, 2, 0, 1, 1)
self.groupBox_2 = QtGui.QGroupBox(self.tabNetworkSettings) self.groupBox_2 = QtGui.QGroupBox(self.tabNetworkSettings)
@ -207,7 +221,8 @@ class Ui_settingsDialog(object):
self.gridLayout_2.addWidget(self.label_6, 2, 4, 1, 1) self.gridLayout_2.addWidget(self.label_6, 2, 4, 1, 1)
self.lineEditSocksPassword = QtGui.QLineEdit(self.groupBox_2) self.lineEditSocksPassword = QtGui.QLineEdit(self.groupBox_2)
self.lineEditSocksPassword.setEnabled(False) self.lineEditSocksPassword.setEnabled(False)
self.lineEditSocksPassword.setInputMethodHints(QtCore.Qt.ImhHiddenText|QtCore.Qt.ImhNoAutoUppercase|QtCore.Qt.ImhNoPredictiveText) self.lineEditSocksPassword.setInputMethodHints(
QtCore.Qt.ImhHiddenText | QtCore.Qt.ImhNoAutoUppercase | QtCore.Qt.ImhNoPredictiveText)
self.lineEditSocksPassword.setEchoMode(QtGui.QLineEdit.Password) self.lineEditSocksPassword.setEchoMode(QtGui.QLineEdit.Password)
self.lineEditSocksPassword.setObjectName(_fromUtf8("lineEditSocksPassword")) self.lineEditSocksPassword.setObjectName(_fromUtf8("lineEditSocksPassword"))
self.gridLayout_2.addWidget(self.lineEditSocksPassword, 2, 5, 1, 1) self.gridLayout_2.addWidget(self.lineEditSocksPassword, 2, 5, 1, 1)
@ -215,7 +230,7 @@ class Ui_settingsDialog(object):
self.checkBoxSocksListen.setObjectName(_fromUtf8("checkBoxSocksListen")) self.checkBoxSocksListen.setObjectName(_fromUtf8("checkBoxSocksListen"))
self.gridLayout_2.addWidget(self.checkBoxSocksListen, 3, 1, 1, 4) self.gridLayout_2.addWidget(self.checkBoxSocksListen, 3, 1, 1, 4)
self.comboBoxProxyType = QtGui.QComboBox(self.groupBox_2) self.comboBoxProxyType = QtGui.QComboBox(self.groupBox_2)
self.comboBoxProxyType.setObjectName(_fromUtf8("comboBoxProxyType")) self.comboBoxProxyType.setObjectName(_fromUtf8("comboBoxProxyType")) # pylint: disable=not-callable
self.comboBoxProxyType.addItem(_fromUtf8("")) self.comboBoxProxyType.addItem(_fromUtf8(""))
self.comboBoxProxyType.addItem(_fromUtf8("")) self.comboBoxProxyType.addItem(_fromUtf8(""))
self.comboBoxProxyType.addItem(_fromUtf8("")) self.comboBoxProxyType.addItem(_fromUtf8(""))
@ -310,7 +325,8 @@ class Ui_settingsDialog(object):
sizePolicy.setHeightForWidth(self.lineEditMaxAcceptableSmallMessageDifficulty.sizePolicy().hasHeightForWidth()) sizePolicy.setHeightForWidth(self.lineEditMaxAcceptableSmallMessageDifficulty.sizePolicy().hasHeightForWidth())
self.lineEditMaxAcceptableSmallMessageDifficulty.setSizePolicy(sizePolicy) self.lineEditMaxAcceptableSmallMessageDifficulty.setSizePolicy(sizePolicy)
self.lineEditMaxAcceptableSmallMessageDifficulty.setMaximumSize(QtCore.QSize(70, 16777215)) self.lineEditMaxAcceptableSmallMessageDifficulty.setMaximumSize(QtCore.QSize(70, 16777215))
self.lineEditMaxAcceptableSmallMessageDifficulty.setObjectName(_fromUtf8("lineEditMaxAcceptableSmallMessageDifficulty")) self.lineEditMaxAcceptableSmallMessageDifficulty.setObjectName(
_fromUtf8("lineEditMaxAcceptableSmallMessageDifficulty"))
self.gridLayout_7.addWidget(self.lineEditMaxAcceptableSmallMessageDifficulty, 2, 2, 1, 1) self.gridLayout_7.addWidget(self.lineEditMaxAcceptableSmallMessageDifficulty, 2, 2, 1, 1)
spacerItem8 = QtGui.QSpacerItem(20, 147, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) spacerItem8 = QtGui.QSpacerItem(20, 147, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
self.gridLayout_7.addItem(spacerItem8, 3, 1, 1, 1) self.gridLayout_7.addItem(spacerItem8, 3, 1, 1, 1)
@ -362,11 +378,13 @@ class Ui_settingsDialog(object):
spacerItem13 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) spacerItem13 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
self.gridLayout_8.addItem(spacerItem13, 5, 0, 1, 1) self.gridLayout_8.addItem(spacerItem13, 5, 0, 1, 1)
self.labelNamecoinPassword = QtGui.QLabel(self.tabNamecoin) self.labelNamecoinPassword = QtGui.QLabel(self.tabNamecoin)
self.labelNamecoinPassword.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) self.labelNamecoinPassword.setAlignment(
QtCore.Qt.AlignRight | QtCore.Qt.AlignTrailing | QtCore.Qt.AlignVCenter)
self.labelNamecoinPassword.setObjectName(_fromUtf8("labelNamecoinPassword")) self.labelNamecoinPassword.setObjectName(_fromUtf8("labelNamecoinPassword"))
self.gridLayout_8.addWidget(self.labelNamecoinPassword, 5, 1, 1, 1) self.gridLayout_8.addWidget(self.labelNamecoinPassword, 5, 1, 1, 1)
self.lineEditNamecoinPassword = QtGui.QLineEdit(self.tabNamecoin) self.lineEditNamecoinPassword = QtGui.QLineEdit(self.tabNamecoin)
self.lineEditNamecoinPassword.setInputMethodHints(QtCore.Qt.ImhHiddenText|QtCore.Qt.ImhNoAutoUppercase|QtCore.Qt.ImhNoPredictiveText) self.lineEditNamecoinPassword.setInputMethodHints(
QtCore.Qt.ImhHiddenText | QtCore.Qt.ImhNoAutoUppercase | QtCore.Qt.ImhNoPredictiveText)
self.lineEditNamecoinPassword.setEchoMode(QtGui.QLineEdit.Password) self.lineEditNamecoinPassword.setEchoMode(QtGui.QLineEdit.Password)
self.lineEditNamecoinPassword.setObjectName(_fromUtf8("lineEditNamecoinPassword")) self.lineEditNamecoinPassword.setObjectName(_fromUtf8("lineEditNamecoinPassword"))
self.gridLayout_8.addWidget(self.lineEditNamecoinPassword, 5, 2, 1, 1) self.gridLayout_8.addWidget(self.lineEditNamecoinPassword, 5, 2, 1, 1)
@ -431,10 +449,20 @@ class Ui_settingsDialog(object):
self.retranslateUi(settingsDialog) self.retranslateUi(settingsDialog)
self.tabWidgetSettings.setCurrentIndex(0) self.tabWidgetSettings.setCurrentIndex(0)
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("accepted()")), settingsDialog.accept) QtCore.QObject.connect( # pylint: disable=no-member
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("rejected()")), settingsDialog.reject) self.buttonBox, QtCore.SIGNAL(_fromUtf8("accepted()")), settingsDialog.accept)
QtCore.QObject.connect(self.checkBoxAuthentication, QtCore.SIGNAL(_fromUtf8("toggled(bool)")), self.lineEditSocksUsername.setEnabled) QtCore.QObject.connect( # pylint: disable=no-member
QtCore.QObject.connect(self.checkBoxAuthentication, QtCore.SIGNAL(_fromUtf8("toggled(bool)")), self.lineEditSocksPassword.setEnabled) self.buttonBox, QtCore.SIGNAL(_fromUtf8("rejected()")), settingsDialog.reject)
QtCore.QObject.connect( # pylint: disable=no-member
self.checkBoxAuthentication,
QtCore.SIGNAL(
_fromUtf8("toggled(bool)")),
self.lineEditSocksUsername.setEnabled)
QtCore.QObject.connect( # pylint: disable=no-member
self.checkBoxAuthentication,
QtCore.SIGNAL(
_fromUtf8("toggled(bool)")),
self.lineEditSocksPassword.setEnabled)
QtCore.QMetaObject.connectSlotsByName(settingsDialog) QtCore.QMetaObject.connectSlotsByName(settingsDialog)
settingsDialog.setTabOrder(self.tabWidgetSettings, self.checkBoxStartOnLogon) settingsDialog.setTabOrder(self.tabWidgetSettings, self.checkBoxStartOnLogon)
settingsDialog.setTabOrder(self.checkBoxStartOnLogon, self.checkBoxStartInTray) settingsDialog.setTabOrder(self.checkBoxStartOnLogon, self.checkBoxStartInTray)
@ -450,22 +478,47 @@ class Ui_settingsDialog(object):
settingsDialog.setTabOrder(self.checkBoxSocksListen, self.buttonBox) settingsDialog.setTabOrder(self.checkBoxSocksListen, self.buttonBox)
def retranslateUi(self, settingsDialog): def retranslateUi(self, settingsDialog):
"""Re-translate the UI into the supported languages"""
settingsDialog.setWindowTitle(_translate("settingsDialog", "Settings", None)) settingsDialog.setWindowTitle(_translate("settingsDialog", "Settings", None))
self.checkBoxStartOnLogon.setText(_translate("settingsDialog", "Start Bitmessage on user login", None)) self.checkBoxStartOnLogon.setText(_translate("settingsDialog", "Start Bitmessage on user login", None))
self.groupBoxTray.setTitle(_translate("settingsDialog", "Tray", None)) self.groupBoxTray.setTitle(_translate("settingsDialog", "Tray", None))
self.checkBoxStartInTray.setText(_translate("settingsDialog", "Start Bitmessage in the tray (don\'t show main window)", None)) self.checkBoxStartInTray.setText(
_translate(
"settingsDialog",
"Start Bitmessage in the tray (don\'t show main window)",
None))
self.checkBoxMinimizeToTray.setText(_translate("settingsDialog", "Minimize to tray", None)) self.checkBoxMinimizeToTray.setText(_translate("settingsDialog", "Minimize to tray", None))
self.checkBoxTrayOnClose.setText(_translate("settingsDialog", "Close to tray", None)) self.checkBoxTrayOnClose.setText(_translate("settingsDialog", "Close to tray", None))
self.checkBoxHideTrayConnectionNotifications.setText(_translate("settingsDialog", "Hide connection notifications", None)) self.checkBoxHideTrayConnectionNotifications.setText(
self.checkBoxShowTrayNotifications.setText(_translate("settingsDialog", "Show notification when message received", None)) _translate("settingsDialog", "Hide connection notifications", None))
self.checkBoxShowTrayNotifications.setText(
_translate(
"settingsDialog",
"Show notification when message received",
None))
self.checkBoxPortableMode.setText(_translate("settingsDialog", "Run in Portable Mode", None)) self.checkBoxPortableMode.setText(_translate("settingsDialog", "Run in Portable Mode", None))
self.PortableModeDescription.setText(_translate("settingsDialog", "In Portable Mode, messages and config files are stored in the same directory as the program rather than the normal application-data folder. This makes it convenient to run Bitmessage from a USB thumb drive.", None)) self.PortableModeDescription.setText(
self.checkBoxWillinglySendToMobile.setText(_translate("settingsDialog", "Willingly include unencrypted destination address when sending to a mobile device", None)) _translate(
"settingsDialog",
"In Portable Mode, messages and config files are stored in the same directory as the"
" program rather than the normal application-data folder. This makes it convenient to"
" run Bitmessage from a USB thumb drive.",
None))
self.checkBoxWillinglySendToMobile.setText(
_translate(
"settingsDialog",
"Willingly include unencrypted destination address when sending to a mobile device",
None))
self.checkBoxUseIdenticons.setText(_translate("settingsDialog", "Use Identicons", None)) self.checkBoxUseIdenticons.setText(_translate("settingsDialog", "Use Identicons", None))
self.checkBoxReplyBelow.setText(_translate("settingsDialog", "Reply below Quote", None)) self.checkBoxReplyBelow.setText(_translate("settingsDialog", "Reply below Quote", None))
self.groupBox.setTitle(_translate("settingsDialog", "Interface Language", None)) self.groupBox.setTitle(_translate("settingsDialog", "Interface Language", None))
self.languageComboBox.setItemText(0, _translate("settingsDialog", "System Settings", "system")) self.languageComboBox.setItemText(0, _translate("settingsDialog", "System Settings", "system"))
self.tabWidgetSettings.setTabText(self.tabWidgetSettings.indexOf(self.tabUserInterface), _translate("settingsDialog", "User Interface", None)) self.tabWidgetSettings.setTabText(
self.tabWidgetSettings.indexOf(
self.tabUserInterface),
_translate(
"settingsDialog", "User Interface", None))
self.groupBox1.setTitle(_translate("settingsDialog", "Listening port", None)) self.groupBox1.setTitle(_translate("settingsDialog", "Listening port", None))
self.label.setText(_translate("settingsDialog", "Listen for connections on port:", None)) self.label.setText(_translate("settingsDialog", "Listen for connections on port:", None))
self.labelUPnP.setText(_translate("settingsDialog", "UPnP:", None)) self.labelUPnP.setText(_translate("settingsDialog", "UPnP:", None))
@ -480,23 +533,70 @@ class Ui_settingsDialog(object):
self.checkBoxAuthentication.setText(_translate("settingsDialog", "Authentication", None)) self.checkBoxAuthentication.setText(_translate("settingsDialog", "Authentication", None))
self.label_5.setText(_translate("settingsDialog", "Username:", None)) self.label_5.setText(_translate("settingsDialog", "Username:", None))
self.label_6.setText(_translate("settingsDialog", "Pass:", None)) self.label_6.setText(_translate("settingsDialog", "Pass:", None))
self.checkBoxSocksListen.setText(_translate("settingsDialog", "Listen for incoming connections when using proxy", None)) self.checkBoxSocksListen.setText(
_translate(
"settingsDialog",
"Listen for incoming connections when using proxy",
None))
self.comboBoxProxyType.setItemText(0, _translate("settingsDialog", "none", None)) self.comboBoxProxyType.setItemText(0, _translate("settingsDialog", "none", None))
self.comboBoxProxyType.setItemText(1, _translate("settingsDialog", "SOCKS4a", None)) self.comboBoxProxyType.setItemText(1, _translate("settingsDialog", "SOCKS4a", None))
self.comboBoxProxyType.setItemText(2, _translate("settingsDialog", "SOCKS5", None)) self.comboBoxProxyType.setItemText(2, _translate("settingsDialog", "SOCKS5", None))
self.tabWidgetSettings.setTabText(self.tabWidgetSettings.indexOf(self.tabNetworkSettings), _translate("settingsDialog", "Network Settings", None)) self.tabWidgetSettings.setTabText(
self.tabWidgetSettings.indexOf(
self.tabNetworkSettings),
_translate(
"settingsDialog", "Network Settings", None))
self.label_9.setText(_translate("settingsDialog", "Total difficulty:", None)) self.label_9.setText(_translate("settingsDialog", "Total difficulty:", None))
self.label_10.setText(_translate("settingsDialog", "The \'Total difficulty\' affects the absolute amount of work the sender must complete. Doubling this value doubles the amount of work.", None)) self.label_10.setText(
_translate(
"settingsDialog",
"The \'Total difficulty\' affects the absolute amount of work the sender must complete."
" Doubling this value doubles the amount of work.",
None))
self.label_11.setText(_translate("settingsDialog", "Small message difficulty:", None)) self.label_11.setText(_translate("settingsDialog", "Small message difficulty:", None))
self.label_8.setText(_translate("settingsDialog", "When someone sends you a message, their computer must first complete some work. The difficulty of this work, by default, is 1. You may raise this default for new addresses you create by changing the values here. Any new addresses you create will require senders to meet the higher difficulty. There is one exception: if you add a friend or acquaintance to your address book, Bitmessage will automatically notify them when you next send a message that they need only complete the minimum amount of work: difficulty 1. ", None)) self.label_8.setText(_translate(
self.label_12.setText(_translate("settingsDialog", "The \'Small message difficulty\' mostly only affects the difficulty of sending small messages. Doubling this value makes it almost twice as difficult to send a small message but doesn\'t really affect large messages.", None)) "settingsDialog",
self.tabWidgetSettings.setTabText(self.tabWidgetSettings.indexOf(self.tabDemandedDifficulty), _translate("settingsDialog", "Demanded difficulty", None)) "When someone sends you a message, their computer must first complete some work. The difficulty of this"
self.label_15.setText(_translate("settingsDialog", "Here you may set the maximum amount of work you are willing to do to send a message to another person. Setting these values to 0 means that any value is acceptable.", None)) " work, by default, is 1. You may raise this default for new addresses you create by changing the values"
" here. Any new addresses you create will require senders to meet the higher difficulty. There is one"
" exception: if you add a friend or acquaintance to your address book, Bitmessage will automatically"
" notify them when you next send a message that they need only complete the minimum amount of"
" work: difficulty 1. ",
None))
self.label_12.setText(
_translate(
"settingsDialog",
"The \'Small message difficulty\' mostly only affects the difficulty of sending small messages."
" Doubling this value makes it almost twice as difficult to send a small message but doesn\'t really"
" affect large messages.",
None))
self.tabWidgetSettings.setTabText(
self.tabWidgetSettings.indexOf(
self.tabDemandedDifficulty),
_translate(
"settingsDialog", "Demanded difficulty", None))
self.label_15.setText(
_translate(
"settingsDialog",
"Here you may set the maximum amount of work you are willing to do to send a message to another"
" person. Setting these values to 0 means that any value is acceptable.",
None))
self.label_13.setText(_translate("settingsDialog", "Maximum acceptable total difficulty:", None)) self.label_13.setText(_translate("settingsDialog", "Maximum acceptable total difficulty:", None))
self.label_14.setText(_translate("settingsDialog", "Maximum acceptable small message difficulty:", None)) self.label_14.setText(_translate("settingsDialog", "Maximum acceptable small message difficulty:", None))
self.tabWidgetSettings.setTabText(self.tabWidgetSettings.indexOf(self.tabMaxAcceptableDifficulty), _translate("settingsDialog", "Max acceptable difficulty", None)) self.tabWidgetSettings.setTabText(
self.tabWidgetSettings.indexOf(
self.tabMaxAcceptableDifficulty),
_translate(
"settingsDialog", "Max acceptable difficulty", None))
self.labelOpenCL.setText(_translate("settingsDialog", "Hardware GPU acceleration (OpenCL):", None)) self.labelOpenCL.setText(_translate("settingsDialog", "Hardware GPU acceleration (OpenCL):", None))
self.label_16.setText(_translate("settingsDialog", "<html><head/><body><p>Bitmessage can utilize a different Bitcoin-based program called Namecoin to make addresses human-friendly. For example, instead of having to tell your friend your long Bitmessage address, you can simply tell him to send a message to <span style=\" font-style:italic;\">test. </span></p><p>(Getting your own Bitmessage address into Namecoin is still rather difficult).</p><p>Bitmessage can use either namecoind directly or a running nmcontrol instance.</p></body></html>", None)) self.label_16.setText(_translate(
"settingsDialog",
"<html><head/><body><p>Bitmessage can utilize a different Bitcoin-based program called Namecoin to make"
" addresses human-friendly. For example, instead of having to tell your friend your long Bitmessage"
" address, you can simply tell him to send a message to <span style=\" font-style:italic;\">test."
" </span></p><p>(Getting your own Bitmessage address into Namecoin is still rather difficult).</p>"
"<p>Bitmessage can use either namecoind directly or a running nmcontrol instance.</p></body></html>",
None))
self.label_17.setText(_translate("settingsDialog", "Host:", None)) self.label_17.setText(_translate("settingsDialog", "Host:", None))
self.label_18.setText(_translate("settingsDialog", "Port:", None)) self.label_18.setText(_translate("settingsDialog", "Port:", None))
self.labelNamecoinUser.setText(_translate("settingsDialog", "Username:", None)) self.labelNamecoinUser.setText(_translate("settingsDialog", "Username:", None))
@ -505,12 +605,26 @@ class Ui_settingsDialog(object):
self.label_21.setText(_translate("settingsDialog", "Connect to:", None)) self.label_21.setText(_translate("settingsDialog", "Connect to:", None))
self.radioButtonNamecoinNamecoind.setText(_translate("settingsDialog", "Namecoind", None)) self.radioButtonNamecoinNamecoind.setText(_translate("settingsDialog", "Namecoind", None))
self.radioButtonNamecoinNmcontrol.setText(_translate("settingsDialog", "NMControl", None)) self.radioButtonNamecoinNmcontrol.setText(_translate("settingsDialog", "NMControl", None))
self.tabWidgetSettings.setTabText(self.tabWidgetSettings.indexOf(self.tabNamecoin), _translate("settingsDialog", "Namecoin integration", None)) self.tabWidgetSettings.setTabText(
self.label_7.setText(_translate("settingsDialog", "<html><head/><body><p>By default, if you send a message to someone and he is offline for more than two days, Bitmessage will send the message again after an additional two days. This will be continued with exponential backoff forever; messages will be resent after 5, 10, 20 days ect. until the receiver acknowledges them. Here you may change that behavior by having Bitmessage give up after a certain number of days or months.</p><p>Leave these input fields blank for the default behavior. </p></body></html>", None)) self.tabWidgetSettings.indexOf(
self.tabNamecoin),
_translate(
"settingsDialog", "Namecoin integration", None))
self.label_7.setText(_translate(
"settingsDialog",
"<html><head/><body><p>By default, if you send a message to someone and he is offline for more than two"
" days, Bitmessage will send the message again after an additional two days. This will be continued with"
" exponential backoff forever; messages will be resent after 5, 10, 20 days ect. until the receiver"
" acknowledges them. Here you may change that behavior by having Bitmessage give up after a certain"
" number of days or months.</p><p>Leave these input fields blank for the default behavior."
" </p></body></html>",
None))
self.label_19.setText(_translate("settingsDialog", "Give up after", None)) self.label_19.setText(_translate("settingsDialog", "Give up after", None))
self.label_20.setText(_translate("settingsDialog", "and", None)) self.label_20.setText(_translate("settingsDialog", "and", None))
self.label_22.setText(_translate("settingsDialog", "days", None)) self.label_22.setText(_translate("settingsDialog", "days", None))
self.label_23.setText(_translate("settingsDialog", "months.", None)) self.label_23.setText(_translate("settingsDialog", "months.", None))
self.tabWidgetSettings.setTabText(self.tabWidgetSettings.indexOf(self.tabResendsExpire), _translate("settingsDialog", "Resends Expire", None)) self.tabWidgetSettings.setTabText(
self.tabWidgetSettings.indexOf(
import bitmessage_icons_rc self.tabResendsExpire),
_translate(
"settingsDialog", "Resends Expire", None))

View File

@ -1,54 +1,64 @@
# Copyright (C) 2013 by Daniel Kraft <d@domob.eu> # pylint: disable=too-many-branches,protected-access
# This file is part of the Bitmessage project. """
# Copyright (C) 2013 by Daniel Kraft <d@domob.eu>
# Permission is hereby granted, free of charge, to any person obtaining a copy This file is part of the Bitmessage project.
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights Permission is hereby granted, free of charge, to any person obtaining a copy
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell of this software and associated documentation files (the "Software"), to deal
# copies of the Software, and to permit persons to whom the Software is in the Software without restriction, including without limitation the rights
# furnished to do so, subject to the following conditions: to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# The above copyright notice and this permission notice shall be included in all furnished to do so, subject to the following conditions:
# copies or substantial portions of the Software.
# The above copyright notice and this permission notice shall be included in all
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR copies or substantial portions of the Software.
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# SOFTWARE. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
.. todo:: from debug import logger crashes PyBitmessage due to a circular dependency. The debug module will also
override/disable logging.getLogger() # loggers so module level logging functions are used instead
"""
from __future__ import absolute_import
import base64 import base64
import httplib import httplib
import json import json
import os
import socket import socket
import sys import sys
import os
from bmconfigparser import BMConfigParser import logging as logger
import defaults import defaults
import tr # translate import tr # translate
from bmconfigparser import BMConfigParser
# FIXME: from debug import logger crashes PyBitmessage due to a circular
# dependency. The debug module will also override/disable logging.getLogger()
# loggers so module level logging functions are used instead
import logging as logger
configSection = "bitmessagesettings" configSection = "bitmessagesettings"
# Error thrown when the RPC call returns an error.
class RPCError(Exception): class RPCError(Exception):
"""Error thrown when the RPC call returns an error."""
error = None error = None
def __init__(self, data): def __init__(self, data):
super(RPCError, self).__init__()
self.error = data self.error = data
def __str__(self): def __str__(self):
return '{0}: {1}'.format(type(self).__name__, self.error) return '{0}: {1}'.format(type(self).__name__, self.error)
# This class handles the Namecoin identity integration.
class namecoinConnection(object): class namecoinConnection(object):
"""This class handles the Namecoin identity integration."""
user = None user = None
password = None password = None
host = None host = None
@ -58,11 +68,13 @@ class namecoinConnection (object):
queryid = 1 queryid = 1
con = None con = None
# Initialise. If options are given, take the connection settings from
# them instead of loading from the configs. This can be used to test
# currently entered connection settings in the config dialog without
# actually changing the values (yet).
def __init__(self, options=None): def __init__(self, options=None):
"""
Initialise. If options are given, take the connection settings from
them instead of loading from the configs. This can be used to test
currently entered connection settings in the config dialog without
actually changing the values (yet).
"""
if options is None: if options is None:
self.nmctype = BMConfigParser().get(configSection, "namecoinrpctype") self.nmctype = BMConfigParser().get(configSection, "namecoinrpctype")
self.host = BMConfigParser().get(configSection, "namecoinrpchost") self.host = BMConfigParser().get(configSection, "namecoinrpchost")
@ -81,11 +93,13 @@ class namecoinConnection (object):
if self.nmctype == "namecoind": if self.nmctype == "namecoind":
self.con = httplib.HTTPConnection(self.host, self.port, timeout=3) self.con = httplib.HTTPConnection(self.host, self.port, timeout=3)
# Query for the bitmessage address corresponding to the given identity
# string. If it doesn't contain a slash, id/ is prepended. We return
# the result as (Error, Address) pair, where the Error is an error
# message to display or None in case of success.
def query(self, string): def query(self, string):
"""
Query for the bitmessage address corresponding to the given identity
string. If it doesn't contain a slash, id/ is prepended. We return
the result as (Error, Address) pair, where the Error is an error
message to display or None in case of success.
"""
slashPos = string.find("/") slashPos = string.find("/")
if slashPos < 0: if slashPos < 0:
string = "id/" + string string = "id/" + string
@ -97,7 +111,7 @@ class namecoinConnection (object):
elif self.nmctype == "nmcontrol": elif self.nmctype == "nmcontrol":
res = self.callRPC("data", ["getValue", string]) res = self.callRPC("data", ["getValue", string])
res = res["reply"] res = res["reply"]
if res == False: if not res:
return (tr._translate("MainWindow", 'The name %1 was not found.').arg(unicode(string)), None) return (tr._translate("MainWindow", 'The name %1 was not found.').arg(unicode(string)), None)
else: else:
assert False assert False
@ -108,7 +122,7 @@ class namecoinConnection (object):
else: else:
errmsg = exc.error errmsg = exc.error
return (tr._translate("MainWindow", 'The namecoin query failed (%1)').arg(unicode(errmsg)), None) return (tr._translate("MainWindow", 'The namecoin query failed (%1)').arg(unicode(errmsg)), None)
except Exception as exc: except Exception:
logger.exception("Namecoin query exception") logger.exception("Namecoin query exception")
return (tr._translate("MainWindow", 'The namecoin query failed.'), None) return (tr._translate("MainWindow", 'The namecoin query failed.'), None)
@ -124,12 +138,19 @@ class namecoinConnection (object):
else: else:
ret = val["bitmessage"] ret = val["bitmessage"]
return (None, ret) return (None, ret)
return (tr._translate("MainWindow",'The name %1 has no associated Bitmessage address.').arg(unicode(string)), None) return (
tr._translate(
"MainWindow",
'The name %1 has no associated Bitmessage address.').arg(
unicode(string)),
None)
# Test the connection settings. This routine tries to query a "getinfo"
# command, and builds either an error message or a success message with
# some info from it.
def test(self): def test(self):
"""
Test the connection settings. This routine tries to query a "getinfo"
command, and builds either an error message or a success message with
some info from it.
"""
try: try:
if self.nmctype == "namecoind": if self.nmctype == "namecoind":
try: try:
@ -146,7 +167,12 @@ class namecoinConnection (object):
versStr = "0.%d.%d" % (v1, v2) versStr = "0.%d.%d" % (v1, v2)
else: else:
versStr = "0.%d.%d.%d" % (v1, v2, v3) versStr = "0.%d.%d.%d" % (v1, v2, v3)
return ('success', tr._translate("MainWindow",'Success! Namecoind version %1 running.').arg(unicode(versStr)) ) message = (
'success',
tr._translate(
"MainWindow",
'Success! Namecoind version %1 running.').arg(
unicode(versStr)))
elif self.nmctype == "nmcontrol": elif self.nmctype == "nmcontrol":
res = self.callRPC("data", ["status"]) res = self.callRPC("data", ["status"])
@ -155,10 +181,13 @@ class namecoinConnection (object):
return ('success', tr._translate("MainWindow", 'Success! NMControll is up and running.')) return ('success', tr._translate("MainWindow", 'Success! NMControll is up and running.'))
logger.error("Unexpected nmcontrol reply: %s", res) logger.error("Unexpected nmcontrol reply: %s", res)
return ('failed', tr._translate("MainWindow",'Couldn\'t understand NMControl.')) message = ('failed', tr._translate("MainWindow", 'Couldn\'t understand NMControl.'))
else: else:
assert False print "Unsupported Namecoin type"
sys.exit(1)
return message
except Exception: except Exception:
logger.info("Namecoin connection test failure") logger.info("Namecoin connection test failure")
@ -168,8 +197,9 @@ class namecoinConnection (object):
"MainWindow", "The connection to namecoin failed.") "MainWindow", "The connection to namecoin failed.")
) )
# Helper routine that actually performs an JSON RPC call.
def callRPC(self, method, params): def callRPC(self, method, params):
"""Helper routine that actually performs an JSON RPC call."""
data = {"method": method, "params": params, "id": self.queryid} data = {"method": method, "params": params, "id": self.queryid}
if self.nmctype == "namecoind": if self.nmctype == "namecoind":
resp = self.queryHTTP(json.dumps(data)) resp = self.queryHTTP(json.dumps(data))
@ -193,8 +223,9 @@ class namecoinConnection (object):
raise RPCError(val["result"]) raise RPCError(val["result"])
raise RPCError(error) raise RPCError(error)
# Query the server via HTTP.
def queryHTTP(self, data): def queryHTTP(self, data):
"""Query the server via HTTP."""
result = None result = None
try: try:
@ -213,7 +244,7 @@ class namecoinConnection (object):
resp = self.con.getresponse() resp = self.con.getresponse()
result = resp.read() result = resp.read()
if resp.status != 200: if resp.status != 200:
raise Exception ("Namecoin returned status %i: %s", resp.status, resp.reason) raise Exception("Namecoin returned status %i: %s" % resp.status, resp.reason)
except: except:
logger.info("HTTP receive error") logger.info("HTTP receive error")
except: except:
@ -221,8 +252,9 @@ class namecoinConnection (object):
return result return result
# Helper routine sending data to the RPC server and returning the result.
def queryServer(self, data): def queryServer(self, data):
"""Helper routine sending data to the RPC server and returning the result."""
try: try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
@ -244,9 +276,14 @@ class namecoinConnection (object):
except socket.error as exc: except socket.error as exc:
raise Exception("Socket error in RPC connection: %s" % str(exc)) raise Exception("Socket error in RPC connection: %s" % str(exc))
# Look up the namecoin data folder.
# FIXME: Check whether this works on other platforms as well!
def lookupNamecoinFolder(): def lookupNamecoinFolder():
"""
Look up the namecoin data folder.
.. todo:: Check whether this works on other platforms as well!
"""
app = "namecoin" app = "namecoin"
from os import path, environ from os import path, environ
if sys.platform == "darwin": if sys.platform == "darwin":
@ -254,8 +291,10 @@ def lookupNamecoinFolder ():
dataFolder = path.join(os.environ["HOME"], dataFolder = path.join(os.environ["HOME"],
"Library/Application Support/", app) + '/' "Library/Application Support/", app) + '/'
else: else:
print ("Could not find home folder, please report this message" print(
+ " and your OS X version to the BitMessage Github.") "Could not find home folder, please report this message"
" and your OS X version to the BitMessage Github."
)
sys.exit() sys.exit()
elif "win32" in sys.platform or "win64" in sys.platform: elif "win32" in sys.platform or "win64" in sys.platform:
@ -265,9 +304,13 @@ def lookupNamecoinFolder ():
return dataFolder return dataFolder
# Ensure all namecoin options are set, by setting those to default values
# that aren't there.
def ensureNamecoinOptions(): def ensureNamecoinOptions():
"""
Ensure all namecoin options are set, by setting those to default values
that aren't there.
"""
if not BMConfigParser().has_option(configSection, "namecoinrpctype"): if not BMConfigParser().has_option(configSection, "namecoinrpctype"):
BMConfigParser().set(configSection, "namecoinrpctype", "namecoind") BMConfigParser().set(configSection, "namecoinrpctype", "namecoind")
if not BMConfigParser().has_option(configSection, "namecoinrpchost"): if not BMConfigParser().has_option(configSection, "namecoinrpchost"):
@ -304,16 +347,16 @@ def ensureNamecoinOptions ():
nmc.close() nmc.close()
except IOError: except IOError:
logger.error("%s unreadable or missing, Namecoin support deactivated", nmcConfig) logger.error("%s unreadable or missing, Namecoin support deactivated", nmcConfig)
except Exception as exc: except Exception:
logger.warning("Error processing namecoin.conf", exc_info=True) logger.warning("Error processing namecoin.conf", exc_info=True)
# If still nothing found, set empty at least. # If still nothing found, set empty at least.
if (not hasUser): if not hasUser:
BMConfigParser().set(configSection, "namecoinrpcuser", defaultUser) BMConfigParser().set(configSection, "namecoinrpcuser", defaultUser)
if (not hasPass): if not hasPass:
BMConfigParser().set(configSection, "namecoinrpcpassword", defaultPass) BMConfigParser().set(configSection, "namecoinrpcpassword", defaultPass)
# Set default port now, possibly to found value. # Set default port now, possibly to found value.
if (not hasPort): if not hasPort:
BMConfigParser().set(configSection, "namecoinrpcport", BMConfigParser().set(configSection, "namecoinrpcport",
defaults.namecoinDefaultRpcPort) defaults.namecoinDefaultRpcPort)