""" src/bitmessageqt/address_dialogs.py =================================== """ # pylint: disable=attribute-defined-outside-init import hashlib from PyQt4 import QtCore, QtGui import queues import widgets from account import AccountMixin, GatewayAccount, MailchuckAccount, accountClass, getSortedAccounts from addresses import addBMIfNotPresent, decodeAddress, encodeVarint from inventory import Inventory from retranslateui import RetranslateMixin from tr import _translate class AddressCheckMixin(object): """Base address validation class for QT UI""" # pylint: disable=too-few-public-methods def __init__(self): self.valid = False QtCore.QObject.connect( # pylint: disable=no-member self.lineEditAddress, QtCore.SIGNAL("textChanged(QString)"), self.addressChanged) def _onSuccess(self, addressVersion, streamNumber, ripe): pass def addressChanged(self, QString): """Address validation callback, performs validation and gives feedback""" status, addressVersion, streamNumber, ripe = decodeAddress( str(QString)) self.valid = status == 'success' if self.valid: self.labelAddressCheck.setText( _translate("MainWindow", "Address is valid.")) self._onSuccess(addressVersion, streamNumber, ripe) elif status == 'missingbm': self.labelAddressCheck.setText(_translate( "MainWindow", # dialog name should be here "The address should start with ''BM-''" )) elif status == 'checksumfailed': self.labelAddressCheck.setText(_translate( "MainWindow", "The address is not typed or copied correctly" " (the checksum failed)." )) elif status == 'versiontoohigh': self.labelAddressCheck.setText(_translate( "MainWindow", "The version number of this address is higher than this" " software can support. Please upgrade Bitmessage." )) elif status == 'invalidcharacters': self.labelAddressCheck.setText(_translate( "MainWindow", "The address contains invalid characters." )) elif status == 'ripetooshort': self.labelAddressCheck.setText(_translate( "MainWindow", "Some data encoded in the address is too short." )) elif status == 'ripetoolong': self.labelAddressCheck.setText(_translate( "MainWindow", "Some data encoded in the address is too long." )) elif status == 'varintmalformed': self.labelAddressCheck.setText(_translate( "MainWindow", "Some data encoded in the address is malformed." )) class AddressDataDialog(QtGui.QDialog, AddressCheckMixin): """QDialog with Bitmessage address validation""" def __init__(self, parent): super(AddressDataDialog, self).__init__(parent) self.parent = parent def accept(self): """Callback for QDIalog accepting value""" if self.valid: self.data = ( addBMIfNotPresent(str(self.lineEditAddress.text())), str(self.lineEditLabel.text().toUtf8()) ) else: queues.UISignalQueue.put(('updateStatusBar', _translate( "MainWindow", "The address you entered was invalid. Ignoring it." ))) super(AddressDataDialog, self).accept() class AddAddressDialog(AddressDataDialog, RetranslateMixin): """QDialog for adding a new address, with validation and translation""" def __init__(self, parent=None, address=None): super(AddAddressDialog, self).__init__(parent) widgets.load('addaddressdialog.ui', self) AddressCheckMixin.__init__(self) if address: self.lineEditAddress.setText(address) class NewAddressDialog(QtGui.QDialog, RetranslateMixin): """QDialog for generating a new address, with translation""" def __init__(self, parent=None): super(NewAddressDialog, self).__init__(parent) widgets.load('newaddressdialog.ui', self) # Let's fill out the 'existing address' combo box with addresses # from the 'Your Identities' tab. for address in getSortedAccounts(): self.radioButtonExisting.click() self.comboBoxExisting.addItem(address) self.groupBoxDeterministic.setHidden(True) QtGui.QWidget.resize(self, QtGui.QWidget.sizeHint(self)) self.show() def accept(self): """accept callback""" self.hide() # self.buttonBox.enabled = False if self.radioButtonRandomAddress.isChecked(): if self.radioButtonMostAvailable.isChecked(): streamNumberForAddress = 1 else: # User selected 'Use the same stream as an existing # address.' streamNumberForAddress = decodeAddress( self.comboBoxExisting.currentText())[2] queues.addressGeneratorQueue.put(( 'createRandomAddress', 4, streamNumberForAddress, str(self.newaddresslabel.text().toUtf8()), 1, "", self.checkBoxEighteenByteRipe.isChecked() )) else: if self.lineEditPassphrase.text() != \ self.lineEditPassphraseAgain.text(): QtGui.QMessageBox.about( self, _translate("MainWindow", "Passphrase mismatch"), _translate( "MainWindow", "The passphrase you entered twice doesn\'t" " match. Try again.") ) elif self.lineEditPassphrase.text() == "": QtGui.QMessageBox.about( self, _translate("MainWindow", "Choose a passphrase"), _translate( "MainWindow", "You really do need a passphrase.") ) else: # this will eventually have to be replaced by logic # to determine the most available stream number. streamNumberForAddress = 1 queues.addressGeneratorQueue.put(( 'createDeterministicAddresses', 4, streamNumberForAddress, "unused deterministic address", self.spinBoxNumberOfAddressesToMake.value(), self.lineEditPassphrase.text().toUtf8(), self.checkBoxEighteenByteRipe.isChecked() )) class NewSubscriptionDialog(AddressDataDialog, RetranslateMixin): """QDialog for subscribing to an address, with validation and translation""" def __init__(self, parent=None): super(NewSubscriptionDialog, self).__init__(parent) widgets.load('newsubscriptiondialog.ui', self) AddressCheckMixin.__init__(self) def _onSuccess(self, addressVersion, streamNumber, ripe): if addressVersion <= 3: self.checkBoxDisplayMessagesAlreadyInInventory.setText(_translate( "MainWindow", "Address is an old type. We cannot display its past" " broadcasts." )) else: Inventory().flush() doubleHashOfAddressData = hashlib.sha512(hashlib.sha512( encodeVarint(addressVersion) + encodeVarint(streamNumber) + ripe ).digest()).digest() tag = doubleHashOfAddressData[32:] self.recent = Inventory().by_type_and_tag(3, tag) count = len(self.recent) if count == 0: self.checkBoxDisplayMessagesAlreadyInInventory.setText( _translate( "MainWindow", "There are no recent broadcasts from this address" " to display." )) else: self.checkBoxDisplayMessagesAlreadyInInventory.setEnabled(True) self.checkBoxDisplayMessagesAlreadyInInventory.setText( _translate( "MainWindow", "Display the %n recent broadcast(s) from this address.", None, QtCore.QCoreApplication.CodecForTr, count )) class RegenerateAddressesDialog(QtGui.QDialog, RetranslateMixin): """QDialog for regenerating deterministic addresses, with translation""" def __init__(self, parent=None): super(RegenerateAddressesDialog, self).__init__(parent) widgets.load('regenerateaddresses.ui', self) self.groupBox.setTitle('') QtGui.QWidget.resize(self, QtGui.QWidget.sizeHint(self)) class SpecialAddressBehaviorDialog(QtGui.QDialog, RetranslateMixin): """QDialog for special address behaviour (e.g. mailing list functionality), with translation""" def __init__(self, parent=None, config=None): super(SpecialAddressBehaviorDialog, self).__init__(parent) widgets.load('specialaddressbehavior.ui', self) self.address = parent.getCurrentAccount() self.parent = parent self.config = config try: self.address_is_chan = config.safeGetBoolean( self.address, 'chan' ) except AttributeError: pass else: if self.address_is_chan: # address is a chan address self.radioButtonBehaviorMailingList.setDisabled(True) self.lineEditMailingListName.setText(_translate( "SpecialAddressBehaviorDialog", "This is a chan address. You cannot use it as a" " pseudo-mailing list." )) else: if config.safeGetBoolean(self.address, 'mailinglist'): self.radioButtonBehaviorMailingList.click() else: self.radioButtonBehaveNormalAddress.click() try: mailingListName = config.get( self.address, 'mailinglistname') except: mailingListName = '' self.lineEditMailingListName.setText( unicode(mailingListName, 'utf-8') ) QtGui.QWidget.resize(self, QtGui.QWidget.sizeHint(self)) self.show() def accept(self): """Accept callback""" self.hide() if self.address_is_chan: return if self.radioButtonBehaveNormalAddress.isChecked(): self.config.set(str(self.address), 'mailinglist', 'false') # Set the color to either black or grey if self.config.getboolean(self.address, 'enabled'): self.parent.setCurrentItemColor( QtGui.QApplication.palette().text().color() ) else: self.parent.setCurrentItemColor(QtGui.QColor(128, 128, 128)) else: self.config.set(str(self.address), 'mailinglist', 'true') self.config.set(str(self.address), 'mailinglistname', str( self.lineEditMailingListName.text().toUtf8())) self.parent.setCurrentItemColor( QtGui.QColor(137, 4, 177)) # magenta self.parent.rerenderComboBoxSendFrom() self.parent.rerenderComboBoxSendFromBroadcast() self.config.save() self.parent.rerenderMessagelistToLabels() class EmailGatewayDialog(QtGui.QDialog, RetranslateMixin): """QDialog for email gateway control, with translation""" def __init__(self, parent, config=None, account=None): super(EmailGatewayDialog, self).__init__(parent) widgets.load('emailgateway.ui', self) self.parent = parent self.config = config if account: self.acct = account self.setWindowTitle(_translate( "EmailGatewayDialog", "Registration failed:")) self.label.setText(_translate( "EmailGatewayDialog", "The requested email address is not available," " please try a new one." )) self.radioButtonRegister.hide() self.radioButtonStatus.hide() self.radioButtonSettings.hide() self.radioButtonUnregister.hide() else: address = parent.getCurrentAccount() self.acct = accountClass(address) try: label = config.get(address, 'label') except AttributeError: pass else: if "@" in label: self.lineEditEmail.setText(label) if isinstance(self.acct, GatewayAccount): self.radioButtonUnregister.setEnabled(True) self.radioButtonStatus.setEnabled(True) self.radioButtonStatus.setChecked(True) self.radioButtonSettings.setEnabled(True) self.lineEditEmail.setEnabled(False) else: self.acct = MailchuckAccount(address) self.lineEditEmail.setFocus() QtGui.QWidget.resize(self, QtGui.QWidget.sizeHint(self)) def accept(self): """Accept callback""" self.hide() # no chans / mailinglists if self.acct.type != AccountMixin.NORMAL: return if not isinstance(self.acct, GatewayAccount): return if self.radioButtonRegister.isChecked() \ or self.radioButtonRegister.isHidden(): email = str(self.lineEditEmail.text().toUtf8()) self.acct.register(email) self.config.set(self.acct.fromAddress, 'label', email) self.config.set(self.acct.fromAddress, 'gateway', 'mailchuck') self.config.save() queues.UISignalQueue.put(('updateStatusBar', _translate( "EmailGatewayDialog", "Sending email gateway registration request" ))) elif self.radioButtonUnregister.isChecked(): self.acct.unregister() self.config.remove_option(self.acct.fromAddress, 'gateway') self.config.save() queues.UISignalQueue.put(('updateStatusBar', _translate( "EmailGatewayDialog", "Sending email gateway unregistration request" ))) elif self.radioButtonStatus.isChecked(): self.acct.status() queues.UISignalQueue.put(('updateStatusBar', _translate( "EmailGatewayDialog", "Sending email gateway status request" ))) elif self.radioButtonSettings.isChecked(): self.data = self.acct super(EmailGatewayDialog, self).accept()