From 01e5400afbf801ce98db39172e130ed85d7f5d74 Mon Sep 17 00:00:00 2001 From: Dmitri Bogomolov <4glitch@gmail.com> Date: Wed, 3 Mar 2021 18:14:16 +0200 Subject: [PATCH 001/105] tr compatible with all Qt APIs --- src/tr.py | 71 ++++++++++++++++++++----------------------------------- 1 file changed, 26 insertions(+), 45 deletions(-) diff --git a/src/tr.py b/src/tr.py index eec82c37..765ba55c 100644 --- a/src/tr.py +++ b/src/tr.py @@ -1,7 +1,6 @@ """ -Translating text +Slim layer providing environment agnostic _translate() """ -import os try: import state @@ -9,51 +8,33 @@ except ImportError: from . import state -class translateClass: - """ - This is used so that the translateText function can be used - when we are in daemon mode and not using any QT functions. - """ - # pylint: disable=old-style-class,too-few-public-methods - def __init__(self, context, text): - self.context = context - self.text = text - - def arg(self, _): - """Replace argument placeholders""" - if '%' in self.text: - # This doesn't actually do anything with the arguments - # because we don't have a UI in which to display this information anyway. - return translateClass(self.context, self.text.replace('%', '', 1)) - return self.text - - -def _translate(context, text, disambiguation=None, encoding=None, n=None): +def _tr_dummy(context, text, disambiguation=None, n=None): # pylint: disable=unused-argument - return translateText(context, text, n) + return text -def translateText(context, text, n=None): - """Translate text in context""" +if state.enableGUI and not state.curses: try: - enableGUI = state.enableGUI - except AttributeError: # inside the plugin - enableGUI = True - if enableGUI: - try: - from PyQt4 import QtCore, QtGui - except Exception as err: - print('PyBitmessage requires PyQt unless you want to run it as a daemon' - ' and interact with it using the API.' - ' You can download PyQt from http://www.riverbankcomputing.com/software/pyqt/download' - ' or by searching Google for \'PyQt Download\'.' - ' If you want to run in daemon mode, see https://bitmessage.org/wiki/Daemon') - print('Error message:', err) - os._exit(0) # pylint: disable=protected-access - if n is None: - return QtGui.QApplication.translate(context, text) - return QtGui.QApplication.translate(context, text, None, QtCore.QCoreApplication.CodecForTr, n) + from fallback import PyQt5 # noqa:F401 + from PyQt5 import QtWidgets, QtCore + except ImportError: + _translate = _tr_dummy else: - if '%' in text: - return translateClass(context, text.replace('%', '', 1)) - return text + try: + from PyQt5 import API + except ImportError: + API = 'pyqt5' + if API == 'pyqt5': + _translate = QtWidgets.QApplication.translate + else: + def _translate(context, text, disambiguation=None, n=None): + return ( + QtWidgets.QApplication.translate( + context, text, disambiguation) + if n is None else + QtWidgets.QApplication.translate( + context, text, disambiguation, + QtCore.QCoreApplication.CodecForTr, n) + ) +else: + _translate = _tr_dummy -- 2.45.1 From b9fca03ed10ffbfc9bbecbf09dce893901175275 Mon Sep 17 00:00:00 2001 From: Dmitri Bogomolov <4glitch@gmail.com> Date: Wed, 3 Mar 2021 18:15:38 +0200 Subject: [PATCH 002/105] Prepare newchandialog module for PyQt5/qtpy --- src/bitmessageqt/addressvalidator.py | 177 +++++++++++++++------------ src/bitmessageqt/newchandialog.py | 84 +++++++------ 2 files changed, 144 insertions(+), 117 deletions(-) diff --git a/src/bitmessageqt/addressvalidator.py b/src/bitmessageqt/addressvalidator.py index 89c17891..0b969173 100644 --- a/src/bitmessageqt/addressvalidator.py +++ b/src/bitmessageqt/addressvalidator.py @@ -1,14 +1,16 @@ """ -Address validator module. +The validator for address and passphrase QLineEdits +used in `.dialogs.NewChanDialog`. """ -# pylint: disable=too-many-branches,too-many-arguments +# pylint: disable=too-many-arguments -from PyQt4 import QtGui from Queue import Empty +from PyQt5 import QtGui + from account import getSortedAccounts from addresses import decodeAddress, addBMIfNotPresent -from queues import apiAddressGeneratorReturnQueue, addressGeneratorQueue +from queues import addressGeneratorQueue, apiAddressGeneratorReturnQueue from tr import _translate from utils import str_chan @@ -16,22 +18,18 @@ from utils import str_chan class AddressPassPhraseValidatorMixin(object): """Bitmessage address or passphrase validator class for Qt UI""" def setParams( - self, - passPhraseObject=None, - addressObject=None, - feedBackObject=None, - buttonBox=None, - addressMandatory=True, + self, passPhraseObject=None, addressObject=None, + feedBackObject=None, button=None, addressMandatory=True ): - """Initialisation""" + """Initialization""" self.addressObject = addressObject self.passPhraseObject = passPhraseObject self.feedBackObject = feedBackObject - self.buttonBox = buttonBox self.addressMandatory = addressMandatory self.isValid = False # save default text - self.okButtonLabel = self.buttonBox.button(QtGui.QDialogButtonBox.Ok).text() + self.okButton = button + self.okButtonLabel = button.text() def setError(self, string): """Indicate that the validation is pending or failed""" @@ -42,13 +40,13 @@ class AddressPassPhraseValidatorMixin(object): self.feedBackObject.setStyleSheet("QLabel { color : red; }") self.feedBackObject.setText(string) self.isValid = False - if self.buttonBox: - self.buttonBox.button(QtGui.QDialogButtonBox.Ok).setEnabled(False) + if self.okButton: + self.okButton.setEnabled(False) if string is not None and self.feedBackObject is not None: - self.buttonBox.button(QtGui.QDialogButtonBox.Ok).setText( + self.okButton.setText( _translate("AddressValidator", "Invalid")) else: - self.buttonBox.button(QtGui.QDialogButtonBox.Ok).setText( + self.okButton.setText( _translate("AddressValidator", "Validating...")) def setOK(self, string): @@ -60,9 +58,9 @@ class AddressPassPhraseValidatorMixin(object): self.feedBackObject.setStyleSheet("QLabel { }") self.feedBackObject.setText(string) self.isValid = True - if self.buttonBox: - self.buttonBox.button(QtGui.QDialogButtonBox.Ok).setEnabled(True) - self.buttonBox.button(QtGui.QDialogButtonBox.Ok).setText(self.okButtonLabel) + if self.okButton: + self.okButton.setEnabled(True) + self.okButton.setText(self.okButtonLabel) def checkQueue(self): """Validator queue loop""" @@ -75,7 +73,8 @@ class AddressPassPhraseValidatorMixin(object): while True: try: - addressGeneratorReturnValue = apiAddressGeneratorReturnQueue.get(False) + addressGeneratorReturnValue = \ + apiAddressGeneratorReturnQueue.get(False) except Empty: if gotOne: break @@ -85,96 +84,120 @@ class AddressPassPhraseValidatorMixin(object): gotOne = True if not addressGeneratorReturnValue: - self.setError(_translate("AddressValidator", "Address already present as one of your identities.")) - return (QtGui.QValidator.Intermediate, 0) - if addressGeneratorReturnValue[0] == 'chan name does not match address': - self.setError( - _translate( - "AddressValidator", - "Although the Bitmessage address you " - "entered was valid, it doesn't match the chan name.")) - return (QtGui.QValidator.Intermediate, 0) - self.setOK(_translate("MainWindow", "Passphrase and address appear to be valid.")) + self.setError(_translate( + "AddressValidator", + "Address already present as one of your identities." + )) + return + if addressGeneratorReturnValue[0] == \ + 'chan name does not match address': + self.setError(_translate( + "AddressValidator", + "Although the Bitmessage address you entered was valid," + " it doesn\'t match the chan name." + )) + return + self.setOK(_translate( + "MainWindow", "Passphrase and address appear to be valid.")) def returnValid(self): """Return the value of whether the validation was successful""" - if self.isValid: - return QtGui.QValidator.Acceptable - return QtGui.QValidator.Intermediate + return QtGui.QValidator.Acceptable if self.isValid \ + else QtGui.QValidator.Intermediate def validate(self, s, pos): """Top level validator method""" - if self.addressObject is None: + try: + address = self.addressObject.text().encode('utf-8') + except AttributeError: address = None - else: - address = str(self.addressObject.text().toUtf8()) - if address == "": - address = None - if self.passPhraseObject is None: + try: + passPhrase = self.passPhraseObject.text().encode('utf-8') + except AttributeError: passPhrase = "" - else: - passPhrase = str(self.passPhraseObject.text().toUtf8()) - if passPhrase == "": - passPhrase = None # no chan name - if passPhrase is None: - self.setError(_translate("AddressValidator", "Chan name/passphrase needed. You didn't enter a chan name.")) - return (QtGui.QValidator.Intermediate, pos) + if not passPhrase: + self.setError(_translate( + "AddressValidator", + "Chan name/passphrase needed. You didn't enter a chan name." + )) + return (QtGui.QValidator.Intermediate, s, pos) - if self.addressMandatory or address is not None: + if self.addressMandatory or address: # check if address already exists: if address in getSortedAccounts(): - self.setError(_translate("AddressValidator", "Address already present as one of your identities.")) - return (QtGui.QValidator.Intermediate, pos) + self.setError(_translate( + "AddressValidator", + "Address already present as one of your identities." + )) + return (QtGui.QValidator.Intermediate, s, pos) + status = decodeAddress(address)[0] # version too high - if decodeAddress(address)[0] == 'versiontoohigh': - self.setError( - _translate( - "AddressValidator", - "Address too new. Although that Bitmessage" - " address might be valid, its version number" - " is too new for us to handle. Perhaps you need" - " to upgrade Bitmessage.")) - return (QtGui.QValidator.Intermediate, pos) - + if status == 'versiontoohigh': + self.setError(_translate( + "AddressValidator", + "Address too new. Although that Bitmessage address" + " might be valid, its version number is too new" + " for us to handle. Perhaps you need to upgrade" + " Bitmessage." + )) + return (QtGui.QValidator.Intermediate, s, pos) # invalid - if decodeAddress(address)[0] != 'success': - self.setError(_translate("AddressValidator", "The Bitmessage address is not valid.")) - return (QtGui.QValidator.Intermediate, pos) + if status != 'success': + self.setError(_translate( + "AddressValidator", + "The Bitmessage address is not valid." + )) + return (QtGui.QValidator.Intermediate, s, pos) # this just disables the OK button without changing the feedback text # but only if triggered by textEdited, not by clicking the Ok button - if not self.buttonBox.button(QtGui.QDialogButtonBox.Ok).hasFocus(): + if not self.okButton.hasFocus(): self.setError(None) # check through generator - if address is None: - addressGeneratorQueue.put(('createChan', 4, 1, str_chan + ' ' + str(passPhrase), passPhrase, False)) + if not address: + addressGeneratorQueue.put(( + 'createChan', 4, 1, + str_chan + ' ' + passPhrase, passPhrase, False + )) else: - addressGeneratorQueue.put( - ('joinChan', addBMIfNotPresent(address), - "{} {}".format(str_chan, passPhrase), passPhrase, False)) + addressGeneratorQueue.put(( + 'joinChan', addBMIfNotPresent(address), + "{} {}".format(str_chan, passPhrase), passPhrase, False + )) - if self.buttonBox.button(QtGui.QDialogButtonBox.Ok).hasFocus(): - return (self.returnValid(), pos) - return (QtGui.QValidator.Intermediate, pos) + if self.okButton.hasFocus(): + return (self.returnValid(), s, pos) + else: + return (QtGui.QValidator.Intermediate, s, pos) def checkData(self): """Validator Qt signal interface""" - return self.validate("", 0) + return self.validate(u"", 0) class AddressValidator(QtGui.QValidator, AddressPassPhraseValidatorMixin): """AddressValidator class for Qt UI""" - def __init__(self, parent=None, passPhraseObject=None, feedBackObject=None, buttonBox=None, addressMandatory=True): + def __init__( + self, parent=None, passPhraseObject=None, feedBackObject=None, + button=None, addressMandatory=True + ): super(AddressValidator, self).__init__(parent) - self.setParams(passPhraseObject, parent, feedBackObject, buttonBox, addressMandatory) + self.setParams( + passPhraseObject, parent, feedBackObject, button, + addressMandatory) class PassPhraseValidator(QtGui.QValidator, AddressPassPhraseValidatorMixin): """PassPhraseValidator class for Qt UI""" - def __init__(self, parent=None, addressObject=None, feedBackObject=None, buttonBox=None, addressMandatory=False): + def __init__( + self, parent=None, addressObject=None, feedBackObject=None, + button=None, addressMandatory=False + ): super(PassPhraseValidator, self).__init__(parent) - self.setParams(parent, addressObject, feedBackObject, buttonBox, addressMandatory) + self.setParams( + parent, addressObject, feedBackObject, button, + addressMandatory) diff --git a/src/bitmessageqt/newchandialog.py b/src/bitmessageqt/newchandialog.py index c0629cd7..f4a89eea 100644 --- a/src/bitmessageqt/newchandialog.py +++ b/src/bitmessageqt/newchandialog.py @@ -1,10 +1,8 @@ """ -src/bitmessageqt/newchandialog.py -================================= - +NewChanDialog class definition """ -from PyQt4 import QtCore, QtGui +from PyQt5 import QtCore, QtWidgets import widgets from addresses import addBMIfNotPresent @@ -15,30 +13,21 @@ from tr import _translate from utils import str_chan -class NewChanDialog(QtGui.QDialog): - """The `New Chan` dialog""" +class NewChanDialog(QtWidgets.QDialog): + """The "New Chan" dialog""" def __init__(self, parent=None): super(NewChanDialog, self).__init__(parent) widgets.load('newchandialog.ui', self) self.parent = parent - self.chanAddress.setValidator( - AddressValidator( - self.chanAddress, - self.chanPassPhrase, - self.validatorFeedback, - self.buttonBox, - False)) - self.chanPassPhrase.setValidator( - PassPhraseValidator( - self.chanPassPhrase, - self.chanAddress, - self.validatorFeedback, - self.buttonBox, - False)) + self.chanAddress.setValidator(AddressValidator( + self.chanAddress, self.chanPassPhrase, self.validatorFeedback, + self.buttonBox.button(QtWidgets.QDialogButtonBox.Ok), False)) + self.chanPassPhrase.setValidator(PassPhraseValidator( + self.chanPassPhrase, self.chanAddress, self.validatorFeedback, + self.buttonBox.button(QtWidgets.QDialogButtonBox.Ok), False)) self.timer = QtCore.QTimer() - QtCore.QObject.connect( # pylint: disable=no-member - self.timer, QtCore.SIGNAL("timeout()"), self.delayedUpdateStatus) + self.timer.timeout.connect(self.delayedUpdateStatus) self.timer.start(500) # milliseconds self.setAttribute(QtCore.Qt.WA_DeleteOnClose) self.show() @@ -52,32 +41,47 @@ class NewChanDialog(QtGui.QDialog): self.timer.stop() self.hide() apiAddressGeneratorReturnQueue.queue.clear() - if self.chanAddress.text().toUtf8() == "": - addressGeneratorQueue.put( - ('createChan', 4, 1, str_chan + ' ' + str(self.chanPassPhrase.text().toUtf8()), - self.chanPassPhrase.text().toUtf8(), - True)) + passPhrase = self.chanPassPhrase.text().encode('utf-8') + if self.chanAddress.text() == "": + addressGeneratorQueue.put(( + 'createChan', 4, 1, + str_chan + ' ' + passPhrase, passPhrase, True + )) else: - addressGeneratorQueue.put( - ('joinChan', addBMIfNotPresent(self.chanAddress.text().toUtf8()), - str_chan + ' ' + str(self.chanPassPhrase.text().toUtf8()), - self.chanPassPhrase.text().toUtf8(), - True)) + addressGeneratorQueue.put(( + 'joinChan', addBMIfNotPresent(self.chanAddress.text()), + str_chan + ' ' + passPhrase, passPhrase, True + )) addressGeneratorReturnValue = apiAddressGeneratorReturnQueue.get(True) - if addressGeneratorReturnValue and addressGeneratorReturnValue[0] != 'chan name does not match address': - UISignalQueue.put(('updateStatusBar', _translate( - "newchandialog", "Successfully created / joined chan %1").arg(unicode(self.chanPassPhrase.text())))) + if ( + len(addressGeneratorReturnValue) > 0 + and addressGeneratorReturnValue[0] + != 'chan name does not match address' + ): + UISignalQueue.put(( + 'updateStatusBar', + _translate( + "newchandialog", + "Successfully created / joined chan {0}" + ).format(passPhrase) + )) self.parent.ui.tabWidget.setCurrentIndex( self.parent.ui.tabWidget.indexOf(self.parent.ui.chans) ) - self.done(QtGui.QDialog.Accepted) + self.done(QtWidgets.QDialog.Accepted) else: - UISignalQueue.put(('updateStatusBar', _translate("newchandialog", "Chan creation / joining failed"))) - self.done(QtGui.QDialog.Rejected) + UISignalQueue.put(( + 'updateStatusBar', + _translate("newchandialog", "Chan creation / joining failed") + )) + self.done(QtWidgets.QDialog.Rejected) def reject(self): """Cancel joining the chan""" self.timer.stop() self.hide() - UISignalQueue.put(('updateStatusBar', _translate("newchandialog", "Chan creation / joining cancelled"))) - self.done(QtGui.QDialog.Rejected) + UISignalQueue.put(( + 'updateStatusBar', + _translate("newchandialog", "Chan creation / joining cancelled") + )) + self.done(QtWidgets.QDialog.Rejected) -- 2.45.1 From 8dca39e9021e96a4c68a604770c9d5c87c25e3b1 Mon Sep 17 00:00:00 2001 From: Dmitri Bogomolov <4glitch@gmail.com> Date: Thu, 15 Feb 2018 19:28:01 +0200 Subject: [PATCH 003/105] Initial support for PyQt5 (main window shown) using QtPy package. QtPy is a compatibility layer which allows to use the code written for PyQt5 with any python Qt binding: PyQt4, PyQt5, pyside or pyside2. Main differences in PyQt5: - all widget classes are now in QtWidgets package, not QtGui; - QString obsoleted by unicode (sip API 2); - changed the way of signals connection. Closes: #1191 --- .travis.yml | 1 - src/bitmessageqt/__init__.py | 1093 ++++++++++++----------- src/bitmessageqt/account.py | 117 +-- src/bitmessageqt/address_dialogs.py | 91 +- src/bitmessageqt/bitmessage_icons_rc.py | 11 +- src/bitmessageqt/bitmessageui.py | 526 ++++++----- src/bitmessageqt/blacklist.py | 89 +- src/bitmessageqt/dialogs.py | 35 +- src/bitmessageqt/foldertree.py | 145 +-- src/bitmessageqt/languagebox.py | 30 +- src/bitmessageqt/messagecompose.py | 31 +- src/bitmessageqt/messageview.py | 92 +- src/bitmessageqt/networkstatus.py | 200 ++--- src/bitmessageqt/newaddressdialog.ui | 4 +- src/bitmessageqt/retranslateui.py | 20 +- src/bitmessageqt/safehtmlparser.py | 4 - src/bitmessageqt/settings.py | 31 +- src/bitmessageqt/settingsmixin.py | 37 +- src/bitmessageqt/statusbar.py | 17 +- src/bitmessageqt/tests/main.py | 6 +- src/bitmessageqt/uisignaler.py | 84 +- src/bitmessageqt/utils.py | 16 +- src/bitmessageqt/widgets.py | 12 +- src/class_addressGenerator.py | 29 +- src/depends.py | 2 +- src/plugins/menu_qrcode.py | 16 +- src/plugins/plugin.py | 1 + 27 files changed, 1399 insertions(+), 1341 deletions(-) diff --git a/.travis.yml b/.travis.yml index 9ecb65ba..e13d9e33 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,7 +9,6 @@ addons: packages: - build-essential - libcap-dev - - python-qt4 - python-pyqt5 - tor - xvfb diff --git a/src/bitmessageqt/__init__.py b/src/bitmessageqt/__init__.py index 6a692f38..eaac4968 100644 --- a/src/bitmessageqt/__init__.py +++ b/src/bitmessageqt/__init__.py @@ -15,8 +15,7 @@ import time from datetime import datetime, timedelta from sqlite3 import register_adapter -from PyQt4 import QtCore, QtGui -from PyQt4.QtNetwork import QLocalSocket, QLocalServer +from PyQt5 import QtCore, QtGui, QtWidgets, QtNetwork import shared import state @@ -27,7 +26,6 @@ from bitmessageui import Ui_MainWindow from bmconfigparser import BMConfigParser import namecoin from messageview import MessageView -from migrationwizard import Ui_MigrationWizard from foldertree import ( AccountMixin, Ui_FolderWidget, Ui_AddressWidget, Ui_SubscriptionWidget, MessageList_AddressWidget, MessageList_SubjectWidget, @@ -99,12 +97,12 @@ class MyForm(settingsmixin.SMainWindow): newlocale = l10n.getTranslationLanguage() try: if not self.qmytranslator.isEmpty(): - QtGui.QApplication.removeTranslator(self.qmytranslator) + QtWidgets.QApplication.removeTranslator(self.qmytranslator) except: pass try: if not self.qsystranslator.isEmpty(): - QtGui.QApplication.removeTranslator(self.qsystranslator) + QtWidgets.QApplication.removeTranslator(self.qsystranslator) except: pass @@ -112,7 +110,7 @@ class MyForm(settingsmixin.SMainWindow): translationpath = os.path.join( paths.codePath(), 'translations', 'bitmessage_' + newlocale) self.qmytranslator.load(translationpath) - QtGui.QApplication.installTranslator(self.qmytranslator) + QtWidgets.QApplication.installTranslator(self.qmytranslator) self.qsystranslator = QtCore.QTranslator() if paths.frozen: @@ -123,7 +121,7 @@ class MyForm(settingsmixin.SMainWindow): str(QtCore.QLibraryInfo.location( QtCore.QLibraryInfo.TranslationsPath)), 'qt_' + newlocale) self.qsystranslator.load(translationpath) - QtGui.QApplication.installTranslator(self.qsystranslator) + QtWidgets.QApplication.installTranslator(self.qsystranslator) # TODO: move this block into l10n # FIXME: shouldn't newlocale be used here? @@ -148,49 +146,35 @@ class MyForm(settingsmixin.SMainWindow): logger.error("Failed to set locale to %s", lang, exc_info=True) def init_file_menu(self): - QtCore.QObject.connect(self.ui.actionExit, QtCore.SIGNAL( - "triggered()"), self.quit) - QtCore.QObject.connect(self.ui.actionNetworkSwitch, QtCore.SIGNAL( - "triggered()"), self.network_switch) - QtCore.QObject.connect(self.ui.actionManageKeys, QtCore.SIGNAL( - "triggered()"), self.click_actionManageKeys) - QtCore.QObject.connect(self.ui.actionDeleteAllTrashedMessages, - QtCore.SIGNAL( - "triggered()"), - self.click_actionDeleteAllTrashedMessages) - QtCore.QObject.connect(self.ui.actionRegenerateDeterministicAddresses, - QtCore.SIGNAL( - "triggered()"), - self.click_actionRegenerateDeterministicAddresses) - QtCore.QObject.connect(self.ui.pushButtonAddChan, QtCore.SIGNAL( - "clicked()"), - self.click_actionJoinChan) # also used for creating chans. - QtCore.QObject.connect(self.ui.pushButtonNewAddress, QtCore.SIGNAL( - "clicked()"), self.click_NewAddressDialog) - QtCore.QObject.connect(self.ui.pushButtonAddAddressBook, QtCore.SIGNAL( - "clicked()"), self.click_pushButtonAddAddressBook) - QtCore.QObject.connect(self.ui.pushButtonAddSubscription, QtCore.SIGNAL( - "clicked()"), self.click_pushButtonAddSubscription) - QtCore.QObject.connect(self.ui.pushButtonTTL, QtCore.SIGNAL( - "clicked()"), self.click_pushButtonTTL) - QtCore.QObject.connect(self.ui.pushButtonClear, QtCore.SIGNAL( - "clicked()"), self.click_pushButtonClear) - QtCore.QObject.connect(self.ui.pushButtonSend, QtCore.SIGNAL( - "clicked()"), self.click_pushButtonSend) - QtCore.QObject.connect(self.ui.pushButtonFetchNamecoinID, QtCore.SIGNAL( - "clicked()"), self.click_pushButtonFetchNamecoinID) - QtCore.QObject.connect(self.ui.actionSettings, QtCore.SIGNAL( - "triggered()"), self.click_actionSettings) - QtCore.QObject.connect(self.ui.actionAbout, QtCore.SIGNAL( - "triggered()"), self.click_actionAbout) - QtCore.QObject.connect(self.ui.actionSupport, QtCore.SIGNAL( - "triggered()"), self.click_actionSupport) - QtCore.QObject.connect(self.ui.actionHelp, QtCore.SIGNAL( - "triggered()"), self.click_actionHelp) + self.ui.actionExit.triggered.connect(self.quit) + self.ui.actionNetworkSwitch.triggered.connect(self.network_switch) + self.ui.actionManageKeys.triggered.connect(self.click_actionManageKeys) + self.ui.actionDeleteAllTrashedMessages.triggered.connect( + self.click_actionDeleteAllTrashedMessages) + self.ui.actionRegenerateDeterministicAddresses.triggered.connect( + self.click_actionRegenerateDeterministicAddresses) + self.ui.actionSettings.triggered.connect(self.click_actionSettings) + self.ui.actionAbout.triggered.connect(self.click_actionAbout) + self.ui.actionSupport.triggered.connect(self.click_actionSupport) + self.ui.actionHelp.triggered.connect(self.click_actionHelp) + + # also used for creating chans. + self.ui.pushButtonAddChan.clicked.connect(self.click_actionJoinChan) + self.ui.pushButtonNewAddress.clicked.connect( + self.click_NewAddressDialog) + self.ui.pushButtonAddAddressBook.clicked.connect( + self.click_pushButtonAddAddressBook) + self.ui.pushButtonAddSubscription.clicked.connect( + self.click_pushButtonAddSubscription) + self.ui.pushButtonTTL.clicked.connect(self.click_pushButtonTTL) + self.ui.pushButtonClear.clicked.connect(self.click_pushButtonClear) + self.ui.pushButtonSend.clicked.connect(self.click_pushButtonSend) + self.ui.pushButtonFetchNamecoinID.clicked.connect( + self.click_pushButtonFetchNamecoinID) def init_inbox_popup_menu(self, connectSignal=True): # Popup menu for the Inbox tab - self.ui.inboxContextMenuToolbar = QtGui.QToolBar() + self.ui.inboxContextMenuToolbar = QtWidgets.QToolBar() # Actions self.actionReply = self.ui.inboxContextMenuToolbar.addAction(_translate( "MainWindow", "Reply to sender"), self.on_action_InboxReply) @@ -226,25 +210,22 @@ class MyForm(settingsmixin.SMainWindow): self.ui.tableWidgetInbox.setContextMenuPolicy( QtCore.Qt.CustomContextMenu) if connectSignal: - self.connect(self.ui.tableWidgetInbox, QtCore.SIGNAL( - 'customContextMenuRequested(const QPoint&)'), + self.ui.tableWidgetInbox.customContextMenuRequested.connect( self.on_context_menuInbox) self.ui.tableWidgetInboxSubscriptions.setContextMenuPolicy( QtCore.Qt.CustomContextMenu) if connectSignal: - self.connect(self.ui.tableWidgetInboxSubscriptions, QtCore.SIGNAL( - 'customContextMenuRequested(const QPoint&)'), + self.ui.tableWidgetInboxSubscriptions.customContextMenuRequested.connect( self.on_context_menuInbox) self.ui.tableWidgetInboxChans.setContextMenuPolicy( QtCore.Qt.CustomContextMenu) if connectSignal: - self.connect(self.ui.tableWidgetInboxChans, QtCore.SIGNAL( - 'customContextMenuRequested(const QPoint&)'), + self.ui.tableWidgetInboxChans.customContextMenuRequested.connect( self.on_context_menuInbox) def init_identities_popup_menu(self, connectSignal=True): # Popup menu for the Your Identities tab - self.ui.addressContextMenuToolbarYourIdentities = QtGui.QToolBar() + self.ui.addressContextMenuToolbarYourIdentities = QtWidgets.QToolBar() # Actions self.actionNewYourIdentities = self.ui.addressContextMenuToolbarYourIdentities.addAction(_translate( "MainWindow", "New"), self.on_action_YourIdentitiesNew) @@ -278,8 +259,7 @@ class MyForm(settingsmixin.SMainWindow): self.ui.treeWidgetYourIdentities.setContextMenuPolicy( QtCore.Qt.CustomContextMenu) if connectSignal: - self.connect(self.ui.treeWidgetYourIdentities, QtCore.SIGNAL( - 'customContextMenuRequested(const QPoint&)'), + self.ui.treeWidgetYourIdentities.customContextMenuRequested.connect( self.on_context_menuYourIdentities) # load all gui.menu plugins with prefix 'address' @@ -328,13 +308,12 @@ class MyForm(settingsmixin.SMainWindow): self.ui.treeWidgetChans.setContextMenuPolicy( QtCore.Qt.CustomContextMenu) if connectSignal: - self.connect(self.ui.treeWidgetChans, QtCore.SIGNAL( - 'customContextMenuRequested(const QPoint&)'), + self.ui.treeWidgetChans.customContextMenuRequested.connect( self.on_context_menuChan) def init_addressbook_popup_menu(self, connectSignal=True): # Popup menu for the Address Book page - self.ui.addressBookContextMenuToolbar = QtGui.QToolBar() + self.ui.addressBookContextMenuToolbar = QtWidgets.QToolBar() # Actions self.actionAddressBookSend = self.ui.addressBookContextMenuToolbar.addAction( _translate( @@ -365,8 +344,7 @@ class MyForm(settingsmixin.SMainWindow): self.ui.tableWidgetAddressBook.setContextMenuPolicy( QtCore.Qt.CustomContextMenu) if connectSignal: - self.connect(self.ui.tableWidgetAddressBook, QtCore.SIGNAL( - 'customContextMenuRequested(const QPoint&)'), + self.ui.tableWidgetAddressBook.customContextMenuRequested.connect( self.on_context_menuAddressBook) def init_subscriptions_popup_menu(self, connectSignal=True): @@ -394,8 +372,7 @@ class MyForm(settingsmixin.SMainWindow): self.ui.treeWidgetSubscriptions.setContextMenuPolicy( QtCore.Qt.CustomContextMenu) if connectSignal: - self.connect(self.ui.treeWidgetSubscriptions, QtCore.SIGNAL( - 'customContextMenuRequested(const QPoint&)'), + self.ui.treeWidgetSubscriptions.customContextMenuRequested.connect( self.on_context_menuSubscriptions) def init_sent_popup_menu(self, connectSignal=True): @@ -413,7 +390,7 @@ class MyForm(settingsmixin.SMainWindow): self.actionSentReply = self.ui.sentContextMenuToolbar.addAction( _translate("MainWindow", "Send update"), self.on_action_SentReply) - # self.popMenuSent = QtGui.QMenu( self ) + # self.popMenuSent = QtWidgets.QMenu( self ) # self.popMenuSent.addAction( self.actionSentClipboard ) # self.popMenuSent.addAction( self.actionTrashSentMessage ) @@ -437,7 +414,6 @@ class MyForm(settingsmixin.SMainWindow): if treeWidget.isSortingEnabled(): treeWidget.setSortingEnabled(False) - widgets = {} i = 0 while i < treeWidget.topLevelItemCount(): widget = treeWidget.topLevelItem(i) @@ -455,7 +431,8 @@ class MyForm(settingsmixin.SMainWindow): while j < widget.childCount(): subwidget = widget.child(j) try: - subwidget.setUnreadCount(db[toAddress][subwidget.folderName]['count']) + subwidget.setUnreadCount( + db[toAddress][subwidget.folderName]['count']) unread += db[toAddress][subwidget.folderName]['count'] db[toAddress].pop(subwidget.folderName, None) except: @@ -469,7 +446,8 @@ class MyForm(settingsmixin.SMainWindow): j = 0 for f, c in db[toAddress].iteritems(): try: - subwidget = Ui_FolderWidget(widget, j, toAddress, f, c['count']) + subwidget = Ui_FolderWidget( + widget, j, toAddress, f, c['count']) except KeyError: subwidget = Ui_FolderWidget(widget, j, toAddress, f, 0) j += 1 @@ -479,15 +457,21 @@ class MyForm(settingsmixin.SMainWindow): i = 0 for toAddress in db: - widget = Ui_SubscriptionWidget(treeWidget, i, toAddress, db[toAddress]["inbox"]['count'], db[toAddress]["inbox"]['label'], db[toAddress]["inbox"]['enabled']) + widget = Ui_SubscriptionWidget( + treeWidget, i, toAddress, db[toAddress]["inbox"]['count'], + db[toAddress]["inbox"]['label'], + db[toAddress]["inbox"]['enabled']) j = 0 unread = 0 for folder in folders: try: - subwidget = Ui_FolderWidget(widget, j, toAddress, folder, db[toAddress][folder]['count']) + subwidget = Ui_FolderWidget( + widget, j, toAddress, folder, + db[toAddress][folder]['count']) unread += db[toAddress][folder]['count'] except KeyError: - subwidget = Ui_FolderWidget(widget, j, toAddress, folder, 0) + subwidget = Ui_FolderWidget( + widget, j, toAddress, folder, 0) j += 1 widget.setUnreadCount(unread) i += 1 @@ -520,8 +504,8 @@ class MyForm(settingsmixin.SMainWindow): toAddress, 'enabled') isChan = BMConfigParser().safeGetBoolean( toAddress, 'chan') - isMaillinglist = BMConfigParser().safeGetBoolean( - toAddress, 'mailinglist') + # isMaillinglist = BMConfigParser().safeGetBoolean( + # toAddress, 'mailinglist') if treeWidget == self.ui.treeWidgetYourIdentities: if isChan: @@ -555,7 +539,6 @@ class MyForm(settingsmixin.SMainWindow): if treeWidget.isSortingEnabled(): treeWidget.setSortingEnabled(False) - widgets = {} i = 0 while i < treeWidget.topLevelItemCount(): widget = treeWidget.topLevelItem(i) @@ -616,7 +599,7 @@ class MyForm(settingsmixin.SMainWindow): treeWidget.setSortingEnabled(True) def __init__(self, parent=None): - QtGui.QWidget.__init__(self, parent) + super(MyForm, self).__init__(parent) self.ui = Ui_MainWindow() self.ui.setupUi(self) @@ -634,11 +617,13 @@ class MyForm(settingsmixin.SMainWindow): addressInKeysFile) if addressVersionNumber == 1: displayMsg = _translate( - "MainWindow", "One of your addresses, %1, is an old version 1 address. Version 1 addresses are no longer supported. " - + "May we delete it now?").arg(addressInKeysFile) - reply = QtGui.QMessageBox.question( - self, 'Message', displayMsg, QtGui.QMessageBox.Yes, QtGui.QMessageBox.No) - if reply == QtGui.QMessageBox.Yes: + "MainWindow", + "One of your addresses, {0}, is an old version 1" + " address. Version 1 addresses are no longer supported." + " May we delete it now?").format(addressInKeysFile) + reply = QtWidgets.QMessageBox.question( + self, 'Message', displayMsg, QtWidgets.QMessageBox.Yes, QtWidgets.QMessageBox.No) + if reply == QtWidgets.QMessageBox.Yes: BMConfigParser().remove_section(addressInKeysFile) BMConfigParser().save() @@ -682,107 +667,97 @@ class MyForm(settingsmixin.SMainWindow): self.rerenderSubscriptions() # Initialize the inbox search - QtCore.QObject.connect(self.ui.inboxSearchLineEdit, QtCore.SIGNAL( - "returnPressed()"), self.inboxSearchLineEditReturnPressed) - QtCore.QObject.connect(self.ui.inboxSearchLineEditSubscriptions, QtCore.SIGNAL( - "returnPressed()"), self.inboxSearchLineEditReturnPressed) - QtCore.QObject.connect(self.ui.inboxSearchLineEditChans, QtCore.SIGNAL( - "returnPressed()"), self.inboxSearchLineEditReturnPressed) - QtCore.QObject.connect(self.ui.inboxSearchLineEdit, QtCore.SIGNAL( - "textChanged(QString)"), self.inboxSearchLineEditUpdated) - QtCore.QObject.connect(self.ui.inboxSearchLineEditSubscriptions, QtCore.SIGNAL( - "textChanged(QString)"), self.inboxSearchLineEditUpdated) - QtCore.QObject.connect(self.ui.inboxSearchLineEditChans, QtCore.SIGNAL( - "textChanged(QString)"), self.inboxSearchLineEditUpdated) + for line_edit in ( + self.ui.inboxSearchLineEdit, + self.ui.inboxSearchLineEditSubscriptions, + self.ui.inboxSearchLineEditChans, + ): + line_edit.returnPressed.connect( + self.inboxSearchLineEditReturnPressed) + line_edit.textChanged.connect( + self.inboxSearchLineEditUpdated) # Initialize addressbook - QtCore.QObject.connect(self.ui.tableWidgetAddressBook, QtCore.SIGNAL( - "itemChanged(QTableWidgetItem *)"), self.tableWidgetAddressBookItemChanged) + self.ui.tableWidgetAddressBook.itemChanged.connect( + self.tableWidgetAddressBookItemChanged) + # This is necessary for the completer to work if multiple recipients - QtCore.QObject.connect(self.ui.lineEditTo, QtCore.SIGNAL( - "cursorPositionChanged(int, int)"), self.ui.lineEditTo.completer().onCursorPositionChanged) + self.ui.lineEditTo.cursorPositionChanged.connect( + self.ui.lineEditTo.completer().onCursorPositionChanged) # show messages from message list - QtCore.QObject.connect(self.ui.tableWidgetInbox, QtCore.SIGNAL( - "itemSelectionChanged ()"), self.tableWidgetInboxItemClicked) - QtCore.QObject.connect(self.ui.tableWidgetInboxSubscriptions, QtCore.SIGNAL( - "itemSelectionChanged ()"), self.tableWidgetInboxItemClicked) - QtCore.QObject.connect(self.ui.tableWidgetInboxChans, QtCore.SIGNAL( - "itemSelectionChanged ()"), self.tableWidgetInboxItemClicked) + for table_widget in ( + self.ui.tableWidgetInbox, + self.ui.tableWidgetInboxSubscriptions, + self.ui.tableWidgetInboxChans + ): + table_widget.itemSelectionChanged.connect( + self.tableWidgetInboxItemClicked) # tree address lists - QtCore.QObject.connect(self.ui.treeWidgetYourIdentities, QtCore.SIGNAL( - "itemSelectionChanged ()"), self.treeWidgetItemClicked) - QtCore.QObject.connect(self.ui.treeWidgetYourIdentities, QtCore.SIGNAL( - "itemChanged (QTreeWidgetItem *, int)"), self.treeWidgetItemChanged) - QtCore.QObject.connect(self.ui.treeWidgetSubscriptions, QtCore.SIGNAL( - "itemSelectionChanged ()"), self.treeWidgetItemClicked) - QtCore.QObject.connect(self.ui.treeWidgetSubscriptions, QtCore.SIGNAL( - "itemChanged (QTreeWidgetItem *, int)"), self.treeWidgetItemChanged) - QtCore.QObject.connect(self.ui.treeWidgetChans, QtCore.SIGNAL( - "itemSelectionChanged ()"), self.treeWidgetItemClicked) - QtCore.QObject.connect(self.ui.treeWidgetChans, QtCore.SIGNAL( - "itemChanged (QTreeWidgetItem *, int)"), self.treeWidgetItemChanged) - QtCore.QObject.connect( - self.ui.tabWidget, QtCore.SIGNAL("currentChanged(int)"), - self.tabWidgetCurrentChanged - ) + for tree_widget in ( + self.ui.treeWidgetYourIdentities, + self.ui.treeWidgetSubscriptions, + self.ui.treeWidgetChans + ): + tree_widget.itemSelectionChanged.connect( + self.treeWidgetItemClicked) + tree_widget.itemChanged.connect(self.treeWidgetItemChanged) + + self.ui.tabWidget.currentChanged.connect(self.tabWidgetCurrentChanged) # Put the colored icon on the status bar # self.pushButtonStatusIcon.setIcon(QIcon(":/newPrefix/images/yellowicon.png")) self.setStatusBar(BMStatusBar()) self.statusbar = self.statusBar() - self.pushButtonStatusIcon = QtGui.QPushButton(self) + self.pushButtonStatusIcon = QtWidgets.QPushButton(self) self.pushButtonStatusIcon.setText('') self.pushButtonStatusIcon.setIcon( QtGui.QIcon(':/newPrefix/images/redicon.png')) self.pushButtonStatusIcon.setFlat(True) self.statusbar.insertPermanentWidget(0, self.pushButtonStatusIcon) - QtCore.QObject.connect(self.pushButtonStatusIcon, QtCore.SIGNAL( - "clicked()"), self.click_pushButtonStatusIcon) + self.pushButtonStatusIcon.clicked.connect( + self.click_pushButtonStatusIcon) self.unreadCount = 0 # Set the icon sizes for the identicons - identicon_size = 3*7 - self.ui.tableWidgetInbox.setIconSize(QtCore.QSize(identicon_size, identicon_size)) - self.ui.treeWidgetChans.setIconSize(QtCore.QSize(identicon_size, identicon_size)) - self.ui.treeWidgetYourIdentities.setIconSize(QtCore.QSize(identicon_size, identicon_size)) - self.ui.treeWidgetSubscriptions.setIconSize(QtCore.QSize(identicon_size, identicon_size)) - self.ui.tableWidgetAddressBook.setIconSize(QtCore.QSize(identicon_size, identicon_size)) - + identicon_size = 3 * 7 + for widget in ( + self.ui.tableWidgetInbox, self.ui.treeWidgetChans, + self.ui.treeWidgetYourIdentities, self.ui.treeWidgetSubscriptions, + self.ui.tableWidgetAddressBook + ): + widget.setIconSize(QtCore.QSize(identicon_size, identicon_size)) + self.UISignalThread = UISignaler.get() - QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL( - "writeNewAddressToTable(PyQt_PyObject,PyQt_PyObject,PyQt_PyObject)"), self.writeNewAddressToTable) - QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL( - "updateStatusBar(PyQt_PyObject)"), self.updateStatusBar) - QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL( - "updateSentItemStatusByToAddress(PyQt_PyObject,PyQt_PyObject)"), self.updateSentItemStatusByToAddress) - QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL( - "updateSentItemStatusByAckdata(PyQt_PyObject,PyQt_PyObject)"), self.updateSentItemStatusByAckdata) - QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL( - "displayNewInboxMessage(PyQt_PyObject,PyQt_PyObject,PyQt_PyObject,PyQt_PyObject,PyQt_PyObject)"), self.displayNewInboxMessage) - QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL( - "displayNewSentMessage(PyQt_PyObject,PyQt_PyObject,PyQt_PyObject,PyQt_PyObject,PyQt_PyObject,PyQt_PyObject)"), self.displayNewSentMessage) - QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL( - "setStatusIcon(PyQt_PyObject)"), self.setStatusIcon) - QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL( - "changedInboxUnread(PyQt_PyObject)"), self.changedInboxUnread) - QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL( - "rerenderMessagelistFromLabels()"), self.rerenderMessagelistFromLabels) - QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL( - "rerenderMessgelistToLabels()"), self.rerenderMessagelistToLabels) - QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL( - "rerenderAddressBook()"), self.rerenderAddressBook) - QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL( - "rerenderSubscriptions()"), self.rerenderSubscriptions) - QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL( - "removeInboxRowByMsgid(PyQt_PyObject)"), self.removeInboxRowByMsgid) - QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL( - "newVersionAvailable(PyQt_PyObject)"), self.newVersionAvailable) - QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL( - "displayAlert(PyQt_PyObject,PyQt_PyObject,PyQt_PyObject)"), self.displayAlert) + self.UISignalThread.writeNewAddressToTable.connect( + self.writeNewAddressToTable) + self.UISignalThread.updateStatusBar.connect(self.updateStatusBar) + self.UISignalThread.updateSentItemStatusByToAddress.connect( + self.updateSentItemStatusByToAddress) + self.UISignalThread.updateSentItemStatusByAckdata.connect( + self.updateSentItemStatusByAckdata) + self.UISignalThread.displayNewInboxMessage.connect( + self.displayNewInboxMessage) + self.UISignalThread.displayNewSentMessage.connect( + self.displayNewSentMessage) + self.UISignalThread.setStatusIcon.connect(self.setStatusIcon) + self.UISignalThread.changedInboxUnread.connect(self.changedInboxUnread) + self.UISignalThread.rerenderMessagelistFromLabels.connect( + self.rerenderMessagelistFromLabels) + self.UISignalThread.rerenderMessagelistToLabels.connect( + self.rerenderMessagelistToLabels) + self.UISignalThread.rerenderAddressBook.connect( + self.rerenderAddressBook) + self.UISignalThread.rerenderSubscriptions.connect( + self.rerenderSubscriptions) + self.UISignalThread.removeInboxRowByMsgid.connect( + self.removeInboxRowByMsgid) + self.UISignalThread.newVersionAvailable.connect( + self.newVersionAvailable) + self.UISignalThread.displayAlert.connect(self.displayAlert) self.UISignalThread.start() # Key press in tree view @@ -811,16 +786,15 @@ class MyForm(settingsmixin.SMainWindow): # Put the TTL slider in the correct spot TTL = BMConfigParser().getint('bitmessagesettings', 'ttl') - if TTL < 3600: # an hour + if TTL < 3600: # an hour TTL = 3600 - elif TTL > 28*24*60*60: # 28 days - TTL = 28*24*60*60 - self.ui.horizontalSliderTTL.setSliderPosition((TTL - 3600) ** (1/3.199)) + elif TTL > 28 * 24 * 60 * 60: # 28 days + TTL = 28 * 24 * 60 * 60 + self.ui.horizontalSliderTTL.setSliderPosition( + (TTL - 3600) ** (1 / 3.199)) self.updateHumanFriendlyTTLDescription(TTL) - - QtCore.QObject.connect(self.ui.horizontalSliderTTL, QtCore.SIGNAL( - "valueChanged(int)"), self.updateTTL) + self.ui.horizontalSliderTTL.valueChanged.connect(self.updateTTL) self.initSettings() self.resetNamecoinConnection() self.sqlInit() @@ -875,21 +849,25 @@ class MyForm(settingsmixin.SMainWindow): BMConfigParser().save() def updateHumanFriendlyTTLDescription(self, TTL): - numberOfHours = int(round(TTL / (60*60))) + numberOfHours = int(round(TTL / (60 * 60))) font = QtGui.QFont() stylesheet = "" if numberOfHours < 48: self.ui.labelHumanFriendlyTTLDescription.setText( - _translate("MainWindow", "%n hour(s)", None, QtCore.QCoreApplication.CodecForTr, numberOfHours) + - ", " + - _translate("MainWindow", "not recommended for chans", None, QtCore.QCoreApplication.CodecForTr) - ) + _translate( + "MainWindow", "%n hour(s)", None, numberOfHours + ) + ",\n" + + _translate("MainWindow", "not recommended for chans") + ) stylesheet = "QLabel { color : red; }" font.setBold(True) else: - numberOfDays = int(round(TTL / (24*60*60))) - self.ui.labelHumanFriendlyTTLDescription.setText(_translate("MainWindow", "%n day(s)", None, QtCore.QCoreApplication.CodecForTr, numberOfDays)) + numberOfDays = int(round(TTL / (24 * 60 * 60))) + self.ui.labelHumanFriendlyTTLDescription.setText( + _translate( + "MainWindow", "%n day(s)", None, numberOfDays) + ) font.setBold(False) self.ui.labelHumanFriendlyTTLDescription.setStyleSheet(stylesheet) self.ui.labelHumanFriendlyTTLDescription.setFont(font) @@ -1117,20 +1095,19 @@ class MyForm(settingsmixin.SMainWindow): elif status == 'msgsent': statusText = _translate( "MainWindow", - "Message sent. Waiting for acknowledgement. Sent at %1" - ).arg(l10n.formatTimestamp(lastactiontime)) + "Message sent. Waiting for acknowledgement. Sent at {0}" + ).format(l10n.formatTimestamp(lastactiontime)) elif status == 'msgsentnoackexpected': statusText = _translate( - "MainWindow", "Message sent. Sent at %1" - ).arg(l10n.formatTimestamp(lastactiontime)) + "MainWindow", "Message sent. Sent at {0}" + ).format(l10n.formatTimestamp(lastactiontime)) elif status == 'doingmsgpow': statusText = _translate( "MainWindow", "Doing work necessary to send message.") elif status == 'ackreceived': statusText = _translate( - "MainWindow", - "Acknowledgement of the message received %1" - ).arg(l10n.formatTimestamp(lastactiontime)) + "MainWindow", "Acknowledgement of the message received {0}" + ).format(l10n.formatTimestamp(lastactiontime)) elif status == 'broadcastqueued': statusText = _translate( "MainWindow", "Broadcast queued.") @@ -1138,36 +1115,34 @@ class MyForm(settingsmixin.SMainWindow): statusText = _translate( "MainWindow", "Doing work necessary to send broadcast.") elif status == 'broadcastsent': - statusText = _translate("MainWindow", "Broadcast on %1").arg( - l10n.formatTimestamp(lastactiontime)) + statusText = _translate("MainWindow", "Broadcast on {0}").format( + l10n.formatTimestamp(lastactiontime) + ) elif status == 'toodifficult': statusText = _translate( "MainWindow", "Problem: The work demanded by the recipient is more" - " difficult than you are willing to do. %1" - ).arg(l10n.formatTimestamp(lastactiontime)) + " difficult than you are willing to do. {0}" + ).format(l10n.formatTimestamp(lastactiontime)) elif status == 'badkey': statusText = _translate( "MainWindow", "Problem: The recipient\'s encryption key is no good." - " Could not encrypt message. %1" - ).arg(l10n.formatTimestamp(lastactiontime)) + " Could not encrypt message. {0}" + ).format(l10n.formatTimestamp(lastactiontime)) elif status == 'forcepow': statusText = _translate( "MainWindow", "Forced difficulty override. Send should start soon.") else: statusText = _translate( - "MainWindow", "Unknown status: %1 %2").arg(status).arg( - l10n.formatTimestamp(lastactiontime)) + "MainWindow", "Unknown status: {0} {1}" + ).format(status, l10n.formatTimestamp(lastactiontime)) items = [ - MessageList_AddressWidget( - toAddress, unicode(acct.toLabel, 'utf-8')), - MessageList_AddressWidget( - fromAddress, unicode(acct.fromLabel, 'utf-8')), - MessageList_SubjectWidget( - str(subject), unicode(acct.subject, 'utf-8', 'replace')), + MessageList_AddressWidget(toAddress, acct.toLabel), + MessageList_AddressWidget(fromAddress, acct.fromLabel), + MessageList_SubjectWidget(subject, acct.subject), MessageList_TimeWidget( statusText, False, lastactiontime, ackdata)] self.addMessageListItem(tableWidget, items) @@ -1187,13 +1162,9 @@ class MyForm(settingsmixin.SMainWindow): acct.parseMessage(toAddress, fromAddress, subject, "") items = [ - MessageList_AddressWidget( - toAddress, unicode(acct.toLabel, 'utf-8'), not read), - MessageList_AddressWidget( - fromAddress, unicode(acct.fromLabel, 'utf-8'), not read), - MessageList_SubjectWidget( - str(subject), unicode(acct.subject, 'utf-8', 'replace'), - not read), + MessageList_AddressWidget(toAddress, acct.toLabel, not read), + MessageList_AddressWidget(fromAddress, acct.fromLabel, not read), + MessageList_SubjectWidget(subject, acct.subject, not read), MessageList_TimeWidget( l10n.formatTimestamp(received), not read, received, msgid) ] @@ -1262,7 +1233,7 @@ class MyForm(settingsmixin.SMainWindow): for row in queryreturn: toAddress, fromAddress, subject, _, msgid, received, read = row self.addMessageListItemInbox( - tableWidget, toAddress, fromAddress, subject, + tableWidget, toAddress, fromAddress, unicode(subject, 'utf-8'), msgid, received, read) tableWidget.horizontalHeader().setSortIndicator( @@ -1276,23 +1247,21 @@ class MyForm(settingsmixin.SMainWindow): # create application indicator def appIndicatorInit(self, app): self.initTrayIcon("can-icon-24px-red.png", app) - traySignal = "activated(QSystemTrayIcon::ActivationReason)" - QtCore.QObject.connect(self.tray, QtCore.SIGNAL( - traySignal), self.__icon_activated) + self.tray.activated.connect(self.__icon_activated) - m = QtGui.QMenu() + m = QtWidgets.QMenu() - self.actionStatus = QtGui.QAction(_translate( + self.actionStatus = QtWidgets.QAction(_translate( "MainWindow", "Not Connected"), m, checkable=False) m.addAction(self.actionStatus) # separator - actionSeparator = QtGui.QAction('', m, checkable=False) + actionSeparator = QtWidgets.QAction('', m, checkable=False) actionSeparator.setSeparator(True) m.addAction(actionSeparator) # show bitmessage - self.actionShow = QtGui.QAction(_translate( + self.actionShow = QtWidgets.QAction(_translate( "MainWindow", "Show Bitmessage"), m, checkable=True) self.actionShow.setChecked(not BMConfigParser().getboolean( 'bitmessagesettings', 'startintray')) @@ -1301,7 +1270,7 @@ class MyForm(settingsmixin.SMainWindow): m.addAction(self.actionShow) # quiet mode - self.actionQuiet = QtGui.QAction(_translate( + self.actionQuiet = QtWidgets.QAction(_translate( "MainWindow", "Quiet Mode"), m, checkable=True) self.actionQuiet.setChecked(not BMConfigParser().getboolean( 'bitmessagesettings', 'showtraynotifications')) @@ -1309,25 +1278,25 @@ class MyForm(settingsmixin.SMainWindow): m.addAction(self.actionQuiet) # Send - actionSend = QtGui.QAction(_translate( + actionSend = QtWidgets.QAction(_translate( "MainWindow", "Send"), m, checkable=False) actionSend.triggered.connect(self.appIndicatorSend) m.addAction(actionSend) # Subscribe - actionSubscribe = QtGui.QAction(_translate( + actionSubscribe = QtWidgets.QAction(_translate( "MainWindow", "Subscribe"), m, checkable=False) actionSubscribe.triggered.connect(self.appIndicatorSubscribe) m.addAction(actionSubscribe) # Channels - actionSubscribe = QtGui.QAction(_translate( + actionSubscribe = QtWidgets.QAction(_translate( "MainWindow", "Channel"), m, checkable=False) actionSubscribe.triggered.connect(self.appIndicatorChannel) m.addAction(actionSubscribe) # separator - actionSeparator = QtGui.QAction('', m, checkable=False) + actionSeparator = QtWidgets.QAction('', m, checkable=False) actionSeparator.setSeparator(True) m.addAction(actionSeparator) @@ -1447,8 +1416,6 @@ class MyForm(settingsmixin.SMainWindow): self.tray.showMessage(title, subtitle, 1, 2000) self._notifier = _simple_notify - # does nothing if isAvailable returns false - self._player = QtGui.QSound.play if not get_plugins: return @@ -1461,7 +1428,10 @@ class MyForm(settingsmixin.SMainWindow): self._theme_player = get_plugin('notification.sound', 'theme') - if not QtGui.QSound.isAvailable(): + try: + from PyQt5 import QtMultimedia + self._player = QtMultimedia.QSound.play + except ImportError: _plugin = get_plugin( 'notification.sound', 'file', fallback='file.fallback') if _plugin: @@ -1485,7 +1455,7 @@ class MyForm(settingsmixin.SMainWindow): if event.key() == QtCore.Qt.Key_Delete: self.on_action_AddressBookDelete() else: - return QtGui.QTableWidget.keyPressEvent( + return QtWidgets.QTableWidget.keyPressEvent( self.ui.tableWidgetAddressBook, event) # inbox / sent @@ -1500,14 +1470,14 @@ class MyForm(settingsmixin.SMainWindow): """This method handles keypress events for all widgets on MyForm""" messagelist = self.getCurrentMessagelist() if event.key() == QtCore.Qt.Key_Delete: - if isinstance(focus, (MessageView, QtGui.QTableWidget)): + if isinstance(focus, (MessageView, QtWidgets.QTableWidget)): folder = self.getCurrentFolder() if folder == "sent": self.on_action_SentTrash() else: self.on_action_InboxTrash() event.ignore() - elif QtGui.QApplication.queryKeyboardModifiers() == QtCore.Qt.NoModifier: + elif QtWidgets.QApplication.queryKeyboardModifiers() == QtCore.Qt.NoModifier: if event.key() == QtCore.Qt.Key_N: currentRow = messagelist.currentRow() if currentRow < messagelist.rowCount() - 1: @@ -1546,38 +1516,71 @@ class MyForm(settingsmixin.SMainWindow): return if isinstance(focus, MessageView): return MessageView.keyPressEvent(focus, event) - if isinstance(focus, QtGui.QTableWidget): - return QtGui.QTableWidget.keyPressEvent(focus, event) - if isinstance(focus, QtGui.QTreeWidget): - return QtGui.QTreeWidget.keyPressEvent(focus, event) + elif isinstance(focus, QtWidgets.QTableWidget): + return QtWidgets.QTableWidget.keyPressEvent(focus, event) + elif isinstance(focus, QtWidgets.QTreeWidget): + return QtWidgets.QTreeWidget.keyPressEvent(focus, event) # menu button 'manage keys' def click_actionManageKeys(self): if 'darwin' in sys.platform or 'linux' in sys.platform: if state.appdata == '': - # reply = QtGui.QMessageBox.information(self, 'keys.dat?','You + # reply = QtWidgets.QMessageBox.information(self, 'keys.dat?','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.', QMessageBox.Ok) - reply = QtGui.QMessageBox.information(self, 'keys.dat?', _translate( - "MainWindow", "You may manage your keys by editing the keys.dat file stored in the same directory as this program. It is important that you back up this file."), QtGui.QMessageBox.Ok) + reply = QtWidgets.QMessageBox.information( + self, 'keys.dat?', _translate( + "MainWindow", + "You may manage your keys by editing the keys.dat" + " file stored in the same directory as this" + " program. It is important that you back up this" + " file."), QtWidgets.QMessageBox.Ok) else: - QtGui.QMessageBox.information(self, 'keys.dat?', _translate( - "MainWindow", "You may manage your keys by editing the keys.dat file stored in\n %1 \nIt is important that you back up this file.").arg(state.appdata), QtGui.QMessageBox.Ok) + QtWidgets.QMessageBox.information( + self, 'keys.dat?', + _translate( + "MainWindow", + "You may manage your keys by editing the keys.dat" + " file stored in\n {0} \nIt is important that you" + " back up this file." + ).format(state.appdata), + QtWidgets.QMessageBox.Ok + ) elif sys.platform == 'win32' or sys.platform == 'win64': if state.appdata == '': - reply = QtGui.QMessageBox.question(self, _translate("MainWindow", "Open keys.dat?"), _translate( - "MainWindow", "You may manage your keys by editing the keys.dat file stored in the same directory as this program. It is important that you back up this file. Would you like to open the file now? (Be sure to close Bitmessage before making any changes.)"), QtGui.QMessageBox.Yes, QtGui.QMessageBox.No) + reply = QtWidgets.QMessageBox.question( + self, _translate("MainWindow", "Open keys.dat?"), + _translate( + "MainWindow", + "You may manage your keys by editing the keys.dat" + " file stored in the same directory as this" + " program. It is important that you back up this" + " file. Would you like to open the file now?" + " (Be sure to close Bitmessage before making any" + " changes.)" + ), QtWidgets.QMessageBox.Yes, QtWidgets.QMessageBox.No) else: - reply = QtGui.QMessageBox.question(self, _translate("MainWindow", "Open keys.dat?"), _translate( - "MainWindow", "You may manage your keys by editing the keys.dat file stored in\n %1 \nIt is important that you back up this file. Would you like to open the file now? (Be sure to close Bitmessage before making any changes.)").arg(state.appdata), QtGui.QMessageBox.Yes, QtGui.QMessageBox.No) - if reply == QtGui.QMessageBox.Yes: + reply = QtWidgets.QMessageBox.question( + self, + _translate("MainWindow", "Open keys.dat?"), + _translate( + "MainWindow", + "You may manage your keys by editing the keys.dat" + " file stored in\n {0} \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.)" + ).format(state.appdata), + QtWidgets.QMessageBox.Yes, QtWidgets.QMessageBox.No + ) + if reply == QtWidgets.QMessageBox.Yes: openKeysFile() # menu button 'delete all treshed messages' def click_actionDeleteAllTrashedMessages(self): - if QtGui.QMessageBox.question(self, _translate("MainWindow", "Delete trash?"), _translate("MainWindow", "Are you sure you want to delete all trashed messages?"), QtGui.QMessageBox.Yes, QtGui.QMessageBox.No) == QtGui.QMessageBox.No: + if QtWidgets.QMessageBox.question(self, _translate("MainWindow", "Delete trash?"), _translate("MainWindow", "Are you sure you want to delete all trashed messages?"), QtWidgets.QMessageBox.Yes, QtWidgets.QMessageBox.No) == QtWidgets.QMessageBox.No: return sqlStoredProcedure('deleteandvacuume') self.rerenderTabTreeMessages() @@ -1595,7 +1598,7 @@ class MyForm(settingsmixin.SMainWindow): dialog = dialogs.RegenerateAddressesDialog(self) if dialog.exec_(): if dialog.lineEditPassphrase.text() == "": - QtGui.QMessageBox.about( + QtWidgets.QMessageBox.about( self, _translate("MainWindow", "bad passphrase"), _translate( "MainWindow", @@ -1608,7 +1611,7 @@ class MyForm(settingsmixin.SMainWindow): addressVersionNumber = int( dialog.lineEditAddressVersionNumber.text()) except: - QtGui.QMessageBox.about( + QtWidgets.QMessageBox.about( self, _translate("MainWindow", "Bad address version number"), _translate( @@ -1618,7 +1621,7 @@ class MyForm(settingsmixin.SMainWindow): )) return if addressVersionNumber < 3 or addressVersionNumber > 4: - QtGui.QMessageBox.about( + QtWidgets.QMessageBox.about( self, _translate("MainWindow", "Bad address version number"), _translate( @@ -1631,7 +1634,7 @@ class MyForm(settingsmixin.SMainWindow): addressVersionNumber, streamNumberForAddress, "regenerated deterministic address", dialog.spinBoxNumberOfAddressesToMake.value(), - dialog.lineEditPassphrase.text().toUtf8(), + dialog.lineEditPassphrase.text().encode('utf-8'), dialog.checkBoxEighteenByteRipe.isChecked() )) self.ui.tabWidget.setCurrentIndex( @@ -1655,13 +1658,6 @@ class MyForm(settingsmixin.SMainWindow): else: self._firstrun = False - def showMigrationWizard(self, level): - self.migrationWizardInstance = Ui_MigrationWizard(["a"]) - if self.migrationWizardInstance.exec_(): - pass - else: - pass - def changeEvent(self, event): if event.type() == QtCore.QEvent.LanguageChange: self.ui.retranslateUi(self) @@ -1682,7 +1678,7 @@ class MyForm(settingsmixin.SMainWindow): pass def __icon_activated(self, reason): - if reason == QtGui.QSystemTrayIcon.Trigger: + if reason == QtWidgets.QSystemTrayIcon.Trigger: self.actionShow.setChecked(not self.actionShow.isChecked()) self.appIndicatorShowOrHideWindow() @@ -1755,7 +1751,7 @@ class MyForm(settingsmixin.SMainWindow): def initTrayIcon(self, iconFileName, app): self.currentTrayIconFileName = iconFileName - self.tray = QtGui.QSystemTrayIcon( + self.tray = QtWidgets.QSystemTrayIcon( self.calcTrayIcon(iconFileName, self.findInboxUnreadCount()), app) def setTrayIconFile(self, iconFileName): @@ -1785,6 +1781,7 @@ class MyForm(settingsmixin.SMainWindow): fontMetrics = QtGui.QFontMetrics(font) rect = fontMetrics.boundingRect(txt) # draw text + # painter = QtGui.QPainter(self) painter = QtGui.QPainter() painter.begin(pixmap) painter.setPen( @@ -1835,8 +1832,11 @@ class MyForm(settingsmixin.SMainWindow): if toAddress == rowAddress: sent.item(i, 3).setToolTip(textToDisplay) try: - newlinePosition = textToDisplay.indexOf('\n') - except: # If someone misses adding a "_translate" to a string before passing it to this function, this function won't receive a qstring which will cause an exception. + newlinePosition = textToDisplay.find('\n') + # If someone misses adding a "_translate" to a string + # before passing it to this function + # ? why textToDisplay isn't unicode + except AttributeError: newlinePosition = 0 if newlinePosition > 1: sent.item(i, 3).setText( @@ -1845,8 +1845,6 @@ class MyForm(settingsmixin.SMainWindow): sent.item(i, 3).setText(textToDisplay) def updateSentItemStatusByAckdata(self, ackdata, textToDisplay): - if type(ackdata) is str: - ackdata = QtCore.QByteArray(ackdata) for sent in ( self.ui.tableWidgetInbox, self.ui.tableWidgetInboxSubscriptions, @@ -1856,21 +1854,22 @@ class MyForm(settingsmixin.SMainWindow): if self.getCurrentFolder(treeWidget) != "sent": continue for i in range(sent.rowCount()): - toAddress = sent.item(i, 0).data(QtCore.Qt.UserRole) - tableAckdata = sent.item(i, 3).data() - status, addressVersionNumber, streamNumber, ripe = decodeAddress( - toAddress) - if ackdata == tableAckdata: + # toAddress = sent.item(i, 0).data(QtCore.Qt.UserRole) + # decodeAddress(toAddress) + + if sent.item(i, 3).data() == ackdata: sent.item(i, 3).setToolTip(textToDisplay) try: - newlinePosition = textToDisplay.indexOf('\n') - except: # If someone misses adding a "_translate" to a string before passing it to this function, this function won't receive a qstring which will cause an exception. + newlinePosition = textToDisplay.find('\n') + # If someone misses adding a "_translate" to a string + # before passing it to this function + # ? why textToDisplay isn't unicode + except AttributeError: newlinePosition = 0 if newlinePosition > 1: - sent.item(i, 3).setText( - textToDisplay[:newlinePosition]) - else: - sent.item(i, 3).setText(textToDisplay) + textToDisplay = textToDisplay[:newlinePosition] + + sent.item(i, 3).setText(textToDisplay) def removeInboxRowByMsgid(self, msgid): # msgid and inventoryHash are the same thing @@ -1898,33 +1897,42 @@ class MyForm(settingsmixin.SMainWindow): self.notifiedNewVersion = ".".join(str(n) for n in version) self.updateStatusBar(_translate( "MainWindow", - "New version of PyBitmessage is available: %1. Download it" + "New version of PyBitmessage is available: {0}. Download it" " from https://github.com/Bitmessage/PyBitmessage/releases/latest" - ).arg(self.notifiedNewVersion) + ).format(self.notifiedNewVersion) ) def displayAlert(self, title, text, exitAfterUserClicksOk): self.updateStatusBar(text) - QtGui.QMessageBox.critical(self, title, text, QtGui.QMessageBox.Ok) + QtWidgets.QMessageBox.critical( + self, title, text, QtWidgets.QMessageBox.Ok) if exitAfterUserClicksOk: os._exit(0) def rerenderMessagelistFromLabels(self): - for messagelist in (self.ui.tableWidgetInbox, self.ui.tableWidgetInboxChans, self.ui.tableWidgetInboxSubscriptions): + for messagelist in ( + self.ui.tableWidgetInbox, + self.ui.tableWidgetInboxChans, + self.ui.tableWidgetInboxSubscriptions + ): for i in range(messagelist.rowCount()): messagelist.item(i, 1).setLabel() def rerenderMessagelistToLabels(self): - for messagelist in (self.ui.tableWidgetInbox, self.ui.tableWidgetInboxChans, self.ui.tableWidgetInboxSubscriptions): + for messagelist in ( + self.ui.tableWidgetInbox, + self.ui.tableWidgetInboxChans, + self.ui.tableWidgetInboxSubscriptions + ): for i in range(messagelist.rowCount()): messagelist.item(i, 0).setLabel() def rerenderAddressBook(self): - def addRow (address, label, type): + def addRow(address, label, type): self.ui.tableWidgetAddressBook.insertRow(0) - newItem = Ui_AddressBookWidgetItemLabel(address, unicode(label, 'utf-8'), type) + newItem = Ui_AddressBookWidgetItemLabel(address, label, type) self.ui.tableWidgetAddressBook.setItem(0, 0, newItem) - newItem = Ui_AddressBookWidgetItemAddress(address, unicode(label, 'utf-8'), type) + newItem = Ui_AddressBookWidgetItemAddress(address, label, type) self.ui.tableWidgetAddressBook.setItem(0, 1, newItem) oldRows = {} @@ -1942,18 +1950,21 @@ class MyForm(settingsmixin.SMainWindow): queryreturn = sqlQuery('SELECT label, address FROM subscriptions WHERE enabled = 1') for row in queryreturn: label, address = row - newRows[address] = [label, AccountMixin.SUBSCRIPTION] + newRows[address] = [unicode(label, 'utf-8'), AccountMixin.SUBSCRIPTION] # chans addresses = getSortedAccounts() for address in addresses: account = accountClass(address) - if (account.type == AccountMixin.CHAN and BMConfigParser().safeGetBoolean(address, 'enabled')): + if ( + account.type == AccountMixin.CHAN + and BMConfigParser().safeGetBoolean(address, 'enabled') + ): newRows[address] = [account.getLabel(), AccountMixin.CHAN] # normal accounts queryreturn = sqlQuery('SELECT * FROM addressbook') for row in queryreturn: label, address = row - newRows[address] = [label, AccountMixin.NORMAL] + newRows[address] = [unicode(label, 'utf-8'), AccountMixin.NORMAL] completerList = [] for address in sorted( @@ -1966,7 +1977,7 @@ class MyForm(settingsmixin.SMainWindow): self.ui.tableWidgetAddressBook.removeRow(oldRows[address][2]) for address in newRows: addRow(address, newRows[address][0], newRows[address][1]) - completerList.append(unicode(newRows[address][0], encoding="UTF-8") + " <" + address + ">") + completerList.append(newRows[address][0] + " <" + address + ">") # sort self.ui.tableWidgetAddressBook.sortByColumn( @@ -1978,11 +1989,17 @@ class MyForm(settingsmixin.SMainWindow): self.rerenderTabTreeSubscriptions() def click_pushButtonTTL(self): - QtGui.QMessageBox.information(self, 'Time To Live', _translate( - "MainWindow", """The TTL, or Time-To-Live is the length of time that the network will hold the message. - The recipient must get it during this time. If your Bitmessage client does not hear an acknowledgement, it - will resend the message automatically. The longer the Time-To-Live, the - more work your computer must do to send the message. A Time-To-Live of four or five days is often appropriate."""), QtGui.QMessageBox.Ok) + QtWidgets.QMessageBox.information( + self, 'Time To Live', _translate( + "MainWindow", + "The TTL, or Time-To-Live is the length of time that" + " the network will hold the message. The recipient must" + " get it during this time. If your Bitmessage client does" + " not hear an acknowledgement, it will resend the message" + " automatically. The longer the Time-To-Live, the more" + " work your computer must do to send the message. A" + " Time-To-Live of four or five days is often appropriate." + ), QtWidgets.QMessageBox.Ok) def click_pushButtonClear(self): self.ui.lineEditSubject.setText("") @@ -1991,7 +2008,10 @@ class MyForm(settingsmixin.SMainWindow): self.ui.comboBoxSendFrom.setCurrentIndex(0) def click_pushButtonSend(self): - encoding = 3 if QtGui.QApplication.queryKeyboardModifiers() & QtCore.Qt.ShiftModifier else 2 + # pylint: disable=too-many-locals + encoding = ( + 3 if QtWidgets.QApplication.queryKeyboardModifiers() + & QtCore.Qt.ShiftModifier else 2) self.statusbar.clearMessage() @@ -1999,38 +2019,36 @@ class MyForm(settingsmixin.SMainWindow): self.ui.tabWidgetSend.indexOf(self.ui.sendDirect): # message to specific people sendMessageToPeople = True - fromAddress = str(self.ui.comboBoxSendFrom.itemData( + fromAddress = self.ui.comboBoxSendFrom.itemData( self.ui.comboBoxSendFrom.currentIndex(), - QtCore.Qt.UserRole).toString()) - toAddresses = str(self.ui.lineEditTo.text().toUtf8()) - subject = str(self.ui.lineEditSubject.text().toUtf8()) - message = str( - self.ui.textEditMessage.document().toPlainText().toUtf8()) + QtCore.Qt.UserRole) + toAddresses = self.ui.lineEditTo.text() + subject = self.ui.lineEditSubject.text() + message = self.ui.textEditMessage.document().toPlainText() else: # broadcast message sendMessageToPeople = False - fromAddress = str(self.ui.comboBoxSendFromBroadcast.itemData( + fromAddress = self.ui.comboBoxSendFromBroadcast.itemData( self.ui.comboBoxSendFromBroadcast.currentIndex(), - QtCore.Qt.UserRole).toString()) - subject = str(self.ui.lineEditSubjectBroadcast.text().toUtf8()) - message = str( - self.ui.textEditMessageBroadcast.document().toPlainText().toUtf8()) - """ - The whole network message must fit in 2^18 bytes. - Let's assume 500 bytes of overhead. If someone wants to get that - too an exact number you are welcome to but I think that it would - be a better use of time to support message continuation so that - users can send messages of any length. - """ - if len(message) > (2 ** 18 - 500): - QtGui.QMessageBox.about( + QtCore.Qt.UserRole) + subject = self.ui.lineEditSubjectBroadcast.text() + message = \ + self.ui.textEditMessageBroadcast.document().toPlainText() + + # The whole network message must fit in 2^18 bytes. + # Let's assume 500 bytes of overhead. If someone wants to get that + # too an exact number you are welcome to but I think that it would + # be a better use of time to support message continuation so that + # users can send messages of any length. + if len(message) > 2 ** 18 - 500: + QtWidgets.QMessageBox.about( self, _translate("MainWindow", "Message too long"), _translate( "MainWindow", "The message that you are trying to send is too long" - " by %1 bytes. (The maximum is 261644 bytes). Please" + " by {0} bytes. (The maximum is 261644 bytes). Please" " cut it down before sending." - ).arg(len(message) - (2 ** 18 - 500))) + ).format(len(message) - (2 ** 18 - 500))) return acct = accountClass(fromAddress) @@ -2051,18 +2069,32 @@ class MyForm(settingsmixin.SMainWindow): # email address if toAddress.find("@") >= 0: if isinstance(acct, GatewayAccount): - acct.createMessage(toAddress, fromAddress, subject, message) + acct.createMessage( + toAddress, fromAddress, subject, message) subject = acct.subject toAddress = acct.toAddress else: - if QtGui.QMessageBox.question(self, "Sending an email?", _translate("MainWindow", - "You are trying to send an email instead of a bitmessage. This requires registering with a gateway. Attempt to register?"), - QtGui.QMessageBox.Yes|QtGui.QMessageBox.No) != QtGui.QMessageBox.Yes: + if QtWidgets.QMessageBox.question( + self, "Sending an email?", + _translate( + "MainWindow", + "You are trying to send an email" + " instead of a bitmessage. This" + " requires registering with a" + " gateway. Attempt to register?" + ), QtWidgets.QMessageBox.Yes + | QtWidgets.QMessageBox.No + ) != QtWidgets.QMessageBox.Yes: continue email = acct.getLabel() - if email[-14:] != "@mailchuck.com": #attempt register + # attempt register + if email[-14:] != "@mailchuck.com": # 12 character random email address - email = ''.join(random.SystemRandom().choice(string.ascii_lowercase) for _ in range(12)) + "@mailchuck.com" + email = ''.join( + random.SystemRandom().choice( + string.ascii_lowercase + ) for _ in range(12) + ) + "@mailchuck.com" acct = MailchuckAccount(fromAddress) acct.register(email) BMConfigParser().set(fromAddress, 'label', email) @@ -2072,75 +2104,79 @@ class MyForm(settingsmixin.SMainWindow): "MainWindow", "Error: Your account wasn't registered at" " an email gateway. Sending registration" - " now as %1, please wait for the registration" + " now as {0}, please wait for the registration" " to be processed before retrying sending." - ).arg(email) - ) + ).format(email)) return - status, addressVersionNumber, streamNumber = decodeAddress(toAddress)[:3] + status, addressVersionNumber, streamNumber = \ + decodeAddress(toAddress)[:3] if status != 'success': try: toAddress = unicode(toAddress, 'utf-8', 'ignore') except: - pass - logger.error('Error: Could not decode recipient address ' + toAddress + ':' + status) + logger.warning( + "Failed unicode(toAddress ):", + exc_info=True) + logger.error( + 'Error: Could not decode recipient address %s: %s', + toAddress, status) if status == 'missingbm': self.updateStatusBar(_translate( "MainWindow", "Error: Bitmessage addresses start with" - " BM- Please check the recipient address %1" - ).arg(toAddress)) + " BM- Please check the recipient address {0}" + ).format(toAddress)) elif status == 'checksumfailed': self.updateStatusBar(_translate( "MainWindow", - "Error: The recipient address %1 is not" + "Error: The recipient address {0} is not" " typed or copied correctly. Please check it." - ).arg(toAddress)) + ).format(toAddress)) elif status == 'invalidcharacters': self.updateStatusBar(_translate( "MainWindow", - "Error: The recipient address %1 contains" + "Error: The recipient address {0} contains" " invalid characters. Please check it." - ).arg(toAddress)) + ).format(toAddress)) elif status == 'versiontoohigh': self.updateStatusBar(_translate( "MainWindow", "Error: The version of the recipient address" - " %1 is too high. Either you need to upgrade" + " {0} is too high. Either you need to upgrade" " your Bitmessage software or your" " acquaintance is being clever." - ).arg(toAddress)) + ).format(toAddress)) elif status == 'ripetooshort': self.updateStatusBar(_translate( "MainWindow", "Error: Some data encoded in the recipient" - " address %1 is too short. There might be" + " address {0} is too short. There might be" " something wrong with the software of" " your acquaintance." - ).arg(toAddress)) + ).format(toAddress)) elif status == 'ripetoolong': self.updateStatusBar(_translate( "MainWindow", "Error: Some data encoded in the recipient" - " address %1 is too long. There might be" + " address {0} is too long. There might be" " something wrong with the software of" " your acquaintance." - ).arg(toAddress)) + ).format(toAddress)) elif status == 'varintmalformed': self.updateStatusBar(_translate( "MainWindow", "Error: Some data encoded in the recipient" - " address %1 is malformed. There might be" + " address {0} is malformed. There might be" " something wrong with the software of" " your acquaintance." - ).arg(toAddress)) + ).format(toAddress)) else: self.updateStatusBar(_translate( "MainWindow", "Error: Something is wrong with the" - " recipient address %1." - ).arg(toAddress)) + " recipient address {0}." + ).format(toAddress)) elif fromAddress == '': self.updateStatusBar(_translate( "MainWindow", @@ -2152,12 +2188,31 @@ class MyForm(settingsmixin.SMainWindow): toAddress = addBMIfNotPresent(toAddress) if addressVersionNumber > 4 or addressVersionNumber <= 1: - QtGui.QMessageBox.about(self, _translate("MainWindow", "Address version number"), _translate( - "MainWindow", "Concerning the address %1, Bitmessage cannot understand address version numbers of %2. Perhaps upgrade Bitmessage to the latest version.").arg(toAddress).arg(str(addressVersionNumber))) + QtWidgets.QMessageBox.about( + self, + _translate( + "MainWindow", "Address version number"), + _translate( + "MainWindow", + "Concerning the address {0}, Bitmessage" + " cannot understand address version" + " numbers of {1}. Perhaps upgrade" + " Bitmessage to the latest version." + ).format(toAddress, addressVersionNumber) + ) continue if streamNumber > 1 or streamNumber == 0: - QtGui.QMessageBox.about(self, _translate("MainWindow", "Stream number"), _translate( - "MainWindow", "Concerning the address %1, Bitmessage cannot handle stream numbers of %2. Perhaps upgrade Bitmessage to the latest version.").arg(toAddress).arg(str(streamNumber))) + QtWidgets.QMessageBox.about( + self, + _translate("MainWindow", "Stream number"), + _translate( + "MainWindow", + "Concerning the address {0}, Bitmessage" + " cannot handle stream numbers of {1}." + " Perhaps upgrade Bitmessage to the" + " latest version." + ).format(toAddress, streamNumber) + ) continue self.statusbar.clearMessage() if state.statusIconColor == 'red': @@ -2242,11 +2297,11 @@ class MyForm(settingsmixin.SMainWindow): )) def click_pushButtonFetchNamecoinID(self): - identities = str(self.ui.lineEditTo.text().toUtf8()).split(";") + identities = self.ui.lineEditTo.text().split(";") err, addr = self.namecoin.query(identities[-1].strip()) if err is not None: self.updateStatusBar( - _translate("MainWindow", "Error: %1").arg(err)) + _translate("MainWindow", "Error: {0}").format(err)) else: identities[-1] = addr self.ui.lineEditTo.setText("; ".join(identities)) @@ -2276,8 +2331,8 @@ class MyForm(settingsmixin.SMainWindow): self.ui.comboBoxSendFrom.addItem(avatarize(addressInKeysFile), label, addressInKeysFile) # self.ui.comboBoxSendFrom.model().sort(1, Qt.AscendingOrder) for i in range(self.ui.comboBoxSendFrom.count()): - address = str(self.ui.comboBoxSendFrom.itemData( - i, QtCore.Qt.UserRole).toString()) + address = self.ui.comboBoxSendFrom.itemData( + i, QtCore.Qt.UserRole) self.ui.comboBoxSendFrom.setItemData( i, AccountColor(address).accountColor(), QtCore.Qt.ForegroundRole) @@ -2299,13 +2354,13 @@ class MyForm(settingsmixin.SMainWindow): label = addressInKeysFile self.ui.comboBoxSendFromBroadcast.addItem(avatarize(addressInKeysFile), label, addressInKeysFile) for i in range(self.ui.comboBoxSendFromBroadcast.count()): - address = str(self.ui.comboBoxSendFromBroadcast.itemData( - i, QtCore.Qt.UserRole).toString()) + address = self.ui.comboBoxSendFromBroadcast.itemData( + i, QtCore.Qt.UserRole) self.ui.comboBoxSendFromBroadcast.setItemData( i, AccountColor(address).accountColor(), QtCore.Qt.ForegroundRole) self.ui.comboBoxSendFromBroadcast.insertItem(0, '', '') - if(self.ui.comboBoxSendFromBroadcast.count() == 2): + if self.ui.comboBoxSendFromBroadcast.count() == 2: self.ui.comboBoxSendFromBroadcast.setCurrentIndex(1) else: self.ui.comboBoxSendFromBroadcast.setCurrentIndex(0) @@ -2379,6 +2434,8 @@ class MyForm(settingsmixin.SMainWindow): tableWidget = self.widgetConvert(treeWidget) current_account = self.getCurrentAccount(treeWidget) current_folder = self.getCurrentFolder(treeWidget) + # inventoryHash surprisingly is of type unicode + # inventoryHash = inventoryHash.encode('utf-8') # pylint: disable=too-many-boolean-expressions if ((tableWidget == inbox and current_account == acct.address @@ -2399,15 +2456,14 @@ class MyForm(settingsmixin.SMainWindow): 'bitmessagesettings', 'showtraynotifications'): self.notifierShow( _translate("MainWindow", "New Message"), - _translate("MainWindow", "From %1").arg( - unicode(acct.fromLabel, 'utf-8')), + _translate("MainWindow", "From {0}").format(acct.fromLabel), sound.SOUND_UNKNOWN ) if self.getCurrentAccount() is not None and ( - (self.getCurrentFolder(treeWidget) != "inbox" - and self.getCurrentFolder(treeWidget) is not None) + (self.getCurrentFolder(treeWidget) != "inbox" + and self.getCurrentFolder(treeWidget) is not None) or self.getCurrentAccount(treeWidget) != acct.address): - # Ubuntu should notify of new message irrespective of + # Ubuntu should notify of new message irespective of # whether it's in current message list or not self.indicatorUpdate(True, to_label=acct.toLabel) @@ -2538,7 +2594,7 @@ class MyForm(settingsmixin.SMainWindow): # Only settings remain here acct.settings() for i in range(self.ui.comboBoxSendFrom.count()): - if str(self.ui.comboBoxSendFrom.itemData(i).toPyObject()) \ + if str(self.ui.comboBoxSendFrom.itemData(i)) \ == acct.fromAddress: self.ui.comboBoxSendFrom.setCurrentIndex(i) break @@ -2557,13 +2613,13 @@ class MyForm(settingsmixin.SMainWindow): self.ui.textEditMessage.setFocus() def on_action_MarkAllRead(self): - if QtGui.QMessageBox.question( + if QtWidgets.QMessageBox.question( self, "Marking all messages as read?", _translate( "MainWindow", "Are you sure you would like to mark all messages read?" - ), QtGui.QMessageBox.Yes | QtGui.QMessageBox.No - ) != QtGui.QMessageBox.Yes: + ), QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No + ) != QtWidgets.QMessageBox.Yes: return tableWidget = self.getCurrentMessagelist() @@ -2574,7 +2630,7 @@ class MyForm(settingsmixin.SMainWindow): msgids = [] for i in range(0, idCount): msgids.append(tableWidget.item(i, 3).data()) - for col in xrange(tableWidget.columnCount()): + for col in range(tableWidget.columnCount()): tableWidget.item(i, col).setUnread(False) markread = sqlExecuteChunked( @@ -2591,7 +2647,7 @@ class MyForm(settingsmixin.SMainWindow): def network_switch(self): dontconnect_option = not BMConfigParser().safeGetBoolean( 'bitmessagesettings', 'dontconnect') - reply = QtGui.QMessageBox.question( + reply = QtWidgets.QMessageBox.question( self, _translate("MainWindow", "Disconnecting") if dontconnect_option else _translate("MainWindow", "Connecting"), _translate( @@ -2600,9 +2656,9 @@ class MyForm(settingsmixin.SMainWindow): ) if dontconnect_option else _translate( "MainWindow", "Bitmessage will now start connecting to network. Are you sure?" - ), QtGui.QMessageBox.Yes | QtGui.QMessageBox.Cancel, - QtGui.QMessageBox.Cancel) - if reply != QtGui.QMessageBox.Yes: + ), QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.Cancel, + QtWidgets.QMessageBox.Cancel) + if reply != QtWidgets.QMessageBox.Yes: return BMConfigParser().set( 'bitmessagesettings', 'dontconnect', str(dontconnect_option)) @@ -2628,68 +2684,67 @@ class MyForm(settingsmixin.SMainWindow): waitForSync = False # C PoW currently doesn't support interrupting and OpenCL is untested - if getPowType() == "python" and (powQueueSize() > 0 or pendingUpload() > 0): - reply = QtGui.QMessageBox.question( + if getPowType() == "python" and ( + powQueueSize() > 0 or pendingUpload() > 0): + reply = QtWidgets.QMessageBox.question( self, _translate("MainWindow", "Proof of work pending"), _translate( "MainWindow", - "%n object(s) pending proof of work", None, - QtCore.QCoreApplication.CodecForTr, powQueueSize() - ) + ", " + - _translate( + "%n object(s) pending proof of work", None, powQueueSize() + ) + ", " + + _translate( "MainWindow", - "%n object(s) waiting to be distributed", None, - QtCore.QCoreApplication.CodecForTr, pendingUpload() - ) + "\n\n" + - _translate( - "MainWindow", "Wait until these tasks finish?"), - QtGui.QMessageBox.Yes | QtGui.QMessageBox.No - | QtGui.QMessageBox.Cancel, QtGui.QMessageBox.Cancel) - if reply == QtGui.QMessageBox.No: + "%n object(s) waiting to be distributed", + None, pendingUpload() + ) + "\n\n" + + _translate("MainWindow", "Wait until these tasks finish?"), + QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No + | QtWidgets.QMessageBox.Cancel, QtWidgets.QMessageBox.Cancel + ) + if reply == QtWidgets.QMessageBox.No: waitForPow = False - elif reply == QtGui.QMessageBox.Cancel: + elif reply == QtWidgets.QMessageBox.Cancel: return if pendingDownload() > 0: - reply = QtGui.QMessageBox.question( + reply = QtWidgets.QMessageBox.question( self, _translate("MainWindow", "Synchronisation pending"), _translate( "MainWindow", "Bitmessage hasn't synchronised with the network," " %n object(s) to be downloaded. If you quit now," " it may cause delivery delays. Wait until the" - " synchronisation finishes?", None, - QtCore.QCoreApplication.CodecForTr, pendingDownload() - ), - QtGui.QMessageBox.Yes | QtGui.QMessageBox.No - | QtGui.QMessageBox.Cancel, QtGui.QMessageBox.Cancel) - if reply == QtGui.QMessageBox.Yes: + " synchronisation finishes?", + None, pendingDownload() + ), QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No + | QtWidgets.QMessageBox.Cancel, QtWidgets.QMessageBox.Cancel) + if reply == QtWidgets.QMessageBox.Yes: self.wait = waitForSync = True - elif reply == QtGui.QMessageBox.Cancel: + elif reply == QtWidgets.QMessageBox.Cancel: return - if state.statusIconColor == 'red' and not BMConfigParser().safeGetBoolean( + if state.statusIconColor == 'red' \ + and not BMConfigParser().safeGetBoolean( 'bitmessagesettings', 'dontconnect'): - reply = QtGui.QMessageBox.question( + reply = QtWidgets.QMessageBox.question( self, _translate("MainWindow", "Not connected"), _translate( "MainWindow", - "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" " connected and the synchronisation finishes?" - ), - QtGui.QMessageBox.Yes | QtGui.QMessageBox.No - | QtGui.QMessageBox.Cancel, QtGui.QMessageBox.Cancel) - if reply == QtGui.QMessageBox.Yes: + ), QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No + | QtWidgets.QMessageBox.Cancel, QtWidgets.QMessageBox.Cancel) + if reply == QtWidgets.QMessageBox.Yes: waitForConnection = True self.wait = waitForSync = True - elif reply == QtGui.QMessageBox.Cancel: + elif reply == QtWidgets.QMessageBox.Cancel: return self.quitAccepted = True self.updateStatusBar(_translate( - "MainWindow", "Shutting down PyBitmessage... %1%").arg(0)) + "MainWindow", "Shutting down PyBitmessage... {0}%").format(0)) if waitForConnection: self.updateStatusBar(_translate( @@ -2723,16 +2778,18 @@ class MyForm(settingsmixin.SMainWindow): maxWorkerQueue = curWorkerQueue if curWorkerQueue > 0: self.updateStatusBar(_translate( - "MainWindow", "Waiting for PoW to finish... %1%" - ).arg(50 * (maxWorkerQueue - curWorkerQueue) / - maxWorkerQueue)) + "MainWindow", "Waiting for PoW to finish... {0}%" + ).format( + 50 * (maxWorkerQueue - curWorkerQueue) / maxWorkerQueue + )) time.sleep(0.5) QtCore.QCoreApplication.processEvents( QtCore.QEventLoop.AllEvents, 1000 ) self.updateStatusBar(_translate( - "MainWindow", "Shutting down Pybitmessage... %1%").arg(50)) + "MainWindow", "Shutting down Pybitmessage... {0}%" + ).format(50)) QtCore.QCoreApplication.processEvents( QtCore.QEventLoop.AllEvents, 1000 @@ -2746,29 +2803,27 @@ class MyForm(settingsmixin.SMainWindow): # check if upload (of objects created locally) pending self.updateStatusBar(_translate( - "MainWindow", "Waiting for objects to be sent... %1%").arg(50)) + "MainWindow", "Waiting for objects to be sent... {0}%" + ).format(50)) maxPendingUpload = max(1, pendingUpload()) while pendingUpload() > 1: self.updateStatusBar(_translate( "MainWindow", - "Waiting for objects to be sent... %1%" - ).arg(int(50 + 20 * (pendingUpload() / maxPendingUpload)))) + "Waiting for objects to be sent... {0}%" + ).format(int(50 + 20 * pendingUpload() / maxPendingUpload))) time.sleep(0.5) QtCore.QCoreApplication.processEvents( QtCore.QEventLoop.AllEvents, 1000 ) - QtCore.QCoreApplication.processEvents( - QtCore.QEventLoop.AllEvents, 1000 - ) QtCore.QCoreApplication.processEvents( QtCore.QEventLoop.AllEvents, 1000 ) # save state and geometry self and all widgets self.updateStatusBar(_translate( - "MainWindow", "Saving settings... %1%").arg(70)) + "MainWindow", "Saving settings... {0}%").format(70)) QtCore.QCoreApplication.processEvents( QtCore.QEventLoop.AllEvents, 1000 ) @@ -2781,18 +2836,18 @@ class MyForm(settingsmixin.SMainWindow): obj.saveSettings() self.updateStatusBar(_translate( - "MainWindow", "Shutting down core... %1%").arg(80)) + "MainWindow", "Shutting down core... {0}%").format(80)) QtCore.QCoreApplication.processEvents( QtCore.QEventLoop.AllEvents, 1000 ) shutdown.doCleanShutdown() self.updateStatusBar(_translate( - "MainWindow", "Stopping notifications... %1%").arg(90)) + "MainWindow", "Stopping notifications... {0}%").format(90)) self.tray.hide() self.updateStatusBar(_translate( - "MainWindow", "Shutdown imminent... %1%").arg(100)) + "MainWindow", "Shutdown imminent... {0}%").format(100)) logger.info("Shutdown complete") self.close() @@ -2827,17 +2882,25 @@ class MyForm(settingsmixin.SMainWindow): totalLines = len(lines) for i in xrange(totalLines): if 'Message ostensibly from ' in lines[i]: - lines[i] = '

%s

' % ( - lines[i]) - elif lines[i] == '------------------------------------------------------': + lines[i] = ( + '

%s

' % + lines[i] + ) + elif ( + lines[i] == + '------------------------------------------------------' + ): lines[i] = '
' - elif lines[i] == '' and (i+1) < totalLines and \ - lines[i+1] != '------------------------------------------------------': + elif ( + lines[i] == '' and (i + 1) < totalLines and + lines[i + 1] != + '------------------------------------------------------' + ): lines[i] = '

' - content = ' '.join(lines) # To keep the whitespace between lines + content = ' '.join(lines) # To keep the whitespace between lines content = shared.fixPotentiallyInvalidUTF8Data(content) - content = unicode(content, 'utf-8)') - textEdit.setHtml(QtCore.QString(content)) + content = unicode(content, 'utf-8') + textEdit.setHtml(content) def on_action_InboxMarkUnread(self): tableWidget = self.getCurrentMessagelist() @@ -2863,18 +2926,15 @@ class MyForm(settingsmixin.SMainWindow): ) self.propagateUnreadCount() - # tableWidget.selectRow(currentRow + 1) - # This doesn't de-select the last message if you try to mark it - # unread, but that doesn't interfere. Might not be necessary. - # We could also select upwards, but then our problem would be - # with the topmost message. - # tableWidget.clearSelection() manages to mark the message - # as read again. # Format predefined text on message reply. def quoted_text(self, message): - if not BMConfigParser().safeGetBoolean('bitmessagesettings', 'replybelow'): - return '\n\n------------------------------------------------------\n' + message + if not BMConfigParser().safeGetBoolean( + 'bitmessagesettings', 'replybelow'): + return ( + '\n\n------------------------------------------------------\n' + + message + ) quoteWrapper = textwrap.TextWrapper( replace_whitespace=False, initial_indent='> ', @@ -2904,7 +2964,7 @@ class MyForm(settingsmixin.SMainWindow): self.ui.comboBoxSendFrom, self.ui.comboBoxSendFromBroadcast ): for i in range(box.count()): - if str(box.itemData(i).toPyObject()) == address: + if str(box.itemData(i)) == address: box.setCurrentIndex(i) break else: @@ -2948,7 +3008,8 @@ class MyForm(settingsmixin.SMainWindow): acct.parseMessage( toAddressAtCurrentInboxRow, fromAddressAtCurrentInboxRow, tableWidget.item(currentInboxRow, 2).subject, - messageAtCurrentInboxRow) + messageAtCurrentInboxRow + ) widget = { 'subject': self.ui.lineEditSubject, 'from': self.ui.comboBoxSendFrom, @@ -2961,23 +3022,26 @@ class MyForm(settingsmixin.SMainWindow): ) # toAddressAtCurrentInboxRow = fromAddressAtCurrentInboxRow elif not BMConfigParser().has_section(toAddressAtCurrentInboxRow): - QtGui.QMessageBox.information( - self, _translate("MainWindow", "Address is gone"), + QtWidgets.QMessageBox.information( + self, + _translate("MainWindow", "Address is gone"), _translate( "MainWindow", - "Bitmessage cannot find your address %1. Perhaps you" + "Bitmessage cannot find your address {0}. Perhaps you" " removed it?" - ).arg(toAddressAtCurrentInboxRow), QtGui.QMessageBox.Ok) + ).format(toAddressAtCurrentInboxRow), + QtWidgets.QMessageBox.Ok) elif not BMConfigParser().getboolean( toAddressAtCurrentInboxRow, 'enabled'): - QtGui.QMessageBox.information( - self, _translate("MainWindow", "Address disabled"), + QtWidgets.QMessageBox.information( + self, + _translate("MainWindow", "Address disabled"), _translate( "MainWindow", "Error: The address from which you are trying to send" - " is disabled. You\'ll have to enable it on the" - " \'Your Identities\' tab before using it." - ), QtGui.QMessageBox.Ok) + " is disabled. You\'ll have to enable it on the \'Your" + " Identities\' tab before using it." + ), QtWidgets.QMessageBox.Ok) else: self.setBroadcastEnablementDependingOnWhetherThisIsAMailingListAddress(toAddressAtCurrentInboxRow) broadcast_tab_index = self.ui.tabWidgetSend.indexOf( @@ -3055,8 +3119,9 @@ class MyForm(settingsmixin.SMainWindow): recipientAddress = tableWidget.item( currentInboxRow, 0).data(QtCore.Qt.UserRole) # Let's make sure that it isn't already in the address book - queryreturn = sqlQuery('''select * from blacklist where address=?''', - addressAtCurrentInboxRow) + queryreturn = sqlQuery( + 'SELECT * FROM blacklist WHERE address=?', + addressAtCurrentInboxRow) if queryreturn == []: label = "\"" + tableWidget.item(currentInboxRow, 2).subject + "\" in " + BMConfigParser().get(recipientAddress, "label") sqlExecute('''INSERT INTO blacklist VALUES (?,?, ?)''', @@ -3104,8 +3169,8 @@ class MyForm(settingsmixin.SMainWindow): return currentRow = 0 folder = self.getCurrentFolder() - shifted = QtGui.QApplication.queryKeyboardModifiers() \ - & QtCore.Qt.ShiftModifier + shifted = (QtWidgets.QApplication.queryKeyboardModifiers() & + QtCore.Qt.ShiftModifier) tableWidget.setUpdatesEnabled(False) inventoryHashesToTrash = set() # ranges in reversed order @@ -3122,8 +3187,8 @@ class MyForm(settingsmixin.SMainWindow): idCount = len(inventoryHashesToTrash) sqlExecuteChunked( ("DELETE FROM inbox" if folder == "trash" or shifted else - "UPDATE inbox SET folder='trash', read=1") + - " WHERE msgid IN ({0})", idCount, *inventoryHashesToTrash) + "UPDATE inbox SET folder='trash', read=1") + + " WHERE msgid IN ({0})", idCount, *inventoryHashesToTrash) tableWidget.selectRow(0 if currentRow == 0 else currentRow - 1) tableWidget.setUpdatesEnabled(True) self.propagateUnreadCount(folder) @@ -3171,14 +3236,18 @@ class MyForm(settingsmixin.SMainWindow): # Retrieve the message data out of the SQL database msgid = tableWidget.item(currentInboxRow, 3).data() queryreturn = sqlQuery( - '''select message from inbox where msgid=?''', msgid) + 'SELECT message FROM inbox WHERE msgid=?', msgid) if queryreturn != []: for row in queryreturn: message, = row - defaultFilename = "".join(x for x in subjectAtCurrentInboxRow if x.isalnum()) + '.txt' - filename = QtGui.QFileDialog.getSaveFileName(self, _translate("MainWindow","Save As..."), defaultFilename, "Text files (*.txt);;All files (*.*)") - if filename == '': + defaultFilename = "".join( + x for x in subjectAtCurrentInboxRow if x.isalnum()) + '.txt' + filename, filetype = QtWidgets.QFileDialog.getSaveFileName( + self, _translate("MainWindow", "Save As..."), defaultFilename, + "Text files (*.txt);;All files (*.*)" + ) + if not filename: return try: f = open(filename, 'w') @@ -3190,11 +3259,13 @@ class MyForm(settingsmixin.SMainWindow): # Send item on the Sent tab to trash def on_action_SentTrash(self): + currentRow = 0 tableWidget = self.getCurrentMessagelist() if not tableWidget: return folder = self.getCurrentFolder() - shifted = QtGui.QApplication.queryKeyboardModifiers() & QtCore.Qt.ShiftModifier + shifted = (QtWidgets.QApplication.queryKeyboardModifiers() & + QtCore.Qt.ShiftModifier) while tableWidget.selectedIndexes() != []: currentRow = tableWidget.selectedIndexes()[0].row() ackdataToTrash = tableWidget.item(currentRow, 3).data() @@ -3222,15 +3293,18 @@ class MyForm(settingsmixin.SMainWindow): queryreturn = sqlQuery('''select ackdata FROM sent WHERE status='forcepow' ''') for row in queryreturn: ackdata, = row - queues.UISignalQueue.put(('updateSentItemStatusByAckdata', ( - ackdata, 'Overriding maximum-difficulty setting. Work queued.'))) + queues.UISignalQueue.put(( + 'updateSentItemStatusByAckdata', + (ackdata, 'Overriding maximum-difficulty setting.' + ' Work queued.') + )) queues.workerQueue.put(('sendmessage', '')) def on_action_SentClipboard(self): currentRow = self.ui.tableWidgetInbox.currentRow() addressAtCurrentRow = self.ui.tableWidgetInbox.item( currentRow, 0).data(QtCore.Qt.UserRole) - clipboard = QtGui.QApplication.clipboard() + clipboard = QtWidgets.QApplication.clipboard() clipboard.setText(str(addressAtCurrentRow)) # Group of functions for the Address Book dialog box @@ -3255,7 +3329,7 @@ class MyForm(settingsmixin.SMainWindow): addresses_string = item.address else: addresses_string += ', ' + item.address - clipboard = QtGui.QApplication.clipboard() + clipboard = QtWidgets.QApplication.clipboard() clipboard.setText(addresses_string) def on_action_AddressBookSend(self): @@ -3265,8 +3339,7 @@ class MyForm(settingsmixin.SMainWindow): return self.updateStatusBar(_translate( "MainWindow", "No addresses selected.")) - addresses_string = unicode( - self.ui.lineEditTo.text().toUtf8(), 'utf-8') + addresses_string = self.ui.lineEditTo.text() for item in selected_items: address_string = item.accountString() if not addresses_string: @@ -3297,7 +3370,7 @@ class MyForm(settingsmixin.SMainWindow): ) def on_context_menuAddressBook(self, point): - self.popMenuAddressBook = QtGui.QMenu(self) + self.popMenuAddressBook = QtWidgets.QMenu(self) self.popMenuAddressBook.addAction(self.actionAddressBookSend) self.popMenuAddressBook.addAction(self.actionAddressBookClipboard) self.popMenuAddressBook.addAction(self.actionAddressBookSubscribe) @@ -3327,7 +3400,7 @@ class MyForm(settingsmixin.SMainWindow): self.click_pushButtonAddSubscription() def on_action_SubscriptionsDelete(self): - if QtGui.QMessageBox.question( + if QtWidgets.QMessageBox.question( self, "Delete subscription?", _translate( "MainWindow", @@ -3338,8 +3411,8 @@ class MyForm(settingsmixin.SMainWindow): " messages, but you can still view messages you" " already received.\n\nAre you sure you want to" " delete the subscription?" - ), QtGui.QMessageBox.Yes | QtGui.QMessageBox.No - ) != QtGui.QMessageBox.Yes: + ), QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No + ) != QtWidgets.QMessageBox.Yes: return address = self.getCurrentAccount() sqlExecute('''DELETE FROM subscriptions WHERE address=?''', @@ -3351,7 +3424,7 @@ class MyForm(settingsmixin.SMainWindow): def on_action_SubscriptionsClipboard(self): address = self.getCurrentAccount() - clipboard = QtGui.QApplication.clipboard() + clipboard = QtWidgets.QApplication.clipboard() clipboard.setText(str(address)) def on_action_SubscriptionsEnable(self): @@ -3376,7 +3449,7 @@ class MyForm(settingsmixin.SMainWindow): def on_context_menuSubscriptions(self, point): currentItem = self.getCurrentItem() - self.popMenuSubscriptions = QtGui.QMenu(self) + self.popMenuSubscriptions = QtWidgets.QMenu(self) if isinstance(currentItem, Ui_AddressWidget): self.popMenuSubscriptions.addAction(self.actionsubscriptionsNew) self.popMenuSubscriptions.addAction(self.actionsubscriptionsDelete) @@ -3416,8 +3489,6 @@ class MyForm(settingsmixin.SMainWindow): return self.ui.tableWidgetInboxSubscriptions elif widget == self.ui.treeWidgetChans: return self.ui.tableWidgetInboxChans - else: - return None def getCurrentTreeWidget(self): currentIndex = self.ui.tabWidget.currentIndex() @@ -3506,7 +3577,7 @@ class MyForm(settingsmixin.SMainWindow): if currentIndex >= 0 and currentIndex < len(messagelistList): return ( messagelistList[currentIndex] if retObj - else messagelistList[currentIndex].text().toUtf8().data()) + else messagelistList[currentIndex].text()) def getCurrentSearchOption(self, currentIndex=None): if currentIndex is None: @@ -3562,7 +3633,7 @@ class MyForm(settingsmixin.SMainWindow): if account.type == AccountMixin.NORMAL: return # maybe in the future elif account.type == AccountMixin.CHAN: - if QtGui.QMessageBox.question( + if QtWidgets.QMessageBox.question( self, "Delete channel?", _translate( "MainWindow", @@ -3573,8 +3644,8 @@ class MyForm(settingsmixin.SMainWindow): " messages, but you can still view messages you" " already received.\n\nAre you sure you want to" " delete the channel?" - ), QtGui.QMessageBox.Yes | QtGui.QMessageBox.No - ) == QtGui.QMessageBox.Yes: + ), QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No + ) == QtWidgets.QMessageBox.Yes: BMConfigParser().remove_section(str(account.address)) else: return @@ -3615,7 +3686,7 @@ class MyForm(settingsmixin.SMainWindow): def on_action_Clipboard(self): address = self.getCurrentAccount() - clipboard = QtGui.QApplication.clipboard() + clipboard = QtWidgets.QApplication.clipboard() clipboard.setText(str(address)) def on_action_ClipboardMessagelist(self): @@ -3633,14 +3704,15 @@ class MyForm(settingsmixin.SMainWindow): myAddress = tableWidget.item(currentRow, 0).data(QtCore.Qt.UserRole) otherAddress = tableWidget.item(currentRow, 1).data(QtCore.Qt.UserRole) account = accountClass(myAddress) - if isinstance(account, GatewayAccount) and otherAddress == account.relayAddress and ( - (currentColumn in [0, 2] and self.getCurrentFolder() == "sent") or - (currentColumn in [1, 2] and self.getCurrentFolder() != "sent")): - text = str(tableWidget.item(currentRow, currentColumn).label) + if isinstance(account, GatewayAccount) \ + and otherAddress == account.relayAddress and ( + (currentColumn in (0, 2) and currentFolder == "sent") + or (currentColumn in (1, 2) and currentFolder != "sent")): + text = tableWidget.item(currentRow, currentColumn).label else: text = tableWidget.item(currentRow, currentColumn).data(QtCore.Qt.UserRole) - - clipboard = QtGui.QApplication.clipboard() + # text = unicode(str(text), 'utf-8', 'ignore') + clipboard = QtWidgets.QApplication.clipboard() clipboard.setText(text) # set avatar functions @@ -3665,10 +3737,7 @@ class MyForm(settingsmixin.SMainWindow): if not os.path.exists(state.appdata + 'avatars/'): os.makedirs(state.appdata + 'avatars/') hash = hashlib.md5(addBMIfNotPresent(addressAtCurrentRow)).hexdigest() - extensions = [ - 'PNG', 'GIF', 'JPG', 'JPEG', 'SVG', 'BMP', 'MNG', 'PBM', - 'PGM', 'PPM', 'TIFF', 'XBM', 'XPM', 'TGA'] - + # http://pyqt.sourceforge.net/Docs/PyQt4/qimagereader.html#supportedImageFormats names = { 'BMP': 'Windows Bitmap', 'GIF': 'Graphic Interchange Format', @@ -3683,11 +3752,12 @@ class MyForm(settingsmixin.SMainWindow): 'XBM': 'X11 Bitmap', 'XPM': 'X11 Pixmap', 'SVG': 'Scalable Vector Graphics', - 'TGA': 'Targa Image Format'} + 'TGA': 'Targa Image Format' + } filters = [] all_images_filter = [] current_files = [] - for ext in extensions: + for ext in names: filters += [names[ext] + ' (*.' + ext.lower() + ')'] all_images_filter += ['*.' + ext.lower()] upper = state.appdata + 'avatars/' + hash + '.' + ext.upper() @@ -3698,7 +3768,7 @@ class MyForm(settingsmixin.SMainWindow): current_files += [upper] filters[0:0] = ['Image files (' + ' '.join(all_images_filter) + ')'] filters[1:1] = ['All files (*.*)'] - sourcefile = QtGui.QFileDialog.getOpenFileName( + sourcefile, filetype = QtWidgets.QFileDialog.getOpenFileName( self, _translate("MainWindow", "Set avatar..."), filter=';;'.join(filters) ) @@ -3710,11 +3780,11 @@ class MyForm(settingsmixin.SMainWindow): if exists | (len(current_files) > 0): displayMsg = _translate( "MainWindow", "Do you really want to remove this avatar?") - overwrite = QtGui.QMessageBox.question( + overwrite = QtWidgets.QMessageBox.question( self, 'Message', displayMsg, - QtGui.QMessageBox.Yes, QtGui.QMessageBox.No) + QtWidgets.QMessageBox.Yes, QtWidgets.QMessageBox.No) else: - overwrite = QtGui.QMessageBox.No + overwrite = QtWidgets.QMessageBox.No else: # ask whether to overwrite old avatar if exists | (len(current_files) > 0): @@ -3722,15 +3792,15 @@ class MyForm(settingsmixin.SMainWindow): "MainWindow", "You have already set an avatar for this address." " Do you really want to overwrite it?") - overwrite = QtGui.QMessageBox.question( + overwrite = QtWidgets.QMessageBox.question( self, 'Message', displayMsg, - QtGui.QMessageBox.Yes, QtGui.QMessageBox.No) + QtWidgets.QMessageBox.Yes, QtWidgets.QMessageBox.No) else: - overwrite = QtGui.QMessageBox.No + overwrite = QtWidgets.QMessageBox.No # copy the image file to the appdata folder - if (not exists) | (overwrite == QtGui.QMessageBox.Yes): - if overwrite == QtGui.QMessageBox.Yes: + if (not exists) | (overwrite == QtWidgets.QMessageBox.Yes): + if overwrite == QtWidgets.QMessageBox.Yes: for file in current_files: QtCore.QFile.remove(file) QtCore.QFile.remove(destination) @@ -3762,10 +3832,10 @@ class MyForm(settingsmixin.SMainWindow): "MainWindow", "Sound files (%s)" % ' '.join(['*%s%s' % (os.extsep, ext) for ext in sound.extensions]) ))] - sourcefile = unicode(QtGui.QFileDialog.getOpenFileName( + sourcefile, filetype = QtWidgets.QFileDialog.getOpenFileName( self, _translate("MainWindow", "Set notification sound..."), filter=';;'.join(filters) - )) + ) if not sourcefile: return @@ -3780,15 +3850,15 @@ class MyForm(settingsmixin.SMainWindow): pattern = destfile.lower() for item in os.listdir(destdir): if item.lower() == pattern: - overwrite = QtGui.QMessageBox.question( + overwrite = QtWidgets.QMessageBox.question( self, _translate("MainWindow", "Message"), _translate( "MainWindow", "You have already set a notification sound" " for this address book entry." " Do you really want to overwrite it?"), - QtGui.QMessageBox.Yes, QtGui.QMessageBox.No - ) == QtGui.QMessageBox.Yes + QtWidgets.QMessageBox.Yes, QtWidgets.QMessageBox.No + ) == QtWidgets.QMessageBox.Yes if overwrite: QtCore.QFile.remove(os.path.join(destdir, item)) break @@ -3799,18 +3869,23 @@ class MyForm(settingsmixin.SMainWindow): def on_context_menuYourIdentities(self, point): currentItem = self.getCurrentItem() - self.popMenuYourIdentities = QtGui.QMenu(self) + self.popMenuYourIdentities = QtWidgets.QMenu(self) if isinstance(currentItem, Ui_AddressWidget): self.popMenuYourIdentities.addAction(self.actionNewYourIdentities) self.popMenuYourIdentities.addSeparator() - self.popMenuYourIdentities.addAction(self.actionClipboardYourIdentities) + self.popMenuYourIdentities.addAction( + self.actionClipboardYourIdentities) self.popMenuYourIdentities.addSeparator() if currentItem.isEnabled: - self.popMenuYourIdentities.addAction(self.actionDisableYourIdentities) + self.popMenuYourIdentities.addAction( + self.actionDisableYourIdentities) else: - self.popMenuYourIdentities.addAction(self.actionEnableYourIdentities) - self.popMenuYourIdentities.addAction(self.actionSetAvatarYourIdentities) - self.popMenuYourIdentities.addAction(self.actionSpecialAddressBehaviorYourIdentities) + self.popMenuYourIdentities.addAction( + self.actionEnableYourIdentities) + self.popMenuYourIdentities.addAction( + self.actionSetAvatarYourIdentities) + self.popMenuYourIdentities.addAction( + self.actionSpecialAddressBehaviorYourIdentities) self.popMenuYourIdentities.addAction(self.actionEmailGateway) self.popMenuYourIdentities.addSeparator() if currentItem.type != AccountMixin.ALL: @@ -3829,7 +3904,7 @@ class MyForm(settingsmixin.SMainWindow): # TODO make one popMenu def on_context_menuChan(self, point): currentItem = self.getCurrentItem() - self.popMenu = QtGui.QMenu(self) + self.popMenu = QtWidgets.QMenu(self) if isinstance(currentItem, Ui_AddressWidget): self.popMenu.addAction(self.actionNew) self.popMenu.addAction(self.actionDelete) @@ -3865,7 +3940,7 @@ class MyForm(settingsmixin.SMainWindow): self.on_context_menuSent(point) return - self.popMenuInbox = QtGui.QMenu(self) + self.popMenuInbox = QtWidgets.QMenu(self) self.popMenuInbox.addAction(self.actionForceHtml) self.popMenuInbox.addAction(self.actionMarkUnread) self.popMenuInbox.addSeparator() @@ -3900,7 +3975,7 @@ class MyForm(settingsmixin.SMainWindow): def on_context_menuSent(self, point): currentRow = self.ui.tableWidgetInbox.currentRow() - self.popMenuSent = QtGui.QMenu(self) + self.popMenuSent = QtWidgets.QMenu(self) self.popMenuSent.addAction(self.actionSentClipboard) self._contact_selected = self.ui.tableWidgetInbox.item(currentRow, 0) # preloaded gui.menu plugins with prefix 'address' @@ -3924,7 +3999,7 @@ class MyForm(settingsmixin.SMainWindow): def inboxSearchLineEditUpdated(self, text): # dynamic search for too short text is slow - text = text.toUtf8() + text = text.encode('utf-8') if 0 < len(text) < 3: return messagelist = self.getCurrentMessagelist() @@ -3937,9 +4012,9 @@ class MyForm(settingsmixin.SMainWindow): def inboxSearchLineEditReturnPressed(self): logger.debug("Search return pressed") - searchLine = self.getCurrentSearchLine() + searchLine = self.getCurrentSearchLine().encode('utf-8') messagelist = self.getCurrentMessagelist() - if messagelist and len(str(searchLine)) < 3: + if messagelist and len(searchLine) < 3: searchOption = self.getCurrentSearchOption() account = self.getCurrentAccount() folder = self.getCurrentFolder() @@ -3979,7 +4054,7 @@ class MyForm(settingsmixin.SMainWindow): if item.type == AccountMixin.ALL: return - newLabel = unicode(item.text(0), 'utf-8', 'ignore') + newLabel = item.text(0) oldLabel = item.defaultLabel() # unchanged, do not do anything either @@ -3998,7 +4073,9 @@ class MyForm(settingsmixin.SMainWindow): self.rerenderMessagelistFromLabels() if item.type != AccountMixin.SUBSCRIPTION: self.rerenderMessagelistToLabels() - if item.type in (AccountMixin.NORMAL, AccountMixin.CHAN, AccountMixin.SUBSCRIPTION): + if item.type in ( + AccountMixin.NORMAL, AccountMixin.CHAN, AccountMixin.SUBSCRIPTION + ): self.rerenderAddressBook() self.recurDepth -= 1 @@ -4018,9 +4095,9 @@ class MyForm(settingsmixin.SMainWindow): ) try: - message = queryreturn[-1][0] + message = unicode(queryreturn[-1][0], 'utf-8') except NameError: - message = "" + message = u"" except IndexError: message = _translate( "MainWindow", @@ -4116,7 +4193,7 @@ app = None myapp = None -class BitmessageQtApplication(QtGui.QApplication): +class BitmessageQtApplication(QtWidgets.QApplication): """ Listener to allow our Qt form to get focus when another instance of the application is open. @@ -4139,15 +4216,15 @@ class BitmessageQtApplication(QtGui.QApplication): self.server = None self.is_running = False - socket = QLocalSocket() + socket = QtNetwork.QLocalSocket() socket.connectToServer(id) self.is_running = socket.waitForConnected() # Cleanup past crashed servers if not self.is_running: - if socket.error() == QLocalSocket.ConnectionRefusedError: + if socket.error() == QtNetwork.QLocalSocket.ConnectionRefusedError: socket.disconnectFromServer() - QLocalServer.removeServer(id) + QtNetwork.QLocalServer.removeServer(id) socket.abort() @@ -4158,7 +4235,7 @@ class BitmessageQtApplication(QtGui.QApplication): else: # Nope, create a local server with this id and assign on_new_connection # for whenever a second instance tries to run focus the application. - self.server = QLocalServer() + self.server = QtNetwork.QLocalServer() self.server.listen(id) self.server.newConnection.connect(self.on_new_connection) @@ -4190,12 +4267,6 @@ def run(): if myapp._firstrun: myapp.showConnectDialog() # ask the user if we may connect -# try: -# if BMConfigParser().get('bitmessagesettings', 'mailchuck') < 1: -# myapp.showMigrationWizard(BMConfigParser().get('bitmessagesettings', 'mailchuck')) -# except: -# myapp.showMigrationWizard(0) - # only show after wizards and connect dialogs have completed if not BMConfigParser().getboolean('bitmessagesettings', 'startintray'): myapp.show() diff --git a/src/bitmessageqt/account.py b/src/bitmessageqt/account.py index 50ea3548..31780e20 100644 --- a/src/bitmessageqt/account.py +++ b/src/bitmessageqt/account.py @@ -1,46 +1,31 @@ -# pylint: disable=too-many-instance-attributes,attribute-defined-outside-init """ -account.py -========== - Account related functions. """ -from __future__ import absolute_import - import inspect import re import sys import time -from PyQt4 import QtGui - import queues from addresses import decodeAddress from bmconfigparser import BMConfigParser from helper_ackPayload import genAckPayload from helper_sql import sqlQuery, sqlExecute -from .foldertree import AccountMixin -from .utils import str_broadcast_subscribers +from foldertree import AccountMixin +from utils import str_broadcast_subscribers +from tr import _translate def getSortedAccounts(): - """Get a sorted list of configSections""" - + """Get a sorted list of address config sections""" configSections = BMConfigParser().addresses() configSections.sort( cmp=lambda x, y: cmp( - unicode( - BMConfigParser().get( - x, - 'label'), - 'utf-8').lower(), - unicode( - BMConfigParser().get( - y, - 'label'), - 'utf-8').lower())) + unicode(BMConfigParser().get(x, 'label'), 'utf-8').lower(), + unicode(BMConfigParser().get(y, 'label'), 'utf-8').lower()) + ) return configSections @@ -94,7 +79,8 @@ def accountClass(address): return subscription try: gateway = BMConfigParser().get(address, "gateway") - for _, cls in inspect.getmembers(sys.modules[__name__], inspect.isclass): + for _, cls in inspect.getmembers( + sys.modules[__name__], inspect.isclass): if issubclass(cls, GatewayAccount) and cls.gatewayName == gateway: return cls(address) # general gateway @@ -105,7 +91,7 @@ def accountClass(address): return BMAccount(address) -class AccountColor(AccountMixin): # pylint: disable=too-few-public-methods +class AccountColor(AccountMixin): """Set the type of account""" def __init__(self, address, address_type=None): @@ -127,12 +113,35 @@ class AccountColor(AccountMixin): # pylint: disable=too-few-public-methods self.type = address_type -class BMAccount(object): - """Encapsulate a Bitmessage account""" - +class NoAccount(object): + """Minimal account like object (All accounts)""" + # pylint: disable=too-many-instance-attributes def __init__(self, address=None): self.address = address self.type = AccountMixin.NORMAL + self.toAddress = self.fromAddress = '' + self.subject = self.message = '' + self.fromLabel = self.toLabel = '' + + def getLabel(self, address=None): + """Get a label for this bitmessage account""" + return address or self.address + + def parseMessage(self, toAddress, fromAddress, subject, message): + """Set metadata and address labels on self""" + self.toAddress = toAddress + self.fromAddress = fromAddress + self.subject = subject + self.message = message + self.fromLabel = self.getLabel(fromAddress) + self.toLabel = self.getLabel(toAddress) + + +class BMAccount(NoAccount): + """Encapsulate a Bitmessage account""" + + def __init__(self, address=None): + super(BMAccount, self).__init__(address) if BMConfigParser().has_section(address): if BMConfigParser().safeGetBoolean(self.address, 'chan'): self.type = AccountMixin.CHAN @@ -148,8 +157,7 @@ class BMAccount(object): def getLabel(self, address=None): """Get a label for this bitmessage account""" - if address is None: - address = self.address + address = super(BMAccount, self).getLabel(address) label = BMConfigParser().safeGet(address, 'label', address) queryreturn = sqlQuery( '''select label from addressbook where address=?''', address) @@ -162,33 +170,7 @@ class BMAccount(object): if queryreturn != []: for row in queryreturn: label, = row - return label - - def parseMessage(self, toAddress, fromAddress, subject, message): - """Set metadata and address labels on self""" - - self.toAddress = toAddress - self.fromAddress = fromAddress - if isinstance(subject, unicode): - self.subject = str(subject) - else: - self.subject = subject - self.message = message - self.fromLabel = self.getLabel(fromAddress) - self.toLabel = self.getLabel(toAddress) - - -class NoAccount(BMAccount): - """Override the __init__ method on a BMAccount""" - - def __init__(self, address=None): # pylint: disable=super-init-not-called - self.address = address - self.type = AccountMixin.NORMAL - - def getLabel(self, address=None): - if address is None: - address = self.address - return address + return unicode(label, 'utf-8') class SubscriptionAccount(BMAccount): @@ -208,15 +190,11 @@ class GatewayAccount(BMAccount): ALL_OK = 0 REGISTRATION_DENIED = 1 - def __init__(self, address): - super(GatewayAccount, self).__init__(address) - def send(self): - """Override the send method for gateway accounts""" - - # pylint: disable=unused-variable - status, addressVersionNumber, streamNumber, ripe = decodeAddress(self.toAddress) - stealthLevel = BMConfigParser().safeGetInt('bitmessagesettings', 'ackstealthlevel') + """The send method for gateway accounts""" + streamNumber, ripe = decodeAddress(self.toAddress)[2:] + stealthLevel = BMConfigParser().safeGetInt( + 'bitmessagesettings', 'ackstealthlevel') ackdata = genAckPayload(streamNumber, stealthLevel) sqlExecute( '''INSERT INTO sent VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)''', @@ -289,10 +267,9 @@ class MailchuckAccount(GatewayAccount): def settings(self): """settings specific to a MailchuckAccount""" - self.toAddress = self.registrationAddress self.subject = "config" - self.message = QtGui.QApplication.translate( + self.message = _translate( "Mailchuck", """# You can use this to configure your email gateway account # Uncomment the setting you want to use @@ -338,8 +315,9 @@ class MailchuckAccount(GatewayAccount): 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: matches = self.regExpIncoming.search(subject) if matches is not None: @@ -360,6 +338,7 @@ class MailchuckAccount(GatewayAccount): self.toLabel = matches.group(1) self.toAddress = matches.group(1) self.feedback = self.ALL_OK - if fromAddress == self.registrationAddress and self.subject == "Registration Request Denied": + if fromAddress == self.registrationAddress \ + and self.subject == "Registration Request Denied": self.feedback = self.REGISTRATION_DENIED return self.feedback diff --git a/src/bitmessageqt/address_dialogs.py b/src/bitmessageqt/address_dialogs.py index 56cf7cc5..6275859a 100644 --- a/src/bitmessageqt/address_dialogs.py +++ b/src/bitmessageqt/address_dialogs.py @@ -1,39 +1,39 @@ """ Dialogs that work with BM address. """ -# pylint: disable=attribute-defined-outside-init,too-few-public-methods,relative-import +# pylint: disable=too-few-public-methods +# https://github.com/PyCQA/pylint/issues/471 import hashlib -from PyQt4 import QtCore, QtGui +from PyQt5 import QtGui, QtWidgets import queues import widgets -from account import AccountMixin, GatewayAccount, MailchuckAccount, accountClass, getSortedAccounts -from addresses import addBMIfNotPresent, decodeAddress, encodeVarint +from account import ( + GatewayAccount, MailchuckAccount, AccountMixin, accountClass, + getSortedAccounts +) +from addresses import decodeAddress, encodeVarint, addBMIfNotPresent from inventory import Inventory from tr import _translate class AddressCheckMixin(object): - """Base address validation class for QT UI""" + """Base address validation class for Qt UI""" - def __init__(self): + def _setup(self): self.valid = False - QtCore.QObject.connect( # pylint: disable=no-member - self.lineEditAddress, - QtCore.SIGNAL("textChanged(QString)"), - self.addressChanged) + self.lineEditAddress.textChanged.connect(self.addressChanged) def _onSuccess(self, addressVersion, streamNumber, ripe): pass - def addressChanged(self, QString): + def addressChanged(self, address): """ Address validation callback, performs validation and gives feedback """ - status, addressVersion, streamNumber, ripe = decodeAddress( - str(QString)) + status, addressVersion, streamNumber, ripe = decodeAddress(address) self.valid = status == 'success' if self.valid: self.labelAddressCheck.setText( @@ -78,19 +78,27 @@ class AddressCheckMixin(object): )) -class AddressDataDialog(QtGui.QDialog, AddressCheckMixin): - """QDialog with Bitmessage address validation""" +class AddressDataDialog(QtWidgets.QDialog, AddressCheckMixin): + """ + Base class for a dialog getting BM-address data. + Corresponding ui-file should define two fields: + lineEditAddress - for the address + lineEditLabel - for it's label + After address validation the values of that fields are put into + the data field of the dialog. + """ def __init__(self, parent): super(AddressDataDialog, self).__init__(parent) self.parent = parent + self.data = ("", "") def accept(self): - """Callback for QDIalog accepting value""" + """Callback for QDialog accepting value""" if self.valid: self.data = ( addBMIfNotPresent(str(self.lineEditAddress.text())), - str(self.lineEditLabel.text().toUtf8()) + self.lineEditLabel.text().encode('utf-8') ) else: queues.UISignalQueue.put(('updateStatusBar', _translate( @@ -106,12 +114,12 @@ class AddAddressDialog(AddressDataDialog): def __init__(self, parent=None, address=None): super(AddAddressDialog, self).__init__(parent) widgets.load('addaddressdialog.ui', self) - AddressCheckMixin.__init__(self) + self._setup() if address: self.lineEditAddress.setText(address) -class NewAddressDialog(QtGui.QDialog): +class NewAddressDialog(QtWidgets.QDialog): """QDialog for generating a new address""" def __init__(self, parent=None): @@ -124,7 +132,7 @@ class NewAddressDialog(QtGui.QDialog): self.radioButtonExisting.click() self.comboBoxExisting.addItem(address) self.groupBoxDeterministic.setHidden(True) - QtGui.QWidget.resize(self, QtGui.QWidget.sizeHint(self)) + QtWidgets.QWidget.resize(self, QtWidgets.QWidget.sizeHint(self)) self.show() def accept(self): @@ -141,13 +149,13 @@ class NewAddressDialog(QtGui.QDialog): self.comboBoxExisting.currentText())[2] queues.addressGeneratorQueue.put(( 'createRandomAddress', 4, streamNumberForAddress, - str(self.newaddresslabel.text().toUtf8()), 1, "", + self.newaddresslabel.text().encode('utf-8'), 1, "", self.checkBoxEighteenByteRipe.isChecked() )) else: if self.lineEditPassphrase.text() != \ self.lineEditPassphraseAgain.text(): - QtGui.QMessageBox.about( + QtWidgets.QMessageBox.about( self, _translate("MainWindow", "Passphrase mismatch"), _translate( "MainWindow", @@ -155,7 +163,7 @@ class NewAddressDialog(QtGui.QDialog): " match. Try again.") ) elif self.lineEditPassphrase.text() == "": - QtGui.QMessageBox.about( + QtWidgets.QMessageBox.about( self, _translate("MainWindow", "Choose a passphrase"), _translate( "MainWindow", "You really do need a passphrase.") @@ -168,7 +176,7 @@ class NewAddressDialog(QtGui.QDialog): 'createDeterministicAddresses', 4, streamNumberForAddress, "unused deterministic address", self.spinBoxNumberOfAddressesToMake.value(), - self.lineEditPassphrase.text().toUtf8(), + self.lineEditPassphrase.text().encode('utf-8'), self.checkBoxEighteenByteRipe.isChecked() )) @@ -179,7 +187,7 @@ class NewSubscriptionDialog(AddressDataDialog): def __init__(self, parent=None): super(NewSubscriptionDialog, self).__init__(parent) widgets.load('newsubscriptiondialog.ui', self) - AddressCheckMixin.__init__(self) + self._setup() def _onSuccess(self, addressVersion, streamNumber, ripe): if addressVersion <= 3: @@ -210,22 +218,21 @@ class NewSubscriptionDialog(AddressDataDialog): _translate( "MainWindow", "Display the %n recent broadcast(s) from this address.", - None, - QtCore.QCoreApplication.CodecForTr, - count + None, count )) -class RegenerateAddressesDialog(QtGui.QDialog): +class RegenerateAddressesDialog(QtWidgets.QDialog): """QDialog for regenerating deterministic addresses""" + 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)) + QtWidgets.QWidget.resize(self, QtWidgets.QWidget.sizeHint(self)) -class SpecialAddressBehaviorDialog(QtGui.QDialog): +class SpecialAddressBehaviorDialog(QtWidgets.QDialog): """ QDialog for special address behaviour (e.g. mailing list functionality) """ @@ -256,12 +263,12 @@ class SpecialAddressBehaviorDialog(QtGui.QDialog): self.radioButtonBehaviorMailingList.click() else: self.radioButtonBehaveNormalAddress.click() - mailingListName = config.safeGet(self.address, 'mailinglistname', '') + mailingListName = config.safeGet( + self.address, 'mailinglistname', '') self.lineEditMailingListName.setText( - unicode(mailingListName, 'utf-8') - ) + mailingListName.decode('utf-8')) - QtGui.QWidget.resize(self, QtGui.QWidget.sizeHint(self)) + QtWidgets.QWidget.resize(self, QtWidgets.QWidget.sizeHint(self)) self.show() def accept(self): @@ -274,14 +281,15 @@ class SpecialAddressBehaviorDialog(QtGui.QDialog): # Set the color to either black or grey if self.config.getboolean(self.address, 'enabled'): self.parent.setCurrentItemColor( - QtGui.QApplication.palette().text().color() + QtWidgets.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.config.set( + str(self.address), 'mailinglistname', + self.lineEditMailingListName.text().encode('utf-8')) self.parent.setCurrentItemColor( QtGui.QColor(137, 4, 177)) # magenta self.parent.rerenderComboBoxSendFrom() @@ -290,8 +298,9 @@ class SpecialAddressBehaviorDialog(QtGui.QDialog): self.parent.rerenderMessagelistToLabels() -class EmailGatewayDialog(QtGui.QDialog): +class EmailGatewayDialog(QtWidgets.QDialog): """QDialog for email gateway control""" + def __init__(self, parent, config=None, account=None): super(EmailGatewayDialog, self).__init__(parent) widgets.load('emailgateway.ui', self) @@ -329,7 +338,7 @@ class EmailGatewayDialog(QtGui.QDialog): else: self.acct = MailchuckAccount(address) self.lineEditEmail.setFocus() - QtGui.QWidget.resize(self, QtGui.QWidget.sizeHint(self)) + QtWidgets.QWidget.resize(self, QtWidgets.QWidget.sizeHint(self)) def accept(self): """Accept callback""" @@ -343,7 +352,7 @@ class EmailGatewayDialog(QtGui.QDialog): if self.radioButtonRegister.isChecked() \ or self.radioButtonRegister.isHidden(): - email = str(self.lineEditEmail.text().toUtf8()) + email = self.lineEditEmail.text().encode('utf-8') self.acct.register(email) self.config.set(self.acct.fromAddress, 'label', email) self.config.set(self.acct.fromAddress, 'gateway', 'mailchuck') diff --git a/src/bitmessageqt/bitmessage_icons_rc.py b/src/bitmessageqt/bitmessage_icons_rc.py index bb0a02c0..5d792c48 100644 --- a/src/bitmessageqt/bitmessage_icons_rc.py +++ b/src/bitmessageqt/bitmessage_icons_rc.py @@ -7,7 +7,7 @@ # # WARNING! All changes made in this file will be lost! -from PyQt4 import QtCore +from PyQt5 import QtCore qt_resource_data = "\ \x00\x00\x03\x66\ @@ -1666,10 +1666,15 @@ qt_resource_struct = "\ \x00\x00\x01\xe6\x00\x00\x00\x00\x00\x01\x00\x00\x34\xdf\ " + def qInitResources(): - QtCore.qRegisterResourceData(0x01, qt_resource_struct, qt_resource_name, qt_resource_data) + QtCore.qRegisterResourceData( + 0x01, qt_resource_struct, qt_resource_name, qt_resource_data) + def qCleanupResources(): - QtCore.qUnregisterResourceData(0x01, qt_resource_struct, qt_resource_name, qt_resource_data) + QtCore.qUnregisterResourceData( + 0x01, qt_resource_struct, qt_resource_name, qt_resource_data) + qInitResources() diff --git a/src/bitmessageqt/bitmessageui.py b/src/bitmessageqt/bitmessageui.py index 7f2c8c91..3388c1cb 100644 --- a/src/bitmessageqt/bitmessageui.py +++ b/src/bitmessageqt/bitmessageui.py @@ -1,13 +1,5 @@ -# -*- coding: utf-8 -*- - -# Form implementation generated from reading ui file 'bitmessageui.ui' -# -# Created: Mon Mar 23 22:18:07 2015 -# by: PyQt4 UI code generator 4.10.4 -# -# WARNING! All changes made in this file will be lost! - -from PyQt4 import QtCore, QtGui +from PyQt5 import QtCore, QtGui, QtWidgets +from tr import _translate from bmconfigparser import BMConfigParser from foldertree import AddressBookCompleter from messageview import MessageView @@ -16,40 +8,23 @@ import settingsmixin from networkstatus import NetworkStatus from blacklist import Blacklist -try: - _fromUtf8 = QtCore.QString.fromUtf8 -except AttributeError: - def _fromUtf8(s): - return s +import bitmessage_icons_rc -try: - _encoding = QtGui.QApplication.UnicodeUTF8 - def _translate(context, text, disambig, encoding = QtCore.QCoreApplication.CodecForTr, n = None): - if n is None: - return QtGui.QApplication.translate(context, text, disambig, _encoding) - else: - return QtGui.QApplication.translate(context, text, disambig, _encoding, n) -except AttributeError: - def _translate(context, text, disambig, encoding = QtCore.QCoreApplication.CodecForTr, n = None): - if n is None: - return QtGui.QApplication.translate(context, text, disambig) - else: - return QtGui.QApplication.translate(context, text, disambig, QtCore.QCoreApplication.CodecForTr, n) class Ui_MainWindow(object): def setupUi(self, MainWindow): - MainWindow.setObjectName(_fromUtf8("MainWindow")) + MainWindow.setObjectName("MainWindow") MainWindow.resize(885, 580) icon = QtGui.QIcon() - icon.addPixmap(QtGui.QPixmap(_fromUtf8(":/newPrefix/images/can-icon-24px.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off) + icon.addPixmap(QtGui.QPixmap(":/newPrefix/images/can-icon-24px.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) MainWindow.setWindowIcon(icon) - MainWindow.setTabShape(QtGui.QTabWidget.Rounded) - self.centralwidget = QtGui.QWidget(MainWindow) - self.centralwidget.setObjectName(_fromUtf8("centralwidget")) - self.gridLayout_10 = QtGui.QGridLayout(self.centralwidget) - self.gridLayout_10.setObjectName(_fromUtf8("gridLayout_10")) - self.tabWidget = QtGui.QTabWidget(self.centralwidget) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding) + MainWindow.setTabShape(QtWidgets.QTabWidget.Rounded) + self.centralwidget = QtWidgets.QWidget(MainWindow) + self.centralwidget.setObjectName("centralwidget") + self.gridLayout_10 = QtWidgets.QGridLayout(self.centralwidget) + self.gridLayout_10.setObjectName("gridLayout_10") + self.tabWidget = QtWidgets.QTabWidget(self.centralwidget) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.tabWidget.sizePolicy().hasHeightForWidth()) @@ -59,27 +34,27 @@ class Ui_MainWindow(object): font = QtGui.QFont() font.setPointSize(9) self.tabWidget.setFont(font) - self.tabWidget.setTabPosition(QtGui.QTabWidget.North) - self.tabWidget.setTabShape(QtGui.QTabWidget.Rounded) - self.tabWidget.setObjectName(_fromUtf8("tabWidget")) - self.inbox = QtGui.QWidget() - self.inbox.setObjectName(_fromUtf8("inbox")) - self.gridLayout = QtGui.QGridLayout(self.inbox) - self.gridLayout.setObjectName(_fromUtf8("gridLayout")) + self.tabWidget.setTabPosition(QtWidgets.QTabWidget.North) + self.tabWidget.setTabShape(QtWidgets.QTabWidget.Rounded) + self.tabWidget.setObjectName("tabWidget") + self.inbox = QtWidgets.QWidget() + self.inbox.setObjectName("inbox") + self.gridLayout = QtWidgets.QGridLayout(self.inbox) + self.gridLayout.setObjectName("gridLayout") self.horizontalSplitter_3 = settingsmixin.SSplitter() - self.horizontalSplitter_3.setObjectName(_fromUtf8("horizontalSplitter_3")) + self.horizontalSplitter_3.setObjectName("horizontalSplitter_3") self.verticalSplitter_12 = settingsmixin.SSplitter() - self.verticalSplitter_12.setObjectName(_fromUtf8("verticalSplitter_12")) + self.verticalSplitter_12.setObjectName("verticalSplitter_12") self.verticalSplitter_12.setOrientation(QtCore.Qt.Vertical) self.treeWidgetYourIdentities = settingsmixin.STreeWidget(self.inbox) - self.treeWidgetYourIdentities.setObjectName(_fromUtf8("treeWidgetYourIdentities")) + self.treeWidgetYourIdentities.setObjectName("treeWidgetYourIdentities") self.treeWidgetYourIdentities.resize(200, self.treeWidgetYourIdentities.height()) icon1 = QtGui.QIcon() - icon1.addPixmap(QtGui.QPixmap(_fromUtf8(":/newPrefix/images/identities.png")), QtGui.QIcon.Selected, QtGui.QIcon.Off) + icon1.addPixmap(QtGui.QPixmap(":/newPrefix/images/identities.png"), QtGui.QIcon.Selected, QtGui.QIcon.Off) self.treeWidgetYourIdentities.headerItem().setIcon(0, icon1) self.verticalSplitter_12.addWidget(self.treeWidgetYourIdentities) - self.pushButtonNewAddress = QtGui.QPushButton(self.inbox) - self.pushButtonNewAddress.setObjectName(_fromUtf8("pushButtonNewAddress")) + self.pushButtonNewAddress = QtWidgets.QPushButton(self.inbox) + self.pushButtonNewAddress.setObjectName("pushButtonNewAddress") self.pushButtonNewAddress.resize(200, self.pushButtonNewAddress.height()) self.verticalSplitter_12.addWidget(self.pushButtonNewAddress) self.verticalSplitter_12.setStretchFactor(0, 1) @@ -89,21 +64,21 @@ class Ui_MainWindow(object): self.verticalSplitter_12.handle(1).setEnabled(False) self.horizontalSplitter_3.addWidget(self.verticalSplitter_12) self.verticalSplitter_7 = settingsmixin.SSplitter() - self.verticalSplitter_7.setObjectName(_fromUtf8("verticalSplitter_7")) + self.verticalSplitter_7.setObjectName("verticalSplitter_7") self.verticalSplitter_7.setOrientation(QtCore.Qt.Vertical) - self.horizontalSplitterSearch = QtGui.QSplitter() - self.horizontalSplitterSearch.setObjectName(_fromUtf8("horizontalSplitterSearch")) - self.inboxSearchLineEdit = QtGui.QLineEdit(self.inbox) - self.inboxSearchLineEdit.setObjectName(_fromUtf8("inboxSearchLineEdit")) + self.horizontalSplitterSearch = QtWidgets.QSplitter() + self.horizontalSplitterSearch.setObjectName("horizontalSplitterSearch") + self.inboxSearchLineEdit = QtWidgets.QLineEdit(self.inbox) + self.inboxSearchLineEdit.setObjectName("inboxSearchLineEdit") self.horizontalSplitterSearch.addWidget(self.inboxSearchLineEdit) - self.inboxSearchOption = QtGui.QComboBox(self.inbox) - self.inboxSearchOption.setObjectName(_fromUtf8("inboxSearchOption")) - self.inboxSearchOption.addItem(_fromUtf8("")) - self.inboxSearchOption.addItem(_fromUtf8("")) - self.inboxSearchOption.addItem(_fromUtf8("")) - self.inboxSearchOption.addItem(_fromUtf8("")) - self.inboxSearchOption.addItem(_fromUtf8("")) - self.inboxSearchOption.setSizeAdjustPolicy(QtGui.QComboBox.AdjustToContents) + self.inboxSearchOption = QtWidgets.QComboBox(self.inbox) + self.inboxSearchOption.setObjectName("inboxSearchOption") + self.inboxSearchOption.addItem("") + self.inboxSearchOption.addItem("") + self.inboxSearchOption.addItem("") + self.inboxSearchOption.addItem("") + self.inboxSearchOption.addItem("") + self.inboxSearchOption.setSizeAdjustPolicy(QtWidgets.QComboBox.AdjustToContents) self.inboxSearchOption.setCurrentIndex(3) self.horizontalSplitterSearch.addWidget(self.inboxSearchOption) self.horizontalSplitterSearch.handle(1).setEnabled(False) @@ -111,21 +86,21 @@ class Ui_MainWindow(object): self.horizontalSplitterSearch.setStretchFactor(1, 0) self.verticalSplitter_7.addWidget(self.horizontalSplitterSearch) self.tableWidgetInbox = settingsmixin.STableWidget(self.inbox) - self.tableWidgetInbox.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers) + self.tableWidgetInbox.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers) self.tableWidgetInbox.setAlternatingRowColors(True) - self.tableWidgetInbox.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection) - self.tableWidgetInbox.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows) + self.tableWidgetInbox.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection) + self.tableWidgetInbox.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows) self.tableWidgetInbox.setWordWrap(False) - self.tableWidgetInbox.setObjectName(_fromUtf8("tableWidgetInbox")) + self.tableWidgetInbox.setObjectName("tableWidgetInbox") self.tableWidgetInbox.setColumnCount(4) self.tableWidgetInbox.setRowCount(0) - item = QtGui.QTableWidgetItem() + item = QtWidgets.QTableWidgetItem() self.tableWidgetInbox.setHorizontalHeaderItem(0, item) - item = QtGui.QTableWidgetItem() + item = QtWidgets.QTableWidgetItem() self.tableWidgetInbox.setHorizontalHeaderItem(1, item) - item = QtGui.QTableWidgetItem() + item = QtWidgets.QTableWidgetItem() self.tableWidgetInbox.setHorizontalHeaderItem(2, item) - item = QtGui.QTableWidgetItem() + item = QtWidgets.QTableWidgetItem() self.tableWidgetInbox.setHorizontalHeaderItem(3, item) self.tableWidgetInbox.horizontalHeader().setCascadingSectionResizes(True) self.tableWidgetInbox.horizontalHeader().setDefaultSectionSize(200) @@ -139,7 +114,7 @@ class Ui_MainWindow(object): self.textEditInboxMessage = MessageView(self.inbox) self.textEditInboxMessage.setBaseSize(QtCore.QSize(0, 500)) self.textEditInboxMessage.setReadOnly(True) - self.textEditInboxMessage.setObjectName(_fromUtf8("textEditInboxMessage")) + self.textEditInboxMessage.setObjectName("textEditInboxMessage") self.verticalSplitter_7.addWidget(self.textEditInboxMessage) self.verticalSplitter_7.setStretchFactor(0, 0) self.verticalSplitter_7.setStretchFactor(1, 1) @@ -155,31 +130,31 @@ class Ui_MainWindow(object): self.horizontalSplitter_3.setCollapsible(1, False) self.gridLayout.addWidget(self.horizontalSplitter_3) icon2 = QtGui.QIcon() - icon2.addPixmap(QtGui.QPixmap(_fromUtf8(":/newPrefix/images/inbox.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.tabWidget.addTab(self.inbox, icon2, _fromUtf8("")) - self.send = QtGui.QWidget() - self.send.setObjectName(_fromUtf8("send")) - self.gridLayout_7 = QtGui.QGridLayout(self.send) - self.gridLayout_7.setObjectName(_fromUtf8("gridLayout_7")) + icon2.addPixmap(QtGui.QPixmap(":/newPrefix/images/inbox.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.tabWidget.addTab(self.inbox, icon2, "") + self.send = QtWidgets.QWidget() + self.send.setObjectName("send") + self.gridLayout_7 = QtWidgets.QGridLayout(self.send) + self.gridLayout_7.setObjectName("gridLayout_7") self.horizontalSplitter = settingsmixin.SSplitter() - self.horizontalSplitter.setObjectName(_fromUtf8("horizontalSplitter")) + self.horizontalSplitter.setObjectName("horizontalSplitter") self.verticalSplitter_2 = settingsmixin.SSplitter() - self.verticalSplitter_2.setObjectName(_fromUtf8("verticalSplitter_2")) + self.verticalSplitter_2.setObjectName("verticalSplitter_2") self.verticalSplitter_2.setOrientation(QtCore.Qt.Vertical) self.tableWidgetAddressBook = settingsmixin.STableWidget(self.send) self.tableWidgetAddressBook.setAlternatingRowColors(True) - self.tableWidgetAddressBook.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection) - self.tableWidgetAddressBook.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows) - self.tableWidgetAddressBook.setObjectName(_fromUtf8("tableWidgetAddressBook")) + self.tableWidgetAddressBook.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection) + self.tableWidgetAddressBook.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows) + self.tableWidgetAddressBook.setObjectName("tableWidgetAddressBook") self.tableWidgetAddressBook.setColumnCount(2) self.tableWidgetAddressBook.setRowCount(0) self.tableWidgetAddressBook.resize(200, self.tableWidgetAddressBook.height()) - item = QtGui.QTableWidgetItem() + item = QtWidgets.QTableWidgetItem() icon3 = QtGui.QIcon() - icon3.addPixmap(QtGui.QPixmap(_fromUtf8(":/newPrefix/images/addressbook.png")), QtGui.QIcon.Selected, QtGui.QIcon.Off) + icon3.addPixmap(QtGui.QPixmap(":/newPrefix/images/addressbook.png"), QtGui.QIcon.Selected, QtGui.QIcon.Off) item.setIcon(icon3) self.tableWidgetAddressBook.setHorizontalHeaderItem(0, item) - item = QtGui.QTableWidgetItem() + item = QtWidgets.QTableWidgetItem() self.tableWidgetAddressBook.setHorizontalHeaderItem(1, item) self.tableWidgetAddressBook.horizontalHeader().setCascadingSectionResizes(True) self.tableWidgetAddressBook.horizontalHeader().setDefaultSectionSize(200) @@ -188,17 +163,17 @@ class Ui_MainWindow(object): self.tableWidgetAddressBook.verticalHeader().setVisible(False) self.verticalSplitter_2.addWidget(self.tableWidgetAddressBook) self.addressBookCompleter = AddressBookCompleter() - self.addressBookCompleter.setCompletionMode(QtGui.QCompleter.PopupCompletion) + self.addressBookCompleter.setCompletionMode(QtWidgets.QCompleter.PopupCompletion) self.addressBookCompleter.setCaseSensitivity(QtCore.Qt.CaseInsensitive) - self.addressBookCompleterModel = QtGui.QStringListModel() + self.addressBookCompleterModel = QtCore.QStringListModel() self.addressBookCompleter.setModel(self.addressBookCompleterModel) - self.pushButtonAddAddressBook = QtGui.QPushButton(self.send) - self.pushButtonAddAddressBook.setObjectName(_fromUtf8("pushButtonAddAddressBook")) + self.pushButtonAddAddressBook = QtWidgets.QPushButton(self.send) + self.pushButtonAddAddressBook.setObjectName("pushButtonAddAddressBook") self.pushButtonAddAddressBook.resize(200, self.pushButtonAddAddressBook.height()) self.verticalSplitter_2.addWidget(self.pushButtonAddAddressBook) - self.pushButtonFetchNamecoinID = QtGui.QPushButton(self.send) + self.pushButtonFetchNamecoinID = QtWidgets.QPushButton(self.send) self.pushButtonFetchNamecoinID.resize(200, self.pushButtonFetchNamecoinID.height()) - self.pushButtonFetchNamecoinID.setObjectName(_fromUtf8("pushButtonFetchNamecoinID")) + self.pushButtonFetchNamecoinID.setObjectName("pushButtonFetchNamecoinID") self.verticalSplitter_2.addWidget(self.pushButtonFetchNamecoinID) self.verticalSplitter_2.setStretchFactor(0, 1) self.verticalSplitter_2.setStretchFactor(1, 0) @@ -210,45 +185,45 @@ class Ui_MainWindow(object): self.verticalSplitter_2.handle(2).setEnabled(False) self.horizontalSplitter.addWidget(self.verticalSplitter_2) self.verticalSplitter = settingsmixin.SSplitter() - self.verticalSplitter.setObjectName(_fromUtf8("verticalSplitter")) + self.verticalSplitter.setObjectName("verticalSplitter") self.verticalSplitter.setOrientation(QtCore.Qt.Vertical) - self.tabWidgetSend = QtGui.QTabWidget(self.send) - self.tabWidgetSend.setObjectName(_fromUtf8("tabWidgetSend")) - self.sendDirect = QtGui.QWidget() - self.sendDirect.setObjectName(_fromUtf8("sendDirect")) - self.gridLayout_8 = QtGui.QGridLayout(self.sendDirect) - self.gridLayout_8.setObjectName(_fromUtf8("gridLayout_8")) + self.tabWidgetSend = QtWidgets.QTabWidget(self.send) + self.tabWidgetSend.setObjectName("tabWidgetSend") + self.sendDirect = QtWidgets.QWidget() + self.sendDirect.setObjectName("sendDirect") + self.gridLayout_8 = QtWidgets.QGridLayout(self.sendDirect) + self.gridLayout_8.setObjectName("gridLayout_8") self.verticalSplitter_5 = settingsmixin.SSplitter() - self.verticalSplitter_5.setObjectName(_fromUtf8("verticalSplitter_5")) + self.verticalSplitter_5.setObjectName("verticalSplitter_5") self.verticalSplitter_5.setOrientation(QtCore.Qt.Vertical) - self.gridLayout_2 = QtGui.QGridLayout() - self.gridLayout_2.setObjectName(_fromUtf8("gridLayout_2")) - self.label_3 = QtGui.QLabel(self.sendDirect) - self.label_3.setObjectName(_fromUtf8("label_3")) + self.gridLayout_2 = QtWidgets.QGridLayout() + self.gridLayout_2.setObjectName("gridLayout_2") + self.label_3 = QtWidgets.QLabel(self.sendDirect) + self.label_3.setObjectName("label_3") self.gridLayout_2.addWidget(self.label_3, 2, 0, 1, 1) - self.label_2 = QtGui.QLabel(self.sendDirect) - self.label_2.setObjectName(_fromUtf8("label_2")) + self.label_2 = QtWidgets.QLabel(self.sendDirect) + self.label_2.setObjectName("label_2") self.gridLayout_2.addWidget(self.label_2, 0, 0, 1, 1) - self.lineEditSubject = QtGui.QLineEdit(self.sendDirect) - self.lineEditSubject.setText(_fromUtf8("")) - self.lineEditSubject.setObjectName(_fromUtf8("lineEditSubject")) + self.lineEditSubject = QtWidgets.QLineEdit(self.sendDirect) + self.lineEditSubject.setText("") + self.lineEditSubject.setObjectName("lineEditSubject") self.gridLayout_2.addWidget(self.lineEditSubject, 2, 1, 1, 1) - self.label = QtGui.QLabel(self.sendDirect) - self.label.setObjectName(_fromUtf8("label")) + self.label = QtWidgets.QLabel(self.sendDirect) + self.label.setObjectName("label") self.gridLayout_2.addWidget(self.label, 1, 0, 1, 1) - self.comboBoxSendFrom = QtGui.QComboBox(self.sendDirect) + self.comboBoxSendFrom = QtWidgets.QComboBox(self.sendDirect) self.comboBoxSendFrom.setMinimumSize(QtCore.QSize(300, 0)) - self.comboBoxSendFrom.setObjectName(_fromUtf8("comboBoxSendFrom")) + self.comboBoxSendFrom.setObjectName("comboBoxSendFrom") self.gridLayout_2.addWidget(self.comboBoxSendFrom, 0, 1, 1, 1) - self.lineEditTo = QtGui.QLineEdit(self.sendDirect) - self.lineEditTo.setObjectName(_fromUtf8("lineEditTo")) + self.lineEditTo = QtWidgets.QLineEdit(self.sendDirect) + self.lineEditTo.setObjectName("lineEditTo") self.gridLayout_2.addWidget(self.lineEditTo, 1, 1, 1, 1) self.lineEditTo.setCompleter(self.addressBookCompleter) - self.gridLayout_2_Widget = QtGui.QWidget() + self.gridLayout_2_Widget = QtWidgets.QWidget() self.gridLayout_2_Widget.setLayout(self.gridLayout_2) self.verticalSplitter_5.addWidget(self.gridLayout_2_Widget) self.textEditMessage = MessageCompose(self.sendDirect) - self.textEditMessage.setObjectName(_fromUtf8("textEditMessage")) + self.textEditMessage.setObjectName("textEditMessage") self.verticalSplitter_5.addWidget(self.textEditMessage) self.verticalSplitter_5.setStretchFactor(0, 0) self.verticalSplitter_5.setStretchFactor(1, 1) @@ -256,35 +231,35 @@ class Ui_MainWindow(object): self.verticalSplitter_5.setCollapsible(1, False) self.verticalSplitter_5.handle(1).setEnabled(False) self.gridLayout_8.addWidget(self.verticalSplitter_5, 0, 0, 1, 1) - self.tabWidgetSend.addTab(self.sendDirect, _fromUtf8("")) - self.sendBroadcast = QtGui.QWidget() - self.sendBroadcast.setObjectName(_fromUtf8("sendBroadcast")) - self.gridLayout_9 = QtGui.QGridLayout(self.sendBroadcast) - self.gridLayout_9.setObjectName(_fromUtf8("gridLayout_9")) + self.tabWidgetSend.addTab(self.sendDirect, "") + self.sendBroadcast = QtWidgets.QWidget() + self.sendBroadcast.setObjectName("sendBroadcast") + self.gridLayout_9 = QtWidgets.QGridLayout(self.sendBroadcast) + self.gridLayout_9.setObjectName("gridLayout_9") self.verticalSplitter_6 = settingsmixin.SSplitter() - self.verticalSplitter_6.setObjectName(_fromUtf8("verticalSplitter_6")) + self.verticalSplitter_6.setObjectName("verticalSplitter_6") self.verticalSplitter_6.setOrientation(QtCore.Qt.Vertical) - self.gridLayout_5 = QtGui.QGridLayout() - self.gridLayout_5.setObjectName(_fromUtf8("gridLayout_5")) - self.label_8 = QtGui.QLabel(self.sendBroadcast) - self.label_8.setObjectName(_fromUtf8("label_8")) + self.gridLayout_5 = QtWidgets.QGridLayout() + self.gridLayout_5.setObjectName("gridLayout_5") + self.label_8 = QtWidgets.QLabel(self.sendBroadcast) + self.label_8.setObjectName("label_8") self.gridLayout_5.addWidget(self.label_8, 0, 0, 1, 1) - self.lineEditSubjectBroadcast = QtGui.QLineEdit(self.sendBroadcast) - self.lineEditSubjectBroadcast.setText(_fromUtf8("")) - self.lineEditSubjectBroadcast.setObjectName(_fromUtf8("lineEditSubjectBroadcast")) + self.lineEditSubjectBroadcast = QtWidgets.QLineEdit(self.sendBroadcast) + self.lineEditSubjectBroadcast.setText("") + self.lineEditSubjectBroadcast.setObjectName("lineEditSubjectBroadcast") self.gridLayout_5.addWidget(self.lineEditSubjectBroadcast, 1, 1, 1, 1) - self.label_7 = QtGui.QLabel(self.sendBroadcast) - self.label_7.setObjectName(_fromUtf8("label_7")) + self.label_7 = QtWidgets.QLabel(self.sendBroadcast) + self.label_7.setObjectName("label_7") self.gridLayout_5.addWidget(self.label_7, 1, 0, 1, 1) - self.comboBoxSendFromBroadcast = QtGui.QComboBox(self.sendBroadcast) + self.comboBoxSendFromBroadcast = QtWidgets.QComboBox(self.sendBroadcast) self.comboBoxSendFromBroadcast.setMinimumSize(QtCore.QSize(300, 0)) - self.comboBoxSendFromBroadcast.setObjectName(_fromUtf8("comboBoxSendFromBroadcast")) + self.comboBoxSendFromBroadcast.setObjectName("comboBoxSendFromBroadcast") self.gridLayout_5.addWidget(self.comboBoxSendFromBroadcast, 0, 1, 1, 1) - self.gridLayout_5_Widget = QtGui.QWidget() + self.gridLayout_5_Widget = QtWidgets.QWidget() self.gridLayout_5_Widget.setLayout(self.gridLayout_5) self.verticalSplitter_6.addWidget(self.gridLayout_5_Widget) self.textEditMessageBroadcast = MessageCompose(self.sendBroadcast) - self.textEditMessageBroadcast.setObjectName(_fromUtf8("textEditMessageBroadcast")) + self.textEditMessageBroadcast.setObjectName("textEditMessageBroadcast") self.verticalSplitter_6.addWidget(self.textEditMessageBroadcast) self.verticalSplitter_6.setStretchFactor(0, 0) self.verticalSplitter_6.setStretchFactor(1, 1) @@ -292,15 +267,15 @@ class Ui_MainWindow(object): self.verticalSplitter_6.setCollapsible(1, False) self.verticalSplitter_6.handle(1).setEnabled(False) self.gridLayout_9.addWidget(self.verticalSplitter_6, 0, 0, 1, 1) - self.tabWidgetSend.addTab(self.sendBroadcast, _fromUtf8("")) + self.tabWidgetSend.addTab(self.sendBroadcast, "") self.verticalSplitter.addWidget(self.tabWidgetSend) - self.tTLContainer = QtGui.QWidget() - self.tTLContainer.setSizePolicy(QtGui.QSizePolicy.MinimumExpanding, QtGui.QSizePolicy.Fixed) - self.horizontalLayout_5 = QtGui.QHBoxLayout() + self.tTLContainer = QtWidgets.QWidget() + self.tTLContainer.setSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed) + self.horizontalLayout_5 = QtWidgets.QHBoxLayout() self.tTLContainer.setLayout(self.horizontalLayout_5) - self.horizontalLayout_5.setObjectName(_fromUtf8("horizontalLayout_5")) - self.pushButtonTTL = QtGui.QPushButton(self.send) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.MinimumExpanding, QtGui.QSizePolicy.Fixed) + self.horizontalLayout_5.setObjectName("horizontalLayout_5") + self.pushButtonTTL = QtWidgets.QPushButton(self.send) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.pushButtonTTL.sizePolicy().hasHeightForWidth()) @@ -320,29 +295,29 @@ class Ui_MainWindow(object): font.setUnderline(True) self.pushButtonTTL.setFont(font) self.pushButtonTTL.setFlat(True) - self.pushButtonTTL.setObjectName(_fromUtf8("pushButtonTTL")) + self.pushButtonTTL.setObjectName("pushButtonTTL") self.horizontalLayout_5.addWidget(self.pushButtonTTL, 0, QtCore.Qt.AlignRight) - self.horizontalSliderTTL = QtGui.QSlider(self.send) + self.horizontalSliderTTL = QtWidgets.QSlider(self.send) self.horizontalSliderTTL.setMinimumSize(QtCore.QSize(70, 0)) self.horizontalSliderTTL.setOrientation(QtCore.Qt.Horizontal) self.horizontalSliderTTL.setInvertedAppearance(False) self.horizontalSliderTTL.setInvertedControls(False) - self.horizontalSliderTTL.setObjectName(_fromUtf8("horizontalSliderTTL")) + self.horizontalSliderTTL.setObjectName("horizontalSliderTTL") self.horizontalLayout_5.addWidget(self.horizontalSliderTTL, 0, QtCore.Qt.AlignLeft) - self.labelHumanFriendlyTTLDescription = QtGui.QLabel(self.send) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.MinimumExpanding, QtGui.QSizePolicy.Fixed) + self.labelHumanFriendlyTTLDescription = QtWidgets.QLabel(self.send) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.labelHumanFriendlyTTLDescription.sizePolicy().hasHeightForWidth()) self.labelHumanFriendlyTTLDescription.setSizePolicy(sizePolicy) self.labelHumanFriendlyTTLDescription.setMinimumSize(QtCore.QSize(45, 0)) - self.labelHumanFriendlyTTLDescription.setObjectName(_fromUtf8("labelHumanFriendlyTTLDescription")) + self.labelHumanFriendlyTTLDescription.setObjectName("labelHumanFriendlyTTLDescription") self.horizontalLayout_5.addWidget(self.labelHumanFriendlyTTLDescription, 1, QtCore.Qt.AlignLeft) - self.pushButtonClear = QtGui.QPushButton(self.send) - self.pushButtonClear.setObjectName(_fromUtf8("pushButtonClear")) + self.pushButtonClear = QtWidgets.QPushButton(self.send) + self.pushButtonClear.setObjectName("pushButtonClear") self.horizontalLayout_5.addWidget(self.pushButtonClear, 0, QtCore.Qt.AlignRight) - self.pushButtonSend = QtGui.QPushButton(self.send) - self.pushButtonSend.setObjectName(_fromUtf8("pushButtonSend")) + self.pushButtonSend = QtWidgets.QPushButton(self.send) + self.pushButtonSend.setObjectName("pushButtonSend") self.horizontalLayout_5.addWidget(self.pushButtonSend, 0, QtCore.Qt.AlignRight) self.horizontalSliderTTL.setMaximumSize(QtCore.QSize(105, self.pushButtonSend.height())) self.verticalSplitter.addWidget(self.tTLContainer) @@ -359,29 +334,29 @@ class Ui_MainWindow(object): self.horizontalSplitter.setCollapsible(1, False) self.gridLayout_7.addWidget(self.horizontalSplitter, 0, 0, 1, 1) icon4 = QtGui.QIcon() - icon4.addPixmap(QtGui.QPixmap(_fromUtf8(":/newPrefix/images/send.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.tabWidget.addTab(self.send, icon4, _fromUtf8("")) - self.subscriptions = QtGui.QWidget() - self.subscriptions.setObjectName(_fromUtf8("subscriptions")) - self.gridLayout_3 = QtGui.QGridLayout(self.subscriptions) - self.gridLayout_3.setObjectName(_fromUtf8("gridLayout_3")) + icon4.addPixmap(QtGui.QPixmap(":/newPrefix/images/send.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.tabWidget.addTab(self.send, icon4, "") + self.subscriptions = QtWidgets.QWidget() + self.subscriptions.setObjectName("subscriptions") + self.gridLayout_3 = QtWidgets.QGridLayout(self.subscriptions) + self.gridLayout_3.setObjectName("gridLayout_3") self.horizontalSplitter_4 = settingsmixin.SSplitter() - self.horizontalSplitter_4.setObjectName(_fromUtf8("horizontalSplitter_4")) + self.horizontalSplitter_4.setObjectName("horizontalSplitter_4") self.verticalSplitter_3 = settingsmixin.SSplitter() - self.verticalSplitter_3.setObjectName(_fromUtf8("verticalSplitter_3")) + self.verticalSplitter_3.setObjectName("verticalSplitter_3") self.verticalSplitter_3.setOrientation(QtCore.Qt.Vertical) self.treeWidgetSubscriptions = settingsmixin.STreeWidget(self.subscriptions) self.treeWidgetSubscriptions.setAlternatingRowColors(True) - self.treeWidgetSubscriptions.setSelectionMode(QtGui.QAbstractItemView.SingleSelection) - self.treeWidgetSubscriptions.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows) - self.treeWidgetSubscriptions.setObjectName(_fromUtf8("treeWidgetSubscriptions")) + self.treeWidgetSubscriptions.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection) + self.treeWidgetSubscriptions.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows) + self.treeWidgetSubscriptions.setObjectName("treeWidgetSubscriptions") self.treeWidgetSubscriptions.resize(200, self.treeWidgetSubscriptions.height()) icon5 = QtGui.QIcon() - icon5.addPixmap(QtGui.QPixmap(_fromUtf8(":/newPrefix/images/subscriptions.png")), QtGui.QIcon.Selected, QtGui.QIcon.Off) + icon5.addPixmap(QtGui.QPixmap(":/newPrefix/images/subscriptions.png"), QtGui.QIcon.Selected, QtGui.QIcon.Off) self.treeWidgetSubscriptions.headerItem().setIcon(0, icon5) self.verticalSplitter_3.addWidget(self.treeWidgetSubscriptions) - self.pushButtonAddSubscription = QtGui.QPushButton(self.subscriptions) - self.pushButtonAddSubscription.setObjectName(_fromUtf8("pushButtonAddSubscription")) + self.pushButtonAddSubscription = QtWidgets.QPushButton(self.subscriptions) + self.pushButtonAddSubscription.setObjectName("pushButtonAddSubscription") self.pushButtonAddSubscription.resize(200, self.pushButtonAddSubscription.height()) self.verticalSplitter_3.addWidget(self.pushButtonAddSubscription) self.verticalSplitter_3.setStretchFactor(0, 1) @@ -391,20 +366,20 @@ class Ui_MainWindow(object): self.verticalSplitter_3.handle(1).setEnabled(False) self.horizontalSplitter_4.addWidget(self.verticalSplitter_3) self.verticalSplitter_4 = settingsmixin.SSplitter() - self.verticalSplitter_4.setObjectName(_fromUtf8("verticalSplitter_4")) + self.verticalSplitter_4.setObjectName("verticalSplitter_4") self.verticalSplitter_4.setOrientation(QtCore.Qt.Vertical) - self.horizontalSplitter_2 = QtGui.QSplitter() - self.horizontalSplitter_2.setObjectName(_fromUtf8("horizontalSplitter_2")) - self.inboxSearchLineEditSubscriptions = QtGui.QLineEdit(self.subscriptions) - self.inboxSearchLineEditSubscriptions.setObjectName(_fromUtf8("inboxSearchLineEditSubscriptions")) + self.horizontalSplitter_2 = QtWidgets.QSplitter() + self.horizontalSplitter_2.setObjectName("horizontalSplitter_2") + self.inboxSearchLineEditSubscriptions = QtWidgets.QLineEdit(self.subscriptions) + self.inboxSearchLineEditSubscriptions.setObjectName("inboxSearchLineEditSubscriptions") self.horizontalSplitter_2.addWidget(self.inboxSearchLineEditSubscriptions) - self.inboxSearchOptionSubscriptions = QtGui.QComboBox(self.subscriptions) - self.inboxSearchOptionSubscriptions.setObjectName(_fromUtf8("inboxSearchOptionSubscriptions")) - self.inboxSearchOptionSubscriptions.addItem(_fromUtf8("")) - self.inboxSearchOptionSubscriptions.addItem(_fromUtf8("")) - self.inboxSearchOptionSubscriptions.addItem(_fromUtf8("")) - self.inboxSearchOptionSubscriptions.addItem(_fromUtf8("")) - self.inboxSearchOptionSubscriptions.setSizeAdjustPolicy(QtGui.QComboBox.AdjustToContents) + self.inboxSearchOptionSubscriptions = QtWidgets.QComboBox(self.subscriptions) + self.inboxSearchOptionSubscriptions.setObjectName("inboxSearchOptionSubscriptions") + self.inboxSearchOptionSubscriptions.addItem("") + self.inboxSearchOptionSubscriptions.addItem("") + self.inboxSearchOptionSubscriptions.addItem("") + self.inboxSearchOptionSubscriptions.addItem("") + self.inboxSearchOptionSubscriptions.setSizeAdjustPolicy(QtWidgets.QComboBox.AdjustToContents) self.inboxSearchOptionSubscriptions.setCurrentIndex(2) self.horizontalSplitter_2.addWidget(self.inboxSearchOptionSubscriptions) self.horizontalSplitter_2.handle(1).setEnabled(False) @@ -412,21 +387,21 @@ class Ui_MainWindow(object): self.horizontalSplitter_2.setStretchFactor(1, 0) self.verticalSplitter_4.addWidget(self.horizontalSplitter_2) self.tableWidgetInboxSubscriptions = settingsmixin.STableWidget(self.subscriptions) - self.tableWidgetInboxSubscriptions.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers) + self.tableWidgetInboxSubscriptions.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers) self.tableWidgetInboxSubscriptions.setAlternatingRowColors(True) - self.tableWidgetInboxSubscriptions.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection) - self.tableWidgetInboxSubscriptions.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows) + self.tableWidgetInboxSubscriptions.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection) + self.tableWidgetInboxSubscriptions.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows) self.tableWidgetInboxSubscriptions.setWordWrap(False) - self.tableWidgetInboxSubscriptions.setObjectName(_fromUtf8("tableWidgetInboxSubscriptions")) + self.tableWidgetInboxSubscriptions.setObjectName("tableWidgetInboxSubscriptions") self.tableWidgetInboxSubscriptions.setColumnCount(4) self.tableWidgetInboxSubscriptions.setRowCount(0) - item = QtGui.QTableWidgetItem() + item = QtWidgets.QTableWidgetItem() self.tableWidgetInboxSubscriptions.setHorizontalHeaderItem(0, item) - item = QtGui.QTableWidgetItem() + item = QtWidgets.QTableWidgetItem() self.tableWidgetInboxSubscriptions.setHorizontalHeaderItem(1, item) - item = QtGui.QTableWidgetItem() + item = QtWidgets.QTableWidgetItem() self.tableWidgetInboxSubscriptions.setHorizontalHeaderItem(2, item) - item = QtGui.QTableWidgetItem() + item = QtWidgets.QTableWidgetItem() self.tableWidgetInboxSubscriptions.setHorizontalHeaderItem(3, item) self.tableWidgetInboxSubscriptions.horizontalHeader().setCascadingSectionResizes(True) self.tableWidgetInboxSubscriptions.horizontalHeader().setDefaultSectionSize(200) @@ -440,7 +415,7 @@ class Ui_MainWindow(object): self.textEditInboxMessageSubscriptions = MessageView(self.subscriptions) self.textEditInboxMessageSubscriptions.setBaseSize(QtCore.QSize(0, 500)) self.textEditInboxMessageSubscriptions.setReadOnly(True) - self.textEditInboxMessageSubscriptions.setObjectName(_fromUtf8("textEditInboxMessageSubscriptions")) + self.textEditInboxMessageSubscriptions.setObjectName("textEditInboxMessageSubscriptions") self.verticalSplitter_4.addWidget(self.textEditInboxMessageSubscriptions) self.verticalSplitter_4.setStretchFactor(0, 0) self.verticalSplitter_4.setStretchFactor(1, 1) @@ -456,31 +431,31 @@ class Ui_MainWindow(object): self.horizontalSplitter_4.setCollapsible(1, False) self.gridLayout_3.addWidget(self.horizontalSplitter_4, 0, 0, 1, 1) icon6 = QtGui.QIcon() - icon6.addPixmap(QtGui.QPixmap(_fromUtf8(":/newPrefix/images/subscriptions.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.tabWidget.addTab(self.subscriptions, icon6, _fromUtf8("")) - self.chans = QtGui.QWidget() - self.chans.setObjectName(_fromUtf8("chans")) - self.gridLayout_4 = QtGui.QGridLayout(self.chans) - self.gridLayout_4.setObjectName(_fromUtf8("gridLayout_4")) + icon6.addPixmap(QtGui.QPixmap(":/newPrefix/images/subscriptions.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.tabWidget.addTab(self.subscriptions, icon6, "") + self.chans = QtWidgets.QWidget() + self.chans.setObjectName("chans") + self.gridLayout_4 = QtWidgets.QGridLayout(self.chans) + self.gridLayout_4.setObjectName("gridLayout_4") self.horizontalSplitter_7 = settingsmixin.SSplitter() - self.horizontalSplitter_7.setObjectName(_fromUtf8("horizontalSplitter_7")) + self.horizontalSplitter_7.setObjectName("horizontalSplitter_7") self.verticalSplitter_17 = settingsmixin.SSplitter() - self.verticalSplitter_17.setObjectName(_fromUtf8("verticalSplitter_17")) + self.verticalSplitter_17.setObjectName("verticalSplitter_17") self.verticalSplitter_17.setOrientation(QtCore.Qt.Vertical) self.treeWidgetChans = settingsmixin.STreeWidget(self.chans) - self.treeWidgetChans.setFrameShadow(QtGui.QFrame.Sunken) + self.treeWidgetChans.setFrameShadow(QtWidgets.QFrame.Sunken) self.treeWidgetChans.setLineWidth(1) self.treeWidgetChans.setAlternatingRowColors(True) - self.treeWidgetChans.setSelectionMode(QtGui.QAbstractItemView.SingleSelection) - self.treeWidgetChans.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows) - self.treeWidgetChans.setObjectName(_fromUtf8("treeWidgetChans")) + self.treeWidgetChans.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection) + self.treeWidgetChans.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows) + self.treeWidgetChans.setObjectName("treeWidgetChans") self.treeWidgetChans.resize(200, self.treeWidgetChans.height()) icon7 = QtGui.QIcon() - icon7.addPixmap(QtGui.QPixmap(_fromUtf8(":/newPrefix/images/can-icon-16px.png")), QtGui.QIcon.Selected, QtGui.QIcon.Off) + icon7.addPixmap(QtGui.QPixmap(":/newPrefix/images/can-icon-16px.png"), QtGui.QIcon.Selected, QtGui.QIcon.Off) self.treeWidgetChans.headerItem().setIcon(0, icon7) self.verticalSplitter_17.addWidget(self.treeWidgetChans) - self.pushButtonAddChan = QtGui.QPushButton(self.chans) - self.pushButtonAddChan.setObjectName(_fromUtf8("pushButtonAddChan")) + self.pushButtonAddChan = QtWidgets.QPushButton(self.chans) + self.pushButtonAddChan.setObjectName("pushButtonAddChan") self.pushButtonAddChan.resize(200, self.pushButtonAddChan.height()) self.verticalSplitter_17.addWidget(self.pushButtonAddChan) self.verticalSplitter_17.setStretchFactor(0, 1) @@ -490,21 +465,21 @@ class Ui_MainWindow(object): self.verticalSplitter_17.handle(1).setEnabled(False) self.horizontalSplitter_7.addWidget(self.verticalSplitter_17) self.verticalSplitter_8 = settingsmixin.SSplitter() - self.verticalSplitter_8.setObjectName(_fromUtf8("verticalSplitter_8")) + self.verticalSplitter_8.setObjectName("verticalSplitter_8") self.verticalSplitter_8.setOrientation(QtCore.Qt.Vertical) - self.horizontalSplitter_6 = QtGui.QSplitter() - self.horizontalSplitter_6.setObjectName(_fromUtf8("horizontalSplitter_6")) - self.inboxSearchLineEditChans = QtGui.QLineEdit(self.chans) - self.inboxSearchLineEditChans.setObjectName(_fromUtf8("inboxSearchLineEditChans")) + self.horizontalSplitter_6 = QtWidgets.QSplitter() + self.horizontalSplitter_6.setObjectName("horizontalSplitter_6") + self.inboxSearchLineEditChans = QtWidgets.QLineEdit(self.chans) + self.inboxSearchLineEditChans.setObjectName("inboxSearchLineEditChans") self.horizontalSplitter_6.addWidget(self.inboxSearchLineEditChans) - self.inboxSearchOptionChans = QtGui.QComboBox(self.chans) - self.inboxSearchOptionChans.setObjectName(_fromUtf8("inboxSearchOptionChans")) - self.inboxSearchOptionChans.addItem(_fromUtf8("")) - self.inboxSearchOptionChans.addItem(_fromUtf8("")) - self.inboxSearchOptionChans.addItem(_fromUtf8("")) - self.inboxSearchOptionChans.addItem(_fromUtf8("")) - self.inboxSearchOptionChans.addItem(_fromUtf8("")) - self.inboxSearchOptionChans.setSizeAdjustPolicy(QtGui.QComboBox.AdjustToContents) + self.inboxSearchOptionChans = QtWidgets.QComboBox(self.chans) + self.inboxSearchOptionChans.setObjectName("inboxSearchOptionChans") + self.inboxSearchOptionChans.addItem("") + self.inboxSearchOptionChans.addItem("") + self.inboxSearchOptionChans.addItem("") + self.inboxSearchOptionChans.addItem("") + self.inboxSearchOptionChans.addItem("") + self.inboxSearchOptionChans.setSizeAdjustPolicy(QtWidgets.QComboBox.AdjustToContents) self.inboxSearchOptionChans.setCurrentIndex(3) self.horizontalSplitter_6.addWidget(self.inboxSearchOptionChans) self.horizontalSplitter_6.handle(1).setEnabled(False) @@ -512,21 +487,21 @@ class Ui_MainWindow(object): self.horizontalSplitter_6.setStretchFactor(1, 0) self.verticalSplitter_8.addWidget(self.horizontalSplitter_6) self.tableWidgetInboxChans = settingsmixin.STableWidget(self.chans) - self.tableWidgetInboxChans.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers) + self.tableWidgetInboxChans.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers) self.tableWidgetInboxChans.setAlternatingRowColors(True) - self.tableWidgetInboxChans.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection) - self.tableWidgetInboxChans.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows) + self.tableWidgetInboxChans.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection) + self.tableWidgetInboxChans.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows) self.tableWidgetInboxChans.setWordWrap(False) - self.tableWidgetInboxChans.setObjectName(_fromUtf8("tableWidgetInboxChans")) + self.tableWidgetInboxChans.setObjectName("tableWidgetInboxChans") self.tableWidgetInboxChans.setColumnCount(4) self.tableWidgetInboxChans.setRowCount(0) - item = QtGui.QTableWidgetItem() + item = QtWidgets.QTableWidgetItem() self.tableWidgetInboxChans.setHorizontalHeaderItem(0, item) - item = QtGui.QTableWidgetItem() + item = QtWidgets.QTableWidgetItem() self.tableWidgetInboxChans.setHorizontalHeaderItem(1, item) - item = QtGui.QTableWidgetItem() + item = QtWidgets.QTableWidgetItem() self.tableWidgetInboxChans.setHorizontalHeaderItem(2, item) - item = QtGui.QTableWidgetItem() + item = QtWidgets.QTableWidgetItem() self.tableWidgetInboxChans.setHorizontalHeaderItem(3, item) self.tableWidgetInboxChans.horizontalHeader().setCascadingSectionResizes(True) self.tableWidgetInboxChans.horizontalHeader().setDefaultSectionSize(200) @@ -540,7 +515,7 @@ class Ui_MainWindow(object): self.textEditInboxMessageChans = MessageView(self.chans) self.textEditInboxMessageChans.setBaseSize(QtCore.QSize(0, 500)) self.textEditInboxMessageChans.setReadOnly(True) - self.textEditInboxMessageChans.setObjectName(_fromUtf8("textEditInboxMessageChans")) + self.textEditInboxMessageChans.setObjectName("textEditInboxMessageChans") self.verticalSplitter_8.addWidget(self.textEditInboxMessageChans) self.verticalSplitter_8.setStretchFactor(0, 0) self.verticalSplitter_8.setStretchFactor(1, 1) @@ -556,8 +531,8 @@ class Ui_MainWindow(object): self.horizontalSplitter_7.setCollapsible(1, False) self.gridLayout_4.addWidget(self.horizontalSplitter_7, 0, 0, 1, 1) icon8 = QtGui.QIcon() - icon8.addPixmap(QtGui.QPixmap(_fromUtf8(":/newPrefix/images/can-icon-16px.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off) - self.tabWidget.addTab(self.chans, icon8, _fromUtf8("")) + icon8.addPixmap(QtGui.QPixmap(":/newPrefix/images/can-icon-16px.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.tabWidget.addTab(self.chans, icon8, "") self.blackwhitelist = Blacklist() self.tabWidget.addTab(self.blackwhitelist, QtGui.QIcon(":/newPrefix/images/blacklist.png"), "") # Initialize the Blacklist or Whitelist @@ -569,62 +544,62 @@ class Ui_MainWindow(object): self.tabWidget.addTab(self.networkstatus, QtGui.QIcon(":/newPrefix/images/networkstatus.png"), "") self.gridLayout_10.addWidget(self.tabWidget, 0, 0, 1, 1) MainWindow.setCentralWidget(self.centralwidget) - self.menubar = QtGui.QMenuBar(MainWindow) + self.menubar = QtWidgets.QMenuBar(MainWindow) self.menubar.setGeometry(QtCore.QRect(0, 0, 885, 27)) - self.menubar.setObjectName(_fromUtf8("menubar")) - self.menuFile = QtGui.QMenu(self.menubar) - self.menuFile.setObjectName(_fromUtf8("menuFile")) - self.menuSettings = QtGui.QMenu(self.menubar) - self.menuSettings.setObjectName(_fromUtf8("menuSettings")) - self.menuHelp = QtGui.QMenu(self.menubar) - self.menuHelp.setObjectName(_fromUtf8("menuHelp")) + self.menubar.setObjectName("menubar") + self.menuFile = QtWidgets.QMenu(self.menubar) + self.menuFile.setObjectName("menuFile") + self.menuSettings = QtWidgets.QMenu(self.menubar) + self.menuSettings.setObjectName("menuSettings") + self.menuHelp = QtWidgets.QMenu(self.menubar) + self.menuHelp.setObjectName("menuHelp") MainWindow.setMenuBar(self.menubar) - self.statusbar = QtGui.QStatusBar(MainWindow) + self.statusbar = QtWidgets.QStatusBar(MainWindow) self.statusbar.setMaximumSize(QtCore.QSize(16777215, 22)) - self.statusbar.setObjectName(_fromUtf8("statusbar")) + self.statusbar.setObjectName("statusbar") MainWindow.setStatusBar(self.statusbar) - self.actionImport_keys = QtGui.QAction(MainWindow) - self.actionImport_keys.setObjectName(_fromUtf8("actionImport_keys")) - self.actionManageKeys = QtGui.QAction(MainWindow) + self.actionImport_keys = QtWidgets.QAction(MainWindow) + self.actionImport_keys.setObjectName("actionImport_keys") + self.actionManageKeys = QtWidgets.QAction(MainWindow) self.actionManageKeys.setCheckable(False) self.actionManageKeys.setEnabled(True) - icon = QtGui.QIcon.fromTheme(_fromUtf8("dialog-password")) + icon = QtGui.QIcon.fromTheme("dialog-password") self.actionManageKeys.setIcon(icon) - self.actionManageKeys.setObjectName(_fromUtf8("actionManageKeys")) - self.actionNetworkSwitch = QtGui.QAction(MainWindow) - self.actionNetworkSwitch.setObjectName(_fromUtf8("actionNetworkSwitch")) - self.actionExit = QtGui.QAction(MainWindow) - icon = QtGui.QIcon.fromTheme(_fromUtf8("application-exit")) + self.actionManageKeys.setObjectName("actionManageKeys") + self.actionNetworkSwitch = QtWidgets.QAction(MainWindow) + self.actionNetworkSwitch.setObjectName("actionNetworkSwitch") + self.actionExit = QtWidgets.QAction(MainWindow) + icon = QtGui.QIcon.fromTheme("application-exit") self.actionExit.setIcon(icon) - self.actionExit.setObjectName(_fromUtf8("actionExit")) - self.actionHelp = QtGui.QAction(MainWindow) - icon = QtGui.QIcon.fromTheme(_fromUtf8("help-contents")) + self.actionExit.setObjectName("actionExit") + self.actionHelp = QtWidgets.QAction(MainWindow) + icon = QtGui.QIcon.fromTheme("help-contents") self.actionHelp.setIcon(icon) - self.actionHelp.setObjectName(_fromUtf8("actionHelp")) - self.actionSupport = QtGui.QAction(MainWindow) - icon = QtGui.QIcon.fromTheme(_fromUtf8("help-support")) + self.actionHelp.setObjectName("actionHelp") + self.actionSupport = QtWidgets.QAction(MainWindow) + icon = QtGui.QIcon.fromTheme("help-support") self.actionSupport.setIcon(icon) - self.actionSupport.setObjectName(_fromUtf8("actionSupport")) - self.actionAbout = QtGui.QAction(MainWindow) - icon = QtGui.QIcon.fromTheme(_fromUtf8("help-about")) + self.actionSupport.setObjectName("actionSupport") + self.actionAbout = QtWidgets.QAction(MainWindow) + icon = QtGui.QIcon.fromTheme("help-about") self.actionAbout.setIcon(icon) - self.actionAbout.setObjectName(_fromUtf8("actionAbout")) - self.actionSettings = QtGui.QAction(MainWindow) - icon = QtGui.QIcon.fromTheme(_fromUtf8("document-properties")) + self.actionAbout.setObjectName("actionAbout") + self.actionSettings = QtWidgets.QAction(MainWindow) + icon = QtGui.QIcon.fromTheme("document-properties") self.actionSettings.setIcon(icon) - self.actionSettings.setObjectName(_fromUtf8("actionSettings")) - self.actionRegenerateDeterministicAddresses = QtGui.QAction(MainWindow) - icon = QtGui.QIcon.fromTheme(_fromUtf8("view-refresh")) + self.actionSettings.setObjectName("actionSettings") + self.actionRegenerateDeterministicAddresses = QtWidgets.QAction(MainWindow) + icon = QtGui.QIcon.fromTheme("view-refresh") self.actionRegenerateDeterministicAddresses.setIcon(icon) - self.actionRegenerateDeterministicAddresses.setObjectName(_fromUtf8("actionRegenerateDeterministicAddresses")) - self.actionDeleteAllTrashedMessages = QtGui.QAction(MainWindow) - icon = QtGui.QIcon.fromTheme(_fromUtf8("user-trash")) + self.actionRegenerateDeterministicAddresses.setObjectName("actionRegenerateDeterministicAddresses") + self.actionDeleteAllTrashedMessages = QtWidgets.QAction(MainWindow) + icon = QtGui.QIcon.fromTheme("user-trash") self.actionDeleteAllTrashedMessages.setIcon(icon) - self.actionDeleteAllTrashedMessages.setObjectName(_fromUtf8("actionDeleteAllTrashedMessages")) - self.actionJoinChan = QtGui.QAction(MainWindow) - icon = QtGui.QIcon.fromTheme(_fromUtf8("contact-new")) + self.actionDeleteAllTrashedMessages.setObjectName("actionDeleteAllTrashedMessages") + self.actionJoinChan = QtWidgets.QAction(MainWindow) + icon = QtGui.QIcon.fromTheme("contact-new") self.actionJoinChan.setIcon(icon) - self.actionJoinChan.setObjectName(_fromUtf8("actionJoinChan")) + self.actionJoinChan.setObjectName("actionJoinChan") self.menuFile.addAction(self.actionManageKeys) self.menuFile.addAction(self.actionDeleteAllTrashedMessages) self.menuFile.addAction(self.actionRegenerateDeterministicAddresses) @@ -655,11 +630,11 @@ class Ui_MainWindow(object): # Popup menu actions container for the Sent page # pylint: disable=attribute-defined-outside-init - self.sentContextMenuToolbar = QtGui.QToolBar() + self.sentContextMenuToolbar = QtWidgets.QToolBar() # Popup menu actions container for chans tree - self.addressContextMenuToolbar = QtGui.QToolBar() + self.addressContextMenuToolbar = QtWidgets.QToolBar() # Popup menu actions container for subscriptions tree - self.subscriptionsContextMenuToolbar = QtGui.QToolBar() + self.subscriptionsContextMenuToolbar = QtWidgets.QToolBar() def updateNetworkSwitchMenuLabel(self, dontconnect=None): if dontconnect is None: @@ -713,7 +688,7 @@ class Ui_MainWindow(object): hours = int(BMConfigParser().getint('bitmessagesettings', 'ttl')/60/60) except: pass - self.labelHumanFriendlyTTLDescription.setText(_translate("MainWindow", "%n hour(s)", None, QtCore.QCoreApplication.CodecForTr, hours)) + self.labelHumanFriendlyTTLDescription.setText(_translate("MainWindow", "%n hour(s)", None, hours)) self.pushButtonClear.setText(_translate("MainWindow", "Clear", None)) self.pushButtonSend.setText(_translate("MainWindow", "Send", None)) self.tabWidget.setTabText(self.tabWidget.indexOf(self.send), _translate("MainWindow", "Send", None)) @@ -774,15 +749,12 @@ class Ui_MainWindow(object): self.updateNetworkSwitchMenuLabel() -import bitmessage_icons_rc - if __name__ == "__main__": import sys - - app = QtGui.QApplication(sys.argv) + + app = QtWidgets.QApplication(sys.argv) MainWindow = settingsmixin.SMainWindow() ui = Ui_MainWindow() ui.setupUi(MainWindow) MainWindow.show() sys.exit(app.exec_()) - diff --git a/src/bitmessageqt/blacklist.py b/src/bitmessageqt/blacklist.py index 3897bddc..1875e001 100644 --- a/src/bitmessageqt/blacklist.py +++ b/src/bitmessageqt/blacklist.py @@ -1,4 +1,4 @@ -from PyQt4 import QtCore, QtGui +from PyQt5 import QtCore, QtGui, QtWidgets import widgets from addresses import addBMIfNotPresent @@ -12,31 +12,31 @@ from uisignaler import UISignaler from utils import avatarize -class Blacklist(QtGui.QWidget, RetranslateMixin): +class Blacklist(QtWidgets.QWidget, RetranslateMixin): def __init__(self, parent=None): super(Blacklist, self).__init__(parent) widgets.load('blacklist.ui', self) - QtCore.QObject.connect(self.radioButtonBlacklist, QtCore.SIGNAL( - "clicked()"), self.click_radioButtonBlacklist) - QtCore.QObject.connect(self.radioButtonWhitelist, QtCore.SIGNAL( - "clicked()"), self.click_radioButtonWhitelist) - QtCore.QObject.connect(self.pushButtonAddBlacklist, QtCore.SIGNAL( - "clicked()"), self.click_pushButtonAddBlacklist) + self.radioButtonBlacklist.clicked.connect( + self.click_radioButtonBlacklist) + self.radioButtonWhitelist.clicked.connect( + self.click_radioButtonWhitelist) + self.pushButtonAddBlacklist.clicked.connect( + self.click_pushButtonAddBlacklist) self.init_blacklist_popup_menu() - # Initialize blacklist - QtCore.QObject.connect(self.tableWidgetBlacklist, QtCore.SIGNAL( - "itemChanged(QTableWidgetItem *)"), self.tableWidgetBlacklistItemChanged) + self.tableWidgetBlacklist.itemChanged.connect( + self.tableWidgetBlacklistItemChanged) # Set the icon sizes for the identicons - identicon_size = 3*7 - self.tableWidgetBlacklist.setIconSize(QtCore.QSize(identicon_size, identicon_size)) + identicon_size = 3 * 7 + self.tableWidgetBlacklist.setIconSize( + QtCore.QSize(identicon_size, identicon_size)) self.UISignalThread = UISignaler.get() - QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL( - "rerenderBlackWhiteList()"), self.rerenderBlackWhiteList) + self.UISignalThread.rerenderBlackWhiteList.connect( + self.rerenderBlackWhiteList) def click_radioButtonBlacklist(self): if BMConfigParser().get('bitmessagesettings', 'blackwhitelist') == 'white': @@ -69,20 +69,20 @@ class Blacklist(QtGui.QWidget, RetranslateMixin): sql = '''select * from blacklist where address=?''' else: sql = '''select * from whitelist where address=?''' - queryreturn = sqlQuery(sql,*t) + queryreturn = sqlQuery(sql, *t) if queryreturn == []: self.tableWidgetBlacklist.setSortingEnabled(False) self.tableWidgetBlacklist.insertRow(0) - newItem = QtGui.QTableWidgetItem(unicode( - self.NewBlacklistDialogInstance.lineEditLabel.text().toUtf8(), 'utf-8')) + newItem = QtGui.QTableWidgetItem( + self.NewBlacklistDialogInstance.lineEditLabel.text()) newItem.setIcon(avatarize(address)) self.tableWidgetBlacklist.setItem(0, 0, newItem) - newItem = QtGui.QTableWidgetItem(address) + newItem = QtWidgets.QTableWidgetItem(address) newItem.setFlags( QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) self.tableWidgetBlacklist.setItem(0, 1, newItem) self.tableWidgetBlacklist.setSortingEnabled(True) - t = (str(self.NewBlacklistDialogInstance.lineEditLabel.text().toUtf8()), address, True) + t = (self.NewBlacklistDialogInstance.lineEditLabel.text(), address, True) if BMConfigParser().get('bitmessagesettings', 'blackwhitelist') == 'black': sql = '''INSERT INTO blacklist VALUES (?,?,?)''' else: @@ -108,17 +108,17 @@ class Blacklist(QtGui.QWidget, RetranslateMixin): def tableWidgetBlacklistItemChanged(self, item): if item.column() == 0: addressitem = self.tableWidgetBlacklist.item(item.row(), 1) - if isinstance(addressitem, QtGui.QTableWidgetItem): + if isinstance(addressitem, QtWidgets.QTableWidgetItem): if self.radioButtonBlacklist.isChecked(): sqlExecute('''UPDATE blacklist SET label=? WHERE address=?''', - str(item.text()), str(addressitem.text())) + item.text(), str(addressitem.text())) else: sqlExecute('''UPDATE whitelist SET label=? WHERE address=?''', - str(item.text()), str(addressitem.text())) + item.text(), str(addressitem.text())) def init_blacklist_popup_menu(self, connectSignal=True): # Popup menu for the Blacklist page - self.blacklistContextMenuToolbar = QtGui.QToolBar() + self.blacklistContextMenuToolbar = QtWidgets.QToolBar() # Actions self.actionBlacklistNew = self.blacklistContextMenuToolbar.addAction( _translate( @@ -143,10 +143,9 @@ class Blacklist(QtGui.QWidget, RetranslateMixin): self.tableWidgetBlacklist.setContextMenuPolicy( QtCore.Qt.CustomContextMenu) if connectSignal: - self.connect(self.tableWidgetBlacklist, QtCore.SIGNAL( - 'customContextMenuRequested(const QPoint&)'), - self.on_context_menuBlacklist) - self.popMenuBlacklist = QtGui.QMenu(self) + self.tableWidgetBlacklist.customContextMenuRequested.connect( + self.on_context_menuBlacklist) + self.popMenuBlacklist = QtWidgets.QMenu(self) # self.popMenuBlacklist.addAction( self.actionBlacklistNew ) self.popMenuBlacklist.addAction(self.actionBlacklistDelete) self.popMenuBlacklist.addSeparator() @@ -172,16 +171,16 @@ class Blacklist(QtGui.QWidget, RetranslateMixin): for row in queryreturn: label, address, enabled = row self.tableWidgetBlacklist.insertRow(0) - newItem = QtGui.QTableWidgetItem(unicode(label, 'utf-8')) + newItem = QtWidgets.QTableWidgetItem(label) if not enabled: - newItem.setTextColor(QtGui.QColor(128, 128, 128)) + newItem.setForeground(QtGui.QColor(128, 128, 128)) newItem.setIcon(avatarize(address)) self.tableWidgetBlacklist.setItem(0, 0, newItem) - newItem = QtGui.QTableWidgetItem(address) + newItem = QtWidgets.QTableWidgetItem(address) newItem.setFlags( QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) if not enabled: - newItem.setTextColor(QtGui.QColor(128, 128, 128)) + newItem.setForeground(QtGui.QColor(128, 128, 128)) self.tableWidgetBlacklist.setItem(0, 1, newItem) self.tableWidgetBlacklist.setSortingEnabled(True) @@ -192,7 +191,7 @@ class Blacklist(QtGui.QWidget, RetranslateMixin): def on_action_BlacklistDelete(self): currentRow = self.tableWidgetBlacklist.currentRow() labelAtCurrentRow = self.tableWidgetBlacklist.item( - currentRow, 0).text().toUtf8() + currentRow, 0).text() addressAtCurrentRow = self.tableWidgetBlacklist.item( currentRow, 1).text() if BMConfigParser().get('bitmessagesettings', 'blackwhitelist') == 'black': @@ -209,7 +208,7 @@ class Blacklist(QtGui.QWidget, RetranslateMixin): currentRow = self.tableWidgetBlacklist.currentRow() addressAtCurrentRow = self.tableWidgetBlacklist.item( currentRow, 1).text() - clipboard = QtGui.QApplication.clipboard() + clipboard = QtWidgets.QApplication.clipboard() clipboard.setText(str(addressAtCurrentRow)) def on_context_menuBlacklist(self, point): @@ -220,11 +219,12 @@ class Blacklist(QtGui.QWidget, RetranslateMixin): currentRow = self.tableWidgetBlacklist.currentRow() addressAtCurrentRow = self.tableWidgetBlacklist.item( currentRow, 1).text() - self.tableWidgetBlacklist.item( - currentRow, 0).setTextColor(QtGui.QApplication.palette().text().color()) - self.tableWidgetBlacklist.item( - currentRow, 1).setTextColor(QtGui.QApplication.palette().text().color()) - if BMConfigParser().get('bitmessagesettings', 'blackwhitelist') == 'black': + self.tableWidgetBlacklist.item(currentRow, 0).setForeground( + QtWidgets.QApplication.palette().text().color()) + self.tableWidgetBlacklist.item(currentRow, 1).setForeground( + QtWidgets.QApplication.palette().text().color()) + if BMConfigParser().get( + 'bitmessagesettings', 'blackwhitelist') == 'black': sqlExecute( '''UPDATE blacklist SET enabled=1 WHERE address=?''', str(addressAtCurrentRow)) @@ -237,11 +237,12 @@ class Blacklist(QtGui.QWidget, RetranslateMixin): currentRow = self.tableWidgetBlacklist.currentRow() addressAtCurrentRow = self.tableWidgetBlacklist.item( currentRow, 1).text() - self.tableWidgetBlacklist.item( - currentRow, 0).setTextColor(QtGui.QColor(128, 128, 128)) - self.tableWidgetBlacklist.item( - currentRow, 1).setTextColor(QtGui.QColor(128, 128, 128)) - if BMConfigParser().get('bitmessagesettings', 'blackwhitelist') == 'black': + self.tableWidgetBlacklist.item(currentRow, 0).setForeground( + QtGui.QColor(128, 128, 128)) + self.tableWidgetBlacklist.item(currentRow, 1).setForeground( + QtGui.QColor(128, 128, 128)) + if BMConfigParser().get( + 'bitmessagesettings', 'blackwhitelist') == 'black': sqlExecute( '''UPDATE blacklist SET enabled=0 WHERE address=?''', str(addressAtCurrentRow)) else: diff --git a/src/bitmessageqt/dialogs.py b/src/bitmessageqt/dialogs.py index e76dd84e..bcceb86a 100644 --- a/src/bitmessageqt/dialogs.py +++ b/src/bitmessageqt/dialogs.py @@ -1,8 +1,9 @@ """ -Custom dialog classes +All dialogs are available in this module. """ # pylint: disable=too-few-public-methods -from PyQt4 import QtGui + +from PyQt5 import QtWidgets import paths import widgets @@ -16,7 +17,6 @@ from settings import SettingsDialog from tr import _translate from version import softwareVersion - __all__ = [ "NewChanDialog", "AddAddressDialog", "NewAddressDialog", "NewSubscriptionDialog", "RegenerateAddressesDialog", @@ -25,8 +25,8 @@ __all__ = [ ] -class AboutDialog(QtGui.QDialog): - """The `About` dialog""" +class AboutDialog(QtWidgets.QDialog): + """The "About" dialog""" def __init__(self, parent=None): super(AboutDialog, self).__init__(parent) widgets.load('about.ui', self) @@ -50,11 +50,11 @@ class AboutDialog(QtGui.QDialog): except AttributeError: pass - self.setFixedSize(QtGui.QWidget.sizeHint(self)) + self.setFixedSize(QtWidgets.QWidget.sizeHint(self)) -class IconGlossaryDialog(QtGui.QDialog): - """The `Icon Glossary` dialog, explaining the status icon colors""" +class IconGlossaryDialog(QtWidgets.QDialog): + """The "Icon Glossary" dialog, explaining the status icon colors""" def __init__(self, parent=None, config=None): super(IconGlossaryDialog, self).__init__(parent) widgets.load('iconglossary.ui', self) @@ -64,22 +64,23 @@ class IconGlossaryDialog(QtGui.QDialog): self.labelPortNumber.setText(_translate( "iconGlossaryDialog", - "You are using TCP port %1. (This can be changed in the settings)." - ).arg(config.getint('bitmessagesettings', 'port'))) - self.setFixedSize(QtGui.QWidget.sizeHint(self)) + "You are using TCP port {0}." + " (This can be changed in the settings)." + ).format(config.getint('bitmessagesettings', 'port'))) + self.setFixedSize(QtWidgets.QWidget.sizeHint(self)) -class HelpDialog(QtGui.QDialog): - """The `Help` dialog""" +class HelpDialog(QtWidgets.QDialog): + """The "Help" dialog""" def __init__(self, parent=None): super(HelpDialog, self).__init__(parent) widgets.load('help.ui', self) - self.setFixedSize(QtGui.QWidget.sizeHint(self)) + self.setFixedSize(QtWidgets.QWidget.sizeHint(self)) -class ConnectDialog(QtGui.QDialog): - """The `Connect` dialog""" +class ConnectDialog(QtWidgets.QDialog): + """The "Connect" dialog""" def __init__(self, parent=None): super(ConnectDialog, self).__init__(parent) widgets.load('connect.ui', self) - self.setFixedSize(QtGui.QWidget.sizeHint(self)) + self.setFixedSize(QtWidgets.QWidget.sizeHint(self)) diff --git a/src/bitmessageqt/foldertree.py b/src/bitmessageqt/foldertree.py index e6d64427..208bc2cb 100644 --- a/src/bitmessageqt/foldertree.py +++ b/src/bitmessageqt/foldertree.py @@ -1,12 +1,12 @@ """ Folder tree and messagelist widgets definitions. """ -# pylint: disable=too-many-arguments,bad-super-call +# pylint: disable=too-many-arguments # pylint: disable=attribute-defined-outside-init from cgi import escape -from PyQt4 import QtCore, QtGui +from PyQt5 import QtCore, QtGui, QtWidgets from bmconfigparser import BMConfigParser from helper_sql import sqlExecute, sqlQuery @@ -38,15 +38,16 @@ class AccountMixin(object): return QtGui.QColor(128, 128, 128) elif self.type == self.CHAN: return QtGui.QColor(216, 119, 0) - elif self.type in [self.MAILINGLIST, self.SUBSCRIPTION]: + elif self.type in (self.MAILINGLIST, self.SUBSCRIPTION): return QtGui.QColor(137, 4, 177) - return QtGui.QApplication.palette().text().color() + + return QtWidgets.QApplication.palette().text().color() def folderColor(self): """QT UI color for a folder""" if not self.parent().isEnabled: return QtGui.QColor(128, 128, 128) - return QtGui.QApplication.palette().text().color() + return QtWidgets.QApplication.palette().text().color() def accountBrush(self): """Account brush (for QT UI)""" @@ -83,7 +84,7 @@ class AccountMixin(object): except AttributeError: pass self.unreadCount = int(cnt) - if isinstance(self, QtGui.QTreeWidgetItem): + if isinstance(self, QtWidgets.QTreeWidgetItem): self.emitDataChanged() def setEnabled(self, enabled): @@ -97,7 +98,7 @@ class AccountMixin(object): for i in range(self.childCount()): if isinstance(self.child(i), Ui_FolderWidget): self.child(i).setEnabled(enabled) - if isinstance(self, QtGui.QTreeWidgetItem): + if isinstance(self, QtWidgets.QTreeWidgetItem): self.emitDataChanged() def setType(self): @@ -111,7 +112,9 @@ class AccountMixin(object): elif BMConfigParser().safeGetBoolean(self.address, 'mailinglist'): self.type = self.MAILINGLIST elif sqlQuery( - '''select label from subscriptions where address=?''', self.address): + 'SELECT label FROM subscriptions WHERE address=?', + self.address + ): self.type = AccountMixin.SUBSCRIPTION else: self.type = self.NORMAL @@ -128,27 +131,30 @@ class AccountMixin(object): BMConfigParser().get(self.address, 'label'), 'utf-8') except Exception: queryreturn = sqlQuery( - '''select label from addressbook where address=?''', self.address) + 'SELECT label FROM addressbook WHERE address=?', + self.address + ) elif self.type == AccountMixin.SUBSCRIPTION: queryreturn = sqlQuery( - '''select label from subscriptions where address=?''', self.address) + 'SELECT label FROM subscriptions WHERE address=?', + self.address + ) if queryreturn is not None: if queryreturn != []: for row in queryreturn: retval, = row retval = unicode(retval, 'utf-8') elif self.address is None or self.type == AccountMixin.ALL: - return unicode( - str(_translate("MainWindow", "All accounts")), 'utf-8') + return _translate("MainWindow", "All accounts") return retval or unicode(self.address, 'utf-8') -class BMTreeWidgetItem(QtGui.QTreeWidgetItem, AccountMixin): +class BMTreeWidgetItem(QtWidgets.QTreeWidgetItem, AccountMixin): """A common abstract class for Tree widget item""" def __init__(self, parent, pos, address, unreadCount): - super(QtGui.QTreeWidgetItem, self).__init__() + super(QtWidgets.QTreeWidgetItem, self).__init__() self.setAddress(address) self.setUnreadCount(unreadCount) self._setup(parent, pos) @@ -157,7 +163,7 @@ class BMTreeWidgetItem(QtGui.QTreeWidgetItem, AccountMixin): return " (" + str(self.unreadCount) + ")" if unreadCount else "" def data(self, column, role): - """Override internal QT method for returning object data""" + """Override internal Qt method for returning object data""" if column == 0: if role == QtCore.Qt.DisplayRole: return self._getLabel() + self._getAddressBracket( @@ -190,11 +196,11 @@ class Ui_FolderWidget(BMTreeWidgetItem): return _translate("MainWindow", self.folderName) def setFolderName(self, fname): - """Set folder name (for QT UI)""" + """Set folder name (for Qt UI)""" self.folderName = str(fname) def data(self, column, role): - """Override internal QT method for returning object data""" + """Override internal Qt method for returning object data""" if column == 0 and role == QtCore.Qt.ForegroundRole: return self.folderBrush() return super(Ui_FolderWidget, self).data(column, role) @@ -216,12 +222,14 @@ class Ui_FolderWidget(BMTreeWidgetItem): return self.folderName < other.folderName return x >= y if reverse else x < y - return super(QtGui.QTreeWidgetItem, self).__lt__(other) + return super(QtWidgets.QTreeWidgetItem, self).__lt__(other) class Ui_AddressWidget(BMTreeWidgetItem, SettingsMixin): """Item in the account/folder tree representing an account""" - def __init__(self, parent, pos=0, address=None, unreadCount=0, enabled=True): + def __init__( + self, parent, pos=0, address=None, unreadCount=0, enabled=True + ): super(Ui_AddressWidget, self).__init__( parent, pos, address, unreadCount) self.setEnabled(enabled) @@ -232,8 +240,7 @@ class Ui_AddressWidget(BMTreeWidgetItem, SettingsMixin): def _getLabel(self): if self.address is None: - return unicode(_translate( - "MainWindow", "All accounts").toUtf8(), 'utf-8', 'ignore') + return _translate("MainWindow", "All accounts") else: try: return unicode( @@ -260,15 +267,14 @@ class Ui_AddressWidget(BMTreeWidgetItem, SettingsMixin): return super(Ui_AddressWidget, self).data(column, role) def setData(self, column, role, value): - """Save account label (if you edit in the the UI, this will be triggered and will save it to keys.dat)""" + """ + Save account label (if you edit in the the UI, this will be + triggered and will save it to keys.dat) + """ if role == QtCore.Qt.EditRole \ and self.type != AccountMixin.SUBSCRIPTION: BMConfigParser().set( - str(self.address), 'label', - str(value.toString().toUtf8()) - if isinstance(value, QtCore.QVariant) - else value.encode('utf-8') - ) + str(self.address), 'label', value.encode('utf-8')) BMConfigParser().save() return super(Ui_AddressWidget, self).setData(column, role, value) @@ -295,19 +301,23 @@ class Ui_AddressWidget(BMTreeWidgetItem, SettingsMixin): if self._getSortRank() < other._getSortRank() else reverse ) - return super(QtGui.QTreeWidgetItem, self).__lt__(other) + return super(Ui_AddressWidget, self).__lt__(other) class Ui_SubscriptionWidget(Ui_AddressWidget): """Special treating of subscription addresses""" # pylint: disable=unused-argument - def __init__(self, parent, pos=0, address="", unreadCount=0, label="", enabled=True): + def __init__( + self, parent, pos=0, address="", unreadCount=0, label="", + enabled=True + ): super(Ui_SubscriptionWidget, self).__init__( parent, pos, address, unreadCount, enabled) def _getLabel(self): queryreturn = sqlQuery( - '''select label from subscriptions where address=?''', self.address) + 'SELECT label FROM subscriptions WHERE address=?', + self.address) if queryreturn != []: for row in queryreturn: retval, = row @@ -322,22 +332,17 @@ class Ui_SubscriptionWidget(Ui_AddressWidget): def setData(self, column, role, value): """Save subscription label to database""" if role == QtCore.Qt.EditRole: - if isinstance(value, QtCore.QVariant): - label = str( - value.toString().toUtf8()).decode('utf-8', 'ignore') - else: - label = unicode(value, 'utf-8', 'ignore') sqlExecute( - '''UPDATE subscriptions SET label=? WHERE address=?''', - label, self.address) + 'UPDATE subscriptions SET label=? WHERE address=?', + value, self.address) return super(Ui_SubscriptionWidget, self).setData(column, role, value) -class BMTableWidgetItem(QtGui.QTableWidgetItem, SettingsMixin): +class BMTableWidgetItem(QtWidgets.QTableWidgetItem, SettingsMixin): """A common abstract class for Table widget item""" def __init__(self, label=None, unread=False): - super(QtGui.QTableWidgetItem, self).__init__() + super(QtWidgets.QTableWidgetItem, self).__init__() self.setLabel(label) self.setUnread(unread) self._setup() @@ -412,10 +417,12 @@ class MessageList_AddressWidget(BMAddressWidget): 'utf-8', 'ignore') except: queryreturn = sqlQuery( - '''select label from addressbook where address=?''', self.address) + 'SELECT label FROM addressbook WHERE address=?', + self.address) elif self.type == AccountMixin.SUBSCRIPTION: queryreturn = sqlQuery( - '''select label from subscriptions where address=?''', self.address) + 'SELECT label FROM subscriptions WHERE address=?', + self.address) if queryreturn: for row in queryreturn: newLabel = unicode(row[0], 'utf-8', 'ignore') @@ -438,7 +445,7 @@ class MessageList_AddressWidget(BMAddressWidget): def __lt__(self, other): if isinstance(other, MessageList_AddressWidget): return self.label.lower() < other.label.lower() - return super(QtGui.QTableWidgetItem, self).__lt__(other) + return super(MessageList_AddressWidget, self).__lt__(other) class MessageList_SubjectWidget(BMTableWidgetItem): @@ -456,14 +463,14 @@ class MessageList_SubjectWidget(BMTableWidgetItem): if role == QtCore.Qt.UserRole: return self.subject if role == QtCore.Qt.ToolTipRole: - return escape(unicode(self.subject, 'utf-8')) + return escape(self.subject) return super(MessageList_SubjectWidget, self).data(role) # label (or address) alphabetically, disabled at the end def __lt__(self, other): if isinstance(other, MessageList_SubjectWidget): return self.label.lower() < other.label.lower() - return super(QtGui.QTableWidgetItem, self).__lt__(other) + return super(MessageList_SubjectWidget, self).__lt__(other) # In order for the time columns on the Inbox and Sent tabs to be sorted @@ -491,15 +498,14 @@ class MessageList_TimeWidget(BMTableWidgetItem): """ data = super(MessageList_TimeWidget, self).data(role) if role == TimestampRole: - return int(data.toPyObject()) + return int(data) if role == QtCore.Qt.UserRole: - return str(data.toPyObject()) + return str(data) return data class Ui_AddressBookWidgetItem(BMAddressWidget): """Addressbook item""" - # pylint: disable=unused-argument def __init__(self, label=None, acc_type=AccountMixin.NORMAL): self.type = acc_type super(Ui_AddressBookWidgetItem, self).__init__(label=label) @@ -513,10 +519,7 @@ class Ui_AddressBookWidgetItem(BMAddressWidget): def setData(self, role, value): """Set data""" if role == QtCore.Qt.EditRole: - self.label = str( - value.toString().toUtf8() - if isinstance(value, QtCore.QVariant) else value - ) + self.label = value.encode('utf-8') if self.type in ( AccountMixin.NORMAL, AccountMixin.MAILINGLIST, AccountMixin.CHAN): @@ -525,22 +528,29 @@ class Ui_AddressBookWidgetItem(BMAddressWidget): BMConfigParser().set(self.address, 'label', self.label) BMConfigParser().save() except: - sqlExecute('''UPDATE addressbook set label=? WHERE address=?''', self.label, self.address) + sqlExecute( + 'UPDATE addressbook SET label=? WHERE address=?', + self.label, self.address + ) elif self.type == AccountMixin.SUBSCRIPTION: - sqlExecute('''UPDATE subscriptions set label=? WHERE address=?''', self.label, self.address) + sqlExecute( + 'UPDATE subscriptions SET label=? WHERE address=?', + self.label, self.address) else: pass return super(Ui_AddressBookWidgetItem, self).setData(role, value) def __lt__(self, other): - if isinstance(other, Ui_AddressBookWidgetItem): - reverse = QtCore.Qt.DescendingOrder == \ - self.tableWidget().horizontalHeader().sortIndicatorOrder() + if not isinstance(other, Ui_AddressBookWidgetItem): + return super(Ui_AddressBookWidgetItem, self).__lt__(other) - if self.type == other.type: - return self.label.lower() < other.label.lower() - return not reverse if self.type < other.type else reverse - return super(QtGui.QTableWidgetItem, self).__lt__(other) + reverse = QtCore.Qt.DescendingOrder == \ + self.tableWidget().horizontalHeader().sortIndicatorOrder() + + if self.type == other.type: + return self.label.lower() < other.label.lower() + + return not reverse if self.type < other.type else reverse class Ui_AddressBookWidgetItemLabel(Ui_AddressBookWidgetItem): @@ -570,28 +580,26 @@ class Ui_AddressBookWidgetItemAddress(Ui_AddressBookWidgetItem): return super(Ui_AddressBookWidgetItemAddress, self).data(role) -class AddressBookCompleter(QtGui.QCompleter): +class AddressBookCompleter(QtWidgets.QCompleter): """Addressbook completer""" - def __init__(self): super(AddressBookCompleter, self).__init__() self.cursorPos = -1 - def onCursorPositionChanged(self, oldPos, newPos): # pylint: disable=unused-argument + def onCursorPositionChanged(self, oldPos, newPos): """Callback for cursor position change""" + # pylint: disable=unused-argument if oldPos != self.cursorPos: self.cursorPos = -1 def splitPath(self, path): """Split on semicolon""" - text = unicode(path.toUtf8(), 'utf-8') - return [text[:self.widget().cursorPosition()].split(';')[-1].strip()] + return [path[:self.widget().cursorPosition()].split(';')[-1].strip()] def pathFromIndex(self, index): """Perform autocompletion (reimplemented QCompleter method)""" - autoString = unicode( - index.data(QtCore.Qt.EditRole).toString().toUtf8(), 'utf-8') - text = unicode(self.widget().text().toUtf8(), 'utf-8') + autoString = index.data(QtCore.Qt.EditRole).toString() + text = self.widget().text() # If cursor position was saved, restore it, else save it if self.cursorPos != -1: @@ -620,7 +628,6 @@ class AddressBookCompleter(QtGui.QCompleter): # Get string value from before auto finished string is selected # pre = text[prevDelimiterIndex + 1:curIndex - 1] - # Get part of string that occurs AFTER cursor part2 = text[nextDelimiterIndex:] diff --git a/src/bitmessageqt/languagebox.py b/src/bitmessageqt/languagebox.py index 9ff78990..d6b6fa4a 100644 --- a/src/bitmessageqt/languagebox.py +++ b/src/bitmessageqt/languagebox.py @@ -1,48 +1,56 @@ -"""Language Box Module for Locale Settings""" -# pylint: disable=too-few-public-methods,bad-continuation +"""LanguageBox widget is for selecting UI language""" + import glob import os -from PyQt4 import QtCore, QtGui +from PyQt5 import QtCore, QtWidgets import paths from bmconfigparser import BMConfigParser +from tr import _translate -class LanguageBox(QtGui.QComboBox): - """LanguageBox class for Qt UI""" +# pylint: disable=too-few-public-methods +class LanguageBox(QtWidgets.QComboBox): + """A subclass of `QtWidgets.QComboBox` for selecting language""" languageName = { - "system": "System Settings", "eo": "Esperanto", + "system": "System Settings", + "eo": "Esperanto", "en_pirate": "Pirate English" } def __init__(self, parent=None): - super(QtGui.QComboBox, self).__init__(parent) + super(LanguageBox, self).__init__(parent) self.populate() def populate(self): """Populates drop down list with all available languages.""" self.clear() localesPath = os.path.join(paths.codePath(), 'translations') - self.addItem(QtGui.QApplication.translate( - "settingsDialog", "System Settings", "system"), "system") + self.addItem( + _translate("settingsDialog", "System Settings", "system"), + "system" + ) self.setCurrentIndex(0) - self.setInsertPolicy(QtGui.QComboBox.InsertAlphabetically) + self.setInsertPolicy(QtWidgets.QComboBox.InsertAlphabetically) for translationFile in sorted( glob.glob(os.path.join(localesPath, "bitmessage_*.qm")) ): localeShort = \ os.path.split(translationFile)[1].split("_", 1)[1][:-3] + locale = QtCore.QLocale(localeShort) if localeShort in LanguageBox.languageName: self.addItem( LanguageBox.languageName[localeShort], localeShort) + elif locale.nativeLanguageName() == "": + self.addItem(localeShort, localeShort) else: locale = QtCore.QLocale(localeShort) self.addItem( locale.nativeLanguageName() or localeShort, localeShort) configuredLocale = BMConfigParser().safeGet( - 'bitmessagesettings', 'userlocale', "system") + 'bitmessagesettings', 'userlocale', 'system') for i in range(self.count()): if self.itemData(i) == configuredLocale: self.setCurrentIndex(i) diff --git a/src/bitmessageqt/messagecompose.py b/src/bitmessageqt/messagecompose.py index c51282f8..0114400d 100644 --- a/src/bitmessageqt/messagecompose.py +++ b/src/bitmessageqt/messagecompose.py @@ -1,33 +1,34 @@ -""" -Message editor with a wheel zoom functionality -""" -# pylint: disable=bad-continuation +"""The MessageCompose class definition""" -from PyQt4 import QtCore, QtGui +from PyQt5 import QtCore, QtWidgets +from tr import _translate -class MessageCompose(QtGui.QTextEdit): +class MessageCompose(QtWidgets.QTextEdit): """Editor class with wheel zoom functionality""" - def __init__(self, parent=0): + def __init__(self, parent=None): super(MessageCompose, self).__init__(parent) + # we'll deal with this later when we have a new message format self.setAcceptRichText(False) self.defaultFontPointSize = self.currentFont().pointSize() def wheelEvent(self, event): """Mouse wheel scroll event handler""" if ( - QtGui.QApplication.queryKeyboardModifiers() & QtCore.Qt.ControlModifier - ) == QtCore.Qt.ControlModifier and event.orientation() == QtCore.Qt.Vertical: + (QtWidgets.QApplication.queryKeyboardModifiers() + & QtCore.Qt.ControlModifier) == QtCore.Qt.ControlModifier + and event.orientation() == QtCore.Qt.Vertical + ): if event.delta() > 0: self.zoomIn(1) else: self.zoomOut(1) - zoom = self.currentFont().pointSize() * 100 / self.defaultFontPointSize - QtGui.QApplication.activeWindow().statusBar().showMessage( - QtGui.QApplication.translate("MainWindow", "Zoom level %1%").arg( - str(zoom) - ) - ) + QtWidgets.QApplication.activeWindow().statusbar.showMessage( + _translate("MainWindow", "Zoom level {0}%").format( + # zoom percentage + self.currentFont().pointSize() * 100 + / self.defaultFontPointSize + )) else: # in QTextEdit, super does not zoom, only scroll super(MessageCompose, self).wheelEvent(event) diff --git a/src/bitmessageqt/messageview.py b/src/bitmessageqt/messageview.py index 13ea16f9..abd15785 100644 --- a/src/bitmessageqt/messageview.py +++ b/src/bitmessageqt/messageview.py @@ -1,22 +1,21 @@ """ Custom message viewer with support for switching between HTML and plain text rendering, HTML sanitization, lazy rendering (as you scroll down), -zoom and URL click warning popup - +zoom and URL click warning popup. """ -from PyQt4 import QtCore, QtGui +from PyQt5 import QtCore, QtGui, QtWidgets from safehtmlparser import SafeHTMLParser from tr import _translate -class MessageView(QtGui.QTextBrowser): +class MessageView(QtWidgets.QTextBrowser): """Message content viewer class, can switch between plaintext and HTML""" MODE_PLAIN = 0 MODE_HTML = 1 - def __init__(self, parent=0): + def __init__(self, parent=None): super(MessageView, self).__init__(parent) self.mode = MessageView.MODE_PLAIN self.html = None @@ -38,8 +37,11 @@ class MessageView(QtGui.QTextBrowser): def mousePressEvent(self, event): """Mouse press button event handler""" - if event.button() == QtCore.Qt.LeftButton and self.html and self.html.has_html and self.cursorForPosition( - event.pos()).block().blockNumber() == 0: + if ( + event.button() == QtCore.Qt.LeftButton + and self.html and self.html.has_html + and self.cursorForPosition(event.pos()).block().blockNumber() == 0 + ): if self.mode == MessageView.MODE_PLAIN: self.showHTML() else: @@ -52,23 +54,23 @@ class MessageView(QtGui.QTextBrowser): # super will actually automatically take care of zooming super(MessageView, self).wheelEvent(event) if ( - QtGui.QApplication.queryKeyboardModifiers() & QtCore.Qt.ControlModifier - ) == QtCore.Qt.ControlModifier and event.orientation() == QtCore.Qt.Vertical: + (QtWidgets.QApplication.queryKeyboardModifiers() + & QtCore.Qt.ControlModifier) == QtCore.Qt.ControlModifier + and event.orientation() == QtCore.Qt.Vertical + ): zoom = self.currentFont().pointSize() * 100 / self.defaultFontPointSize - QtGui.QApplication.activeWindow().statusBar().showMessage(_translate( - "MainWindow", "Zoom level %1%").arg(str(zoom))) + QtWidgets.QApplication.activeWindow().statusbar.showMessage( + _translate("MainWindow", "Zoom level {0}%").format(zoom)) def setWrappingWidth(self, width=None): """Set word-wrapping width""" - self.setLineWrapMode(QtGui.QTextEdit.FixedPixelWidth) - if width is None: - width = self.width() - self.setLineWrapColumnOrWidth(width) + self.setLineWrapMode(QtWidgets.QTextEdit.FixedPixelWidth) + self.setLineWrapColumnOrWidth(width or self.width()) def confirmURL(self, link): """Show a dialog requesting URL opening confirmation""" if link.scheme() == "mailto": - window = QtGui.QApplication.activeWindow() + window = QtWidgets.QApplication.activeWindow() window.ui.lineEditTo.setText(link.path()) if link.hasQueryItem("subject"): window.ui.lineEditSubject.setText( @@ -83,39 +85,40 @@ class MessageView(QtGui.QTextBrowser): ) window.ui.textEditMessage.setFocus() return - reply = QtGui.QMessageBox.warning( - self, - QtGui.QApplication.translate( + reply = QtWidgets.QMessageBox.warning( + self, _translate("MessageView", "Follow external link"), + _translate( "MessageView", - "Follow external link"), - QtGui.QApplication.translate( - "MessageView", - "The link \"%1\" will open in a browser. It may be a security risk, it could de-anonymise you" - " or download malicious data. Are you sure?").arg(unicode(link.toString())), - QtGui.QMessageBox.Yes, - QtGui.QMessageBox.No) - if reply == QtGui.QMessageBox.Yes: + "The link \"{0}\" will open in a browser. It may be" + " a security risk, it could de-anonymise you or download" + " malicious data. Are you sure?" + ).format(link.toString()), + QtWidgets.QMessageBox.Yes, QtWidgets.QMessageBox.No) + if reply == QtWidgets.QMessageBox.Yes: QtGui.QDesktopServices.openUrl(link) def loadResource(self, restype, name): """ - Callback for loading referenced objects, such as an image. For security reasons at the moment doesn't do - anything) + Callback for loading referenced objects, such as an image. + For security reasons at the moment doesn't do anything """ pass def lazyRender(self): """ - Partially render a message. This is to avoid UI freezing when loading huge messages. It continues loading as - you scroll down. + Partially render a message. This is to avoid UI freezing when + loading huge messages. It continues loading as you scroll down. """ if self.rendering: return self.rendering = True position = self.verticalScrollBar().value() cursor = QtGui.QTextCursor(self.document()) - while self.outpos < len(self.out) and self.verticalScrollBar().value( - ) >= self.document().size().height() - 2 * self.size().height(): + while ( + self.outpos < len(self.out) + and self.verticalScrollBar().value() + >= self.document().size().height() - 2 * self.size().height() + ): startpos = self.outpos self.outpos += 10240 # find next end of tag @@ -123,8 +126,9 @@ class MessageView(QtGui.QTextBrowser): pos = self.out.find(">", self.outpos) if pos > self.outpos: self.outpos = pos + 1 - cursor.movePosition(QtGui.QTextCursor.End, QtGui.QTextCursor.MoveAnchor) - cursor.insertHtml(QtCore.QString(self.out[startpos:self.outpos])) + cursor.movePosition( + QtGui.QTextCursor.End, QtGui.QTextCursor.MoveAnchor) + cursor.insertHtml(self.out[startpos:self.outpos]) self.verticalScrollBar().setValue(position) self.rendering = False @@ -133,9 +137,11 @@ class MessageView(QtGui.QTextBrowser): self.mode = MessageView.MODE_PLAIN out = self.html.raw if self.html.has_html: - out = "
" + unicode( - QtGui.QApplication.translate( - "MessageView", "HTML detected, click here to display")) + "

" + out + out = ( + '
' + + _translate( + "MessageView", "HTML detected, click here to display" + ) + '

' + out) self.out = out self.outpos = 0 self.setHtml("") @@ -144,10 +150,10 @@ class MessageView(QtGui.QTextBrowser): def showHTML(self): """Render message as HTML""" self.mode = MessageView.MODE_HTML - out = self.html.sanitised - out = "
" + unicode( - QtGui.QApplication.translate("MessageView", "Click here to disable HTML")) + "

" + out - self.out = out + self.out = ( + '
' + + _translate("MessageView", "Click here to disable HTML") + + '

' + self.html.sanitised) self.outpos = 0 self.setHtml("") self.lazyRender() @@ -155,8 +161,6 @@ class MessageView(QtGui.QTextBrowser): def setContent(self, data): """Set message content from argument""" self.html = SafeHTMLParser() - self.html.reset() - self.html.reset_safe() self.html.allow_picture = True self.html.feed(data) self.html.close() diff --git a/src/bitmessageqt/networkstatus.py b/src/bitmessageqt/networkstatus.py index e7fd9e94..b1f3d4de 100644 --- a/src/bitmessageqt/networkstatus.py +++ b/src/bitmessageqt/networkstatus.py @@ -4,7 +4,7 @@ Network status tab widget definition. import time -from PyQt4 import QtCore, QtGui +from PyQt5 import QtCore, QtGui, QtWidgets import l10n import network.stats @@ -17,14 +17,17 @@ from tr import _translate from uisignaler import UISignaler -class NetworkStatus(QtGui.QWidget, RetranslateMixin): +class NetworkStatus(QtWidgets.QWidget, RetranslateMixin): """Network status tab""" def __init__(self, parent=None): super(NetworkStatus, self).__init__(parent) widgets.load('networkstatus.ui', self) header = self.tableWidgetConnectionCount.horizontalHeader() - header.setResizeMode(QtGui.QHeaderView.ResizeToContents) + # header.setSectionResizeMode(0, QtWidgets.QHeaderView.Stretch) + for column in range(0, 4): + header.setSectionResizeMode( + column, QtWidgets.QHeaderView.ResizeToContents) # Somehow this value was 5 when I tested if header.sortIndicatorSection() > 4: @@ -33,20 +36,17 @@ class NetworkStatus(QtGui.QWidget, RetranslateMixin): self.startup = time.localtime() self.UISignalThread = UISignaler.get() - # pylint: disable=no-member - QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL( - "updateNumberOfMessagesProcessed()"), self.updateNumberOfMessagesProcessed) - QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL( - "updateNumberOfPubkeysProcessed()"), self.updateNumberOfPubkeysProcessed) - QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL( - "updateNumberOfBroadcastsProcessed()"), self.updateNumberOfBroadcastsProcessed) - QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL( - "updateNetworkStatusTab(PyQt_PyObject,PyQt_PyObject,PyQt_PyObject)"), self.updateNetworkStatusTab) + self.UISignalThread.updateNumberOfMessagesProcessed.connect( + self.updateNumberOfMessagesProcessed) + self.UISignalThread.updateNumberOfPubkeysProcessed.connect( + self.updateNumberOfPubkeysProcessed) + self.UISignalThread.updateNumberOfBroadcastsProcessed.connect( + self.updateNumberOfBroadcastsProcessed) + self.UISignalThread.updateNetworkStatusTab.connect( + self.updateNetworkStatusTab) self.timer = QtCore.QTimer() - - QtCore.QObject.connect(self.timer, QtCore.SIGNAL("timeout()"), self.runEveryTwoSeconds) - # pylint: enable=no-member + self.timer.timeout.connect(self.runEveryTwoSeconds) def startUpdate(self): """Start a timer to update counters every 2 seconds""" @@ -58,91 +58,66 @@ class NetworkStatus(QtGui.QWidget, RetranslateMixin): """Stop counter update timer""" self.timer.stop() - def formatBytes(self, num): + @staticmethod + def formatBytes(num): """Format bytes nicely (SI prefixes)""" - # pylint: disable=no-self-use - for x in [ - _translate( - "networkstatus", - "byte(s)", - None, - QtCore.QCoreApplication.CodecForTr, - num), - "kB", - "MB", - "GB", - ]: + for x in ( + _translate("networkstatus", "byte(s)", None, num), + "kB", "MB", "GB" + ): if num < 1000.0: return "%3.0f %s" % (num, x) num /= 1000.0 - return "%3.0f %s" % (num, 'TB') + return "%3.0f %s" % (num, "TB") - def formatByteRate(self, num): + @staticmethod + def formatByteRate(num): """Format transfer speed in kB/s""" - # pylint: disable=no-self-use num /= 1000 return "%4.0f kB" % num def updateNumberOfObjectsToBeSynced(self): """Update the counter for number of objects to be synced""" - self.labelSyncStatus.setText( - _translate( - "networkstatus", - "Object(s) to be synced: %n", - None, - QtCore.QCoreApplication.CodecForTr, - network.stats.pendingDownload() - + network.stats.pendingUpload())) + self.labelSyncStatus.setText(_translate( + "networkstatus", "Object(s) to be synced: %n", None, + network.stats.pendingDownload() + network.stats.pendingUpload())) def updateNumberOfMessagesProcessed(self): """Update the counter for number of processed messages""" self.updateNumberOfObjectsToBeSynced() - self.labelMessageCount.setText( - _translate( - "networkstatus", - "Processed %n person-to-person message(s).", - None, - QtCore.QCoreApplication.CodecForTr, - state.numberOfMessagesProcessed)) + self.labelMessageCount.setText(_translate( + "networkstatus", "Processed %n person-to-person message(s).", + None, state.numberOfMessagesProcessed)) def updateNumberOfBroadcastsProcessed(self): """Update the counter for the number of processed broadcasts""" self.updateNumberOfObjectsToBeSynced() - self.labelBroadcastCount.setText( - _translate( - "networkstatus", - "Processed %n broadcast message(s).", - None, - QtCore.QCoreApplication.CodecForTr, - state.numberOfBroadcastsProcessed)) + self.labelBroadcastCount.setText(_translate( + "networkstatus", "Processed %n broadcast message(s).", None, + state.numberOfBroadcastsProcessed)) def updateNumberOfPubkeysProcessed(self): """Update the counter for the number of processed pubkeys""" self.updateNumberOfObjectsToBeSynced() - self.labelPubkeyCount.setText( - _translate( - "networkstatus", - "Processed %n public key(s).", - None, - QtCore.QCoreApplication.CodecForTr, - state.numberOfPubkeysProcessed)) + self.labelPubkeyCount.setText(_translate( + "networkstatus", "Processed %n public key(s).", None, + state.numberOfPubkeysProcessed)) def updateNumberOfBytes(self): """ - This function is run every two seconds, so we divide the rate of bytes - sent and received by 2. + This function is run every two seconds, so we divide the rate + of bytes sent and received by 2. """ - self.labelBytesRecvCount.setText( - _translate( - "networkstatus", - "Down: %1/s Total: %2").arg( - self.formatByteRate(network.stats.downloadSpeed()), - self.formatBytes(network.stats.receivedBytes()))) - self.labelBytesSentCount.setText( - _translate( - "networkstatus", "Up: %1/s Total: %2").arg( - self.formatByteRate(network.stats.uploadSpeed()), - self.formatBytes(network.stats.sentBytes()))) + self.labelBytesRecvCount.setText(_translate( + "networkstatus", "Down: {0}/s Total: {1}").format( + self.formatByteRate(network.stats.downloadSpeed()), + self.formatBytes(network.stats.receivedBytes()) + )) + self.labelBytesSentCount.setText(_translate( + "networkstatus", "Up: {0}/s Total: {1}").format( + self.formatByteRate(network.stats.uploadSpeed()), + self.formatBytes(network.stats.sentBytes()) + )) def updateNetworkStatusTab(self, outbound, add, destination): """Add or remove an entry to the list of connected peers""" @@ -169,67 +144,67 @@ class NetworkStatus(QtGui.QWidget, RetranslateMixin): if add: self.tableWidgetConnectionCount.insertRow(0) self.tableWidgetConnectionCount.setItem( - 0, 0, - QtGui.QTableWidgetItem("%s:%i" % (destination.host, destination.port)) - ) + 0, 0, QtWidgets.QTableWidgetItem( + "%s:%i" % (destination.host, destination.port))) self.tableWidgetConnectionCount.setItem( - 0, 2, - QtGui.QTableWidgetItem("%s" % (c.userAgent)) - ) + 0, 2, QtWidgets.QTableWidgetItem("%s" % (c.userAgent))) self.tableWidgetConnectionCount.setItem( - 0, 3, - QtGui.QTableWidgetItem("%s" % (c.tlsVersion)) - ) + 0, 3, QtWidgets.QTableWidgetItem("%s" % (c.tlsVersion))) self.tableWidgetConnectionCount.setItem( - 0, 4, - QtGui.QTableWidgetItem("%s" % (",".join(map(str, c.streams)))) - ) + 0, 4, QtWidgets.QTableWidgetItem( + "%s" % ",".join(map(str, c.streams)))) try: # .. todo:: FIXME: hard coded stream no - rating = "%.1f" % (knownnodes.knownNodes[1][destination]['rating']) + rating = "%.1f" % knownnodes.knownNodes[1][destination]['rating'] except KeyError: rating = "-" self.tableWidgetConnectionCount.setItem( - 0, 1, - QtGui.QTableWidgetItem("%s" % (rating)) - ) + 0, 1, QtWidgets.QTableWidgetItem("%s" % (rating))) if outbound: - brush = QtGui.QBrush(QtGui.QColor("yellow"), QtCore.Qt.SolidPattern) + brush = QtGui.QBrush( + QtGui.QColor("yellow"), QtCore.Qt.SolidPattern) else: - brush = QtGui.QBrush(QtGui.QColor("green"), QtCore.Qt.SolidPattern) + brush = QtGui.QBrush( + QtGui.QColor("green"), QtCore.Qt.SolidPattern) for j in range(1): self.tableWidgetConnectionCount.item(0, j).setBackground(brush) - self.tableWidgetConnectionCount.item(0, 0).setData(QtCore.Qt.UserRole, destination) - self.tableWidgetConnectionCount.item(0, 1).setData(QtCore.Qt.UserRole, outbound) + self.tableWidgetConnectionCount.item(0, 0).setData( + QtCore.Qt.UserRole, destination) + self.tableWidgetConnectionCount.item(0, 1).setData( + QtCore.Qt.UserRole, outbound) else: if not BMConnectionPool().inboundConnections: self.window().setStatusIcon('yellow') for i in range(self.tableWidgetConnectionCount.rowCount()): - if self.tableWidgetConnectionCount.item(i, 0).data(QtCore.Qt.UserRole).toPyObject() != destination: + if self.tableWidgetConnectionCount.item(i, 0).data( + QtCore.Qt.UserRole) != destination: continue - if self.tableWidgetConnectionCount.item(i, 1).data(QtCore.Qt.UserRole).toPyObject() == outbound: + if self.tableWidgetConnectionCount.item(i, 1).data( + QtCore.Qt.UserRole) == outbound: self.tableWidgetConnectionCount.removeRow(i) break self.tableWidgetConnectionCount.setUpdatesEnabled(True) self.tableWidgetConnectionCount.setSortingEnabled(True) - self.labelTotalConnections.setText( - _translate( - "networkstatus", "Total Connections: %1").arg( - str(self.tableWidgetConnectionCount.rowCount()))) - # FYI: The 'singlelistener' thread sets the icon color to green when it - # receives an incoming connection, meaning that the user's firewall is - # configured correctly. - if self.tableWidgetConnectionCount.rowCount() and state.statusIconColor == 'red': - self.window().setStatusIcon('yellow') - elif self.tableWidgetConnectionCount.rowCount() == 0 and state.statusIconColor != "red": + self.labelTotalConnections.setText(_translate( + "networkstatus", "Total Connections: {0}").format( + self.tableWidgetConnectionCount.rowCount() + )) + # FYI: The 'singlelistener' thread sets the icon color to green + # when it receives an incoming connection, meaning that the user's + # firewall is configured correctly. + if self.tableWidgetConnectionCount.rowCount(): + if state.statusIconColor == 'red': + self.window().setStatusIcon('yellow') + elif state.statusIconColor != 'red': self.window().setStatusIcon('red') # timer driven def runEveryTwoSeconds(self): """Updates counters, runs every 2 seconds if the timer is running""" - self.labelLookupsPerSecond.setText(_translate("networkstatus", "Inventory lookups per second: %1").arg( - str(Inventory().numberOfInventoryLookupsPerformed / 2))) + self.labelLookupsPerSecond.setText(_translate( + "networkstatus", "Inventory lookups per second: {0}" + ).format(Inventory().numberOfInventoryLookupsPerformed / 2)) Inventory().numberOfInventoryLookupsPerformed = 0 self.updateNumberOfBytes() self.updateNumberOfObjectsToBeSynced() @@ -237,13 +212,12 @@ class NetworkStatus(QtGui.QWidget, RetranslateMixin): def retranslateUi(self): """Conventional Qt Designer method for dynamic l10n""" super(NetworkStatus, self).retranslateUi() - self.labelTotalConnections.setText( - _translate( - "networkstatus", "Total Connections: %1").arg( - str(self.tableWidgetConnectionCount.rowCount()))) + self.labelTotalConnections.setText(_translate( + "networkstatus", "Total Connections: {0}" + ).format(self.tableWidgetConnectionCount.rowCount())) self.labelStartupTime.setText(_translate( - "networkstatus", "Since startup on %1" - ).arg(l10n.formatTimestamp(self.startup))) + "networkstatus", "Since startup on {0}" + ).format(l10n.formatTimestamp(self.startup))) self.updateNumberOfMessagesProcessed() self.updateNumberOfBroadcastsProcessed() self.updateNumberOfPubkeysProcessed() diff --git a/src/bitmessageqt/newaddressdialog.ui b/src/bitmessageqt/newaddressdialog.ui index a9eda5c3..0f8c33d7 100644 --- a/src/bitmessageqt/newaddressdialog.ui +++ b/src/bitmessageqt/newaddressdialog.ui @@ -375,7 +375,7 @@ The 'Random Number' option is selected by default but deterministic addresses ha radioButtonDeterministicAddress toggled(bool) groupBoxDeterministic - setShown(bool) + setVisible(bool) 92 @@ -391,7 +391,7 @@ The 'Random Number' option is selected by default but deterministic addresses ha radioButtonRandomAddress toggled(bool) groupBox - setShown(bool) + setVisible(bool) 72 diff --git a/src/bitmessageqt/retranslateui.py b/src/bitmessageqt/retranslateui.py index e9d5bb3a..dd08e53c 100644 --- a/src/bitmessageqt/retranslateui.py +++ b/src/bitmessageqt/retranslateui.py @@ -1,18 +1,20 @@ -from os import path -from PyQt4 import QtGui -from debug import logger +from PyQt5 import QtWidgets + import widgets + class RetranslateMixin(object): def retranslateUi(self): - defaults = QtGui.QWidget() + defaults = QtWidgets.QWidget() widgets.load(self.__class__.__name__.lower() + '.ui', defaults) for attr, value in defaults.__dict__.iteritems(): setTextMethod = getattr(value, "setText", None) if callable(setTextMethod): getattr(self, attr).setText(getattr(defaults, attr).text()) - elif isinstance(value, QtGui.QTableWidget): - for i in range (value.columnCount()): - getattr(self, attr).horizontalHeaderItem(i).setText(getattr(defaults, attr).horizontalHeaderItem(i).text()) - for i in range (value.rowCount()): - getattr(self, attr).verticalHeaderItem(i).setText(getattr(defaults, attr).verticalHeaderItem(i).text()) + elif isinstance(value, QtWidgets.QTableWidget): + for i in range(value.columnCount()): + getattr(self, attr).horizontalHeaderItem(i).setText( + getattr(defaults, attr).horizontalHeaderItem(i).text()) + for i in range(value.rowCount()): + getattr(self, attr).verticalHeaderItem(i).setText( + getattr(defaults, attr).verticalHeaderItem(i).text()) diff --git a/src/bitmessageqt/safehtmlparser.py b/src/bitmessageqt/safehtmlparser.py index d408d2c7..a7161ae0 100644 --- a/src/bitmessageqt/safehtmlparser.py +++ b/src/bitmessageqt/safehtmlparser.py @@ -123,10 +123,6 @@ class SafeHTMLParser(HTMLParser): self.sanitised += "&" + name + ";" def feed(self, data): - try: - data = unicode(data, 'utf-8') - except UnicodeDecodeError: - data = unicode(data, 'utf-8', errors='replace') HTMLParser.feed(self, data) tmp = SafeHTMLParser.replace_pre(data) tmp = self.uriregex1.sub(r'\1', tmp) diff --git a/src/bitmessageqt/settings.py b/src/bitmessageqt/settings.py index 4173ebd2..a6353131 100644 --- a/src/bitmessageqt/settings.py +++ b/src/bitmessageqt/settings.py @@ -1,12 +1,13 @@ """ -This module setting file is for settings +SettingsDialog class definition """ + import ConfigParser import os import sys import tempfile -from PyQt4 import QtCore, QtGui +from PyQt5 import QtCore, QtGui, QtWidgets import debug import defaults @@ -37,7 +38,7 @@ def getSOCKSProxyType(config): return result -class SettingsDialog(QtGui.QDialog): +class SettingsDialog(QtWidgets.QDialog): """The "Settings" dialog""" def __init__(self, parent=None, firstrun=False): super(SettingsDialog, self).__init__(parent) @@ -78,7 +79,7 @@ class SettingsDialog(QtGui.QDialog): self.tabWidgetSettings.setCurrentIndex( self.tabWidgetSettings.indexOf(self.tabNetworkSettings) ) - QtGui.QWidget.resize(self, QtGui.QWidget.sizeHint(self)) + QtWidgets.QWidget.resize(self, QtWidgets.QWidget.sizeHint(self)) def adjust_from_config(self, config): """Adjust all widgets state according to config settings""" @@ -290,10 +291,10 @@ class SettingsDialog(QtGui.QDialog): _translate("MainWindow", "Testing...")) nc = namecoin.namecoinConnection({ 'type': self.getNamecoinType(), - 'host': str(self.lineEditNamecoinHost.text().toUtf8()), - 'port': str(self.lineEditNamecoinPort.text().toUtf8()), - 'user': str(self.lineEditNamecoinUser.text().toUtf8()), - 'password': str(self.lineEditNamecoinPassword.text().toUtf8()) + 'host': str(self.lineEditNamecoinHost.text()), + 'port': str(self.lineEditNamecoinPort.text()), + 'user': str(self.lineEditNamecoinUser.text()), + 'password': str(self.lineEditNamecoinPassword.text()) }) status, text = nc.test() self.labelNamecoinTestResult.setText(text) @@ -326,8 +327,8 @@ class SettingsDialog(QtGui.QDialog): self.config.set('bitmessagesettings', 'replybelow', str( self.checkBoxReplyBelow.isChecked())) - lang = str(self.languageComboBox.itemData( - self.languageComboBox.currentIndex()).toString()) + lang = self.languageComboBox.itemData( + self.languageComboBox.currentIndex()) self.config.set('bitmessagesettings', 'userlocale', lang) self.parent.change_translation() @@ -409,7 +410,7 @@ class SettingsDialog(QtGui.QDialog): self.config.set('bitmessagesettings', 'maxuploadrate', str( int(float(self.lineEditMaxUploadRate.text())))) except ValueError: - QtGui.QMessageBox.about( + QtWidgets.QMessageBox.about( self, _translate("MainWindow", "Number needed"), _translate( "MainWindow", @@ -450,7 +451,7 @@ class SettingsDialog(QtGui.QDialog): float(self.lineEditSmallMessageDifficulty.text()) * defaults.networkDefaultPayloadLengthExtraBytes))) - if self.comboBoxOpenCL.currentText().toUtf8() != self.config.safeGet( + if self.comboBoxOpenCL.currentText() != self.config.safeGet( 'bitmessagesettings', 'opencl'): self.config.set( 'bitmessagesettings', 'opencl', @@ -464,7 +465,7 @@ class SettingsDialog(QtGui.QDialog): or float(self.lineEditMaxAcceptableTotalDifficulty.text()) == 0 ): if self.config.get( - 'bitmessagesettings', 'maxacceptablenoncetrialsperbyte' + 'bitmessagesettings', 'maxacceptablenoncetrialsperbyte' ) != str(int( float(self.lineEditMaxAcceptableTotalDifficulty.text()) * defaults.networkDefaultProofOfWorkNonceTrialsPerByte)): @@ -481,7 +482,7 @@ class SettingsDialog(QtGui.QDialog): or float(self.lineEditMaxAcceptableSmallMessageDifficulty.text()) == 0 ): if self.config.get( - 'bitmessagesettings', 'maxacceptablepayloadlengthextrabytes' + 'bitmessagesettings', 'maxacceptablepayloadlengthextrabytes' ) != str(int( float(self.lineEditMaxAcceptableSmallMessageDifficulty.text()) * defaults.networkDefaultPayloadLengthExtraBytes)): @@ -533,7 +534,7 @@ class SettingsDialog(QtGui.QDialog): if state.maximumLengthOfTimeToBotherResendingMessages < 432000: # If the time period is less than 5 hours, we give # zero values to all fields. No message will be sent again. - QtGui.QMessageBox.about( + QtWidgets.QMessageBox.about( self, _translate("MainWindow", "Will not resend ever"), _translate( diff --git a/src/bitmessageqt/settingsmixin.py b/src/bitmessageqt/settingsmixin.py index 3d5999e2..a5b8db5c 100644 --- a/src/bitmessageqt/settingsmixin.py +++ b/src/bitmessageqt/settingsmixin.py @@ -1,15 +1,15 @@ -#!/usr/bin/python2.7 """ src/settingsmixin.py ==================== """ -from PyQt4 import QtCore, QtGui +from PyQt5 import QtCore, QtWidgets class SettingsMixin(object): - """Mixin for adding geometry and state saving between restarts.""" + """Mixin for adding geometry and state saving between restarts""" + def warnIfNoObjectName(self): """ Handle objects which don't have a name. Currently it ignores them. Objects without a name can't have their @@ -40,8 +40,9 @@ class SettingsMixin(object): self.warnIfNoObjectName() settings = QtCore.QSettings() try: - geom = settings.value("/".join([str(self.objectName()), "geometry"])) - target.restoreGeometry(geom.toByteArray() if hasattr(geom, 'toByteArray') else geom) + geom = settings.value( + "/".join([str(self.objectName()), "geometry"])) + target.restoreGeometry(geom) except Exception: pass @@ -51,13 +52,14 @@ class SettingsMixin(object): settings = QtCore.QSettings() try: state = settings.value("/".join([str(self.objectName()), "state"])) - target.restoreState(state.toByteArray() if hasattr(state, 'toByteArray') else state) + target.restoreState(state) except Exception: pass -class SMainWindow(QtGui.QMainWindow, SettingsMixin): - """Main window with Settings functionality.""" +class SMainWindow(QtWidgets.QMainWindow, SettingsMixin): + """Main window with Settings functionality""" + def loadSettings(self): """Load main window settings.""" self.readGeometry(self) @@ -69,9 +71,9 @@ class SMainWindow(QtGui.QMainWindow, SettingsMixin): self.writeGeometry(self) -class STableWidget(QtGui.QTableWidget, SettingsMixin): +class STableWidget(QtWidgets.QTableWidget, SettingsMixin): """Table widget with Settings functionality""" - # pylint: disable=too-many-ancestors + def loadSettings(self): """Load table settings.""" self.readState(self.horizontalHeader()) @@ -81,8 +83,9 @@ class STableWidget(QtGui.QTableWidget, SettingsMixin): self.writeState(self.horizontalHeader()) -class SSplitter(QtGui.QSplitter, SettingsMixin): - """Splitter with Settings functionality.""" +class SSplitter(QtWidgets.QSplitter, SettingsMixin): + """Splitter with Settings functionality""" + def loadSettings(self): """Load splitter settings""" self.readState(self) @@ -92,17 +95,17 @@ class SSplitter(QtGui.QSplitter, SettingsMixin): self.writeState(self) -class STreeWidget(QtGui.QTreeWidget, SettingsMixin): - """Tree widget with settings functionality.""" - # pylint: disable=too-many-ancestors +class STreeWidget(QtWidgets.QTreeWidget, SettingsMixin): + """Tree widget with settings functionality""" + def loadSettings(self): - """Load tree settings.""" + """Load tree settings. Unimplemented.""" # recurse children # self.readState(self) pass def saveSettings(self): - """Save tree settings""" + """Save tree settings. Unimplemented.""" # recurse children # self.writeState(self) pass diff --git a/src/bitmessageqt/statusbar.py b/src/bitmessageqt/statusbar.py index 2add604d..006ba564 100644 --- a/src/bitmessageqt/statusbar.py +++ b/src/bitmessageqt/statusbar.py @@ -1,11 +1,11 @@ -# pylint: disable=unused-argument -"""Status bar Module""" +"""BMStatusBar class definition""" from time import time -from PyQt4 import QtGui + +from PyQt5 import QtWidgets -class BMStatusBar(QtGui.QStatusBar): +class BMStatusBar(QtWidgets.QStatusBar): """Status bar with queue and priorities""" duration = 10000 deleteAfter = 60 @@ -16,21 +16,24 @@ class BMStatusBar(QtGui.QStatusBar): self.timer = self.startTimer(BMStatusBar.duration) 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 show in the status bar, for example if many messages come very quickly after one another, it adds delays and so on""" while len(self.important) > 0: self.iterator += 1 try: - if time() > self.important[self.iterator][1] + BMStatusBar.deleteAfter: + if ( + self.important[self.iterator][1] + + BMStatusBar.deleteAfter < time() + ): del self.important[self.iterator] self.iterator -= 1 continue except IndexError: self.iterator = -1 continue - super(BMStatusBar, self).showMessage(self.important[self.iterator][0], 0) + self.showMessage(self.important[self.iterator][0], 0) break def addImportant(self, message): diff --git a/src/bitmessageqt/tests/main.py b/src/bitmessageqt/tests/main.py index b3aa67fa..9ffba909 100644 --- a/src/bitmessageqt/tests/main.py +++ b/src/bitmessageqt/tests/main.py @@ -4,7 +4,7 @@ import Queue import sys import unittest -from PyQt4 import QtCore, QtGui +from qtpy import QtCore, QtWidgets import bitmessageqt import queues @@ -16,7 +16,7 @@ class TestBase(unittest.TestCase): def setUp(self): self.app = ( - QtGui.QApplication.instance() + QtWidgets.QApplication.instance() or bitmessageqt.BitmessageQtApplication(sys.argv)) self.window = self.app.activeWindow() if not self.window: @@ -41,7 +41,7 @@ class TestMain(unittest.TestCase): """Check the results of _translate() with various args""" self.assertIsInstance( _translate("MainWindow", "Test"), - QtCore.QString + unicode ) diff --git a/src/bitmessageqt/uisignaler.py b/src/bitmessageqt/uisignaler.py index 055f9097..2753121f 100644 --- a/src/bitmessageqt/uisignaler.py +++ b/src/bitmessageqt/uisignaler.py @@ -1,15 +1,35 @@ -from PyQt4.QtCore import QThread, SIGNAL import sys +from PyQt5 import QtCore + import queues +from network.node import Peer -class UISignaler(QThread): +class UISignaler(QtCore.QThread): _instance = None - def __init__(self, parent=None): - QThread.__init__(self, parent) + writeNewAddressToTable = QtCore.Signal(str, str, str) + updateStatusBar = QtCore.Signal(object) + updateSentItemStatusByToAddress = QtCore.Signal(object, str) + updateSentItemStatusByAckdata = QtCore.Signal(object, str) + displayNewInboxMessage = QtCore.Signal(object, str, str, object, str) + displayNewSentMessage = QtCore.Signal(object, str, str, str, object, str) + updateNetworkStatusTab = QtCore.Signal(bool, bool, Peer) + updateNumberOfMessagesProcessed = QtCore.Signal() + updateNumberOfPubkeysProcessed = QtCore.Signal() + updateNumberOfBroadcastsProcessed = QtCore.Signal() + setStatusIcon = QtCore.Signal(str) + changedInboxUnread = QtCore.Signal(str) + rerenderMessagelistFromLabels = QtCore.Signal() + rerenderMessagelistToLabels = QtCore.Signal() + rerenderAddressBook = QtCore.Signal() + rerenderSubscriptions = QtCore.Signal() + rerenderBlackWhiteList = QtCore.Signal() + removeInboxRowByMsgid = QtCore.Signal(str) + newVersionAvailable = QtCore.Signal(str) + displayAlert = QtCore.Signal(str, str, bool) @classmethod def get(cls): @@ -22,58 +42,58 @@ class UISignaler(QThread): command, data = queues.UISignalQueue.get() if command == 'writeNewAddressToTable': label, address, streamNumber = data - self.emit(SIGNAL( - "writeNewAddressToTable(PyQt_PyObject,PyQt_PyObject,PyQt_PyObject)"), label, address, str(streamNumber)) + self.writeNewAddressToTable.emit( + label, address, str(streamNumber)) elif command == 'updateStatusBar': - self.emit(SIGNAL("updateStatusBar(PyQt_PyObject)"), data) + self.updateStatusBar.emit(data) elif command == 'updateSentItemStatusByToAddress': toAddress, message = data - self.emit(SIGNAL( - "updateSentItemStatusByToAddress(PyQt_PyObject,PyQt_PyObject)"), toAddress, message) + self.updateSentItemStatusByToAddress.emit(toAddress, message) elif command == 'updateSentItemStatusByAckdata': ackData, message = data - self.emit(SIGNAL( - "updateSentItemStatusByAckdata(PyQt_PyObject,PyQt_PyObject)"), ackData, message) + self.updateSentItemStatusByAckdata.emit(ackData, message) elif command == 'displayNewInboxMessage': inventoryHash, toAddress, fromAddress, subject, body = data - self.emit(SIGNAL( - "displayNewInboxMessage(PyQt_PyObject,PyQt_PyObject,PyQt_PyObject,PyQt_PyObject,PyQt_PyObject)"), - inventoryHash, toAddress, fromAddress, subject, body) + self.displayNewInboxMessage.emit( + inventoryHash, toAddress, fromAddress, + unicode(subject, 'utf-8'), body) elif command == 'displayNewSentMessage': toAddress, fromLabel, fromAddress, subject, message, ackdata = data - self.emit(SIGNAL( - "displayNewSentMessage(PyQt_PyObject,PyQt_PyObject,PyQt_PyObject,PyQt_PyObject,PyQt_PyObject,PyQt_PyObject)"), - toAddress, fromLabel, fromAddress, subject, message, ackdata) + self.displayNewSentMessage.emit( + toAddress, fromLabel, fromAddress, + unicode(subject, 'utf-8'), message, ackdata) elif command == 'updateNetworkStatusTab': outbound, add, destination = data - self.emit(SIGNAL("updateNetworkStatusTab(PyQt_PyObject,PyQt_PyObject,PyQt_PyObject)"), outbound, add, destination) + self.updateNetworkStatusTab.emit(outbound, add, destination) elif command == 'updateNumberOfMessagesProcessed': - self.emit(SIGNAL("updateNumberOfMessagesProcessed()")) + self.updateNumberOfMessagesProcessed.emit() elif command == 'updateNumberOfPubkeysProcessed': - self.emit(SIGNAL("updateNumberOfPubkeysProcessed()")) + self.updateNumberOfPubkeysProcessed.emit() elif command == 'updateNumberOfBroadcastsProcessed': - self.emit(SIGNAL("updateNumberOfBroadcastsProcessed()")) + self.updateNumberOfBroadcastsProcessed.emit() elif command == 'setStatusIcon': - self.emit(SIGNAL("setStatusIcon(PyQt_PyObject)"), data) + self.setStatusIcon.emit(data) elif command == 'changedInboxUnread': - self.emit(SIGNAL("changedInboxUnread(PyQt_PyObject)"), data) + self.changedInboxUnread.emit(data) elif command == 'rerenderMessagelistFromLabels': - self.emit(SIGNAL("rerenderMessagelistFromLabels()")) + self.rerenderMessagelistFromLabels.emit() elif command == 'rerenderMessagelistToLabels': - self.emit(SIGNAL("rerenderMessagelistToLabels()")) + self.rerenderMessagelistToLabels.emit() elif command == 'rerenderAddressBook': - self.emit(SIGNAL("rerenderAddressBook()")) + self.rerenderAddressBook.emit() elif command == 'rerenderSubscriptions': - self.emit(SIGNAL("rerenderSubscriptions()")) + self.rerenderSubscriptions.emit() elif command == 'rerenderBlackWhiteList': - self.emit(SIGNAL("rerenderBlackWhiteList()")) + self.rerenderBlackWhiteList.emit() elif command == 'removeInboxRowByMsgid': - self.emit(SIGNAL("removeInboxRowByMsgid(PyQt_PyObject)"), data) + self.removeInboxRowByMsgid.emit(data) elif command == 'newVersionAvailable': - self.emit(SIGNAL("newVersionAvailable(PyQt_PyObject)"), data) + self.newVersionAvailable.emit(data) elif command == 'alert': title, text, exitAfterUserClicksOk = data - self.emit(SIGNAL("displayAlert(PyQt_PyObject, PyQt_PyObject, PyQt_PyObject)"), title, text, exitAfterUserClicksOk) + self.displayAlert.emit(title, text, exitAfterUserClicksOk) else: sys.stderr.write( - 'Command sent to UISignaler not recognized: %s\n' % command) + 'Command sent to UISignaler not recognized: %s\n' + % command + ) diff --git a/src/bitmessageqt/utils.py b/src/bitmessageqt/utils.py index e118f487..a4f035c7 100644 --- a/src/bitmessageqt/utils.py +++ b/src/bitmessageqt/utils.py @@ -1,7 +1,7 @@ import hashlib import os -from PyQt4 import QtGui +from PyQt5 import QtGui import state from addresses import addBMIfNotPresent @@ -30,16 +30,17 @@ def identiconize(address): # It can be used as a pseudo-password to salt the generation of # the identicons to decrease the risk of attacks where someone creates # an address to mimic someone else's identicon. - identiconsuffix = BMConfigParser().get('bitmessagesettings', 'identiconsuffix') + data = addBMIfNotPresent(address) + BMConfigParser().get( + 'bitmessagesettings', 'identiconsuffix') if identicon_lib[:len('qidenticon')] == 'qidenticon': # originally by: # :Author:Shin Adachi # Licesensed under FreeBSD License. # stripped from PIL and uses QT instead (by sendiulo, same license) import qidenticon - icon_hash = hashlib.md5( - addBMIfNotPresent(address) + identiconsuffix).hexdigest() - use_two_colors = identicon_lib[:len('qidenticon_two')] == 'qidenticon_two' + icon_hash = hashlib.md5(data).hexdigest() + use_two_colors = ( + identicon_lib[:len('qidenticon_two')] == 'qidenticon_two') opacity = int( identicon_lib not in ( 'qidenticon_x', 'qidenticon_two_x', @@ -63,8 +64,7 @@ def identiconize(address): # https://github.com/azaghal/pydenticon # note that it requires pillow (or PIL) to be installed: # https://python-pillow.org/ - idcon_render = Pydenticon( - addBMIfNotPresent(address) + identiconsuffix, size * 3) + idcon_render = Pydenticon(data, size * 3) rendering = idcon_render._render() data = rendering.convert("RGBA").tostring("raw", "RGBA") qim = QtGui.QImage(data, size, size, QtGui.QImage.Format_ARGB32) @@ -105,11 +105,9 @@ def avatarize(address): lower_default = state.appdata + 'avatars/' + 'default.' + ext.lower() upper_default = state.appdata + 'avatars/' + 'default.' + ext.upper() if os.path.isfile(lower_default): - default = lower_default idcon.addFile(lower_default) return idcon elif os.path.isfile(upper_default): - default = upper_default idcon.addFile(upper_default) return idcon # If no avatar is found diff --git a/src/bitmessageqt/widgets.py b/src/bitmessageqt/widgets.py index 8ef807f2..c4a91375 100644 --- a/src/bitmessageqt/widgets.py +++ b/src/bitmessageqt/widgets.py @@ -1,13 +1,15 @@ -from PyQt4 import uic +from PyQt5 import uic import os.path import paths -import sys + def resource_path(resFile): baseDir = paths.codePath() - for subDir in ["ui", "bitmessageqt"]: - if os.path.isdir(os.path.join(baseDir, subDir)) and os.path.isfile(os.path.join(baseDir, subDir, resFile)): - return os.path.join(baseDir, subDir, resFile) + for subDir in ("ui", "bitmessageqt"): + path = os.path.join(baseDir, subDir, resFile) + if os.path.isfile(path): + return path + def load(resFile, widget): uic.loadUi(resource_path(resFile), widget) diff --git a/src/class_addressGenerator.py b/src/class_addressGenerator.py index 25b0c5df..1fa0ce0e 100644 --- a/src/class_addressGenerator.py +++ b/src/class_addressGenerator.py @@ -1,5 +1,5 @@ """ -A thread for creating addresses +addressGenerator thread class definition """ import hashlib import time @@ -213,10 +213,11 @@ class addressGenerator(StoppableThread): queues.workerQueue.put(( 'sendOutOrStoreMyV4Pubkey', address)) - elif command == 'createDeterministicAddresses' \ - or command == 'getDeterministicAddress' \ - or command == 'createChan' or command == 'joinChan': - if not deterministicPassphrase: + elif command in ( + 'createDeterministicAddresses', + 'getDeterministicAddress', 'createChan', 'joinChan' + ): + if len(deterministicPassphrase) == 0: self.logger.warning( 'You are creating deterministic' ' address(es) using a blank passphrase.' @@ -225,9 +226,8 @@ class addressGenerator(StoppableThread): queues.UISignalQueue.put(( 'updateStatusBar', tr._translate( - "MainWindow", - "Generating %1 new addresses." - ).arg(str(numberOfAddressesToMake)) + "MainWindow", "Generating {0} new addresses." + ).format(str(numberOfAddressesToMake)) )) signingKeyNonce = 0 encryptionKeyNonce = 1 @@ -331,17 +331,16 @@ class addressGenerator(StoppableThread): 'updateStatusBar', tr._translate( "MainWindow", - "%1 is already in 'Your Identities'." + "{0} is already in 'Your Identities'." " Not adding it again." - ).arg(address) + ).format(address) )) else: self.logger.debug('label: %s', label) BMConfigParser().set(address, 'label', label) BMConfigParser().set(address, 'enabled', 'true') BMConfigParser().set(address, 'decoy', 'false') - if command == 'joinChan' \ - or command == 'createChan': + if command in ('joinChan', 'createChan'): BMConfigParser().set(address, 'chan', 'true') BMConfigParser().set( address, 'noncetrialsperbyte', @@ -392,8 +391,10 @@ class addressGenerator(StoppableThread): address) # Done generating addresses. - if command == 'createDeterministicAddresses' \ - or command == 'joinChan' or command == 'createChan': + if command in ( + 'createDeterministicAddresses', + 'joinChan', 'createChan' + ): queues.apiAddressGeneratorReturnQueue.put( listOfNewAddressesToSendOutThroughTheAPI) elif command == 'getDeterministicAddress': diff --git a/src/depends.py b/src/depends.py index 212c3143..23da7d92 100755 --- a/src/depends.py +++ b/src/depends.py @@ -384,7 +384,7 @@ def check_pyqt(): PyQt 4.8 or later. """ QtCore = try_import( - 'PyQt4.QtCore', 'PyBitmessage requires PyQt 4.8 or later and Qt 4.7 or later.') + 'qtpy.QtCore', 'PyBitmessage requires PyQt 4.8 or later and Qt 4.7 or later.') if not QtCore: return False diff --git a/src/plugins/menu_qrcode.py b/src/plugins/menu_qrcode.py index ea322a49..1fbccbe4 100644 --- a/src/plugins/menu_qrcode.py +++ b/src/plugins/menu_qrcode.py @@ -6,7 +6,7 @@ A menu plugin showing QR-Code for bitmessage address in modal dialog. import urllib import qrcode -from PyQt4 import QtCore, QtGui +from qtpy import QtGui, QtCore, QtWidgets from pybitmessage.tr import _translate @@ -39,23 +39,23 @@ class Image(qrcode.image.base.BaseImage): # pylint: disable=abstract-method QtCore.Qt.black) -class QRCodeDialog(QtGui.QDialog): +class QRCodeDialog(QtWidgets.QDialog): """The dialog""" def __init__(self, parent): super(QRCodeDialog, self).__init__(parent) - self.image = QtGui.QLabel(self) - self.label = QtGui.QLabel(self) + self.image = QtWidgets.QLabel(self) + self.label = QtWidgets.QLabel(self) font = QtGui.QFont() font.setBold(True) font.setWeight(75) self.label.setFont(font) self.label.setAlignment( QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter) - buttonBox = QtGui.QDialogButtonBox(self) + buttonBox = QtWidgets.QDialogButtonBox(self) buttonBox.setOrientation(QtCore.Qt.Horizontal) - buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Ok) + buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Ok) buttonBox.accepted.connect(self.accept) - layout = QtGui.QVBoxLayout(self) + layout = QtWidgets.QVBoxLayout(self) layout.addWidget(self.image) layout.addWidget(self.label) layout.addWidget(buttonBox) @@ -72,7 +72,7 @@ class QRCodeDialog(QtGui.QDialog): self.label.setText(text) self.label.setToolTip(text) self.label.setFixedWidth(pixmap.width()) - self.setFixedSize(QtGui.QWidget.sizeHint(self)) + self.setFixedSize(QtWidgets.QWidget.sizeHint(self)) def connect_plugin(form): diff --git a/src/plugins/plugin.py b/src/plugins/plugin.py index 629de0a6..9f3b76c0 100644 --- a/src/plugins/plugin.py +++ b/src/plugins/plugin.py @@ -32,6 +32,7 @@ def get_plugins(group, point='', name=None, fallback=None): except (AttributeError, ImportError, ValueError, + RuntimeError, # PyQt for example pkg_resources.DistributionNotFound, pkg_resources.UnknownExtra): logger.debug( -- 2.45.1 From 58466d5424767a7f342063196e331413cddc06da Mon Sep 17 00:00:00 2001 From: Dmitri Bogomolov <4glitch@gmail.com> Date: Mon, 19 Feb 2018 14:38:25 +0200 Subject: [PATCH 004/105] Changes for pyside: customwidgets in ui-files and QtGui.QPen instantiation --- src/bitmessageqt/__init__.py | 4 +--- src/bitmessageqt/blacklist.ui | 2 +- src/bitmessageqt/networkstatus.ui | 2 +- src/qidenticon.py | 5 +++-- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/bitmessageqt/__init__.py b/src/bitmessageqt/__init__.py index eaac4968..d25f2f14 100644 --- a/src/bitmessageqt/__init__.py +++ b/src/bitmessageqt/__init__.py @@ -1781,11 +1781,9 @@ class MyForm(settingsmixin.SMainWindow): fontMetrics = QtGui.QFontMetrics(font) rect = fontMetrics.boundingRect(txt) # draw text - # painter = QtGui.QPainter(self) painter = QtGui.QPainter() painter.begin(pixmap) - painter.setPen( - QtGui.QPen(QtGui.QColor(255, 0, 0), QtCore.Qt.SolidPattern)) + painter.setPen(QtGui.QPen(QtGui.QColor(255, 0, 0))) painter.setFont(font) painter.drawText(24-rect.right()-marginX, -rect.top()+marginY, txt) painter.end() diff --git a/src/bitmessageqt/blacklist.ui b/src/bitmessageqt/blacklist.ui index 80993fac..3068a6ae 100644 --- a/src/bitmessageqt/blacklist.ui +++ b/src/bitmessageqt/blacklist.ui @@ -98,7 +98,7 @@ STableWidget QTableWidget -
bitmessageqt/settingsmixin.h
+
bitmessageqt.settingsmixin
diff --git a/src/bitmessageqt/networkstatus.ui b/src/bitmessageqt/networkstatus.ui index e0c01b57..14aeca6e 100644 --- a/src/bitmessageqt/networkstatus.ui +++ b/src/bitmessageqt/networkstatus.ui @@ -296,7 +296,7 @@ STableWidget QTableWidget -
bitmessageqt/settingsmixin.h
+
bitmessageqt.settingsmixin
diff --git a/src/qidenticon.py b/src/qidenticon.py index 13be3578..5294da86 100644 --- a/src/qidenticon.py +++ b/src/qidenticon.py @@ -129,11 +129,12 @@ class IdenticonRendererBase(object): QtCore.QPointF(size, size), QtCore.QPointF(0., size)] rotation = [0, 90, 180, 270] - nopen = QtGui.QPen(foreColor, QtCore.Qt.NoPen) + nopen = QtGui.QPen(foreColor) + nopen.setStyle(QtCore.Qt.NoPen) foreBrush = QtGui.QBrush(foreColor, QtCore.Qt.SolidPattern) if penwidth > 0: pen_color = QtGui.QColor(255, 255, 255) - pen = QtGui.QPen(pen_color, QtCore.Qt.SolidPattern) + pen = QtGui.QPen(pen_color) pen.setWidth(penwidth) painter = QtGui.QPainter() -- 2.45.1 From 07c2a514295178268534742bee909ac98351fd31 Mon Sep 17 00:00:00 2001 From: Dmitri Bogomolov <4glitch@gmail.com> Date: Wed, 21 Feb 2018 19:10:32 +0200 Subject: [PATCH 005/105] Module support rewrite: - added Qt API string into support request - finished flake8 formatting --- src/bitmessageqt/support.py | 55 +++++++++++++++++++++++-------------- 1 file changed, 34 insertions(+), 21 deletions(-) diff --git a/src/bitmessageqt/support.py b/src/bitmessageqt/support.py index ac02e2ca..965303ca 100644 --- a/src/bitmessageqt/support.py +++ b/src/bitmessageqt/support.py @@ -1,12 +1,12 @@ """Composing support request message functions.""" -# pylint: disable=no-member import ctypes +import os import ssl import sys import time -from PyQt4 import QtCore +from qtpy import QtCore import account import defaults @@ -22,8 +22,8 @@ from l10n import getTranslationLanguage from openclpow import openclEnabled from pyelliptic.openssl import OpenSSL from settings import getSOCKSProxyType -from version import softwareVersion from tr import _translate +from version import softwareVersion # this is BM support address going to Peter Surda @@ -31,7 +31,7 @@ OLD_SUPPORT_ADDRESS = 'BM-2cTkCtMYkrSPwFTpgcBrMrf5d8oZwvMZWK' SUPPORT_ADDRESS = 'BM-2cUdgkDDAahwPAU6oD2A7DnjqZz3hgY832' SUPPORT_LABEL = _translate("Support", "PyBitmessage support") SUPPORT_MY_LABEL = _translate("Support", "My new address") -SUPPORT_SUBJECT = 'Support request' +SUPPORT_SUBJECT = _translate("Support", "Support request") SUPPORT_MESSAGE = _translate("Support", ''' You can use this message to send a report to one of the PyBitmessage core \ developers regarding PyBitmessage or the mailchuck.com email service. \ @@ -55,6 +55,7 @@ Operating system: {} Architecture: {}bit Python Version: {} OpenSSL Version: {} +Qt API: {} Frozen: {} Portable mode: {} C PoW: {} @@ -67,28 +68,35 @@ Connected hosts: {} def checkAddressBook(myapp): + """ + Add "PyBitmessage support" address to address book, remove old one if found. + """ sqlExecute('DELETE from addressbook WHERE address=?', OLD_SUPPORT_ADDRESS) - queryreturn = sqlQuery('SELECT * FROM addressbook WHERE address=?', SUPPORT_ADDRESS) + queryreturn = sqlQuery( + 'SELECT * FROM addressbook WHERE address=?', SUPPORT_ADDRESS) if queryreturn == []: sqlExecute( 'INSERT INTO addressbook VALUES (?,?)', - SUPPORT_LABEL.toUtf8(), SUPPORT_ADDRESS) + SUPPORT_LABEL.encode('utf-8'), SUPPORT_ADDRESS) myapp.rerenderAddressBook() def checkHasNormalAddress(): + """Returns first enabled normal address or False if not found.""" for address in account.getSortedAccounts(): acct = account.accountClass(address) - if acct.type == AccountMixin.NORMAL and BMConfigParser().safeGetBoolean(address, 'enabled'): + if acct.type == AccountMixin.NORMAL and BMConfigParser().safeGetBoolean( + address, 'enabled'): return address return False def createAddressIfNeeded(myapp): + """Checks if user has any anabled normal address, creates new one if no.""" if not checkHasNormalAddress(): queues.addressGeneratorQueue.put(( 'createRandomAddress', 4, 1, - str(SUPPORT_MY_LABEL.toUtf8()), + SUPPORT_MY_LABEL.encode('utf-8'), 1, "", False, defaults.networkDefaultProofOfWorkNonceTrialsPerByte, defaults.networkDefaultPayloadLengthExtraBytes @@ -100,6 +108,9 @@ def createAddressIfNeeded(myapp): def createSupportMessage(myapp): + """ + Prepare the support request message and switch to tab "Send" + """ checkAddressBook(myapp) address = createAddressIfNeeded(myapp) if state.shutdown: @@ -119,15 +130,13 @@ def createSupportMessage(myapp): if commit: version += " GIT " + commit - os = sys.platform - if os == "win32": - windowsversion = sys.getwindowsversion() - os = "Windows " + str(windowsversion[0]) + "." + str(windowsversion[1]) + if sys.platform.startswith("win"): + # pylint: disable=no-member + osname = "Windows %s.%s" % sys.getwindowsversion()[:2] else: try: - from os import uname - unixversion = uname() - os = unixversion[0] + " " + unixversion[2] + unixversion = os.uname() + osname = unixversion[0] + " " + unixversion[2] except: pass architecture = "32" if ctypes.sizeof(ctypes.c_voidp) == 4 else "64" @@ -136,22 +145,26 @@ def createSupportMessage(myapp): opensslversion = "%s (Python internal), %s (external for PyElliptic)" % ( ssl.OPENSSL_VERSION, OpenSSL._version) + qtapi = os.environ['QT_API'] + frozen = "N/A" if paths.frozen: frozen = paths.frozen - portablemode = "True" if state.appdata == paths.lookupExeFolder() else "False" + portablemode = str(state.appdata == paths.lookupExeFolder()) cpow = "True" if proofofwork.bmpow else "False" openclpow = str( BMConfigParser().safeGet('bitmessagesettings', 'opencl') ) if openclEnabled() else "None" locale = getTranslationLanguage() - socks = getSOCKSProxyType(BMConfigParser()) or "N/A" - upnp = BMConfigParser().safeGet('bitmessagesettings', 'upnp', "N/A") + socks = getSOCKSProxyType(BMConfigParser()) or 'N/A' + upnp = BMConfigParser().safeGet('bitmessagesettings', 'upnp', 'N/A') connectedhosts = len(network.stats.connectedHostsList()) - myapp.ui.textEditMessage.setText(unicode(SUPPORT_MESSAGE, 'utf-8').format( - version, os, architecture, pythonversion, opensslversion, frozen, - portablemode, cpow, openclpow, locale, socks, upnp, connectedhosts)) + myapp.ui.textEditMessage.setText(SUPPORT_MESSAGE.format( + version, osname, architecture, pythonversion, opensslversion, qtapi, + frozen, portablemode, cpow, openclpow, locale, socks, upnp, + connectedhosts + )) # single msg tab myapp.ui.tabWidgetSend.setCurrentIndex( -- 2.45.1 From 1cae5201916abd001750d3f642cc5bde3c71af1a Mon Sep 17 00:00:00 2001 From: Dmitri Bogomolov <4glitch@gmail.com> Date: Thu, 22 Feb 2018 12:33:16 +0200 Subject: [PATCH 006/105] Better formatting of connections table header --- src/bitmessageqt/networkstatus.py | 7 +++---- src/bitmessageqt/networkstatus.ui | 3 --- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/bitmessageqt/networkstatus.py b/src/bitmessageqt/networkstatus.py index b1f3d4de..ef1265af 100644 --- a/src/bitmessageqt/networkstatus.py +++ b/src/bitmessageqt/networkstatus.py @@ -24,10 +24,9 @@ class NetworkStatus(QtWidgets.QWidget, RetranslateMixin): widgets.load('networkstatus.ui', self) header = self.tableWidgetConnectionCount.horizontalHeader() - # header.setSectionResizeMode(0, QtWidgets.QHeaderView.Stretch) - for column in range(0, 4): - header.setSectionResizeMode( - column, QtWidgets.QHeaderView.ResizeToContents) + header.setSectionResizeMode(QtWidgets.QHeaderView.ResizeToContents) + header.setSectionResizeMode(0, QtWidgets.QHeaderView.Stretch) + header.setSectionResizeMode(2, QtWidgets.QHeaderView.Stretch) # Somehow this value was 5 when I tested if header.sortIndicatorSection() > 4: diff --git a/src/bitmessageqt/networkstatus.ui b/src/bitmessageqt/networkstatus.ui index 14aeca6e..7c40a002 100644 --- a/src/bitmessageqt/networkstatus.ui +++ b/src/bitmessageqt/networkstatus.ui @@ -109,9 +109,6 @@ false - - true - false -- 2.45.1 From 3202082e76003f423f0f7b02ef12bd9e1e7a5410 Mon Sep 17 00:00:00 2001 From: Dmitri Bogomolov <4glitch@gmail.com> Date: Thu, 22 Feb 2018 15:09:40 +0200 Subject: [PATCH 007/105] No more arg() call on result of _translate() --- src/class_objectProcessor.py | 7 +- src/class_singleWorker.py | 215 ++++++++++++++++------------------- src/namecoin.py | 127 ++++++++++----------- src/network/tcp.py | 5 +- src/upnp.py | 9 +- 5 files changed, 168 insertions(+), 195 deletions(-) diff --git a/src/class_objectProcessor.py b/src/class_objectProcessor.py index 1bacf639..fcc63cc6 100644 --- a/src/class_objectProcessor.py +++ b/src/class_objectProcessor.py @@ -144,11 +144,10 @@ class objectProcessor(threading.Thread): " WHERE ackdata=?", int(time.time()), data[readPosition:]) queues.UISignalQueue.put(( 'updateSentItemStatusByAckdata', ( - data[readPosition:], - _translate( + data[readPosition:], _translate( "MainWindow", - "Acknowledgement of the message received %1" - ).arg(l10n.formatTimestamp())) + "Acknowledgement of the message received {0}" + ).format(l10n.formatTimestamp())) )) else: logger.debug('This object is not an acknowledgement bound for me.') diff --git a/src/class_singleWorker.py b/src/class_singleWorker.py index fea842ea..6e2fb94d 100644 --- a/src/class_singleWorker.py +++ b/src/class_singleWorker.py @@ -12,6 +12,8 @@ from binascii import hexlify, unhexlify from struct import pack from subprocess import call # nosec +from six.moves import configparser, queue + import defaults import helper_inbox import helper_msgcoding @@ -24,15 +26,13 @@ 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 helper_sql import sqlExecute, sqlQuery from inventory import Inventory from network import knownnodes, StoppableThread -from six.moves import configparser, queue +from tr import _translate def sizeof_fmt(num, suffix='h/s'): @@ -216,9 +216,8 @@ class singleWorker(StoppableThread): return privSigningKeyHex, privEncryptionKeyHex, \ pubSigningKey, pubEncryptionKey - def _doPOWDefaults(self, payload, TTL, - log_prefix='', - log_time=False): + def _doPOWDefaults( + self, payload, TTL, log_prefix='', log_time=False): target = 2 ** 64 / ( defaults.networkDefaultProofOfWorkNonceTrialsPerByte * ( len(payload) + 8 @@ -244,14 +243,16 @@ class singleWorker(StoppableThread): 'PoW took %.1f seconds, speed %s.', delta, sizeof_fmt(nonce / delta) ) - except: # noqa:E722 # NameError + except NameError: self.logger.warning("Proof of Work exception") payload = pack('>Q', nonce) + payload return payload def doPOWForMyV2Pubkey(self, adressHash): - """ This function also broadcasts out the pubkey - message once it is done with the POW""" + """ + This function also broadcasts out the pubkey message once it is + done with the POW + """ # Look up my stream number based on my address hash myAddress = shared.myAddressesByHash[adressHash] # status @@ -311,9 +312,10 @@ class singleWorker(StoppableThread): def sendOutOrStoreMyV3Pubkey(self, adressHash): """ - If this isn't a chan address, this function assembles the pubkey data, does the necessary POW and sends it out. - If it *is* a chan then it assembles the pubkey and stores is in the pubkey table so that we can send messages - to "ourselves". + If this isn't a chan address, this function assembles the pubkey + data, does the necessary POW and sends it out. + If it *is* a chan then it assembles the pubkey and stores it in + the pubkey table so that we can send messages to "ourselves". """ try: myAddress = shared.myAddressesByHash[adressHash] @@ -399,9 +401,10 @@ class singleWorker(StoppableThread): def sendOutOrStoreMyV4Pubkey(self, myAddress): """ - It doesn't send directly anymore. It put is to a queue for another thread to send at an appropriate time, - whereas in the past it directly appended it to the outgoing buffer, I think. Same with all the other methods in - this class. + It doesn't send directly anymore. It put is to a queue for + another thread to send at an appropriate time, whereas in the + past it directly appended it to the outgoing buffer, I think. + Same with all the other methods in this class. """ if not BMConfigParser().has_section(myAddress): # The address has been deleted. @@ -530,7 +533,10 @@ class singleWorker(StoppableThread): queues.invQueue.put((streamNumber, inventoryHash)) def sendBroadcast(self): - """Send a broadcast-type object (assemble the object, perform PoW and put it to the inv announcement queue)""" + """ + Send a broadcast-type object (assemble the object, perform PoW + and put it to the inv announcement queue) + """ # Reset just in case sqlExecute( '''UPDATE sent SET status='broadcastqueued' ''' @@ -562,8 +568,7 @@ class singleWorker(StoppableThread): self.logger.warning("Section or Option did not found: %s", err) queues.UISignalQueue.put(( 'updateSentItemStatusByAckdata', ( - ackdata, - tr._translate( + ackdata, _translate( "MainWindow", "Error! Could not find sender address" " (your address) in the keys.dat file.")) @@ -577,7 +582,7 @@ class singleWorker(StoppableThread): queues.UISignalQueue.put(( 'updateSentItemStatusByAckdata', ( ackdata, - tr._translate( + _translate( "MainWindow", "Error, can't send.")) )) @@ -666,8 +671,7 @@ class singleWorker(StoppableThread): queues.UISignalQueue.put(( 'updateSentItemStatusByAckdata', ( - ackdata, - tr._translate( + ackdata, _translate( "MainWindow", "Doing work necessary to send broadcast...")) )) @@ -699,11 +703,9 @@ class singleWorker(StoppableThread): queues.UISignalQueue.put(( 'updateSentItemStatusByAckdata', ( - ackdata, - tr._translate( - "MainWindow", - "Broadcast sent on %1" - ).arg(l10n.formatTimestamp())) + ackdata, _translate( + "MainWindow", "Broadcast sent on {0}" + ).format(l10n.formatTimestamp())) )) # Update the status of the message in the 'sent' table to have @@ -715,7 +717,10 @@ class singleWorker(StoppableThread): ) def sendMsg(self): - """Send a message-type object (assemble the object, perform PoW and put it to the inv announcement queue)""" + """ + Send a message-type object (assemble the object, perform PoW + and put it to the inv announcement queue) + """ # pylint: disable=too-many-nested-blocks # Reset just in case sqlExecute( @@ -811,8 +816,7 @@ class singleWorker(StoppableThread): ) queues.UISignalQueue.put(( 'updateSentItemStatusByToAddress', ( - toaddress, - tr._translate( + toaddress, _translate( "MainWindow", "Encryption key was requested earlier.")) )) @@ -884,8 +888,7 @@ class singleWorker(StoppableThread): ) queues.UISignalQueue.put(( 'updateSentItemStatusByToAddress', ( - toaddress, - tr._translate( + toaddress, _translate( "MainWindow", "Sending a request for the" " recipient\'s encryption key.")) @@ -909,8 +912,7 @@ class singleWorker(StoppableThread): state.ackdataForWhichImWatching[ackdata] = 0 queues.UISignalQueue.put(( 'updateSentItemStatusByAckdata', ( - ackdata, - tr._translate( + ackdata, _translate( "MainWindow", "Looking up the receiver\'s public key")) )) @@ -967,15 +969,14 @@ class singleWorker(StoppableThread): ) queues.UISignalQueue.put(( 'updateSentItemStatusByAckdata', ( - ackdata, - tr._translate( + ackdata, _translate( "MainWindow", "Problem: Destination is a mobile" " device who requests that the" " destination be included in the" " message but this is disallowed in" - " your settings. %1" - ).arg(l10n.formatTimestamp())) + " your settings. {0}" + ).format(l10n.formatTimestamp())) )) # if the human changes their setting and then # sends another message or restarts their client, @@ -998,8 +999,7 @@ class singleWorker(StoppableThread): defaults.networkDefaultPayloadLengthExtraBytes queues.UISignalQueue.put(( 'updateSentItemStatusByAckdata', ( - ackdata, - tr._translate( + ackdata, _translate( "MainWindow", "Doing work necessary to send message.\n" "There is no required difficulty for" @@ -1031,32 +1031,19 @@ class singleWorker(StoppableThread): requiredAverageProofOfWorkNonceTrialsPerByte, requiredPayloadLengthExtraBytes ) - - queues.UISignalQueue.put( - ( - 'updateSentItemStatusByAckdata', - ( - ackdata, - tr._translate( - "MainWindow", - "Doing work necessary to send message.\n" - "Receiver\'s required difficulty: %1" - " and %2" - ).arg( - str( - float(requiredAverageProofOfWorkNonceTrialsPerByte) - / defaults.networkDefaultProofOfWorkNonceTrialsPerByte - ) - ).arg( - str( - float(requiredPayloadLengthExtraBytes) - / defaults.networkDefaultPayloadLengthExtraBytes - ) - ) - ) - ) - ) - + queues.UISignalQueue.put(( + 'updateSentItemStatusByAckdata', ( + ackdata, _translate( + "MainWindow", + "Doing work necessary to send message.\n" + "Receiver\'s required difficulty: {0} and {1}" + ).format( + float(requiredAverageProofOfWorkNonceTrialsPerByte) + / defaults.networkDefaultProofOfWorkNonceTrialsPerByte, + float(requiredPayloadLengthExtraBytes) + / defaults.networkDefaultPayloadLengthExtraBytes + )) + )) if status != 'forcepow': maxacceptablenoncetrialsperbyte = BMConfigParser().getint( 'bitmessagesettings', 'maxacceptablenoncetrialsperbyte') @@ -1076,18 +1063,19 @@ class singleWorker(StoppableThread): ackdata) queues.UISignalQueue.put(( 'updateSentItemStatusByAckdata', ( - ackdata, - tr._translate( + ackdata, _translate( "MainWindow", - "Problem: The work demanded by" - " the recipient (%1 and %2) is" - " more difficult than you are" - " willing to do. %3" - ).arg(str(float(requiredAverageProofOfWorkNonceTrialsPerByte) - / defaults.networkDefaultProofOfWorkNonceTrialsPerByte) - ).arg(str(float(requiredPayloadLengthExtraBytes) - / defaults.networkDefaultPayloadLengthExtraBytes) - ).arg(l10n.formatTimestamp())))) + "Problem: The work demanded by the" + " recipient ({0} and {1}) is more" + " difficult than you are willing" + " to do. {2}" + ).format( + float(requiredAverageProofOfWorkNonceTrialsPerByte) + / defaults.networkDefaultProofOfWorkNonceTrialsPerByte, + float(requiredPayloadLengthExtraBytes) + / defaults.networkDefaultPayloadLengthExtraBytes, + l10n.formatTimestamp())) + )) continue else: # if we are sending a message to ourselves or a chan.. self.logger.info('Sending a message.') @@ -1101,15 +1089,14 @@ class singleWorker(StoppableThread): except (configparser.NoSectionError, configparser.NoOptionError) as err: queues.UISignalQueue.put(( 'updateSentItemStatusByAckdata', ( - ackdata, - tr._translate( + ackdata, _translate( "MainWindow", "Problem: You are trying to send a" " message to yourself or a chan but your" " encryption key could not be found in" " the keys.dat file. Could not encrypt" - " message. %1" - ).arg(l10n.formatTimestamp())) + " message. {0}" + ).format(l10n.formatTimestamp())) )) self.logger.error( 'Error within sendMsg. Could not read the keys' @@ -1126,8 +1113,7 @@ class singleWorker(StoppableThread): defaults.networkDefaultPayloadLengthExtraBytes queues.UISignalQueue.put(( 'updateSentItemStatusByAckdata', ( - ackdata, - tr._translate( + ackdata, _translate( "MainWindow", "Doing work necessary to send message.")) )) @@ -1150,8 +1136,7 @@ class singleWorker(StoppableThread): self.logger.warning("Section or Option did not found: %s", err) queues.UISignalQueue.put(( 'updateSentItemStatusByAckdata', ( - ackdata, - tr._translate( + ackdata, _translate( "MainWindow", "Error! Could not find sender address" " (your address) in the keys.dat file.")) @@ -1165,7 +1150,7 @@ class singleWorker(StoppableThread): queues.UISignalQueue.put(( 'updateSentItemStatusByAckdata', ( ackdata, - tr._translate( + _translate( "MainWindow", "Error, can't send.")) )) @@ -1217,8 +1202,7 @@ class singleWorker(StoppableThread): # The fullAckPayload is a normal msg protocol message # with the proof of work already completed that the # receiver of this message can easily send out. - fullAckPayload = self.generateFullAckMessage( - ackdata, toStreamNumber, TTL) + fullAckPayload = self.generateFullAckMessage(ackdata, TTL) payload += encodeVarint(len(fullAckPayload)) payload += fullAckPayload dataToSign = pack('>Q', embeddedTime) + '\x00\x00\x00\x02' + \ @@ -1240,12 +1224,11 @@ class singleWorker(StoppableThread): ) queues.UISignalQueue.put(( 'updateSentItemStatusByAckdata', ( - ackdata, - tr._translate( + ackdata, _translate( "MainWindow", "Problem: The recipient\'s encryption key is" - " no good. Could not encrypt message. %1" - ).arg(l10n.formatTimestamp())) + " no good. Could not encrypt message. {0}" + ).format(l10n.formatTimestamp())) )) continue @@ -1309,21 +1292,19 @@ class singleWorker(StoppableThread): not protocol.checkBitfield(behaviorBitfield, protocol.BITFIELD_DOESACK): queues.UISignalQueue.put(( 'updateSentItemStatusByAckdata', ( - ackdata, - tr._translate( - "MainWindow", - "Message sent. Sent at %1" - ).arg(l10n.formatTimestamp())))) + ackdata, _translate( + "MainWindow", "Message sent. Sent at {0}" + ).format(l10n.formatTimestamp())) + )) else: # not sending to a chan or one of my addresses queues.UISignalQueue.put(( 'updateSentItemStatusByAckdata', ( - ackdata, - tr._translate( + ackdata, _translate( "MainWindow", "Message sent. Waiting for acknowledgement." - " Sent on %1" - ).arg(l10n.formatTimestamp())) + " Sent on {0}" + ).format(l10n.formatTimestamp())) )) self.logger.info( 'Broadcasting inv for my msg(within sendmsg function): %s', @@ -1451,8 +1432,7 @@ class singleWorker(StoppableThread): queues.UISignalQueue.put(('updateStatusBar', statusbar)) queues.UISignalQueue.put(( 'updateSentItemStatusByToAddress', ( - toAddress, - tr._translate( + toAddress, _translate( "MainWindow", "Doing work necessary to request encryption key.")) )) @@ -1476,30 +1456,31 @@ class singleWorker(StoppableThread): int(time.time()), retryNumber + 1, sleeptill, toAddress) queues.UISignalQueue.put(( - 'updateStatusBar', - tr._translate( + 'updateStatusBar', _translate( "MainWindow", "Broadcasting the public key request. This program will" " auto-retry if they are offline.") )) queues.UISignalQueue.put(( 'updateSentItemStatusByToAddress', ( - toAddress, - tr._translate( + toAddress, _translate( "MainWindow", "Sending public key request. Waiting for reply." - " Requested at %1" - ).arg(l10n.formatTimestamp())) + " Requested at {0}" + ).format(l10n.formatTimestamp())) )) - def generateFullAckMessage(self, ackdata, _, TTL): - """ - It might be perfectly fine to just use the same TTL for the ackdata that we use for the message. But I would - rather it be more difficult for attackers to associate ackData with the associated msg object. However, users - would want the TTL of the acknowledgement to be about the same as they set for the message itself. So let's set - the TTL of the acknowledgement to be in one of three 'buckets': 1 hour, 7 days, or 28 days, whichever is - relatively close to what the user specified. - """ + def generateFullAckMessage(self, ackdata, TTL): + """Create ACK packet""" + # It might be perfectly fine to just use the same TTL for + # the ackdata that we use for the message. But I would rather + # it be more difficult for attackers to associate ackData with + # the associated msg object. However, users would want the TTL + # of the acknowledgement to be about the same as they set + # for the message itself. So let's set the TTL of the + # acknowledgement to be in one of three 'buckets': 1 hour, 7 + # days, or 28 days, whichever is relatively close to what the + # user specified. if TTL < 24 * 60 * 60: # 1 day TTL = 24 * 60 * 60 # 1 day elif TTL < 7 * 24 * 60 * 60: # 1 week diff --git a/src/namecoin.py b/src/namecoin.py index 33d39070..d1205261 100644 --- a/src/namecoin.py +++ b/src/namecoin.py @@ -1,7 +1,7 @@ """ Namecoin queries """ -# pylint: disable=too-many-branches,protected-access +# pylint: disable=too-many-branches import base64 import httplib @@ -14,14 +14,14 @@ import defaults from addresses import decodeAddress from bmconfigparser import BMConfigParser from debug import logger -from tr import _translate # translate +from tr import _translate + configSection = "bitmessagesettings" class RPCError(Exception): """Error thrown when the RPC call returns an error.""" - error = None def __init__(self, data): @@ -29,7 +29,7 @@ class RPCError(Exception): self.error = data def __str__(self): - return "{0}: {1}".format(type(self).__name__, self.error) + return '{0}: {1}'.format(type(self).__name__, self.error) class namecoinConnection(object): @@ -46,20 +46,18 @@ class namecoinConnection(object): 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 + 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: self.nmctype = BMConfigParser().get( configSection, "namecoinrpctype") - self.host = BMConfigParser().get( - configSection, "namecoinrpchost") + self.host = BMConfigParser().get(configSection, "namecoinrpchost") self.port = int(BMConfigParser().get( configSection, "namecoinrpcport")) - self.user = BMConfigParser().get( - configSection, "namecoinrpcuser") + self.user = BMConfigParser().get(configSection, "namecoinrpcuser") self.password = BMConfigParser().get( configSection, "namecoinrpcpassword") else: @@ -69,14 +67,14 @@ class namecoinConnection(object): self.user = options["user"] self.password = options["password"] - assert self.nmctype == "namecoind" or self.nmctype == "nmcontrol" + assert self.nmctype in ("namecoind", "nmcontrol") if self.nmctype == "namecoind": self.con = httplib.HTTPConnection(self.host, self.port, timeout=3) def query(self, identity): """ Query for the bitmessage address corresponding to the given identity - string. If it doesn't contain a slash, id/ is prepended. We return + 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. """ @@ -96,8 +94,8 @@ class namecoinConnection(object): res = res["reply"] if not res: return (_translate( - "MainWindow", "The name %1 was not found." - ).arg(identity.decode("utf-8", "ignore")), None) + "MainWindow", "The name {0} was not found." + ).format(identity.decode('utf-8', 'ignore')), None) else: assert False except RPCError as exc: @@ -107,12 +105,12 @@ class namecoinConnection(object): else: errmsg = exc.error return (_translate( - "MainWindow", "The namecoin query failed (%1)" - ).arg(errmsg.decode("utf-8", "ignore")), None) + "MainWindow", "The namecoin query failed ({0})" + ).format(errmsg.decode('utf-8', 'ignore')), None) except AssertionError: return (_translate( - "MainWindow", "Unknown namecoin interface type: %1" - ).arg(self.nmctype.decode("utf-8", "ignore")), None) + "MainWindow", "Unknown namecoin interface type: {0}" + ).format(self.nmctype.decode('utf-8', 'ignore')), None) except Exception: logger.exception("Namecoin query exception") return (_translate( @@ -135,12 +133,12 @@ class namecoinConnection(object): ) if valid else ( _translate( "MainWindow", - "The name %1 has no associated Bitmessage address." - ).arg(identity.decode("utf-8", "ignore")), None) + "The name {0} has no associated Bitmessage address." + ).format(identity.decode('utf-8', 'ignore')), None) def test(self): """ - Test the connection settings. This routine tries to query a "getinfo" + 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. """ @@ -160,44 +158,36 @@ class namecoinConnection(object): versStr = "0.%d.%d" % (v1, v2) else: versStr = "0.%d.%d.%d" % (v1, v2, v3) - message = ( - "success", - _translate( + return ( + 'success', _translate( "MainWindow", - "Success! Namecoind version %1 running.").arg( - versStr.decode("utf-8", "ignore"))) + "Success! Namecoind version {0} running." + ).format(versStr.decode('utf-8', 'ignore')) + ) elif self.nmctype == "nmcontrol": res = self.callRPC("data", ["status"]) prefix = "Plugin data running" if ("reply" in res) and res["reply"][:len(prefix)] == prefix: return ( - "success", - _translate( + 'success', _translate( "MainWindow", - "Success! NMControll is up and running." - ) + "Success! NMControll is up and running.") ) logger.error("Unexpected nmcontrol reply: %s", res) - message = ( - "failed", - _translate( - "MainWindow", - "Couldn\'t understand NMControl." - ) + return ( + 'failed', _translate( + "MainWindow", "Couldn\'t understand NMControl.") ) else: sys.exit("Unsupported Namecoin type") - return message - except Exception: logger.info("Namecoin connection test failure") return ( - "failed", - _translate( + 'failed', _translate( "MainWindow", "The connection to namecoin failed.") ) @@ -245,26 +235,24 @@ class namecoinConnection(object): "Authorization", "Basic %s" % base64.b64encode(authstr)) self.con.endheaders() self.con.send(data) + try: + resp = self.con.getresponse() + result = resp.read() + if resp.status != 200: + raise Exception( + "Namecoin returned status %i: %s" % + (resp.status, resp.reason)) + except: # noqa:E722 + logger.info("HTTP receive error") except: # noqa:E722 logger.info("HTTP connection error") - return None - - try: - resp = self.con.getresponse() - result = resp.read() - if resp.status != 200: - raise Exception( - "Namecoin returned status" - " %i: %s" % (resp.status, resp.reason)) - except: # noqa:E722 - logger.info("HTTP receive error") - return None return result def queryServer(self, data): - """Helper routine sending data to the RPC " - "server and returning the result.""" + """ + Helper routine sending data to the RPC server and returning the result. + """ try: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) @@ -296,23 +284,24 @@ def lookupNamecoinFolder(): """ app = "namecoin" - from os import path, environ + if sys.platform == "darwin": - if "HOME" in environ: - dataFolder = path.join(os.environ["HOME"], - "Library/Application Support/", app) + "/" - else: + try: + dataFolder = os.path.join( + os.getenv("HOME"), "Library/Application Support/", app) + except TypeError: # getenv is None sys.exit( "Could not find home folder, please report this message" " and your OS X version to the BitMessage Github." - ) + ) # TODO: remove exits from utility modules - elif "win32" in sys.platform or "win64" in sys.platform: - dataFolder = path.join(environ["APPDATA"], app) + "\\" - else: - dataFolder = path.join(environ["HOME"], ".%s" % app) + "/" + dataFolder = ( + os.path.join(os.getenv("APPDATA"), app) + if sys.platform.startswith('win') else + os.path.join(os.getenv("HOME"), ".%s" % app) + ) - return dataFolder + return dataFolder + os.path.sep def ensureNamecoinOptions(): @@ -357,8 +346,8 @@ def ensureNamecoinOptions(): nmc.close() except IOError: logger.warning( - "%s unreadable or missing, Namecoin support deactivated", - nmcConfig) + "%s unreadable or missing, Namecoin support deactivated", nmcConfig + ) except Exception: logger.warning("Error processing namecoin.conf", exc_info=True) @@ -370,5 +359,5 @@ def ensureNamecoinOptions(): # Set default port now, possibly to found value. if not hasPort: - BMConfigParser().set(configSection, "namecoinrpcport", - defaults.namecoinDefaultRpcPort) + BMConfigParser().set( + configSection, "namecoinrpcport", defaults.namecoinDefaultRpcPort) diff --git a/src/network/tcp.py b/src/network/tcp.py index ff778378..77bb21c3 100644 --- a/src/network/tcp.py +++ b/src/network/tcp.py @@ -138,9 +138,10 @@ class TCPConnection(BMProto, TLSDispatcher): 'updateStatusBar', _translate( "MainWindow", - "The time on your computer, %1, may be wrong. " + "The time on your computer, {0}, may be wrong. " "Please verify your settings." - ).arg(l10n.formatTimestamp()))) + ).format(l10n.formatTimestamp()) + )) def state_connection_fully_established(self): """ diff --git a/src/upnp.py b/src/upnp.py index c6db487b..82608ddd 100644 --- a/src/upnp.py +++ b/src/upnp.py @@ -266,9 +266,12 @@ class uPnPThread(StoppableThread): with knownnodes.knownNodesLock: knownnodes.addKnownNode( 1, self_peer, is_self=True) - queues.UISignalQueue.put(('updateStatusBar', tr._translate( - "MainWindow", 'UPnP port mapping established on port %1' - ).arg(str(self.extPort)))) + queues.UISignalQueue.put(( + 'updateStatusBar', tr._translate( + "MainWindow", + "UPnP port mapping established on port {0}" + ).format(self.extPort) + )) break except socket.timeout: pass -- 2.45.1 From c5de33d6261fb683f0b32f034fbcc01f6b3149fc Mon Sep 17 00:00:00 2001 From: Dmitri Bogomolov <4glitch@gmail.com> Date: Fri, 23 Feb 2018 15:42:50 +0200 Subject: [PATCH 008/105] QComboBox.findData() compatible with pyside --- src/bitmessageqt/support.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/bitmessageqt/support.py b/src/bitmessageqt/support.py index 965303ca..92a5d112 100644 --- a/src/bitmessageqt/support.py +++ b/src/bitmessageqt/support.py @@ -6,8 +6,6 @@ import ssl import sys import time -from qtpy import QtCore - import account import defaults import network.stats @@ -117,9 +115,11 @@ def createSupportMessage(myapp): return myapp.ui.lineEditSubject.setText(SUPPORT_SUBJECT) - addrIndex = myapp.ui.comboBoxSendFrom.findData( - address, QtCore.Qt.UserRole, - QtCore.Qt.MatchFixedString | QtCore.Qt.MatchCaseSensitive) + # addrIndex = myapp.ui.comboBoxSendFrom.findData( + # address, QtCore.Qt.UserRole, + # QtCore.Qt.MatchFixedString | QtCore.Qt.MatchCaseSensitive + # ) + addrIndex = myapp.ui.comboBoxSendFrom.findData(address) if addrIndex == -1: # something is very wrong return myapp.ui.comboBoxSendFrom.setCurrentIndex(addrIndex) -- 2.45.1 From 5f4b67a61ecc02c13e6d2cb11e66f24bd4ecaf0e Mon Sep 17 00:00:00 2001 From: Dmitri Bogomolov <4glitch@gmail.com> Date: Mon, 26 Feb 2018 12:36:00 +0200 Subject: [PATCH 009/105] fromAddress - str, subject - unicode (for simple encoding like for extended) --- src/bitmessageqt/uisignaler.py | 10 ++++++---- src/helper_msgcoding.py | 5 +++-- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/bitmessageqt/uisignaler.py b/src/bitmessageqt/uisignaler.py index 2753121f..7efda169 100644 --- a/src/bitmessageqt/uisignaler.py +++ b/src/bitmessageqt/uisignaler.py @@ -14,8 +14,9 @@ class UISignaler(QtCore.QThread): updateStatusBar = QtCore.Signal(object) updateSentItemStatusByToAddress = QtCore.Signal(object, str) updateSentItemStatusByAckdata = QtCore.Signal(object, str) - displayNewInboxMessage = QtCore.Signal(object, str, str, object, str) - displayNewSentMessage = QtCore.Signal(object, str, str, str, object, str) + displayNewInboxMessage = QtCore.Signal(object, str, object, object, str) + displayNewSentMessage = QtCore.Signal( + object, str, str, object, object, str) updateNetworkStatusTab = QtCore.Signal(bool, bool, Peer) updateNumberOfMessagesProcessed = QtCore.Signal() updateNumberOfPubkeysProcessed = QtCore.Signal() @@ -54,14 +55,15 @@ class UISignaler(QtCore.QThread): self.updateSentItemStatusByAckdata.emit(ackData, message) elif command == 'displayNewInboxMessage': inventoryHash, toAddress, fromAddress, subject, body = data + self.displayNewInboxMessage.emit( inventoryHash, toAddress, fromAddress, - unicode(subject, 'utf-8'), body) + subject, body) elif command == 'displayNewSentMessage': toAddress, fromLabel, fromAddress, subject, message, ackdata = data self.displayNewSentMessage.emit( toAddress, fromLabel, fromAddress, - unicode(subject, 'utf-8'), message, ackdata) + subject.decode('utf-8'), message, ackdata) elif command == 'updateNetworkStatusTab': outbound, add, destination = data self.updateNetworkStatusTab.emit(outbound, add, destination) diff --git a/src/helper_msgcoding.py b/src/helper_msgcoding.py index 28f92288..76447884 100644 --- a/src/helper_msgcoding.py +++ b/src/helper_msgcoding.py @@ -155,5 +155,6 @@ class MsgDecode(object): # Throw away any extra lines (headers) after the subject. if subject: subject = subject.splitlines()[0] - self.subject = subject - self.body = body + # Field types should be the same for all message types + self.subject = subject.decode('utf-8', 'replace') + self.body = body.decode('utf-8', 'replace') -- 2.45.1 From acaa2743ef6a5b2e4e47063ab9593f1c3cc3c097 Mon Sep 17 00:00:00 2001 From: Dmitri Bogomolov <4glitch@gmail.com> Date: Thu, 1 Mar 2018 17:40:13 +0200 Subject: [PATCH 010/105] QWheelEvent.orientation() is obsolete, used angleDelta() instead --- src/bitmessageqt/messagecompose.py | 2 +- src/bitmessageqt/messageview.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/bitmessageqt/messagecompose.py b/src/bitmessageqt/messagecompose.py index 0114400d..c520030b 100644 --- a/src/bitmessageqt/messagecompose.py +++ b/src/bitmessageqt/messagecompose.py @@ -17,7 +17,7 @@ class MessageCompose(QtWidgets.QTextEdit): if ( (QtWidgets.QApplication.queryKeyboardModifiers() & QtCore.Qt.ControlModifier) == QtCore.Qt.ControlModifier - and event.orientation() == QtCore.Qt.Vertical + and event.angleDelta().y() != 0 ): if event.delta() > 0: self.zoomIn(1) diff --git a/src/bitmessageqt/messageview.py b/src/bitmessageqt/messageview.py index abd15785..364a92c2 100644 --- a/src/bitmessageqt/messageview.py +++ b/src/bitmessageqt/messageview.py @@ -56,7 +56,7 @@ class MessageView(QtWidgets.QTextBrowser): if ( (QtWidgets.QApplication.queryKeyboardModifiers() & QtCore.Qt.ControlModifier) == QtCore.Qt.ControlModifier - and event.orientation() == QtCore.Qt.Vertical + and event.angleDelta().y() != 0 ): zoom = self.currentFont().pointSize() * 100 / self.defaultFontPointSize QtWidgets.QApplication.activeWindow().statusbar.showMessage( -- 2.45.1 From c39c7d139753a19f38990648c1aabe0e608ebe89 Mon Sep 17 00:00:00 2001 From: Dmitri Bogomolov <4glitch@gmail.com> Date: Wed, 27 Jun 2018 17:44:55 +0300 Subject: [PATCH 011/105] Changed check_pyqt() to work with qtpy (closes #897, closes #1418) --- src/depends.py | 45 ++++++++++++++++++++++----------------------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/src/depends.py b/src/depends.py index 23da7d92..3a48ae63 100755 --- a/src/depends.py +++ b/src/depends.py @@ -18,7 +18,7 @@ if not hasattr(sys, 'hexversion') or sys.hexversion < 0x20300F0: import logging # noqa:E402 import subprocess - +from distutils import version from importlib import import_module # We can now use logging so set up a simple configuration @@ -53,23 +53,22 @@ PACKAGE_MANAGER = { } PACKAGES = { - "PyQt4": { - "OpenBSD": "py-qt4", - "FreeBSD": "py27-qt4", - "Debian": "python-qt4", - "Ubuntu": "python-qt4", - "Ubuntu 12": "python-qt4", - "Ubuntu 20": "", - "openSUSE": "python-qt", - "Fedora": "PyQt4", - "Guix": "python2-pyqt@4.11.4", - "Gentoo": "dev-python/PyQt4", + "qtpy": { + "OpenBSD": "py-qtpy", + "FreeBSD": "py27-QtPy", + "Debian": "python-qtpy", + "Ubuntu": "python-qtpy", + "Ubuntu 12": "python-qtpy", + "openSUSE": "python-QtPy", + "Fedora": "python2-QtPy", + "Guix": "", + "Gentoo": "dev-python/QtPy", "optional": True, "description": - "You only need PyQt if you want to use the GUI." + "You only need qtpy if you want to use the GUI." " When only running as a daemon, this can be skipped.\n" - "However, you would have to install it manually" - " because setuptools does not support PyQt." + "Also maybe you need to install PyQt5 if your package manager" + " not installs it as qtpy dependency" }, "msgpack": { "OpenBSD": "py-msgpack", @@ -383,21 +382,21 @@ def check_pyqt(): Here we are checking for PyQt4 with its version, as for it require PyQt 4.8 or later. """ - QtCore = try_import( - 'qtpy.QtCore', 'PyBitmessage requires PyQt 4.8 or later and Qt 4.7 or later.') + qtpy = try_import( + 'qtpy', 'PyBitmessage requires qtpy, PyQt 4.8 or later and Qt 4.7 or later.') - if not QtCore: + if not qtpy: return False - logger.info('PyQt Version: %s', QtCore.PYQT_VERSION_STR) - logger.info('Qt Version: %s', QtCore.QT_VERSION_STR) + logger.info('PyQt Version: %s', qtpy.PYQT_VERSION) + logger.info('Qt Version: %s', qtpy.QT_VERSION) passed = True - if QtCore.PYQT_VERSION < 0x40800: + if version.LooseVersion(qtpy.PYQT_VERSION) < '4.8': logger.error( 'This version of PyQt is too old. PyBitmessage requries' ' PyQt 4.8 or later.') passed = False - if QtCore.QT_VERSION < 0x40700: + if version.LooseVersion(qtpy.QT_VERSION) < '4.7': logger.error( 'This version of Qt is too old. PyBitmessage requries' ' Qt 4.7 or later.') @@ -406,7 +405,7 @@ def check_pyqt(): def check_msgpack(): - """Do sgpack module check. + """Do msgpack module check. simply checking if msgpack package with all its dependency is available or not as recommended for messages coding. -- 2.45.1 From bc8900003526229d70346fb183f508247b795bbc Mon Sep 17 00:00:00 2001 From: Dmitri Bogomolov <4glitch@gmail.com> Date: Fri, 16 Nov 2018 18:44:21 +0200 Subject: [PATCH 012/105] Handled pylint warnings in bitmessageqt, qidenticon, depends, resolved pylint redefined-variable-type warnings, marked autogenerated modules for skipping by pylint and flake8 --- src/bitmessageqt/__init__.py | 81 +++++++++++++++-------------- src/bitmessageqt/address_dialogs.py | 4 +- src/bitmessageqt/bitmessageui.py | 3 ++ src/depends.py | 10 ++-- 4 files changed, 55 insertions(+), 43 deletions(-) diff --git a/src/bitmessageqt/__init__.py b/src/bitmessageqt/__init__.py index d25f2f14..eddebeec 100644 --- a/src/bitmessageqt/__init__.py +++ b/src/bitmessageqt/__init__.py @@ -1580,7 +1580,13 @@ class MyForm(settingsmixin.SMainWindow): # menu button 'delete all treshed messages' def click_actionDeleteAllTrashedMessages(self): - if QtWidgets.QMessageBox.question(self, _translate("MainWindow", "Delete trash?"), _translate("MainWindow", "Are you sure you want to delete all trashed messages?"), QtWidgets.QMessageBox.Yes, QtWidgets.QMessageBox.No) == QtWidgets.QMessageBox.No: + if QtWidgets.QMessageBox.question( + self, _translate("MainWindow", "Delete trash?"), + _translate( + "MainWindow", + "Are you sure you want to delete all trashed messages?" + ), QtWidgets.QMessageBox.Yes, QtWidgets.QMessageBox.No + ) == QtWidgets.QMessageBox.No: return sqlStoredProcedure('deleteandvacuume') self.rerenderTabTreeMessages() @@ -2073,22 +2079,22 @@ class MyForm(settingsmixin.SMainWindow): toAddress = acct.toAddress else: if QtWidgets.QMessageBox.question( - self, "Sending an email?", - _translate( - "MainWindow", - "You are trying to send an email" - " instead of a bitmessage. This" - " requires registering with a" - " gateway. Attempt to register?" - ), QtWidgets.QMessageBox.Yes - | QtWidgets.QMessageBox.No + self, "Sending an email?", + _translate( + "MainWindow", + "You are trying to send an email" + " instead of a bitmessage. This" + " requires registering with a" + " gateway. Attempt to register?" + ), QtWidgets.QMessageBox.Yes + | QtWidgets.QMessageBox.No ) != QtWidgets.QMessageBox.Yes: continue email = acct.getLabel() # attempt register if email[-14:] != "@mailchuck.com": # 12 character random email address - email = ''.join( + email = u''.join( random.SystemRandom().choice( string.ascii_lowercase ) for _ in range(12) @@ -2110,33 +2116,33 @@ class MyForm(settingsmixin.SMainWindow): decodeAddress(toAddress)[:3] if status != 'success': try: - toAddress = unicode(toAddress, 'utf-8', 'ignore') + toAddress_value = unicode( + toAddress, 'utf-8', 'ignore') except: logger.warning( - "Failed unicode(toAddress ):", - exc_info=True) + "Failed unicode(toAddress ):", exc_info=True) logger.error( 'Error: Could not decode recipient address %s: %s', - toAddress, status) + toAddress_value, status) if status == 'missingbm': self.updateStatusBar(_translate( "MainWindow", "Error: Bitmessage addresses start with" " BM- Please check the recipient address {0}" - ).format(toAddress)) + ).format(toAddress_value)) elif status == 'checksumfailed': self.updateStatusBar(_translate( "MainWindow", "Error: The recipient address {0} is not" " typed or copied correctly. Please check it." - ).format(toAddress)) + ).format(toAddress_value)) elif status == 'invalidcharacters': self.updateStatusBar(_translate( "MainWindow", "Error: The recipient address {0} contains" " invalid characters. Please check it." - ).format(toAddress)) + ).format(toAddress_value)) elif status == 'versiontoohigh': self.updateStatusBar(_translate( "MainWindow", @@ -2144,7 +2150,7 @@ class MyForm(settingsmixin.SMainWindow): " {0} is too high. Either you need to upgrade" " your Bitmessage software or your" " acquaintance is being clever." - ).format(toAddress)) + ).format(toAddress_value)) elif status == 'ripetooshort': self.updateStatusBar(_translate( "MainWindow", @@ -2152,7 +2158,7 @@ class MyForm(settingsmixin.SMainWindow): " address {0} is too short. There might be" " something wrong with the software of" " your acquaintance." - ).format(toAddress)) + ).format(toAddress_value)) elif status == 'ripetoolong': self.updateStatusBar(_translate( "MainWindow", @@ -2160,7 +2166,7 @@ class MyForm(settingsmixin.SMainWindow): " address {0} is too long. There might be" " something wrong with the software of" " your acquaintance." - ).format(toAddress)) + ).format(toAddress_value)) elif status == 'varintmalformed': self.updateStatusBar(_translate( "MainWindow", @@ -2168,13 +2174,13 @@ class MyForm(settingsmixin.SMainWindow): " address {0} is malformed. There might be" " something wrong with the software of" " your acquaintance." - ).format(toAddress)) + ).format(toAddress_value)) else: self.updateStatusBar(_translate( "MainWindow", "Error: Something is wrong with the" " recipient address {0}." - ).format(toAddress)) + ).format(toAddress_value)) elif fromAddress == '': self.updateStatusBar(_translate( "MainWindow", @@ -2480,7 +2486,7 @@ class MyForm(settingsmixin.SMainWindow): dialog.exec_() try: address, label = dialog.data - except AttributeError: + except (AttributeError, TypeError): return # First we must check to see if the address is already in the @@ -2525,7 +2531,7 @@ class MyForm(settingsmixin.SMainWindow): dialog.exec_() try: address, label = dialog.data - except AttributeError: + except (AttributeError, TypeError): return # We must check to see if the address is already in the @@ -2584,9 +2590,8 @@ class MyForm(settingsmixin.SMainWindow): dialog = dialogs.EmailGatewayDialog(self, config=BMConfigParser()) # For Modal dialogs dialog.exec_() - try: - acct = dialog.data - except AttributeError: + acct = dialog.data + if not acct: return # Only settings remain here @@ -3241,10 +3246,9 @@ class MyForm(settingsmixin.SMainWindow): defaultFilename = "".join( x for x in subjectAtCurrentInboxRow if x.isalnum()) + '.txt' - filename, filetype = QtWidgets.QFileDialog.getSaveFileName( + filename = QtWidgets.QFileDialog.getSaveFileName( self, _translate("MainWindow", "Save As..."), defaultFilename, - "Text files (*.txt);;All files (*.*)" - ) + "Text files (*.txt);;All files (*.*)")[0] if not filename: return try: @@ -3704,8 +3708,8 @@ class MyForm(settingsmixin.SMainWindow): account = accountClass(myAddress) if isinstance(account, GatewayAccount) \ and otherAddress == account.relayAddress and ( - (currentColumn in (0, 2) and currentFolder == "sent") - or (currentColumn in (1, 2) and currentFolder != "sent")): + (currentColumn in (0, 2) and currentFolder == "sent") or + (currentColumn in (1, 2) and currentFolder != "sent")): text = tableWidget.item(currentRow, currentColumn).label else: text = tableWidget.item(currentRow, currentColumn).data(QtCore.Qt.UserRole) @@ -3766,10 +3770,9 @@ class MyForm(settingsmixin.SMainWindow): current_files += [upper] filters[0:0] = ['Image files (' + ' '.join(all_images_filter) + ')'] filters[1:1] = ['All files (*.*)'] - sourcefile, filetype = QtWidgets.QFileDialog.getOpenFileName( + sourcefile = QtWidgets.QFileDialog.getOpenFileName( self, _translate("MainWindow", "Set avatar..."), - filter=';;'.join(filters) - ) + filter=';;'.join(filters))[0] # determine the correct filename (note that avatars don't use the suffix) destination = state.appdata + 'avatars/' + hash + '.' + sourcefile.split('.')[-1] exists = QtCore.QFile.exists(destination) @@ -3830,10 +3833,10 @@ class MyForm(settingsmixin.SMainWindow): "MainWindow", "Sound files (%s)" % ' '.join(['*%s%s' % (os.extsep, ext) for ext in sound.extensions]) ))] - sourcefile, filetype = QtWidgets.QFileDialog.getOpenFileName( + sourcefile = QtWidgets.QFileDialog.getOpenFileName( self, _translate("MainWindow", "Set notification sound..."), filter=';;'.join(filters) - ) + )[0] if not sourcefile: return @@ -4097,6 +4100,8 @@ class MyForm(settingsmixin.SMainWindow): except NameError: message = u"" except IndexError: + # _translate() often returns unicode, no redefinition here! + # pylint: disable=redefined-variable-type message = _translate( "MainWindow", "Error occurred: could not load message from disk." diff --git a/src/bitmessageqt/address_dialogs.py b/src/bitmessageqt/address_dialogs.py index 6275859a..92677f09 100644 --- a/src/bitmessageqt/address_dialogs.py +++ b/src/bitmessageqt/address_dialogs.py @@ -91,7 +91,7 @@ class AddressDataDialog(QtWidgets.QDialog, AddressCheckMixin): def __init__(self, parent): super(AddressDataDialog, self).__init__(parent) self.parent = parent - self.data = ("", "") + self.data = None def accept(self): """Callback for QDialog accepting value""" @@ -187,6 +187,7 @@ class NewSubscriptionDialog(AddressDataDialog): def __init__(self, parent=None): super(NewSubscriptionDialog, self).__init__(parent) widgets.load('newsubscriptiondialog.ui', self) + self.recent = [] self._setup() def _onSuccess(self, addressVersion, streamNumber, ripe): @@ -306,6 +307,7 @@ class EmailGatewayDialog(QtWidgets.QDialog): widgets.load('emailgateway.ui', self) self.parent = parent self.config = config + self.data = None if account: self.acct = account self.setWindowTitle(_translate( diff --git a/src/bitmessageqt/bitmessageui.py b/src/bitmessageqt/bitmessageui.py index 3388c1cb..136f4c8a 100644 --- a/src/bitmessageqt/bitmessageui.py +++ b/src/bitmessageqt/bitmessageui.py @@ -1,3 +1,6 @@ +# pylint: skip-file +# flake8: noqa + from PyQt5 import QtCore, QtGui, QtWidgets from tr import _translate from bmconfigparser import BMConfigParser diff --git a/src/depends.py b/src/depends.py index 3a48ae63..9cff1b22 100755 --- a/src/depends.py +++ b/src/depends.py @@ -155,17 +155,17 @@ detectOS.result = None def detectOSRelease(): """Detecting the release of OS""" with open("/etc/os-release", 'r') as osRelease: - version = None + ver = None for line in osRelease: if line.startswith("NAME="): detectOS.result = OS_RELEASE.get( line.replace('"', '').split("=")[-1].strip().lower()) elif line.startswith("VERSION_ID="): try: - version = float(line.split("=")[1].replace("\"", "")) + ver = float(line.split("=")[1].replace("\"", "")) except ValueError: pass - if detectOS.result == "Ubuntu" and version < 14: + if detectOS.result == "Ubuntu" and ver < 14: detectOS.result = "Ubuntu 12" elif detectOS.result == "Ubuntu" and version >= 20: detectOS.result = "Ubuntu 20" @@ -382,8 +382,10 @@ def check_pyqt(): Here we are checking for PyQt4 with its version, as for it require PyQt 4.8 or later. """ + # pylint: disable=no-member qtpy = try_import( - 'qtpy', 'PyBitmessage requires qtpy, PyQt 4.8 or later and Qt 4.7 or later.') + 'qtpy', + 'PyBitmessage requires qtpy, PyQt 4.8 or later and Qt 4.7 or later.') if not qtpy: return False -- 2.45.1 From 6864b4465a85fcaa1fc784461733ae1dd2a5462d Mon Sep 17 00:00:00 2001 From: Dmitri Bogomolov <4glitch@gmail.com> Date: Mon, 11 Feb 2019 18:48:57 +0200 Subject: [PATCH 013/105] PyQt5 based qtpy fallback --- src/bitmessageqt/support.py | 2 +- src/depends.py | 10 +++++++--- src/fallback/__init__.py | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 41 insertions(+), 4 deletions(-) diff --git a/src/bitmessageqt/support.py b/src/bitmessageqt/support.py index 92a5d112..08125446 100644 --- a/src/bitmessageqt/support.py +++ b/src/bitmessageqt/support.py @@ -145,7 +145,7 @@ def createSupportMessage(myapp): opensslversion = "%s (Python internal), %s (external for PyElliptic)" % ( ssl.OPENSSL_VERSION, OpenSSL._version) - qtapi = os.environ['QT_API'] + qtapi = os.environ.get('QT_API', 'fallback') frozen = "N/A" if paths.frozen: diff --git a/src/depends.py b/src/depends.py index 9cff1b22..113c8895 100755 --- a/src/depends.py +++ b/src/depends.py @@ -383,9 +383,13 @@ def check_pyqt(): PyQt 4.8 or later. """ # pylint: disable=no-member - qtpy = try_import( - 'qtpy', - 'PyBitmessage requires qtpy, PyQt 4.8 or later and Qt 4.7 or later.') + try: + from fallback import qtpy + except ImportError: + logger.error( + 'PyBitmessage requires qtpy, PyQt 4.8 or later and Qt 4.7 or later.' + ) + qtpy = None if not qtpy: return False diff --git a/src/fallback/__init__.py b/src/fallback/__init__.py index 9a8d646f..bd1f51b9 100644 --- a/src/fallback/__init__.py +++ b/src/fallback/__init__.py @@ -30,3 +30,36 @@ else: if data: hasher.update(data) return hasher + +try: + import qtpy +except ImportError: + try: + from PyQt5 import QtCore, QtGui, QtWidgets, QtNetwork, uic + except ImportError: + qtpy = None + else: + import sys + import types + + QtCore.Signal = QtCore.pyqtSignal + context = { + 'API': 'pyqt5', # for tr + 'PYQT_VERSION': QtCore.PYQT_VERSION_STR, + 'QT_VERSION': QtCore.QT_VERSION_STR, + 'QtCore': QtCore, + 'QtGui': QtGui, + 'QtWidgets': QtWidgets, + 'QtNetwork': QtNetwork, + 'uic': uic + } + try: + from PyQt5 import QtTest + except ImportError: + pass + else: + context['QtTest'] = QtTest + qtpy = types.ModuleType( + 'qtpy', 'PyQt5 based dynamic fallback for qtpy') + qtpy.__dict__.update(context) + sys.modules['qtpy'] = qtpy -- 2.45.1 From b046898553652d16390518ab7572665165ce59d3 Mon Sep 17 00:00:00 2001 From: Dmitri Bogomolov <4glitch@gmail.com> Date: Fri, 12 Apr 2019 12:33:24 +0300 Subject: [PATCH 014/105] Explicitly set wordWrap property to false in STableWidgets on tabs "Send", "Blacklist" and "Network Status": in qt5 it's probably true by default. --- src/bitmessageqt/bitmessageui.py | 1 + src/bitmessageqt/blacklist.ui | 3 +++ src/bitmessageqt/networkstatus.ui | 3 +++ 3 files changed, 7 insertions(+) diff --git a/src/bitmessageqt/bitmessageui.py b/src/bitmessageqt/bitmessageui.py index 136f4c8a..f7a59459 100644 --- a/src/bitmessageqt/bitmessageui.py +++ b/src/bitmessageqt/bitmessageui.py @@ -164,6 +164,7 @@ class Ui_MainWindow(object): self.tableWidgetAddressBook.horizontalHeader().setHighlightSections(False) self.tableWidgetAddressBook.horizontalHeader().setStretchLastSection(True) self.tableWidgetAddressBook.verticalHeader().setVisible(False) + self.tableWidgetAddressBook.setWordWrap(False) self.verticalSplitter_2.addWidget(self.tableWidgetAddressBook) self.addressBookCompleter = AddressBookCompleter() self.addressBookCompleter.setCompletionMode(QtWidgets.QCompleter.PopupCompletion) diff --git a/src/bitmessageqt/blacklist.ui b/src/bitmessageqt/blacklist.ui index 3068a6ae..0eb347a3 100644 --- a/src/bitmessageqt/blacklist.ui +++ b/src/bitmessageqt/blacklist.ui @@ -62,6 +62,9 @@ true + + false + true diff --git a/src/bitmessageqt/networkstatus.ui b/src/bitmessageqt/networkstatus.ui index 7c40a002..64a3d48d 100644 --- a/src/bitmessageqt/networkstatus.ui +++ b/src/bitmessageqt/networkstatus.ui @@ -100,6 +100,9 @@ true + + false + true -- 2.45.1 From 46d8576a64b2b6c9fa3e77a683a83a4a7d70d9f1 Mon Sep 17 00:00:00 2001 From: Dmitri Bogomolov <4glitch@gmail.com> Date: Wed, 24 Apr 2019 14:40:25 +0300 Subject: [PATCH 015/105] Suppressed pylint relative-import and pycodestyle E402 in depends --- src/depends.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/depends.py b/src/depends.py index 113c8895..f4a5157c 100755 --- a/src/depends.py +++ b/src/depends.py @@ -190,7 +190,7 @@ def try_import(module, log_extra=False): def check_ripemd160(): """Check availability of the RIPEMD160 hash function""" try: - from fallback import RIPEMD160Hash # pylint: disable=relative-import + from fallback import RIPEMD160Hash except ImportError: return False return RIPEMD160Hash is not None -- 2.45.1 From 677c117290ad925086488968653babe9bb91a283 Mon Sep 17 00:00:00 2001 From: Dmitri Bogomolov <4glitch@gmail.com> Date: Tue, 1 Sep 2020 12:31:05 +0300 Subject: [PATCH 016/105] Don't close BitmessageQtApplication.server in __del__() --- src/bitmessageqt/__init__.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/bitmessageqt/__init__.py b/src/bitmessageqt/__init__.py index eddebeec..a175402d 100644 --- a/src/bitmessageqt/__init__.py +++ b/src/bitmessageqt/__init__.py @@ -4244,10 +4244,6 @@ class BitmessageQtApplication(QtWidgets.QApplication): self.setStyleSheet("QStatusBar::item { border: 0px solid black }") - def __del__(self): - if self.server: - self.server.close() - def on_new_connection(self): if myapp: myapp.appIndicatorShow() -- 2.45.1 From 3e3985267a80556082979bbc556e95f60d4b0f6d Mon Sep 17 00:00:00 2001 From: Dmitri Bogomolov <4glitch@gmail.com> Date: Mon, 14 Sep 2020 13:30:11 +0300 Subject: [PATCH 017/105] Removed unused resources in ui-files --- src/bitmessageqt/blacklist.ui | 3 --- src/bitmessageqt/networkstatus.ui | 3 --- src/bitmessageqt/settings.ui | 3 --- 3 files changed, 9 deletions(-) diff --git a/src/bitmessageqt/blacklist.ui b/src/bitmessageqt/blacklist.ui index 0eb347a3..c3b9b5a3 100644 --- a/src/bitmessageqt/blacklist.ui +++ b/src/bitmessageqt/blacklist.ui @@ -104,8 +104,5 @@
bitmessageqt.settingsmixin
- - - diff --git a/src/bitmessageqt/networkstatus.ui b/src/bitmessageqt/networkstatus.ui index 64a3d48d..7830714a 100644 --- a/src/bitmessageqt/networkstatus.ui +++ b/src/bitmessageqt/networkstatus.ui @@ -299,8 +299,5 @@
bitmessageqt.settingsmixin
- - - diff --git a/src/bitmessageqt/settings.ui b/src/bitmessageqt/settings.ui index 1e9a6f09..7ce1e389 100644 --- a/src/bitmessageqt/settings.ui +++ b/src/bitmessageqt/settings.ui @@ -1086,9 +1086,6 @@ checkBoxSocksListen buttonBox - - - buttonBox -- 2.45.1 From 782010fc1927d18dfb6726f3fe01328fe2c543f9 Mon Sep 17 00:00:00 2001 From: Dmitri Bogomolov <4glitch@gmail.com> Date: Tue, 20 Oct 2020 14:42:58 +0300 Subject: [PATCH 018/105] Changes for PyInstaller to build with qtpy and PyQt4 --- packages/pyinstaller/bitmessagemain.spec | 18 +++++++++++++----- .../hooks/pyinstaller_rthook_pyqt4.py | 10 ++++++++++ 2 files changed, 23 insertions(+), 5 deletions(-) create mode 100644 packages/pyinstaller/hooks/pyinstaller_rthook_pyqt4.py diff --git a/packages/pyinstaller/bitmessagemain.spec b/packages/pyinstaller/bitmessagemain.spec index d7d4d70d..739d0424 100644 --- a/packages/pyinstaller/bitmessagemain.spec +++ b/packages/pyinstaller/bitmessagemain.spec @@ -37,8 +37,17 @@ a = Analysis( 'setuptools.msvc', '_cffi_backend', 'plugins.menu_qrcode', 'plugins.proxyconfig_stem' ], - runtime_hooks=[os.path.join(hookspath, 'pyinstaller_rthook_plugins.py')], - excludes=['bsddb', 'bz2', 'tcl', 'tk', 'Tkinter', 'tests'] + # https://github.com/pyinstaller/pyinstaller/wiki/Recipe-PyQt4-API-Version + runtime_hooks=[ + os.path.join(hookspath, hook) for hook in ( + 'pyinstaller_rthook_pyqt4.py', + 'pyinstaller_rthook_plugins.py' + )], + excludes=[ + 'bsddb', 'bz2', + 'PyQt4.QtOpenGL', 'PyQt4.QtOpenGL', 'PyQt4.QtSql', + 'PyQt4.QtSvg', 'PyQt4.QtTest', 'PyQt4.QtWebKit', 'PyQt4.QtXml', + 'tcl', 'tk', 'Tkinter', 'win32ui', 'tests'] ) @@ -77,9 +86,8 @@ a.datas += addTranslations() excluded_binaries = [ - 'QtOpenGL4.dll', - 'QtSvg4.dll', - 'QtXml4.dll', + 'QtOpenGL4.dll', 'QtSql4.dll', 'QtSvg4.dll', 'QtTest4.dll', + 'QtWebKit4.dll', 'QtXml4.dll' ] a.binaries = TOC([x for x in a.binaries if x[0] not in excluded_binaries]) diff --git a/packages/pyinstaller/hooks/pyinstaller_rthook_pyqt4.py b/packages/pyinstaller/hooks/pyinstaller_rthook_pyqt4.py new file mode 100644 index 00000000..b30fb1cc --- /dev/null +++ b/packages/pyinstaller/hooks/pyinstaller_rthook_pyqt4.py @@ -0,0 +1,10 @@ +# https://github.com/pyinstaller/pyinstaller/wiki/Recipe-PyQt4-API-Version +import sip + +sip.setapi(u'QDate', 2) +sip.setapi(u'QDateTime', 2) +sip.setapi(u'QString', 2) +sip.setapi(u'QTextStream', 2) +sip.setapi(u'QTime', 2) +sip.setapi(u'QUrl', 2) +sip.setapi(u'QVariant', 2) -- 2.45.1 From 4480d5d1dd044b8385996c5397058ba682dee4dc Mon Sep 17 00:00:00 2001 From: Dmitri Bogomolov <4glitch@gmail.com> Date: Tue, 20 Oct 2020 14:47:21 +0300 Subject: [PATCH 019/105] winbuild.sh script: additional packages --- buildscripts/winbuild.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/buildscripts/winbuild.sh b/buildscripts/winbuild.sh index 66a2f7aa..e809089a 100755 --- a/buildscripts/winbuild.sh +++ b/buildscripts/winbuild.sh @@ -72,6 +72,8 @@ function install_python(){ wine python -m pip install pytools==2020.2 echo "Upgrading pip" wine python -m pip install --upgrade pip + # install pypiwin32 for win32com + wine python -m pip install pypiwin32 } function install_pyqt(){ @@ -82,6 +84,8 @@ function install_pyqt(){ echo "Installing PyQt-${PYQT_VERSION} 32b" wine PyQt${PYQT_VERSION}-x32.exe /S /WX fi + # and qtpy + wine python -m pip install qtpy } function install_openssl(){ -- 2.45.1 From 229cf1ded90d07ba8438da535cc149a522608be5 Mon Sep 17 00:00:00 2001 From: Dmitri Bogomolov <4glitch@gmail.com> Date: Fri, 19 Feb 2021 22:21:22 +0200 Subject: [PATCH 020/105] Fix tray icon changing upon notification --- src/bitmessageqt/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/bitmessageqt/__init__.py b/src/bitmessageqt/__init__.py index a175402d..1f2266e6 100644 --- a/src/bitmessageqt/__init__.py +++ b/src/bitmessageqt/__init__.py @@ -1413,7 +1413,8 @@ class MyForm(settingsmixin.SMainWindow): def notifierInit(self): def _simple_notify( title, subtitle, category, label=None, icon=None): - self.tray.showMessage(title, subtitle, 1, 2000) + self.tray.showMessage( + title, subtitle, self.tray.NoIcon, msecs=2000) self._notifier = _simple_notify -- 2.45.1 From d75d38852210eb2288c22e989e8d71612141c3c0 Mon Sep 17 00:00:00 2001 From: Dmitri Bogomolov <4glitch@gmail.com> Date: Sat, 27 Feb 2021 22:26:19 +0200 Subject: [PATCH 021/105] Sorted imports in __init__ and removed import from debug --- src/bitmessageqt/__init__.py | 49 +++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 23 deletions(-) diff --git a/src/bitmessageqt/__init__.py b/src/bitmessageqt/__init__.py index 1f2266e6..07862e10 100644 --- a/src/bitmessageqt/__init__.py +++ b/src/bitmessageqt/__init__.py @@ -4,6 +4,7 @@ PyQt based UI for bitmessage, the main module import hashlib import locale +import logging import os import random import string @@ -17,48 +18,50 @@ from sqlite3 import register_adapter from PyQt5 import QtCore, QtGui, QtWidgets, QtNetwork +# This is needed for tray icon +import bitmessage_icons_rc # noqa:F401 pylint: disable=unused-import +import dialogs +import helper_addressbook +import helper_search +import helper_sent +import l10n +import namecoin +import paths +import queues +import settingsmixin import shared +import shutdown +import sound import state -from debug import logger -from tr import _translate +import support +from account import ( + getSortedAccounts, getSortedSubscriptions, accountClass, BMAccount, + GatewayAccount, MailchuckAccount, AccountColor) from addresses import decodeAddress, addBMIfNotPresent from bitmessageui import Ui_MainWindow from bmconfigparser import BMConfigParser -import namecoin -from messageview import MessageView from foldertree import ( AccountMixin, Ui_FolderWidget, Ui_AddressWidget, Ui_SubscriptionWidget, MessageList_AddressWidget, MessageList_SubjectWidget, Ui_AddressBookWidgetItemLabel, Ui_AddressBookWidgetItemAddress, MessageList_TimeWidget) -import settingsmixin -import support -from helper_sql import sqlQuery, sqlExecute, sqlExecuteChunked, sqlStoredProcedure -import helper_addressbook -import helper_search -import l10n -from utils import str_broadcast_subscribers, avatarize -from account import ( - getSortedAccounts, getSortedSubscriptions, accountClass, BMAccount, - GatewayAccount, MailchuckAccount, AccountColor) -import dialogs +from helper_sql import ( + sqlQuery, sqlExecute, sqlExecuteChunked, sqlStoredProcedure) +from messageview import MessageView from network.stats import pendingDownload, pendingUpload -from uisignaler import UISignaler -import paths from proofofwork import getPowType -import queues -import shutdown from statusbar import BMStatusBar -import sound -# This is needed for tray icon -import bitmessage_icons_rc # noqa:F401 pylint: disable=unused-import -import helper_sent +from tr import _translate +from uisignaler import UISignaler +from utils import str_broadcast_subscribers, avatarize try: from plugins.plugin import get_plugin, get_plugins except ImportError: get_plugins = False +logger = logging.getLogger('default') + # TODO: rewrite def powQueueSize(): -- 2.45.1 From caec9434b058f37cd4f8db1d7a456d4bee753579 Mon Sep 17 00:00:00 2001 From: Dmitri Bogomolov <4glitch@gmail.com> Date: Sat, 8 May 2021 20:34:34 +0300 Subject: [PATCH 022/105] Replace unicode() by .decode() in bitmessageqt.foldertree --- src/bitmessageqt/foldertree.py | 47 ++++++++++++---------------------- 1 file changed, 17 insertions(+), 30 deletions(-) diff --git a/src/bitmessageqt/foldertree.py b/src/bitmessageqt/foldertree.py index 208bc2cb..0b64dab4 100644 --- a/src/bitmessageqt/foldertree.py +++ b/src/bitmessageqt/foldertree.py @@ -121,14 +121,12 @@ class AccountMixin(object): def defaultLabel(self): """Default label (in case no label is set manually)""" - queryreturn = None - retval = None + queryreturn = retval = None if self.type in ( AccountMixin.NORMAL, AccountMixin.CHAN, AccountMixin.MAILINGLIST): try: - retval = unicode( - BMConfigParser().get(self.address, 'label'), 'utf-8') + retval = BMConfigParser().get(self.address, 'label') except Exception: queryreturn = sqlQuery( 'SELECT label FROM addressbook WHERE address=?', @@ -139,15 +137,12 @@ class AccountMixin(object): 'SELECT label FROM subscriptions WHERE address=?', self.address ) - if queryreturn is not None: - if queryreturn != []: - for row in queryreturn: - retval, = row - retval = unicode(retval, 'utf-8') + if queryreturn: + retval = queryreturn[-1][0] elif self.address is None or self.type == AccountMixin.ALL: return _translate("MainWindow", "All accounts") - return retval or unicode(self.address, 'utf-8') + return (retval or self.address).decode('utf-8') class BMTreeWidgetItem(QtWidgets.QTreeWidgetItem, AccountMixin): @@ -241,13 +236,12 @@ class Ui_AddressWidget(BMTreeWidgetItem, SettingsMixin): def _getLabel(self): if self.address is None: return _translate("MainWindow", "All accounts") - else: - try: - return unicode( - BMConfigParser().get(self.address, 'label'), - 'utf-8', 'ignore') - except: - return unicode(self.address, 'utf-8') + + try: + return BMConfigParser().get( + self.address, 'label').decode('utf-8', 'ignore') + except: + return self.address.decode('utf-8') def _getAddressBracket(self, unreadCount=False): ret = "" if self.isExpanded() \ @@ -318,11 +312,9 @@ class Ui_SubscriptionWidget(Ui_AddressWidget): queryreturn = sqlQuery( 'SELECT label FROM subscriptions WHERE address=?', self.address) - if queryreturn != []: - for row in queryreturn: - retval, = row - return unicode(retval, 'utf-8', 'ignore') - return unicode(self.address, 'utf-8') + if queryreturn: + return queryreturn[-1][0].decode('utf-8', 'ignore') + return self.address.decode('utf-8') def setType(self): """Set account type""" @@ -412,9 +404,7 @@ class MessageList_AddressWidget(BMAddressWidget): AccountMixin.NORMAL, AccountMixin.CHAN, AccountMixin.MAILINGLIST): try: - newLabel = unicode( - BMConfigParser().get(self.address, 'label'), - 'utf-8', 'ignore') + newLabel = BMConfigParser().get(self.address, 'label') except: queryreturn = sqlQuery( 'SELECT label FROM addressbook WHERE address=?', @@ -424,10 +414,9 @@ class MessageList_AddressWidget(BMAddressWidget): 'SELECT label FROM subscriptions WHERE address=?', self.address) if queryreturn: - for row in queryreturn: - newLabel = unicode(row[0], 'utf-8', 'ignore') + newLabel = queryreturn[-1][0] - self.label = newLabel + self.label = newLabel.decode('utf-8', 'ignore') def data(self, role): """Return object data (QT UI)""" @@ -536,8 +525,6 @@ class Ui_AddressBookWidgetItem(BMAddressWidget): sqlExecute( 'UPDATE subscriptions SET label=? WHERE address=?', self.label, self.address) - else: - pass return super(Ui_AddressBookWidgetItem, self).setData(role, value) def __lt__(self, other): -- 2.45.1 From 6fd07a079d79ce7f80da5cbbbb0caef21e1b6823 Mon Sep 17 00:00:00 2001 From: Dmitri Bogomolov <4glitch@gmail.com> Date: Sat, 8 May 2021 20:50:16 +0300 Subject: [PATCH 023/105] bitmessageqt.account: replace unicode() by .decode() and format --- src/bitmessageqt/account.py | 60 ++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 31 deletions(-) diff --git a/src/bitmessageqt/account.py b/src/bitmessageqt/account.py index 31780e20..a1331334 100644 --- a/src/bitmessageqt/account.py +++ b/src/bitmessageqt/account.py @@ -23,8 +23,8 @@ def getSortedAccounts(): configSections = BMConfigParser().addresses() configSections.sort( cmp=lambda x, y: cmp( - unicode(BMConfigParser().get(x, 'label'), 'utf-8').lower(), - unicode(BMConfigParser().get(y, 'label'), 'utf-8').lower()) + BMConfigParser().get(x, 'label').decode('utf-8').lower(), + BMConfigParser().get(y, 'label').decode('utf-8').lower()) ) return configSections @@ -38,22 +38,21 @@ def getSortedSubscriptions(count=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 = {} - for row in queryreturn: - label, address, enabled = row - ret[address] = {} - ret[address]["inbox"] = {} - ret[address]["inbox"]['label'] = label - ret[address]["inbox"]['enabled'] = enabled - ret[address]["inbox"]['count'] = 0 + for label, address, enabled in queryreturn: + ret[address] = {'inbox': {}} + ret[address]['inbox'].update(label=label, enabled=enabled, count=0) if count: - queryreturn = sqlQuery('''SELECT fromaddress, folder, count(msgid) as cnt - FROM inbox, subscriptions ON subscriptions.address = inbox.fromaddress - WHERE read = 0 AND toaddress = ? - GROUP BY inbox.fromaddress, folder''', str_broadcast_subscribers) - for row in queryreturn: - address, folder, cnt = row + queryreturn = sqlQuery( + 'SELECT fromaddress, folder, count(msgid) AS cnt' + ' FROM inbox, subscriptions' + ' ON subscriptions.address = inbox.fromaddress WHERE read = 0' + ' AND toaddress = ? GROUP BY inbox.fromaddress, folder', + str_broadcast_subscribers) + for address, folder, cnt in queryreturn: if folder not in ret[address]: ret[address][folder] = { 'label': ret[address]['inbox']['label'], @@ -105,7 +104,9 @@ class AccountColor(AccountMixin): elif BMConfigParser().safeGetBoolean(self.address, 'chan'): self.type = AccountMixin.CHAN elif sqlQuery( - '''select label from subscriptions where address=?''', self.address): + 'SELECT label FROM subscriptions WHERE address=?', + self.address + ): self.type = AccountMixin.SUBSCRIPTION else: self.type = AccountMixin.NORMAL @@ -149,28 +150,25 @@ class BMAccount(NoAccount): self.type = AccountMixin.MAILINGLIST elif self.address == str_broadcast_subscribers: self.type = AccountMixin.BROADCAST - else: - queryreturn = sqlQuery( - '''select label from subscriptions where address=?''', self.address) - if queryreturn: - self.type = AccountMixin.SUBSCRIPTION + elif sqlQuery( + 'SELECT label FROM subscriptions WHERE address=?', self.address + ): + self.type = AccountMixin.SUBSCRIPTION def getLabel(self, address=None): """Get a label for this bitmessage account""" address = super(BMAccount, self).getLabel(address) label = BMConfigParser().safeGet(address, 'label', address) queryreturn = sqlQuery( - '''select label from addressbook where address=?''', address) - if queryreturn != []: - for row in queryreturn: - label, = row + 'SELECT label FROM addressbook WHERE address=?', address) + if queryreturn: + label = queryreturn[-1][0] else: queryreturn = sqlQuery( - '''select label from subscriptions where address=?''', address) - if queryreturn != []: - for row in queryreturn: - label, = row - return unicode(label, 'utf-8') + 'SELECT label FROM subscriptions WHERE address=?', address) + if queryreturn: + label = queryreturn[-1][0] + return label.decode('utf-8') class SubscriptionAccount(BMAccount): -- 2.45.1 From e57a4fa7a980ac1da3b9f6da043a8ec758b65ae5 Mon Sep 17 00:00:00 2001 From: Dmitri Bogomolov <4glitch@gmail.com> Date: Sat, 8 May 2021 21:30:45 +0300 Subject: [PATCH 024/105] bitmessageqt.__init__: removed or replaced unicode(), formatted a bit --- src/bitmessageqt/__init__.py | 110 ++++++++++++++++++----------------- 1 file changed, 56 insertions(+), 54 deletions(-) diff --git a/src/bitmessageqt/__init__.py b/src/bitmessageqt/__init__.py index 07862e10..5c6bebdc 100644 --- a/src/bitmessageqt/__init__.py +++ b/src/bitmessageqt/__init__.py @@ -525,9 +525,10 @@ class MyForm(settingsmixin.SMainWindow): # get number of (unread) messages total = 0 - queryreturn = sqlQuery('SELECT toaddress, folder, count(msgid) as cnt FROM inbox WHERE read = 0 GROUP BY toaddress, folder') - for row in queryreturn: - toaddress, folder, cnt = row + queryreturn = sqlQuery( + 'SELECT toaddress, folder, count(msgid) as cnt' + ' FROM inbox WHERE read = 0 GROUP BY toaddress, folder') + for toaddress, folder, cnt in queryreturn: total += cnt if toaddress in db and folder in db[toaddress]: db[toaddress][folder] = cnt @@ -1236,7 +1237,7 @@ class MyForm(settingsmixin.SMainWindow): for row in queryreturn: toAddress, fromAddress, subject, _, msgid, received, read = row self.addMessageListItemInbox( - tableWidget, toAddress, fromAddress, unicode(subject, 'utf-8'), + tableWidget, toAddress, fromAddress, subject.decode('utf-8'), msgid, received, read) tableWidget.horizontalHeader().setSortIndicator( @@ -1446,8 +1447,7 @@ class MyForm(settingsmixin.SMainWindow): def notifierShow( self, title, subtitle, category, label=None, icon=None): self.playSound(category, label) - self._notifier( - unicode(title), unicode(subtitle), category, label, icon) + self._notifier(title, subtitle, category, label, icon) # tree def treeWidgetKeyPressEvent(self, event): @@ -1949,16 +1949,18 @@ class MyForm(settingsmixin.SMainWindow): oldRows[item.address] = [item.label, item.type, i] if self.ui.tableWidgetAddressBook.rowCount() == 0: - self.ui.tableWidgetAddressBook.horizontalHeader().setSortIndicator(0, QtCore.Qt.AscendingOrder) + self.ui.tableWidgetAddressBook.horizontalHeader( + ).setSortIndicator(0, QtCore.Qt.AscendingOrder) if self.ui.tableWidgetAddressBook.isSortingEnabled(): self.ui.tableWidgetAddressBook.setSortingEnabled(False) newRows = {} # subscriptions - queryreturn = sqlQuery('SELECT label, address FROM subscriptions WHERE enabled = 1') - for row in queryreturn: - label, address = row - newRows[address] = [unicode(label, 'utf-8'), AccountMixin.SUBSCRIPTION] + queryreturn = sqlQuery( + 'SELECT label, address FROM subscriptions WHERE enabled = 1') + for label, address in queryreturn: + newRows[address] = [ + label.decode('utf-8'), AccountMixin.SUBSCRIPTION] # chans addresses = getSortedAccounts() for address in addresses: @@ -1969,10 +1971,9 @@ class MyForm(settingsmixin.SMainWindow): ): newRows[address] = [account.getLabel(), AccountMixin.CHAN] # normal accounts - queryreturn = sqlQuery('SELECT * FROM addressbook') - for row in queryreturn: - label, address = row - newRows[address] = [unicode(label, 'utf-8'), AccountMixin.NORMAL] + queryreturn = sqlQuery('SELECT label, address FROM addressbook') + for label, address in queryreturn: + newRows[address] = [label.decode('utf-8'), AccountMixin.NORMAL] completerList = [] for address in sorted( @@ -2117,14 +2118,13 @@ class MyForm(settingsmixin.SMainWindow): ).format(email)) return status, addressVersionNumber, streamNumber = \ - decodeAddress(toAddress)[:3] + decodeAddress(toAddress)[:3] if status != 'success': try: - toAddress_value = unicode( - toAddress, 'utf-8', 'ignore') - except: + toAddress_value = toAddress.decode('utf-8') + except UnicodeDecodeError: logger.warning( - "Failed unicode(toAddress ):", exc_info=True) + "Failed decoding toAddress ):", exc_info=True) logger.error( 'Error: Could not decode recipient address %s: %s', toAddress_value, status) @@ -2331,13 +2331,15 @@ class MyForm(settingsmixin.SMainWindow): for addressInKeysFile in getSortedAccounts(): isEnabled = BMConfigParser().getboolean( addressInKeysFile, 'enabled') # I realize that this is poor programming practice but I don't care. It's easier for others to read. - isMaillinglist = BMConfigParser().safeGetBoolean(addressInKeysFile, 'mailinglist') + isMaillinglist = BMConfigParser().safeGetBoolean( + addressInKeysFile, 'mailinglist') if isEnabled and not isMaillinglist: - label = unicode(BMConfigParser().get(addressInKeysFile, 'label'), 'utf-8', 'ignore').strip() - if label == "": - label = addressInKeysFile - self.ui.comboBoxSendFrom.addItem(avatarize(addressInKeysFile), label, addressInKeysFile) -# self.ui.comboBoxSendFrom.model().sort(1, Qt.AscendingOrder) + label = ( + BMConfigParser().get(addressInKeysFile, 'label').decode( + 'utf-8', 'ignore').strip() or addressInKeysFile) + self.ui.comboBoxSendFrom.addItem( + avatarize(addressInKeysFile), label, addressInKeysFile) + # self.ui.comboBoxSendFrom.model().sort(1, QtCore.Qt.AscendingOrder) for i in range(self.ui.comboBoxSendFrom.count()): address = self.ui.comboBoxSendFrom.itemData( i, QtCore.Qt.UserRole) @@ -2345,7 +2347,7 @@ class MyForm(settingsmixin.SMainWindow): i, AccountColor(address).accountColor(), QtCore.Qt.ForegroundRole) self.ui.comboBoxSendFrom.insertItem(0, '', '') - if(self.ui.comboBoxSendFrom.count() == 2): + if self.ui.comboBoxSendFrom.count() == 2: self.ui.comboBoxSendFrom.setCurrentIndex(1) else: self.ui.comboBoxSendFrom.setCurrentIndex(0) @@ -2357,10 +2359,11 @@ class MyForm(settingsmixin.SMainWindow): addressInKeysFile, 'enabled') # I realize that this is poor programming practice but I don't care. It's easier for others to read. isChan = BMConfigParser().safeGetBoolean(addressInKeysFile, 'chan') if isEnabled and not isChan: - label = unicode(BMConfigParser().get(addressInKeysFile, 'label'), 'utf-8', 'ignore').strip() - if label == "": - label = addressInKeysFile - self.ui.comboBoxSendFromBroadcast.addItem(avatarize(addressInKeysFile), label, addressInKeysFile) + label = ( + BMConfigParser().get(addressInKeysFile, 'label').decode( + 'utf-8', 'ignore').strip() or addressInKeysFile) + self.ui.comboBoxSendFromBroadcast.addItem( + avatarize(addressInKeysFile), label, addressInKeysFile) for i in range(self.ui.comboBoxSendFromBroadcast.count()): address = self.ui.comboBoxSendFromBroadcast.itemData( i, QtCore.Qt.UserRole) @@ -2880,33 +2883,32 @@ class MyForm(settingsmixin.SMainWindow): if not msgid: return queryreturn = sqlQuery( - '''select message from inbox where msgid=?''', msgid) - if queryreturn != []: - for row in queryreturn: - messageText, = row + 'SELECT message FROM inbox WHERE msgid=?', msgid) + try: + lines = queryreturn[-1][0].split('\n') + except IndexError: + lines = '' - lines = messageText.split('\n') totalLines = len(lines) - for i in xrange(totalLines): + for i in range(totalLines): if 'Message ostensibly from ' in lines[i]: lines[i] = ( '

%s

' % lines[i] ) elif ( - lines[i] == - '------------------------------------------------------' + lines[i] + == '------------------------------------------------------' ): lines[i] = '
' elif ( - lines[i] == '' and (i + 1) < totalLines and - lines[i + 1] != - '------------------------------------------------------' + lines[i] == '' and (i + 1) < totalLines and lines[i + 1] + != '------------------------------------------------------' ): lines[i] = '

' content = ' '.join(lines) # To keep the whitespace between lines content = shared.fixPotentiallyInvalidUTF8Data(content) - content = unicode(content, 'utf-8') + content = content.decode('utf-8') textEdit.setHtml(content) def on_action_InboxMarkUnread(self): @@ -3090,7 +3092,7 @@ class MyForm(settingsmixin.SMainWindow): self.setSendFromComboBox(toAddressAtCurrentInboxRow) quotedText = self.quoted_text( - unicode(messageAtCurrentInboxRow, 'utf-8', 'replace')) + messageAtCurrentInboxRow.decode('utf-8', 'replace')) widget['message'].setPlainText(quotedText) if acct.subject[0:3] in ('Re:', 'RE:'): widget['subject'].setText( @@ -3717,7 +3719,6 @@ class MyForm(settingsmixin.SMainWindow): text = tableWidget.item(currentRow, currentColumn).label else: text = tableWidget.item(currentRow, currentColumn).data(QtCore.Qt.UserRole) - # text = unicode(str(text), 'utf-8', 'ignore') clipboard = QtWidgets.QApplication.clipboard() clipboard.setText(text) @@ -3833,10 +3834,10 @@ class MyForm(settingsmixin.SMainWindow): self.setAddressSound(widget.item(widget.currentRow(), 0).text()) def setAddressSound(self, addr): - filters = [unicode(_translate( + filters = [_translate( "MainWindow", "Sound files (%s)" % ' '.join(['*%s%s' % (os.extsep, ext) for ext in sound.extensions]) - ))] + )] sourcefile = QtWidgets.QFileDialog.getOpenFileName( self, _translate("MainWindow", "Set notification sound..."), filter=';;'.join(filters) @@ -3846,7 +3847,7 @@ class MyForm(settingsmixin.SMainWindow): return destdir = os.path.join(state.appdata, 'sounds') - destfile = unicode(addr) + os.path.splitext(sourcefile)[-1] + destfile = addr.decode('utf-8') + os.path.splitext(sourcefile)[-1] destination = os.path.join(destdir, destfile) if sourcefile == destination: @@ -4093,16 +4094,16 @@ class MyForm(settingsmixin.SMainWindow): folder = self.getCurrentFolder() if msgid: queryreturn = sqlQuery( - '''SELECT message FROM %s WHERE %s=?''' % ( + 'SELECT message FROM %s WHERE %s=?' % ( ('sent', 'ackdata') if folder == 'sent' else ('inbox', 'msgid') ), msgid ) try: - message = unicode(queryreturn[-1][0], 'utf-8') + message = queryreturn[-1][0].decode('utf-8') except NameError: - message = u"" + message = u'' except IndexError: # _translate() often returns unicode, no redefinition here! # pylint: disable=redefined-variable-type @@ -4118,7 +4119,7 @@ class MyForm(settingsmixin.SMainWindow): self.updateUnreadStatus(tableWidget, currentRow, msgid) # propagate if folder != 'sent' and sqlExecute( - '''UPDATE inbox SET read=1 WHERE msgid=? AND read=0''', + 'UPDATE inbox SET read=1 WHERE msgid=? AND read=0', msgid ) > 0: self.propagateUnreadCount() @@ -4134,8 +4135,9 @@ class MyForm(settingsmixin.SMainWindow): self.rerenderMessagelistToLabels() completerList = self.ui.lineEditTo.completer().model().stringList() for i in range(len(completerList)): - if unicode(completerList[i]).endswith(" <" + item.address + ">"): - completerList[i] = item.label + " <" + item.address + ">" + address_block = " <" + item.address + ">" + if completerList[i].endswith(address_block): + completerList[i] = item.label + address_block self.ui.lineEditTo.completer().model().setStringList(completerList) def tabWidgetCurrentChanged(self, n): -- 2.45.1 From 5acee0cf41dc7318400b595daa6f2e484342c259 Mon Sep 17 00:00:00 2001 From: Dmitri Bogomolov <4glitch@gmail.com> Date: Sat, 8 May 2021 22:16:53 +0300 Subject: [PATCH 025/105] Remove redundant unicode() in plugins.indicator_libmessaging --- src/plugins/indicator_libmessaging.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/plugins/indicator_libmessaging.py b/src/plugins/indicator_libmessaging.py index b471d2ef..4cd583e3 100644 --- a/src/plugins/indicator_libmessaging.py +++ b/src/plugins/indicator_libmessaging.py @@ -23,9 +23,9 @@ class IndicatorLibmessaging(object): return self._menu = { - 'send': unicode(_translate('MainWindow', 'Send')), - 'messages': unicode(_translate('MainWindow', 'Messages')), - 'subscriptions': unicode(_translate('MainWindow', 'Subscriptions')) + 'send': _translate('MainWindow', 'Send'), + 'messages': _translate('MainWindow', 'Messages'), + 'subscriptions': _translate('MainWindow', 'Subscriptions') } self.new_message_item = self.new_broadcast_item = None @@ -45,12 +45,11 @@ class IndicatorLibmessaging(object): def show_unread(self, draw_attention=False): """ - show the number of unread messages and subscriptions + Show the number of unread messages and subscriptions on the messaging menu """ for source, count in zip( - ('messages', 'subscriptions'), - self.form.getUnread() + ('messages', 'subscriptions'), self.form.getUnread() ): if count > 0: if self.app.has_source(source): -- 2.45.1 From 2f8734d60b36a8d77bc54a2a23fea5350ba41e08 Mon Sep 17 00:00:00 2001 From: Dmitri Bogomolov <4glitch@gmail.com> Date: Wed, 9 Jun 2021 20:21:50 +0300 Subject: [PATCH 026/105] Change depends in stdeb.cfg --- stdeb.cfg | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stdeb.cfg b/stdeb.cfg index 0d4cfbcb..f337a9fe 100644 --- a/stdeb.cfg +++ b/stdeb.cfg @@ -2,8 +2,8 @@ Package: pybitmessage Section: net Build-Depends: dh-python, libssl-dev, python-all-dev, python-setuptools, python-six -Depends: openssl, python-setuptools -Recommends: apparmor, python-msgpack, python-qt4, python-stem, tor +Depends: openssl, python-setuptools, python-six +Recommends: apparmor, python-msgpack, python-pyqt5, python-stem, tor Suggests: python-pyopencl, python-jsonrpclib, python-defusedxml, python-qrcode Suite: bionic Setup-Env-Vars: DEB_BUILD_OPTIONS=nocheck -- 2.45.1 From 9a1424c189b82d6a8b1f7312d63c708def1768a1 Mon Sep 17 00:00:00 2001 From: Dmitri Bogomolov <4glitch@gmail.com> Date: Thu, 7 Oct 2021 18:31:51 +0300 Subject: [PATCH 027/105] qtpy based fallback for PyQt5 --- src/depends.py | 18 +++++------ src/fallback/__init__.py | 64 +++++++++++++++++++++++----------------- 2 files changed, 46 insertions(+), 36 deletions(-) diff --git a/src/depends.py b/src/depends.py index f4a5157c..5774c1ac 100755 --- a/src/depends.py +++ b/src/depends.py @@ -384,25 +384,25 @@ def check_pyqt(): """ # pylint: disable=no-member try: - from fallback import qtpy + from fallback import PyQt5 except ImportError: logger.error( - 'PyBitmessage requires qtpy, PyQt 4.8 or later and Qt 4.7 or later.' - ) - qtpy = None + 'PyBitmessage requires PyQt5 or qtpy, PyQt 4.8 or later' + ' and Qt 4.7 or later.') + PyQt5 = None - if not qtpy: + if not PyQt5: return False - logger.info('PyQt Version: %s', qtpy.PYQT_VERSION) - logger.info('Qt Version: %s', qtpy.QT_VERSION) + logger.info('PyQt Version: %s', PyQt5.PYQT_VERSION) + logger.info('Qt Version: %s', PyQt5.QT_VERSION) passed = True - if version.LooseVersion(qtpy.PYQT_VERSION) < '4.8': + if version.LooseVersion(PyQt5.PYQT_VERSION) < '4.8': logger.error( 'This version of PyQt is too old. PyBitmessage requries' ' PyQt 4.8 or later.') passed = False - if version.LooseVersion(qtpy.QT_VERSION) < '4.7': + if version.LooseVersion(PyQt5.QT_VERSION) < '4.7': logger.error( 'This version of Qt is too old. PyBitmessage requries' ' Qt 4.7 or later.') diff --git a/src/fallback/__init__.py b/src/fallback/__init__.py index bd1f51b9..06998e2a 100644 --- a/src/fallback/__init__.py +++ b/src/fallback/__init__.py @@ -32,34 +32,44 @@ else: return hasher try: - import qtpy + import PyQt5 except ImportError: try: - from PyQt5 import QtCore, QtGui, QtWidgets, QtNetwork, uic + import qtpy as PyQt5 except ImportError: - qtpy = None - else: - import sys - import types + pass +else: + from PyQt5 import QtCore - QtCore.Signal = QtCore.pyqtSignal - context = { - 'API': 'pyqt5', # for tr - 'PYQT_VERSION': QtCore.PYQT_VERSION_STR, - 'QT_VERSION': QtCore.QT_VERSION_STR, - 'QtCore': QtCore, - 'QtGui': QtGui, - 'QtWidgets': QtWidgets, - 'QtNetwork': QtNetwork, - 'uic': uic - } - try: - from PyQt5 import QtTest - except ImportError: - pass - else: - context['QtTest'] = QtTest - qtpy = types.ModuleType( - 'qtpy', 'PyQt5 based dynamic fallback for qtpy') - qtpy.__dict__.update(context) - sys.modules['qtpy'] = qtpy + QtCore.Signal = QtCore.pyqtSignal + PyQt5.PYQT_VERSION = QtCore.PYQT_VERSION_STR + PyQt5.QT_VERSION = QtCore.QT_VERSION_STR + # try: + # from qtpy import QtCore, QtGui, QtWidgets, QtNetwork, uic + # except ImportError: + # PyQt5 = None + # else: + # import sys + # import types + + # QtCore.Signal = QtCore.pyqtSignal + # context = { + # 'API': 'pyqt5', # for tr + # 'PYQT_VERSION': QtCore.PYQT_VERSION_STR, + # 'QT_VERSION': QtCore.QT_VERSION_STR, + # 'QtCore': QtCore, + # 'QtGui': QtGui, + # 'QtWidgets': QtWidgets, + # 'QtNetwork': QtNetwork, + # 'uic': uic + # } + # try: + # from PyQt5 import QtTest + # except ImportError: + # pass + # else: + # context['QtTest'] = QtTest + # PyQt5 = types.ModuleType( + # 'PyQt5', 'qtpy based dynamic fallback for PyQt5') + # PyQt5.__dict__.update(context) + # sys.modules['PyQt5'] = PyQt5 -- 2.45.1 From ced7b4df30877ff80b652db0ccc989df4c94250b Mon Sep 17 00:00:00 2001 From: Dmitri Bogomolov <4glitch@gmail.com> Date: Fri, 19 Nov 2021 23:11:11 +0200 Subject: [PATCH 028/105] Fix UnicodeEncodeError in bitmessageqt.blacklist when deleting an entry --- src/bitmessageqt/blacklist.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/bitmessageqt/blacklist.py b/src/bitmessageqt/blacklist.py index 1875e001..0a1a2a3a 100644 --- a/src/bitmessageqt/blacklist.py +++ b/src/bitmessageqt/blacklist.py @@ -197,11 +197,11 @@ class Blacklist(QtWidgets.QWidget, RetranslateMixin): if BMConfigParser().get('bitmessagesettings', 'blackwhitelist') == 'black': sqlExecute( '''DELETE FROM blacklist WHERE label=? AND address=?''', - str(labelAtCurrentRow), str(addressAtCurrentRow)) + labelAtCurrentRow, addressAtCurrentRow) else: sqlExecute( '''DELETE FROM whitelist WHERE label=? AND address=?''', - str(labelAtCurrentRow), str(addressAtCurrentRow)) + labelAtCurrentRow, addressAtCurrentRow) self.tableWidgetBlacklist.removeRow(currentRow) def on_action_BlacklistClipboard(self): -- 2.45.1 From 327a539a552f4f48a6627d1f6d7f229b0a5426e8 Mon Sep 17 00:00:00 2001 From: Dmitri Bogomolov <4glitch@gmail.com> Date: Mon, 29 Nov 2021 16:30:33 +0200 Subject: [PATCH 029/105] Replace removed cmp parameter of list.sort() by key in getSortedAccounts() --- src/bitmessageqt/account.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/bitmessageqt/account.py b/src/bitmessageqt/account.py index a1331334..852eb836 100644 --- a/src/bitmessageqt/account.py +++ b/src/bitmessageqt/account.py @@ -22,10 +22,8 @@ def getSortedAccounts(): """Get a sorted list of address config sections""" configSections = BMConfigParser().addresses() configSections.sort( - cmp=lambda x, y: cmp( - BMConfigParser().get(x, 'label').decode('utf-8').lower(), - BMConfigParser().get(y, 'label').decode('utf-8').lower()) - ) + key=lambda item: + BMConfigParser().get(item, 'label').decode('utf-8').lower()) return configSections -- 2.45.1 From a0496813fad5eb7c91f4b1ba9b3a115a83adb5f6 Mon Sep 17 00:00:00 2001 From: Dmitri Bogomolov <4glitch@gmail.com> Date: Mon, 29 Nov 2021 17:41:39 +0200 Subject: [PATCH 030/105] Fix imports in bitmessageqt.tests --- src/bitmessageqt/tests/main.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/bitmessageqt/tests/main.py b/src/bitmessageqt/tests/main.py index 9ffba909..9631878d 100644 --- a/src/bitmessageqt/tests/main.py +++ b/src/bitmessageqt/tests/main.py @@ -4,7 +4,8 @@ import Queue import sys import unittest -from qtpy import QtCore, QtWidgets +from PyQt5 import QtCore, QtWidgets +from six import string_types import bitmessageqt import queues @@ -39,10 +40,7 @@ class TestMain(unittest.TestCase): def test_translate(self): """Check the results of _translate() with various args""" - self.assertIsInstance( - _translate("MainWindow", "Test"), - unicode - ) + self.assertIsInstance(_translate("MainWindow", "Test"), string_types) class TestUISignaler(TestBase): -- 2.45.1 From d9fb640b26415cf60f8b6e68e51cfd45dea4d510 Mon Sep 17 00:00:00 2001 From: Dmitri Bogomolov <4glitch@gmail.com> Date: Wed, 15 Dec 2021 19:10:27 +0200 Subject: [PATCH 031/105] Add python-qtpy into appimage recipe to build with Qt4 --- packages/AppImage/PyBitmessage.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/AppImage/PyBitmessage.yml b/packages/AppImage/PyBitmessage.yml index 4f0c7e3d..33e8ff00 100644 --- a/packages/AppImage/PyBitmessage.yml +++ b/packages/AppImage/PyBitmessage.yml @@ -11,6 +11,7 @@ ingredients: - python-msgpack - python-qrcode - python-qt4 + - python-qtpy - python-setuptools - python-sip - python-six -- 2.45.1 From 14347689578225d4913525f0c363f476e0ad3890 Mon Sep 17 00:00:00 2001 From: Dmitri Bogomolov <4glitch@gmail.com> Date: Wed, 15 Dec 2021 19:26:21 +0200 Subject: [PATCH 032/105] Try to fix the issue with XKB in appimage by adding xkb-data package --- packages/AppImage/PyBitmessage.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/AppImage/PyBitmessage.yml b/packages/AppImage/PyBitmessage.yml index 33e8ff00..1738da08 100644 --- a/packages/AppImage/PyBitmessage.yml +++ b/packages/AppImage/PyBitmessage.yml @@ -16,6 +16,7 @@ ingredients: - python-sip - python-six - sni-qt + - xkb-data exclude: - libmng2 - libncursesw5 -- 2.45.1 From 991055621630bd2f190927a79876dd9c8fa0bd43 Mon Sep 17 00:00:00 2001 From: Dmitri Bogomolov <4glitch@gmail.com> Date: Wed, 15 Dec 2021 19:31:33 +0200 Subject: [PATCH 033/105] Add "Ubuntu 20" key to depends.PACKAGES['qtpy'] dict --- src/depends.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/depends.py b/src/depends.py index 5774c1ac..2519b5bd 100755 --- a/src/depends.py +++ b/src/depends.py @@ -59,6 +59,7 @@ PACKAGES = { "Debian": "python-qtpy", "Ubuntu": "python-qtpy", "Ubuntu 12": "python-qtpy", + "Ubuntu 20": "python-qtpy", "openSUSE": "python-QtPy", "Fedora": "python2-QtPy", "Guix": "", -- 2.45.1 From 1368013a4e9ab87cc0b52fb4075e93e09ccb4766 Mon Sep 17 00:00:00 2001 From: Dmitri Bogomolov <4glitch@gmail.com> Date: Wed, 15 Dec 2021 20:53:57 +0200 Subject: [PATCH 034/105] Remove rebasing artifact in depends --- src/depends.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/depends.py b/src/depends.py index 2519b5bd..4cbd2ef7 100755 --- a/src/depends.py +++ b/src/depends.py @@ -168,7 +168,7 @@ def detectOSRelease(): pass if detectOS.result == "Ubuntu" and ver < 14: detectOS.result = "Ubuntu 12" - elif detectOS.result == "Ubuntu" and version >= 20: + elif detectOS.result == "Ubuntu" and ver >= 20: detectOS.result = "Ubuntu 20" -- 2.45.1 From 72ba0b6bc17eecbfce3f50adbbbd828ed893a865 Mon Sep 17 00:00:00 2001 From: Kashiko Koibumi Date: Mon, 20 May 2024 15:42:04 +0900 Subject: [PATCH 035/105] make runnable with OpenSSL 3 in addition to other versions --- src/network/tls.py | 48 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 40 insertions(+), 8 deletions(-) diff --git a/src/network/tls.py b/src/network/tls.py index a3774b44..87240ce8 100644 --- a/src/network/tls.py +++ b/src/network/tls.py @@ -58,25 +58,44 @@ class TLSDispatcher(AdvancedDispatcher): self.tlsDone = False self.tlsVersion = "N/A" self.isSSL = False + if ssl.OPENSSL_VERSION_NUMBER >= 0x30000000: + self.tlsPrepared = False def state_tls_init(self): """Prepare sockets for TLS handshake""" self.isSSL = True self.tlsStarted = True + + if ssl.OPENSSL_VERSION_NUMBER >= 0x30000000: + self.want_read = self.want_write = True + self.set_state("tls_handshake") + return False + + do_tls_init(self) + + def do_tls_init(self): # Once the connection has been established, # it's safe to wrap the socket. if sys.version_info >= (2, 7, 9): - context = ssl.create_default_context( - purpose=ssl.Purpose.SERVER_AUTH - if self.server_side else ssl.Purpose.CLIENT_AUTH) + if ssl.OPENSSL_VERSION_NUMBER >= 0x30000000: + context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) + else: + context = ssl.create_default_context( + purpose=ssl.Purpose.SERVER_AUTH + if self.server_side else ssl.Purpose.CLIENT_AUTH) context.set_ciphers(self.ciphers) context.set_ecdh_curve("secp256k1") context.check_hostname = False context.verify_mode = ssl.CERT_NONE # also exclude TLSv1 and TLSv1.1 in the future - context.options = ssl.OP_ALL | ssl.OP_NO_SSLv2 |\ - ssl.OP_NO_SSLv3 | ssl.OP_SINGLE_ECDH_USE |\ - ssl.OP_CIPHER_SERVER_PREFERENCE + if ssl.OPENSSL_VERSION_NUMBER >= 0x30000000: + context.options = ssl.OP_ALL | ssl.OP_NO_SSLv2 |\ + ssl.OP_NO_SSLv3 | ssl.OP_SINGLE_ECDH_USE |\ + ssl.OP_CIPHER_SERVER_PREFERENCE | ssl.OP_NO_TLS1_3 + else: + context.options = ssl.OP_ALL | ssl.OP_NO_SSLv2 |\ + ssl.OP_NO_SSLv3 | ssl.OP_SINGLE_ECDH_USE |\ + ssl.OP_CIPHER_SERVER_PREFERENCE self.sslSocket = context.wrap_socket( self.socket, server_side=self.server_side, do_handshake_on_connect=False) @@ -88,7 +107,10 @@ class TLSDispatcher(AdvancedDispatcher): ciphers=self.ciphers, do_handshake_on_connect=False) self.sslSocket.setblocking(0) self.want_read = self.want_write = True - self.set_state("tls_handshake") + if ssl.OPENSSL_VERSION_NUMBER >= 0x30000000: + self.tlsPrepared = True + else: + self.set_state("tls_handshake") return False @staticmethod @@ -114,7 +136,9 @@ class TLSDispatcher(AdvancedDispatcher): # during TLS handshake, and after flushing write buffer, # return status of last handshake attempt if self.tlsStarted and not self.tlsDone and not self.write_buf: - logger.debug('tls readable, %r', self.want_read) + # with OpenSSL 3, excessive logs are spitted + if ssl.OPENSSL_VERSION_NUMBER < 0x30000000: + logger.debug('tls readable, %r', self.want_read) return self.want_read # prior to TLS handshake, # receiveDataThread should emulate synchronous behaviour @@ -134,6 +158,10 @@ class TLSDispatcher(AdvancedDispatcher): try: # wait for write buffer flush if self.tlsStarted and not self.tlsDone and not self.write_buf: + if ssl.OPENSSL_VERSION_NUMBER >= 0x30000000: + if not self.tlsPrepared: + self.do_tls_init() + return self.tls_handshake() else: AdvancedDispatcher.handle_read(self) @@ -156,6 +184,10 @@ class TLSDispatcher(AdvancedDispatcher): try: # wait for write buffer flush if self.tlsStarted and not self.tlsDone and not self.write_buf: + if ssl.OPENSSL_VERSION_NUMBER >= 0x30000000: + if not self.tlsPrepared: + self.do_tls_init() + return self.tls_handshake() else: AdvancedDispatcher.handle_write(self) -- 2.45.1 From 4cd0df72993261631e4fdf0f6d1353fd48780751 Mon Sep 17 00:00:00 2001 From: Kashiko Koibumi Date: Wed, 22 May 2024 13:05:32 +0900 Subject: [PATCH 036/105] use qtpy directly instead of using fallback-PyQt5 --- docs/conf.py | 3 +- src/bitmessageqt/__init__.py | 4 +- src/bitmessageqt/address_dialogs.py | 2 +- src/bitmessageqt/addressvalidator.py | 2 +- src/bitmessageqt/bitmessage_icons_rc.py | 2 +- src/bitmessageqt/bitmessageui.py | 2 +- src/bitmessageqt/blacklist.py | 2 +- src/bitmessageqt/dialogs.py | 2 +- src/bitmessageqt/foldertree.py | 2 +- src/bitmessageqt/languagebox.py | 2 +- src/bitmessageqt/messagecompose.py | 2 +- src/bitmessageqt/messageview.py | 2 +- src/bitmessageqt/migrationwizard.py | 3 +- src/bitmessageqt/networkstatus.py | 2 +- src/bitmessageqt/newchandialog.py | 2 +- src/bitmessageqt/retranslateui.py | 2 +- src/bitmessageqt/settings.py | 2 +- src/bitmessageqt/settingsmixin.py | 2 +- src/bitmessageqt/statusbar.py | 2 +- src/bitmessageqt/tests/main.py | 2 +- src/bitmessageqt/uisignaler.py | 2 +- src/bitmessageqt/utils.py | 2 +- src/bitmessageqt/widgets.py | 2 +- src/depends.py | 55 +++++++++++++++---------- src/fallback/__init__.py | 43 ------------------- src/qidenticon.py | 5 +-- src/tests/test_identicon.py | 2 +- src/tr.py | 20 +-------- 28 files changed, 62 insertions(+), 113 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index b0cfef7b..bc0505cc 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -216,8 +216,7 @@ autodoc_mock_imports = [ 'pkg_resources', 'pycanberra', 'pyopencl', - 'PyQt4', - 'PyQt5', + 'qtpy', 'qrcode', 'stem', 'xdg', diff --git a/src/bitmessageqt/__init__.py b/src/bitmessageqt/__init__.py index 43b958a2..4b3e63da 100644 --- a/src/bitmessageqt/__init__.py +++ b/src/bitmessageqt/__init__.py @@ -16,7 +16,7 @@ import time from datetime import datetime, timedelta from sqlite3 import register_adapter -from PyQt5 import QtCore, QtGui, QtWidgets, QtNetwork +from qtpy import QtCore, QtGui, QtWidgets, QtNetwork import dialogs import helper_addressbook @@ -1442,7 +1442,7 @@ class MyForm(settingsmixin.SMainWindow): self._theme_player = get_plugin('notification.sound', 'theme') try: - from PyQt5 import QtMultimedia + from qtpy import QtMultimedia self._player = QtMultimedia.QSound.play except ImportError: _plugin = get_plugin( diff --git a/src/bitmessageqt/address_dialogs.py b/src/bitmessageqt/address_dialogs.py index 92b18ae7..903b588a 100644 --- a/src/bitmessageqt/address_dialogs.py +++ b/src/bitmessageqt/address_dialogs.py @@ -6,7 +6,7 @@ Dialogs that work with BM address. import hashlib -from PyQt5 import QtGui, QtWidgets +from qtpy import QtGui, QtWidgets import queues import widgets diff --git a/src/bitmessageqt/addressvalidator.py b/src/bitmessageqt/addressvalidator.py index ac1e70bc..600347c6 100644 --- a/src/bitmessageqt/addressvalidator.py +++ b/src/bitmessageqt/addressvalidator.py @@ -6,7 +6,7 @@ used in `.dialogs.NewChanDialog`. from Queue import Empty -from PyQt5 import QtGui +from qtpy import QtGui from addresses import decodeAddress, addBMIfNotPresent from bmconfigparser import config diff --git a/src/bitmessageqt/bitmessage_icons_rc.py b/src/bitmessageqt/bitmessage_icons_rc.py index 5d792c48..68404748 100644 --- a/src/bitmessageqt/bitmessage_icons_rc.py +++ b/src/bitmessageqt/bitmessage_icons_rc.py @@ -7,7 +7,7 @@ # # WARNING! All changes made in this file will be lost! -from PyQt5 import QtCore +from qtpy import QtCore qt_resource_data = "\ \x00\x00\x03\x66\ diff --git a/src/bitmessageqt/bitmessageui.py b/src/bitmessageqt/bitmessageui.py index bd888309..7a034dfa 100644 --- a/src/bitmessageqt/bitmessageui.py +++ b/src/bitmessageqt/bitmessageui.py @@ -1,7 +1,7 @@ # pylint: skip-file # flake8: noqa -from PyQt5 import QtCore, QtGui, QtWidgets +from qtpy import QtCore, QtGui, QtWidgets from tr import _translate from bmconfigparser import config from foldertree import AddressBookCompleter diff --git a/src/bitmessageqt/blacklist.py b/src/bitmessageqt/blacklist.py index 52a366ac..ae271866 100644 --- a/src/bitmessageqt/blacklist.py +++ b/src/bitmessageqt/blacklist.py @@ -1,4 +1,4 @@ -from PyQt5 import QtCore, QtGui, QtWidgets +from qtpy import QtCore, QtGui, QtWidgets import widgets from addresses import addBMIfNotPresent diff --git a/src/bitmessageqt/dialogs.py b/src/bitmessageqt/dialogs.py index fc828fef..07224f00 100644 --- a/src/bitmessageqt/dialogs.py +++ b/src/bitmessageqt/dialogs.py @@ -3,7 +3,7 @@ All dialogs are available in this module. """ # pylint: disable=too-few-public-methods -from PyQt5 import QtWidgets +from qtpy import QtWidgets import paths import widgets diff --git a/src/bitmessageqt/foldertree.py b/src/bitmessageqt/foldertree.py index 235aaf5c..57c2cd12 100644 --- a/src/bitmessageqt/foldertree.py +++ b/src/bitmessageqt/foldertree.py @@ -6,7 +6,7 @@ Folder tree and messagelist widgets definitions. from cgi import escape -from PyQt5 import QtCore, QtGui, QtWidgets +from qtpy import QtCore, QtGui, QtWidgets from bmconfigparser import config from helper_sql import sqlExecute, sqlQuery diff --git a/src/bitmessageqt/languagebox.py b/src/bitmessageqt/languagebox.py index 1fd69334..c4b61154 100644 --- a/src/bitmessageqt/languagebox.py +++ b/src/bitmessageqt/languagebox.py @@ -3,7 +3,7 @@ import glob import os -from PyQt5 import QtCore, QtWidgets +from qtpy import QtCore, QtWidgets import paths from bmconfigparser import config diff --git a/src/bitmessageqt/messagecompose.py b/src/bitmessageqt/messagecompose.py index c520030b..68de5ce0 100644 --- a/src/bitmessageqt/messagecompose.py +++ b/src/bitmessageqt/messagecompose.py @@ -1,6 +1,6 @@ """The MessageCompose class definition""" -from PyQt5 import QtCore, QtWidgets +from qtpy import QtCore, QtWidgets from tr import _translate diff --git a/src/bitmessageqt/messageview.py b/src/bitmessageqt/messageview.py index 364a92c2..ebf23c87 100644 --- a/src/bitmessageqt/messageview.py +++ b/src/bitmessageqt/messageview.py @@ -4,7 +4,7 @@ text rendering, HTML sanitization, lazy rendering (as you scroll down), zoom and URL click warning popup. """ -from PyQt5 import QtCore, QtGui, QtWidgets +from qtpy import QtCore, QtGui, QtWidgets from safehtmlparser import SafeHTMLParser from tr import _translate diff --git a/src/bitmessageqt/migrationwizard.py b/src/bitmessageqt/migrationwizard.py index 2bc32849..239770d2 100644 --- a/src/bitmessageqt/migrationwizard.py +++ b/src/bitmessageqt/migrationwizard.py @@ -1,5 +1,4 @@ -#!/usr/bin/env python2.7 -from PyQt5 import QtCore, QtWidgets +from qtpy import QtCore, QtWidgets class MigrationWizardIntroPage(QtWidgets.QWizardPage): def __init__(self): diff --git a/src/bitmessageqt/networkstatus.py b/src/bitmessageqt/networkstatus.py index 318d44ab..9c7e5a25 100644 --- a/src/bitmessageqt/networkstatus.py +++ b/src/bitmessageqt/networkstatus.py @@ -4,7 +4,7 @@ Network status tab widget definition. import time -from PyQt5 import QtCore, QtGui, QtWidgets +from qtpy import QtCore, QtGui, QtWidgets import l10n import network.stats diff --git a/src/bitmessageqt/newchandialog.py b/src/bitmessageqt/newchandialog.py index f4a89eea..2091a7ab 100644 --- a/src/bitmessageqt/newchandialog.py +++ b/src/bitmessageqt/newchandialog.py @@ -2,7 +2,7 @@ NewChanDialog class definition """ -from PyQt5 import QtCore, QtWidgets +from qtpy import QtCore, QtWidgets import widgets from addresses import addBMIfNotPresent diff --git a/src/bitmessageqt/retranslateui.py b/src/bitmessageqt/retranslateui.py index dd08e53c..706c3e81 100644 --- a/src/bitmessageqt/retranslateui.py +++ b/src/bitmessageqt/retranslateui.py @@ -1,4 +1,4 @@ -from PyQt5 import QtWidgets +from qtpy import QtWidgets import widgets diff --git a/src/bitmessageqt/settings.py b/src/bitmessageqt/settings.py index 34c9c5d0..c784b2aa 100644 --- a/src/bitmessageqt/settings.py +++ b/src/bitmessageqt/settings.py @@ -7,7 +7,7 @@ import os import sys import tempfile -from PyQt5 import QtCore, QtGui, QtWidgets +from qtpy import QtCore, QtGui, QtWidgets import six import debug diff --git a/src/bitmessageqt/settingsmixin.py b/src/bitmessageqt/settingsmixin.py index a5b8db5c..9e53c6fb 100644 --- a/src/bitmessageqt/settingsmixin.py +++ b/src/bitmessageqt/settingsmixin.py @@ -4,7 +4,7 @@ src/settingsmixin.py """ -from PyQt5 import QtCore, QtWidgets +from qtpy import QtCore, QtWidgets class SettingsMixin(object): diff --git a/src/bitmessageqt/statusbar.py b/src/bitmessageqt/statusbar.py index 006ba564..478d570c 100644 --- a/src/bitmessageqt/statusbar.py +++ b/src/bitmessageqt/statusbar.py @@ -2,7 +2,7 @@ from time import time -from PyQt5 import QtWidgets +from qtpy import QtWidgets class BMStatusBar(QtWidgets.QStatusBar): diff --git a/src/bitmessageqt/tests/main.py b/src/bitmessageqt/tests/main.py index 9631878d..1d65f16e 100644 --- a/src/bitmessageqt/tests/main.py +++ b/src/bitmessageqt/tests/main.py @@ -4,7 +4,7 @@ import Queue import sys import unittest -from PyQt5 import QtCore, QtWidgets +from qtpy import QtCore, QtWidgets from six import string_types import bitmessageqt diff --git a/src/bitmessageqt/uisignaler.py b/src/bitmessageqt/uisignaler.py index 6b72344e..8f34aff0 100644 --- a/src/bitmessageqt/uisignaler.py +++ b/src/bitmessageqt/uisignaler.py @@ -1,6 +1,6 @@ import sys -from PyQt5 import QtCore +from qtpy import QtCore import queues from network.node import Peer diff --git a/src/bitmessageqt/utils.py b/src/bitmessageqt/utils.py index cb5aedcb..cdeb0331 100644 --- a/src/bitmessageqt/utils.py +++ b/src/bitmessageqt/utils.py @@ -1,7 +1,7 @@ import hashlib import os -from PyQt5 import QtGui +from qtpy import QtGui import state from addresses import addBMIfNotPresent diff --git a/src/bitmessageqt/widgets.py b/src/bitmessageqt/widgets.py index c4a91375..e3232fe6 100644 --- a/src/bitmessageqt/widgets.py +++ b/src/bitmessageqt/widgets.py @@ -1,4 +1,4 @@ -from PyQt5 import uic +from qtpy import uic import os.path import paths diff --git a/src/depends.py b/src/depends.py index 1c42f441..6aeb32ef 100755 --- a/src/depends.py +++ b/src/depends.py @@ -69,8 +69,8 @@ PACKAGES = { "description": "You only need qtpy if you want to use the GUI." " When only running as a daemon, this can be skipped.\n" - "Also maybe you need to install PyQt5 if your package manager" - " not installs it as qtpy dependency" + "Also maybe you need to install PyQt5 or PyQt4" + " if your package manager not installs it as qtpy dependency" }, "msgpack": { "OpenBSD": "py-msgpack", @@ -381,34 +381,47 @@ def check_curses(): def check_pyqt(): """Do pyqt dependency check. - Here we are checking for PyQt4 with its version, as for it require + Here we are checking for qtpy with its version, as for it require PyQt 4.8 or later. """ # pylint: disable=no-member try: - from fallback import PyQt5 + import qtpy except ImportError: logger.error( - 'PyBitmessage requires PyQt5 or qtpy, PyQt 4.8 or later' - ' and Qt 4.7 or later.') - PyQt5 = None - - if not PyQt5: + 'PyBitmessage requires qtpy, and PyQt5 or PyQt4, ' + ' PyQt 4.8 or later and Qt 4.7 or later.') return False - logger.info('PyQt Version: %s', PyQt5.PYQT_VERSION) - logger.info('Qt Version: %s', PyQt5.QT_VERSION) + from qtpy import QtCore + try: + logger.info('PyQt Version: %s', QtCore.PYQT_VERSION_STR) + except AttributeError: + logger.info('Can be PySide..') + try: + logger.info('Qt Version: %s', QtCore.__version__) + except AttributeError: + # Can be PySide.. + pass passed = True - if version.LooseVersion(PyQt5.PYQT_VERSION) < '4.8': - logger.error( - 'This version of PyQt is too old. PyBitmessage requries' - ' PyQt 4.8 or later.') - passed = False - if version.LooseVersion(PyQt5.QT_VERSION) < '4.7': - logger.error( - 'This version of Qt is too old. PyBitmessage requries' - ' Qt 4.7 or later.') - passed = False + try: + if version.LooseVersion(QtCore.PYQT_VERSION_STR) < '4.8': + logger.error( + 'This version of PyQt is too old. PyBitmessage requries' + ' PyQt 4.8 or later.') + passed = False + except AttributeError: + # Can be PySide.. + pass + try: + if version.LooseVersion(QtCore.__version__) < '4.7': + logger.error( + 'This version of Qt is too old. PyBitmessage requries' + ' Qt 4.7 or later.') + passed = False + except AttributeError: + # Can be PySide.. + pass return passed diff --git a/src/fallback/__init__.py b/src/fallback/__init__.py index a0b8b6b4..f65999a1 100644 --- a/src/fallback/__init__.py +++ b/src/fallback/__init__.py @@ -30,46 +30,3 @@ else: if data: hasher.update(data) return hasher - -try: - import PyQt5 -except ImportError: - try: - import qtpy as PyQt5 - except ImportError: - pass -else: - from PyQt5 import QtCore - - QtCore.Signal = QtCore.pyqtSignal - PyQt5.PYQT_VERSION = QtCore.PYQT_VERSION_STR - PyQt5.QT_VERSION = QtCore.QT_VERSION_STR - # try: - # from qtpy import QtCore, QtGui, QtWidgets, QtNetwork, uic - # except ImportError: - # PyQt5 = None - # else: - # import sys - # import types - - # QtCore.Signal = QtCore.pyqtSignal - # context = { - # 'API': 'pyqt5', # for tr - # 'PYQT_VERSION': QtCore.PYQT_VERSION_STR, - # 'QT_VERSION': QtCore.QT_VERSION_STR, - # 'QtCore': QtCore, - # 'QtGui': QtGui, - # 'QtWidgets': QtWidgets, - # 'QtNetwork': QtNetwork, - # 'uic': uic - # } - # try: - # from PyQt5 import QtTest - # except ImportError: - # pass - # else: - # context['QtTest'] = QtTest - # PyQt5 = types.ModuleType( - # 'PyQt5', 'qtpy based dynamic fallback for PyQt5') - # PyQt5.__dict__.update(context) - # sys.modules['PyQt5'] = PyQt5 diff --git a/src/qidenticon.py b/src/qidenticon.py index 049c0b2a..722c47ca 100644 --- a/src/qidenticon.py +++ b/src/qidenticon.py @@ -42,10 +42,7 @@ Returns an instance of :class:`QPixmap` which have generated identicon image. from six.moves import range -try: - from PyQt5 import QtCore, QtGui -except (ImportError, RuntimeError): - from PyQt4 import QtCore, QtGui +from qtpy import QtCore, QtGui class IdenticonRendererBase(object): diff --git a/src/tests/test_identicon.py b/src/tests/test_identicon.py index 4c6be32d..35503d1c 100644 --- a/src/tests/test_identicon.py +++ b/src/tests/test_identicon.py @@ -4,7 +4,7 @@ import atexit import unittest try: - from PyQt5 import QtGui, QtWidgets + from qtpy import QtGui, QtWidgets from xvfbwrapper import Xvfb from pybitmessage import qidenticon except ImportError: diff --git a/src/tr.py b/src/tr.py index 765ba55c..45e8668c 100644 --- a/src/tr.py +++ b/src/tr.py @@ -15,26 +15,10 @@ def _tr_dummy(context, text, disambiguation=None, n=None): if state.enableGUI and not state.curses: try: - from fallback import PyQt5 # noqa:F401 - from PyQt5 import QtWidgets, QtCore + from qtpy import QtWidgets, QtCore except ImportError: _translate = _tr_dummy else: - try: - from PyQt5 import API - except ImportError: - API = 'pyqt5' - if API == 'pyqt5': - _translate = QtWidgets.QApplication.translate - else: - def _translate(context, text, disambiguation=None, n=None): - return ( - QtWidgets.QApplication.translate( - context, text, disambiguation) - if n is None else - QtWidgets.QApplication.translate( - context, text, disambiguation, - QtCore.QCoreApplication.CodecForTr, n) - ) + _translate = QtWidgets.QApplication.translate else: _translate = _tr_dummy -- 2.45.1 From f181b85d97f4d57d05996bf0aefe8b990feecede Mon Sep 17 00:00:00 2001 From: Kashiko Koibumi Date: Wed, 22 May 2024 17:14:00 +0900 Subject: [PATCH 037/105] replace all of arg() occurrences to format() --- src/bitmessageqt/__init__.py | 120 ++++++++++++++--------------- src/bitmessageqt/dialogs.py | 4 +- src/bitmessageqt/messagecompose.py | 2 +- src/bitmessageqt/messageview.py | 6 +- src/bitmessageqt/networkstatus.py | 14 ++-- src/bitmessageqt/newchandialog.py | 2 +- src/class_addressGenerator.py | 8 +- src/class_objectProcessor.py | 4 +- src/class_singleWorker.py | 51 ++++++------ src/namecoin.py | 18 ++--- src/network/tcp.py | 4 +- src/upnp.py | 4 +- 12 files changed, 118 insertions(+), 119 deletions(-) diff --git a/src/bitmessageqt/__init__.py b/src/bitmessageqt/__init__.py index 40113b5a..122a878c 100644 --- a/src/bitmessageqt/__init__.py +++ b/src/bitmessageqt/__init__.py @@ -646,9 +646,9 @@ class MyForm(settingsmixin.SMainWindow): if addressVersionNumber == 1: displayMsg = _translate( "MainWindow", - "One of your addresses, %1, is an old version 1 address. " + "One of your addresses, {0}, is an old version 1 address. " "Version 1 addresses are no longer supported. " - "May we delete it now?").arg(addressInKeysFile) + "May we delete it now?").format(addressInKeysFile) reply = QtGui.QMessageBox.question( self, 'Message', displayMsg, QtGui.QMessageBox.Yes, QtGui.QMessageBox.No) if reply == QtGui.QMessageBox.Yes: @@ -1140,20 +1140,20 @@ class MyForm(settingsmixin.SMainWindow): elif status == 'msgsent': statusText = _translate( "MainWindow", - "Message sent. Waiting for acknowledgement. Sent at %1" - ).arg(l10n.formatTimestamp(lastactiontime)) + "Message sent. Waiting for acknowledgement. Sent at {0}" + ).format(l10n.formatTimestamp(lastactiontime)) elif status == 'msgsentnoackexpected': statusText = _translate( - "MainWindow", "Message sent. Sent at %1" - ).arg(l10n.formatTimestamp(lastactiontime)) + "MainWindow", "Message sent. Sent at {0}" + ).format(l10n.formatTimestamp(lastactiontime)) elif status == 'doingmsgpow': statusText = _translate( "MainWindow", "Doing work necessary to send message.") elif status == 'ackreceived': statusText = _translate( "MainWindow", - "Acknowledgement of the message received %1" - ).arg(l10n.formatTimestamp(lastactiontime)) + "Acknowledgement of the message received {0}" + ).format(l10n.formatTimestamp(lastactiontime)) elif status == 'broadcastqueued': statusText = _translate( "MainWindow", "Broadcast queued.") @@ -1161,27 +1161,27 @@ class MyForm(settingsmixin.SMainWindow): statusText = _translate( "MainWindow", "Doing work necessary to send broadcast.") elif status == 'broadcastsent': - statusText = _translate("MainWindow", "Broadcast on %1").arg( + statusText = _translate("MainWindow", "Broadcast on {0}").format( l10n.formatTimestamp(lastactiontime)) elif status == 'toodifficult': statusText = _translate( "MainWindow", "Problem: The work demanded by the recipient is more" - " difficult than you are willing to do. %1" - ).arg(l10n.formatTimestamp(lastactiontime)) + " difficult than you are willing to do. {0}" + ).format(l10n.formatTimestamp(lastactiontime)) elif status == 'badkey': statusText = _translate( "MainWindow", "Problem: The recipient\'s encryption key is no good." - " Could not encrypt message. %1" - ).arg(l10n.formatTimestamp(lastactiontime)) + " Could not encrypt message. {0}" + ).format(l10n.formatTimestamp(lastactiontime)) elif status == 'forcepow': statusText = _translate( "MainWindow", "Forced difficulty override. Send should start soon.") else: statusText = _translate( - "MainWindow", "Unknown status: %1 %2").arg(status).arg( + "MainWindow", "Unknown status: {0} {1}").format(status, l10n.formatTimestamp(lastactiontime)) items = [ @@ -1599,9 +1599,9 @@ class MyForm(settingsmixin.SMainWindow): _translate( "MainWindow", "You may manage your keys by editing the keys.dat file stored in" - "\n %1 \n" + "\n {0} \n" "It is important that you back up this file." - ).arg(state.appdata), + ).format(state.appdata), QtGui.QMessageBox.Ok) elif sys.platform == 'win32' or sys.platform == 'win64': if state.appdata == '': @@ -1622,9 +1622,9 @@ class MyForm(settingsmixin.SMainWindow): _translate("MainWindow", "Open keys.dat?"), _translate( "MainWindow", - "You may manage your keys by editing the keys.dat file stored in\n %1 \n" + "You may manage your keys by editing the keys.dat file stored in\n {0} \n" "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.)").arg(state.appdata), + "(Be sure to close Bitmessage before making any changes.)").format(state.appdata), QtGui.QMessageBox.Yes, QtGui.QMessageBox.No) if reply == QtGui.QMessageBox.Yes: openKeysFile() @@ -1967,9 +1967,9 @@ class MyForm(settingsmixin.SMainWindow): self.notifiedNewVersion = ".".join(str(n) for n in version) self.updateStatusBar(_translate( "MainWindow", - "New version of PyBitmessage is available: %1. Download it" + "New version of PyBitmessage is available: {0}. Download it" " from https://github.com/Bitmessage/PyBitmessage/releases/latest" - ).arg(self.notifiedNewVersion) + ).format(self.notifiedNewVersion) ) def displayAlert(self, title, text, exitAfterUserClicksOk): @@ -2105,9 +2105,9 @@ class MyForm(settingsmixin.SMainWindow): _translate( "MainWindow", "The message that you are trying to send is too long" - " by %1 bytes. (The maximum is 261644 bytes). Please" + " by {0} bytes. (The maximum is 261644 bytes). Please" " cut it down before sending." - ).arg(len(message) - (2 ** 18 - 500))) + ).format(len(message) - (2 ** 18 - 500))) return acct = accountClass(fromAddress) @@ -2156,9 +2156,9 @@ class MyForm(settingsmixin.SMainWindow): "MainWindow", "Error: Your account wasn't registered at" " an email gateway. Sending registration" - " now as %1, please wait for the registration" + " now as {0}, please wait for the registration" " to be processed before retrying sending." - ).arg(email) + ).format(email) ) return status, addressVersionNumber, streamNumber = decodeAddress(toAddress)[:3] @@ -2173,58 +2173,58 @@ class MyForm(settingsmixin.SMainWindow): self.updateStatusBar(_translate( "MainWindow", "Error: Bitmessage addresses start with" - " BM- Please check the recipient address %1" - ).arg(toAddress)) + " BM- Please check the recipient address {0}" + ).format(toAddress)) elif status == 'checksumfailed': self.updateStatusBar(_translate( "MainWindow", - "Error: The recipient address %1 is not" + "Error: The recipient address {0} is not" " typed or copied correctly. Please check it." - ).arg(toAddress)) + ).format(toAddress)) elif status == 'invalidcharacters': self.updateStatusBar(_translate( "MainWindow", - "Error: The recipient address %1 contains" + "Error: The recipient address {0} contains" " invalid characters. Please check it." - ).arg(toAddress)) + ).format(toAddress)) elif status == 'versiontoohigh': self.updateStatusBar(_translate( "MainWindow", "Error: The version of the recipient address" - " %1 is too high. Either you need to upgrade" + " {0} is too high. Either you need to upgrade" " your Bitmessage software or your" " acquaintance is being clever." - ).arg(toAddress)) + ).format(toAddress)) elif status == 'ripetooshort': self.updateStatusBar(_translate( "MainWindow", "Error: Some data encoded in the recipient" - " address %1 is too short. There might be" + " address {0} is too short. There might be" " something wrong with the software of" " your acquaintance." - ).arg(toAddress)) + ).format(toAddress)) elif status == 'ripetoolong': self.updateStatusBar(_translate( "MainWindow", "Error: Some data encoded in the recipient" - " address %1 is too long. There might be" + " address {0} is too long. There might be" " something wrong with the software of" " your acquaintance." - ).arg(toAddress)) + ).format(toAddress)) elif status == 'varintmalformed': self.updateStatusBar(_translate( "MainWindow", "Error: Some data encoded in the recipient" - " address %1 is malformed. There might be" + " address {0} is malformed. There might be" " something wrong with the software of" " your acquaintance." - ).arg(toAddress)) + ).format(toAddress)) else: self.updateStatusBar(_translate( "MainWindow", "Error: Something is wrong with the" - " recipient address %1." - ).arg(toAddress)) + " recipient address {0}." + ).format(toAddress)) elif fromAddress == '': self.updateStatusBar(_translate( "MainWindow", @@ -2241,9 +2241,9 @@ class MyForm(settingsmixin.SMainWindow): _translate("MainWindow", "Address version number"), _translate( "MainWindow", - "Concerning the address %1, Bitmessage cannot understand address version numbers" - " of %2. Perhaps upgrade Bitmessage to the latest version." - ).arg(toAddress).arg(str(addressVersionNumber))) + "Concerning the address {0}, Bitmessage cannot understand address version numbers" + " of {1}. Perhaps upgrade Bitmessage to the latest version." + ).format(toAddress, str(addressVersionNumber))) continue if streamNumber > 1 or streamNumber == 0: QtGui.QMessageBox.about( @@ -2251,9 +2251,9 @@ class MyForm(settingsmixin.SMainWindow): _translate("MainWindow", "Stream number"), _translate( "MainWindow", - "Concerning the address %1, Bitmessage cannot handle stream numbers of %2." + "Concerning the address {0}, Bitmessage cannot handle stream numbers of {1}." " Perhaps upgrade Bitmessage to the latest version." - ).arg(toAddress).arg(str(streamNumber))) + ).format(toAddress, str(streamNumber))) continue self.statusbar.clearMessage() if state.statusIconColor == 'red': @@ -2342,7 +2342,7 @@ class MyForm(settingsmixin.SMainWindow): err, addr = self.namecoin.query(identities[-1].strip()) if err is not None: self.updateStatusBar( - _translate("MainWindow", "Error: %1").arg(err)) + _translate("MainWindow", "Error: {0}").format(err)) else: identities[-1] = addr self.ui.lineEditTo.setText("; ".join(identities)) @@ -2497,7 +2497,7 @@ class MyForm(settingsmixin.SMainWindow): 'bitmessagesettings', 'showtraynotifications'): self.notifierShow( _translate("MainWindow", "New Message"), - _translate("MainWindow", "From %1").arg( + _translate("MainWindow", "From {0}").format( unicode(acct.fromLabel, 'utf-8')), sound.SOUND_UNKNOWN ) @@ -2787,7 +2787,7 @@ class MyForm(settingsmixin.SMainWindow): self.quitAccepted = True self.updateStatusBar(_translate( - "MainWindow", "Shutting down PyBitmessage... %1%").arg(0)) + "MainWindow", "Shutting down PyBitmessage... {0}%").format(0)) if waitForConnection: self.updateStatusBar(_translate( @@ -2821,8 +2821,8 @@ class MyForm(settingsmixin.SMainWindow): maxWorkerQueue = curWorkerQueue if curWorkerQueue > 0: self.updateStatusBar(_translate( - "MainWindow", "Waiting for PoW to finish... %1%" - ).arg(50 * (maxWorkerQueue - curWorkerQueue) / + "MainWindow", "Waiting for PoW to finish... {0}%" + ).format(50 * (maxWorkerQueue - curWorkerQueue) / maxWorkerQueue)) time.sleep(0.5) QtCore.QCoreApplication.processEvents( @@ -2830,7 +2830,7 @@ class MyForm(settingsmixin.SMainWindow): ) self.updateStatusBar(_translate( - "MainWindow", "Shutting down Pybitmessage... %1%").arg(50)) + "MainWindow", "Shutting down Pybitmessage... {0}%").format(50)) QtCore.QCoreApplication.processEvents( QtCore.QEventLoop.AllEvents, 1000 @@ -2844,14 +2844,14 @@ class MyForm(settingsmixin.SMainWindow): # check if upload (of objects created locally) pending self.updateStatusBar(_translate( - "MainWindow", "Waiting for objects to be sent... %1%").arg(50)) + "MainWindow", "Waiting for objects to be sent... {0}%").format(50)) maxPendingUpload = max(1, pendingUpload()) while pendingUpload() > 1: self.updateStatusBar(_translate( "MainWindow", - "Waiting for objects to be sent... %1%" - ).arg(int(50 + 20 * (pendingUpload() / maxPendingUpload)))) + "Waiting for objects to be sent... {0}%" + ).format(int(50 + 20 * (pendingUpload() / maxPendingUpload)))) time.sleep(0.5) QtCore.QCoreApplication.processEvents( QtCore.QEventLoop.AllEvents, 1000 @@ -2866,7 +2866,7 @@ class MyForm(settingsmixin.SMainWindow): # save state and geometry self and all widgets self.updateStatusBar(_translate( - "MainWindow", "Saving settings... %1%").arg(70)) + "MainWindow", "Saving settings... {0}%").format(70)) QtCore.QCoreApplication.processEvents( QtCore.QEventLoop.AllEvents, 1000 ) @@ -2879,18 +2879,18 @@ class MyForm(settingsmixin.SMainWindow): obj.saveSettings() self.updateStatusBar(_translate( - "MainWindow", "Shutting down core... %1%").arg(80)) + "MainWindow", "Shutting down core... {0}%").format(80)) QtCore.QCoreApplication.processEvents( QtCore.QEventLoop.AllEvents, 1000 ) shutdown.doCleanShutdown() self.updateStatusBar(_translate( - "MainWindow", "Stopping notifications... %1%").arg(90)) + "MainWindow", "Stopping notifications... {0}%").format(90)) self.tray.hide() self.updateStatusBar(_translate( - "MainWindow", "Shutdown imminent... %1%").arg(100)) + "MainWindow", "Shutdown imminent... {0}%").format(100)) logger.info("Shutdown complete") self.close() @@ -3063,9 +3063,9 @@ class MyForm(settingsmixin.SMainWindow): self, _translate("MainWindow", "Address is gone"), _translate( "MainWindow", - "Bitmessage cannot find your address %1. Perhaps you" + "Bitmessage cannot find your address {0}. Perhaps you" " removed it?" - ).arg(toAddressAtCurrentInboxRow), QtGui.QMessageBox.Ok) + ).format(toAddressAtCurrentInboxRow), QtGui.QMessageBox.Ok) elif not config.getboolean( toAddressAtCurrentInboxRow, 'enabled'): QtGui.QMessageBox.information( diff --git a/src/bitmessageqt/dialogs.py b/src/bitmessageqt/dialogs.py index dc31e266..bba7421e 100644 --- a/src/bitmessageqt/dialogs.py +++ b/src/bitmessageqt/dialogs.py @@ -64,8 +64,8 @@ class IconGlossaryDialog(QtGui.QDialog): self.labelPortNumber.setText(_translate( "iconGlossaryDialog", - "You are using TCP port %1. (This can be changed in the settings)." - ).arg(config.getint('bitmessagesettings', 'port'))) + "You are using TCP port {0}. (This can be changed in the settings)." + ).format(config.getint('bitmessagesettings', 'port'))) self.setFixedSize(QtGui.QWidget.sizeHint(self)) diff --git a/src/bitmessageqt/messagecompose.py b/src/bitmessageqt/messagecompose.py index c51282f8..8cd0e7ff 100644 --- a/src/bitmessageqt/messagecompose.py +++ b/src/bitmessageqt/messagecompose.py @@ -24,7 +24,7 @@ class MessageCompose(QtGui.QTextEdit): self.zoomOut(1) zoom = self.currentFont().pointSize() * 100 / self.defaultFontPointSize QtGui.QApplication.activeWindow().statusBar().showMessage( - QtGui.QApplication.translate("MainWindow", "Zoom level %1%").arg( + QtGui.QApplication.translate("MainWindow", "Zoom level {0}%").format( str(zoom) ) ) diff --git a/src/bitmessageqt/messageview.py b/src/bitmessageqt/messageview.py index 13ea16f9..4c17569c 100644 --- a/src/bitmessageqt/messageview.py +++ b/src/bitmessageqt/messageview.py @@ -56,7 +56,7 @@ class MessageView(QtGui.QTextBrowser): ) == QtCore.Qt.ControlModifier and event.orientation() == QtCore.Qt.Vertical: zoom = self.currentFont().pointSize() * 100 / self.defaultFontPointSize QtGui.QApplication.activeWindow().statusBar().showMessage(_translate( - "MainWindow", "Zoom level %1%").arg(str(zoom))) + "MainWindow", "Zoom level {0}%").format(str(zoom))) def setWrappingWidth(self, width=None): """Set word-wrapping width""" @@ -90,8 +90,8 @@ class MessageView(QtGui.QTextBrowser): "Follow external link"), QtGui.QApplication.translate( "MessageView", - "The link \"%1\" will open in a browser. It may be a security risk, it could de-anonymise you" - " or download malicious data. Are you sure?").arg(unicode(link.toString())), + "The link \"{0}\" will open in a browser. It may be a security risk, it could de-anonymise you" + " or download malicious data. Are you sure?").format(unicode(link.toString())), QtGui.QMessageBox.Yes, QtGui.QMessageBox.No) if reply == QtGui.QMessageBox.Yes: diff --git a/src/bitmessageqt/networkstatus.py b/src/bitmessageqt/networkstatus.py index 5d669f39..dbaf8fd0 100644 --- a/src/bitmessageqt/networkstatus.py +++ b/src/bitmessageqt/networkstatus.py @@ -134,12 +134,12 @@ class NetworkStatus(QtGui.QWidget, RetranslateMixin): self.labelBytesRecvCount.setText( _translate( "networkstatus", - "Down: %1/s Total: %2").arg( + "Down: {0}/s Total: {1}").format( self.formatByteRate(network.stats.downloadSpeed()), self.formatBytes(network.stats.receivedBytes()))) self.labelBytesSentCount.setText( _translate( - "networkstatus", "Up: %1/s Total: %2").arg( + "networkstatus", "Up: {0}/s Total: {1}").format( self.formatByteRate(network.stats.uploadSpeed()), self.formatBytes(network.stats.sentBytes()))) @@ -214,7 +214,7 @@ class NetworkStatus(QtGui.QWidget, RetranslateMixin): self.tableWidgetConnectionCount.setSortingEnabled(True) self.labelTotalConnections.setText( _translate( - "networkstatus", "Total Connections: %1").arg( + "networkstatus", "Total Connections: {0}").format( str(self.tableWidgetConnectionCount.rowCount()))) # FYI: The 'singlelistener' thread sets the icon color to green when it # receives an incoming connection, meaning that the user's firewall is @@ -227,7 +227,7 @@ class NetworkStatus(QtGui.QWidget, RetranslateMixin): # timer driven def runEveryTwoSeconds(self): """Updates counters, runs every 2 seconds if the timer is running""" - self.labelLookupsPerSecond.setText(_translate("networkstatus", "Inventory lookups per second: %1").arg( + self.labelLookupsPerSecond.setText(_translate("networkstatus", "Inventory lookups per second: {0}").format( str(state.Inventory.numberOfInventoryLookupsPerformed / 2))) state.Inventory.numberOfInventoryLookupsPerformed = 0 self.updateNumberOfBytes() @@ -238,11 +238,11 @@ class NetworkStatus(QtGui.QWidget, RetranslateMixin): super(NetworkStatus, self).retranslateUi() self.labelTotalConnections.setText( _translate( - "networkstatus", "Total Connections: %1").arg( + "networkstatus", "Total Connections: {0}").format( str(self.tableWidgetConnectionCount.rowCount()))) self.labelStartupTime.setText(_translate( - "networkstatus", "Since startup on %1" - ).arg(l10n.formatTimestamp(self.startup))) + "networkstatus", "Since startup on {0}" + ).format(l10n.formatTimestamp(self.startup))) self.updateNumberOfMessagesProcessed() self.updateNumberOfBroadcastsProcessed() self.updateNumberOfPubkeysProcessed() diff --git a/src/bitmessageqt/newchandialog.py b/src/bitmessageqt/newchandialog.py index c0629cd7..35087543 100644 --- a/src/bitmessageqt/newchandialog.py +++ b/src/bitmessageqt/newchandialog.py @@ -66,7 +66,7 @@ class NewChanDialog(QtGui.QDialog): addressGeneratorReturnValue = apiAddressGeneratorReturnQueue.get(True) if addressGeneratorReturnValue and addressGeneratorReturnValue[0] != 'chan name does not match address': UISignalQueue.put(('updateStatusBar', _translate( - "newchandialog", "Successfully created / joined chan %1").arg(unicode(self.chanPassPhrase.text())))) + "newchandialog", "Successfully created / joined chan {0}").format(unicode(self.chanPassPhrase.text())))) self.parent.ui.tabWidget.setCurrentIndex( self.parent.ui.tabWidget.indexOf(self.parent.ui.chans) ) diff --git a/src/class_addressGenerator.py b/src/class_addressGenerator.py index 33da1371..7ceb539a 100644 --- a/src/class_addressGenerator.py +++ b/src/class_addressGenerator.py @@ -211,8 +211,8 @@ class addressGenerator(StoppableThread): 'updateStatusBar', _translate( "MainWindow", - "Generating %1 new addresses." - ).arg(str(numberOfAddressesToMake)) + "Generating {0} new addresses." + ).format(str(numberOfAddressesToMake)) )) signingKeyNonce = 0 encryptionKeyNonce = 1 @@ -302,9 +302,9 @@ class addressGenerator(StoppableThread): 'updateStatusBar', _translate( "MainWindow", - "%1 is already in 'Your Identities'." + "{0} is already in 'Your Identities'." " Not adding it again." - ).arg(address) + ).format(address) )) else: self.logger.debug('label: %s', label) diff --git a/src/class_objectProcessor.py b/src/class_objectProcessor.py index 469ccbfa..f9feb183 100644 --- a/src/class_objectProcessor.py +++ b/src/class_objectProcessor.py @@ -151,8 +151,8 @@ class objectProcessor(threading.Thread): data[readPosition:], _translate( "MainWindow", - "Acknowledgement of the message received %1" - ).arg(l10n.formatTimestamp())) + "Acknowledgement of the message received {0}" + ).format(l10n.formatTimestamp())) )) else: logger.debug('This object is not an acknowledgement bound for me.') diff --git a/src/class_singleWorker.py b/src/class_singleWorker.py index f2821f65..45b7621f 100644 --- a/src/class_singleWorker.py +++ b/src/class_singleWorker.py @@ -697,8 +697,8 @@ class singleWorker(StoppableThread): ackdata, tr._translate( "MainWindow", - "Broadcast sent on %1" - ).arg(l10n.formatTimestamp())) + "Broadcast sent on {0}" + ).format(l10n.formatTimestamp())) )) # Update the status of the message in the 'sent' table to have @@ -969,8 +969,8 @@ class singleWorker(StoppableThread): " device who requests that the" " destination be included in the" " message but this is disallowed in" - " your settings. %1" - ).arg(l10n.formatTimestamp())) + " your settings. {0}" + ).format(l10n.formatTimestamp())) )) # if the human changes their setting and then # sends another message or restarts their client, @@ -1035,14 +1035,13 @@ class singleWorker(StoppableThread): tr._translate( "MainWindow", "Doing work necessary to send message.\n" - "Receiver\'s required difficulty: %1" - " and %2" - ).arg( + "Receiver\'s required difficulty: {0}" + " and {1}" + ).format( str( float(requiredAverageProofOfWorkNonceTrialsPerByte) / defaults.networkDefaultProofOfWorkNonceTrialsPerByte - ) - ).arg( + ), str( float(requiredPayloadLengthExtraBytes) / defaults.networkDefaultPayloadLengthExtraBytes @@ -1075,14 +1074,14 @@ class singleWorker(StoppableThread): tr._translate( "MainWindow", "Problem: The work demanded by" - " the recipient (%1 and %2) is" + " the recipient ({0} and {1}) is" " more difficult than you are" - " willing to do. %3" - ).arg(str(float(requiredAverageProofOfWorkNonceTrialsPerByte) - / defaults.networkDefaultProofOfWorkNonceTrialsPerByte) - ).arg(str(float(requiredPayloadLengthExtraBytes) - / defaults.networkDefaultPayloadLengthExtraBytes) - ).arg(l10n.formatTimestamp())))) + " willing to do. {2}" + ).format(str(float(requiredAverageProofOfWorkNonceTrialsPerByte) + / defaults.networkDefaultProofOfWorkNonceTrialsPerByte), + str(float(requiredPayloadLengthExtraBytes) + / defaults.networkDefaultPayloadLengthExtraBytes), + l10n.formatTimestamp())))) continue else: # if we are sending a message to ourselves or a chan.. self.logger.info('Sending a message.') @@ -1103,8 +1102,8 @@ class singleWorker(StoppableThread): " message to yourself or a chan but your" " encryption key could not be found in" " the keys.dat file. Could not encrypt" - " message. %1" - ).arg(l10n.formatTimestamp())) + " message. {0}" + ).format(l10n.formatTimestamp())) )) self.logger.error( 'Error within sendMsg. Could not read the keys' @@ -1241,8 +1240,8 @@ class singleWorker(StoppableThread): tr._translate( "MainWindow", "Problem: The recipient\'s encryption key is" - " no good. Could not encrypt message. %1" - ).arg(l10n.formatTimestamp())) + " no good. Could not encrypt message. {0}" + ).format(l10n.formatTimestamp())) )) continue @@ -1309,8 +1308,8 @@ class singleWorker(StoppableThread): ackdata, tr._translate( "MainWindow", - "Message sent. Sent at %1" - ).arg(l10n.formatTimestamp())))) + "Message sent. Sent at {0}" + ).format(l10n.formatTimestamp())))) else: # not sending to a chan or one of my addresses queues.UISignalQueue.put(( @@ -1319,8 +1318,8 @@ class singleWorker(StoppableThread): tr._translate( "MainWindow", "Message sent. Waiting for acknowledgement." - " Sent on %1" - ).arg(l10n.formatTimestamp())) + " Sent on {0}" + ).format(l10n.formatTimestamp())) )) self.logger.info( 'Broadcasting inv for my msg(within sendmsg function): %s', @@ -1483,8 +1482,8 @@ class singleWorker(StoppableThread): tr._translate( "MainWindow", "Sending public key request. Waiting for reply." - " Requested at %1" - ).arg(l10n.formatTimestamp())) + " Requested at {0}" + ).format(l10n.formatTimestamp())) )) def generateFullAckMessage(self, ackdata, _, TTL): diff --git a/src/namecoin.py b/src/namecoin.py index a16cb3d7..7311cd42 100644 --- a/src/namecoin.py +++ b/src/namecoin.py @@ -96,8 +96,8 @@ class namecoinConnection(object): res = res["reply"] if not res: return (_translate( - "MainWindow", "The name %1 was not found." - ).arg(identity.decode("utf-8", "ignore")), None) + "MainWindow", "The name {0} was not found." + ).format(identity.decode("utf-8", "ignore")), None) else: assert False except RPCError as exc: @@ -107,12 +107,12 @@ class namecoinConnection(object): else: errmsg = exc.error return (_translate( - "MainWindow", "The namecoin query failed (%1)" - ).arg(errmsg.decode("utf-8", "ignore")), None) + "MainWindow", "The namecoin query failed ({0})" + ).format(errmsg.decode("utf-8", "ignore")), None) except AssertionError: return (_translate( - "MainWindow", "Unknown namecoin interface type: %1" - ).arg(self.nmctype.decode("utf-8", "ignore")), None) + "MainWindow", "Unknown namecoin interface type: {0}" + ).format(self.nmctype.decode("utf-8", "ignore")), None) except Exception: logger.exception("Namecoin query exception") return (_translate( @@ -135,8 +135,8 @@ class namecoinConnection(object): ) if valid else ( _translate( "MainWindow", - "The name %1 has no associated Bitmessage address." - ).arg(identity.decode("utf-8", "ignore")), None) + "The name {0} has no associated Bitmessage address." + ).format(identity.decode("utf-8", "ignore")), None) def test(self): """ @@ -164,7 +164,7 @@ class namecoinConnection(object): "success", _translate( "MainWindow", - "Success! Namecoind version %1 running.").arg( + "Success! Namecoind version {0} running.").format( versStr.decode("utf-8", "ignore"))) elif self.nmctype == "nmcontrol": diff --git a/src/network/tcp.py b/src/network/tcp.py index 139715a6..72d6a421 100644 --- a/src/network/tcp.py +++ b/src/network/tcp.py @@ -138,9 +138,9 @@ class TCPConnection(BMProto, TLSDispatcher): 'updateStatusBar', _translate( "MainWindow", - "The time on your computer, %1, may be wrong. " + "The time on your computer, {0}, may be wrong. " "Please verify your settings." - ).arg(l10n.formatTimestamp()))) + ).format(l10n.formatTimestamp()))) def state_connection_fully_established(self): """ diff --git a/src/upnp.py b/src/upnp.py index 42ff0c6d..8776e0f9 100644 --- a/src/upnp.py +++ b/src/upnp.py @@ -269,8 +269,8 @@ class uPnPThread(StoppableThread): knownnodes.addKnownNode( 1, self_peer, is_self=True) queues.UISignalQueue.put(('updateStatusBar', tr._translate( - "MainWindow", 'UPnP port mapping established on port %1' - ).arg(str(self.extPort)))) + "MainWindow", 'UPnP port mapping established on port {0}' + ).format(str(self.extPort)))) break except socket.timeout: pass -- 2.45.1 From 046a29e1a88d557136a608b4e65f92ff3854d8ba Mon Sep 17 00:00:00 2001 From: Kashiko Koibumi Date: Thu, 23 May 2024 13:28:40 +0900 Subject: [PATCH 038/105] stop using QString --- src/bitmessageqt/__init__.py | 129 ++++++++++++++------------- src/bitmessageqt/account.py | 18 ++-- src/bitmessageqt/address_dialogs.py | 31 +++---- src/bitmessageqt/addressvalidator.py | 7 +- src/bitmessageqt/blacklist.py | 33 +++---- src/bitmessageqt/dialogs.py | 7 +- src/bitmessageqt/foldertree.py | 76 ++++++++-------- src/bitmessageqt/messageview.py | 15 ++-- src/bitmessageqt/networkstatus.py | 4 +- src/bitmessageqt/newchandialog.py | 15 ++-- src/bitmessageqt/retranslateui.py | 7 +- src/bitmessageqt/safehtmlparser.py | 6 +- src/bitmessageqt/settings.py | 27 +++--- src/bitmessageqt/settingsmixin.py | 5 +- src/bitmessageqt/support.py | 13 +-- src/bitmessageqt/tests/main.py | 2 +- src/bitmessageqt/tests/support.py | 6 +- src/depends.py | 14 +++ src/tr.py | 4 +- src/ver.py | 30 +++++++ 20 files changed, 252 insertions(+), 197 deletions(-) create mode 100644 src/ver.py diff --git a/src/bitmessageqt/__init__.py b/src/bitmessageqt/__init__.py index 122a878c..a4a7bb60 100644 --- a/src/bitmessageqt/__init__.py +++ b/src/bitmessageqt/__init__.py @@ -15,6 +15,7 @@ import time from datetime import datetime, timedelta from sqlite3 import register_adapter +from ver import ustr, unic from PyQt4 import QtCore, QtGui from PyQt4.QtNetwork import QLocalSocket, QLocalServer @@ -120,7 +121,7 @@ class MyForm(settingsmixin.SMainWindow): paths.codePath(), 'translations', 'qt_' + newlocale) else: translationpath = os.path.join( - str(QtCore.QLibraryInfo.location( + ustr(QtCore.QLibraryInfo.location( QtCore.QLibraryInfo.TranslationsPath)), 'qt_' + newlocale) self.qsystranslator.load(translationpath) QtGui.QApplication.installTranslator(self.qsystranslator) @@ -1186,11 +1187,11 @@ class MyForm(settingsmixin.SMainWindow): items = [ MessageList_AddressWidget( - toAddress, unicode(acct.toLabel, 'utf-8')), + toAddress, unic(ustr(acct.toLabel))), MessageList_AddressWidget( - fromAddress, unicode(acct.fromLabel, 'utf-8')), + fromAddress, unic(ustr(acct.fromLabel))), MessageList_SubjectWidget( - str(subject), unicode(acct.subject, 'utf-8', 'replace')), + ustr(subject), unic(ustr(acct.subject))), MessageList_TimeWidget( statusText, False, lastactiontime, ackdata)] self.addMessageListItem(tableWidget, items) @@ -1211,11 +1212,11 @@ class MyForm(settingsmixin.SMainWindow): items = [ MessageList_AddressWidget( - toAddress, unicode(acct.toLabel, 'utf-8'), not read), + toAddress, unic(ustr(acct.toLabel)), not read), MessageList_AddressWidget( - fromAddress, unicode(acct.fromLabel, 'utf-8'), not read), + fromAddress, unic(ustr(acct.fromLabel)), not read), MessageList_SubjectWidget( - str(subject), unicode(acct.subject, 'utf-8', 'replace'), + ustr(subject), unic(ustr(acct.subject)), not read), MessageList_TimeWidget( l10n.formatTimestamp(received), not read, received, msgid) @@ -1496,7 +1497,7 @@ class MyForm(settingsmixin.SMainWindow): self, title, subtitle, category, label=None, icon=None): self.playSound(category, label) self._notifier( - unicode(title), unicode(subtitle), category, label, icon) + unic(ustr(title)), unic(ustr(subtitle)), category, label, icon) # tree def treeWidgetKeyPressEvent(self, event): @@ -1699,7 +1700,7 @@ class MyForm(settingsmixin.SMainWindow): addressVersionNumber, streamNumberForAddress, "regenerated deterministic address", dialog.spinBoxNumberOfAddressesToMake.value(), - dialog.lineEditPassphrase.text().toUtf8(), + ustr(dialog.lineEditPassphrase.text()), dialog.checkBoxEighteenByteRipe.isChecked() )) self.ui.tabWidget.setCurrentIndex( @@ -1995,9 +1996,9 @@ class MyForm(settingsmixin.SMainWindow): def rerenderAddressBook(self): def addRow (address, label, type): self.ui.tableWidgetAddressBook.insertRow(0) - newItem = Ui_AddressBookWidgetItemLabel(address, unicode(label, 'utf-8'), type) + newItem = Ui_AddressBookWidgetItemLabel(address, unic(ustr(label)), type) self.ui.tableWidgetAddressBook.setItem(0, 0, newItem) - newItem = Ui_AddressBookWidgetItemAddress(address, unicode(label, 'utf-8'), type) + newItem = Ui_AddressBookWidgetItemAddress(address, unic(ustr(label)), type) self.ui.tableWidgetAddressBook.setItem(0, 1, newItem) oldRows = {} @@ -2038,7 +2039,7 @@ class MyForm(settingsmixin.SMainWindow): self.ui.tableWidgetAddressBook.removeRow(oldRows[address][2]) for address in newRows: addRow(address, newRows[address][0], newRows[address][1]) - completerList.append(unicode(newRows[address][0], encoding="UTF-8") + " <" + address + ">") + completerList.append(unic(ustr(newRows[address][0]) + " <" + ustr(address) + ">")) # sort self.ui.tableWidgetAddressBook.sortByColumn( @@ -2076,22 +2077,22 @@ class MyForm(settingsmixin.SMainWindow): self.ui.tabWidgetSend.indexOf(self.ui.sendDirect): # message to specific people sendMessageToPeople = True - fromAddress = str(self.ui.comboBoxSendFrom.itemData( + fromAddress = ustr(self.ui.comboBoxSendFrom.itemData( self.ui.comboBoxSendFrom.currentIndex(), - QtCore.Qt.UserRole).toString()) - toAddresses = str(self.ui.lineEditTo.text().toUtf8()) - subject = str(self.ui.lineEditSubject.text().toUtf8()) - message = str( - self.ui.textEditMessage.document().toPlainText().toUtf8()) + QtCore.Qt.UserRole)) + toAddresses = ustr(self.ui.lineEditTo.text()) + subject = ustr(self.ui.lineEditSubject.text()) + message = ustr( + self.ui.textEditMessage.document().toPlainText()) else: # broadcast message sendMessageToPeople = False - fromAddress = str(self.ui.comboBoxSendFromBroadcast.itemData( + fromAddress = ustr(self.ui.comboBoxSendFromBroadcast.itemData( self.ui.comboBoxSendFromBroadcast.currentIndex(), - QtCore.Qt.UserRole).toString()) - subject = str(self.ui.lineEditSubjectBroadcast.text().toUtf8()) - message = str( - self.ui.textEditMessageBroadcast.document().toPlainText().toUtf8()) + QtCore.Qt.UserRole)) + subject = ustr(self.ui.lineEditSubjectBroadcast.text()) + message = ustr( + self.ui.textEditMessageBroadcast.document().toPlainText()) """ The whole network message must fit in 2^18 bytes. Let's assume 500 bytes of overhead. If someone wants to get that @@ -2164,7 +2165,7 @@ class MyForm(settingsmixin.SMainWindow): status, addressVersionNumber, streamNumber = decodeAddress(toAddress)[:3] if status != 'success': try: - toAddress = unicode(toAddress, 'utf-8', 'ignore') + toAddress = unic(ustr(toAddress)) except: pass logger.error('Error: Could not decode recipient address ' + toAddress + ':' + status) @@ -2338,7 +2339,7 @@ class MyForm(settingsmixin.SMainWindow): )) def click_pushButtonFetchNamecoinID(self): - identities = str(self.ui.lineEditTo.text().toUtf8()).split(";") + identities = ustr(self.ui.lineEditTo.text()).split(";") err, addr = self.namecoin.query(identities[-1].strip()) if err is not None: self.updateStatusBar( @@ -2355,7 +2356,7 @@ class MyForm(settingsmixin.SMainWindow): self.ui.tabWidgetSend.setCurrentIndex( self.ui.tabWidgetSend.indexOf( self.ui.sendBroadcast - if config.safeGetBoolean(str(address), 'mailinglist') + if config.safeGetBoolean(ustr(address), 'mailinglist') else self.ui.sendDirect )) @@ -2368,14 +2369,14 @@ class MyForm(settingsmixin.SMainWindow): addressInKeysFile, 'enabled') isMaillinglist = config.safeGetBoolean(addressInKeysFile, 'mailinglist') if isEnabled and not isMaillinglist: - label = unicode(config.get(addressInKeysFile, 'label'), 'utf-8', 'ignore').strip() + label = unic(ustr(config.get(addressInKeysFile, 'label')).strip()) if label == "": label = addressInKeysFile self.ui.comboBoxSendFrom.addItem(avatarize(addressInKeysFile), label, addressInKeysFile) # self.ui.comboBoxSendFrom.model().sort(1, Qt.AscendingOrder) for i in range(self.ui.comboBoxSendFrom.count()): - address = str(self.ui.comboBoxSendFrom.itemData( - i, QtCore.Qt.UserRole).toString()) + address = ustr(self.ui.comboBoxSendFrom.itemData( + i, QtCore.Qt.UserRole)) self.ui.comboBoxSendFrom.setItemData( i, AccountColor(address).accountColor(), QtCore.Qt.ForegroundRole) @@ -2392,13 +2393,13 @@ class MyForm(settingsmixin.SMainWindow): addressInKeysFile, 'enabled') isChan = config.safeGetBoolean(addressInKeysFile, 'chan') if isEnabled and not isChan: - label = unicode(config.get(addressInKeysFile, 'label'), 'utf-8', 'ignore').strip() + label = unic(ustr(config.get(addressInKeysFile, 'label')).strip()) if label == "": label = addressInKeysFile self.ui.comboBoxSendFromBroadcast.addItem(avatarize(addressInKeysFile), label, addressInKeysFile) for i in range(self.ui.comboBoxSendFromBroadcast.count()): - address = str(self.ui.comboBoxSendFromBroadcast.itemData( - i, QtCore.Qt.UserRole).toString()) + address = ustr(self.ui.comboBoxSendFromBroadcast.itemData( + i, QtCore.Qt.UserRole)) self.ui.comboBoxSendFromBroadcast.setItemData( i, AccountColor(address).accountColor(), QtCore.Qt.ForegroundRole) @@ -2498,7 +2499,7 @@ class MyForm(settingsmixin.SMainWindow): self.notifierShow( _translate("MainWindow", "New Message"), _translate("MainWindow", "From {0}").format( - unicode(acct.fromLabel, 'utf-8')), + unic(ustr(acct.fromLabel))), sound.SOUND_UNKNOWN ) if self.getCurrentAccount() is not None and ( @@ -2636,7 +2637,7 @@ class MyForm(settingsmixin.SMainWindow): # Only settings remain here acct.settings() for i in range(self.ui.comboBoxSendFrom.count()): - if str(self.ui.comboBoxSendFrom.itemData(i).toPyObject()) \ + if ustr(self.ui.comboBoxSendFrom.itemData(i)) \ == acct.fromAddress: self.ui.comboBoxSendFrom.setCurrentIndex(i) break @@ -2703,7 +2704,7 @@ class MyForm(settingsmixin.SMainWindow): if reply != QtGui.QMessageBox.Yes: return config.set( - 'bitmessagesettings', 'dontconnect', str(dontconnect_option)) + 'bitmessagesettings', 'dontconnect', ustr(dontconnect_option)) config.save() self.ui.updateNetworkSwitchMenuLabel(dontconnect_option) @@ -2934,8 +2935,8 @@ class MyForm(settingsmixin.SMainWindow): lines[i] = '

' content = ' '.join(lines) # To keep the whitespace between lines content = shared.fixPotentiallyInvalidUTF8Data(content) - content = unicode(content, 'utf-8)') - textEdit.setHtml(QtCore.QString(content)) + content = unic(ustr(content)) + textEdit.setHtml(content) def on_action_InboxMarkUnread(self): tableWidget = self.getCurrentMessagelist() @@ -3002,7 +3003,7 @@ class MyForm(settingsmixin.SMainWindow): self.ui.comboBoxSendFrom, self.ui.comboBoxSendFromBroadcast ): for i in range(box.count()): - if str(box.itemData(i).toPyObject()) == address: + if ustr(box.itemData(i)) == ustr(address): box.setCurrentIndex(i) break else: @@ -3093,7 +3094,7 @@ class MyForm(settingsmixin.SMainWindow): tableWidget.item(currentInboxRow, column_from).label or ( isinstance(acct, GatewayAccount) and fromAddressAtCurrentInboxRow == acct.relayAddress): - self.ui.lineEditTo.setText(str(acct.fromAddress)) + self.ui.lineEditTo.setText(ustr(acct.fromAddress)) else: self.ui.lineEditTo.setText( tableWidget.item(currentInboxRow, column_from).accountString() @@ -3108,7 +3109,7 @@ class MyForm(settingsmixin.SMainWindow): ' reply to the chan address.') if toAddressAtCurrentInboxRow == \ tableWidget.item(currentInboxRow, column_to).label: - self.ui.lineEditTo.setText(str(toAddressAtCurrentInboxRow)) + self.ui.lineEditTo.setText(ustr(toAddressAtCurrentInboxRow)) else: self.ui.lineEditTo.setText( tableWidget.item(currentInboxRow, column_to).accountString() @@ -3117,7 +3118,7 @@ class MyForm(settingsmixin.SMainWindow): self.setSendFromComboBox(toAddressAtCurrentInboxRow) quotedText = self.quoted_text( - unicode(messageAtCurrentInboxRow, 'utf-8', 'replace')) + unic(ustr(messageAtCurrentInboxRow))) widget['message'].setPlainText(quotedText) if acct.subject[0:3] in ('Re:', 'RE:'): widget['subject'].setText( @@ -3262,7 +3263,7 @@ class MyForm(settingsmixin.SMainWindow): return currentInboxRow = tableWidget.currentRow() try: - subjectAtCurrentInboxRow = str(tableWidget.item( + subjectAtCurrentInboxRow = ustr(tableWidget.item( currentInboxRow, 2).data(QtCore.Qt.UserRole)) except: subjectAtCurrentInboxRow = '' @@ -3334,7 +3335,7 @@ class MyForm(settingsmixin.SMainWindow): addressAtCurrentRow = self.ui.tableWidgetInbox.item( currentRow, 0).data(QtCore.Qt.UserRole) clipboard = QtGui.QApplication.clipboard() - clipboard.setText(str(addressAtCurrentRow)) + clipboard.setText(ustr(addressAtCurrentRow)) # Group of functions for the Address Book dialog box def on_action_AddressBookNew(self): @@ -3368,8 +3369,8 @@ class MyForm(settingsmixin.SMainWindow): return self.updateStatusBar(_translate( "MainWindow", "No addresses selected.")) - addresses_string = unicode( - self.ui.lineEditTo.text().toUtf8(), 'utf-8') + addresses_string = unic(ustr( + self.ui.lineEditTo.text())) for item in selected_items: address_string = item.accountString() if not addresses_string: @@ -3455,7 +3456,7 @@ class MyForm(settingsmixin.SMainWindow): def on_action_SubscriptionsClipboard(self): address = self.getCurrentAccount() clipboard = QtGui.QApplication.clipboard() - clipboard.setText(str(address)) + clipboard.setText(ustr(address)) def on_action_SubscriptionsEnable(self): address = self.getCurrentAccount() @@ -3607,9 +3608,9 @@ class MyForm(settingsmixin.SMainWindow): self.ui.inboxSearchLineEditChans, ) if currentIndex >= 0 and currentIndex < len(messagelistList): - return ( + return ustr( messagelistList[currentIndex] if retObj - else messagelistList[currentIndex].text().toUtf8().data()) + else ustr(messagelistList[currentIndex].text())) def getCurrentSearchOption(self, currentIndex=None): if currentIndex is None: @@ -3678,7 +3679,7 @@ class MyForm(settingsmixin.SMainWindow): " delete the channel?" ), QtGui.QMessageBox.Yes | QtGui.QMessageBox.No ) == QtGui.QMessageBox.Yes: - config.remove_section(str(account.address)) + config.remove_section(ustr(account.address)) else: return else: @@ -3711,7 +3712,7 @@ class MyForm(settingsmixin.SMainWindow): account.setEnabled(False) def disableIdentity(self, address): - config.set(str(address), 'enabled', 'false') + config.set(ustr(address), 'enabled', 'false') config.save() shared.reloadMyAddressHashes() self.rerenderAddressBook() @@ -3719,7 +3720,7 @@ class MyForm(settingsmixin.SMainWindow): def on_action_Clipboard(self): address = self.getCurrentAccount() clipboard = QtGui.QApplication.clipboard() - clipboard.setText(str(address)) + clipboard.setText(ustr(address)) def on_action_ClipboardMessagelist(self): tableWidget = self.getCurrentMessagelist() @@ -3739,7 +3740,7 @@ class MyForm(settingsmixin.SMainWindow): if isinstance(account, GatewayAccount) and otherAddress == account.relayAddress and ( (currentColumn in [0, 2] and self.getCurrentFolder() == "sent") or (currentColumn in [1, 2] and self.getCurrentFolder() != "sent")): - text = str(tableWidget.item(currentRow, currentColumn).label) + text = ustr(tableWidget.item(currentRow, currentColumn).label) else: text = tableWidget.item(currentRow, currentColumn).data(QtCore.Qt.UserRole) @@ -3756,8 +3757,8 @@ class MyForm(settingsmixin.SMainWindow): def on_action_SetAvatar(self, thisTableWidget): currentRow = thisTableWidget.currentRow() - addressAtCurrentRow = thisTableWidget.item( - currentRow, 1).text() + addressAtCurrentRow = ustr(thisTableWidget.item( + currentRow, 1).text()) setToIdenticon = not self.setAvatar(addressAtCurrentRow) if setToIdenticon: thisTableWidget.item( @@ -3858,23 +3859,23 @@ class MyForm(settingsmixin.SMainWindow): def on_action_AddressBookSetSound(self): widget = self.ui.tableWidgetAddressBook - self.setAddressSound(widget.item(widget.currentRow(), 0).text()) + self.setAddressSound(ustr(widget.item(widget.currentRow(), 0).text())) def setAddressSound(self, addr): - filters = [unicode(_translate( + filters = [unic(_translate( "MainWindow", "Sound files (%s)" % ' '.join(['*%s%s' % (os.extsep, ext) for ext in sound.extensions]) ))] - sourcefile = unicode(QtGui.QFileDialog.getOpenFileName( + sourcefile = unic(ustr(QtGui.QFileDialog.getOpenFileName( self, _translate("MainWindow", "Set notification sound..."), filter=';;'.join(filters) - )) + ))) if not sourcefile: return destdir = os.path.join(state.appdata, 'sounds') - destfile = unicode(addr) + os.path.splitext(sourcefile)[-1] + destfile = unic(ustr(addr) + os.path.splitext(sourcefile)[-1]) destination = os.path.join(destdir, destfile) if sourcefile == destination: @@ -4027,7 +4028,7 @@ class MyForm(settingsmixin.SMainWindow): def inboxSearchLineEditUpdated(self, text): # dynamic search for too short text is slow - text = text.toUtf8() + text = ustr(text) if 0 < len(text) < 3: return messagelist = self.getCurrentMessagelist() @@ -4042,7 +4043,7 @@ class MyForm(settingsmixin.SMainWindow): logger.debug("Search return pressed") searchLine = self.getCurrentSearchLine() messagelist = self.getCurrentMessagelist() - if messagelist and len(str(searchLine)) < 3: + if messagelist and len(ustr(searchLine)) < 3: searchOption = self.getCurrentSearchOption() account = self.getCurrentAccount() folder = self.getCurrentFolder() @@ -4084,7 +4085,7 @@ class MyForm(settingsmixin.SMainWindow): if item.type == AccountMixin.ALL: return - newLabel = unicode(item.text(0), 'utf-8', 'ignore') + newLabel = unic(ustr(item.text(0))) oldLabel = item.defaultLabel() # unchanged, do not do anything either @@ -4155,8 +4156,8 @@ class MyForm(settingsmixin.SMainWindow): self.rerenderMessagelistToLabels() completerList = self.ui.lineEditTo.completer().model().stringList() for i in range(len(completerList)): - if unicode(completerList[i]).endswith(" <" + item.address + ">"): - completerList[i] = item.label + " <" + item.address + ">" + if unic(ustr(completerList[i])).endswith(" <" + ustr(item.address) + ">"): + completerList[i] = ustr(item.label) + " <" + ustr(item.address) + ">" self.ui.lineEditTo.completer().model().setStringList(completerList) def tabWidgetCurrentChanged(self, n): diff --git a/src/bitmessageqt/account.py b/src/bitmessageqt/account.py index 8c82c6f6..eefb3a7e 100644 --- a/src/bitmessageqt/account.py +++ b/src/bitmessageqt/account.py @@ -14,6 +14,7 @@ import re import sys import time +from ver import ustr from PyQt4 import QtGui import queues @@ -131,6 +132,8 @@ class BMAccount(object): """Get a label for this bitmessage account""" if address is None: address = self.address + else: + address = ustr(address) label = config.safeGet(address, 'label', address) queryreturn = sqlQuery( '''select label from addressbook where address=?''', address) @@ -148,15 +151,12 @@ class BMAccount(object): def parseMessage(self, toAddress, fromAddress, subject, message): """Set metadata and address labels on self""" - self.toAddress = toAddress - self.fromAddress = fromAddress - if isinstance(subject, unicode): - self.subject = str(subject) - else: - self.subject = subject - self.message = message - self.fromLabel = self.getLabel(fromAddress) - self.toLabel = self.getLabel(toAddress) + self.toAddress = ustr(toAddress) + self.fromAddress = ustr(fromAddress) + self.subject = ustr(subject) + self.message = ustr(message) + self.fromLabel = ustr(self.getLabel(fromAddress)) + self.toLabel = ustr(self.getLabel(toAddress)) class NoAccount(BMAccount): diff --git a/src/bitmessageqt/address_dialogs.py b/src/bitmessageqt/address_dialogs.py index bf571041..caf7f687 100644 --- a/src/bitmessageqt/address_dialogs.py +++ b/src/bitmessageqt/address_dialogs.py @@ -5,6 +5,7 @@ Dialogs that work with BM address. import hashlib +from ver import ustr, unic from PyQt4 import QtCore, QtGui import queues @@ -29,12 +30,12 @@ class AddressCheckMixin(object): def _onSuccess(self, addressVersion, streamNumber, ripe): pass - def addressChanged(self, QString): + def addressChanged(self, addr): """ Address validation callback, performs validation and gives feedback """ status, addressVersion, streamNumber, ripe = decodeAddress( - str(QString)) + ustr(addr)) self.valid = status == 'success' if self.valid: self.labelAddressCheck.setText( @@ -90,8 +91,8 @@ class AddressDataDialog(QtGui.QDialog, AddressCheckMixin): """Callback for QDIalog accepting value""" if self.valid: self.data = ( - addBMIfNotPresent(str(self.lineEditAddress.text())), - str(self.lineEditLabel.text().toUtf8()) + addBMIfNotPresent(ustr(self.lineEditAddress.text())), + ustr(self.lineEditLabel.text()) ) else: queues.UISignalQueue.put(('updateStatusBar', _translate( @@ -142,12 +143,12 @@ class NewAddressDialog(QtGui.QDialog): self.comboBoxExisting.currentText())[2] queues.addressGeneratorQueue.put(( 'createRandomAddress', 4, streamNumberForAddress, - str(self.newaddresslabel.text().toUtf8()), 1, "", + ustr(self.newaddresslabel.text()), 1, "", self.checkBoxEighteenByteRipe.isChecked() )) else: - if self.lineEditPassphrase.text() != \ - self.lineEditPassphraseAgain.text(): + if ustr(self.lineEditPassphrase.text()) != \ + ustr(self.lineEditPassphraseAgain.text()): QtGui.QMessageBox.about( self, _translate("MainWindow", "Passphrase mismatch"), _translate( @@ -169,7 +170,7 @@ class NewAddressDialog(QtGui.QDialog): 'createDeterministicAddresses', 4, streamNumberForAddress, "unused deterministic address", self.spinBoxNumberOfAddressesToMake.value(), - self.lineEditPassphrase.text().toUtf8(), + ustr(self.lineEditPassphrase.text()), self.checkBoxEighteenByteRipe.isChecked() )) @@ -234,7 +235,7 @@ class SpecialAddressBehaviorDialog(QtGui.QDialog): def __init__(self, parent=None, config=global_config): super(SpecialAddressBehaviorDialog, self).__init__(parent) widgets.load('specialaddressbehavior.ui', self) - self.address = parent.getCurrentAccount() + self.address = ustr(parent.getCurrentAccount()) self.parent = parent self.config = config @@ -259,7 +260,7 @@ class SpecialAddressBehaviorDialog(QtGui.QDialog): self.radioButtonBehaveNormalAddress.click() mailingListName = config.safeGet(self.address, 'mailinglistname', '') self.lineEditMailingListName.setText( - unicode(mailingListName, 'utf-8') + unic(ustr(mailingListName)) ) QtGui.QWidget.resize(self, QtGui.QWidget.sizeHint(self)) @@ -271,7 +272,7 @@ class SpecialAddressBehaviorDialog(QtGui.QDialog): if self.address_is_chan: return if self.radioButtonBehaveNormalAddress.isChecked(): - self.config.set(str(self.address), 'mailinglist', 'false') + self.config.set(self.address, 'mailinglist', 'false') # Set the color to either black or grey if self.config.getboolean(self.address, 'enabled'): self.parent.setCurrentItemColor( @@ -280,9 +281,9 @@ class SpecialAddressBehaviorDialog(QtGui.QDialog): 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.config.set(self.address, 'mailinglist', 'true') + self.config.set(self.address, 'mailinglistname', ustr( + self.lineEditMailingListName.text())) self.parent.setCurrentItemColor( QtGui.QColor(137, 4, 177)) # magenta self.parent.rerenderComboBoxSendFrom() @@ -344,7 +345,7 @@ class EmailGatewayDialog(QtGui.QDialog): if self.radioButtonRegister.isChecked() \ or self.radioButtonRegister.isHidden(): - email = str(self.lineEditEmail.text().toUtf8()) + email = ustr(self.lineEditEmail.text()) self.acct.register(email) self.config.set(self.acct.fromAddress, 'label', email) self.config.set(self.acct.fromAddress, 'gateway', 'mailchuck') diff --git a/src/bitmessageqt/addressvalidator.py b/src/bitmessageqt/addressvalidator.py index dc61b41c..fe939266 100644 --- a/src/bitmessageqt/addressvalidator.py +++ b/src/bitmessageqt/addressvalidator.py @@ -5,6 +5,7 @@ Address validator module. from Queue import Empty +from ver import ustr from PyQt4 import QtGui from addresses import decodeAddress, addBMIfNotPresent @@ -108,13 +109,13 @@ class AddressPassPhraseValidatorMixin(object): if self.addressObject is None: address = None else: - address = str(self.addressObject.text().toUtf8()) + address = ustr(self.addressObject.text()) if address == "": address = None if self.passPhraseObject is None: passPhrase = "" else: - passPhrase = str(self.passPhraseObject.text().toUtf8()) + passPhrase = ustr(self.passPhraseObject.text()) if passPhrase == "": passPhrase = None @@ -152,7 +153,7 @@ class AddressPassPhraseValidatorMixin(object): # check through generator if address is None: - addressGeneratorQueue.put(('createChan', 4, 1, str_chan + ' ' + str(passPhrase), passPhrase, False)) + addressGeneratorQueue.put(('createChan', 4, 1, str_chan + ' ' + ustr(passPhrase), passPhrase, False)) else: addressGeneratorQueue.put( ('joinChan', addBMIfNotPresent(address), diff --git a/src/bitmessageqt/blacklist.py b/src/bitmessageqt/blacklist.py index 093f23d8..5db3152f 100644 --- a/src/bitmessageqt/blacklist.py +++ b/src/bitmessageqt/blacklist.py @@ -1,3 +1,4 @@ +from ver import ustr, unic from PyQt4 import QtCore, QtGui import widgets @@ -59,7 +60,7 @@ class Blacklist(QtGui.QWidget, RetranslateMixin): if self.NewBlacklistDialogInstance.exec_(): if self.NewBlacklistDialogInstance.labelAddressCheck.text() == \ _translate("MainWindow", "Address is valid."): - address = addBMIfNotPresent(str( + address = addBMIfNotPresent(ustr( self.NewBlacklistDialogInstance.lineEditAddress.text())) # First we must check to see if the address is already in the # address book. The user cannot add it again or else it will @@ -73,8 +74,8 @@ class Blacklist(QtGui.QWidget, RetranslateMixin): if queryreturn == []: self.tableWidgetBlacklist.setSortingEnabled(False) self.tableWidgetBlacklist.insertRow(0) - newItem = QtGui.QTableWidgetItem(unicode( - self.NewBlacklistDialogInstance.lineEditLabel.text().toUtf8(), 'utf-8')) + newItem = QtGui.QTableWidgetItem(unic(ustr( + self.NewBlacklistDialogInstance.lineEditLabel.text()))) newItem.setIcon(avatarize(address)) self.tableWidgetBlacklist.setItem(0, 0, newItem) newItem = QtGui.QTableWidgetItem(address) @@ -82,7 +83,7 @@ class Blacklist(QtGui.QWidget, RetranslateMixin): QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) self.tableWidgetBlacklist.setItem(0, 1, newItem) self.tableWidgetBlacklist.setSortingEnabled(True) - t = (str(self.NewBlacklistDialogInstance.lineEditLabel.text().toUtf8()), address, True) + t = (ustr(self.NewBlacklistDialogInstance.lineEditLabel.text()), address, True) if config.get('bitmessagesettings', 'blackwhitelist') == 'black': sql = '''INSERT INTO blacklist VALUES (?,?,?)''' else: @@ -111,10 +112,10 @@ class Blacklist(QtGui.QWidget, RetranslateMixin): if isinstance(addressitem, QtGui.QTableWidgetItem): if self.radioButtonBlacklist.isChecked(): sqlExecute('''UPDATE blacklist SET label=? WHERE address=?''', - str(item.text()), str(addressitem.text())) + ustr(item.text()), ustr(addressitem.text())) else: sqlExecute('''UPDATE whitelist SET label=? WHERE address=?''', - str(item.text()), str(addressitem.text())) + ustr(item.text()), ustr(addressitem.text())) def init_blacklist_popup_menu(self, connectSignal=True): # Popup menu for the Blacklist page @@ -172,7 +173,7 @@ class Blacklist(QtGui.QWidget, RetranslateMixin): for row in queryreturn: label, address, enabled = row self.tableWidgetBlacklist.insertRow(0) - newItem = QtGui.QTableWidgetItem(unicode(label, 'utf-8')) + newItem = QtGui.QTableWidgetItem(unic(ustr(label))) if not enabled: newItem.setTextColor(QtGui.QColor(128, 128, 128)) newItem.setIcon(avatarize(address)) @@ -191,18 +192,18 @@ class Blacklist(QtGui.QWidget, RetranslateMixin): def on_action_BlacklistDelete(self): currentRow = self.tableWidgetBlacklist.currentRow() - labelAtCurrentRow = self.tableWidgetBlacklist.item( - currentRow, 0).text().toUtf8() + labelAtCurrentRow = ustr(self.tableWidgetBlacklist.item( + currentRow, 0).text()) addressAtCurrentRow = self.tableWidgetBlacklist.item( currentRow, 1).text() if config.get('bitmessagesettings', 'blackwhitelist') == 'black': sqlExecute( '''DELETE FROM blacklist WHERE label=? AND address=?''', - str(labelAtCurrentRow), str(addressAtCurrentRow)) + ustr(labelAtCurrentRow), ustr(addressAtCurrentRow)) else: sqlExecute( '''DELETE FROM whitelist WHERE label=? AND address=?''', - str(labelAtCurrentRow), str(addressAtCurrentRow)) + ustr(labelAtCurrentRow), ustr(addressAtCurrentRow)) self.tableWidgetBlacklist.removeRow(currentRow) def on_action_BlacklistClipboard(self): @@ -210,7 +211,7 @@ class Blacklist(QtGui.QWidget, RetranslateMixin): addressAtCurrentRow = self.tableWidgetBlacklist.item( currentRow, 1).text() clipboard = QtGui.QApplication.clipboard() - clipboard.setText(str(addressAtCurrentRow)) + clipboard.setText(ustr(addressAtCurrentRow)) def on_context_menuBlacklist(self, point): self.popMenuBlacklist.exec_( @@ -227,11 +228,11 @@ class Blacklist(QtGui.QWidget, RetranslateMixin): if config.get('bitmessagesettings', 'blackwhitelist') == 'black': sqlExecute( '''UPDATE blacklist SET enabled=1 WHERE address=?''', - str(addressAtCurrentRow)) + ustr(addressAtCurrentRow)) else: sqlExecute( '''UPDATE whitelist SET enabled=1 WHERE address=?''', - str(addressAtCurrentRow)) + ustr(addressAtCurrentRow)) def on_action_BlacklistDisable(self): currentRow = self.tableWidgetBlacklist.currentRow() @@ -243,10 +244,10 @@ class Blacklist(QtGui.QWidget, RetranslateMixin): currentRow, 1).setTextColor(QtGui.QColor(128, 128, 128)) if config.get('bitmessagesettings', 'blackwhitelist') == 'black': sqlExecute( - '''UPDATE blacklist SET enabled=0 WHERE address=?''', str(addressAtCurrentRow)) + '''UPDATE blacklist SET enabled=0 WHERE address=?''', ustr(addressAtCurrentRow)) else: sqlExecute( - '''UPDATE whitelist SET enabled=0 WHERE address=?''', str(addressAtCurrentRow)) + '''UPDATE whitelist SET enabled=0 WHERE address=?''', ustr(addressAtCurrentRow)) def on_action_BlacklistSetAvatar(self): self.window().on_action_SetAvatar(self.tableWidgetBlacklist) diff --git a/src/bitmessageqt/dialogs.py b/src/bitmessageqt/dialogs.py index bba7421e..c8969dae 100644 --- a/src/bitmessageqt/dialogs.py +++ b/src/bitmessageqt/dialogs.py @@ -2,6 +2,7 @@ Custom dialog classes """ # pylint: disable=too-few-public-methods +from ver import ustr from PyQt4 import QtGui import paths @@ -36,7 +37,7 @@ class AboutDialog(QtGui.QDialog): if commit: version += '-' + commit[:7] self.labelVersion.setText( - self.labelVersion.text().replace( + ustr(self.labelVersion.text()).replace( ':version:', version ).replace(':branch:', commit or 'v%s' % version) ) @@ -44,8 +45,8 @@ class AboutDialog(QtGui.QDialog): try: self.label_2.setText( - self.label_2.text().replace( - '2022', str(last_commit.get('time').year) + ustr(self.label_2.text()).replace( + '2022', ustr(last_commit.get('time').year) )) except AttributeError: pass diff --git a/src/bitmessageqt/foldertree.py b/src/bitmessageqt/foldertree.py index c50b7d3d..437fe314 100644 --- a/src/bitmessageqt/foldertree.py +++ b/src/bitmessageqt/foldertree.py @@ -6,6 +6,7 @@ Folder tree and messagelist widgets definitions. from cgi import escape +from ver import ustr, unic from PyQt4 import QtCore, QtGui from bmconfigparser import config @@ -62,7 +63,7 @@ class AccountMixin(object): def accountString(self): """Account string suitable for use in To: field: label
""" - label = self._getLabel() + label = ustr(self._getLabel()) return ( self.address if label == self.address else '%s <%s>' % (label, self.address) @@ -73,7 +74,7 @@ class AccountMixin(object): if address is None: self.address = None else: - self.address = str(address) + self.address = ustr(address) def setUnreadCount(self, cnt): """Set number of unread messages""" @@ -124,8 +125,8 @@ class AccountMixin(object): AccountMixin.NORMAL, AccountMixin.CHAN, AccountMixin.MAILINGLIST): try: - retval = unicode( - config.get(self.address, 'label'), 'utf-8') + retval = unic(ustr( + config.get(self.address, 'label'))) except Exception: queryreturn = sqlQuery( '''select label from addressbook where address=?''', self.address) @@ -136,12 +137,11 @@ class AccountMixin(object): if queryreturn != []: for row in queryreturn: retval, = row - retval = unicode(retval, 'utf-8') + retval = unic(ustr(retval)) elif self.address is None or self.type == AccountMixin.ALL: - return unicode( - str(_translate("MainWindow", "All accounts")), 'utf-8') + return unic(_translate("MainWindow", "All accounts")) - return retval or unicode(self.address, 'utf-8') + return retval or unic(self.address) class BMTreeWidgetItem(QtGui.QTreeWidgetItem, AccountMixin): @@ -154,7 +154,7 @@ class BMTreeWidgetItem(QtGui.QTreeWidgetItem, AccountMixin): self._setup(parent, pos) def _getAddressBracket(self, unreadCount=False): - return " (" + str(self.unreadCount) + ")" if unreadCount else "" + return " (" + ustr(self.unreadCount) + ")" if unreadCount else "" def data(self, column, role): """Override internal QT method for returning object data""" @@ -191,7 +191,7 @@ class Ui_FolderWidget(BMTreeWidgetItem): def setFolderName(self, fname): """Set folder name (for QT UI)""" - self.folderName = str(fname) + self.folderName = ustr(fname) def data(self, column, role): """Override internal QT method for returning object data""" @@ -232,15 +232,14 @@ class Ui_AddressWidget(BMTreeWidgetItem, SettingsMixin): def _getLabel(self): if self.address is None: - return unicode(_translate( - "MainWindow", "All accounts").toUtf8(), 'utf-8', 'ignore') + return unic(_translate( + "MainWindow", "All accounts")) else: try: - return unicode( - config.get(self.address, 'label'), - 'utf-8', 'ignore') + return unic(ustr( + config.get(self.address, 'label'))) except: - return unicode(self.address, 'utf-8') + return unic(self.address) def _getAddressBracket(self, unreadCount=False): ret = "" if self.isExpanded() \ @@ -264,8 +263,8 @@ class Ui_AddressWidget(BMTreeWidgetItem, SettingsMixin): if role == QtCore.Qt.EditRole \ and self.type != AccountMixin.SUBSCRIPTION: config.set( - str(self.address), 'label', - str(value.toString().toUtf8()) + self.address, 'label', + ustr(value) if isinstance(value, QtCore.QVariant) else value.encode('utf-8') ) @@ -311,8 +310,8 @@ class Ui_SubscriptionWidget(Ui_AddressWidget): if queryreturn != []: for row in queryreturn: retval, = row - return unicode(retval, 'utf-8', 'ignore') - return unicode(self.address, 'utf-8') + return unic(ustr(retval)) + return unic(self.address) def setType(self): """Set account type""" @@ -323,10 +322,10 @@ class Ui_SubscriptionWidget(Ui_AddressWidget): """Save subscription label to database""" if role == QtCore.Qt.EditRole: if isinstance(value, QtCore.QVariant): - label = str( - value.toString().toUtf8()).decode('utf-8', 'ignore') + label = ustr( + value) else: - label = unicode(value, 'utf-8', 'ignore') + label = unic(ustr(value)) sqlExecute( '''UPDATE subscriptions SET label=? WHERE address=?''', label, self.address) @@ -407,9 +406,8 @@ class MessageList_AddressWidget(BMAddressWidget): AccountMixin.NORMAL, AccountMixin.CHAN, AccountMixin.MAILINGLIST): try: - newLabel = unicode( - config.get(self.address, 'label'), - 'utf-8', 'ignore') + newLabel = unic(ustr( + config.get(self.address, 'label'))) except: queryreturn = sqlQuery( '''select label from addressbook where address=?''', self.address) @@ -418,7 +416,7 @@ class MessageList_AddressWidget(BMAddressWidget): '''select label from subscriptions where address=?''', self.address) if queryreturn: for row in queryreturn: - newLabel = unicode(row[0], 'utf-8', 'ignore') + newLabel = unic(ustr(row[0])) self.label = newLabel @@ -454,9 +452,9 @@ class MessageList_SubjectWidget(BMTableWidgetItem): def data(self, role): """Return object data (QT UI)""" if role == QtCore.Qt.UserRole: - return self.subject + return ustr(self.subject) if role == QtCore.Qt.ToolTipRole: - return escape(unicode(self.subject, 'utf-8')) + return escape(unic(ustr(self.subject))) return super(MessageList_SubjectWidget, self).data(role) # label (or address) alphabetically, disabled at the end @@ -491,9 +489,9 @@ class MessageList_TimeWidget(BMTableWidgetItem): """ data = super(MessageList_TimeWidget, self).data(role) if role == TimestampRole: - return int(data.toPyObject()) + return int(data) if role == QtCore.Qt.UserRole: - return str(data.toPyObject()) + return ustr(data) return data @@ -513,8 +511,8 @@ class Ui_AddressBookWidgetItem(BMAddressWidget): def setData(self, role, value): """Set data""" if role == QtCore.Qt.EditRole: - self.label = str( - value.toString().toUtf8() + self.label = ustr( + value if isinstance(value, QtCore.QVariant) else value ) if self.type in ( @@ -546,7 +544,7 @@ class Ui_AddressBookWidgetItem(BMAddressWidget): class Ui_AddressBookWidgetItemLabel(Ui_AddressBookWidgetItem): """Addressbook label item""" def __init__(self, address, label, acc_type): - self.address = address + self.address = ustr(address) super(Ui_AddressBookWidgetItemLabel, self).__init__(label, acc_type) def data(self, role): @@ -558,7 +556,7 @@ class Ui_AddressBookWidgetItemLabel(Ui_AddressBookWidgetItem): class Ui_AddressBookWidgetItemAddress(Ui_AddressBookWidgetItem): """Addressbook address item""" def __init__(self, address, label, acc_type): - self.address = address + self.address = ustr(address) super(Ui_AddressBookWidgetItemAddress, self).__init__(address, acc_type) def data(self, role): @@ -584,14 +582,14 @@ class AddressBookCompleter(QtGui.QCompleter): def splitPath(self, path): """Split on semicolon""" - text = unicode(path.toUtf8(), 'utf-8') + text = unic(ustr(path)) return [text[:self.widget().cursorPosition()].split(';')[-1].strip()] def pathFromIndex(self, index): """Perform autocompletion (reimplemented QCompleter method)""" - autoString = unicode( - index.data(QtCore.Qt.EditRole).toString().toUtf8(), 'utf-8') - text = unicode(self.widget().text().toUtf8(), 'utf-8') + autoString = unic(ustr( + index.data(QtCore.Qt.EditRole))) + text = unic(ustr(self.widget().text())) # If cursor position was saved, restore it, else save it if self.cursorPos != -1: diff --git a/src/bitmessageqt/messageview.py b/src/bitmessageqt/messageview.py index 4c17569c..fe58cc0f 100644 --- a/src/bitmessageqt/messageview.py +++ b/src/bitmessageqt/messageview.py @@ -5,6 +5,7 @@ zoom and URL click warning popup """ +from ver import ustr, unic from PyQt4 import QtCore, QtGui from safehtmlparser import SafeHTMLParser @@ -56,7 +57,7 @@ class MessageView(QtGui.QTextBrowser): ) == QtCore.Qt.ControlModifier and event.orientation() == QtCore.Qt.Vertical: zoom = self.currentFont().pointSize() * 100 / self.defaultFontPointSize QtGui.QApplication.activeWindow().statusBar().showMessage(_translate( - "MainWindow", "Zoom level {0}%").format(str(zoom))) + "MainWindow", "Zoom level {0}%").format(ustr(zoom))) def setWrappingWidth(self, width=None): """Set word-wrapping width""" @@ -91,7 +92,7 @@ class MessageView(QtGui.QTextBrowser): QtGui.QApplication.translate( "MessageView", "The link \"{0}\" will open in a browser. It may be a security risk, it could de-anonymise you" - " or download malicious data. Are you sure?").format(unicode(link.toString())), + " or download malicious data. Are you sure?").format(unic(ustr(link))), QtGui.QMessageBox.Yes, QtGui.QMessageBox.No) if reply == QtGui.QMessageBox.Yes: @@ -124,7 +125,7 @@ class MessageView(QtGui.QTextBrowser): if pos > self.outpos: self.outpos = pos + 1 cursor.movePosition(QtGui.QTextCursor.End, QtGui.QTextCursor.MoveAnchor) - cursor.insertHtml(QtCore.QString(self.out[startpos:self.outpos])) + cursor.insertHtml(unic(self.out[startpos:self.outpos])) self.verticalScrollBar().setValue(position) self.rendering = False @@ -133,9 +134,9 @@ class MessageView(QtGui.QTextBrowser): self.mode = MessageView.MODE_PLAIN out = self.html.raw if self.html.has_html: - out = "
" + unicode( + out = "
" + unic(ustr( QtGui.QApplication.translate( - "MessageView", "HTML detected, click here to display")) + "

" + out + "MessageView", "HTML detected, click here to display")) + "

" + out) self.out = out self.outpos = 0 self.setHtml("") @@ -145,8 +146,8 @@ class MessageView(QtGui.QTextBrowser): """Render message as HTML""" self.mode = MessageView.MODE_HTML out = self.html.sanitised - out = "
" + unicode( - QtGui.QApplication.translate("MessageView", "Click here to disable HTML")) + "

" + out + out = "
" + unic(ustr( + QtGui.QApplication.translate("MessageView", "Click here to disable HTML")) + "

" + out) self.out = out self.outpos = 0 self.setHtml("") diff --git a/src/bitmessageqt/networkstatus.py b/src/bitmessageqt/networkstatus.py index dbaf8fd0..8dd6dea7 100644 --- a/src/bitmessageqt/networkstatus.py +++ b/src/bitmessageqt/networkstatus.py @@ -204,9 +204,9 @@ class NetworkStatus(QtGui.QWidget, RetranslateMixin): if not connectionpool.pool.inboundConnections: self.window().setStatusIcon('yellow') for i in range(self.tableWidgetConnectionCount.rowCount()): - if self.tableWidgetConnectionCount.item(i, 0).data(QtCore.Qt.UserRole).toPyObject() != destination: + if self.tableWidgetConnectionCount.item(i, 0).data(QtCore.Qt.UserRole) != destination: continue - if self.tableWidgetConnectionCount.item(i, 1).data(QtCore.Qt.UserRole).toPyObject() == outbound: + if self.tableWidgetConnectionCount.item(i, 1).data(QtCore.Qt.UserRole) == outbound: self.tableWidgetConnectionCount.removeRow(i) break diff --git a/src/bitmessageqt/newchandialog.py b/src/bitmessageqt/newchandialog.py index 35087543..46e06959 100644 --- a/src/bitmessageqt/newchandialog.py +++ b/src/bitmessageqt/newchandialog.py @@ -4,6 +4,7 @@ src/bitmessageqt/newchandialog.py """ +from ver import ustr, unic from PyQt4 import QtCore, QtGui import widgets @@ -52,21 +53,21 @@ class NewChanDialog(QtGui.QDialog): self.timer.stop() self.hide() apiAddressGeneratorReturnQueue.queue.clear() - if self.chanAddress.text().toUtf8() == "": + if ustr(self.chanAddress.text()) == "": addressGeneratorQueue.put( - ('createChan', 4, 1, str_chan + ' ' + str(self.chanPassPhrase.text().toUtf8()), - self.chanPassPhrase.text().toUtf8(), + ('createChan', 4, 1, str_chan + ' ' + ustr(self.chanPassPhrase.text()), + ustr(self.chanPassPhrase.text()), True)) else: addressGeneratorQueue.put( - ('joinChan', addBMIfNotPresent(self.chanAddress.text().toUtf8()), - str_chan + ' ' + str(self.chanPassPhrase.text().toUtf8()), - self.chanPassPhrase.text().toUtf8(), + ('joinChan', addBMIfNotPresent(ustr(self.chanAddress.text())), + str_chan + ' ' + ustr(self.chanPassPhrase.text()), + ustr(self.chanPassPhrase.text()), True)) addressGeneratorReturnValue = apiAddressGeneratorReturnQueue.get(True) if addressGeneratorReturnValue and addressGeneratorReturnValue[0] != 'chan name does not match address': UISignalQueue.put(('updateStatusBar', _translate( - "newchandialog", "Successfully created / joined chan {0}").format(unicode(self.chanPassPhrase.text())))) + "newchandialog", "Successfully created / joined chan {0}").format(unic(ustr(self.chanPassPhrase.text()))))) self.parent.ui.tabWidget.setCurrentIndex( self.parent.ui.tabWidget.indexOf(self.parent.ui.chans) ) diff --git a/src/bitmessageqt/retranslateui.py b/src/bitmessageqt/retranslateui.py index c7676f77..5b1df839 100644 --- a/src/bitmessageqt/retranslateui.py +++ b/src/bitmessageqt/retranslateui.py @@ -1,4 +1,5 @@ from os import path +from ver import ustr from PyQt4 import QtGui from debug import logger import widgets @@ -10,11 +11,11 @@ class RetranslateMixin(object): for attr, value in defaults.__dict__.iteritems(): setTextMethod = getattr(value, "setText", None) if callable(setTextMethod): - getattr(self, attr).setText(getattr(defaults, attr).text()) + getattr(self, attr).setText(ustr(getattr(defaults, attr).text())) elif isinstance(value, QtGui.QTableWidget): for i in range (value.columnCount()): getattr(self, attr).horizontalHeaderItem(i).setText( - getattr(defaults, attr).horizontalHeaderItem(i).text()) + ustr(getattr(defaults, attr).horizontalHeaderItem(i).text())) for i in range (value.rowCount()): getattr(self, attr).verticalHeaderItem(i).setText( - getattr(defaults, attr).verticalHeaderItem(i).text()) + ustr(getattr(defaults, attr).verticalHeaderItem(i).text())) diff --git a/src/bitmessageqt/safehtmlparser.py b/src/bitmessageqt/safehtmlparser.py index d408d2c7..42c71486 100644 --- a/src/bitmessageqt/safehtmlparser.py +++ b/src/bitmessageqt/safehtmlparser.py @@ -7,6 +7,7 @@ from HTMLParser import HTMLParser from urllib import quote_plus from urlparse import urlparse +from ver import ustr, unic class SafeHTMLParser(HTMLParser): """HTML parser with sanitisation""" @@ -123,10 +124,7 @@ class SafeHTMLParser(HTMLParser): self.sanitised += "&" + name + ";" def feed(self, data): - try: - data = unicode(data, 'utf-8') - except UnicodeDecodeError: - data = unicode(data, 'utf-8', errors='replace') + data = unic(ustr(data)) HTMLParser.feed(self, data) tmp = SafeHTMLParser.replace_pre(data) tmp = self.uriregex1.sub(r'\1', tmp) diff --git a/src/bitmessageqt/settings.py b/src/bitmessageqt/settings.py index 3d05db25..50e8ebdb 100644 --- a/src/bitmessageqt/settings.py +++ b/src/bitmessageqt/settings.py @@ -7,6 +7,7 @@ import sys import tempfile import six +from ver import ustr from PyQt4 import QtCore, QtGui import debug @@ -175,7 +176,7 @@ class SettingsDialog(QtGui.QDialog): else: if self.checkBoxOnionOnly.isChecked(): self.checkBoxOnionOnly.setText( - self.checkBoxOnionOnly.text() + ", " + _translate( + ustr(self.checkBoxOnionOnly.text()) + ", " + _translate( "MainWindow", "may cause connection problems!")) self.checkBoxOnionOnly.setStyleSheet( "QCheckBox { color : red; }") @@ -312,10 +313,10 @@ class SettingsDialog(QtGui.QDialog): _translate("MainWindow", "Testing...")) nc = namecoin.namecoinConnection({ 'type': self.getNamecoinType(), - 'host': str(self.lineEditNamecoinHost.text().toUtf8()), - 'port': str(self.lineEditNamecoinPort.text().toUtf8()), - 'user': str(self.lineEditNamecoinUser.text().toUtf8()), - 'password': str(self.lineEditNamecoinPassword.text().toUtf8()) + 'host': ustr(self.lineEditNamecoinHost.text()), + 'port': ustr(self.lineEditNamecoinPort.text()), + 'user': ustr(self.lineEditNamecoinUser.text()), + 'password': ustr(self.lineEditNamecoinPassword.text()) }) status, text = nc.test() self.labelNamecoinTestResult.setText(text) @@ -349,7 +350,7 @@ class SettingsDialog(QtGui.QDialog): self.checkBoxReplyBelow.isChecked())) lang = str(self.languageComboBox.itemData( - self.languageComboBox.currentIndex()).toString()) + self.languageComboBox.currentIndex())) self.config.set('bitmessagesettings', 'userlocale', lang) self.parent.change_translation() @@ -448,13 +449,13 @@ class SettingsDialog(QtGui.QDialog): self.config.set( 'bitmessagesettings', 'namecoinrpctype', self.getNamecoinType()) - self.config.set('bitmessagesettings', 'namecoinrpchost', str( + self.config.set('bitmessagesettings', 'namecoinrpchost', ustr( self.lineEditNamecoinHost.text())) - self.config.set('bitmessagesettings', 'namecoinrpcport', str( + self.config.set('bitmessagesettings', 'namecoinrpcport', ustr( self.lineEditNamecoinPort.text())) - self.config.set('bitmessagesettings', 'namecoinrpcuser', str( + self.config.set('bitmessagesettings', 'namecoinrpcuser', ustr( self.lineEditNamecoinUser.text())) - self.config.set('bitmessagesettings', 'namecoinrpcpassword', str( + self.config.set('bitmessagesettings', 'namecoinrpcpassword', ustr( self.lineEditNamecoinPassword.text())) self.parent.resetNamecoinConnection() @@ -472,11 +473,11 @@ class SettingsDialog(QtGui.QDialog): float(self.lineEditSmallMessageDifficulty.text()) * defaults.networkDefaultPayloadLengthExtraBytes))) - if self.comboBoxOpenCL.currentText().toUtf8() != self.config.safeGet( - 'bitmessagesettings', 'opencl'): + if ustr(self.comboBoxOpenCL.currentText()) != ustr(self.config.safeGet( + 'bitmessagesettings', 'opencl')): self.config.set( 'bitmessagesettings', 'opencl', - str(self.comboBoxOpenCL.currentText())) + ustr(self.comboBoxOpenCL.currentText())) queues.workerQueue.put(('resetPoW', '')) acceptableDifficultyChanged = False diff --git a/src/bitmessageqt/settingsmixin.py b/src/bitmessageqt/settingsmixin.py index 3d5999e2..5a24837d 100644 --- a/src/bitmessageqt/settingsmixin.py +++ b/src/bitmessageqt/settingsmixin.py @@ -5,6 +5,7 @@ src/settingsmixin.py """ +from ver import ustr from PyQt4 import QtCore, QtGui @@ -40,7 +41,7 @@ class SettingsMixin(object): self.warnIfNoObjectName() settings = QtCore.QSettings() try: - geom = settings.value("/".join([str(self.objectName()), "geometry"])) + geom = settings.value("/".join([ustr(self.objectName()), "geometry"])) target.restoreGeometry(geom.toByteArray() if hasattr(geom, 'toByteArray') else geom) except Exception: pass @@ -50,7 +51,7 @@ class SettingsMixin(object): self.warnIfNoObjectName() settings = QtCore.QSettings() try: - state = settings.value("/".join([str(self.objectName()), "state"])) + state = settings.value("/".join([ustr(self.objectName()), "state"])) target.restoreState(state.toByteArray() if hasattr(state, 'toByteArray') else state) except Exception: pass diff --git a/src/bitmessageqt/support.py b/src/bitmessageqt/support.py index a84affa4..8bb80b02 100644 --- a/src/bitmessageqt/support.py +++ b/src/bitmessageqt/support.py @@ -6,6 +6,7 @@ import ssl import sys import time +from ver import ustr, unic from PyQt4 import QtCore import account @@ -72,7 +73,7 @@ def checkAddressBook(myapp): if queryreturn == []: sqlExecute( 'INSERT INTO addressbook VALUES (?,?)', - SUPPORT_LABEL.toUtf8(), SUPPORT_ADDRESS) + ustr(SUPPORT_LABEL), SUPPORT_ADDRESS) myapp.rerenderAddressBook() @@ -88,7 +89,7 @@ def createAddressIfNeeded(myapp): if not checkHasNormalAddress(): queues.addressGeneratorQueue.put(( 'createRandomAddress', 4, 1, - str(SUPPORT_MY_LABEL.toUtf8()), + ustr(SUPPORT_MY_LABEL), 1, "", False, defaults.networkDefaultProofOfWorkNonceTrialsPerByte, defaults.networkDefaultPayloadLengthExtraBytes @@ -122,7 +123,7 @@ def createSupportMessage(myapp): os = sys.platform if os == "win32": windowsversion = sys.getwindowsversion() - os = "Windows " + str(windowsversion[0]) + "." + str(windowsversion[1]) + os = "Windows " + ustr(windowsversion[0]) + "." + ustr(windowsversion[1]) else: try: from os import uname @@ -141,7 +142,7 @@ def createSupportMessage(myapp): frozen = paths.frozen portablemode = "True" if state.appdata == paths.lookupExeFolder() else "False" cpow = "True" if proofofwork.bmpow else "False" - openclpow = str( + openclpow = ustr( config.safeGet('bitmessagesettings', 'opencl') ) if openclEnabled() else "None" locale = getTranslationLanguage() @@ -149,9 +150,9 @@ def createSupportMessage(myapp): upnp = config.safeGet('bitmessagesettings', 'upnp', "N/A") connectedhosts = len(network.stats.connectedHostsList()) - myapp.ui.textEditMessage.setText(unicode(SUPPORT_MESSAGE, 'utf-8').format( + myapp.ui.textEditMessage.setText(unic(ustr(SUPPORT_MESSAGE).format( version, os, architecture, pythonversion, opensslversion, frozen, - portablemode, cpow, openclpow, locale, socks, upnp, connectedhosts)) + portablemode, cpow, openclpow, locale, socks, upnp, connectedhosts))) # single msg tab myapp.ui.tabWidgetSend.setCurrentIndex( diff --git a/src/bitmessageqt/tests/main.py b/src/bitmessageqt/tests/main.py index b3aa67fa..91f0ae11 100644 --- a/src/bitmessageqt/tests/main.py +++ b/src/bitmessageqt/tests/main.py @@ -41,7 +41,7 @@ class TestMain(unittest.TestCase): """Check the results of _translate() with various args""" self.assertIsInstance( _translate("MainWindow", "Test"), - QtCore.QString + str ) diff --git a/src/bitmessageqt/tests/support.py b/src/bitmessageqt/tests/support.py index ba28b73a..f611a0e7 100644 --- a/src/bitmessageqt/tests/support.py +++ b/src/bitmessageqt/tests/support.py @@ -6,6 +6,8 @@ from shared import isAddressInMyAddressBook from main import TestBase +from ver import ustr + class TestSupport(TestBase): """A test case for support module""" @@ -26,8 +28,8 @@ class TestSupport(TestBase): self.assertEqual( ui.tabWidget.currentIndex(), ui.tabWidget.indexOf(ui.send)) self.assertEqual( - ui.lineEditTo.text(), self.SUPPORT_ADDRESS) + ustr(ui.lineEditTo.text()), ustr(self.SUPPORT_ADDRESS)) self.assertEqual( - ui.lineEditSubject.text(), self.SUPPORT_SUBJECT) + ustr(ui.lineEditSubject.text()), ustr(self.SUPPORT_SUBJECT)) self.assertIn( sys.version, ui.textEditMessage.toPlainText()) diff --git a/src/depends.py b/src/depends.py index d966d5fe..4212d654 100755 --- a/src/depends.py +++ b/src/depends.py @@ -383,6 +383,15 @@ def check_pyqt(): Here we are checking for PyQt4 with its version, as for it require PyQt 4.8 or later. """ + sip_found = False + try: + import sip + sip.setapi("QString", 2) + sip.setapi("QVariant", 2) + sip_found = True + except ImportError: + pass + QtCore = try_import( 'PyQt4.QtCore', 'PyBitmessage requires PyQt 4.8 or later and Qt 4.7 or later.') @@ -402,6 +411,11 @@ def check_pyqt(): 'This version of Qt is too old. PyBitmessage requries' ' Qt 4.7 or later.') passed = False + + if passed and not sip_found: + logger.info("sip is not found although PyQt is found") + return False + return passed diff --git a/src/tr.py b/src/tr.py index eec82c37..66920197 100644 --- a/src/tr.py +++ b/src/tr.py @@ -3,6 +3,8 @@ Translating text """ import os +from ver import ustr + try: import state except ImportError: @@ -30,7 +32,7 @@ class translateClass: def _translate(context, text, disambiguation=None, encoding=None, n=None): # pylint: disable=unused-argument - return translateText(context, text, n) + return ustr(translateText(context, text, n)) def translateText(context, text, n=None): diff --git a/src/ver.py b/src/ver.py new file mode 100644 index 00000000..50e49609 --- /dev/null +++ b/src/ver.py @@ -0,0 +1,30 @@ +import sys + +if not hasattr(sys, "hexversion"): + sys.exit("Python version: {0}\n" + "PyBitmessage requires Python 2.7.4 or greater" + .format(sys.version)) + +if sys.hexversion < 0x3000000: + VER = 2 +else: + VER = 3 + +def ustr(v): + if VER == 3: + if isinstance(v, str): + return v + else: + return str(v) + # assume VER == 2 + if isinstance(v, unicode): + return v.encode("utf-8", "replace") + return str(v) + +def unic(v): + if VER == 3: + return v + # assume VER == 2 + if isinstance(v, unicode): + return v + return unicode(v, "utf-8", "replace") -- 2.45.1 From f70aff617bcc55d7b190cc03fa56fda1c40e8347 Mon Sep 17 00:00:00 2001 From: Kashiko Koibumi Date: Fri, 24 May 2024 12:42:29 +0900 Subject: [PATCH 039/105] use import paths compatible with both Python2 and Python3 --- src/bitmessageqt/__init__.py | 26 +++++++++++++------------- src/bitmessageqt/address_dialogs.py | 4 ++-- src/bitmessageqt/addressvalidator.py | 2 +- src/bitmessageqt/bitmessageui.py | 12 ++++++------ src/bitmessageqt/blacklist.py | 8 ++++---- src/bitmessageqt/dialogs.py | 8 ++++---- src/bitmessageqt/foldertree.py | 4 ++-- src/bitmessageqt/messageview.py | 2 +- src/bitmessageqt/networkstatus.py | 6 +++--- src/bitmessageqt/newchandialog.py | 6 +++--- src/bitmessageqt/retranslateui.py | 2 +- src/bitmessageqt/settings.py | 2 +- src/bitmessageqt/support.py | 6 +++--- src/bitmessageqt/tests/__init__.py | 8 ++++---- src/bitmessageqt/tests/addressbook.py | 2 +- src/bitmessageqt/tests/settings.py | 2 +- src/bitmessageqt/tests/support.py | 2 +- src/network/__init__.py | 2 +- src/network/addrthread.py | 4 ++-- src/network/advanceddispatcher.py | 2 +- src/network/announcethread.py | 6 +++--- src/network/bmobject.py | 4 ++-- src/network/bmproto.py | 22 +++++++++++----------- src/network/connectionchooser.py | 2 +- src/network/connectionpool.py | 14 +++++++------- src/network/dandelion.py | 2 +- src/network/downloadthread.py | 6 +++--- src/network/http.py | 10 +++++----- src/network/invthread.py | 4 ++-- src/network/networkthread.py | 4 ++-- src/network/objectracker.py | 4 ++-- src/network/proxy.py | 6 +++--- src/network/receivequeuethread.py | 4 ++-- src/network/socks4a.py | 2 +- src/network/socks5.py | 4 ++-- src/network/stats.py | 6 +++--- src/network/tcp.py | 18 +++++++++--------- src/network/udp.py | 10 +++++----- src/network/uploadthread.py | 4 ++-- 39 files changed, 121 insertions(+), 121 deletions(-) diff --git a/src/bitmessageqt/__init__.py b/src/bitmessageqt/__init__.py index a4a7bb60..1212e45a 100644 --- a/src/bitmessageqt/__init__.py +++ b/src/bitmessageqt/__init__.py @@ -23,38 +23,38 @@ import shared import state from debug import logger from tr import _translate -from account import ( +from .account import ( accountClass, getSortedSubscriptions, BMAccount, GatewayAccount, MailchuckAccount, AccountColor) from addresses import decodeAddress, addBMIfNotPresent -from bitmessageui import Ui_MainWindow +from bitmessageqt.bitmessageui import Ui_MainWindow from bmconfigparser import config import namecoin -from messageview import MessageView -from migrationwizard import Ui_MigrationWizard -from foldertree import ( +from .messageview import MessageView +from .migrationwizard import Ui_MigrationWizard +from .foldertree import ( AccountMixin, Ui_FolderWidget, Ui_AddressWidget, Ui_SubscriptionWidget, MessageList_AddressWidget, MessageList_SubjectWidget, Ui_AddressBookWidgetItemLabel, Ui_AddressBookWidgetItemAddress, MessageList_TimeWidget) -import settingsmixin -import support +from bitmessageqt import settingsmixin +from bitmessageqt import support from helper_sql import sqlQuery, sqlExecute, sqlExecuteChunked, sqlStoredProcedure import helper_addressbook import helper_search import l10n -from utils import str_broadcast_subscribers, avatarize -import dialogs +from .utils import str_broadcast_subscribers, avatarize +from bitmessageqt import dialogs from network.stats import pendingDownload, pendingUpload -from uisignaler import UISignaler +from .uisignaler import UISignaler import paths from proofofwork import getPowType import queues import shutdown -from statusbar import BMStatusBar -import sound +from .statusbar import BMStatusBar +from bitmessageqt import sound # This is needed for tray icon -import bitmessage_icons_rc # noqa:F401 pylint: disable=unused-import +from bitmessageqt import bitmessage_icons_rc # noqa:F401 pylint: disable=unused-import import helper_sent try: diff --git a/src/bitmessageqt/address_dialogs.py b/src/bitmessageqt/address_dialogs.py index caf7f687..98d3dd1c 100644 --- a/src/bitmessageqt/address_dialogs.py +++ b/src/bitmessageqt/address_dialogs.py @@ -9,9 +9,9 @@ from ver import ustr, unic from PyQt4 import QtCore, QtGui import queues -import widgets +from bitmessageqt import widgets import state -from account import AccountMixin, GatewayAccount, MailchuckAccount, accountClass +from .account import AccountMixin, GatewayAccount, MailchuckAccount, accountClass from addresses import addBMIfNotPresent, decodeAddress, encodeVarint from bmconfigparser import config as global_config from tr import _translate diff --git a/src/bitmessageqt/addressvalidator.py b/src/bitmessageqt/addressvalidator.py index fe939266..ac23c31e 100644 --- a/src/bitmessageqt/addressvalidator.py +++ b/src/bitmessageqt/addressvalidator.py @@ -12,7 +12,7 @@ from addresses import decodeAddress, addBMIfNotPresent from bmconfigparser import config from queues import apiAddressGeneratorReturnQueue, addressGeneratorQueue from tr import _translate -from utils import str_chan +from .utils import str_chan class AddressPassPhraseValidatorMixin(object): diff --git a/src/bitmessageqt/bitmessageui.py b/src/bitmessageqt/bitmessageui.py index 961fc093..e12a7bdf 100644 --- a/src/bitmessageqt/bitmessageui.py +++ b/src/bitmessageqt/bitmessageui.py @@ -9,12 +9,12 @@ from PyQt4 import QtCore, QtGui from bmconfigparser import config -from foldertree import AddressBookCompleter -from messageview import MessageView -from messagecompose import MessageCompose -import settingsmixin -from networkstatus import NetworkStatus -from blacklist import Blacklist +from .foldertree import AddressBookCompleter +from .messageview import MessageView +from .messagecompose import MessageCompose +from bitmessageqt import settingsmixin +from .networkstatus import NetworkStatus +from .blacklist import Blacklist try: _fromUtf8 = QtCore.QString.fromUtf8 diff --git a/src/bitmessageqt/blacklist.py b/src/bitmessageqt/blacklist.py index 5db3152f..0927f596 100644 --- a/src/bitmessageqt/blacklist.py +++ b/src/bitmessageqt/blacklist.py @@ -4,13 +4,13 @@ from PyQt4 import QtCore, QtGui import widgets from addresses import addBMIfNotPresent from bmconfigparser import config -from dialogs import AddAddressDialog +from .dialogs import AddAddressDialog from helper_sql import sqlExecute, sqlQuery from queues import UISignalQueue -from retranslateui import RetranslateMixin +from .retranslateui import RetranslateMixin from tr import _translate -from uisignaler import UISignaler -from utils import avatarize +from .uisignaler import UISignaler +from .utils import avatarize class Blacklist(QtGui.QWidget, RetranslateMixin): diff --git a/src/bitmessageqt/dialogs.py b/src/bitmessageqt/dialogs.py index c8969dae..85536410 100644 --- a/src/bitmessageqt/dialogs.py +++ b/src/bitmessageqt/dialogs.py @@ -6,14 +6,14 @@ from ver import ustr from PyQt4 import QtGui import paths -import widgets -from address_dialogs import ( +from bitmessageqt import widgets +from .address_dialogs import ( AddAddressDialog, EmailGatewayDialog, NewAddressDialog, NewSubscriptionDialog, RegenerateAddressesDialog, SpecialAddressBehaviorDialog ) -from newchandialog import NewChanDialog -from settings import SettingsDialog +from .newchandialog import NewChanDialog +from .settings import SettingsDialog from tr import _translate from version import softwareVersion diff --git a/src/bitmessageqt/foldertree.py b/src/bitmessageqt/foldertree.py index 437fe314..e9fe8038 100644 --- a/src/bitmessageqt/foldertree.py +++ b/src/bitmessageqt/foldertree.py @@ -11,9 +11,9 @@ from PyQt4 import QtCore, QtGui from bmconfigparser import config from helper_sql import sqlExecute, sqlQuery -from settingsmixin import SettingsMixin +from .settingsmixin import SettingsMixin from tr import _translate -from utils import avatarize +from .utils import avatarize # for pylupdate _translate("MainWindow", "inbox") diff --git a/src/bitmessageqt/messageview.py b/src/bitmessageqt/messageview.py index fe58cc0f..a94b01d1 100644 --- a/src/bitmessageqt/messageview.py +++ b/src/bitmessageqt/messageview.py @@ -8,7 +8,7 @@ zoom and URL click warning popup from ver import ustr, unic from PyQt4 import QtCore, QtGui -from safehtmlparser import SafeHTMLParser +from .safehtmlparser import SafeHTMLParser from tr import _translate diff --git a/src/bitmessageqt/networkstatus.py b/src/bitmessageqt/networkstatus.py index 8dd6dea7..4a5993d2 100644 --- a/src/bitmessageqt/networkstatus.py +++ b/src/bitmessageqt/networkstatus.py @@ -9,11 +9,11 @@ from PyQt4 import QtCore, QtGui import l10n import network.stats import state -import widgets +from bitmessageqt import widgets from network import connectionpool, knownnodes -from retranslateui import RetranslateMixin +from .retranslateui import RetranslateMixin from tr import _translate -from uisignaler import UISignaler +from .uisignaler import UISignaler class NetworkStatus(QtGui.QWidget, RetranslateMixin): diff --git a/src/bitmessageqt/newchandialog.py b/src/bitmessageqt/newchandialog.py index 46e06959..72b4f273 100644 --- a/src/bitmessageqt/newchandialog.py +++ b/src/bitmessageqt/newchandialog.py @@ -7,13 +7,13 @@ src/bitmessageqt/newchandialog.py from ver import ustr, unic from PyQt4 import QtCore, QtGui -import widgets +from bitmessageqt import widgets from addresses import addBMIfNotPresent -from addressvalidator import AddressValidator, PassPhraseValidator +from .addressvalidator import AddressValidator, PassPhraseValidator from queues import ( addressGeneratorQueue, apiAddressGeneratorReturnQueue, UISignalQueue) from tr import _translate -from utils import str_chan +from .utils import str_chan class NewChanDialog(QtGui.QDialog): diff --git a/src/bitmessageqt/retranslateui.py b/src/bitmessageqt/retranslateui.py index 5b1df839..ae22e96f 100644 --- a/src/bitmessageqt/retranslateui.py +++ b/src/bitmessageqt/retranslateui.py @@ -2,7 +2,7 @@ from os import path from ver import ustr from PyQt4 import QtGui from debug import logger -import widgets +from bitmessageqt import widgets class RetranslateMixin(object): def retranslateUi(self): diff --git a/src/bitmessageqt/settings.py b/src/bitmessageqt/settings.py index 50e8ebdb..14f2d30a 100644 --- a/src/bitmessageqt/settings.py +++ b/src/bitmessageqt/settings.py @@ -17,7 +17,7 @@ import openclpow import paths import queues import state -import widgets +from bitmessageqt import widgets from bmconfigparser import config as config_obj from helper_sql import sqlExecute, sqlStoredProcedure from helper_startup import start_proxyconfig diff --git a/src/bitmessageqt/support.py b/src/bitmessageqt/support.py index 8bb80b02..cb28d534 100644 --- a/src/bitmessageqt/support.py +++ b/src/bitmessageqt/support.py @@ -9,7 +9,7 @@ import time from ver import ustr, unic from PyQt4 import QtCore -import account +from bitmessageqt import account import defaults import network.stats import paths @@ -17,12 +17,12 @@ import proofofwork import queues import state from bmconfigparser import config -from foldertree import AccountMixin +from .foldertree import AccountMixin from helper_sql import sqlExecute, sqlQuery from l10n import getTranslationLanguage from openclpow import openclEnabled from pyelliptic.openssl import OpenSSL -from settings import getSOCKSProxyType +from .settings import getSOCKSProxyType from version import softwareVersion from tr import _translate diff --git a/src/bitmessageqt/tests/__init__.py b/src/bitmessageqt/tests/__init__.py index a542abdc..a81ddb04 100644 --- a/src/bitmessageqt/tests/__init__.py +++ b/src/bitmessageqt/tests/__init__.py @@ -1,9 +1,9 @@ """bitmessageqt tests""" -from addressbook import TestAddressbook -from main import TestMain, TestUISignaler -from settings import TestSettings -from support import TestSupport +from .addressbook import TestAddressbook +from .main import TestMain, TestUISignaler +from .settings import TestSettings +from .support import TestSupport __all__ = [ "TestAddressbook", "TestMain", "TestSettings", "TestSupport", diff --git a/src/bitmessageqt/tests/addressbook.py b/src/bitmessageqt/tests/addressbook.py index cd86c5d6..47d50b96 100644 --- a/src/bitmessageqt/tests/addressbook.py +++ b/src/bitmessageqt/tests/addressbook.py @@ -1,7 +1,7 @@ import helper_addressbook from bitmessageqt.support import createAddressIfNeeded -from main import TestBase +from .main import TestBase class TestAddressbook(TestBase): diff --git a/src/bitmessageqt/tests/settings.py b/src/bitmessageqt/tests/settings.py index 0dcf8cf3..e7927ea0 100644 --- a/src/bitmessageqt/tests/settings.py +++ b/src/bitmessageqt/tests/settings.py @@ -1,7 +1,7 @@ import threading import time -from main import TestBase +from .main import TestBase from bmconfigparser import config from bitmessageqt import settings diff --git a/src/bitmessageqt/tests/support.py b/src/bitmessageqt/tests/support.py index f611a0e7..8985987a 100644 --- a/src/bitmessageqt/tests/support.py +++ b/src/bitmessageqt/tests/support.py @@ -4,7 +4,7 @@ import sys from shared import isAddressInMyAddressBook -from main import TestBase +from .main import TestBase from ver import ustr diff --git a/src/network/__init__.py b/src/network/__init__.py index d89670a7..678d9f59 100644 --- a/src/network/__init__.py +++ b/src/network/__init__.py @@ -12,7 +12,7 @@ def start(config, state): """Start network threads""" import state from .announcethread import AnnounceThread - import connectionpool # pylint: disable=relative-import + from network import connectionpool from .addrthread import AddrThread from .dandelion import Dandelion from .downloadthread import DownloadThread diff --git a/src/network/addrthread.py b/src/network/addrthread.py index a0e869e3..452598e8 100644 --- a/src/network/addrthread.py +++ b/src/network/addrthread.py @@ -4,12 +4,12 @@ Announce addresses as they are received from other hosts from six.moves import queue # magic imports! -import connectionpool +from network import connectionpool from helper_random import randomshuffle from protocol import assembleAddrMessage from queues import addrQueue # FIXME: init with queue -from threads import StoppableThread +from .threads import StoppableThread class AddrThread(StoppableThread): diff --git a/src/network/advanceddispatcher.py b/src/network/advanceddispatcher.py index 49f0d19d..33c0c12e 100644 --- a/src/network/advanceddispatcher.py +++ b/src/network/advanceddispatcher.py @@ -7,7 +7,7 @@ import time import network.asyncore_pollchoose as asyncore import state -from threads import BusyError, nonBlocking +from .threads import BusyError, nonBlocking class ProcessingError(Exception): diff --git a/src/network/announcethread.py b/src/network/announcethread.py index 7cb35e77..77c7c63a 100644 --- a/src/network/announcethread.py +++ b/src/network/announcethread.py @@ -4,12 +4,12 @@ Announce myself (node address) import time # magic imports! -import connectionpool +from network import connectionpool from bmconfigparser import config from protocol import assembleAddrMessage -from node import Peer -from threads import StoppableThread +from .node import Peer +from .threads import StoppableThread class AnnounceThread(StoppableThread): diff --git a/src/network/bmobject.py b/src/network/bmobject.py index c91bf1b3..a8b0d761 100644 --- a/src/network/bmobject.py +++ b/src/network/bmobject.py @@ -6,7 +6,7 @@ import time import protocol import state -import connectionpool +import network.connectionpool # use long name to address recursive import from highlevelcrypto import calculateInventoryHash logger = logging.getLogger('default') @@ -99,7 +99,7 @@ class BMObject(object): # pylint: disable=too-many-instance-attributes logger.warning( 'The object has invalid stream: %s', self.streamNumber) raise BMObjectInvalidError() - if self.streamNumber not in connectionpool.pool.streams: + if self.streamNumber not in network.connectionpool.pool.streams: logger.debug( 'The streamNumber %i isn\'t one we are interested in.', self.streamNumber) diff --git a/src/network/bmproto.py b/src/network/bmproto.py index ed1d48c4..8e49935b 100644 --- a/src/network/bmproto.py +++ b/src/network/bmproto.py @@ -12,10 +12,10 @@ import time # magic imports! import addresses -import knownnodes +from network import knownnodes import protocol import state -import connectionpool +import network.connectionpool # use long name to address recursive import from bmconfigparser import config from queues import invQueue, objectProcessorQueue, portCheckerQueue from randomtrackingdict import RandomTrackingDict @@ -27,8 +27,8 @@ from network.bmobject import ( ) from network.proxy import ProxyError -from node import Node, Peer -from objectracker import ObjectTracker, missingObjects +from .node import Node, Peer +from .objectracker import ObjectTracker, missingObjects logger = logging.getLogger('default') @@ -445,7 +445,7 @@ class BMProto(AdvancedDispatcher, ObjectTracker): for seenTime, stream, _, ip, port in self._decode_addr(): ip = str(ip) if ( - stream not in connectionpool.pool.streams + stream not in network.connectionpool.pool.streams # FIXME: should check against complete list or ip.startswith('bootstrap') ): @@ -540,7 +540,7 @@ class BMProto(AdvancedDispatcher, ObjectTracker): if not self.isOutbound: self.append_write_buf(protocol.assembleVersionMessage( self.destination.host, self.destination.port, - connectionpool.pool.streams, True, + network.connectionpool.pool.streams, True, nodeid=self.nodeid)) logger.debug( '%(host)s:%(port)i sending version', @@ -596,7 +596,7 @@ class BMProto(AdvancedDispatcher, ObjectTracker): 'Closed connection to %s because there is no overlapping' ' interest in streams.', self.destination) return False - if connectionpool.pool.inboundConnections.get( + if network.connectionpool.pool.inboundConnections.get( self.destination): try: if not protocol.checkSocksIP(self.destination.host): @@ -614,8 +614,8 @@ class BMProto(AdvancedDispatcher, ObjectTracker): # or server full report the same error to counter deanonymisation if ( Peer(self.destination.host, self.peerNode.port) - in connectionpool.pool.inboundConnections - or len(connectionpool.pool) + in network.connectionpool.pool.inboundConnections + or len(network.connectionpool.pool) > config.safeGetInt( 'bitmessagesettings', 'maxtotalconnections') + config.safeGetInt( @@ -627,7 +627,7 @@ class BMProto(AdvancedDispatcher, ObjectTracker): 'Closed connection to %s due to server full' ' or duplicate inbound/outbound.', self.destination) return False - if connectionpool.pool.isAlreadyConnected(self.nonce): + if network.connectionpool.pool.isAlreadyConnected(self.nonce): self.append_write_buf(protocol.assembleErrorMessage( errorText="I'm connected to myself. Closing connection.", fatal=2)) @@ -641,7 +641,7 @@ class BMProto(AdvancedDispatcher, ObjectTracker): @staticmethod def stopDownloadingObject(hashId, forwardAnyway=False): """Stop downloading object *hashId*""" - for connection in connectionpool.pool.connections(): + for connection in network.connectionpool.pool.connections(): try: del connection.objectsNewToMe[hashId] except KeyError: diff --git a/src/network/connectionchooser.py b/src/network/connectionchooser.py index d7062d24..f4ae075d 100644 --- a/src/network/connectionchooser.py +++ b/src/network/connectionchooser.py @@ -5,7 +5,7 @@ Select which node to connect to import logging import random -import knownnodes +from network import knownnodes import protocol import state from bmconfigparser import config diff --git a/src/network/connectionpool.py b/src/network/connectionpool.py index 36c91c18..11240506 100644 --- a/src/network/connectionpool.py +++ b/src/network/connectionpool.py @@ -8,19 +8,19 @@ import socket import sys import time -import asyncore_pollchoose as asyncore +from network import asyncore_pollchoose as asyncore import helper_random -import knownnodes +from network import knownnodes import protocol import state from bmconfigparser import config -from connectionchooser import chooseConnection -from node import Peer -from proxy import Proxy -from tcp import ( +from .connectionchooser import chooseConnection +from .node import Peer +from .proxy import Proxy +from .tcp import ( bootstrap, Socks4aBMConnection, Socks5BMConnection, TCPConnection, TCPServer) -from udp import UDPSocket +from .udp import UDPSocket logger = logging.getLogger('default') diff --git a/src/network/dandelion.py b/src/network/dandelion.py index 35e70c95..29879085 100644 --- a/src/network/dandelion.py +++ b/src/network/dandelion.py @@ -7,7 +7,7 @@ from random import choice, expovariate, sample from threading import RLock from time import time -import connectionpool +from network import connectionpool import state from queues import invQueue diff --git a/src/network/downloadthread.py b/src/network/downloadthread.py index 4f108c72..4230cca7 100644 --- a/src/network/downloadthread.py +++ b/src/network/downloadthread.py @@ -6,9 +6,9 @@ import state import addresses import helper_random import protocol -import connectionpool -from objectracker import missingObjects -from threads import StoppableThread +from network import connectionpool +from .objectracker import missingObjects +from .threads import StoppableThread class DownloadThread(StoppableThread): diff --git a/src/network/http.py b/src/network/http.py index d7a938fa..af0015c7 100644 --- a/src/network/http.py +++ b/src/network/http.py @@ -1,10 +1,10 @@ import socket -from advanceddispatcher import AdvancedDispatcher -import asyncore_pollchoose as asyncore -from proxy import ProxyError -from socks5 import Socks5Connection, Socks5Resolver -from socks4a import Socks4aConnection, Socks4aResolver +from .advanceddispatcher import AdvancedDispatcher +from network import asyncore_pollchoose as asyncore +from .proxy import ProxyError +from .socks5 import Socks5Connection, Socks5Resolver +from .socks4a import Socks4aConnection, Socks4aResolver class HttpError(ProxyError): diff --git a/src/network/invthread.py b/src/network/invthread.py index b55408d4..51224b7f 100644 --- a/src/network/invthread.py +++ b/src/network/invthread.py @@ -8,9 +8,9 @@ from time import time import addresses import protocol import state -import connectionpool +from network import connectionpool from queues import invQueue -from threads import StoppableThread +from .threads import StoppableThread def handleExpiredDandelion(expired): diff --git a/src/network/networkthread.py b/src/network/networkthread.py index 640d47a1..6a4be2a4 100644 --- a/src/network/networkthread.py +++ b/src/network/networkthread.py @@ -2,9 +2,9 @@ A thread to handle network concerns """ import network.asyncore_pollchoose as asyncore -import connectionpool +from network import connectionpool from queues import excQueue -from threads import StoppableThread +from .threads import StoppableThread class BMNetworkThread(StoppableThread): diff --git a/src/network/objectracker.py b/src/network/objectracker.py index a458e5d2..c352200d 100644 --- a/src/network/objectracker.py +++ b/src/network/objectracker.py @@ -5,7 +5,7 @@ import time from threading import RLock import state -import connectionpool +import network.connectionpool # use long name to address recursive import from randomtrackingdict import RandomTrackingDict haveBloom = False @@ -100,7 +100,7 @@ class ObjectTracker(object): def handleReceivedObject(self, streamNumber, hashid): """Handling received object""" - for i in connectionpool.pool.connections(): + for i in network.connectionpool.pool.connections(): if not i.fullyEstablished: continue try: diff --git a/src/network/proxy.py b/src/network/proxy.py index ed1af127..eb76ce97 100644 --- a/src/network/proxy.py +++ b/src/network/proxy.py @@ -6,10 +6,10 @@ import logging import socket import time -import asyncore_pollchoose as asyncore -from advanceddispatcher import AdvancedDispatcher +from network import asyncore_pollchoose as asyncore +from .advanceddispatcher import AdvancedDispatcher from bmconfigparser import config -from node import Peer +from .node import Peer logger = logging.getLogger('default') diff --git a/src/network/receivequeuethread.py b/src/network/receivequeuethread.py index 10f2acea..0e9b5d21 100644 --- a/src/network/receivequeuethread.py +++ b/src/network/receivequeuethread.py @@ -5,10 +5,10 @@ import errno import Queue import socket -import connectionpool +from network import connectionpool from network.advanceddispatcher import UnknownStateError from queues import receiveDataQueue -from threads import StoppableThread +from .threads import StoppableThread class ReceiveQueueThread(StoppableThread): diff --git a/src/network/socks4a.py b/src/network/socks4a.py index e9786168..2758838a 100644 --- a/src/network/socks4a.py +++ b/src/network/socks4a.py @@ -6,7 +6,7 @@ import logging import socket import struct -from proxy import GeneralProxyError, Proxy, ProxyError +from .proxy import GeneralProxyError, Proxy, ProxyError logger = logging.getLogger('default') diff --git a/src/network/socks5.py b/src/network/socks5.py index d1daae42..1838a737 100644 --- a/src/network/socks5.py +++ b/src/network/socks5.py @@ -7,8 +7,8 @@ import logging import socket import struct -from node import Peer -from proxy import GeneralProxyError, Proxy, ProxyError +from .node import Peer +from .proxy import GeneralProxyError, Proxy, ProxyError logger = logging.getLogger('default') diff --git a/src/network/stats.py b/src/network/stats.py index 0ab1ae0f..ea2c40c9 100644 --- a/src/network/stats.py +++ b/src/network/stats.py @@ -3,9 +3,9 @@ Network statistics """ import time -import asyncore_pollchoose as asyncore -import connectionpool -from objectracker import missingObjects +from network import asyncore_pollchoose as asyncore +from network import connectionpool +from .objectracker import missingObjects lastReceivedTimestamp = time.time() diff --git a/src/network/tcp.py b/src/network/tcp.py index 72d6a421..831a3b11 100644 --- a/src/network/tcp.py +++ b/src/network/tcp.py @@ -15,21 +15,21 @@ import helper_random import l10n import protocol import state -import connectionpool +import network.connectionpool # use long name to address recursive import from bmconfigparser import config from highlevelcrypto import randomBytes from queues import invQueue, receiveDataQueue, UISignalQueue from tr import _translate -import asyncore_pollchoose as asyncore -import knownnodes +from network import asyncore_pollchoose as asyncore +from network import knownnodes from network.advanceddispatcher import AdvancedDispatcher from network.bmproto import BMProto from network.objectracker import ObjectTracker from network.socks4a import Socks4aConnection from network.socks5 import Socks5Connection from network.tls import TLSDispatcher -from node import Peer +from .node import Peer logger = logging.getLogger('default') @@ -267,7 +267,7 @@ class TCPConnection(BMProto, TLSDispatcher): self.append_write_buf( protocol.assembleVersionMessage( self.destination.host, self.destination.port, - connectionpool.pool.streams, + network.connectionpool.pool.streams, False, nodeid=self.nodeid)) self.connectedAt = time.time() receiveDataQueue.put(self.destination) @@ -318,7 +318,7 @@ class Socks5BMConnection(Socks5Connection, TCPConnection): self.append_write_buf( protocol.assembleVersionMessage( self.destination.host, self.destination.port, - connectionpool.pool.streams, + network.connectionpool.pool.streams, False, nodeid=self.nodeid)) self.set_state("bm_header", expectBytes=protocol.Header.size) return True @@ -342,7 +342,7 @@ class Socks4aBMConnection(Socks4aConnection, TCPConnection): self.append_write_buf( protocol.assembleVersionMessage( self.destination.host, self.destination.port, - connectionpool.pool.streams, + network.connectionpool.pool.streams, False, nodeid=self.nodeid)) self.set_state("bm_header", expectBytes=protocol.Header.size) return True @@ -430,7 +430,7 @@ class TCPServer(AdvancedDispatcher): state.ownAddresses[Peer(*sock.getsockname())] = True if ( - len(connectionpool.pool) + len(network.connectionpool.pool) > config.safeGetInt( 'bitmessagesettings', 'maxtotalconnections') + config.safeGetInt( @@ -442,7 +442,7 @@ class TCPServer(AdvancedDispatcher): sock.close() return try: - connectionpool.pool.addConnection( + network.connectionpool.pool.addConnection( TCPConnection(sock=sock)) except socket.error: pass diff --git a/src/network/udp.py b/src/network/udp.py index b16146f9..e0abe110 100644 --- a/src/network/udp.py +++ b/src/network/udp.py @@ -8,12 +8,12 @@ import time # magic imports! import protocol import state -import connectionpool +import network.connectionpool # use long name to address recursive import from queues import receiveDataQueue -from bmproto import BMProto -from node import Peer -from objectracker import ObjectTracker +from .bmproto import BMProto +from .node import Peer +from .objectracker import ObjectTracker logger = logging.getLogger('default') @@ -82,7 +82,7 @@ class UDPSocket(BMProto): # pylint: disable=too-many-instance-attributes remoteport = False for seenTime, stream, _, ip, port in addresses: decodedIP = protocol.checkIPAddress(str(ip)) - if stream not in connectionpool.pool.streams: + if stream not in network.connectionpool.pool.streams: continue if (seenTime < time.time() - protocol.MAX_TIME_OFFSET or seenTime > time.time() + protocol.MAX_TIME_OFFSET): diff --git a/src/network/uploadthread.py b/src/network/uploadthread.py index 90048c0a..96794769 100644 --- a/src/network/uploadthread.py +++ b/src/network/uploadthread.py @@ -6,9 +6,9 @@ import time import helper_random import protocol import state -import connectionpool +from network import connectionpool from randomtrackingdict import RandomTrackingDict -from threads import StoppableThread +from .threads import StoppableThread class UploadThread(StoppableThread): -- 2.45.1 From f37a973f5f65668bd17a192eb37c13ec19970ec6 Mon Sep 17 00:00:00 2001 From: Kashiko Koibumi Date: Sat, 25 May 2024 09:06:02 +0900 Subject: [PATCH 040/105] use six.PY2 and six.PY3 --- setup.py | 3 ++- src/depends.py | 3 ++- src/fallback/umsgpack/umsgpack.py | 7 ++++--- src/l10n.py | 6 +++--- src/pyelliptic/openssl.py | 3 ++- src/tests/common.py | 4 ++-- src/tests/partial.py | 3 ++- src/tests/test_api_thread.py | 4 ++-- src/tests/test_l10n.py | 4 ++-- src/tests/test_log.py | 4 ++-- src/tests/test_protocol.py | 4 ++-- tests.py | 3 ++- 12 files changed, 27 insertions(+), 21 deletions(-) diff --git a/setup.py b/setup.py index 30436bec..0daf5d74 100644 --- a/setup.py +++ b/setup.py @@ -4,6 +4,7 @@ import os import platform import shutil import sys +import six from importlib import import_module from setuptools import setup, Extension @@ -83,7 +84,7 @@ if __name__ == "__main__": 'images/kivy/text_images*.png' ]} - if sys.version_info[0] == 3: + if six.PY3: packages.extend( [ 'pybitmessage.bitmessagekivy', diff --git a/src/depends.py b/src/depends.py index d966d5fe..bc754440 100755 --- a/src/depends.py +++ b/src/depends.py @@ -6,6 +6,7 @@ and suggest how it may be installed import os import re import sys +import six # Only really old versions of Python don't have sys.hexversion. We don't # support them. The logging module was introduced in Python 2.3 @@ -438,7 +439,7 @@ def check_dependencies(verbose=False, optional=False): 'PyBitmessage requires Python 2.7.4 or greater' ' (but not Python 3+)') has_all_dependencies = False - if sys.hexversion >= 0x3000000: + if six.PY3: logger.error( 'PyBitmessage does not support Python 3+. Python 2.7.4' ' or greater is required. Python 2.7.18 is recommended.') diff --git a/src/fallback/umsgpack/umsgpack.py b/src/fallback/umsgpack/umsgpack.py index 34938614..d4c347ca 100644 --- a/src/fallback/umsgpack/umsgpack.py +++ b/src/fallback/umsgpack/umsgpack.py @@ -53,6 +53,7 @@ import collections import io import struct import sys +import six __version__ = "2.4.1" "Module version string" @@ -99,9 +100,9 @@ class Ext: # pylint: disable=old-style-class if not isinstance(type, int) or not (type >= 0 and type <= 127): raise TypeError("ext type out of range") # Check data is type bytes - elif sys.version_info[0] == 3 and not isinstance(data, bytes): + elif six.PY3 and not isinstance(data, bytes): raise TypeError("ext data is not type \'bytes\'") - elif sys.version_info[0] == 2 and not isinstance(data, str): + elif six.PY2 and not isinstance(data, str): raise TypeError("ext data is not type \'str\'") self.type = type self.data = data @@ -990,7 +991,7 @@ def __init(): _float_precision = "single" # Map packb and unpackb to the appropriate version - if sys.version_info[0] == 3: + if six.PY3: pack = _pack3 packb = _packb3 dump = _pack3 diff --git a/src/l10n.py b/src/l10n.py index fe02d3f4..927937d7 100644 --- a/src/l10n.py +++ b/src/l10n.py @@ -3,8 +3,8 @@ import logging import os import re -import sys import time +import six from six.moves import range @@ -61,7 +61,7 @@ if not re.search(r'\d', time.strftime(time_format)): # It seems some systems lie about the encoding they use # so we perform comprehensive decoding tests -elif sys.version_info[0] == 2: +elif six.PY2: try: # Check day names for i in range(7): @@ -118,7 +118,7 @@ def formatTimestamp(timestamp=None): except ValueError: timestring = time.strftime(time_format) - if sys.version_info[0] == 2: + if six.PY2: return timestring.decode(encoding) return timestring diff --git a/src/pyelliptic/openssl.py b/src/pyelliptic/openssl.py index deb81644..42c2946d 100644 --- a/src/pyelliptic/openssl.py +++ b/src/pyelliptic/openssl.py @@ -8,6 +8,7 @@ needed openssl functionality in class _OpenSSL. """ import ctypes import sys +import six # pylint: disable=protected-access @@ -745,7 +746,7 @@ class _OpenSSL(object): """ buffer_ = None if data != 0: - if sys.version_info.major == 3 and isinstance(data, type('')): + if six.PY3 and isinstance(data, type('')): data = data.encode() buffer_ = self.create_string_buffer(data, size) else: diff --git a/src/tests/common.py b/src/tests/common.py index 2d60c716..0cd84d2f 100644 --- a/src/tests/common.py +++ b/src/tests/common.py @@ -1,7 +1,7 @@ import os -import sys import time import unittest +import six _files = ( @@ -33,7 +33,7 @@ def checkup(): def skip_python3(): """Raise unittest.SkipTest() if detected python3""" - if sys.hexversion >= 0x3000000: + if six.PY3: raise unittest.SkipTest('Module is not ported to python3') diff --git a/src/tests/partial.py b/src/tests/partial.py index 870f6626..b5543b71 100644 --- a/src/tests/partial.py +++ b/src/tests/partial.py @@ -3,6 +3,7 @@ import os import sys import unittest +import six from pybitmessage import pathmagic @@ -22,7 +23,7 @@ class TestPartialRun(unittest.TestCase): import state from debug import logger # noqa:F401 pylint: disable=unused-variable - if sys.hexversion >= 0x3000000: + if six.PY3: # pylint: disable=no-name-in-module,relative-import from mockbm import network as network_mock import network diff --git a/src/tests/test_api_thread.py b/src/tests/test_api_thread.py index 6e453b19..6fc3b66f 100644 --- a/src/tests/test_api_thread.py +++ b/src/tests/test_api_thread.py @@ -1,9 +1,9 @@ """TestAPIThread class definition""" -import sys import time from binascii import hexlify, unhexlify from struct import pack +import six from six.moves import queue, xmlrpc_client @@ -68,7 +68,7 @@ class TestAPIThread(TestPartialRun): def test_client_status(self): """Ensure the reply of clientStatus corresponds to mock""" status = self.api.clientStatus() - if sys.hexversion >= 0x3000000: + if six.PY3: self.assertEqual(status["networkConnections"], 4) self.assertEqual(status["pendingDownload"], 0) diff --git a/src/tests/test_l10n.py b/src/tests/test_l10n.py index c6988827..a61f2a99 100644 --- a/src/tests/test_l10n.py +++ b/src/tests/test_l10n.py @@ -1,9 +1,9 @@ """Tests for l10n module""" import re -import sys import time import unittest +import six from pybitmessage import l10n @@ -16,7 +16,7 @@ class TestL10n(unittest.TestCase): self.assertFalse(re.search(r'\d', time.strftime("wrong"))) timestring_type = type(time.strftime(l10n.DEFAULT_TIME_FORMAT)) self.assertEqual(timestring_type, str) - if sys.version_info[0] == 2: + if six.PY2: self.assertEqual(timestring_type, bytes) def test_getWindowsLocale(self): diff --git a/src/tests/test_log.py b/src/tests/test_log.py index 4e74e50d..0d05fcb7 100644 --- a/src/tests/test_log.py +++ b/src/tests/test_log.py @@ -1,8 +1,8 @@ """Tests for logging""" import subprocess -import sys import unittest +import six from pybitmessage import proofofwork @@ -11,7 +11,7 @@ class TestLog(unittest.TestCase): """A test case for logging""" @unittest.skipIf( - sys.hexversion < 0x3000000, 'assertLogs is new in version 3.4') + six.PY2, 'assertLogs is new in version 3.4') def test_LogOutput(self): """Use proofofwork.LogOutput to log output of a shell command""" with self.assertLogs('default') as cm: # pylint: disable=no-member diff --git a/src/tests/test_protocol.py b/src/tests/test_protocol.py index e3137b25..6a7f1ee5 100644 --- a/src/tests/test_protocol.py +++ b/src/tests/test_protocol.py @@ -2,8 +2,8 @@ Tests for common protocol functions """ -import sys import unittest +import six from pybitmessage import protocol, state from pybitmessage.helper_startup import fixSocket @@ -79,7 +79,7 @@ class TestProtocol(TestSocketInet): self.assertEqual(protocol.checkIPAddress(globalhost), '8.8.8.8') @unittest.skipIf( - sys.hexversion >= 0x3000000, 'this is still not working with python3') + six.PY3, 'this is still not working with python3') def test_check_local_socks(self): """The SOCKS part of the local check""" self.assertTrue( diff --git a/tests.py b/tests.py index 713b25ef..0e3adaf1 100644 --- a/tests.py +++ b/tests.py @@ -3,11 +3,12 @@ import random # noseq import sys import unittest +import six def unittest_discover(): """Explicit test suite creation""" - if sys.hexversion >= 0x3000000: + if six.PY3: from pybitmessage import pathmagic pathmagic.setup() loader = unittest.defaultTestLoader -- 2.45.1 From 46d56c703e489a00f9c3856407c470b26920462e Mon Sep 17 00:00:00 2001 From: Kashiko Koibumi Date: Sat, 25 May 2024 11:39:46 +0900 Subject: [PATCH 041/105] use six.itervalues(), six.iteritems() --- src/bitmessageqt/__init__.py | 15 ++++++++------- src/bitmessageqt/retranslateui.py | 3 ++- src/network/dandelion.py | 19 ++++++++++--------- src/network/downloadthread.py | 3 ++- src/network/knownnodes.py | 7 ++++--- src/network/objectracker.py | 3 ++- src/network/tcp.py | 3 ++- src/tests/core.py | 13 +++++++------ 8 files changed, 37 insertions(+), 29 deletions(-) diff --git a/src/bitmessageqt/__init__.py b/src/bitmessageqt/__init__.py index 40113b5a..b4ce8678 100644 --- a/src/bitmessageqt/__init__.py +++ b/src/bitmessageqt/__init__.py @@ -14,6 +14,7 @@ import threading import time from datetime import datetime, timedelta from sqlite3 import register_adapter +import six from PyQt4 import QtCore, QtGui from PyQt4.QtNetwork import QLocalSocket, QLocalServer @@ -468,7 +469,7 @@ class MyForm(settingsmixin.SMainWindow): # add missing folders if len(db[toAddress]) > 0: j = 0 - for f, c in db[toAddress].iteritems(): + for f, c in six.iteritems(db[toAddress]): try: subwidget = Ui_FolderWidget(widget, j, toAddress, f, c['count']) except KeyError: @@ -598,7 +599,7 @@ class MyForm(settingsmixin.SMainWindow): # add missing folders if len(db[toAddress]) > 0: j = 0 - for f, c in db[toAddress].iteritems(): + for f, c in six.iteritems(db[toAddress]): if toAddress is not None and tab == 'messages' and folder == "new": continue subwidget = Ui_FolderWidget(widget, j, toAddress, f, c) @@ -1075,15 +1076,15 @@ class MyForm(settingsmixin.SMainWindow): for i in range(root.childCount()): addressItem = root.child(i) if addressItem.type == AccountMixin.ALL: - newCount = sum(totalUnread.itervalues()) + newCount = sum(six.itervalues(totalUnread)) self.drawTrayIcon(self.currentTrayIconFileName, newCount) else: try: - newCount = sum(( + newCount = sum(six.itervalues(( broadcastsUnread if addressItem.type == AccountMixin.SUBSCRIPTION else normalUnread - )[addressItem.address].itervalues()) + )[addressItem.address])) except KeyError: newCount = 0 if newCount != addressItem.unreadCount: @@ -2871,7 +2872,7 @@ class MyForm(settingsmixin.SMainWindow): QtCore.QEventLoop.AllEvents, 1000 ) self.saveSettings() - for attr, obj in self.ui.__dict__.iteritems(): + for attr, obj in six.iteritems(self.ui.__dict__): if hasattr(obj, "__class__") \ and isinstance(obj, settingsmixin.SettingsMixin): saveMethod = getattr(obj, "saveSettings", None) @@ -4209,7 +4210,7 @@ class MyForm(settingsmixin.SMainWindow): def initSettings(self): self.loadSettings() - for attr, obj in self.ui.__dict__.iteritems(): + for attr, obj in six.iteritems(self.ui.__dict__): if hasattr(obj, "__class__") and \ isinstance(obj, settingsmixin.SettingsMixin): loadMethod = getattr(obj, "loadSettings", None) diff --git a/src/bitmessageqt/retranslateui.py b/src/bitmessageqt/retranslateui.py index c7676f77..1b4b7716 100644 --- a/src/bitmessageqt/retranslateui.py +++ b/src/bitmessageqt/retranslateui.py @@ -1,4 +1,5 @@ from os import path +import six from PyQt4 import QtGui from debug import logger import widgets @@ -7,7 +8,7 @@ class RetranslateMixin(object): def retranslateUi(self): defaults = QtGui.QWidget() widgets.load(self.__class__.__name__.lower() + '.ui', defaults) - for attr, value in defaults.__dict__.iteritems(): + for attr, value in six.iteritems(defaults.__dict__): setTextMethod = getattr(value, "setText", None) if callable(setTextMethod): getattr(self, attr).setText(getattr(defaults, attr).text()) diff --git a/src/network/dandelion.py b/src/network/dandelion.py index 35e70c95..e2232082 100644 --- a/src/network/dandelion.py +++ b/src/network/dandelion.py @@ -6,6 +6,7 @@ from collections import namedtuple from random import choice, expovariate, sample from threading import RLock from time import time +import six import connectionpool import state @@ -99,12 +100,12 @@ class Dandelion: # pylint: disable=old-style-class with self.lock: if len(self.stem) < MAX_STEMS: self.stem.append(connection) - for k in (k for k, v in self.nodeMap.iteritems() if v is None): + for k in (k for k, v in six.iteritems(self.nodeMap) if v is None): self.nodeMap[k] = connection - for k, v in { - k: v for k, v in self.hashMap.iteritems() + for k, v in six.iteritems({ + k: v for k, v in six.iteritems(self.hashMap) if v.child is None - }.iteritems(): + }): self.hashMap[k] = Stem( connection, v.stream, self.poissonTimeout()) invQueue.put((v.stream, k, v.child)) @@ -120,14 +121,14 @@ class Dandelion: # pylint: disable=old-style-class self.stem.remove(connection) # active mappings to pointing to the removed node for k in ( - k for k, v in self.nodeMap.iteritems() + k for k, v in six.iteritems(self.nodeMap) if v == connection ): self.nodeMap[k] = None - for k, v in { - k: v for k, v in self.hashMap.iteritems() + for k, v in six.iteritems({ + k: v for k, v in six.iteritems(self.hashMap) if v.child == connection - }.iteritems(): + }): self.hashMap[k] = Stem( None, v.stream, self.poissonTimeout()) @@ -168,7 +169,7 @@ class Dandelion: # pylint: disable=old-style-class with self.lock: deadline = time() toDelete = [ - [v.stream, k, v.child] for k, v in self.hashMap.iteritems() + [v.stream, k, v.child] for k, v in six.iteritems(self.hashMap) if v.timeout < deadline ] diff --git a/src/network/downloadthread.py b/src/network/downloadthread.py index 4f108c72..15013a3b 100644 --- a/src/network/downloadthread.py +++ b/src/network/downloadthread.py @@ -3,6 +3,7 @@ """ import time import state +import six import addresses import helper_random import protocol @@ -28,7 +29,7 @@ class DownloadThread(StoppableThread): deadline = time.time() - self.requestExpires try: toDelete = [ - k for k, v in missingObjects.iteritems() + k for k, v in six.iteritems(missingObjects) if v < deadline] except RuntimeError: pass diff --git a/src/network/knownnodes.py b/src/network/knownnodes.py index c53be2cd..f0fd6d90 100644 --- a/src/network/knownnodes.py +++ b/src/network/knownnodes.py @@ -14,6 +14,7 @@ try: from collections.abc import Iterable except ImportError: from collections import Iterable +import six import state from bmconfigparser import config @@ -54,8 +55,8 @@ def json_serialize_knownnodes(output): Reorganize knownnodes dict and write it as JSON to output """ _serialized = [] - for stream, peers in knownNodes.iteritems(): - for peer, info in peers.iteritems(): + for stream, peers in six.iteritems(knownNodes): + for peer, info in six.iteritems(peers): info.update(rating=round(info.get('rating', 0), 2)) _serialized.append({ 'stream': stream, 'peer': peer._asdict(), 'info': info @@ -87,7 +88,7 @@ def pickle_deserialize_old_knownnodes(source): global knownNodes knownNodes = pickle.load(source) # nosec B301 for stream in knownNodes.keys(): - for node, params in knownNodes[stream].iteritems(): + for node, params in six.iteritems(knownNodes[stream]): if isinstance(params, (float, int)): addKnownNode(stream, node, params) diff --git a/src/network/objectracker.py b/src/network/objectracker.py index a458e5d2..f1cfa131 100644 --- a/src/network/objectracker.py +++ b/src/network/objectracker.py @@ -3,6 +3,7 @@ Module for tracking objects """ import time from threading import RLock +import six import state import connectionpool @@ -75,7 +76,7 @@ class ObjectTracker(object): with self.objectsNewToThemLock: self.objectsNewToThem = { k: v - for k, v in self.objectsNewToThem.iteritems() + for k, v in six.iteritems(self.objectsNewToThem) if v >= deadline} self.lastCleaned = time.time() diff --git a/src/network/tcp.py b/src/network/tcp.py index 139715a6..a31544fd 100644 --- a/src/network/tcp.py +++ b/src/network/tcp.py @@ -8,6 +8,7 @@ import math import random import socket import time +import six # magic imports! import addresses @@ -191,7 +192,7 @@ class TCPConnection(BMProto, TLSDispatcher): # only if more recent than 3 hours # and having positive or neutral rating filtered = [ - (k, v) for k, v in nodes.iteritems() + (k, v) for k, v in six.iteritems(nodes) if v["lastseen"] > int(time.time()) - maximumAgeOfNodesThatIAdvertiseToOthers and v["rating"] >= 0 and not k.host.endswith('.onion') diff --git a/src/tests/core.py b/src/tests/core.py index f1a11a06..e24293b0 100644 --- a/src/tests/core.py +++ b/src/tests/core.py @@ -15,6 +15,7 @@ import sys import threading import time import unittest +import six import protocol import state @@ -137,8 +138,8 @@ class TestCore(unittest.TestCase): @staticmethod def _outdate_knownnodes(): with knownnodes.knownNodesLock: - for nodes in knownnodes.knownNodes.itervalues(): - for node in nodes.itervalues(): + for nodes in six.itervalues(knownnodes.knownNodes): + for node in six.itervalues(nodes): node['lastseen'] -= 2419205 # older than 28 days def test_knownnodes_pickle(self): @@ -146,9 +147,9 @@ class TestCore(unittest.TestCase): pickle_knownnodes() self._wipe_knownnodes() knownnodes.readKnownNodes() - for nodes in knownnodes.knownNodes.itervalues(): + for nodes in six.itervalues(knownnodes.knownNodes): self_count = n = 0 - for n, node in enumerate(nodes.itervalues()): + for n, node in enumerate(six.itervalues(nodes)): if node.get('self'): self_count += 1 self.assertEqual(n - self_count, 2) @@ -202,7 +203,7 @@ class TestCore(unittest.TestCase): while c > 0: time.sleep(1) c -= 2 - for peer, con in connectionpool.pool.outboundConnections.iteritems(): + for peer, con in six.iteritems(connectionpool.pool.outboundConnections): if ( peer.host.startswith('bootstrap') or peer.host == 'quzwelsuziwqgpt2.onion' @@ -223,7 +224,7 @@ class TestCore(unittest.TestCase): 'Failed to connect during %.2f sec' % (time.time() - _started)) def _check_knownnodes(self): - for stream in knownnodes.knownNodes.itervalues(): + for stream in six.itervalues(knownnodes.knownNodes): for peer in stream: if peer.host.startswith('bootstrap'): self.fail( -- 2.45.1 From 21a7bdba441c34a104186d573c90d772e7c7cdcd Mon Sep 17 00:00:00 2001 From: Kashiko Koibumi Date: Sat, 25 May 2024 12:27:32 +0900 Subject: [PATCH 042/105] use six.int2byte(), six.byte2int, six.BytesIO --- src/bitmessagecurses/__init__.py | 11 ++--- src/bitmessagekivy/identiconGeneration.py | 2 +- src/fallback/umsgpack/umsgpack.py | 51 +++++++++++------------ src/network/dandelion.py | 2 +- src/network/socks4a.py | 17 ++++---- src/network/socks5.py | 23 +++++----- src/protocol.py | 3 +- src/pyelliptic/arithmetic.py | 3 +- src/pyelliptic/hash.py | 4 +- src/pyelliptic/openssl.py | 2 +- src/tests/test_randomtrackingdict.py | 3 +- 11 files changed, 64 insertions(+), 57 deletions(-) diff --git a/src/bitmessagecurses/__init__.py b/src/bitmessagecurses/__init__.py index 64fd735b..c2764d1c 100644 --- a/src/bitmessagecurses/__init__.py +++ b/src/bitmessagecurses/__init__.py @@ -17,6 +17,7 @@ import sys import time from textwrap import fill from threading import Timer +import six from dialog import Dialog import helper_sent @@ -105,7 +106,7 @@ def ascii(s): """ASCII values""" r = "" for c in s: - if ord(c) in range(128): + if six.byte2int(c) in range(128): r += c return r @@ -326,13 +327,13 @@ def handlech(c, stdscr): if c != curses.ERR: global inboxcur, addrcur, sentcur, subcur, abookcur, blackcur if c in range(256): - if chr(c) in '12345678': + if six.int2byte(c) in '12345678': global menutab - menutab = int(chr(c)) - elif chr(c) == 'q': + menutab = int(six.int2byte(c)) + elif six.int2byte(c) == 'q': global quit_ quit_ = True - elif chr(c) == '\n': + elif six.int2byte(c) == '\n': curses.curs_set(1) d = Dialog(dialog="dialog") if menutab == 1: diff --git a/src/bitmessagekivy/identiconGeneration.py b/src/bitmessagekivy/identiconGeneration.py index 2e2f2e93..63c58c0d 100644 --- a/src/bitmessagekivy/identiconGeneration.py +++ b/src/bitmessagekivy/identiconGeneration.py @@ -3,7 +3,7 @@ Core classes for loading images and converting them to a Texture. The raw image data can be keep in memory for further access """ import hashlib -from io import BytesIO +from six import BytesIO from PIL import Image from kivy.core.image import Image as CoreImage diff --git a/src/fallback/umsgpack/umsgpack.py b/src/fallback/umsgpack/umsgpack.py index d4c347ca..cac4986f 100644 --- a/src/fallback/umsgpack/umsgpack.py +++ b/src/fallback/umsgpack/umsgpack.py @@ -50,7 +50,6 @@ License: MIT # pylint: disable=unused-argument import collections -import io import struct import sys import six @@ -126,7 +125,7 @@ class Ext: # pylint: disable=old-style-class String representation of this Ext object. """ s = "Ext Object (Type: 0x%02x, Data: " % self.type - s += " ".join(["0x%02x" % ord(self.data[i:i + 1]) + s += " ".join(["0x%02x" % six.byte2int(self.data[i:i + 1]) for i in xrange(min(len(self.data), 8))]) if len(self.data) > 8: s += " ..." @@ -550,7 +549,7 @@ def _packb2(obj, **options): '\x82\xa7compact\xc3\xa6schema\x00' >>> """ - fp = io.BytesIO() + fp = six.BytesIO() _pack2(obj, fp, **options) return fp.getvalue() @@ -583,7 +582,7 @@ def _packb3(obj, **options): b'\x82\xa7compact\xc3\xa6schema\x00' >>> """ - fp = io.BytesIO() + fp = six.BytesIO() _pack3(obj, fp, **options) return fp.getvalue() @@ -600,7 +599,7 @@ def _read_except(fp, n): def _unpack_integer(code, fp, options): - if (ord(code) & 0xe0) == 0xe0: + if (six.byte2int(code) & 0xe0) == 0xe0: return struct.unpack("b", code)[0] elif code == b'\xd0': return struct.unpack("b", _read_except(fp, 1))[0] @@ -610,7 +609,7 @@ def _unpack_integer(code, fp, options): return struct.unpack(">i", _read_except(fp, 4))[0] elif code == b'\xd3': return struct.unpack(">q", _read_except(fp, 8))[0] - elif (ord(code) & 0x80) == 0x00: + elif (six.byte2int(code) & 0x80) == 0x00: return struct.unpack("B", code)[0] elif code == b'\xcc': return struct.unpack("B", _read_except(fp, 1))[0] @@ -620,21 +619,21 @@ def _unpack_integer(code, fp, options): return struct.unpack(">I", _read_except(fp, 4))[0] elif code == b'\xcf': return struct.unpack(">Q", _read_except(fp, 8))[0] - raise Exception("logic error, not int: 0x%02x" % ord(code)) + raise Exception("logic error, not int: 0x%02x" % six.byte2int(code)) def _unpack_reserved(code, fp, options): if code == b'\xc1': raise ReservedCodeException( - "encountered reserved code: 0x%02x" % ord(code)) + "encountered reserved code: 0x%02x" % six.byte2int(code)) raise Exception( - "logic error, not reserved code: 0x%02x" % ord(code)) + "logic error, not reserved code: 0x%02x" % six.byte2int(code)) def _unpack_nil(code, fp, options): if code == b'\xc0': return None - raise Exception("logic error, not nil: 0x%02x" % ord(code)) + raise Exception("logic error, not nil: 0x%02x" % six.byte2int(code)) def _unpack_boolean(code, fp, options): @@ -642,7 +641,7 @@ def _unpack_boolean(code, fp, options): return False elif code == b'\xc3': return True - raise Exception("logic error, not boolean: 0x%02x" % ord(code)) + raise Exception("logic error, not boolean: 0x%02x" % six.byte2int(code)) def _unpack_float(code, fp, options): @@ -650,12 +649,12 @@ def _unpack_float(code, fp, options): return struct.unpack(">f", _read_except(fp, 4))[0] elif code == b'\xcb': return struct.unpack(">d", _read_except(fp, 8))[0] - raise Exception("logic error, not float: 0x%02x" % ord(code)) + raise Exception("logic error, not float: 0x%02x" % six.byte2int(code)) def _unpack_string(code, fp, options): - if (ord(code) & 0xe0) == 0xa0: - length = ord(code) & ~0xe0 + if (six.byte2int(code) & 0xe0) == 0xa0: + length = six.byte2int(code) & ~0xe0 elif code == b'\xd9': length = struct.unpack("B", _read_except(fp, 1))[0] elif code == b'\xda': @@ -663,7 +662,7 @@ def _unpack_string(code, fp, options): elif code == b'\xdb': length = struct.unpack(">I", _read_except(fp, 4))[0] else: - raise Exception("logic error, not string: 0x%02x" % ord(code)) + raise Exception("logic error, not string: 0x%02x" % six.byte2int(code)) # Always return raw bytes in compatibility mode global compatibility @@ -687,7 +686,7 @@ def _unpack_binary(code, fp, options): elif code == b'\xc6': length = struct.unpack(">I", _read_except(fp, 4))[0] else: - raise Exception("logic error, not binary: 0x%02x" % ord(code)) + raise Exception("logic error, not binary: 0x%02x" % six.byte2int(code)) return _read_except(fp, length) @@ -710,9 +709,9 @@ def _unpack_ext(code, fp, options): elif code == b'\xc9': length = struct.unpack(">I", _read_except(fp, 4))[0] else: - raise Exception("logic error, not ext: 0x%02x" % ord(code)) + raise Exception("logic error, not ext: 0x%02x" % six.byte2int(code)) - ext = Ext(ord(_read_except(fp, 1)), _read_except(fp, length)) + ext = Ext(six.byte2int(_read_except(fp, 1)), _read_except(fp, length)) # Unpack with ext handler, if we have one ext_handlers = options.get("ext_handlers") @@ -723,14 +722,14 @@ def _unpack_ext(code, fp, options): def _unpack_array(code, fp, options): - if (ord(code) & 0xf0) == 0x90: - length = (ord(code) & ~0xf0) + if (six.byte2int(code) & 0xf0) == 0x90: + length = (six.byte2int(code) & ~0xf0) elif code == b'\xdc': length = struct.unpack(">H", _read_except(fp, 2))[0] elif code == b'\xdd': length = struct.unpack(">I", _read_except(fp, 4))[0] else: - raise Exception("logic error, not array: 0x%02x" % ord(code)) + raise Exception("logic error, not array: 0x%02x" % six.byte2int(code)) return [_unpack(fp, options) for _ in xrange(length)] @@ -742,14 +741,14 @@ def _deep_list_to_tuple(obj): def _unpack_map(code, fp, options): - if (ord(code) & 0xf0) == 0x80: - length = (ord(code) & ~0xf0) + if (six.byte2int(code) & 0xf0) == 0x80: + length = (six.byte2int(code) & ~0xf0) elif code == b'\xde': length = struct.unpack(">H", _read_except(fp, 2))[0] elif code == b'\xdf': length = struct.unpack(">I", _read_except(fp, 4))[0] else: - raise Exception("logic error, not map: 0x%02x" % ord(code)) + raise Exception("logic error, not map: 0x%02x" % six.byte2int(code)) d = {} if not options.get('use_ordered_dict') \ else collections.OrderedDict() @@ -912,7 +911,7 @@ def _unpackb2(s, **options): """ if not isinstance(s, (str, bytearray)): raise TypeError("packed data must be type 'str' or 'bytearray'") - return _unpack(io.BytesIO(s), options) + return _unpack(six.BytesIO(s), options) # For Python 3, expects a bytes object @@ -958,7 +957,7 @@ def _unpackb3(s, **options): """ if not isinstance(s, (bytes, bytearray)): raise TypeError("packed data must be type 'bytes' or 'bytearray'") - return _unpack(io.BytesIO(s), options) + return _unpack(six.BytesIO(s), options) ############################################################################# # Module Initialization diff --git a/src/network/dandelion.py b/src/network/dandelion.py index e2232082..8bed5bee 100644 --- a/src/network/dandelion.py +++ b/src/network/dandelion.py @@ -75,7 +75,7 @@ class Dandelion: # pylint: disable=old-style-class if logger.isEnabledFor(logging.DEBUG): logger.debug( '%s entering fluff mode due to %s.', - ''.join('%02x' % ord(i) for i in hashId), reason) + ''.join('%02x' % six.byte2int(i) for i in hashId), reason) with self.lock: try: del self.hashMap[hashId] diff --git a/src/network/socks4a.py b/src/network/socks4a.py index e9786168..2df46f06 100644 --- a/src/network/socks4a.py +++ b/src/network/socks4a.py @@ -5,6 +5,7 @@ SOCKS4a proxy module import logging import socket import struct +import six from proxy import GeneralProxyError, Proxy, ProxyError @@ -39,16 +40,16 @@ class Socks4a(Proxy): def state_pre_connect(self): """Handle feedback from SOCKS4a while it is connecting on our behalf""" # Get the response - if self.read_buf[0:1] != chr(0x00).encode(): + if self.read_buf[0:1] != six.int2byte(0x00).encode(): # bad data self.close() raise GeneralProxyError(1) - elif self.read_buf[1:2] != chr(0x5A).encode(): + elif self.read_buf[1:2] != six.int2byte(0x5A).encode(): # Connection failed self.close() - if ord(self.read_buf[1:2]) in (91, 92, 93): + if six.byte2int(self.read_buf[1:2]) in (91, 92, 93): # socks 4 error - raise Socks4aError(ord(self.read_buf[1:2]) - 90) + raise Socks4aError(six.byte2int(self.read_buf[1:2]) - 90) else: raise Socks4aError(4) # Get the bound address/port @@ -102,9 +103,9 @@ class Socks4aConnection(Socks4a): self.append_write_buf(self.ipaddr) if self._auth: self.append_write_buf(self._auth[0]) - self.append_write_buf(chr(0x00).encode()) + self.append_write_buf(six.int2byte(0x00).encode()) if rmtrslv: - self.append_write_buf(self.destination[0] + chr(0x00).encode()) + self.append_write_buf(self.destination[0] + six.int2byte(0x00).encode()) self.set_state("pre_connect", length=0, expectBytes=8) return True @@ -132,8 +133,8 @@ class Socks4aResolver(Socks4a): self.append_write_buf(struct.pack("BBBB", 0x00, 0x00, 0x00, 0x01)) if self._auth: self.append_write_buf(self._auth[0]) - self.append_write_buf(chr(0x00).encode()) - self.append_write_buf(self.host + chr(0x00).encode()) + self.append_write_buf(six.int2byte(0x00).encode()) + self.append_write_buf(self.host + six.int2byte(0x00).encode()) self.set_state("pre_connect", length=0, expectBytes=8) return True diff --git a/src/network/socks5.py b/src/network/socks5.py index d1daae42..9aaa57cc 100644 --- a/src/network/socks5.py +++ b/src/network/socks5.py @@ -6,6 +6,7 @@ SOCKS5 proxy module import logging import socket import struct +import six from node import Peer from proxy import GeneralProxyError, Proxy, ProxyError @@ -97,20 +98,20 @@ class Socks5(Proxy): def state_pre_connect(self): """Handle feedback from socks5 while it is connecting on our behalf.""" # Get the response - if self.read_buf[0:1] != chr(0x05).encode(): + if self.read_buf[0:1] != six.int2byte(0x05).encode(): self.close() raise GeneralProxyError(1) - elif self.read_buf[1:2] != chr(0x00).encode(): + elif self.read_buf[1:2] != six.int2byte(0x00).encode(): # Connection failed self.close() - if ord(self.read_buf[1:2]) <= 8: - raise Socks5Error(ord(self.read_buf[1:2])) + if six.byte2int(self.read_buf[1:2]) <= 8: + raise Socks5Error(six.byte2int(self.read_buf[1:2])) else: raise Socks5Error(9) # Get the bound address/port - elif self.read_buf[3:4] == chr(0x01).encode(): + elif self.read_buf[3:4] == six.int2byte(0x01).encode(): self.set_state("proxy_addr_1", length=4, expectBytes=4) - elif self.read_buf[3:4] == chr(0x03).encode(): + elif self.read_buf[3:4] == six.int2byte(0x03).encode(): self.set_state("proxy_addr_2_1", length=4, expectBytes=1) else: self.close() @@ -129,7 +130,7 @@ class Socks5(Proxy): (e.g. IPv6, onion, ...). This is part 1 which retrieves the length of the data. """ - self.address_length = ord(self.read_buf[0:1]) + self.address_length = six.byte2int(self.read_buf[0:1]) self.set_state( "proxy_addr_2_2", length=1, expectBytes=self.address_length) return True @@ -171,19 +172,19 @@ class Socks5Connection(Socks5): # use the IPv4 address request even if remote resolving was specified. try: self.ipaddr = socket.inet_aton(self.destination[0]) - self.append_write_buf(chr(0x01).encode() + self.ipaddr) + self.append_write_buf(six.int2byte(0x01).encode() + self.ipaddr) except socket.error: # may be IPv6! # Well it's not an IP number, so it's probably a DNS name. if self._remote_dns: # Resolve remotely self.ipaddr = None - self.append_write_buf(chr(0x03).encode() + chr( + self.append_write_buf(six.int2byte(0x03).encode() + six.int2byte( len(self.destination[0])).encode() + self.destination[0]) else: # Resolve locally self.ipaddr = socket.inet_aton( socket.gethostbyname(self.destination[0])) - self.append_write_buf(chr(0x01).encode() + self.ipaddr) + self.append_write_buf(six.int2byte(0x01).encode() + self.ipaddr) self.append_write_buf(struct.pack(">H", self.destination[1])) self.set_state("pre_connect", length=0, expectBytes=4) return True @@ -208,7 +209,7 @@ class Socks5Resolver(Socks5): """Perform resolving""" # Now we can request the actual connection self.append_write_buf(struct.pack('BBB', 0x05, 0xF0, 0x00)) - self.append_write_buf(chr(0x03).encode() + chr( + self.append_write_buf(six.int2byte(0x03).encode() + six.int2byte( len(self.host)).encode() + str(self.host)) self.append_write_buf(struct.pack(">H", self.port)) self.set_state("pre_connect", length=0, expectBytes=4) diff --git a/src/protocol.py b/src/protocol.py index 7f9830e5..e300b97a 100644 --- a/src/protocol.py +++ b/src/protocol.py @@ -12,6 +12,7 @@ import sys import time from binascii import hexlify from struct import Struct, pack, unpack +import six import defaults import highlevelcrypto @@ -227,7 +228,7 @@ def checkIPv6Address(host, hostStandardFormat, private=False): logger.debug('Ignoring loopback address: %s', hostStandardFormat) return False try: - host = [ord(c) for c in host[:2]] + host = [six.byte2int(c) for c in host[:2]] except TypeError: # python3 has ints already pass if host[0] == 0xfe and host[1] & 0xc0 == 0x80: diff --git a/src/pyelliptic/arithmetic.py b/src/pyelliptic/arithmetic.py index 23c24b5e..ce66db98 100644 --- a/src/pyelliptic/arithmetic.py +++ b/src/pyelliptic/arithmetic.py @@ -3,6 +3,7 @@ Arithmetic Expressions """ import hashlib import re +import six P = 2**256 - 2**32 - 2**9 - 2**8 - 2**7 - 2**6 - 2**4 - 1 A = 0 @@ -34,7 +35,7 @@ def get_code_string(base): return b'123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz' if base == 256: try: - return b''.join([chr(x) for x in range(256)]) + return b''.join([six.int2byte(x) for x in range(256)]) except TypeError: return bytes([x for x in range(256)]) diff --git a/src/pyelliptic/hash.py b/src/pyelliptic/hash.py index 70c9a6ce..51ffd623 100644 --- a/src/pyelliptic/hash.py +++ b/src/pyelliptic/hash.py @@ -4,6 +4,8 @@ Wrappers for hash functions from OpenSSL. # Copyright (C) 2011 Yann GUIBET # See LICENSE for details. +import six + from .openssl import OpenSSL @@ -22,7 +24,7 @@ def _equals_str(a, b): return False result = 0 for x, y in zip(a, b): - result |= ord(x) ^ ord(y) + result |= six.byte2int(x) ^ six.byte2int(y) return result == 0 diff --git a/src/pyelliptic/openssl.py b/src/pyelliptic/openssl.py index 42c2946d..f1def5d3 100644 --- a/src/pyelliptic/openssl.py +++ b/src/pyelliptic/openssl.py @@ -692,7 +692,7 @@ class _OpenSSL(object): length = self.BN_num_bytes(x) data = self.malloc(0, length) OpenSSL.BN_bn2bin(x, data) - return ord(data[length - 1]) & 1 + return six.byte2int(data[length - 1]) & 1 def get_cipher(self, name): """ diff --git a/src/tests/test_randomtrackingdict.py b/src/tests/test_randomtrackingdict.py index 2db3c423..528780a9 100644 --- a/src/tests/test_randomtrackingdict.py +++ b/src/tests/test_randomtrackingdict.py @@ -3,6 +3,7 @@ Tests for RandomTrackingDict Class """ import random import unittest +import six from time import time @@ -17,7 +18,7 @@ class TestRandomTrackingDict(unittest.TestCase): """helper function for tests, generates a random string""" retval = '' for _ in range(32): - retval += chr(random.randint(0, 255)) + retval += six.int2byte(random.randint(0, 255)) return retval def test_check_randomtrackingdict(self): -- 2.45.1 From 81a6bdb223d0a56baed8ed8f61dc3ab99700d303 Mon Sep 17 00:00:00 2001 From: Kashiko Koibumi Date: Sat, 25 May 2024 13:07:59 +0900 Subject: [PATCH 043/105] use six.assertRaisesRegex, six.assertRegex, six.assertNotRegex --- src/tests/test_addressgenerator.py | 5 +++-- src/tests/test_api.py | 27 ++++++++++++++------------- src/tests/test_inventory.py | 3 ++- src/tests/test_logger.py | 5 +++-- 4 files changed, 22 insertions(+), 18 deletions(-) diff --git a/src/tests/test_addressgenerator.py b/src/tests/test_addressgenerator.py index e48daef9..ea4e6e44 100644 --- a/src/tests/test_addressgenerator.py +++ b/src/tests/test_addressgenerator.py @@ -3,6 +3,7 @@ from binascii import unhexlify from six.moves import queue +import six from .partial import TestPartialRun from .samples import ( @@ -91,8 +92,8 @@ class TestAddressGenerator(TestPartialRun): self.command_queue.put(( 'createRandomAddress', 4, 1, 'test_random', 1, '', False, 0, 0)) addr = self.return_queue.get() - self.assertRegexpMatches(addr, r'^BM-') - self.assertRegexpMatches(addr[3:], r'[a-zA-Z1-9]+$') + six.assertRegex(self, addr, r'^BM-') + six.assertRegex(self, addr[3:], r'[a-zA-Z1-9]+$') self.assertLessEqual(len(addr[3:]), 40) self.assertEqual( diff --git a/src/tests/test_api.py b/src/tests/test_api.py index 2a4640fa..db52cc9c 100644 --- a/src/tests/test_api.py +++ b/src/tests/test_api.py @@ -8,6 +8,7 @@ import time from binascii import hexlify from six.moves import xmlrpc_client # nosec +import six import psutil @@ -174,28 +175,28 @@ class TestAPI(TestAPIProto): self.assertEqual( self.api.getDeterministicAddress(self._seed, 3, 1), sample_deterministic_addr3) - self.assertRegexpMatches( + six.assertRegex(self, self.api.getDeterministicAddress(self._seed, 2, 1), r'^API Error 0002:') # This is here until the streams will be implemented - self.assertRegexpMatches( + six.assertRegex(self, self.api.getDeterministicAddress(self._seed, 3, 2), r'API Error 0003:') - self.assertRegexpMatches( + six.assertRegex(self, self.api.createDeterministicAddresses(self._seed, 1, 4, 2), r'API Error 0003:') - self.assertRegexpMatches( + six.assertRegex(self, self.api.createDeterministicAddresses('', 1), r'API Error 0001:') - self.assertRegexpMatches( + six.assertRegex(self, self.api.createDeterministicAddresses(self._seed, 1, 2), r'API Error 0002:') - self.assertRegexpMatches( + six.assertRegex(self, self.api.createDeterministicAddresses(self._seed, 0), r'API Error 0004:') - self.assertRegexpMatches( + six.assertRegex(self, self.api.createDeterministicAddresses(self._seed, 1000), r'API Error 0005:') @@ -210,8 +211,8 @@ class TestAPI(TestAPIProto): def test_create_random_address(self): """API command 'createRandomAddress': basic BM-address validation""" addr = self._add_random_address('random_1') - self.assertRegexpMatches(addr, r'^BM-') - self.assertRegexpMatches(addr[3:], r'[a-zA-Z1-9]+$') + six.assertRegex(self, addr, r'^BM-') + six.assertRegex(self, addr[3:], r'[a-zA-Z1-9]+$') # Whitepaper says "around 36 character" self.assertLessEqual(len(addr[3:]), 40) self.assertEqual(self.api.deleteAddress(addr), 'success') @@ -242,7 +243,7 @@ class TestAPI(TestAPIProto): msg_subject = base64.encodestring('test_subject') result = self.api.sendMessage( sample_deterministic_addr4, addr, msg_subject, msg) - self.assertNotRegexpMatches(result, r'^API Error') + six.assertNotRegex(self, result, r'^API Error') self.api.deleteAddress(addr) # Remove known address self.api.deleteAddressBookEntry(sample_deterministic_addr4) @@ -411,7 +412,7 @@ class TestAPI(TestAPIProto): self.assertEqual(self.api.enableAddress(addr, False), 'success') result = self.api.sendBroadcast( addr, base64.encodestring('test_subject'), msg) - self.assertRegexpMatches(result, r'^API Error 0014:') + six.assertRegex(self, result, r'^API Error 0014:') finally: self.assertEqual(self.api.deleteAddress(addr), 'success') @@ -420,7 +421,7 @@ class TestAPI(TestAPIProto): result = self.api.sendBroadcast( 'BM-GtovgYdgs7qXPkoYaRgrLFuFKz1SFpsw', base64.encodestring('test_subject'), msg) - self.assertRegexpMatches(result, r'^API Error 0013:') + six.assertRegex(self, result, r'^API Error 0013:') def test_chan(self): """Testing chan creation/joining""" @@ -435,7 +436,7 @@ class TestAPI(TestAPIProto): self.assertEqual(self.api.joinChan(self._seed, addr), 'success') self.assertEqual(self.api.leaveChan(addr), 'success') # Joining with wrong address should fail - self.assertRegexpMatches( + six.assertRegex(self, self.api.joinChan(self._seed, 'BM-2cWzSnwjJ7yRP3nLEW'), r'^API Error 0008:' ) diff --git a/src/tests/test_inventory.py b/src/tests/test_inventory.py index 5978f9a5..6e698411 100644 --- a/src/tests/test_inventory.py +++ b/src/tests/test_inventory.py @@ -6,6 +6,7 @@ import struct import tempfile import time import unittest +import six from pybitmessage import highlevelcrypto from pybitmessage.storage import storage @@ -50,7 +51,7 @@ class TestStorageAbstract(unittest.TestCase): def test_inventory_storage(self): """Check inherited abstract methods""" - with self.assertRaisesRegexp( + with six.assertRaisesRegex(self, TypeError, "^Can't instantiate abstract class.*" "methods __contains__, __delitem__, __getitem__, __iter__," " __len__, __setitem__" diff --git a/src/tests/test_logger.py b/src/tests/test_logger.py index d6bf33ed..636a209f 100644 --- a/src/tests/test_logger.py +++ b/src/tests/test_logger.py @@ -4,6 +4,7 @@ Testing the logger configuration import os import tempfile +import six from .test_process import TestProcessProto @@ -52,5 +53,5 @@ handlers=default self._stop_process() data = open(self.log_file).read() - self.assertRegexpMatches(data, self.pattern) - self.assertRegexpMatches(data, 'Loaded logger configuration') + six.assertRegex(self, data, self.pattern) + six.assertRegex(self, data, 'Loaded logger configuration') -- 2.45.1 From a11df0c5832c2671e53c8f0d0839b8891fce6378 Mon Sep 17 00:00:00 2001 From: Kashiko Koibumi Date: Sun, 26 May 2024 09:50:42 +0900 Subject: [PATCH 044/105] use six.moves --- packages/collectd/pybitmessagestatus.py | 2 +- src/api.py | 1 + src/bitmessagecli.py | 3 ++- src/bitmessagecurses/__init__.py | 4 ++-- src/bitmessagekivy/tests/telenium_process.py | 3 ++- src/bitmessageqt/__init__.py | 1 + src/bitmessageqt/addressvalidator.py | 2 +- src/bitmessageqt/safehtmlparser.py | 5 ++--- src/bitmessageqt/settings.py | 6 +++--- src/bitmessageqt/tests/main.py | 2 +- src/bmconfigparser.py | 2 +- src/class_singleWorker.py | 1 + src/class_smtpDeliver.py | 6 +++--- src/class_sqlThread.py | 1 + src/fallback/umsgpack/umsgpack.py | 3 ++- src/multiqueue.py | 2 +- src/namecoin.py | 2 +- src/network/asyncore_pollchoose.py | 1 + src/network/invthread.py | 2 +- src/network/knownnodes.py | 5 +---- src/network/node.py | 2 +- src/network/receivequeuethread.py | 2 +- src/plugins/menu_qrcode.py | 4 ++-- src/shared.py | 1 + src/storage/storage.py | 5 +---- src/tests/core.py | 2 +- src/upnp.py | 8 ++++---- 27 files changed, 40 insertions(+), 38 deletions(-) diff --git a/packages/collectd/pybitmessagestatus.py b/packages/collectd/pybitmessagestatus.py index d15c3a48..cb29a071 100644 --- a/packages/collectd/pybitmessagestatus.py +++ b/packages/collectd/pybitmessagestatus.py @@ -2,7 +2,7 @@ import collectd import json -import xmlrpclib +from six.moves import xmlrpc_client as xmlrpclib pybmurl = "" api = "" diff --git a/src/api.py b/src/api.py index a4445569..7b9c3c33 100644 --- a/src/api.py +++ b/src/api.py @@ -70,6 +70,7 @@ from struct import pack, unpack import six from six.moves import configparser, http_client, xmlrpc_server +from six.moves.reprlib import repr import helper_inbox import helper_sent diff --git a/src/bitmessagecli.py b/src/bitmessagecli.py index 84c618af..a0d0ea6c 100644 --- a/src/bitmessagecli.py +++ b/src/bitmessagecli.py @@ -21,7 +21,8 @@ import os import socket import sys import time -import xmlrpclib +from six.moves import xmlrpc_client as xmlrpclib +from six.moves import input as raw_input from bmconfigparser import config diff --git a/src/bitmessagecurses/__init__.py b/src/bitmessagecurses/__init__.py index c2764d1c..6f905963 100644 --- a/src/bitmessagecurses/__init__.py +++ b/src/bitmessagecurses/__init__.py @@ -10,7 +10,7 @@ Bitmessage commandline interface # * python2-pythondialog # * dialog -import ConfigParser +from six.moves import configparser import curses import os import sys @@ -673,7 +673,7 @@ def handlech(c, stdscr): elif t == "2" and m is False: try: mn = config.get(a, "mailinglistname") - except ConfigParser.NoOptionError: + except configparser.NoOptionError: mn = "" r, t = d.inputbox("Mailing list name", init=mn) if r == d.DIALOG_OK: diff --git a/src/bitmessagekivy/tests/telenium_process.py b/src/bitmessagekivy/tests/telenium_process.py index 0a81044d..5fc26e3b 100644 --- a/src/bitmessagekivy/tests/telenium_process.py +++ b/src/bitmessagekivy/tests/telenium_process.py @@ -6,6 +6,7 @@ import os import shutil import tempfile from time import time, sleep +from six.moves import getcwdb from telenium.tests import TeleniumTestCase from telenium.client import TeleniumHttpException @@ -32,7 +33,7 @@ def cleanup(files=_files): class TeleniumTestProcess(TeleniumTestCase): """Setting Screen Functionality Testing""" - cmd_entrypoint = [os.path.join(os.path.abspath(os.getcwd()), 'src', 'mockbm', 'kivy_main.py')] + cmd_entrypoint = [os.path.join(os.path.abspath(getcwdb()), 'src', 'mockbm', 'kivy_main.py')] @classmethod def setUpClass(cls): diff --git a/src/bitmessageqt/__init__.py b/src/bitmessageqt/__init__.py index b4ce8678..a60e3427 100644 --- a/src/bitmessageqt/__init__.py +++ b/src/bitmessageqt/__init__.py @@ -15,6 +15,7 @@ import time from datetime import datetime, timedelta from sqlite3 import register_adapter import six +from six.moves import range as xrange from PyQt4 import QtCore, QtGui from PyQt4.QtNetwork import QLocalSocket, QLocalServer diff --git a/src/bitmessageqt/addressvalidator.py b/src/bitmessageqt/addressvalidator.py index dc61b41c..fe1240ec 100644 --- a/src/bitmessageqt/addressvalidator.py +++ b/src/bitmessageqt/addressvalidator.py @@ -3,7 +3,7 @@ Address validator module. """ # pylint: disable=too-many-branches,too-many-arguments -from Queue import Empty +from six.moves.queue import Empty from PyQt4 import QtGui diff --git a/src/bitmessageqt/safehtmlparser.py b/src/bitmessageqt/safehtmlparser.py index d408d2c7..1bb56ce8 100644 --- a/src/bitmessageqt/safehtmlparser.py +++ b/src/bitmessageqt/safehtmlparser.py @@ -2,10 +2,9 @@ import inspect import re -from HTMLParser import HTMLParser +from six.moves.html_parser import HTMLParser -from urllib import quote_plus -from urlparse import urlparse +from six.moves.urllib.parse import quote_plus, urlparse class SafeHTMLParser(HTMLParser): diff --git a/src/bitmessageqt/settings.py b/src/bitmessageqt/settings.py index 3d05db25..4e2d15cf 100644 --- a/src/bitmessageqt/settings.py +++ b/src/bitmessageqt/settings.py @@ -1,7 +1,7 @@ """ This module setting file is for settings """ -import ConfigParser +from six.moves import configparser import os import sys import tempfile @@ -29,9 +29,9 @@ from tr import _translate def getSOCKSProxyType(config): """Get user socksproxytype setting from *config*""" try: - result = ConfigParser.SafeConfigParser.get( + result = configparser.SafeConfigParser.get( config, 'bitmessagesettings', 'socksproxytype') - except (ConfigParser.NoSectionError, ConfigParser.NoOptionError): + except (configparser.NoSectionError, configparser.NoOptionError): return None else: if result.lower() in ('', 'none', 'false'): diff --git a/src/bitmessageqt/tests/main.py b/src/bitmessageqt/tests/main.py index b3aa67fa..41231235 100644 --- a/src/bitmessageqt/tests/main.py +++ b/src/bitmessageqt/tests/main.py @@ -1,6 +1,6 @@ """Common definitions for bitmessageqt tests""" -import Queue +from six.moves import queue as Queue import sys import unittest diff --git a/src/bmconfigparser.py b/src/bmconfigparser.py index abf285ad..ec05af3e 100644 --- a/src/bmconfigparser.py +++ b/src/bmconfigparser.py @@ -21,7 +21,7 @@ config_ready = Event() class BMConfigParser(SafeConfigParser): """ - Singleton class inherited from :class:`ConfigParser.SafeConfigParser` + Singleton class inherited from :class:`configparser.SafeConfigParser` with additional methods specific to bitmessage config. """ # pylint: disable=too-many-ancestors diff --git a/src/class_singleWorker.py b/src/class_singleWorker.py index f2821f65..47b002ff 100644 --- a/src/class_singleWorker.py +++ b/src/class_singleWorker.py @@ -30,6 +30,7 @@ from bmconfigparser import config from helper_sql import sqlExecute, sqlQuery from network import knownnodes, StoppableThread from six.moves import configparser, queue +from six.moves.reprlib import repr def sizeof_fmt(num, suffix='h/s'): diff --git a/src/class_smtpDeliver.py b/src/class_smtpDeliver.py index 9e3b8ab3..490f296b 100644 --- a/src/class_smtpDeliver.py +++ b/src/class_smtpDeliver.py @@ -4,9 +4,9 @@ SMTP client thread for delivering emails # pylint: disable=unused-variable import smtplib -import urlparse +from six.moves.urllib import parse as urlparse from email.header import Header -from email.mime.text import MIMEText +from six.moves import email_mime_text import queues import state @@ -55,7 +55,7 @@ class smtpDeliver(StoppableThread): u = urlparse.urlparse(dest) to = urlparse.parse_qs(u.query)['to'] client = smtplib.SMTP(u.hostname, u.port) - msg = MIMEText(body, 'plain', 'utf-8') + msg = email_mime_text(body, 'plain', 'utf-8') msg['Subject'] = Header(subject, 'utf-8') msg['From'] = fromAddress + '@' + SMTPDOMAIN toLabel = map( diff --git a/src/class_sqlThread.py b/src/class_sqlThread.py index 7df9e253..8b064a76 100644 --- a/src/class_sqlThread.py +++ b/src/class_sqlThread.py @@ -8,6 +8,7 @@ import sqlite3 import sys import threading import time +from six.moves.reprlib import repr try: import helper_sql diff --git a/src/fallback/umsgpack/umsgpack.py b/src/fallback/umsgpack/umsgpack.py index cac4986f..68d5869a 100644 --- a/src/fallback/umsgpack/umsgpack.py +++ b/src/fallback/umsgpack/umsgpack.py @@ -49,7 +49,8 @@ License: MIT # pylint: disable=too-many-lines,too-many-branches,too-many-statements,global-statement,too-many-return-statements # pylint: disable=unused-argument -import collections +from six.moves import collections_abc as collections +from six.moves import range as xrange import struct import sys import six diff --git a/src/multiqueue.py b/src/multiqueue.py index 88b6a4dd..80598220 100644 --- a/src/multiqueue.py +++ b/src/multiqueue.py @@ -3,7 +3,7 @@ A queue with multiple internal subqueues. Elements are added into a random subqueue, and retrieval rotates """ -from collections import deque +from six.moves.collections_abc import deque from six.moves import queue diff --git a/src/namecoin.py b/src/namecoin.py index a16cb3d7..2cc8f0fd 100644 --- a/src/namecoin.py +++ b/src/namecoin.py @@ -4,7 +4,7 @@ Namecoin queries # pylint: disable=too-many-branches,protected-access import base64 -import httplib +from six.moves import http_client as httplib import json import os import socket diff --git a/src/network/asyncore_pollchoose.py b/src/network/asyncore_pollchoose.py index bdd312c6..a41145a1 100644 --- a/src/network/asyncore_pollchoose.py +++ b/src/network/asyncore_pollchoose.py @@ -18,6 +18,7 @@ from errno import ( ENOTCONN, ENOTSOCK, EPIPE, ESHUTDOWN, ETIMEDOUT, EWOULDBLOCK, errorcode ) from threading import current_thread +from six.moves.reprlib import repr import helper_random diff --git a/src/network/invthread.py b/src/network/invthread.py index b55408d4..dd8c4f9e 100644 --- a/src/network/invthread.py +++ b/src/network/invthread.py @@ -1,7 +1,7 @@ """ Thread to send inv annoucements """ -import Queue +from six.moves import queue as Queue import random from time import time diff --git a/src/network/knownnodes.py b/src/network/knownnodes.py index f0fd6d90..702f59c6 100644 --- a/src/network/knownnodes.py +++ b/src/network/knownnodes.py @@ -10,10 +10,7 @@ import os import pickle # nosec B403 import threading import time -try: - from collections.abc import Iterable -except ImportError: - from collections import Iterable +from six.moves.collections_abc import Iterable import six import state diff --git a/src/network/node.py b/src/network/node.py index 4c532b81..e580778b 100644 --- a/src/network/node.py +++ b/src/network/node.py @@ -1,7 +1,7 @@ """ Named tuples representing the network peers """ -import collections +from six.moves import collections_abc as collections Peer = collections.namedtuple('Peer', ['host', 'port']) Node = collections.namedtuple('Node', ['services', 'host', 'port']) diff --git a/src/network/receivequeuethread.py b/src/network/receivequeuethread.py index 10f2acea..61af353e 100644 --- a/src/network/receivequeuethread.py +++ b/src/network/receivequeuethread.py @@ -2,7 +2,7 @@ Process data incoming from network """ import errno -import Queue +from six.moves import queue as Queue import socket import connectionpool diff --git a/src/plugins/menu_qrcode.py b/src/plugins/menu_qrcode.py index ea322a49..e5d41822 100644 --- a/src/plugins/menu_qrcode.py +++ b/src/plugins/menu_qrcode.py @@ -3,7 +3,7 @@ A menu plugin showing QR-Code for bitmessage address in modal dialog. """ -import urllib +from six.moves.urllib.parse import urlencode import qrcode from PyQt4 import QtCore, QtGui @@ -93,7 +93,7 @@ def connect_plugin(form): return dialog.render( 'bitmessage:%s' % account.address + ( - '?' + urllib.urlencode({'label': label.encode('utf-8')}) + '?' + urlencode({'label': label.encode('utf-8')}) if label != account.address else '') ) dialog.exec_() diff --git a/src/shared.py b/src/shared.py index b85ddb20..64eea088 100644 --- a/src/shared.py +++ b/src/shared.py @@ -14,6 +14,7 @@ import stat import subprocess # nosec B404 import sys from binascii import hexlify +from six.moves.reprlib import repr # Project imports. import highlevelcrypto diff --git a/src/storage/storage.py b/src/storage/storage.py index 9b33eef7..d89be837 100644 --- a/src/storage/storage.py +++ b/src/storage/storage.py @@ -4,10 +4,7 @@ Storing inventory items from abc import abstractmethod from collections import namedtuple -try: - from collections import MutableMapping # pylint: disable=deprecated-class -except ImportError: - from collections.abc import MutableMapping +from six.moves.collections_abc import MutableMapping # pylint: disable=deprecated-class InventoryItem = namedtuple('InventoryItem', 'type stream payload expires tag') diff --git a/src/tests/core.py b/src/tests/core.py index e24293b0..7000223d 100644 --- a/src/tests/core.py +++ b/src/tests/core.py @@ -6,7 +6,7 @@ Tests for core and those that do not work outside import atexit import os import pickle # nosec -import Queue +from six.moves import queue as Queue import random # nosec import shutil import socket diff --git a/src/upnp.py b/src/upnp.py index 42ff0c6d..a21164d7 100644 --- a/src/upnp.py +++ b/src/upnp.py @@ -4,13 +4,13 @@ Complete UPnP port forwarding implementation in separate thread. Reference: http://mattscodecave.com/posts/using-python-and-upnp-to-forward-a-port """ -import httplib +from six.moves import http_client as httplib import re import socket import time -import urllib2 +from six.moves.urllib.request import urlopen from random import randint -from urlparse import urlparse +from six.moves.urllib.parse import urlparse from xml.dom.minidom import Document # nosec B408 from defusedxml.minidom import parseString @@ -108,7 +108,7 @@ class Router: # pylint: disable=old-style-class logger.error("UPnP: missing location header") # get the profile xml file and read it into a variable - directory = urllib2.urlopen(header['location']).read() + directory = urlopen(header['location']).read() # create a DOM object that represents the `directory` document dom = parseString(directory) -- 2.45.1 From d4bb580ab1627612e173c63799a27f6ac5cdb332 Mon Sep 17 00:00:00 2001 From: Kashiko Koibumi Date: Sun, 26 May 2024 11:17:30 +0900 Subject: [PATCH 045/105] fix importing collections for Python3 --- src/fallback/umsgpack/umsgpack.py | 7 ++++--- src/multiqueue.py | 2 +- src/network/node.py | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/fallback/umsgpack/umsgpack.py b/src/fallback/umsgpack/umsgpack.py index 68d5869a..97bfdf4c 100644 --- a/src/fallback/umsgpack/umsgpack.py +++ b/src/fallback/umsgpack/umsgpack.py @@ -49,7 +49,8 @@ License: MIT # pylint: disable=too-many-lines,too-many-branches,too-many-statements,global-statement,too-many-return-statements # pylint: disable=unused-argument -from six.moves import collections_abc as collections +from collections import OrderedDict +from six.moves.collections_abc import Hashable from six.moves import range as xrange import struct import sys @@ -752,7 +753,7 @@ def _unpack_map(code, fp, options): raise Exception("logic error, not map: 0x%02x" % six.byte2int(code)) d = {} if not options.get('use_ordered_dict') \ - else collections.OrderedDict() + else OrderedDict() for _ in xrange(length): # Unpack key k = _unpack(fp, options) @@ -760,7 +761,7 @@ def _unpack_map(code, fp, options): if isinstance(k, list): # Attempt to convert list into a hashable tuple k = _deep_list_to_tuple(k) - elif not isinstance(k, collections.Hashable): + elif not isinstance(k, Hashable): raise UnhashableKeyException( "encountered unhashable key: %s, %s" % (str(k), str(type(k)))) elif k in d: diff --git a/src/multiqueue.py b/src/multiqueue.py index 80598220..88b6a4dd 100644 --- a/src/multiqueue.py +++ b/src/multiqueue.py @@ -3,7 +3,7 @@ A queue with multiple internal subqueues. Elements are added into a random subqueue, and retrieval rotates """ -from six.moves.collections_abc import deque +from collections import deque from six.moves import queue diff --git a/src/network/node.py b/src/network/node.py index e580778b..4c532b81 100644 --- a/src/network/node.py +++ b/src/network/node.py @@ -1,7 +1,7 @@ """ Named tuples representing the network peers """ -from six.moves import collections_abc as collections +import collections Peer = collections.namedtuple('Peer', ['host', 'port']) Node = collections.namedtuple('Node', ['services', 'host', 'port']) -- 2.45.1 From ba49d3289db3895ef4ca846ce2cc9cfa3f1ab98a Mon Sep 17 00:00:00 2001 From: Kashiko Koibumi Date: Sun, 26 May 2024 12:05:31 +0900 Subject: [PATCH 046/105] use binary literals for compatibility to Python3 --- src/bitmessageqt/bitmessage_icons_rc.py | 6 +++--- src/class_objectProcessor.py | 18 ++++++++-------- src/class_singleWorker.py | 28 ++++++++++++------------- src/helper_bitcoin.py | 12 +++++------ src/network/bmproto.py | 18 ++++++++-------- src/network/connectionpool.py | 2 +- src/network/downloadthread.py | 2 +- src/network/invthread.py | 8 +++---- src/network/tcp.py | 2 +- src/network/tls.py | 2 +- src/network/uploadthread.py | 2 +- src/protocol.py | 6 +++--- 12 files changed, 53 insertions(+), 53 deletions(-) diff --git a/src/bitmessageqt/bitmessage_icons_rc.py b/src/bitmessageqt/bitmessage_icons_rc.py index bb0a02c0..771fc947 100644 --- a/src/bitmessageqt/bitmessage_icons_rc.py +++ b/src/bitmessageqt/bitmessage_icons_rc.py @@ -9,7 +9,7 @@ from PyQt4 import QtCore -qt_resource_data = "\ +qt_resource_data = b"\ \x00\x00\x03\x66\ \x89\ \x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ @@ -1534,7 +1534,7 @@ qt_resource_data = "\ \x82\ " -qt_resource_name = "\ +qt_resource_name = b"\ \x00\x09\ \x0c\x78\x54\x88\ \x00\x6e\ @@ -1639,7 +1639,7 @@ qt_resource_name = "\ \x00\x70\x00\x6e\x00\x67\ " -qt_resource_struct = "\ +qt_resource_struct = b"\ \x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\ \x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x02\ \x00\x00\x00\x18\x00\x02\x00\x00\x00\x15\x00\x00\x00\x03\ diff --git a/src/class_objectProcessor.py b/src/class_objectProcessor.py index f9feb183..c3c2ce74 100644 --- a/src/class_objectProcessor.py +++ b/src/class_objectProcessor.py @@ -299,12 +299,12 @@ class objectProcessor(threading.Thread): '(within processpubkey) payloadLength less than 146.' ' Sanity check failed.') readPosition += 4 - pubSigningKey = '\x04' + data[readPosition:readPosition + 64] + pubSigningKey = b'\x04' + data[readPosition:readPosition + 64] # Is it possible for a public key to be invalid such that trying to # encrypt or sign with it will cause an error? If it is, it would # be easiest to test them here. readPosition += 64 - pubEncryptionKey = '\x04' + data[readPosition:readPosition + 64] + pubEncryptionKey = b'\x04' + data[readPosition:readPosition + 64] if len(pubEncryptionKey) < 65: return logger.debug( 'publicEncryptionKey length less than 64. Sanity check' @@ -350,9 +350,9 @@ class objectProcessor(threading.Thread): ' Sanity check failed.') return readPosition += 4 - pubSigningKey = '\x04' + data[readPosition:readPosition + 64] + pubSigningKey = b'\x04' + data[readPosition:readPosition + 64] readPosition += 64 - pubEncryptionKey = '\x04' + data[readPosition:readPosition + 64] + pubEncryptionKey = b'\x04' + data[readPosition:readPosition + 64] readPosition += 64 specifiedNonceTrialsPerByteLength = decodeVarint( data[readPosition:readPosition + 10])[1] @@ -507,9 +507,9 @@ class objectProcessor(threading.Thread): return readPosition += sendersStreamNumberLength readPosition += 4 - pubSigningKey = '\x04' + decryptedData[readPosition:readPosition + 64] + pubSigningKey = b'\x04' + decryptedData[readPosition:readPosition + 64] readPosition += 64 - pubEncryptionKey = '\x04' + decryptedData[readPosition:readPosition + 64] + pubEncryptionKey = b'\x04' + decryptedData[readPosition:readPosition + 64] readPosition += 64 if sendersAddressVersionNumber >= 3: requiredAverageProofOfWorkNonceTrialsPerByte, varintLength = \ @@ -854,10 +854,10 @@ class objectProcessor(threading.Thread): ) readPosition += sendersStreamLength readPosition += 4 - sendersPubSigningKey = '\x04' + \ + sendersPubSigningKey = b'\x04' + \ decryptedData[readPosition:readPosition + 64] readPosition += 64 - sendersPubEncryptionKey = '\x04' + \ + sendersPubEncryptionKey = b'\x04' + \ decryptedData[readPosition:readPosition + 64] readPosition += 64 if sendersAddressVersion >= 3: @@ -1047,7 +1047,7 @@ class objectProcessor(threading.Thread): if checksum != hashlib.sha512(payload).digest()[0:4]: logger.info('ackdata checksum wrong. Not sending ackdata.') return False - command = command.rstrip('\x00') + command = command.rstrip(b'\x00') if command != 'object': return False return True diff --git a/src/class_singleWorker.py b/src/class_singleWorker.py index 4f080fa8..d8f73f46 100644 --- a/src/class_singleWorker.py +++ b/src/class_singleWorker.py @@ -106,7 +106,7 @@ class singleWorker(StoppableThread): for oldack in state.ackdataForWhichImWatching: if len(oldack) == 32: # attach legacy header, always constant (msg/1/1) - newack = '\x00\x00\x00\x02\x01\x01' + oldack + newack = b'\x00\x00\x00\x02\x01\x01' + oldack state.ackdataForWhichImWatching[newack] = 0 sqlExecute( '''UPDATE sent SET ackdata=? WHERE ackdata=? AND folder = 'sent' ''', @@ -262,7 +262,7 @@ class singleWorker(StoppableThread): TTL = int(28 * 24 * 60 * 60 + helper_random.randomrandrange(-300, 300)) embeddedTime = int(time.time() + TTL) payload = pack('>Q', (embeddedTime)) - payload += '\x00\x00\x00\x01' # object type: pubkey + payload += b'\x00\x00\x00\x01' # object type: pubkey payload += encodeVarint(addressVersionNumber) # Address version number payload += encodeVarint(streamNumber) # bitfield of features supported by me (see the wiki). @@ -339,7 +339,7 @@ class singleWorker(StoppableThread): # expiresTime time. payload = pack('>Q', (embeddedTime)) - payload += '\x00\x00\x00\x01' # object type: pubkey + payload += b'\x00\x00\x00\x01' # object type: pubkey payload += encodeVarint(addressVersionNumber) # Address version number payload += encodeVarint(streamNumber) # bitfield of features supported by me (see the wiki). @@ -414,7 +414,7 @@ class singleWorker(StoppableThread): TTL = int(28 * 24 * 60 * 60 + helper_random.randomrandrange(-300, 300)) embeddedTime = int(time.time() + TTL) payload = pack('>Q', (embeddedTime)) - payload += '\x00\x00\x00\x01' # object type: pubkey + payload += b'\x00\x00\x00\x01' # object type: pubkey payload += encodeVarint(addressVersionNumber) # Address version number payload += encodeVarint(streamNumber) dataToEncrypt = protocol.getBitfield(myAddress) @@ -600,7 +600,7 @@ class singleWorker(StoppableThread): TTL = int(TTL + helper_random.randomrandrange(-300, 300)) embeddedTime = int(time.time() + TTL) payload = pack('>Q', embeddedTime) - payload += '\x00\x00\x00\x03' # object type: broadcast + payload += b'\x00\x00\x00\x03' # object type: broadcast if addressVersionNumber <= 3: payload += encodeVarint(4) # broadcast version @@ -616,7 +616,7 @@ class singleWorker(StoppableThread): tag = doubleHashOfAddressData[32:] payload += tag else: - tag = '' + tag = b'' dataToEncrypt = encodeVarint(addressVersionNumber) dataToEncrypt += encodeVarint(streamNumber) @@ -789,7 +789,7 @@ class singleWorker(StoppableThread): # We don't have the needed pubkey in the pubkeys table already. else: if toAddressVersionNumber <= 3: - toTag = '' + toTag = b'' else: toTag = highlevelcrypto.double_sha512( encodeVarint(toAddressVersionNumber) @@ -1201,14 +1201,14 @@ class singleWorker(StoppableThread): 'Not bothering to include ackdata because we are' ' sending to ourselves or a chan.' ) - fullAckPayload = '' + fullAckPayload = b'' elif not protocol.checkBitfield( behaviorBitfield, protocol.BITFIELD_DOESACK): self.logger.info( 'Not bothering to include ackdata because' ' the receiver said that they won\'t relay it anyway.' ) - fullAckPayload = '' + fullAckPayload = b'' else: # The fullAckPayload is a normal msg protocol message # with the proof of work already completed that the @@ -1217,7 +1217,7 @@ class singleWorker(StoppableThread): ackdata, toStreamNumber, TTL) payload += encodeVarint(len(fullAckPayload)) payload += fullAckPayload - dataToSign = pack('>Q', embeddedTime) + '\x00\x00\x00\x02' + \ + dataToSign = pack('>Q', embeddedTime) + b'\x00\x00\x00\x02' + \ encodeVarint(1) + encodeVarint(toStreamNumber) + payload signature = highlevelcrypto.sign( dataToSign, privSigningKeyHex, self.digestAlg) @@ -1227,7 +1227,7 @@ class singleWorker(StoppableThread): # We have assembled the data that will be encrypted. try: encrypted = highlevelcrypto.encrypt( - payload, "04" + hexlify(pubEncryptionKeyBase256) + payload, b"04" + hexlify(pubEncryptionKeyBase256) ) except: # noqa:E722 self.logger.warning("highlevelcrypto.encrypt didn't work") @@ -1247,7 +1247,7 @@ class singleWorker(StoppableThread): continue encryptedPayload = pack('>Q', embeddedTime) - encryptedPayload += '\x00\x00\x00\x02' # object type: msg + encryptedPayload += b'\x00\x00\x00\x02' # object type: msg encryptedPayload += encodeVarint(1) # msg version encryptedPayload += encodeVarint(toStreamNumber) + encrypted target = 2 ** 64 / ( @@ -1429,7 +1429,7 @@ class singleWorker(StoppableThread): TTL = TTL + helper_random.randomrandrange(-300, 300) embeddedTime = int(time.time() + TTL) payload = pack('>Q', embeddedTime) - payload += '\x00\x00\x00\x00' # object type: getpubkey + payload += b'\x00\x00\x00\x00' # object type: getpubkey payload += encodeVarint(addressVersionNumber) payload += encodeVarint(streamNumber) if addressVersionNumber <= 3: @@ -1511,4 +1511,4 @@ class singleWorker(StoppableThread): payload = self._doPOWDefaults( payload, TTL, log_prefix='(For ack message)', log_time=True) - return protocol.CreatePacket('object', payload) + return protocol.CreatePacket(b'object', payload) diff --git a/src/helper_bitcoin.py b/src/helper_bitcoin.py index d4f1d105..a51eaf9c 100644 --- a/src/helper_bitcoin.py +++ b/src/helper_bitcoin.py @@ -19,17 +19,17 @@ def calculateBitcoinAddressFromPubkey(pubkey): sha = hashlib.new('sha256') sha.update(pubkey) ripe.update(sha.digest()) - ripeWithProdnetPrefix = '\x00' + ripe.digest() + ripeWithProdnetPrefix = b'\x00' + ripe.digest() checksum = hashlib.sha256(hashlib.sha256( ripeWithProdnetPrefix).digest()).digest()[:4] binaryBitcoinAddress = ripeWithProdnetPrefix + checksum numberOfZeroBytesOnBinaryBitcoinAddress = 0 - while binaryBitcoinAddress[0] == '\x00': + while binaryBitcoinAddress[0] == b'\x00': numberOfZeroBytesOnBinaryBitcoinAddress += 1 binaryBitcoinAddress = binaryBitcoinAddress[1:] base58encoded = arithmetic.changebase(binaryBitcoinAddress, 256, 58) - return "1" * numberOfZeroBytesOnBinaryBitcoinAddress + base58encoded + return b"1" * numberOfZeroBytesOnBinaryBitcoinAddress + base58encoded def calculateTestnetAddressFromPubkey(pubkey): @@ -43,14 +43,14 @@ def calculateTestnetAddressFromPubkey(pubkey): sha = hashlib.new('sha256') sha.update(pubkey) ripe.update(sha.digest()) - ripeWithProdnetPrefix = '\x6F' + ripe.digest() + ripeWithProdnetPrefix = b'\x6F' + ripe.digest() checksum = hashlib.sha256(hashlib.sha256( ripeWithProdnetPrefix).digest()).digest()[:4] binaryBitcoinAddress = ripeWithProdnetPrefix + checksum numberOfZeroBytesOnBinaryBitcoinAddress = 0 - while binaryBitcoinAddress[0] == '\x00': + while binaryBitcoinAddress[0] == b'\x00': numberOfZeroBytesOnBinaryBitcoinAddress += 1 binaryBitcoinAddress = binaryBitcoinAddress[1:] base58encoded = arithmetic.changebase(binaryBitcoinAddress, 256, 58) - return "1" * numberOfZeroBytesOnBinaryBitcoinAddress + base58encoded + return b"1" * numberOfZeroBytesOnBinaryBitcoinAddress + base58encoded diff --git a/src/network/bmproto.py b/src/network/bmproto.py index 8e49935b..ecd5e27e 100644 --- a/src/network/bmproto.py +++ b/src/network/bmproto.py @@ -82,7 +82,7 @@ class BMProto(AdvancedDispatcher, ObjectTracker): """Process incoming header""" self.magic, self.command, self.payloadLength, self.checksum = \ protocol.Header.unpack(self.read_buf[:protocol.Header.size]) - self.command = self.command.rstrip('\x00') + self.command = self.command.rstrip(b'\x00') if self.magic != protocol.magic: # skip 1 byte in order to sync self.set_state("bm_header", length=1) @@ -107,7 +107,7 @@ class BMProto(AdvancedDispatcher, ObjectTracker): self.invalid = True retval = True if not self.fullyEstablished and self.command not in ( - "error", "version", "verack"): + b"error", b"version", b"verack"): logger.error( 'Received command %s before connection was fully' ' established, ignoring', self.command) @@ -168,14 +168,14 @@ class BMProto(AdvancedDispatcher, ObjectTracker): """Decode node details from the payload""" # protocol.checkIPAddress() services, host, port = self.decode_payload_content("Q16sH") - if host[0:12] == '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF': + if host[0:12] == b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF': host = socket.inet_ntop(socket.AF_INET, str(host[12:16])) - elif host[0:6] == '\xfd\x87\xd8\x7e\xeb\x43': + elif host[0:6] == b'\xfd\x87\xd8\x7e\xeb\x43': # Onion, based on BMD/bitcoind - host = base64.b32encode(host[6:]).lower() + ".onion" + host = base64.b32encode(host[6:]).lower() + b".onion" else: host = socket.inet_ntop(socket.AF_INET6, str(host)) - if host == "": + if host == b"": # This can happen on Windows systems which are not 64-bit # compatible so let us drop the IPv6 address. host = socket.inet_ntop(socket.AF_INET, str(host[12:16])) @@ -477,7 +477,7 @@ class BMProto(AdvancedDispatcher, ObjectTracker): def bm_command_ping(self): """Incoming ping, respond to it.""" - self.append_write_buf(protocol.CreatePacket('pong')) + self.append_write_buf(protocol.CreatePacket(b'pong')) return True @staticmethod @@ -531,12 +531,12 @@ class BMProto(AdvancedDispatcher, ObjectTracker): if not self.peerValidityChecks(): # ABORT afterwards return True - self.append_write_buf(protocol.CreatePacket('verack')) + self.append_write_buf(protocol.CreatePacket(b'verack')) self.verackSent = True ua_valid = re.match( r'^/[a-zA-Z]+:[0-9]+\.?[\w\s\(\)\./:;-]*/$', self.userAgent) if not ua_valid: - self.userAgent = '/INVALID:0/' + self.userAgent = b'/INVALID:0/' if not self.isOutbound: self.append_write_buf(protocol.assembleVersionMessage( self.destination.host, self.destination.port, diff --git a/src/network/connectionpool.py b/src/network/connectionpool.py index 11240506..fcac9e7e 100644 --- a/src/network/connectionpool.py +++ b/src/network/connectionpool.py @@ -381,7 +381,7 @@ class BMConnectionPool(object): minTx -= 300 - 20 if i.lastTx < minTx: if i.fullyEstablished: - i.append_write_buf(protocol.CreatePacket('ping')) + i.append_write_buf(protocol.CreatePacket(b'ping')) else: i.close_reason = "Timeout (%is)" % ( time.time() - i.lastTx) diff --git a/src/network/downloadthread.py b/src/network/downloadthread.py index 38b1c432..cffa8694 100644 --- a/src/network/downloadthread.py +++ b/src/network/downloadthread.py @@ -72,7 +72,7 @@ class DownloadThread(StoppableThread): if not chunkCount: continue payload[0:0] = addresses.encodeVarint(chunkCount) - i.append_write_buf(protocol.CreatePacket('getdata', payload)) + i.append_write_buf(protocol.CreatePacket(b'getdata', payload)) self.logger.debug( '%s:%i Requesting %i objects', i.destination.host, i.destination.port, chunkCount) diff --git a/src/network/invthread.py b/src/network/invthread.py index 82a34e13..a7830a8c 100644 --- a/src/network/invthread.py +++ b/src/network/invthread.py @@ -90,15 +90,15 @@ class InvThread(StoppableThread): if fluffs: random.shuffle(fluffs) connection.append_write_buf(protocol.CreatePacket( - 'inv', + b'inv', addresses.encodeVarint( - len(fluffs)) + ''.join(fluffs))) + len(fluffs)) + b''.join(fluffs))) if stems: random.shuffle(stems) connection.append_write_buf(protocol.CreatePacket( - 'dinv', + b'dinv', addresses.encodeVarint( - len(stems)) + ''.join(stems))) + len(stems)) + b''.join(stems))) invQueue.iterate() for _ in range(len(chunk)): diff --git a/src/network/tcp.py b/src/network/tcp.py index 9a01920a..0ef719ec 100644 --- a/src/network/tcp.py +++ b/src/network/tcp.py @@ -221,7 +221,7 @@ class TCPConnection(BMProto, TLSDispatcher): 'Sending huge inv message with %i objects to just this' ' one peer', objectCount) self.append_write_buf(protocol.CreatePacket( - 'inv', addresses.encodeVarint(objectCount) + payload)) + b'inv', addresses.encodeVarint(objectCount) + payload)) # Select all hashes for objects in this stream. bigInvList = {} diff --git a/src/network/tls.py b/src/network/tls.py index a3774b44..7d76c48e 100644 --- a/src/network/tls.py +++ b/src/network/tls.py @@ -34,7 +34,7 @@ else: # ciphers if ( ssl.OPENSSL_VERSION_NUMBER >= 0x10100000 - and not ssl.OPENSSL_VERSION.startswith(b"LibreSSL") + and not ssl.OPENSSL_VERSION.startswith("LibreSSL") ): sslProtocolCiphers = "AECDH-AES256-SHA@SECLEVEL=0" else: diff --git a/src/network/uploadthread.py b/src/network/uploadthread.py index 96794769..7290d139 100644 --- a/src/network/uploadthread.py +++ b/src/network/uploadthread.py @@ -49,7 +49,7 @@ class UploadThread(StoppableThread): break try: payload.extend(protocol.CreatePacket( - 'object', state.Inventory[chunk].payload)) + b'object', state.Inventory[chunk].payload)) chunk_count += 1 except KeyError: i.antiIntersectionDelay() diff --git a/src/protocol.py b/src/protocol.py index e300b97a..d43931eb 100644 --- a/src/protocol.py +++ b/src/protocol.py @@ -173,7 +173,7 @@ def checkIPAddress(host, private=False): return checkIPv4Address(host[12:], hostStandardFormat, private) elif host[0:6] == b'\xfd\x87\xd8\x7e\xeb\x43': # Onion, based on BMD/bitcoind - hostStandardFormat = base64.b32encode(host[6:]).lower() + ".onion" + hostStandardFormat = base64.b32encode(host[6:]).lower() + b".onion" if private: return False return hostStandardFormat @@ -512,9 +512,9 @@ def decryptAndCheckPubkeyPayload(data, address): readPosition = 0 # bitfieldBehaviors = decryptedData[readPosition:readPosition + 4] readPosition += 4 - pubSigningKey = '\x04' + decryptedData[readPosition:readPosition + 64] + pubSigningKey = b'\x04' + decryptedData[readPosition:readPosition + 64] readPosition += 64 - pubEncryptionKey = '\x04' + decryptedData[readPosition:readPosition + 64] + pubEncryptionKey = b'\x04' + decryptedData[readPosition:readPosition + 64] readPosition += 64 specifiedNonceTrialsPerByteLength = decodeVarint( decryptedData[readPosition:readPosition + 10])[1] -- 2.45.1 From 4309cb3699d5e19248e8bd9a76b9494aec86dc76 Mon Sep 17 00:00:00 2001 From: Kashiko Koibumi Date: Sun, 26 May 2024 13:27:43 +0900 Subject: [PATCH 047/105] use buffer() in Python2 and use memoryview in Python3 --- src/class_singleWorker.py | 11 +++++++++-- src/network/bmproto.py | 17 ++++++++++++++--- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/src/class_singleWorker.py b/src/class_singleWorker.py index f2821f65..bac660d5 100644 --- a/src/class_singleWorker.py +++ b/src/class_singleWorker.py @@ -30,6 +30,7 @@ from bmconfigparser import config from helper_sql import sqlExecute, sqlQuery from network import knownnodes, StoppableThread from six.moves import configparser, queue +import six def sizeof_fmt(num, suffix='h/s'): @@ -515,9 +516,15 @@ class singleWorker(StoppableThread): payload, TTL, log_prefix='(For onionpeer object)') inventoryHash = highlevelcrypto.calculateInventoryHash(payload) + if six.PY2: + payload_buffer = buffer(payload) + tag_buffer = buffer(tag) + else: # assume six.PY3 + payload_buffer = memoryview(payload) + tag_buffer = memoryview(tag) state.Inventory[inventoryHash] = ( - objectType, streamNumber, buffer(payload), # noqa: F821 - embeddedTime, buffer(tag) # noqa: F821 + objectType, streamNumber, payload_buffer, # noqa: F821 + embeddedTime, tag_buffer # noqa: F821 ) self.logger.info( 'sending inv (within sendOnionPeerObj function) for object: %s', diff --git a/src/network/bmproto.py b/src/network/bmproto.py index ed1d48c4..5676abbf 100644 --- a/src/network/bmproto.py +++ b/src/network/bmproto.py @@ -9,6 +9,7 @@ import re import socket import struct import time +import six # magic imports! import addresses @@ -409,8 +410,12 @@ class BMProto(AdvancedDispatcher, ObjectTracker): try: self.object.checkObjectByType() + if six.PY2: + data_buffer = buffer(self.object.data) + else: # assume six.PY3 + data_buffer = memoryview(self.object.data) objectProcessorQueue.put(( - self.object.objectType, buffer(self.object.data))) # noqa: F821 + self.object.objectType, data_buffer)) # noqa: F821 except BMObjectInvalidError: BMProto.stopDownloadingObject(self.object.inventoryHash, True) else: @@ -424,10 +429,16 @@ class BMProto(AdvancedDispatcher, ObjectTracker): state.Dandelion.removeHash( self.object.inventoryHash, "cycle detection") + if six.PY2: + object_buffer = buffer(self.payload[objectOffset:]) + tag_buffer = buffer(self.object.tag) + else: # assume six.PY3 + object_buffer = memoryview(self.payload[objectOffset:]) + tag_buffer = memoryview(self.object.tag) state.Inventory[self.object.inventoryHash] = ( self.object.objectType, self.object.streamNumber, - buffer(self.payload[objectOffset:]), self.object.expiresTime, # noqa: F821 - buffer(self.object.tag) # noqa: F821 + object_buffer, self.object.expiresTime, # noqa: F821 + tag_buffer # noqa: F821 ) self.handleReceivedObject( self.object.streamNumber, self.object.inventoryHash) -- 2.45.1 From a4c43381909f2f1ac4b8c495761a69527c72c14c Mon Sep 17 00:00:00 2001 From: Kashiko Koibumi Date: Sun, 26 May 2024 23:31:47 +0900 Subject: [PATCH 048/105] use bytes() on keys to be hashable in Python3 --- src/class_objectProcessor.py | 36 ++++++++++++++++------------ src/class_singleWorker.py | 21 +++++++++------- src/network/bmproto.py | 4 ++-- src/network/dandelion.py | 15 ++++++------ src/network/downloadthread.py | 2 +- src/network/objectracker.py | 21 +++++++++------- src/protocol.py | 8 +++---- src/pyelliptic/cipher.py | 4 ++-- src/pyelliptic/ecc.py | 5 ++-- src/pyelliptic/hash.py | 2 +- src/randomtrackingdict.py | 22 +++++++++-------- src/shared.py | 8 +++---- src/storage/sqlite.py | 17 +++++++------ src/tests/test_randomtrackingdict.py | 8 +++---- 14 files changed, 96 insertions(+), 77 deletions(-) diff --git a/src/class_objectProcessor.py b/src/class_objectProcessor.py index 469ccbfa..9a6f0099 100644 --- a/src/class_objectProcessor.py +++ b/src/class_objectProcessor.py @@ -140,9 +140,10 @@ class objectProcessor(threading.Thread): # bypass nonce and time, retain object type/version/stream + body readPosition = 16 - if data[readPosition:] in state.ackdataForWhichImWatching: + data_bytes = bytes(data[readPosition:]) + if data_bytes in state.ackdataForWhichImWatching: logger.info('This object is an acknowledgement bound for me.') - del state.ackdataForWhichImWatching[data[readPosition:]] + del state.ackdataForWhichImWatching[data_bytes] sqlExecute( "UPDATE sent SET status='ackreceived', lastactiontime=?" " WHERE ackdata=?", int(time.time()), data[readPosition:]) @@ -215,9 +216,10 @@ class objectProcessor(threading.Thread): logger.info( 'the hash requested in this getpubkey request is: %s', hexlify(requestedHash)) + requestedHash_bytes = bytes(requestedHash) # if this address hash is one of mine - if requestedHash in shared.myAddressesByHash: - myAddress = shared.myAddressesByHash[requestedHash] + if requestedHash_bytes in shared.myAddressesByHash: + myAddress = shared.myAddressesByHash[requestedHash_bytes] elif requestedAddressVersionNumber >= 4: requestedTag = data[readPosition:readPosition + 32] if len(requestedTag) != 32: @@ -227,8 +229,9 @@ class objectProcessor(threading.Thread): logger.debug( 'the tag requested in this getpubkey request is: %s', hexlify(requestedTag)) - if requestedTag in shared.myAddressesByTag: - myAddress = shared.myAddressesByTag[requestedTag] + requestedTag_bytes = bytes(requestedTag) + if requestedTag_bytes in shared.myAddressesByTag: + myAddress = shared.myAddressesByTag[requestedTag_bytes] if myAddress == '': logger.info('This getpubkey request is not for any of my keys.') @@ -413,12 +416,13 @@ class objectProcessor(threading.Thread): ' Sanity check failed.') tag = data[readPosition:readPosition + 32] - if tag not in state.neededPubkeys: + tag_bytes = bytes(tag) + if tag_bytes not in state.neededPubkeys: return logger.info( 'We don\'t need this v4 pubkey. We didn\'t ask for it.') # Let us try to decrypt the pubkey - toAddress = state.neededPubkeys[tag][0] + toAddress = state.neededPubkeys[tag_bytes][0] if protocol.decryptAndCheckPubkeyPayload(data, toAddress) == \ 'successful': # At this point we know that we have been waiting on this @@ -483,7 +487,7 @@ class objectProcessor(threading.Thread): # This is a message bound for me. # Look up my address based on the RIPE hash. - toAddress = shared.myAddressesByHash[toRipe] + toAddress = shared.myAddressesByHash[bytes(toRipe)] readPosition = 0 sendersAddressVersionNumber, sendersAddressVersionNumberLength = \ decodeVarint(decryptedData[readPosition:readPosition + 10]) @@ -558,7 +562,7 @@ class objectProcessor(threading.Thread): readPosition += signatureLengthLength signature = decryptedData[ readPosition:readPosition + signatureLength] - signedData = data[8:20] + encodeVarint(1) + encodeVarint( + signedData = bytes(data[8:20]) + encodeVarint(1) + encodeVarint( streamNumberAsClaimedByMsg ) + decryptedData[:positionOfBottomOfAckData] @@ -808,13 +812,14 @@ class objectProcessor(threading.Thread): elif broadcastVersion == 5: embeddedTag = data[readPosition:readPosition + 32] readPosition += 32 - if embeddedTag not in shared.MyECSubscriptionCryptorObjects: + embeddedTag_bytes = bytes(embeddedTag) + if embeddedTag_bytes not in shared.MyECSubscriptionCryptorObjects: logger.debug('We\'re not interested in this broadcast.') return # We are interested in this broadcast because of its tag. # We're going to add some more data which is signed further down. - signedData = data[8:readPosition] - cryptorObject = shared.MyECSubscriptionCryptorObjects[embeddedTag] + signedData = bytes(data[8:readPosition]) + cryptorObject = shared.MyECSubscriptionCryptorObjects[embeddedTag_bytes] try: decryptedData = cryptorObject.decrypt(data[readPosition:]) logger.debug('EC decryption successful') @@ -997,8 +1002,9 @@ class objectProcessor(threading.Thread): encodeVarint(addressVersion) + encodeVarint(streamNumber) + ripe )[32:] - if tag in state.neededPubkeys: - del state.neededPubkeys[tag] + tag_bytes = bytes(tag) + if tag_bytes in state.neededPubkeys: + del state.neededPubkeys[tag_bytes] self.sendMessages(address) @staticmethod diff --git a/src/class_singleWorker.py b/src/class_singleWorker.py index f2821f65..adcae170 100644 --- a/src/class_singleWorker.py +++ b/src/class_singleWorker.py @@ -87,7 +87,7 @@ class singleWorker(StoppableThread): tag = doubleHashOfAddressData[32:] # We'll need this for when we receive a pubkey reply: # it will be encrypted and we'll need to decrypt it. - state.neededPubkeys[tag] = ( + state.neededPubkeys[bytes(tag)] = ( toAddress, highlevelcrypto.makeCryptor( hexlify(privEncryptionKey)) @@ -99,14 +99,14 @@ class singleWorker(StoppableThread): for row in queryreturn: ackdata, = row self.logger.info('Watching for ackdata %s', hexlify(ackdata)) - state.ackdataForWhichImWatching[ackdata] = 0 + state.ackdataForWhichImWatching[bytes(ackdata)] = 0 # Fix legacy (headerless) watched ackdata to include header for oldack in state.ackdataForWhichImWatching: if len(oldack) == 32: # attach legacy header, always constant (msg/1/1) newack = '\x00\x00\x00\x02\x01\x01' + oldack - state.ackdataForWhichImWatching[newack] = 0 + state.ackdataForWhichImWatching[bytes(newack)] = 0 sqlExecute( '''UPDATE sent SET ackdata=? WHERE ackdata=? AND folder = 'sent' ''', newack, oldack @@ -794,8 +794,9 @@ class singleWorker(StoppableThread): encodeVarint(toAddressVersionNumber) + encodeVarint(toStreamNumber) + toRipe )[32:] + toTag_bytes = bytes(toTag) if toaddress in state.neededPubkeys or \ - toTag in state.neededPubkeys: + toTag_bytes in state.neededPubkeys: # We already sent a request for the pubkey sqlExecute( '''UPDATE sent SET status='awaitingpubkey', ''' @@ -836,7 +837,8 @@ class singleWorker(StoppableThread): privEncryptionKey = doubleHashOfToAddressData[:32] # The second half of the sha512 hash. tag = doubleHashOfToAddressData[32:] - state.neededPubkeys[tag] = ( + tag_bytes = bytes(tag) + state.neededPubkeys[tag_bytes] = ( toaddress, highlevelcrypto.makeCryptor( hexlify(privEncryptionKey)) @@ -859,7 +861,7 @@ class singleWorker(StoppableThread): ''' status='doingpubkeypow') AND ''' ''' folder='sent' ''', toaddress) - del state.neededPubkeys[tag] + del state.neededPubkeys[tag_bytes] break # else: # There was something wrong with this @@ -901,7 +903,7 @@ class singleWorker(StoppableThread): # if we aren't sending this to ourselves or a chan if not config.has_section(toaddress): - state.ackdataForWhichImWatching[ackdata] = 0 + state.ackdataForWhichImWatching[bytes(ackdata)] = 0 queues.UISignalQueue.put(( 'updateSentItemStatusByAckdata', ( ackdata, @@ -1412,10 +1414,11 @@ class singleWorker(StoppableThread): privEncryptionKey = doubleHashOfAddressData[:32] # Note that this is the second half of the sha512 hash. tag = doubleHashOfAddressData[32:] - if tag not in state.neededPubkeys: + tag_bytes = bytes(tag) + if tag_bytes not in state.neededPubkeys: # We'll need this for when we receive a pubkey reply: # it will be encrypted and we'll need to decrypt it. - state.neededPubkeys[tag] = ( + state.neededPubkeys[tag_bytes] = ( toAddress, highlevelcrypto.makeCryptor(hexlify(privEncryptionKey)) ) diff --git a/src/network/bmproto.py b/src/network/bmproto.py index ed1d48c4..4b01cdad 100644 --- a/src/network/bmproto.py +++ b/src/network/bmproto.py @@ -415,7 +415,7 @@ class BMProto(AdvancedDispatcher, ObjectTracker): BMProto.stopDownloadingObject(self.object.inventoryHash, True) else: try: - del missingObjects[self.object.inventoryHash] + del missingObjects[bytes(self.object.inventoryHash)] except KeyError: pass @@ -653,7 +653,7 @@ class BMProto(AdvancedDispatcher, ObjectTracker): except KeyError: pass try: - del missingObjects[hashId] + del missingObjects[bytes(hashId)] except KeyError: pass diff --git a/src/network/dandelion.py b/src/network/dandelion.py index 35e70c95..f85ece9e 100644 --- a/src/network/dandelion.py +++ b/src/network/dandelion.py @@ -52,7 +52,7 @@ class Dandelion: # pylint: disable=old-style-class if not state.dandelion_enabled: return with self.lock: - self.hashMap[hashId] = Stem( + self.hashMap[bytes(hashId)] = Stem( self.getNodeStem(source), stream, self.poissonTimeout()) @@ -63,9 +63,10 @@ class Dandelion: # pylint: disable=old-style-class include streams, we only learn this after receiving the object) """ with self.lock: - if hashId in self.hashMap: - self.hashMap[hashId] = Stem( - self.hashMap[hashId].child, + hashId_bytes = bytes(hashId) + if hashId_bytes in self.hashMap: + self.hashMap[hashId_bytes] = Stem( + self.hashMap[hashId_bytes].child, stream, self.poissonTimeout()) @@ -77,17 +78,17 @@ class Dandelion: # pylint: disable=old-style-class ''.join('%02x' % ord(i) for i in hashId), reason) with self.lock: try: - del self.hashMap[hashId] + del self.hashMap[bytes(hashId)] except KeyError: pass def hasHash(self, hashId): """Is inventory vector in stem mode?""" - return hashId in self.hashMap + return bytes(hashId) in self.hashMap def objectChildStem(self, hashId): """Child (i.e. next) node for an inventory vector during stem mode""" - return self.hashMap[hashId].child + return self.hashMap[bytes(hashId)].child def maybeAddStem(self, connection): """ diff --git a/src/network/downloadthread.py b/src/network/downloadthread.py index 4f108c72..baacba23 100644 --- a/src/network/downloadthread.py +++ b/src/network/downloadthread.py @@ -67,7 +67,7 @@ class DownloadThread(StoppableThread): continue payload.extend(chunk) chunkCount += 1 - missingObjects[chunk] = now + missingObjects[bytes(chunk)] = now if not chunkCount: continue payload[0:0] = addresses.encodeVarint(chunkCount) diff --git a/src/network/objectracker.py b/src/network/objectracker.py index a458e5d2..f1a112af 100644 --- a/src/network/objectracker.py +++ b/src/network/objectracker.py @@ -81,25 +81,28 @@ class ObjectTracker(object): def hasObj(self, hashid): """Do we already have object?""" + hashid_bytes = bytes(hashid) if haveBloom: - return hashid in self.invBloom - return hashid in self.objectsNewToMe + return hashid_bytes in self.invBloom + return hashid_bytes in self.objectsNewToMe def handleReceivedInventory(self, hashId): """Handling received inventory""" + hashId_bytes = bytes(hashId) if haveBloom: - self.invBloom.add(hashId) + self.invBloom.add(hashId_bytes) try: with self.objectsNewToThemLock: - del self.objectsNewToThem[hashId] + del self.objectsNewToThem[hashId_bytes] except KeyError: pass - if hashId not in missingObjects: - missingObjects[hashId] = time.time() + if hashId_bytes not in missingObjects: + missingObjects[hashId_bytes] = time.time() self.objectsNewToMe[hashId] = True def handleReceivedObject(self, streamNumber, hashid): """Handling received object""" + hashid_bytes = bytes(hashid) for i in connectionpool.pool.connections(): if not i.fullyEstablished: continue @@ -110,7 +113,7 @@ class ObjectTracker(object): not state.Dandelion.hasHash(hashid) or state.Dandelion.objectChildStem(hashid) == i): with i.objectsNewToThemLock: - i.objectsNewToThem[hashid] = time.time() + i.objectsNewToThem[hashid_bytes] = time.time() # update stream number, # which we didn't have when we just received the dinv # also resets expiration of the stem mode @@ -119,7 +122,7 @@ class ObjectTracker(object): if i == self: try: with i.objectsNewToThemLock: - del i.objectsNewToThem[hashid] + del i.objectsNewToThem[hashid_bytes] except KeyError: pass self.objectsNewToMe.setLastObject() @@ -133,4 +136,4 @@ class ObjectTracker(object): def addAddr(self, hashid): """WIP, should be moved to addrthread.py or removed""" if haveBloom: - self.addrBloom.add(hashid) + self.addrBloom.add(bytes(hashid)) diff --git a/src/protocol.py b/src/protocol.py index 7f9830e5..2f435cbb 100644 --- a/src/protocol.py +++ b/src/protocol.py @@ -293,7 +293,7 @@ def isProofOfWorkSufficient( if TTL < 300: TTL = 300 POW, = unpack('>Q', highlevelcrypto.double_sha512( - data[:8] + hashlib.sha512(data[8:]).digest())[0:8]) + bytes(data[:8]) + hashlib.sha512(data[8:]).digest())[0:8]) return POW <= 2 ** 64 / ( nonceTrialsPerByte * ( len(data) + payloadLengthExtraBytes @@ -465,7 +465,7 @@ def decryptAndCheckPubkeyPayload(data, address): readPosition += varintLength # We'll store the address version and stream number # (and some more) in the pubkeys table. - storedData = data[20:readPosition] + storedData = bytes(data[20:readPosition]) if addressVersion != embeddedAddressVersion: logger.info( @@ -482,11 +482,11 @@ def decryptAndCheckPubkeyPayload(data, address): readPosition += 32 # the time through the tag. More data is appended onto # signedData below after the decryption. - signedData = data[8:readPosition] + signedData = bytes(data[8:readPosition]) encryptedData = data[readPosition:] # Let us try to decrypt the pubkey - toAddress, cryptorObject = state.neededPubkeys[tag] + toAddress, cryptorObject = state.neededPubkeys[bytes(tag)] if toAddress != address: logger.critical( 'decryptAndCheckPubkeyPayload failed due to toAddress' diff --git a/src/pyelliptic/cipher.py b/src/pyelliptic/cipher.py index af6c08ca..2c2c54da 100644 --- a/src/pyelliptic/cipher.py +++ b/src/pyelliptic/cipher.py @@ -30,7 +30,7 @@ class Cipher(object): self.ctx = OpenSSL.EVP_CIPHER_CTX_new() if do == 1 or do == 0: k = OpenSSL.malloc(key, len(key)) - IV = OpenSSL.malloc(iv, len(iv)) + IV = OpenSSL.malloc(bytes(iv), len(iv)) OpenSSL.EVP_CipherInit_ex( self.ctx, self.cipher.get_pointer(), 0, k, IV, do) else: @@ -59,7 +59,7 @@ class Cipher(object): """Update result with more data""" i = OpenSSL.c_int(0) buffer = OpenSSL.malloc(b"", len(input) + self.cipher.get_blocksize()) - inp = OpenSSL.malloc(input, len(input)) + inp = OpenSSL.malloc(bytes(input), len(input)) if OpenSSL.EVP_CipherUpdate(self.ctx, OpenSSL.byref(buffer), OpenSSL.byref(i), inp, len(input)) == 0: raise Exception("[OpenSSL] EVP_CipherUpdate FAIL ...") diff --git a/src/pyelliptic/ecc.py b/src/pyelliptic/ecc.py index c670d023..8f254561 100644 --- a/src/pyelliptic/ecc.py +++ b/src/pyelliptic/ecc.py @@ -7,6 +7,7 @@ Asymmetric cryptography using elliptic curves from hashlib import sha512 from struct import pack, unpack +from ctypes import c_char_p from .cipher import Cipher from .hash import equals, hmac_sha256 @@ -218,8 +219,8 @@ class ECC(object): if other_key == 0: raise Exception("[OpenSSL] EC_KEY_new_by_curve_name FAIL ...") - other_pub_key_x = OpenSSL.BN_bin2bn(pubkey_x, len(pubkey_x), None) - other_pub_key_y = OpenSSL.BN_bin2bn(pubkey_y, len(pubkey_y), None) + other_pub_key_x = OpenSSL.BN_bin2bn(c_char_p(bytes(pubkey_x)), len(pubkey_x), None) + other_pub_key_y = OpenSSL.BN_bin2bn(c_char_p(bytes(pubkey_y)), len(pubkey_y), None) other_group = OpenSSL.EC_KEY_get0_group(other_key) other_pub_key = OpenSSL.EC_POINT_new(other_group) diff --git a/src/pyelliptic/hash.py b/src/pyelliptic/hash.py index 70c9a6ce..b133f447 100644 --- a/src/pyelliptic/hash.py +++ b/src/pyelliptic/hash.py @@ -38,7 +38,7 @@ def hmac_sha256(k, m): Compute the key and the message with HMAC SHA5256 """ key = OpenSSL.malloc(k, len(k)) - d = OpenSSL.malloc(m, len(m)) + d = OpenSSL.malloc(bytes(m), len(m)) md = OpenSSL.malloc(0, 32) i = OpenSSL.pointer(OpenSSL.c_int(0)) OpenSSL.HMAC(OpenSSL.EVP_sha256(), key, len(k), d, len(m), md, i) diff --git a/src/randomtrackingdict.py b/src/randomtrackingdict.py index 5bf19181..0944da2a 100644 --- a/src/randomtrackingdict.py +++ b/src/randomtrackingdict.py @@ -38,10 +38,10 @@ class RandomTrackingDict(object): return self.len def __contains__(self, key): - return key in self.dictionary + return bytes(key) in self.dictionary def __getitem__(self, key): - return self.dictionary[key][1] + return self.dictionary[bytes(key)][1] def _swap(self, i1, i2): with self.lock: @@ -49,26 +49,28 @@ class RandomTrackingDict(object): key2 = self.indexDict[i2] self.indexDict[i1] = key2 self.indexDict[i2] = key1 - self.dictionary[key1][0] = i2 - self.dictionary[key2][0] = i1 + self.dictionary[bytes(key1)][0] = i2 + self.dictionary[bytes(key2)][0] = i1 # for quick reassignment return i2 def __setitem__(self, key, value): with self.lock: - if key in self.dictionary: - self.dictionary[key][1] = value + key_bytes = bytes(key) + if key_bytes in self.dictionary: + self.dictionary[key_bytes][1] = value else: self.indexDict.append(key) - self.dictionary[key] = [self.len, value] + self.dictionary[key_bytes] = [self.len, value] self._swap(self.len, self.len - self.pendingLen) self.len += 1 def __delitem__(self, key): - if key not in self.dictionary: + key_bytes = bytes(key) + if key_bytes not in self.dictionary: raise KeyError with self.lock: - index = self.dictionary[key][0] + index = self.dictionary[key_bytes][0] # not pending if index < self.len - self.pendingLen: # left of pending part @@ -82,7 +84,7 @@ class RandomTrackingDict(object): # operation can improve 4x, but it's already very fast so we'll # ignore it for the time being del self.indexDict[-1] - del self.dictionary[key] + del self.dictionary[key_bytes] self.len -= 1 def setMaxPending(self, maxPending): diff --git a/src/shared.py b/src/shared.py index b85ddb20..a1541eac 100644 --- a/src/shared.py +++ b/src/shared.py @@ -114,11 +114,11 @@ def reloadMyAddressHashes(): if len(privEncryptionKey) == 64: myECCryptorObjects[hashobj] = \ highlevelcrypto.makeCryptor(privEncryptionKey) - myAddressesByHash[hashobj] = addressInKeysFile + myAddressesByHash[bytes(hashobj)] = addressInKeysFile tag = highlevelcrypto.double_sha512( encodeVarint(addressVersionNumber) + encodeVarint(streamNumber) + hashobj)[32:] - myAddressesByTag[tag] = addressInKeysFile + myAddressesByTag[bytes(tag)] = addressInKeysFile if not keyfileSecure: fixSensitiveFilePermissions(os.path.join( @@ -149,7 +149,7 @@ def reloadBroadcastSendersForWhichImWatching(): encodeVarint(addressVersionNumber) + encodeVarint(streamNumber) + hashobj ).digest()[:32] - MyECSubscriptionCryptorObjects[hashobj] = \ + MyECSubscriptionCryptorObjects[bytes(hashobj)] = \ highlevelcrypto.makeCryptor(hexlify(privEncryptionKey)) else: doubleHashOfAddressData = highlevelcrypto.double_sha512( @@ -158,7 +158,7 @@ def reloadBroadcastSendersForWhichImWatching(): ) tag = doubleHashOfAddressData[32:] privEncryptionKey = doubleHashOfAddressData[:32] - MyECSubscriptionCryptorObjects[tag] = \ + MyECSubscriptionCryptorObjects[bytes(tag)] = \ highlevelcrypto.makeCryptor(hexlify(privEncryptionKey)) diff --git a/src/storage/sqlite.py b/src/storage/sqlite.py index eb5df098..5d967aec 100644 --- a/src/storage/sqlite.py +++ b/src/storage/sqlite.py @@ -29,20 +29,22 @@ class SqliteInventory(InventoryStorage): def __contains__(self, hash_): with self.lock: - if hash_ in self._objects: + hash_bytes = bytes(hash_) + if hash_bytes in self._objects: return True rows = sqlQuery( 'SELECT streamnumber FROM inventory WHERE hash=?', sqlite3.Binary(hash_)) if not rows: return False - self._objects[hash_] = rows[0][0] + self._objects[hash_bytes] = rows[0][0] return True def __getitem__(self, hash_): with self.lock: - if hash_ in self._inventory: - return self._inventory[hash_] + hash_bytes = bytes(hash_) + if hash_bytes in self._inventory: + return self._inventory[hash_bytes] rows = sqlQuery( 'SELECT objecttype, streamnumber, payload, expirestime, tag' ' FROM inventory WHERE hash=?', sqlite3.Binary(hash_)) @@ -53,15 +55,16 @@ class SqliteInventory(InventoryStorage): def __setitem__(self, hash_, value): with self.lock: value = InventoryItem(*value) - self._inventory[hash_] = value - self._objects[hash_] = value.stream + hash_bytes = bytes(hash_) + self._inventory[hash_bytes] = value + self._objects[hash_bytes] = value.stream def __delitem__(self, hash_): raise NotImplementedError def __iter__(self): with self.lock: - hashes = self._inventory.keys()[:] + hashes = [] + self._inventory.keys()[:] hashes += (x for x, in sqlQuery('SELECT hash FROM inventory')) return hashes.__iter__() diff --git a/src/tests/test_randomtrackingdict.py b/src/tests/test_randomtrackingdict.py index 2db3c423..cbe0ee55 100644 --- a/src/tests/test_randomtrackingdict.py +++ b/src/tests/test_randomtrackingdict.py @@ -15,10 +15,10 @@ class TestRandomTrackingDict(unittest.TestCase): @staticmethod def randString(): """helper function for tests, generates a random string""" - retval = '' - for _ in range(32): - retval += chr(random.randint(0, 255)) - return retval + retval = bytearray(32) + for i in range(32): + retval[i] = random.randint(0, 255) + return bytes(retval) def test_check_randomtrackingdict(self): """Check the logic of RandomTrackingDict class""" -- 2.45.1 From d04d620c68bd80512174fc1c399f78fb7549c41c Mon Sep 17 00:00:00 2001 From: Kashiko Koibumi Date: Mon, 27 May 2024 01:52:39 +0900 Subject: [PATCH 049/105] update translation files for using format() instead of arg() --- src/translations/bitmessage_ar.qm | Bin 39410 -> 38947 bytes src/translations/bitmessage_ar.ts | 146 ++++++------- src/translations/bitmessage_cs.qm | Bin 55998 -> 55524 bytes src/translations/bitmessage_cs.ts | 152 ++++++------- src/translations/bitmessage_da.qm | Bin 51755 -> 51240 bytes src/translations/bitmessage_da.ts | 146 ++++++------- src/translations/bitmessage_de.qm | Bin 97474 -> 97681 bytes src/translations/bitmessage_de.ts | 266 +++++++++++------------ src/translations/bitmessage_en.qm | Bin 81265 -> 80955 bytes src/translations/bitmessage_en.ts | 208 +++++++++--------- src/translations/bitmessage_en_pirate.qm | Bin 17497 -> 16990 bytes src/translations/bitmessage_en_pirate.ts | 104 ++++----- src/translations/bitmessage_eo.qm | Bin 87362 -> 87560 bytes src/translations/bitmessage_eo.ts | 256 +++++++++++----------- src/translations/bitmessage_fr.qm | Bin 92731 -> 92929 bytes src/translations/bitmessage_fr.ts | 256 +++++++++++----------- src/translations/bitmessage_it.qm | Bin 20451 -> 19879 bytes src/translations/bitmessage_it.ts | 110 +++++----- src/translations/bitmessage_ja.qm | Bin 66472 -> 66668 bytes src/translations/bitmessage_ja.ts | 254 +++++++++++----------- src/translations/bitmessage_nb.ts | 76 +++---- src/translations/bitmessage_nl.qm | Bin 12417 -> 11909 bytes src/translations/bitmessage_nl.ts | 112 +++++----- src/translations/bitmessage_no.qm | Bin 59534 -> 59029 bytes src/translations/bitmessage_no.ts | 158 +++++++------- src/translations/bitmessage_pl.qm | Bin 91161 -> 91359 bytes src/translations/bitmessage_pl.ts | 256 +++++++++++----------- src/translations/bitmessage_pt.qm | Bin 5172 -> 4715 bytes src/translations/bitmessage_pt.ts | 106 ++++----- src/translations/bitmessage_ru.qm | Bin 86534 -> 86735 bytes src/translations/bitmessage_ru.ts | 256 +++++++++++----------- src/translations/bitmessage_sk.qm | Bin 90043 -> 90252 bytes src/translations/bitmessage_sk.ts | 266 +++++++++++------------ src/translations/bitmessage_sv.ts | 104 ++++----- src/translations/bitmessage_zh_cn.ts | 248 ++++++++++----------- src/translations/noarg.sh | 7 + src/translations/update.sh | 2 + 37 files changed, 1749 insertions(+), 1740 deletions(-) create mode 100755 src/translations/noarg.sh create mode 100755 src/translations/update.sh diff --git a/src/translations/bitmessage_ar.qm b/src/translations/bitmessage_ar.qm index 892f61604c7d0314c27d1fad99d42ddc84a73641..6f2795451a825180ddc1bf77e6c00a0394580a1c 100644 GIT binary patch delta 2894 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 JzPR06@*jZVK*|6B diff --git a/src/translations/bitmessage_ar.ts b/src/translations/bitmessage_ar.ts index 6bf906d7..4b3ba9c1 100644 --- a/src/translations/bitmessage_ar.ts +++ b/src/translations/bitmessage_ar.ts @@ -241,8 +241,8 @@ Please type the desired email address (including @mailchuck.com) below: - One of your addresses, %1, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? - واحد من العناوين، %1، حاصل على رقم إصدار 1، العناوين ذات رقم الإصدار 1 غير مدعومه حالياً، هل باستطاعتنا حذفه الآن؟ + One of your addresses, {0}, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? + واحد من العناوين، {0}، حاصل على رقم إصدار 1، العناوين ذات رقم الإصدار 1 غير مدعومه حالياً، هل باستطاعتنا حذفه الآن؟ @@ -261,13 +261,13 @@ Please type the desired email address (including @mailchuck.com) below: - Message sent. Waiting for acknowledgement. Sent at %1 + Message sent. Waiting for acknowledgement. Sent at {0} - Message sent. Sent at %1 - تم إرسال الرسالة في %1 + Message sent. Sent at {0} + تم إرسال الرسالة في {0} @@ -276,8 +276,8 @@ Please type the desired email address (including @mailchuck.com) below: - Acknowledgement of the message received %1 - تم استلام إشعار الاستلام للرسالة %1 + Acknowledgement of the message received {0} + تم استلام إشعار الاستلام للرسالة {0} @@ -286,18 +286,18 @@ Please type the desired email address (including @mailchuck.com) below: - Broadcast on %1 - البث في %1 + Broadcast on {0} + البث في {0} - Problem: The work demanded by the recipient is more difficult than you are willing to do. %1 - مشكلة: العمل المطلوب من قبل المستلم أصعب من ما كنت مستعد للقيام به %1 + Problem: The work demanded by the recipient is more difficult than you are willing to do. {0} + مشكلة: العمل المطلوب من قبل المستلم أصعب من ما كنت مستعد للقيام به {0} - Problem: The recipient's encryption key is no good. Could not encrypt message. %1 - مشكلة: مفتاح تشفير المرسل إليه غير جيد، لا يمكن تشفير الرسالة. %1 + Problem: The recipient's encryption key is no good. Could not encrypt message. {0} + مشكلة: مفتاح تشفير المرسل إليه غير جيد، لا يمكن تشفير الرسالة. {0} @@ -306,8 +306,8 @@ Please type the desired email address (including @mailchuck.com) below: - Unknown status: %1 %2 - حالة غير معروفه: %1 %2 + Unknown status: {0} {1} + حالة غير معروفه: {0} {1} @@ -347,10 +347,10 @@ Please type the desired email address (including @mailchuck.com) below: You may manage your keys by editing the keys.dat file stored in - %1 + {0} It is important that you back up this file. يمكنك إدارة مفاتيحك بواسطة تعديل ملف keys.dat المحفوظ في -%1 +{0} مهم جداً أن تحتفظ بنسخة إضافية من هذا الملف. @@ -366,10 +366,10 @@ It is important that you back up this file. You may manage your keys by editing the keys.dat file stored in - %1 + {0} 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.) يمكنك إدارة مفاتيحك بواسطة تعديل ملف keys.dat المحفوظ في -%1 +{0} مهم جداً أن تحتفظ بنسخة إضافية من هذا الملف. هل ترغب بفتح الملف الآن؟ تأكد من إغلاق البرنامج Bitmessage قبل تعديل الملف. @@ -434,8 +434,8 @@ It is important that you back up this file. Would you like to open the file now? - Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: %1. This address also appears in 'Your Identities'. - تم تكوين زمرة بنجاح، لإتاحة الفرصة للأخرين بالإنضمام لمجموعتك أعطهم إسم الزمرة و هذا العنوان %1، هذا العنوان سيظهر ضمن هوياتك. + Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: {0}. This address also appears in 'Your Identities'. + تم تكوين زمرة بنجاح، لإتاحة الفرصة للأخرين بالإنضمام لمجموعتك أعطهم إسم الزمرة و هذا العنوان {0}، هذا العنوان سيظهر ضمن هوياتك. @@ -502,53 +502,53 @@ It is important that you back up this file. Would you like to open the file now? - The message that you are trying to send is too long by %1 bytes. (The maximum is 261644 bytes). Please cut it down before sending. + The message that you are trying to send is too long by {0} bytes. (The maximum is 261644 bytes). Please cut it down before sending. - Error: Your account wasn't registered at an email gateway. Sending registration now as %1, please wait for the registration to be processed before retrying sending. + Error: Your account wasn't registered at an email gateway. Sending registration now as {0}, please wait for the registration to be processed before retrying sending. - Error: Bitmessage addresses start with BM- Please check %1 - خطأ: عناوين ال Bitmessage تبدأ ب BM-، يرجى فحص %1 + Error: Bitmessage addresses start with BM- Please check {0} + خطأ: عناوين ال Bitmessage تبدأ ب BM-، يرجى فحص {0} - Error: The address %1 is not typed or copied correctly. Please check it. - خطأ: لم يتم إدخال أو نسخ العنوان %1 بطريقة صحيحة، يرجى فحصه. + Error: The address {0} is not typed or copied correctly. Please check it. + خطأ: لم يتم إدخال أو نسخ العنوان {0} بطريقة صحيحة، يرجى فحصه. - Error: The address %1 contains invalid characters. Please check it. - خطأ: العنوان %1 يحتوي على حروف غير صالحة، يرجى فحصه. + Error: The address {0} contains invalid characters. Please check it. + خطأ: العنوان {0} يحتوي على حروف غير صالحة، يرجى فحصه. - Error: The address version in %1 is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. - خطأ: رقم إصدار العنوان %1 عالي جداً، إما أن تقوم بتحديث برنامج Bitmessage أو أن شريكك ذكي جدأ. + Error: The address version in {0} is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. + خطأ: رقم إصدار العنوان {0} عالي جداً، إما أن تقوم بتحديث برنامج Bitmessage أو أن شريكك ذكي جدأ. - Error: Some data encoded in the address %1 is too short. There might be something wrong with the software of your acquaintance. - بعض البيانات المشفرة ضمن العنوان %1 قصيرة جداً. يمكن أن يكون هناك خطأ في برنامج شريكك. + Error: Some data encoded in the address {0} is too short. There might be something wrong with the software of your acquaintance. + بعض البيانات المشفرة ضمن العنوان {0} قصيرة جداً. يمكن أن يكون هناك خطأ في برنامج شريكك. - Error: Some data encoded in the address %1 is too long. There might be something wrong with the software of your acquaintance. - بعض البيانات المشفرة ضمن العنوان %1 طويلة جداً. يمكن أن يكون هناك خطأ في برنامج شريكك. + Error: Some data encoded in the address {0} is too long. There might be something wrong with the software of your acquaintance. + بعض البيانات المشفرة ضمن العنوان {0} طويلة جداً. يمكن أن يكون هناك خطأ في برنامج شريكك. - Error: Some data encoded in the address %1 is malformed. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is malformed. There might be something wrong with the software of your acquaintance. - Error: Something is wrong with the address %1. - خطأ: هناك خطأ في هذا العنوان %1. + Error: Something is wrong with the address {0}. + خطأ: هناك خطأ في هذا العنوان {0}. @@ -562,8 +562,8 @@ It is important that you back up this file. Would you like to open the file now? - Concerning the address %1, Bitmessage cannot understand address version numbers of %2. Perhaps upgrade Bitmessage to the latest version. - بالنظر إلى العنوان %1, Bitmessage لم يستطع فهم رقم إصدار العنوان %2، ربما يجب عليك تحديث برنامج Bitmessage لإصداره الأخير. + Concerning the address {0}, Bitmessage cannot understand address version numbers of {1}. Perhaps upgrade Bitmessage to the latest version. + بالنظر إلى العنوان {0}, Bitmessage لم يستطع فهم رقم إصدار العنوان {1}، ربما يجب عليك تحديث برنامج Bitmessage لإصداره الأخير. @@ -572,8 +572,8 @@ It is important that you back up this file. Would you like to open the file now? - Concerning the address %1, Bitmessage cannot handle stream numbers of %2. Perhaps upgrade Bitmessage to the latest version. - بالنظر إلى العنوان %1, Bitmessage لم يستطع فهم رقم إصدار العنوان %2، ربما يجب عليك تحديث برنامج Bitmessage لإصداره الأخير. + Concerning the address {0}, Bitmessage cannot handle stream numbers of {1}. Perhaps upgrade Bitmessage to the latest version. + بالنظر إلى العنوان {0}, Bitmessage لم يستطع فهم رقم إصدار العنوان {1}، ربما يجب عليك تحديث برنامج Bitmessage لإصداره الأخير. @@ -707,8 +707,8 @@ It is important that you back up this file. Would you like to open the file now? - Bitmessage cannot find your address %1. Perhaps you removed it? - لم يستطع Bitmessage العثور على عنوانك %1, ربما قمت بحذف العنوان؟ + Bitmessage cannot find your address {0}. Perhaps you removed it? + لم يستطع Bitmessage العثور على عنوانك {0}, ربما قمت بحذف العنوان؟ @@ -861,8 +861,8 @@ Are you sure you want to delete the channel? - You are using TCP port %1. (This can be changed in the settings). - أنت تستخدم نقطة عبور TCP %1 - يمكنك تغييره في قائمة الضبط. + You are using TCP port {0}. (This can be changed in the settings). + أنت تستخدم نقطة عبور TCP {0} - يمكنك تغييره في قائمة الضبط. @@ -1056,7 +1056,7 @@ Are you sure you want to delete the channel? - Zoom level %1% + Zoom level {0}% @@ -1071,47 +1071,47 @@ Are you sure you want to delete the channel? - Display the %1 recent broadcast(s) from this address. + Display the {0} recent broadcast(s) from this address. - New version of PyBitmessage is available: %1. Download it from https://github.com/Bitmessage/PyBitmessage/releases/latest + New version of PyBitmessage is available: {0}. Download it from https://github.com/Bitmessage/PyBitmessage/releases/latest - Waiting for PoW to finish... %1% + Waiting for PoW to finish... {0}% - Shutting down Pybitmessage... %1% + Shutting down Pybitmessage... {0}% - Waiting for objects to be sent... %1% + Waiting for objects to be sent... {0}% - Saving settings... %1% + Saving settings... {0}% - Shutting down core... %1% + Shutting down core... {0}% - Stopping notifications... %1% + Stopping notifications... {0}% - Shutdown imminent... %1% + Shutdown imminent... {0}% @@ -1140,7 +1140,7 @@ Are you sure you want to delete the channel? - Shutting down PyBitmessage... %1% + Shutting down PyBitmessage... {0}% @@ -1160,12 +1160,12 @@ Are you sure you want to delete the channel? - Generating %1 new addresses. + Generating {0} new addresses. - %1 is already in 'Your Identities'. Not adding it again. + {0} is already in 'Your Identities'. Not adding it again. @@ -1175,7 +1175,7 @@ Are you sure you want to delete the channel? - SOCKS5 Authentication problem: %1 + SOCKS5 Authentication problem: {0} @@ -1200,7 +1200,7 @@ Are you sure you want to delete the channel? - Broadcast sent on %1 + Broadcast sent on {0} @@ -1220,7 +1220,7 @@ Are you sure you want to delete the channel? - Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. %1 + Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. {0} @@ -1232,17 +1232,17 @@ There is no required difficulty for version 2 addresses like this. Doing work necessary to send message. -Receiver's required difficulty: %1 and %2 +Receiver's required difficulty: {0} and {1} - Problem: The work demanded by the recipient (%1 and %2) is more difficult than you are willing to do. %3 + Problem: The work demanded by the recipient ({0} and {1}) is more difficult than you are willing to do. {2} - Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. %1 + Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. {0} @@ -1252,7 +1252,7 @@ Receiver's required difficulty: %1 and %2 - Message sent. Waiting for acknowledgement. Sent on %1 + Message sent. Waiting for acknowledgement. Sent on {0} @@ -1267,12 +1267,12 @@ Receiver's required difficulty: %1 and %2 - Sending public key request. Waiting for reply. Requested at %1 + Sending public key request. Waiting for reply. Requested at {0} - UPnP port mapping established on port %1 + UPnP port mapping established on port {0} @@ -1635,27 +1635,27 @@ The 'Random Number' option is selected by default but deterministic ad - Since startup on %1 + Since startup on {0} - Down: %1/s Total: %2 + Down: {0}/s Total: {1} - Up: %1/s Total: %2 + Up: {0}/s Total: {1} - Total Connections: %1 + Total Connections: {0} - Inventory lookups per second: %1 + Inventory lookups per second: {0} diff --git a/src/translations/bitmessage_cs.qm b/src/translations/bitmessage_cs.qm index c25ccafac3de70f43735d13ce56b870a4f452c24..8fde0714829146363a484a3e9d35ed0f36890845 100644 GIT binary patch delta 3298 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 - One of your addresses, %1, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? - Jedna z Vašich adres, %1, je stará adresa verze 1. Adresy verze 1 již nejsou podporovány. Můžeme ji nyní smazat? + One of your addresses, {0}, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? + Jedna z Vašich adres, {0}, je stará adresa verze 1. Adresy verze 1 již nejsou podporovány. Můžeme ji nyní smazat? @@ -261,13 +261,13 @@ Please type the desired email address (including @mailchuck.com) below: - Message sent. Waiting for acknowledgement. Sent at %1 - Zpráva odeslána. Čekám na potvrzení. Odesláno v %1 + Message sent. Waiting for acknowledgement. Sent at {0} + Zpráva odeslána. Čekám na potvrzení. Odesláno v {0} - Message sent. Sent at %1 - Zpráva odeslána. Odesláno v %1 + Message sent. Sent at {0} + Zpráva odeslána. Odesláno v {0} @@ -276,8 +276,8 @@ Please type the desired email address (including @mailchuck.com) below: - Acknowledgement of the message received %1 - Potvrzení o přijetí zprávy %1 + Acknowledgement of the message received {0} + Potvrzení o přijetí zprávy {0} @@ -286,18 +286,18 @@ Please type the desired email address (including @mailchuck.com) below: - Broadcast on %1 - Rozesláno v %1 + Broadcast on {0} + Rozesláno v {0} - Problem: The work demanded by the recipient is more difficult than you are willing to do. %1 - Problém: Obtížnost práce požadovaná adresátem je vyšší než Vámi povolené maximum. %1 + Problem: The work demanded by the recipient is more difficult than you are willing to do. {0} + Problém: Obtížnost práce požadovaná adresátem je vyšší než Vámi povolené maximum. {0} - Problem: The recipient's encryption key is no good. Could not encrypt message. %1 - Problém: Šifrovací klíč adresáta je nepoužitelný. Zprávu nelze zašifrovat. %1 + Problem: The recipient's encryption key is no good. Could not encrypt message. {0} + Problém: Šifrovací klíč adresáta je nepoužitelný. Zprávu nelze zašifrovat. {0} @@ -306,8 +306,8 @@ Please type the desired email address (including @mailchuck.com) below: - Unknown status: %1 %2 - Neznámý stav: %1 %2 + Unknown status: {0} {1} + Neznámý stav: {0} {1} @@ -347,10 +347,10 @@ Please type the desired email address (including @mailchuck.com) below: You may manage your keys by editing the keys.dat file stored in - %1 + {0} It is important that you back up this file. Své klíče můžete spravovat editováním souboru keys.dat, který najdete zde: - %1 + {0} Je důležité si tento soubor zazálohovat. @@ -366,10 +366,10 @@ Je důležité si tento soubor zazálohovat. You may manage your keys by editing the keys.dat file stored in - %1 + {0} 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.) Své klíče můžete spravovat editováním souboru keys.dat, který najdete zde: - %1 + {0} Je důležité si tento soubor zazálohovat. Přejete si tento soubor nyní otevřít? (Nezapomeňte zavřít Bitmessage předtím, než provedete jakékoli změny.) @@ -434,8 +434,8 @@ Je důležité si tento soubor zazálohovat. Přejete si tento soubor nyní otev - Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: %1. This address also appears in 'Your Identities'. - Kanál byl úspěšně vytvořen. Když chcete jiným lidem povolit připojit se k Vašemu kanálu, řekněte jim jméno kanálu a tuto adresu Bitmessage: %1. Tuto adresu také najdete v sekci "Vaše identity". + Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: {0}. This address also appears in 'Your Identities'. + Kanál byl úspěšně vytvořen. Když chcete jiným lidem povolit připojit se k Vašemu kanálu, řekněte jim jméno kanálu a tuto adresu Bitmessage: {0}. Tuto adresu také najdete v sekci "Vaše identity". @@ -502,53 +502,53 @@ Je důležité si tento soubor zazálohovat. Přejete si tento soubor nyní otev - The message that you are trying to send is too long by %1 bytes. (The maximum is 261644 bytes). Please cut it down before sending. - Zpráva, kterou se snažíte poslat, je o %1 bajtů delší, než je dovoleno. (Maximum je 261644 bajtů). Zkuste ji prosím před odesláním zkrátit. + The message that you are trying to send is too long by {0} bytes. (The maximum is 261644 bytes). Please cut it down before sending. + Zpráva, kterou se snažíte poslat, je o {0} bajtů delší, než je dovoleno. (Maximum je 261644 bajtů). Zkuste ji prosím před odesláním zkrátit. - Error: Your account wasn't registered at an email gateway. Sending registration now as %1, please wait for the registration to be processed before retrying sending. + Error: Your account wasn't registered at an email gateway. Sending registration now as {0}, please wait for the registration to be processed before retrying sending. - Error: Bitmessage addresses start with BM- Please check %1 - Chyba: Adresy Bitmessage začínají na BM- Zkontroluje prosím %1 + Error: Bitmessage addresses start with BM- Please check {0} + Chyba: Adresy Bitmessage začínají na BM- Zkontroluje prosím {0} - Error: The address %1 is not typed or copied correctly. Please check it. - Chyba: Adresa %1 nebyla správně opsána nebo zkopírována. Zkontrolujte ji prosím. + Error: The address {0} is not typed or copied correctly. Please check it. + Chyba: Adresa {0} nebyla správně opsána nebo zkopírována. Zkontrolujte ji prosím. - Error: The address %1 contains invalid characters. Please check it. - Chyba: Adresa %1 obsahuje neplatné znaky. Zkontrolujte ji prosím. + Error: The address {0} contains invalid characters. Please check it. + Chyba: Adresa {0} obsahuje neplatné znaky. Zkontrolujte ji prosím. - Error: The address version in %1 is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. - Chyba: Verze adresy %1 je příliš vysoká. Buď používáte starou verzi Bitmessage a je čas na aktualizaci, nebo si Váš známý dělá legraci. + Error: The address version in {0} is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. + Chyba: Verze adresy {0} je příliš vysoká. Buď používáte starou verzi Bitmessage a je čas na aktualizaci, nebo si Váš známý dělá legraci. - Error: Some data encoded in the address %1 is too short. There might be something wrong with the software of your acquaintance. - Chyba: Některá data zakódovaná v adrese %1 jsou příliš krátká. Možná je to chyba softwaru, který Váš známý používá. + Error: Some data encoded in the address {0} is too short. There might be something wrong with the software of your acquaintance. + Chyba: Některá data zakódovaná v adrese {0} jsou příliš krátká. Možná je to chyba softwaru, který Váš známý používá. - Error: Some data encoded in the address %1 is too long. There might be something wrong with the software of your acquaintance. - Chyba: Některá data zakódovaná v adrese %1 jsou příliš dlouhá. Možná je to chyba softwaru, který Váš známý používá. + Error: Some data encoded in the address {0} is too long. There might be something wrong with the software of your acquaintance. + Chyba: Některá data zakódovaná v adrese {0} jsou příliš dlouhá. Možná je to chyba softwaru, který Váš známý používá. - Error: Some data encoded in the address %1 is malformed. There might be something wrong with the software of your acquaintance. - Chyba: Některá data zakódovaná v adrese %1 mají neplatný formát. Možná je to chyba softwaru, který Váš známý používá. + Error: Some data encoded in the address {0} is malformed. There might be something wrong with the software of your acquaintance. + Chyba: Některá data zakódovaná v adrese {0} mají neplatný formát. Možná je to chyba softwaru, který Váš známý používá. - Error: Something is wrong with the address %1. - Chyba: Nastal problém s adresou %1. + Error: Something is wrong with the address {0}. + Chyba: Nastal problém s adresou {0}. @@ -562,8 +562,8 @@ Je důležité si tento soubor zazálohovat. Přejete si tento soubor nyní otev - Concerning the address %1, Bitmessage cannot understand address version numbers of %2. Perhaps upgrade Bitmessage to the latest version. - Co se týče adresy %1, Bitmessage nerozumí jejímu číslu verze "%2". Možná byste měl(a) aktualizovat Bitmessage na nejnovější verzi. + Concerning the address {0}, Bitmessage cannot understand address version numbers of {1}. Perhaps upgrade Bitmessage to the latest version. + Co se týče adresy {0}, Bitmessage nerozumí jejímu číslu verze "{1}". Možná byste měl(a) aktualizovat Bitmessage na nejnovější verzi. @@ -572,8 +572,8 @@ Je důležité si tento soubor zazálohovat. Přejete si tento soubor nyní otev - Concerning the address %1, Bitmessage cannot handle stream numbers of %2. Perhaps upgrade Bitmessage to the latest version. - Co se týče adresy %1, Bitmessage neumí zpracovat její číslo proudu "%2". Možná byste měl(a) aktualizovat Bitmessage na nejnovější verzi. + Concerning the address {0}, Bitmessage cannot handle stream numbers of {1}. Perhaps upgrade Bitmessage to the latest version. + Co se týče adresy {0}, Bitmessage neumí zpracovat její číslo proudu "{1}". Možná byste měl(a) aktualizovat Bitmessage na nejnovější verzi. @@ -707,8 +707,8 @@ Je důležité si tento soubor zazálohovat. Přejete si tento soubor nyní otev - Bitmessage cannot find your address %1. Perhaps you removed it? - Bitmessage nemůže najít Vaši adresu %1. Možná jste ji odstranil(a)? + Bitmessage cannot find your address {0}. Perhaps you removed it? + Bitmessage nemůže najít Vaši adresu {0}. Možná jste ji odstranil(a)? @@ -861,8 +861,8 @@ Are you sure you want to delete the channel? - You are using TCP port %1. (This can be changed in the settings). - Používáte TCP port %1. (To lze změnit v nastavení). + You are using TCP port {0}. (This can be changed in the settings). + Používáte TCP port {0}. (To lze změnit v nastavení). @@ -1056,7 +1056,7 @@ Are you sure you want to delete the channel? - Zoom level %1% + Zoom level {0}% @@ -1071,47 +1071,47 @@ Are you sure you want to delete the channel? - Display the %1 recent broadcast(s) from this address. + Display the {0} recent broadcast(s) from this address. - New version of PyBitmessage is available: %1. Download it from https://github.com/Bitmessage/PyBitmessage/releases/latest + New version of PyBitmessage is available: {0}. Download it from https://github.com/Bitmessage/PyBitmessage/releases/latest - Waiting for PoW to finish... %1% + Waiting for PoW to finish... {0}% - Shutting down Pybitmessage... %1% + Shutting down Pybitmessage... {0}% - Waiting for objects to be sent... %1% + Waiting for objects to be sent... {0}% - Saving settings... %1% + Saving settings... {0}% - Shutting down core... %1% + Shutting down core... {0}% - Stopping notifications... %1% + Stopping notifications... {0}% - Shutdown imminent... %1% + Shutdown imminent... {0}% @@ -1134,7 +1134,7 @@ Are you sure you want to delete the channel? - Shutting down PyBitmessage... %1% + Shutting down PyBitmessage... {0}% @@ -1154,12 +1154,12 @@ Are you sure you want to delete the channel? - Generating %1 new addresses. + Generating {0} new addresses. - %1 is already in 'Your Identities'. Not adding it again. + {0} is already in 'Your Identities'. Not adding it again. @@ -1169,7 +1169,7 @@ Are you sure you want to delete the channel? - SOCKS5 Authentication problem: %1 + SOCKS5 Authentication problem: {0} @@ -1194,7 +1194,7 @@ Are you sure you want to delete the channel? - Broadcast sent on %1 + Broadcast sent on {0} @@ -1214,7 +1214,7 @@ Are you sure you want to delete the channel? - Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. %1 + Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. {0} @@ -1226,17 +1226,17 @@ There is no required difficulty for version 2 addresses like this. Doing work necessary to send message. -Receiver's required difficulty: %1 and %2 +Receiver's required difficulty: {0} and {1} - Problem: The work demanded by the recipient (%1 and %2) is more difficult than you are willing to do. %3 + Problem: The work demanded by the recipient ({0} and {1}) is more difficult than you are willing to do. {2} - Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. %1 + Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. {0} @@ -1246,7 +1246,7 @@ Receiver's required difficulty: %1 and %2 - Message sent. Waiting for acknowledgement. Sent on %1 + Message sent. Waiting for acknowledgement. Sent on {0} @@ -1261,12 +1261,12 @@ Receiver's required difficulty: %1 and %2 - Sending public key request. Waiting for reply. Requested at %1 + Sending public key request. Waiting for reply. Requested at {0} - UPnP port mapping established on port %1 + UPnP port mapping established on port {0} @@ -1629,27 +1629,27 @@ Možnost "Náhodné číslo" je nastavena jako výchozí, deterministi - Since startup on %1 + Since startup on {0} - Down: %1/s Total: %2 + Down: {0}/s Total: {1} - Up: %1/s Total: %2 + Up: {0}/s Total: {1} - Total Connections: %1 + Total Connections: {0} - Inventory lookups per second: %1 + Inventory lookups per second: {0} diff --git a/src/translations/bitmessage_da.qm b/src/translations/bitmessage_da.qm index e5588987d61b2cbd158dd2b8b9444f3daa08fb46..1b4366011f9a29afbab0e833797b0c7327ffe3f8 100644 GIT binary patch delta 3458 zcmaJ@2~<;O7XDsdUiL*4MWsqqK$d_=Q4z}`f-GuqMFnJ0qavCp!37b5Vp|0q(T6Qi z3RJQN#7G~6Q5XXiC z^#(}8k5a%LunT_(tiFdqS6%>aO1MgbfH+@x_Pt1;#PHo*0VJhi#I-yi_jg3Rcb1ZP zZnODzi288~&{Kd3TYn~i4=~|983A-e%)(W`PA5!Wc>+L@)tZ5|hY_2<5ZJ#C(^F}~ z{&vhbL;<@i5oZb@q#KbS$|oC-qyQx_s}4(^lS94&%llJCkynxVkvA|R}bDTs#5j@hz*oTt}jv z$g1DI0_3e^d({1t7`eu3%7X~lQFgd72iRd^M>P@fp6l2^orccuFtekRnt;^%Z0YZb zz=U$PBJph!;a&Ea;w(^mkF8H6l@E7gFT79hhlR2i#d@IIJ)14q&Nj6b1Cr(JPtz%p zal6>Il@w@!n^2uZn%UPb4E!_<*t@#bUnUMUmrDEtd{-R%q$pexpLDL9OlVoOnF)=bovLf8< zP5u3=Buh_$RPRgjcf^qfvL%~6NGv9$gg-@rjm?r1$Af63o|0VHeU`c+SMs&FKeb_r zRH@vP#nWtb)3z)MnR)OP;J<3gldt_E@|D(6>k(cTsyDm@4%x$t0ku z(h=r_Il!AwrQ`7um@`Rg(oq19QYqg}NR!P?T6T39i3ZYbZ_#>wi}b+u7^<~J`s38! ziORprHJ6isb0Q?|3lS`tEsgO0kL#6R~ zOU_KFrGZo*Bo-A+5 zY@?BTSbigND+SWY?{^;z6xPe{Ye@A~_40?c6mU?bLS9LJgZvdfR!xjgRfK3M-Z_53Dy{AV>VHX#D)LD_QL9i*1eJhyRV9>BrgJk?n;y`{c)6UH+cktdYKiLNkUk_n*sSQW&92#JvjtA7CLLW$*)=v>c3bsek~7@_ zr`1DTh-u+EwXb2B8Q9&Z9`+>#+&M`-?l5II(peo-6$C6gqE0SbM}0g+o#Eg`>UB{U zT%pS*BwM|=;RW#FWp!Y6t7@r*Va#ii=gJ;}~csvFik2Q)F9U(gvq5NmTL;2gPzIIvgK{hlJYjz^~dh!yr z8=K{m%`a8kTgIyA$eHy#bJBs2a_Y`s>FdmO9N?ez4Q4|407qx*R!g#DJ2SKwMq?gK z(8GYa$N>FEvHE`Pxm#$uF=g(Y6jO%AXwY;7A=1uybpzYi$V=W zHlG~e#E)}u<1ab+J7$kD8s_NJ4XK9tnv4Z{P0HN4>3Wl?!`lFj7n?OSo1dtO*fLwh zi=CYR;_$Y{|GzlQ|Gy6H`SSx@JDpmF4}2_U7V=sTz51`21@aXh0iB#Nllcc8<6iOV z{W|+0e3YkW$DRQLds>pc%nXymr+7KN;6lzyEME#HbeY_$px4k2~G2XmeuzMH0efY%SUN$U!dhvz98C}+g^U9DnJM*!` zhKv?7kNA=Z&sSK_MKm~O#TfJ&<2+5Kaanq274#;pwGft?NG-$v5^c}7Ms4Zhc`{!Z z9nR delta 3802 zcmaJ@3tY{28~^^#IsbFNR5F)F$E8rIL?M(U-E^>0D^W)sm2ys6uh02B{cg|Y`+T40_uo;@-(ATs zcQRL=1q2nq5PyJe1ZI2%gn0n+4M5E2fPXBlxzX=2kUkM;;UGBY0=Pv&aB(K!UJt=t zZ@|OVCd(CIR|$X#r@&S{1KyefwwCTqDg?V{D{vqR?7>o!Z4mC{!;F>|h+;#4W3G^d z93q27un+kKD5}GN^S=Xw?!r|Z0K`9sd+$~t`dj!^kaJ017}>TISbPAX>rPS-FKn{( zG{SF31CGBUYVFVDU@M~5Nl8A#l(`Fm`gXika1=nfRhoe%dc>B^1sca9E`tsz#EnI8hZd5m*!0Wfk9)6a_#*m8>*EFSW$`!6T1H&^*vvmHKS>7b_-Edy z1>b)BR*?>{yJeFrxyrPK~d66hK|scP;DGG!ECnV%s41tFVzMNqJ{l~Ql660GneNXNAZ zcCTRorzXLkA>=^fuYx@u^)$aOXj~dcr12A2Y8`=@-wFP4cL*6;D>%8pg&;gAXmdD0 z>qRW{JsIj=$d3HE3K+GQ9esw_|K2dxKb=o06tWW@YJeX0Y~qyM6^Jo-~zhC}qizJ9}U{DfWnF z52umg$krhV0&9i4 z)W@hCuL&)yy8(+X2|u!?uJnQM+g((4jXw%6$C6_W6NUGMq&L=8A%sfB&o7fy*GrtXQ@QS! zOI*!gkVn3C5}&FCs zm(@!4*G(Y~yeGLG^PC_(EtTaEXK+H=pSeM~ekpZbN(ij_LK<7Thd9& z-N}?1q0~J0Dk&^Vm3GMLKxxq^ig5NiX+yv>%3-ebknABD%#j|d{e@WEB>iNug`{43 zZaJmK+evyYkvL%-BV(c(sKYIkNfrLc~C!7Z~0 znL9FX;UXZ1Z2dDA#0)w_qh$(sAO7s?MBC}rjx`4PrM9PqNqCTDqzBRR&clb@SQa_N`yuT|ur z|8Me(kNS}QVEOlj=jmQ^zWhnd2I|$<72;dX1Z9CjIf)MTOIJ8$Q4Vv96a!N}p_Y3} z;aW`wMwBXsa=U=>n+^|cz&SLvZyPp$Ww zGVE~~u>PcSDkvrIT~V(2iS`pND60=ps+h^jO*2MOKe(=}QmQ$PX#9 zQ7=?ewgv!MCRK9HJ5<*Js$FM)2R- zo8yS2p;fA9@6x@dR3gx^I6iqe5Zw040Ly2Rn*!!7ZjUlb<$_^Qi>=-Z>F35tRf8E9 z?ms@=E#ayZ8MBHq~4D%wf2CwL5FI?!o0`_u^u`9k@BpZe+rTEAe;c zG(84$KRAzK3c0=gdXOp3OFfk5;=?7WLz$%)gULoM6f%}kS5m>uK6 zg$E9K&AXmlN#Glu-W70-fqAd(`f|g^5ARG^@%SJS^MLy})V;&MpF++NJniSfx=aKvsvxIw|Jkq-7r{xKm!QALH=fT!=TiM~$g>Cog`b@nc zU#~XhYIE~U{)C>IvYgZ3(NdFki_a8rC7FXdbPlVD>m3wt$Wv>LI(42YL!YLO37)FX zHW+iQkk{3CSR%6;8RiPtm{TH>S~&_xq465h9#(w_!> zXrbfsYdiK`Gy3FwWl+1M;quDL>;KZn%AbcB)Xo2LME>QfZ871MJ$lDFhoM8}{xR*6 z)Rg{qP-FXlgZj|l4TWBpADph$Pt4F}8Pe=Dy8IwpDcKev)6O>J<=Q6FbX`_<=ep9Q z%grSom^$W68mHdu#3d=69biWaUem#Otm(^Tuj~=+kdb20hh`Z}CarNnryj}dENx0= uR)#6pA!MF5BP&#!tIOB^u`7+zX6WNG^r?n?DCn|Ym(uCW3JQqFF#iQ;MEF?% diff --git a/src/translations/bitmessage_da.ts b/src/translations/bitmessage_da.ts index fcf80470..707967e7 100644 --- a/src/translations/bitmessage_da.ts +++ b/src/translations/bitmessage_da.ts @@ -241,8 +241,8 @@ Please type the desired email address (including @mailchuck.com) below: - One of your addresses, %1, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? - En af dine adresser, %1 er en gammel version 1-addresse. Version 1-addresser understøttes ikke længere. Må vi slette den? + One of your addresses, {0}, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? + En af dine adresser, {0} er en gammel version 1-addresse. Version 1-addresser understøttes ikke længere. Må vi slette den? @@ -261,13 +261,13 @@ Please type the desired email address (including @mailchuck.com) below: - Message sent. Waiting for acknowledgement. Sent at %1 - Besked afsendt. Afventer bekræftelse på modtagelse. Sendt %1 + Message sent. Waiting for acknowledgement. Sent at {0} + Besked afsendt. Afventer bekræftelse på modtagelse. Sendt {0} - Message sent. Sent at %1 - Besked sendt. Sendt %1 + Message sent. Sent at {0} + Besked sendt. Sendt {0} @@ -276,8 +276,8 @@ Please type the desired email address (including @mailchuck.com) below: - Acknowledgement of the message received %1 - Bekræftelse på modtagelse er modtaget %1 + Acknowledgement of the message received {0} + Bekræftelse på modtagelse er modtaget {0} @@ -286,18 +286,18 @@ Please type the desired email address (including @mailchuck.com) below: - Broadcast on %1 - Afsendt %1 + Broadcast on {0} + Afsendt {0} - Problem: The work demanded by the recipient is more difficult than you are willing to do. %1 - Problem: Beregningen som kræves af modtageren er mere besværlig end du accepterer. %1 + Problem: The work demanded by the recipient is more difficult than you are willing to do. {0} + Problem: Beregningen som kræves af modtageren er mere besværlig end du accepterer. {0} - Problem: The recipient's encryption key is no good. Could not encrypt message. %1 - Problem: Modtagerens krypteringsnøgle virker ikke. Beskeden kunne ikke krypteres. %1 + Problem: The recipient's encryption key is no good. Could not encrypt message. {0} + Problem: Modtagerens krypteringsnøgle virker ikke. Beskeden kunne ikke krypteres. {0} @@ -306,8 +306,8 @@ Please type the desired email address (including @mailchuck.com) below: - Unknown status: %1 %2 - Ukendt status: %1 %2 + Unknown status: {0} {1} + Ukendt status: {0} {1} @@ -347,10 +347,10 @@ Please type the desired email address (including @mailchuck.com) below: You may manage your keys by editing the keys.dat file stored in - %1 + {0} It is important that you back up this file. Du kan administrere dine nøgler ved at redigere keys.dat-filen i -%1 +{0} Det er vigtigt at tage backup af denne fil. @@ -366,10 +366,10 @@ Det er vigtigt at tage backup af denne fil. You may manage your keys by editing the keys.dat file stored in - %1 + {0} 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.) Du kan administrere dine nøgler ved at redigere keys.dat-filen i -%1 +{0} Det er vigtigt at tage backup af denne fil. (Sørg for at lukke Bitmessage før du foretager ændringer.) @@ -434,8 +434,8 @@ Det er vigtigt at tage backup af denne fil. (Sørg for at lukke Bitmessage før - Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: %1. This address also appears in 'Your Identities'. - Ny kanal oprettet. For at andre kan blive medlem skal du oplyse dem kanalnavnet og denne Bitmessage-adresse: %1. Denne adresse vises også i 'Dine identiteter'. + Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: {0}. This address also appears in 'Your Identities'. + Ny kanal oprettet. For at andre kan blive medlem skal du oplyse dem kanalnavnet og denne Bitmessage-adresse: {0}. Denne adresse vises også i 'Dine identiteter'. @@ -502,53 +502,53 @@ Det er vigtigt at tage backup af denne fil. (Sørg for at lukke Bitmessage før - The message that you are trying to send is too long by %1 bytes. (The maximum is 261644 bytes). Please cut it down before sending. - Beskeden som du prøver at sende er %1 byte for lang. (Den maksimale størrelse er 261644 byte). Prøv at gøre den kortere før afsendelsen. + The message that you are trying to send is too long by {0} bytes. (The maximum is 261644 bytes). Please cut it down before sending. + Beskeden som du prøver at sende er {0} byte for lang. (Den maksimale størrelse er 261644 byte). Prøv at gøre den kortere før afsendelsen. - Error: Your account wasn't registered at an email gateway. Sending registration now as %1, please wait for the registration to be processed before retrying sending. + Error: Your account wasn't registered at an email gateway. Sending registration now as {0}, please wait for the registration to be processed before retrying sending. - Error: Bitmessage addresses start with BM- Please check %1 - Fejl: Bitmessage-adresser starter med BM- Check %1 + Error: Bitmessage addresses start with BM- Please check {0} + Fejl: Bitmessage-adresser starter med BM- Check {0} - Error: The address %1 is not typed or copied correctly. Please check it. - Fejl: Adressen %1 er skrever eller kopieret forkert. Tjek den venligst. + Error: The address {0} is not typed or copied correctly. Please check it. + Fejl: Adressen {0} er skrever eller kopieret forkert. Tjek den venligst. - Error: The address %1 contains invalid characters. Please check it. - Fejl: Adressen %1 indeholder ugyldige tegn. Tjek den venligst. + Error: The address {0} contains invalid characters. Please check it. + Fejl: Adressen {0} indeholder ugyldige tegn. Tjek den venligst. - Error: The address version in %1 is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. + Error: The address version in {0} is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. - Error: Some data encoded in the address %1 is too short. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is too short. There might be something wrong with the software of your acquaintance. - Error: Some data encoded in the address %1 is too long. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is too long. There might be something wrong with the software of your acquaintance. - Error: Some data encoded in the address %1 is malformed. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is malformed. There might be something wrong with the software of your acquaintance. - Error: Something is wrong with the address %1. - Fejl: Der er noget galt med adressen %1. + Error: Something is wrong with the address {0}. + Fejl: Der er noget galt med adressen {0}. @@ -562,8 +562,8 @@ Det er vigtigt at tage backup af denne fil. (Sørg for at lukke Bitmessage før - Concerning the address %1, Bitmessage cannot understand address version numbers of %2. Perhaps upgrade Bitmessage to the latest version. - Vedrørende adressen %1, Bitmessage forstår ikke addreseversion %2. Måske bør du opgradere Bitmessage til den nyeste version. + Concerning the address {0}, Bitmessage cannot understand address version numbers of {1}. Perhaps upgrade Bitmessage to the latest version. + Vedrørende adressen {0}, Bitmessage forstår ikke addreseversion {1}. Måske bør du opgradere Bitmessage til den nyeste version. @@ -572,8 +572,8 @@ Det er vigtigt at tage backup af denne fil. (Sørg for at lukke Bitmessage før - Concerning the address %1, Bitmessage cannot handle stream numbers of %2. Perhaps upgrade Bitmessage to the latest version. - Vedrørende adressen %1, Bitmessage kan ikke håndtere flod nummer %2. Måske bør du opgradere Bitmessage til den nyeste version. + Concerning the address {0}, Bitmessage cannot handle stream numbers of {1}. Perhaps upgrade Bitmessage to the latest version. + Vedrørende adressen {0}, Bitmessage kan ikke håndtere flod nummer {1}. Måske bør du opgradere Bitmessage til den nyeste version. @@ -707,8 +707,8 @@ Det er vigtigt at tage backup af denne fil. (Sørg for at lukke Bitmessage før - Bitmessage cannot find your address %1. Perhaps you removed it? - Bitmessage kan ikke finde din adresse %1. Måske har du fjernet den? + Bitmessage cannot find your address {0}. Perhaps you removed it? + Bitmessage kan ikke finde din adresse {0}. Måske har du fjernet den? @@ -865,8 +865,8 @@ Er du sikker på at du vil slette denne kanal? - You are using TCP port %1. (This can be changed in the settings). - Du bruger TCP-port %1. (Dette kan ændres i indstillingerne). + You are using TCP port {0}. (This can be changed in the settings). + Du bruger TCP-port {0}. (Dette kan ændres i indstillingerne). @@ -1060,8 +1060,8 @@ Er du sikker på at du vil slette denne kanal? - Zoom level %1% - Zoom %1% + Zoom level {0}% + Zoom {0}% @@ -1075,47 +1075,47 @@ Er du sikker på at du vil slette denne kanal? - Display the %1 recent broadcast(s) from this address. + Display the {0} recent broadcast(s) from this address. - New version of PyBitmessage is available: %1. Download it from https://github.com/Bitmessage/PyBitmessage/releases/latest + New version of PyBitmessage is available: {0}. Download it from https://github.com/Bitmessage/PyBitmessage/releases/latest - Waiting for PoW to finish... %1% + Waiting for PoW to finish... {0}% - Shutting down Pybitmessage... %1% + Shutting down Pybitmessage... {0}% - Waiting for objects to be sent... %1% + Waiting for objects to be sent... {0}% - Saving settings... %1% + Saving settings... {0}% - Shutting down core... %1% + Shutting down core... {0}% - Stopping notifications... %1% + Stopping notifications... {0}% - Shutdown imminent... %1% + Shutdown imminent... {0}% @@ -1136,7 +1136,7 @@ Er du sikker på at du vil slette denne kanal? - Shutting down PyBitmessage... %1% + Shutting down PyBitmessage... {0}% @@ -1156,12 +1156,12 @@ Er du sikker på at du vil slette denne kanal? - Generating %1 new addresses. + Generating {0} new addresses. - %1 is already in 'Your Identities'. Not adding it again. + {0} is already in 'Your Identities'. Not adding it again. @@ -1171,7 +1171,7 @@ Er du sikker på at du vil slette denne kanal? - SOCKS5 Authentication problem: %1 + SOCKS5 Authentication problem: {0} @@ -1196,7 +1196,7 @@ Er du sikker på at du vil slette denne kanal? - Broadcast sent on %1 + Broadcast sent on {0} @@ -1216,7 +1216,7 @@ Er du sikker på at du vil slette denne kanal? - Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. %1 + Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. {0} @@ -1228,17 +1228,17 @@ There is no required difficulty for version 2 addresses like this. Doing work necessary to send message. -Receiver's required difficulty: %1 and %2 +Receiver's required difficulty: {0} and {1} - Problem: The work demanded by the recipient (%1 and %2) is more difficult than you are willing to do. %3 + Problem: The work demanded by the recipient ({0} and {1}) is more difficult than you are willing to do. {2} - Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. %1 + Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. {0} @@ -1248,7 +1248,7 @@ Receiver's required difficulty: %1 and %2 - Message sent. Waiting for acknowledgement. Sent on %1 + Message sent. Waiting for acknowledgement. Sent on {0} @@ -1263,12 +1263,12 @@ Receiver's required difficulty: %1 and %2 - Sending public key request. Waiting for reply. Requested at %1 + Sending public key request. Waiting for reply. Requested at {0} - UPnP port mapping established on port %1 + UPnP port mapping established on port {0} @@ -1631,27 +1631,27 @@ Som standard er tilfældige tal valgt, men der er både fordele og ulemper ved a - Since startup on %1 + Since startup on {0} - Down: %1/s Total: %2 + Down: {0}/s Total: {1} - Up: %1/s Total: %2 + Up: {0}/s Total: {1} - Total Connections: %1 + Total Connections: {0} - Inventory lookups per second: %1 + Inventory lookups per second: {0} diff --git a/src/translations/bitmessage_de.qm b/src/translations/bitmessage_de.qm index ef443a619e0e40e55aede8479d45b488e57652f4..e42c1760a3ef57b38624c14f3ff0d4606f57589b 100644 GIT binary patch delta 6500 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 - One of your addresses, %1, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? - Eine Ihrer Adressen, %1, ist eine alte Adresse der Version 1 und wird nicht mehr unterstützt. Soll sie jetzt gelöscht werden? + One of your addresses, {0}, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? + Eine Ihrer Adressen, {0}, ist eine alte Adresse der Version 1 und wird nicht mehr unterstützt. Soll sie jetzt gelöscht werden? @@ -334,13 +334,13 @@ Please type the desired email address (including @mailchuck.com) below: - Message sent. Waiting for acknowledgement. Sent at %1 - Nachricht gesendet. Warte auf Bestätigung. Zeitpunkt der Sendung: %1 + Message sent. Waiting for acknowledgement. Sent at {0} + Nachricht gesendet. Warte auf Bestätigung. Zeitpunkt der Sendung: {0} - Message sent. Sent at %1 - Nachricht gesendet. Zeitpunkt der Sendung: %1 + Message sent. Sent at {0} + Nachricht gesendet. Zeitpunkt der Sendung: {0} @@ -349,8 +349,8 @@ Please type the desired email address (including @mailchuck.com) below: - Acknowledgement of the message received %1 - Bestätigung der Nachricht erhalten %1 + Acknowledgement of the message received {0} + Bestätigung der Nachricht erhalten {0} @@ -359,18 +359,18 @@ Please type the desired email address (including @mailchuck.com) below: - Broadcast on %1 - Rundruf um %1 + Broadcast on {0} + Rundruf um {0} - Problem: The work demanded by the recipient is more difficult than you are willing to do. %1 - Problem: Die vom Empfänger geforderte Arbeit ist schwerer als Sie bereit sind, zu berechnen. %1 + Problem: The work demanded by the recipient is more difficult than you are willing to do. {0} + Problem: Die vom Empfänger geforderte Arbeit ist schwerer als Sie bereit sind, zu berechnen. {0} - Problem: The recipient's encryption key is no good. Could not encrypt message. %1 - Problem: Der Verschlüsselungscode des Empfängers ist nicht in Ordnung. Nachricht konnte nicht verschlüsselt werden. %1 + Problem: The recipient's encryption key is no good. Could not encrypt message. {0} + Problem: Der Verschlüsselungscode des Empfängers ist nicht in Ordnung. Nachricht konnte nicht verschlüsselt werden. {0} @@ -379,8 +379,8 @@ Please type the desired email address (including @mailchuck.com) below: - Unknown status: %1 %2 - Unbekannter Status: %1 %2 + Unknown status: {0} {1} + Unbekannter Status: {0} {1} @@ -420,10 +420,10 @@ Please type the desired email address (including @mailchuck.com) below: You may manage your keys by editing the keys.dat file stored in - %1 + {0} It is important that you back up this file. Sie können Ihre Schlüssel verwalten, indem Sie die keys.dat bearbeiten, die im Ordner -%1 liegt. +{0} liegt. Es ist empfehlenswert, vorher ein Backup dieser Datei anzulegen. @@ -439,10 +439,10 @@ Es ist empfehlenswert, vorher ein Backup dieser Datei anzulegen. You may manage your keys by editing the keys.dat file stored in - %1 + {0} 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.) Sie können Ihre Schlüssel verwalten, indem Sie die keys.dat bearbeiten, -die im Ordner %1 liegt. +die im Ordner {0} liegt. Es ist empfehlenswert, vorher ein Backup dieser Datei anzulegen. Möchten Sie die Datei jetzt öffnen? (Stellen Sie sicher, dass Sie Bitmessage beendet haben, bevor Sie etwas ändern.) @@ -508,7 +508,7 @@ Es ist empfehlenswert, vorher ein Backup dieser Datei anzulegen. Möchten Sie di - Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: %1. This address also appears in 'Your Identities'. + Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: {0}. This address also appears in 'Your Identities'. @@ -576,52 +576,52 @@ Es ist empfehlenswert, vorher ein Backup dieser Datei anzulegen. Möchten Sie di - The message that you are trying to send is too long by %1 bytes. (The maximum is 261644 bytes). Please cut it down before sending. - Die Nachricht, die Sie zu senden versuchen, ist %1 Byte zu lang. (Maximum 261.644 Bytes). Bitte verringern Sie ihre Größe vor dem Senden. + The message that you are trying to send is too long by {0} bytes. (The maximum is 261644 bytes). Please cut it down before sending. + Die Nachricht, die Sie zu senden versuchen, ist {0} Byte zu lang. (Maximum 261.644 Bytes). Bitte verringern Sie ihre Größe vor dem Senden. - Error: Your account wasn't registered at an email gateway. Sending registration now as %1, please wait for the registration to be processed before retrying sending. - Fehler: Ihr Konto war an keiner E-Mail Schnittstelle registriert. Registrierung als %1 wird versandt, bitte vor einem erneutem Sendeversuch auf die Registrierungsverarbeitung warten. + Error: Your account wasn't registered at an email gateway. Sending registration now as {0}, please wait for the registration to be processed before retrying sending. + Fehler: Ihr Konto war an keiner E-Mail Schnittstelle registriert. Registrierung als {0} wird versandt, bitte vor einem erneutem Sendeversuch auf die Registrierungsverarbeitung warten. - Error: Bitmessage addresses start with BM- Please check %1 + Error: Bitmessage addresses start with BM- Please check {0} - Error: The address %1 is not typed or copied correctly. Please check it. + Error: The address {0} is not typed or copied correctly. Please check it. - Error: The address %1 contains invalid characters. Please check it. + Error: The address {0} contains invalid characters. Please check it. - Error: The address version in %1 is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. + Error: The address version in {0} is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. - Error: Some data encoded in the address %1 is too short. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is too short. There might be something wrong with the software of your acquaintance. - Error: Some data encoded in the address %1 is too long. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is too long. There might be something wrong with the software of your acquaintance. - Error: Some data encoded in the address %1 is malformed. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is malformed. There might be something wrong with the software of your acquaintance. - Error: Something is wrong with the address %1. + Error: Something is wrong with the address {0}. @@ -636,8 +636,8 @@ Es ist empfehlenswert, vorher ein Backup dieser Datei anzulegen. Möchten Sie di - Concerning the address %1, Bitmessage cannot understand address version numbers of %2. Perhaps upgrade Bitmessage to the latest version. - Aufgrund der Adresse %1 kann Bitmessage Adressen mit der Version %2 nicht verarbeiten. Möglicherweise müssen Sie Bitmessage auf die aktuelle Version aktualisieren. + Concerning the address {0}, Bitmessage cannot understand address version numbers of {1}. Perhaps upgrade Bitmessage to the latest version. + Aufgrund der Adresse {0} kann Bitmessage Adressen mit der Version {1} nicht verarbeiten. Möglicherweise müssen Sie Bitmessage auf die aktuelle Version aktualisieren. @@ -646,8 +646,8 @@ Es ist empfehlenswert, vorher ein Backup dieser Datei anzulegen. Möchten Sie di - Concerning the address %1, Bitmessage cannot handle stream numbers of %2. Perhaps upgrade Bitmessage to the latest version. - Aufgrund der Adresse %1 kann Bitmessage den Datenstrom mit der Version %2 nicht verarbeiten. Möglicherweise müssen Sie Bitmessage auf die aktuelle Version aktualisieren. + Concerning the address {0}, Bitmessage cannot handle stream numbers of {1}. Perhaps upgrade Bitmessage to the latest version. + Aufgrund der Adresse {0} kann Bitmessage den Datenstrom mit der Version {1} nicht verarbeiten. Möglicherweise müssen Sie Bitmessage auf die aktuelle Version aktualisieren. @@ -781,8 +781,8 @@ Es ist empfehlenswert, vorher ein Backup dieser Datei anzulegen. Möchten Sie di - Bitmessage cannot find your address %1. Perhaps you removed it? - Bitmessage kann Ihre Adresse %1 nicht finden. Haben Sie sie gelöscht? + Bitmessage cannot find your address {0}. Perhaps you removed it? + Bitmessage kann Ihre Adresse {0} nicht finden. Haben Sie sie gelöscht? @@ -939,7 +939,7 @@ Sind Sie sicher, dass Sie das Chan löschen möchten? - You are using TCP port %1. (This can be changed in the settings). + You are using TCP port {0}. (This can be changed in the settings). @@ -1134,8 +1134,8 @@ Sind Sie sicher, dass Sie das Chan löschen möchten? - Zoom level %1% - Zoom-Stufe %1% + Zoom level {0}% + Zoom-Stufe {0}% @@ -1149,48 +1149,48 @@ Sind Sie sicher, dass Sie das Chan löschen möchten? - Display the %1 recent broadcast(s) from this address. + Display the {0} recent broadcast(s) from this address. - New version of PyBitmessage is available: %1. Download it from https://github.com/Bitmessage/PyBitmessage/releases/latest - Neue Version von PyBitmessage steht zur Verfügung: %1. Sie können sie von https://github.com/Bitmessage/PyBitmessage/releases/latest herunterladen. + New version of PyBitmessage is available: {0}. Download it from https://github.com/Bitmessage/PyBitmessage/releases/latest + Neue Version von PyBitmessage steht zur Verfügung: {0}. Sie können sie von https://github.com/Bitmessage/PyBitmessage/releases/latest herunterladen. - Waiting for PoW to finish... %1% - Warte auf Abschluss von Berechnungen (PoW)... %1% + Waiting for PoW to finish... {0}% + Warte auf Abschluss von Berechnungen (PoW)... {0}% - Shutting down Pybitmessage... %1% - PyBitmessage wird beendet... %1% + Shutting down Pybitmessage... {0}% + PyBitmessage wird beendet... {0}% - Waiting for objects to be sent... %1% - Warte auf Versand von Objekten... %1% + Waiting for objects to be sent... {0}% + Warte auf Versand von Objekten... {0}% - Saving settings... %1% - Einstellungen werden gespeichert... %1% + Saving settings... {0}% + Einstellungen werden gespeichert... {0}% - Shutting down core... %1% - Kern wird beendet... %1% + Shutting down core... {0}% + Kern wird beendet... {0}% - Stopping notifications... %1% - Beende Benachrichtigungen... %1% + Stopping notifications... {0}% + Beende Benachrichtigungen... {0}% - Shutdown imminent... %1% - Unmittelbar vor Beendung... %1% + Shutdown imminent... {0}% + Unmittelbar vor Beendung... {0}% @@ -1204,8 +1204,8 @@ Sind Sie sicher, dass Sie das Chan löschen möchten? - Shutting down PyBitmessage... %1% - PyBitmessage wird beendet... %1% + Shutting down PyBitmessage... {0}% + PyBitmessage wird beendet... {0}% @@ -1224,13 +1224,13 @@ Sind Sie sicher, dass Sie das Chan löschen möchten? - Generating %1 new addresses. - Erzeuge %1 neue Addressen. + Generating {0} new addresses. + Erzeuge {0} neue Addressen. - %1 is already in 'Your Identities'. Not adding it again. - %1 befindet sich bereits unter Ihren Identitäten, wird nicht doppelt hinzugefügt. + {0} is already in 'Your Identities'. Not adding it again. + {0} befindet sich bereits unter Ihren Identitäten, wird nicht doppelt hinzugefügt. @@ -1239,7 +1239,7 @@ Sind Sie sicher, dass Sie das Chan löschen möchten? - SOCKS5 Authentication problem: %1 + SOCKS5 Authentication problem: {0} @@ -1264,8 +1264,8 @@ Sind Sie sicher, dass Sie das Chan löschen möchten? - Broadcast sent on %1 - Rundruf verschickt um %1 + Broadcast sent on {0} + Rundruf verschickt um {0} @@ -1284,7 +1284,7 @@ Sind Sie sicher, dass Sie das Chan löschen möchten? - Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. %1 + Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. {0} Problem: Der Empfänger benutzt ein mobiles Gerät und erfordert eine unverschlüsselte Empfängeraddresse. Dies ist in Ihren Einstellungen jedoch nicht zulässig. 1% @@ -1297,17 +1297,17 @@ Version-2-Addressen wie die des Empfängers haben keine Schweirigkeitserforderun Doing work necessary to send message. -Receiver's required difficulty: %1 and %2 - Arbeit für Nachrichtenversand wird errichtet. Vom Empfänger geforderte Schwierigkeit: %1 und %2 +Receiver's required difficulty: {0} and {1} + Arbeit für Nachrichtenversand wird errichtet. Vom Empfänger geforderte Schwierigkeit: {0} und {1} - Problem: The work demanded by the recipient (%1 and %2) is more difficult than you are willing to do. %3 - Problem: Die vom Empfänger verlangte Arbeit (%1 und %2) ist schwieriger, als Sie in den Einstellungen erlaubt haben. %3 + Problem: The work demanded by the recipient ({0} and {1}) is more difficult than you are willing to do. {2} + Problem: Die vom Empfänger verlangte Arbeit ({0} und {1}) ist schwieriger, als Sie in den Einstellungen erlaubt haben. {2} - Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. %1 + Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. {0} Problem: Sie versuchen, eine Nachricht an sich zu versenden, aber Ihr Schlüssel befindet sich nicht in der keys.dat-Datei. Die Nachricht kann nicht verschlüsselt werden. 1% @@ -1317,8 +1317,8 @@ Receiver's required difficulty: %1 and %2 - Message sent. Waiting for acknowledgement. Sent on %1 - Nachricht gesendet. Auf Bestätigung wird gewartet. Zeitpunkt der Sendung: %1 + Message sent. Waiting for acknowledgement. Sent on {0} + Nachricht gesendet. Auf Bestätigung wird gewartet. Zeitpunkt der Sendung: {0} @@ -1332,13 +1332,13 @@ Receiver's required difficulty: %1 and %2 - Sending public key request. Waiting for reply. Requested at %1 - Nachfrage nach dem öffentlichen Schlüssel läuft, auf Antwort wird gewartet. Nachgefragt am %1 + Sending public key request. Waiting for reply. Requested at {0} + Nachfrage nach dem öffentlichen Schlüssel läuft, auf Antwort wird gewartet. Nachgefragt am {0} - UPnP port mapping established on port %1 - UPnP Port-Mapping eingerichtet auf Port %1 + UPnP port mapping established on port {0} + UPnP Port-Mapping eingerichtet auf Port {0} @@ -1382,28 +1382,28 @@ Receiver's required difficulty: %1 and %2 - Problem communicating with proxy: %1. Please check your network settings. - Kommunikationsfehler mit dem Proxy: %1. Bitte überprüfen Sie Ihre Netzwerkeinstellungen. + Problem communicating with proxy: {0}. Please check your network settings. + Kommunikationsfehler mit dem Proxy: {0}. Bitte überprüfen Sie Ihre Netzwerkeinstellungen. - SOCKS5 Authentication problem: %1. Please check your SOCKS5 settings. - SOCKS5-Authentizierung fehlgeschlagen: %1. Bitte überprüfen Sie Ihre SOCKS5-Einstellungen. + SOCKS5 Authentication problem: {0}. Please check your SOCKS5 settings. + SOCKS5-Authentizierung fehlgeschlagen: {0}. Bitte überprüfen Sie Ihre SOCKS5-Einstellungen. - The time on your computer, %1, may be wrong. Please verify your settings. - Die Uhrzeit ihres Computers, %1, ist möglicherweise falsch. Bitte überprüfen Sie Ihre einstellungen. + The time on your computer, {0}, may be wrong. Please verify your settings. + Die Uhrzeit ihres Computers, {0}, ist möglicherweise falsch. Bitte überprüfen Sie Ihre einstellungen. - The name %1 was not found. - Der Name %1 wurde nicht gefunden. + The name {0} was not found. + Der Name {0} wurde nicht gefunden. - The namecoin query failed (%1) - Namecoin-abfrage fehlgeschlagen (%1) + The namecoin query failed ({0}) + Namecoin-abfrage fehlgeschlagen ({0}) @@ -1412,18 +1412,18 @@ Receiver's required difficulty: %1 and %2 - The name %1 has no valid JSON data. - Der Name %1 beinhaltet keine gültige JSON-Daten. + The name {0} has no valid JSON data. + Der Name {0} beinhaltet keine gültige JSON-Daten. - The name %1 has no associated Bitmessage address. - Der Name %1 hat keine zugewiesene Bitmessageaddresse. + The name {0} has no associated Bitmessage address. + Der Name {0} hat keine zugewiesene Bitmessageaddresse. - Success! Namecoind version %1 running. - Erfolg! Namecoind Version %1 läuft. + Success! Namecoind version {0} running. + Erfolg! Namecoind Version {0} läuft. @@ -1481,53 +1481,53 @@ Willkommen zu einfachem und sicherem Bitmessage - Error: Bitmessage addresses start with BM- Please check the recipient address %1 - Fehler: Bitmessage Adressen starten mit BM- Bitte überprüfen Sie die Empfängeradresse %1 + Error: Bitmessage addresses start with BM- Please check the recipient address {0} + Fehler: Bitmessage Adressen starten mit BM- Bitte überprüfen Sie die Empfängeradresse {0} - Error: The recipient address %1 is not typed or copied correctly. Please check it. - Fehler: Die Empfängeradresse %1 wurde nicht korrekt getippt oder kopiert. Bitte überprüfen. + Error: The recipient address {0} is not typed or copied correctly. Please check it. + Fehler: Die Empfängeradresse {0} wurde nicht korrekt getippt oder kopiert. Bitte überprüfen. - Error: The recipient address %1 contains invalid characters. Please check it. - Fehler: Die Empfängeradresse %1 beinhaltet ungültig Zeichen. Bitte überprüfen. + Error: The recipient address {0} contains invalid characters. Please check it. + Fehler: Die Empfängeradresse {0} beinhaltet ungültig Zeichen. Bitte überprüfen. - Error: The version of the recipient address %1 is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. - Fehler: Die Empfängerdresseversion von %1 ist zu hoch. Entweder Sie müssen Ihre Bitmessage Software aktualisieren oder Ihr Bekannter ist sehr clever. + Error: The version of the recipient address {0} is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. + Fehler: Die Empfängerdresseversion von {0} ist zu hoch. Entweder Sie müssen Ihre Bitmessage Software aktualisieren oder Ihr Bekannter ist sehr clever. - Error: Some data encoded in the recipient address %1 is too short. There might be something wrong with the software of your acquaintance. - Fehler: Einige Daten die in der Empfängerdresse %1 codiert sind, sind zu kurz. Es könnte sein, dass etwas mit der Software Ihres Bekannten nicht stimmt. + Error: Some data encoded in the recipient address {0} is too short. There might be something wrong with the software of your acquaintance. + Fehler: Einige Daten die in der Empfängerdresse {0} codiert sind, sind zu kurz. Es könnte sein, dass etwas mit der Software Ihres Bekannten nicht stimmt. - Error: Some data encoded in the recipient address %1 is too long. There might be something wrong with the software of your acquaintance. - Fehler: Einige Daten die in der Empfängeradresse %1 codiert sind, sind zu lang. Es könnte sein, dass etwas mit der Software Ihres Bekannten nicht stimmt. + Error: Some data encoded in the recipient address {0} is too long. There might be something wrong with the software of your acquaintance. + Fehler: Einige Daten die in der Empfängeradresse {0} codiert sind, sind zu lang. Es könnte sein, dass etwas mit der Software Ihres Bekannten nicht stimmt. - Error: Some data encoded in the recipient address %1 is malformed. There might be something wrong with the software of your acquaintance. - Fehler: Einige codierte Daten in der Empfängeradresse %1 sind ungültig. Es könnte etwas mit der Software Ihres Bekannten sein. + Error: Some data encoded in the recipient address {0} is malformed. There might be something wrong with the software of your acquaintance. + Fehler: Einige codierte Daten in der Empfängeradresse {0} sind ungültig. Es könnte etwas mit der Software Ihres Bekannten sein. - Error: Something is wrong with the recipient address %1. - Fehler: Mit der Empfängeradresse %1 stimmt etwas nicht. + Error: Something is wrong with the recipient address {0}. + Fehler: Mit der Empfängeradresse {0} stimmt etwas nicht. - Error: %1 - Fehler: %1 + Error: {0} + Fehler: {0} - From %1 - Von %1 + From {0} + Von {0} @@ -1572,7 +1572,7 @@ Willkommen zu einfachem und sicherem Bitmessage Display the %n recent broadcast(s) from this address. - Den letzten %1 Rundruf von dieser Addresse anzeigen.Die letzten %1 Rundrufe von dieser Addresse anzeigen. + Den letzten {0} Rundruf von dieser Addresse anzeigen.Die letzten {0} Rundrufe von dieser Addresse anzeigen. @@ -1619,8 +1619,8 @@ Willkommen zu einfachem und sicherem Bitmessage - The link "%1" will open in a browser. It may be a security risk, it could de-anonymise you or download malicious data. Are you sure? - Der Link "%1" wird in Browser geöffnet. Es kann ein Sicherheitsrisiko darstellen, es könnte Sie de-anonymisieren oder schädliche Aktivitäten durchführen. Sind Sie sicher? + The link "{0}" will open in a browser. It may be a security risk, it could de-anonymise you or download malicious data. Are you sure? + Der Link "{0}" wird in Browser geöffnet. Es kann ein Sicherheitsrisiko darstellen, es könnte Sie de-anonymisieren oder schädliche Aktivitäten durchführen. Sind Sie sicher? @@ -1955,8 +1955,8 @@ Die Zufallszahlen-Option ist standardmässig gewählt, jedoch haben deterministi - You are using TCP port %1. (This can be changed in the settings). - Sie benutzen TCP-Port %1 (Dieser kann in den Einstellungen verändert werden). + You are using TCP port {0}. (This can be changed in the settings). + Sie benutzen TCP-Port {0} (Dieser kann in den Einstellungen verändert werden). @@ -2008,28 +2008,28 @@ Die Zufallszahlen-Option ist standardmässig gewählt, jedoch haben deterministi - Since startup on %1 - Seit Start der Anwendung am %1 + Since startup on {0} + Seit Start der Anwendung am {0} - Down: %1/s Total: %2 - Herunter: %1/s Insg.: %2 + Down: {0}/s Total: {1} + Herunter: {0}/s Insg.: {1} - Up: %1/s Total: %2 - Hoch: %1/s Insg.: %2 + Up: {0}/s Total: {1} + Hoch: {0}/s Insg.: {1} - Total Connections: %1 - Verbindungen insgesamt: %1 + Total Connections: {0} + Verbindungen insgesamt: {0} - Inventory lookups per second: %1 - Inventory lookups pro Sekunde: %1 + Inventory lookups per second: {0} + Inventory lookups pro Sekunde: {0} @@ -2194,8 +2194,8 @@ Die Zufallszahlen-Option ist standardmässig gewählt, jedoch haben deterministi newchandialog - Successfully created / joined chan %1 - Chan %1 erfolgreich erstellt/beigetreten + Successfully created / joined chan {0} + Chan {0} erfolgreich erstellt/beigetreten diff --git a/src/translations/bitmessage_en.qm b/src/translations/bitmessage_en.qm index 4751f4ca1a79835180d272a4b023afb6b34b38c9..71a25005981bf7a657344b246fa16f1201b279fa 100644 GIT binary patch delta 5926 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 diff --git a/src/translations/bitmessage_en.ts b/src/translations/bitmessage_en.ts index 05e9cc4b..8525b52c 100644 --- a/src/translations/bitmessage_en.ts +++ b/src/translations/bitmessage_en.ts @@ -281,8 +281,8 @@ Please type the desired email address (including @mailchuck.com) below: - One of your addresses, %1, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? - One of your addresses, %1, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? + One of your addresses, {0}, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? + One of your addresses, {0}, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? @@ -301,13 +301,13 @@ Please type the desired email address (including @mailchuck.com) below: - Message sent. Waiting for acknowledgement. Sent at %1 - Message sent. Waiting for acknowledgement. Sent at %1 + Message sent. Waiting for acknowledgement. Sent at {0} + Message sent. Waiting for acknowledgement. Sent at {0} - Message sent. Sent at %1 - Message sent. Sent at %1 + Message sent. Sent at {0} + Message sent. Sent at {0} @@ -316,8 +316,8 @@ Please type the desired email address (including @mailchuck.com) below: - Acknowledgement of the message received %1 - Acknowledgement of the message received %1 + Acknowledgement of the message received {0} + Acknowledgement of the message received {0} @@ -326,18 +326,18 @@ Please type the desired email address (including @mailchuck.com) below: - Broadcast on %1 - Broadcast on %1 + Broadcast on {0} + Broadcast on {0} - Problem: The work demanded by the recipient is more difficult than you are willing to do. %1 - Problem: The work demanded by the recipient is more difficult than you are willing to do. %1 + Problem: The work demanded by the recipient is more difficult than you are willing to do. {0} + Problem: The work demanded by the recipient is more difficult than you are willing to do. {0} - Problem: The recipient's encryption key is no good. Could not encrypt message. %1 - Problem: The recipient's encryption key is no good. Could not encrypt message. %1 + Problem: The recipient's encryption key is no good. Could not encrypt message. {0} + Problem: The recipient's encryption key is no good. Could not encrypt message. {0} @@ -346,8 +346,8 @@ Please type the desired email address (including @mailchuck.com) below: - Unknown status: %1 %2 - Unknown status: %1 %2 + Unknown status: {0} {1} + Unknown status: {0} {1} @@ -387,10 +387,10 @@ Please type the desired email address (including @mailchuck.com) below: You may manage your keys by editing the keys.dat file stored in - %1 + {0} It is important that you back up this file. You may manage your keys by editing the keys.dat file stored in - %1 + {0} It is important that you back up this file. @@ -406,10 +406,10 @@ It is important that you back up this file. You may manage your keys by editing the keys.dat file stored in - %1 + {0} 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.) You may manage your keys by editing the keys.dat file stored in - %1 + {0} 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.) @@ -474,8 +474,8 @@ It is important that you back up this file. Would you like to open the file now? - Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: %1. This address also appears in 'Your Identities'. - Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: %1. This address also appears in 'Your Identities'. + Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: {0}. This address also appears in 'Your Identities'. + Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: {0}. This address also appears in 'Your Identities'. @@ -545,53 +545,53 @@ It is important that you back up this file. Would you like to open the file now? - The message that you are trying to send is too long by %1 bytes. (The maximum is 261644 bytes). Please cut it down before sending. - The message that you are trying to send is too long by %1 bytes. (The maximum is 261644 bytes). Please cut it down before sending. + The message that you are trying to send is too long by {0} bytes. (The maximum is 261644 bytes). Please cut it down before sending. + The message that you are trying to send is too long by {0} bytes. (The maximum is 261644 bytes). Please cut it down before sending. - Error: Your account wasn't registered at an email gateway. Sending registration now as %1, please wait for the registration to be processed before retrying sending. - Error: Your account wasn't registered at an email gateway. Sending registration now as %1, please wait for the registration to be processed before retrying sending. + Error: Your account wasn't registered at an email gateway. Sending registration now as {0}, please wait for the registration to be processed before retrying sending. + Error: Your account wasn't registered at an email gateway. Sending registration now as {0}, please wait for the registration to be processed before retrying sending. - Error: Bitmessage addresses start with BM- Please check %1 - Error: Bitmessage addresses start with BM- Please check %1 + Error: Bitmessage addresses start with BM- Please check {0} + Error: Bitmessage addresses start with BM- Please check {0} - Error: The address %1 is not typed or copied correctly. Please check it. - Error: The address %1 is not typed or copied correctly. Please check it. + Error: The address {0} is not typed or copied correctly. Please check it. + Error: The address {0} is not typed or copied correctly. Please check it. - Error: The address %1 contains invalid characters. Please check it. - Error: The address %1 contains invalid characters. Please check it. + Error: The address {0} contains invalid characters. Please check it. + Error: The address {0} contains invalid characters. Please check it. - Error: The address version in %1 is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. - Error: The address version in %1 is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. + Error: The address version in {0} is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. + Error: The address version in {0} is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. - Error: Some data encoded in the address %1 is too short. There might be something wrong with the software of your acquaintance. - Error: Some data encoded in the address %1 is too short. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is too short. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is too short. There might be something wrong with the software of your acquaintance. - Error: Some data encoded in the address %1 is too long. There might be something wrong with the software of your acquaintance. - Error: Some data encoded in the address %1 is too long. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is too long. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is too long. There might be something wrong with the software of your acquaintance. - Error: Some data encoded in the address %1 is malformed. There might be something wrong with the software of your acquaintance. - Error: Some data encoded in the address %1 is malformed. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is malformed. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is malformed. There might be something wrong with the software of your acquaintance. - Error: Something is wrong with the address %1. - Error: Something is wrong with the address %1. + Error: Something is wrong with the address {0}. + Error: Something is wrong with the address {0}. @@ -605,8 +605,8 @@ It is important that you back up this file. Would you like to open the file now? - Concerning the address %1, Bitmessage cannot understand address version numbers of %2. Perhaps upgrade Bitmessage to the latest version. - Concerning the address %1, Bitmessage cannot understand address version numbers of %2. Perhaps upgrade Bitmessage to the latest version. + Concerning the address {0}, Bitmessage cannot understand address version numbers of {1}. Perhaps upgrade Bitmessage to the latest version. + Concerning the address {0}, Bitmessage cannot understand address version numbers of {1}. Perhaps upgrade Bitmessage to the latest version. @@ -615,8 +615,8 @@ It is important that you back up this file. Would you like to open the file now? - Concerning the address %1, Bitmessage cannot handle stream numbers of %2. Perhaps upgrade Bitmessage to the latest version. - Concerning the address %1, Bitmessage cannot handle stream numbers of %2. Perhaps upgrade Bitmessage to the latest version. + Concerning the address {0}, Bitmessage cannot handle stream numbers of {1}. Perhaps upgrade Bitmessage to the latest version. + Concerning the address {0}, Bitmessage cannot handle stream numbers of {1}. Perhaps upgrade Bitmessage to the latest version. @@ -750,8 +750,8 @@ It is important that you back up this file. Would you like to open the file now? - Bitmessage cannot find your address %1. Perhaps you removed it? - Bitmessage cannot find your address %1. Perhaps you removed it? + Bitmessage cannot find your address {0}. Perhaps you removed it? + Bitmessage cannot find your address {0}. Perhaps you removed it? @@ -908,8 +908,8 @@ Are you sure you want to delete the channel? - You are using TCP port %1. (This can be changed in the settings). - You are using TCP port %1. (This can be changed in the settings). + You are using TCP port {0}. (This can be changed in the settings). + You are using TCP port {0}. (This can be changed in the settings). @@ -1103,8 +1103,8 @@ Are you sure you want to delete the channel? - Zoom level %1% - Zoom level %1% + Zoom level {0}% + Zoom level {0}% @@ -1118,48 +1118,48 @@ Are you sure you want to delete the channel? - Display the %1 recent broadcast(s) from this address. - Display the %1 recent broadcast(s) from this address. + Display the {0} recent broadcast(s) from this address. + Display the {0} recent broadcast(s) from this address. - New version of PyBitmessage is available: %1. Download it from https://github.com/Bitmessage/PyBitmessage/releases/latest - New version of PyBitmessage is available: %1. Download it from https://github.com/Bitmessage/PyBitmessage/releases/latest + New version of PyBitmessage is available: {0}. Download it from https://github.com/Bitmessage/PyBitmessage/releases/latest + New version of PyBitmessage is available: {0}. Download it from https://github.com/Bitmessage/PyBitmessage/releases/latest - Waiting for PoW to finish... %1% - Waiting for PoW to finish... %1% + Waiting for PoW to finish... {0}% + Waiting for PoW to finish... {0}% - Shutting down Pybitmessage... %1% - Shutting down Pybitmessage... %1% + Shutting down Pybitmessage... {0}% + Shutting down Pybitmessage... {0}% - Waiting for objects to be sent... %1% - Waiting for objects to be sent... %1% + Waiting for objects to be sent... {0}% + Waiting for objects to be sent... {0}% - Saving settings... %1% - Saving settings... %1% + Saving settings... {0}% + Saving settings... {0}% - Shutting down core... %1% - Shutting down core... %1% + Shutting down core... {0}% + Shutting down core... {0}% - Stopping notifications... %1% - Stopping notifications... %1% + Stopping notifications... {0}% + Stopping notifications... {0}% - Shutdown imminent... %1% - Shutdown imminent... %1% + Shutdown imminent... {0}% + Shutdown imminent... {0}% @@ -1179,8 +1179,8 @@ Are you sure you want to delete the channel? - Shutting down PyBitmessage... %1% - Shutting down PyBitmessage... %1% + Shutting down PyBitmessage... {0}% + Shutting down PyBitmessage... {0}% @@ -1199,13 +1199,13 @@ Are you sure you want to delete the channel? - Generating %1 new addresses. - Generating %1 new addresses. + Generating {0} new addresses. + Generating {0} new addresses. - %1 is already in 'Your Identities'. Not adding it again. - %1 is already in 'Your Identities'. Not adding it again. + {0} is already in 'Your Identities'. Not adding it again. + {0} is already in 'Your Identities'. Not adding it again. @@ -1214,8 +1214,8 @@ Are you sure you want to delete the channel? - SOCKS5 Authentication problem: %1 - SOCKS5 Authentication problem: %1 + SOCKS5 Authentication problem: {0} + SOCKS5 Authentication problem: {0} @@ -1239,8 +1239,8 @@ Are you sure you want to delete the channel? - Broadcast sent on %1 - Broadcast sent on %1 + Broadcast sent on {0} + Broadcast sent on {0} @@ -1259,8 +1259,8 @@ Are you sure you want to delete the channel? - Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. %1 - Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. %1 + Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. {0} + Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. {0} @@ -1272,19 +1272,19 @@ There is no required difficulty for version 2 addresses like this. Doing work necessary to send message. -Receiver's required difficulty: %1 and %2 +Receiver's required difficulty: {0} and {1} Doing work necessary to send message. -Receiver's required difficulty: %1 and %2 +Receiver's required difficulty: {0} and {1} - Problem: The work demanded by the recipient (%1 and %2) is more difficult than you are willing to do. %3 - Problem: The work demanded by the recipient (%1 and %2) is more difficult than you are willing to do. %3 + Problem: The work demanded by the recipient ({0} and {1}) is more difficult than you are willing to do. {2} + Problem: The work demanded by the recipient ({0} and {1}) is more difficult than you are willing to do. {2} - Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. %1 - Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. %1 + Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. {0} + Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. {0} @@ -1293,8 +1293,8 @@ Receiver's required difficulty: %1 and %2 - Message sent. Waiting for acknowledgement. Sent on %1 - Message sent. Waiting for acknowledgement. Sent on %1 + Message sent. Waiting for acknowledgement. Sent on {0} + Message sent. Waiting for acknowledgement. Sent on {0} @@ -1308,13 +1308,13 @@ Receiver's required difficulty: %1 and %2 - Sending public key request. Waiting for reply. Requested at %1 - Sending public key request. Waiting for reply. Requested at %1 + Sending public key request. Waiting for reply. Requested at {0} + Sending public key request. Waiting for reply. Requested at {0} - UPnP port mapping established on port %1 - UPnP port mapping established on port %1 + UPnP port mapping established on port {0} + UPnP port mapping established on port {0} @@ -1703,28 +1703,28 @@ The 'Random Number' option is selected by default but deterministic ad - Since startup on %1 - Since startup on %1 + Since startup on {0} + Since startup on {0} - Down: %1/s Total: %2 - Down: %1/s Total: %2 + Down: {0}/s Total: {1} + Down: {0}/s Total: {1} - Up: %1/s Total: %2 - Up: %1/s Total: %2 + Up: {0}/s Total: {1} + Up: {0}/s Total: {1} - Total Connections: %1 - Total Connections: %1 + Total Connections: {0} + Total Connections: {0} - Inventory lookups per second: %1 - Inventory lookups per second: %1 + Inventory lookups per second: {0} + Inventory lookups per second: {0} diff --git a/src/translations/bitmessage_en_pirate.qm b/src/translations/bitmessage_en_pirate.qm index 69e6bde80093b2b1fb33eac0eba92e595a373db1..753e7e1aa6f9eb30367c1489a9e77030178e29fc 100644 GIT binary patch delta 17 YcmccF!FaEQaYMKhdj|sp0}~@706Q)Oq5uE@ delta 445 zcmccD!g#ZTaYMLMy*>j2<2Q!s47dOzh6EQ}L;%hLF~q<;ITSI1oO%Xr9BNE(h=YWk zk>vc~>aQh=x^wHPKUATKwWS6bXqC^I=f&pju5^4fxQchxWc1~t- X372nTW?pz^UP^vBLkG}(OpJ^G^OP~O diff --git a/src/translations/bitmessage_en_pirate.ts b/src/translations/bitmessage_en_pirate.ts index 69642a96..48f60e6c 100644 --- a/src/translations/bitmessage_en_pirate.ts +++ b/src/translations/bitmessage_en_pirate.ts @@ -241,7 +241,7 @@ Please type the desired email address (including @mailchuck.com) below: - One of your addresses, %1, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? + One of your addresses, {0}, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? @@ -261,12 +261,12 @@ Please type the desired email address (including @mailchuck.com) below: - Message sent. Waiting for acknowledgement. Sent at %1 + Message sent. Waiting for acknowledgement. Sent at {0} - Message sent. Sent at %1 + Message sent. Sent at {0} @@ -276,7 +276,7 @@ Please type the desired email address (including @mailchuck.com) below: - Acknowledgement of the message received %1 + Acknowledgement of the message received {0} @@ -286,17 +286,17 @@ Please type the desired email address (including @mailchuck.com) below: - Broadcast on %1 + Broadcast on {0} - Problem: The work demanded by the recipient is more difficult than you are willing to do. %1 + Problem: The work demanded by the recipient is more difficult than you are willing to do. {0} - Problem: The recipient's encryption key is no good. Could not encrypt message. %1 + Problem: The recipient's encryption key is no good. Could not encrypt message. {0} @@ -306,7 +306,7 @@ Please type the desired email address (including @mailchuck.com) below: - Unknown status: %1 %2 + Unknown status: {0} {1} @@ -347,7 +347,7 @@ Please type the desired email address (including @mailchuck.com) below: You may manage your keys by editing the keys.dat file stored in - %1 + {0} It is important that you back up this file. @@ -364,7 +364,7 @@ It is important that you back up this file. You may manage your keys by editing the keys.dat file stored in - %1 + {0} 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.) @@ -430,7 +430,7 @@ It is important that you back up this file. Would you like to open the file now? - Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: %1. This address also appears in 'Your Identities'. + Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: {0}. This address also appears in 'Your Identities'. @@ -498,52 +498,52 @@ It is important that you back up this file. Would you like to open the file now? - The message that you are trying to send is too long by %1 bytes. (The maximum is 261644 bytes). Please cut it down before sending. + The message that you are trying to send is too long by {0} bytes. (The maximum is 261644 bytes). Please cut it down before sending. - Error: Your account wasn't registered at an email gateway. Sending registration now as %1, please wait for the registration to be processed before retrying sending. + Error: Your account wasn't registered at an email gateway. Sending registration now as {0}, please wait for the registration to be processed before retrying sending. - Error: Bitmessage addresses start with BM- Please check %1 + Error: Bitmessage addresses start with BM- Please check {0} - Error: The address %1 is not typed or copied correctly. Please check it. + Error: The address {0} is not typed or copied correctly. Please check it. - Error: The address %1 contains invalid characters. Please check it. + Error: The address {0} contains invalid characters. Please check it. - Error: The address version in %1 is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. + Error: The address version in {0} is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. - Error: Some data encoded in the address %1 is too short. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is too short. There might be something wrong with the software of your acquaintance. - Error: Some data encoded in the address %1 is too long. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is too long. There might be something wrong with the software of your acquaintance. - Error: Some data encoded in the address %1 is malformed. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is malformed. There might be something wrong with the software of your acquaintance. - Error: Something is wrong with the address %1. + Error: Something is wrong with the address {0}. @@ -558,7 +558,7 @@ It is important that you back up this file. Would you like to open the file now? - Concerning the address %1, Bitmessage cannot understand address version numbers of %2. Perhaps upgrade Bitmessage to the latest version. + Concerning the address {0}, Bitmessage cannot understand address version numbers of {1}. Perhaps upgrade Bitmessage to the latest version. @@ -568,7 +568,7 @@ It is important that you back up this file. Would you like to open the file now? - Concerning the address %1, Bitmessage cannot handle stream numbers of %2. Perhaps upgrade Bitmessage to the latest version. + Concerning the address {0}, Bitmessage cannot handle stream numbers of {1}. Perhaps upgrade Bitmessage to the latest version. @@ -703,7 +703,7 @@ It is important that you back up this file. Would you like to open the file now? - Bitmessage cannot find your address %1. Perhaps you removed it? + Bitmessage cannot find your address {0}. Perhaps you removed it? @@ -857,7 +857,7 @@ Are you sure you want to delete the channel? - You are using TCP port %1. (This can be changed in the settings). + You are using TCP port {0}. (This can be changed in the settings). @@ -1052,7 +1052,7 @@ Are you sure you want to delete the channel? - Zoom level %1% + Zoom level {0}% @@ -1067,47 +1067,47 @@ Are you sure you want to delete the channel? - Display the %1 recent broadcast(s) from this address. + Display the {0} recent broadcast(s) from this address. - New version of PyBitmessage is available: %1. Download it from https://github.com/Bitmessage/PyBitmessage/releases/latest + New version of PyBitmessage is available: {0}. Download it from https://github.com/Bitmessage/PyBitmessage/releases/latest - Waiting for PoW to finish... %1% + Waiting for PoW to finish... {0}% - Shutting down Pybitmessage... %1% + Shutting down Pybitmessage... {0}% - Waiting for objects to be sent... %1% + Waiting for objects to be sent... {0}% - Saving settings... %1% + Saving settings... {0}% - Shutting down core... %1% + Shutting down core... {0}% - Stopping notifications... %1% + Stopping notifications... {0}% - Shutdown imminent... %1% + Shutdown imminent... {0}% @@ -1128,7 +1128,7 @@ Are you sure you want to delete the channel? - Shutting down PyBitmessage... %1% + Shutting down PyBitmessage... {0}% @@ -1148,12 +1148,12 @@ Are you sure you want to delete the channel? - Generating %1 new addresses. + Generating {0} new addresses. - %1 is already in 'Your Identities'. Not adding it again. + {0} is already in 'Your Identities'. Not adding it again. @@ -1163,7 +1163,7 @@ Are you sure you want to delete the channel? - SOCKS5 Authentication problem: %1 + SOCKS5 Authentication problem: {0} @@ -1188,7 +1188,7 @@ Are you sure you want to delete the channel? - Broadcast sent on %1 + Broadcast sent on {0} @@ -1208,7 +1208,7 @@ Are you sure you want to delete the channel? - Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. %1 + Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. {0} @@ -1220,17 +1220,17 @@ There is no required difficulty for version 2 addresses like this. Doing work necessary to send message. -Receiver's required difficulty: %1 and %2 +Receiver's required difficulty: {0} and {1} - Problem: The work demanded by the recipient (%1 and %2) is more difficult than you are willing to do. %3 + Problem: The work demanded by the recipient ({0} and {1}) is more difficult than you are willing to do. {2} - Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. %1 + Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. {0} @@ -1240,7 +1240,7 @@ Receiver's required difficulty: %1 and %2 - Message sent. Waiting for acknowledgement. Sent on %1 + Message sent. Waiting for acknowledgement. Sent on {0} @@ -1255,12 +1255,12 @@ Receiver's required difficulty: %1 and %2 - Sending public key request. Waiting for reply. Requested at %1 + Sending public key request. Waiting for reply. Requested at {0} - UPnP port mapping established on port %1 + UPnP port mapping established on port {0} @@ -1623,27 +1623,27 @@ T' 'Random Number' option be selected by default but deterministi - Since startup on %1 + Since startup on {0} - Down: %1/s Total: %2 + Down: {0}/s Total: {1} - Up: %1/s Total: %2 + Up: {0}/s Total: {1} - Total Connections: %1 + Total Connections: {0} - Inventory lookups per second: %1 + Inventory lookups per second: {0} diff --git a/src/translations/bitmessage_eo.qm b/src/translations/bitmessage_eo.qm index 77c20edfbc100594577d3e66405b12d4c0e33e21..76fac0960defd52d61cd0e5895ffd01e9e7096f2 100644 GIT binary patch delta 6327 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 delta 6230 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 diff --git a/src/translations/bitmessage_eo.ts b/src/translations/bitmessage_eo.ts index 5707a390..835de58d 100644 --- a/src/translations/bitmessage_eo.ts +++ b/src/translations/bitmessage_eo.ts @@ -350,8 +350,8 @@ Please type the desired email address (including @mailchuck.com) below: - One of your addresses, %1, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? - Iu de viaj adresoj, %1, estas malnova versio 1 adreso. Versioj 1 adresoj ne estas jam subtenataj. Ĉu ni povas forigi ĝin? + One of your addresses, {0}, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? + Iu de viaj adresoj, {0}, estas malnova versio 1 adreso. Versioj 1 adresoj ne estas jam subtenataj. Ĉu ni povas forigi ĝin? @@ -370,13 +370,13 @@ Please type the desired email address (including @mailchuck.com) below: - Message sent. Waiting for acknowledgement. Sent at %1 - Mesaĝo sendita. Atendado je konfirmo. Sendita je %1 + Message sent. Waiting for acknowledgement. Sent at {0} + Mesaĝo sendita. Atendado je konfirmo. Sendita je {0} - Message sent. Sent at %1 - Mesaĝo sendita. Sendita je %1 + Message sent. Sent at {0} + Mesaĝo sendita. Sendita je {0} @@ -385,8 +385,8 @@ Please type the desired email address (including @mailchuck.com) below: - Acknowledgement of the message received %1 - Ricevis konfirmon de la mesaĝo je %1 + Acknowledgement of the message received {0} + Ricevis konfirmon de la mesaĝo je {0} @@ -395,18 +395,18 @@ Please type the desired email address (including @mailchuck.com) below: - Broadcast on %1 - Elsendo je %1 + Broadcast on {0} + Elsendo je {0} - Problem: The work demanded by the recipient is more difficult than you are willing to do. %1 - Problemo: la demandita laboro de la ricevonto estas pli malfacila ol vi pretas fari. %1 + Problem: The work demanded by the recipient is more difficult than you are willing to do. {0} + Problemo: la demandita laboro de la ricevonto estas pli malfacila ol vi pretas fari. {0} - Problem: The recipient's encryption key is no good. Could not encrypt message. %1 - Problemo: la ĉifroŝlosilo de la ricevonto estas rompita. Ne povis ĉifri la mesaĝon. %1 + Problem: The recipient's encryption key is no good. Could not encrypt message. {0} + Problemo: la ĉifroŝlosilo de la ricevonto estas rompita. Ne povis ĉifri la mesaĝon. {0} @@ -415,8 +415,8 @@ Please type the desired email address (including @mailchuck.com) below: - Unknown status: %1 %2 - Nekonata stato: %1 %2 + Unknown status: {0} {1} + Nekonata stato: {0} {1} @@ -456,10 +456,10 @@ Please type the desired email address (including @mailchuck.com) below: You may manage your keys by editing the keys.dat file stored in - %1 + {0} It is important that you back up this file. Vi povas administri viajn ŝlosilojn per redakti la dosieron “keys.dat” en la dosierujo -%1. +{0}. Estas grava, ke vi faru sekurkopion de tiu dosiero. @@ -475,10 +475,10 @@ Estas grava, ke vi faru sekurkopion de tiu dosiero. You may manage your keys by editing the keys.dat file stored in - %1 + {0} 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.) Vi povas administri viajn ŝlosilojn per redakti la dosieron “keys.dat” en la dosierujo -%1. +{0}. Estas grava, ke vi faru sekurkopion de tiu dosiero. Ĉu vi volas malfermi la dosieron nun? (Bonvolu certigi ke Bitmesaĝo estas fermita antaŭ fari ŝanĝojn.) @@ -543,7 +543,7 @@ Estas grava, ke vi faru sekurkopion de tiu dosiero. Ĉu vi volas malfermi la dos - Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: %1. This address also appears in 'Your Identities'. + Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: {0}. This address also appears in 'Your Identities'. @@ -611,52 +611,52 @@ Estas grava, ke vi faru sekurkopion de tiu dosiero. Ĉu vi volas malfermi la dos - The message that you are trying to send is too long by %1 bytes. (The maximum is 261644 bytes). Please cut it down before sending. - La mesaĝon kiun vi provis sendi estas tro longa je %1 bitokoj. (La maksimumo estas 261644 bitokoj.) Bonvolu mallongigi ĝin antaŭ sendado. + The message that you are trying to send is too long by {0} bytes. (The maximum is 261644 bytes). Please cut it down before sending. + La mesaĝon kiun vi provis sendi estas tro longa je {0} bitokoj. (La maksimumo estas 261644 bitokoj.) Bonvolu mallongigi ĝin antaŭ sendado. - Error: Your account wasn't registered at an email gateway. Sending registration now as %1, please wait for the registration to be processed before retrying sending. - Eraro: via konto ne estas registrita je retpoŝta kluzo. Registranta nun kiel %1, bonvolu atendi ĝis la registrado finos antaŭ vi reprovos sendi iun ajn. + Error: Your account wasn't registered at an email gateway. Sending registration now as {0}, please wait for the registration to be processed before retrying sending. + Eraro: via konto ne estas registrita je retpoŝta kluzo. Registranta nun kiel {0}, bonvolu atendi ĝis la registrado finos antaŭ vi reprovos sendi iun ajn. - Error: Bitmessage addresses start with BM- Please check %1 + Error: Bitmessage addresses start with BM- Please check {0} - Error: The address %1 is not typed or copied correctly. Please check it. + Error: The address {0} is not typed or copied correctly. Please check it. - Error: The address %1 contains invalid characters. Please check it. + Error: The address {0} contains invalid characters. Please check it. - Error: The address version in %1 is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. + Error: The address version in {0} is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. - Error: Some data encoded in the address %1 is too short. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is too short. There might be something wrong with the software of your acquaintance. - Error: Some data encoded in the address %1 is too long. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is too long. There might be something wrong with the software of your acquaintance. - Error: Some data encoded in the address %1 is malformed. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is malformed. There might be something wrong with the software of your acquaintance. - Error: Something is wrong with the address %1. + Error: Something is wrong with the address {0}. @@ -671,8 +671,8 @@ Estas grava, ke vi faru sekurkopion de tiu dosiero. Ĉu vi volas malfermi la dos - Concerning the address %1, Bitmessage cannot understand address version numbers of %2. Perhaps upgrade Bitmessage to the latest version. - Dum prilaborado de adreso adreso %1, Bitmesaĝo ne povas kompreni numerojn %2 de adresversioj. Eble ĝisdatigu Bitmesaĝon al la plej nova versio. + Concerning the address {0}, Bitmessage cannot understand address version numbers of {1}. Perhaps upgrade Bitmessage to the latest version. + Dum prilaborado de adreso adreso {0}, Bitmesaĝo ne povas kompreni numerojn {1} de adresversioj. Eble ĝisdatigu Bitmesaĝon al la plej nova versio. @@ -681,8 +681,8 @@ Estas grava, ke vi faru sekurkopion de tiu dosiero. Ĉu vi volas malfermi la dos - Concerning the address %1, Bitmessage cannot handle stream numbers of %2. Perhaps upgrade Bitmessage to the latest version. - Dum prilaborado de adreso %1, Bitmesaĝo ne povas priservi %2 fluojn numerojn. Eble ĝisdatigu Bitmesaĝon al la plej nova versio. + Concerning the address {0}, Bitmessage cannot handle stream numbers of {1}. Perhaps upgrade Bitmessage to the latest version. + Dum prilaborado de adreso {0}, Bitmesaĝo ne povas priservi {1} fluojn numerojn. Eble ĝisdatigu Bitmesaĝon al la plej nova versio. @@ -816,8 +816,8 @@ Estas grava, ke vi faru sekurkopion de tiu dosiero. Ĉu vi volas malfermi la dos - Bitmessage cannot find your address %1. Perhaps you removed it? - Bitmesaĝo ne povas trovi vian adreson %1. Ĉu eble vi forviŝis ĝin? + Bitmessage cannot find your address {0}. Perhaps you removed it? + Bitmesaĝo ne povas trovi vian adreson {0}. Ĉu eble vi forviŝis ĝin? @@ -974,7 +974,7 @@ Are you sure you want to delete the channel? - You are using TCP port %1. (This can be changed in the settings). + You are using TCP port {0}. (This can be changed in the settings). @@ -1169,8 +1169,8 @@ Are you sure you want to delete the channel? - Zoom level %1% - Pligrandigo: %1 + Zoom level {0}% + Pligrandigo: {0} @@ -1184,48 +1184,48 @@ Are you sure you want to delete the channel? - Display the %1 recent broadcast(s) from this address. + Display the {0} recent broadcast(s) from this address. - New version of PyBitmessage is available: %1. Download it from https://github.com/Bitmessage/PyBitmessage/releases/latest - La nova versio de PyBitmessage estas disponebla: %1. Elŝutu ĝin de https://github.com/Bitmessage/PyBitmessage/releases/latest + New version of PyBitmessage is available: {0}. Download it from https://github.com/Bitmessage/PyBitmessage/releases/latest + La nova versio de PyBitmessage estas disponebla: {0}. Elŝutu ĝin de https://github.com/Bitmessage/PyBitmessage/releases/latest - Waiting for PoW to finish... %1% - Atendado ĝis laborpruvo finiĝos… %1% + Waiting for PoW to finish... {0}% + Atendado ĝis laborpruvo finiĝos… {0}% - Shutting down Pybitmessage... %1% - Fermado de PyBitmessage… %1% + Shutting down Pybitmessage... {0}% + Fermado de PyBitmessage… {0}% - Waiting for objects to be sent... %1% - Atendado ĝis objektoj estos senditaj… %1% + Waiting for objects to be sent... {0}% + Atendado ĝis objektoj estos senditaj… {0}% - Saving settings... %1% - Konservado de agordoj… %1% + Saving settings... {0}% + Konservado de agordoj… {0}% - Shutting down core... %1% - Fermado de kerno… %1% + Shutting down core... {0}% + Fermado de kerno… {0}% - Stopping notifications... %1% - Haltigado de sciigoj… %1% + Stopping notifications... {0}% + Haltigado de sciigoj… {0}% - Shutdown imminent... %1% - Fermado tuj… %1% + Shutdown imminent... {0}% + Fermado tuj… {0}% @@ -1239,8 +1239,8 @@ Are you sure you want to delete the channel? - Shutting down PyBitmessage... %1% - Fermado de PyBitmessage… %1% + Shutting down PyBitmessage... {0}% + Fermado de PyBitmessage… {0}% @@ -1259,13 +1259,13 @@ Are you sure you want to delete the channel? - Generating %1 new addresses. - Kreado de %1 novaj adresoj. + Generating {0} new addresses. + Kreado de {0} novaj adresoj. - %1 is already in 'Your Identities'. Not adding it again. - %1 jam estas en ‘Viaj Identigoj’. Ĝi ne estos aldonita ree. + {0} is already in 'Your Identities'. Not adding it again. + {0} jam estas en ‘Viaj Identigoj’. Ĝi ne estos aldonita ree. @@ -1274,7 +1274,7 @@ Are you sure you want to delete the channel? - SOCKS5 Authentication problem: %1 + SOCKS5 Authentication problem: {0} @@ -1299,8 +1299,8 @@ Are you sure you want to delete the channel? - Broadcast sent on %1 - Elsendo sendita je %1 + Broadcast sent on {0} + Elsendo sendita je {0} @@ -1319,8 +1319,8 @@ Are you sure you want to delete the channel? - Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. %1 - Eraro: celadreso estas portebla aparato kiu necesas, ke la celadreso estu enhavita en la mesaĝo, sed tio estas malpermesita ne viaj agordoj. %1 + Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. {0} + Eraro: celadreso estas portebla aparato kiu necesas, ke la celadreso estu enhavita en la mesaĝo, sed tio estas malpermesita ne viaj agordoj. {0} @@ -1332,19 +1332,19 @@ Malfacilaĵo ne estas bezonata por adresoj versioj 2, kiel tiu ĉi adreso. Doing work necessary to send message. -Receiver's required difficulty: %1 and %2 +Receiver's required difficulty: {0} and {1} Kalkulado de laborpruvo, kiu endas por sendi mesaĝon. -Ricevonto postulas malfacilaĵon: %1 kaj %2 +Ricevonto postulas malfacilaĵon: {0} kaj {1} - Problem: The work demanded by the recipient (%1 and %2) is more difficult than you are willing to do. %3 - Eraro: la demandita laboro de la ricevonto (%1 kaj %2) estas pli malfacila ol vi pretas fari. %3 + Problem: The work demanded by the recipient ({0} and {1}) is more difficult than you are willing to do. {2} + Eraro: la demandita laboro de la ricevonto ({0} kaj {1}) estas pli malfacila ol vi pretas fari. {2} - Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. %1 - Eraro: Vi provis sendi mesaĝon al vi mem aŭ al kanalo, tamen via ĉifroŝlosilo ne estas trovebla en la dosiero keys.dat. Mesaĝo ne povis esti ĉifrita. %1 + Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. {0} + Eraro: Vi provis sendi mesaĝon al vi mem aŭ al kanalo, tamen via ĉifroŝlosilo ne estas trovebla en la dosiero keys.dat. Mesaĝo ne povis esti ĉifrita. {0} @@ -1353,8 +1353,8 @@ Ricevonto postulas malfacilaĵon: %1 kaj %2 - Message sent. Waiting for acknowledgement. Sent on %1 - Mesaĝo sendita. Atendado je konfirmo. Sendita je %1 + Message sent. Waiting for acknowledgement. Sent on {0} + Mesaĝo sendita. Atendado je konfirmo. Sendita je {0} @@ -1368,13 +1368,13 @@ Ricevonto postulas malfacilaĵon: %1 kaj %2 - Sending public key request. Waiting for reply. Requested at %1 - Sendado de peto pri publika ĉifroŝlosilo. Atendado je respondo. Petis je %1 + Sending public key request. Waiting for reply. Requested at {0} + Sendado de peto pri publika ĉifroŝlosilo. Atendado je respondo. Petis je {0} - UPnP port mapping established on port %1 - UPnP pord-mapigo farita je pordo %1 + UPnP port mapping established on port {0} + UPnP pord-mapigo farita je pordo {0} @@ -1418,18 +1418,18 @@ Ricevonto postulas malfacilaĵon: %1 kaj %2 - The name %1 was not found. - La nomo %1 ne trovita. + The name {0} was not found. + La nomo {0} ne trovita. - The namecoin query failed (%1) - La namecoin-peto fiaskis (%1) + The namecoin query failed ({0}) + La namecoin-peto fiaskis ({0}) - Unknown namecoin interface type: %1 - Nekonata tipo de namecoin-fasado: %1 + Unknown namecoin interface type: {0} + Nekonata tipo de namecoin-fasado: {0} @@ -1438,13 +1438,13 @@ Ricevonto postulas malfacilaĵon: %1 kaj %2 - The name %1 has no associated Bitmessage address. - La nomo %1 ne estas atribuita kun bitmesaĝa adreso. + The name {0} has no associated Bitmessage address. + La nomo {0} ne estas atribuita kun bitmesaĝa adreso. - Success! Namecoind version %1 running. - Sukceso! Namecoind versio %1 funkcias. + Success! Namecoind version {0} running. + Sukceso! Namecoind versio {0} funkcias. @@ -1507,53 +1507,53 @@ Bonvenon al facila kaj sekura Bitmesaĝo - Error: Bitmessage addresses start with BM- Please check the recipient address %1 - Eraro: bitmesaĝaj adresoj komenciĝas kun BM-. Bonvolu kontroli la adreson de ricevonto %1 + Error: Bitmessage addresses start with BM- Please check the recipient address {0} + Eraro: bitmesaĝaj adresoj komenciĝas kun BM-. Bonvolu kontroli la adreson de ricevonto {0} - Error: The recipient address %1 is not typed or copied correctly. Please check it. - Eraro: la adreso de ricevonto %1 estas malprave tajpita aŭ kopiita. Bonvolu kontroli ĝin. + Error: The recipient address {0} is not typed or copied correctly. Please check it. + Eraro: la adreso de ricevonto {0} estas malprave tajpita aŭ kopiita. Bonvolu kontroli ĝin. - Error: The recipient address %1 contains invalid characters. Please check it. - Eraro: la adreso de ricevonto %1 enhavas malpermesatajn simbolojn. Bonvolu kontroli ĝin. + Error: The recipient address {0} contains invalid characters. Please check it. + Eraro: la adreso de ricevonto {0} enhavas malpermesatajn simbolojn. Bonvolu kontroli ĝin. - Error: The version of the recipient address %1 is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. - Eraro: la versio de adreso de ricevonto %1 estas tro alta. Eble vi devas ĝisdatigi vian bitmesaĝan programon aŭ via sagaca konato uzas alian programon. + Error: The version of the recipient address {0} is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. + Eraro: la versio de adreso de ricevonto {0} estas tro alta. Eble vi devas ĝisdatigi vian bitmesaĝan programon aŭ via sagaca konato uzas alian programon. - Error: Some data encoded in the recipient address %1 is too short. There might be something wrong with the software of your acquaintance. - Eraro: kelkaj datumoj koditaj en la adreso de ricevonto %1 estas tro mallongaj. Povus esti ke io en la programo de via konato malfunkcias. + Error: Some data encoded in the recipient address {0} is too short. There might be something wrong with the software of your acquaintance. + Eraro: kelkaj datumoj koditaj en la adreso de ricevonto {0} estas tro mallongaj. Povus esti ke io en la programo de via konato malfunkcias. - Error: Some data encoded in the recipient address %1 is too long. There might be something wrong with the software of your acquaintance. - Eraro: kelkaj datumoj koditaj en la adreso de ricevonto %1 estas tro longaj. Povus esti ke io en la programo de via konato malfunkcias. + Error: Some data encoded in the recipient address {0} is too long. There might be something wrong with the software of your acquaintance. + Eraro: kelkaj datumoj koditaj en la adreso de ricevonto {0} estas tro longaj. Povus esti ke io en la programo de via konato malfunkcias. - Error: Some data encoded in the recipient address %1 is malformed. There might be something wrong with the software of your acquaintance. - Eraro: kelkaj datumoj koditaj en la adreso de ricevonto %1 estas misformitaj. Povus esti ke io en la programo de via konato malfunkcias. + Error: Some data encoded in the recipient address {0} is malformed. There might be something wrong with the software of your acquaintance. + Eraro: kelkaj datumoj koditaj en la adreso de ricevonto {0} estas misformitaj. Povus esti ke io en la programo de via konato malfunkcias. - Error: Something is wrong with the recipient address %1. - Eraro: io malĝustas kun la adreso de ricevonto %1. + Error: Something is wrong with the recipient address {0}. + Eraro: io malĝustas kun la adreso de ricevonto {0}. - Error: %1 - Eraro: %1 + Error: {0} + Eraro: {0} - From %1 - De %1 + From {0} + De {0} @@ -1665,8 +1665,8 @@ Bonvenon al facila kaj sekura Bitmesaĝo - The link "%1" will open in a browser. It may be a security risk, it could de-anonymise you or download malicious data. Are you sure? - La ligilo "%1" estos malfermita per foliumilo. Tio povas esti malsekura, ĝi povos malanonimigi vin aŭ elŝuti malicajn datumojn. Ĉu vi certas? + The link "{0}" will open in a browser. It may be a security risk, it could de-anonymise you or download malicious data. Are you sure? + La ligilo "{0}" estos malfermita per foliumilo. Tio povas esti malsekura, ĝi povos malanonimigi vin aŭ elŝuti malicajn datumojn. Ĉu vi certas? @@ -2001,8 +2001,8 @@ La “hazardnombra” adreso estas antaŭagordita, sed antaŭkalkuleblaj adresoj - You are using TCP port %1. (This can be changed in the settings). - Vi uzas TCP-pordon %1 (tio ĉi estas ŝanĝebla en la agordoj). + You are using TCP port {0}. (This can be changed in the settings). + Vi uzas TCP-pordon {0} (tio ĉi estas ŝanĝebla en la agordoj). @@ -2054,28 +2054,28 @@ La “hazardnombra” adreso estas antaŭagordita, sed antaŭkalkuleblaj adresoj - Since startup on %1 - Ekde lanĉo de la programo je %1 + Since startup on {0} + Ekde lanĉo de la programo je {0} - Down: %1/s Total: %2 - Elŝuto: %1/s Sume: %2 + Down: {0}/s Total: {1} + Elŝuto: {0}/s Sume: {1} - Up: %1/s Total: %2 - Alŝuto: %1/s Sume: %2 + Up: {0}/s Total: {1} + Alŝuto: {0}/s Sume: {1} - Total Connections: %1 - Ĉiuj konektoj: %1 + Total Connections: {0} + Ĉiuj konektoj: {0} - Inventory lookups per second: %1 - Petoj pri inventaro en sekundo: %1 + Inventory lookups per second: {0} + Petoj pri inventaro en sekundo: {0} @@ -2240,8 +2240,8 @@ La “hazardnombra” adreso estas antaŭagordita, sed antaŭkalkuleblaj adresoj newchandialog - Successfully created / joined chan %1 - Sukcese kreis / anigis al la kanalo %1 + Successfully created / joined chan {0} + Sukcese kreis / anigis al la kanalo {0} diff --git a/src/translations/bitmessage_fr.qm b/src/translations/bitmessage_fr.qm index 8cb08a3ad728c12b465349fc4b3be1cb1c2a9230..d54bf1649533cafe0ae660f2a3a35bfb1c7d5ff5 100644 GIT binary patch delta 6280 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 diff --git a/src/translations/bitmessage_fr.ts b/src/translations/bitmessage_fr.ts index 149fd1ef..44fa0248 100644 --- a/src/translations/bitmessage_fr.ts +++ b/src/translations/bitmessage_fr.ts @@ -314,8 +314,8 @@ Please type the desired email address (including @mailchuck.com) below: - One of your addresses, %1, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? - Une de vos adresses, %1, est une vieille adresse de la version 1. Les adresses de la version 1 ne sont plus supportées. Nous pourrions la supprimer maintenant? + One of your addresses, {0}, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? + Une de vos adresses, {0}, est une vieille adresse de la version 1. Les adresses de la version 1 ne sont plus supportées. Nous pourrions la supprimer maintenant? @@ -334,13 +334,13 @@ Please type the desired email address (including @mailchuck.com) below: - Message sent. Waiting for acknowledgement. Sent at %1 - Message envoyé. En attente de l’accusé de réception. Envoyé %1 + Message sent. Waiting for acknowledgement. Sent at {0} + Message envoyé. En attente de l’accusé de réception. Envoyé {0} - Message sent. Sent at %1 - Message envoyé. Envoyé %1 + Message sent. Sent at {0} + Message envoyé. Envoyé {0} @@ -349,8 +349,8 @@ Please type the desired email address (including @mailchuck.com) below: - Acknowledgement of the message received %1 - Accusé de réception reçu %1 + Acknowledgement of the message received {0} + Accusé de réception reçu {0} @@ -359,18 +359,18 @@ Please type the desired email address (including @mailchuck.com) below: - Broadcast on %1 - Message de diffusion du %1 + Broadcast on {0} + Message de diffusion du {0} - Problem: The work demanded by the recipient is more difficult than you are willing to do. %1 - Problème : Le travail demandé par le destinataire est plus difficile que ce que vous avez paramétré. %1 + Problem: The work demanded by the recipient is more difficult than you are willing to do. {0} + Problème : Le travail demandé par le destinataire est plus difficile que ce que vous avez paramétré. {0} - Problem: The recipient's encryption key is no good. Could not encrypt message. %1 - Problème : la clé de chiffrement du destinataire n’est pas bonne. Il n’a pas été possible de chiffrer le message. %1 + Problem: The recipient's encryption key is no good. Could not encrypt message. {0} + Problème : la clé de chiffrement du destinataire n’est pas bonne. Il n’a pas été possible de chiffrer le message. {0} @@ -379,8 +379,8 @@ Please type the desired email address (including @mailchuck.com) below: - Unknown status: %1 %2 - Statut inconnu : %1 %2 + Unknown status: {0} {1} + Statut inconnu : {0} {1} @@ -420,9 +420,9 @@ Please type the desired email address (including @mailchuck.com) below: You may manage your keys by editing the keys.dat file stored in - %1 + {0} It is important that you back up this file. - Vous pouvez éditer vos clés en éditant le fichier keys.dat stocké dans le répertoire %1. + Vous pouvez éditer vos clés en éditant le fichier keys.dat stocké dans le répertoire {0}. Il est important de faire des sauvegardes de ce fichier. @@ -438,9 +438,9 @@ Il est important de faire des sauvegardes de ce fichier. You may manage your keys by editing the keys.dat file stored in - %1 + {0} 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.) - Vous pouvez éditer vos clés en éditant le fichier keys.dat stocké dans le répertoire %1. Il est important de faire des sauvegardes de ce fichier. Souhaitez-vous l’ouvrir maintenant? (Assurez-vous de fermer Bitmessage avant d’effectuer des changements.) + Vous pouvez éditer vos clés en éditant le fichier keys.dat stocké dans le répertoire {0}. Il est important de faire des sauvegardes de ce fichier. Souhaitez-vous l’ouvrir maintenant? (Assurez-vous de fermer Bitmessage avant d’effectuer des changements.) @@ -504,7 +504,7 @@ It is important that you back up this file. Would you like to open the file now? - Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: %1. This address also appears in 'Your Identities'. + Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: {0}. This address also appears in 'Your Identities'. @@ -573,52 +573,52 @@ Le destinataire doit l’obtenir avant ce temps. Si votre client Bitmessage ne r - The message that you are trying to send is too long by %1 bytes. (The maximum is 261644 bytes). Please cut it down before sending. - Le message que vous essayez d’envoyer est trop long de %1 octets (le maximum est 261644 octets). Veuillez le réduire avant de l’envoyer. + The message that you are trying to send is too long by {0} bytes. (The maximum is 261644 bytes). Please cut it down before sending. + Le message que vous essayez d’envoyer est trop long de {0} octets (le maximum est 261644 octets). Veuillez le réduire avant de l’envoyer. - Error: Your account wasn't registered at an email gateway. Sending registration now as %1, please wait for the registration to be processed before retrying sending. - Erreur : votre compte n’a pas été inscrit à une passerelle de courrier électronique. Envoi de l’inscription maintenant en tant que %1, veuillez patienter tandis que l’inscription est en cours de traitement, avant de retenter l’envoi. + Error: Your account wasn't registered at an email gateway. Sending registration now as {0}, please wait for the registration to be processed before retrying sending. + Erreur : votre compte n’a pas été inscrit à une passerelle de courrier électronique. Envoi de l’inscription maintenant en tant que {0}, veuillez patienter tandis que l’inscription est en cours de traitement, avant de retenter l’envoi. - Error: Bitmessage addresses start with BM- Please check %1 + Error: Bitmessage addresses start with BM- Please check {0} - Error: The address %1 is not typed or copied correctly. Please check it. + Error: The address {0} is not typed or copied correctly. Please check it. - Error: The address %1 contains invalid characters. Please check it. + Error: The address {0} contains invalid characters. Please check it. - Error: The address version in %1 is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. + Error: The address version in {0} is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. - Error: Some data encoded in the address %1 is too short. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is too short. There might be something wrong with the software of your acquaintance. - Error: Some data encoded in the address %1 is too long. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is too long. There might be something wrong with the software of your acquaintance. - Error: Some data encoded in the address %1 is malformed. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is malformed. There might be something wrong with the software of your acquaintance. - Error: Something is wrong with the address %1. + Error: Something is wrong with the address {0}. @@ -633,8 +633,8 @@ Le destinataire doit l’obtenir avant ce temps. Si votre client Bitmessage ne r - Concerning the address %1, Bitmessage cannot understand address version numbers of %2. Perhaps upgrade Bitmessage to the latest version. - Concernant l’adresse %1, Bitmessage ne peut pas comprendre les numéros de version de %2. Essayez de mettre à jour Bitmessage vers la dernière version. + Concerning the address {0}, Bitmessage cannot understand address version numbers of {1}. Perhaps upgrade Bitmessage to the latest version. + Concernant l’adresse {0}, Bitmessage ne peut pas comprendre les numéros de version de {1}. Essayez de mettre à jour Bitmessage vers la dernière version. @@ -643,8 +643,8 @@ Le destinataire doit l’obtenir avant ce temps. Si votre client Bitmessage ne r - Concerning the address %1, Bitmessage cannot handle stream numbers of %2. Perhaps upgrade Bitmessage to the latest version. - Concernant l’adresse %1, Bitmessage ne peut pas supporter les nombres de flux de %2. Essayez de mettre à jour Bitmessage vers la dernière version. + Concerning the address {0}, Bitmessage cannot handle stream numbers of {1}. Perhaps upgrade Bitmessage to the latest version. + Concernant l’adresse {0}, Bitmessage ne peut pas supporter les nombres de flux de {1}. Essayez de mettre à jour Bitmessage vers la dernière version. @@ -778,8 +778,8 @@ Le destinataire doit l’obtenir avant ce temps. Si votre client Bitmessage ne r - Bitmessage cannot find your address %1. Perhaps you removed it? - Bitmessage ne peut pas trouver votre adresse %1. Peut-être l’avez-vous supprimée? + Bitmessage cannot find your address {0}. Perhaps you removed it? + Bitmessage ne peut pas trouver votre adresse {0}. Peut-être l’avez-vous supprimée? @@ -936,7 +936,7 @@ Are you sure you want to delete the channel? - You are using TCP port %1. (This can be changed in the settings). + You are using TCP port {0}. (This can be changed in the settings). @@ -1131,8 +1131,8 @@ Are you sure you want to delete the channel? - Zoom level %1% - Niveau de zoom %1% + Zoom level {0}% + Niveau de zoom {0}% @@ -1146,48 +1146,48 @@ Are you sure you want to delete the channel? - Display the %1 recent broadcast(s) from this address. + Display the {0} recent broadcast(s) from this address. - New version of PyBitmessage is available: %1. Download it from https://github.com/Bitmessage/PyBitmessage/releases/latest - Une nouvelle version de PyBitmessage est disponible : %1. Veuillez la télécharger depuis https://github.com/Bitmessage/PyBitmessage/releases/latest + New version of PyBitmessage is available: {0}. Download it from https://github.com/Bitmessage/PyBitmessage/releases/latest + Une nouvelle version de PyBitmessage est disponible : {0}. Veuillez la télécharger depuis https://github.com/Bitmessage/PyBitmessage/releases/latest - Waiting for PoW to finish... %1% - En attente de la fin de la PoW… %1% + Waiting for PoW to finish... {0}% + En attente de la fin de la PoW… {0}% - Shutting down Pybitmessage... %1% - Pybitmessage en cours d’arrêt… %1% + Shutting down Pybitmessage... {0}% + Pybitmessage en cours d’arrêt… {0}% - Waiting for objects to be sent... %1% - En attente de l’envoi des objets… %1% + Waiting for objects to be sent... {0}% + En attente de l’envoi des objets… {0}% - Saving settings... %1% - Enregistrement des paramètres… %1% + Saving settings... {0}% + Enregistrement des paramètres… {0}% - Shutting down core... %1% - Cœur en cours d’arrêt… %1% + Shutting down core... {0}% + Cœur en cours d’arrêt… {0}% - Stopping notifications... %1% - Arrêt des notifications… %1% + Stopping notifications... {0}% + Arrêt des notifications… {0}% - Shutdown imminent... %1% - Arrêt imminent… %1% + Shutdown imminent... {0}% + Arrêt imminent… {0}% @@ -1201,8 +1201,8 @@ Are you sure you want to delete the channel? - Shutting down PyBitmessage... %1% - PyBitmessage en cours d’arrêt… %1% + Shutting down PyBitmessage... {0}% + PyBitmessage en cours d’arrêt… {0}% @@ -1221,13 +1221,13 @@ Are you sure you want to delete the channel? - Generating %1 new addresses. - Production de %1 nouvelles adresses. + Generating {0} new addresses. + Production de {0} nouvelles adresses. - %1 is already in 'Your Identities'. Not adding it again. - %1 est déjà dans "Vos identités". Il ne sera pas ajouté de nouveau. + {0} is already in 'Your Identities'. Not adding it again. + {0} est déjà dans "Vos identités". Il ne sera pas ajouté de nouveau. @@ -1236,7 +1236,7 @@ Are you sure you want to delete the channel? - SOCKS5 Authentication problem: %1 + SOCKS5 Authentication problem: {0} @@ -1261,8 +1261,8 @@ Are you sure you want to delete the channel? - Broadcast sent on %1 - Message de diffusion envoyé %1 + Broadcast sent on {0} + Message de diffusion envoyé {0} @@ -1281,8 +1281,8 @@ Are you sure you want to delete the channel? - Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. %1 - Problème : la destination est un dispositif mobile qui nécessite que la destination soit incluse dans le message mais ceci n’est pas autorisé dans vos paramètres. %1 + Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. {0} + Problème : la destination est un dispositif mobile qui nécessite que la destination soit incluse dans le message mais ceci n’est pas autorisé dans vos paramètres. {0} @@ -1294,19 +1294,19 @@ Il n’y a pas de difficulté requise pour les adresses version 2 comme celle-ci Doing work necessary to send message. -Receiver's required difficulty: %1 and %2 +Receiver's required difficulty: {0} and {1} Travail en cours afin d’envoyer le message. -Difficulté requise du destinataire : %1 et %2 +Difficulté requise du destinataire : {0} et {1} - Problem: The work demanded by the recipient (%1 and %2) is more difficult than you are willing to do. %3 - Problème : Le travail demandé par le destinataire (%1 and %2) est plus difficile que ce que vous avez paramétré. %3 + Problem: The work demanded by the recipient ({0} and {1}) is more difficult than you are willing to do. {2} + Problème : Le travail demandé par le destinataire ({0} and {1}) est plus difficile que ce que vous avez paramétré. {2} - Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. %1 - Problème : Vous essayez d’envoyer un message à un canal ou à vous-même mais votre clef de chiffrement n’a pas été trouvée dans le fichier keys.dat. Le message ne peut pas être chiffré. %1 + Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. {0} + Problème : Vous essayez d’envoyer un message à un canal ou à vous-même mais votre clef de chiffrement n’a pas été trouvée dans le fichier keys.dat. Le message ne peut pas être chiffré. {0} @@ -1315,8 +1315,8 @@ Difficulté requise du destinataire : %1 et %2 - Message sent. Waiting for acknowledgement. Sent on %1 - Message envoyé. En attente de l’accusé de réception. Envoyé %1 + Message sent. Waiting for acknowledgement. Sent on {0} + Message envoyé. En attente de l’accusé de réception. Envoyé {0} @@ -1330,13 +1330,13 @@ Difficulté requise du destinataire : %1 et %2 - Sending public key request. Waiting for reply. Requested at %1 - Envoi d’une demande de clef publique. En attente d’une réponse. Demandée à %1 + Sending public key request. Waiting for reply. Requested at {0} + Envoi d’une demande de clef publique. En attente d’une réponse. Demandée à {0} - UPnP port mapping established on port %1 - Transfert de port UPnP établi sur le port %1 + UPnP port mapping established on port {0} + Transfert de port UPnP établi sur le port {0} @@ -1380,13 +1380,13 @@ Difficulté requise du destinataire : %1 et %2 - The name %1 was not found. - Le nom %1 n'a pas été trouvé. + The name {0} was not found. + Le nom {0} n'a pas été trouvé. - The namecoin query failed (%1) - La requête Namecoin a échouée (%1) + The namecoin query failed ({0}) + La requête Namecoin a échouée ({0}) @@ -1395,18 +1395,18 @@ Difficulté requise du destinataire : %1 et %2 - The name %1 has no valid JSON data. - Le nom %1 n'a aucune donnée JSON valide. + The name {0} has no valid JSON data. + Le nom {0} n'a aucune donnée JSON valide. - The name %1 has no associated Bitmessage address. - Le nom %1 n'a aucune adresse Bitmessage d'associée. + The name {0} has no associated Bitmessage address. + Le nom {0} n'a aucune adresse Bitmessage d'associée. - Success! Namecoind version %1 running. - Succès ! Namecoind version %1 en cours d'exécution. + Success! Namecoind version {0} running. + Succès ! Namecoind version {0} en cours d'exécution. @@ -1470,53 +1470,53 @@ Bienvenue dans le facile et sécurisé Bitmessage - Error: Bitmessage addresses start with BM- Please check the recipient address %1 - Erreur : Les adresses Bitmessage commencent par BM- Veuillez vérifier l'adresse du destinataire %1 + Error: Bitmessage addresses start with BM- Please check the recipient address {0} + Erreur : Les adresses Bitmessage commencent par BM- Veuillez vérifier l'adresse du destinataire {0} - Error: The recipient address %1 is not typed or copied correctly. Please check it. - Erreur : L’adresse du destinataire %1 n’est pas correctement tapée ou recopiée. Veuillez la vérifier. + Error: The recipient address {0} is not typed or copied correctly. Please check it. + Erreur : L’adresse du destinataire {0} n’est pas correctement tapée ou recopiée. Veuillez la vérifier. - Error: The recipient address %1 contains invalid characters. Please check it. - Erreur : L’adresse du destinataire %1 contient des caractères invalides. Veuillez la vérifier. + Error: The recipient address {0} contains invalid characters. Please check it. + Erreur : L’adresse du destinataire {0} contient des caractères invalides. Veuillez la vérifier. - Error: The version of the recipient address %1 is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. - Erreur : la version de l’adresse destinataire %1 est trop élevée. Vous devez mettre à niveau votre logiciel Bitmessage ou alors celui de votre connaissance est plus intelligent. + Error: The version of the recipient address {0} is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. + Erreur : la version de l’adresse destinataire {0} est trop élevée. Vous devez mettre à niveau votre logiciel Bitmessage ou alors celui de votre connaissance est plus intelligent. - Error: Some data encoded in the recipient address %1 is too short. There might be something wrong with the software of your acquaintance. - Erreur : quelques données codées dans l’adresse destinataire %1 sont trop courtes. Il pourrait y avoir un soucis avec le logiciel de votre connaissance. + Error: Some data encoded in the recipient address {0} is too short. There might be something wrong with the software of your acquaintance. + Erreur : quelques données codées dans l’adresse destinataire {0} sont trop courtes. Il pourrait y avoir un soucis avec le logiciel de votre connaissance. - Error: Some data encoded in the recipient address %1 is too long. There might be something wrong with the software of your acquaintance. - Erreur : quelques données codées dans l’adresse destinataire %1 sont trop longues. Il pourrait y avoir un soucis avec le logiciel de votre connaissance. + Error: Some data encoded in the recipient address {0} is too long. There might be something wrong with the software of your acquaintance. + Erreur : quelques données codées dans l’adresse destinataire {0} sont trop longues. Il pourrait y avoir un soucis avec le logiciel de votre connaissance. - Error: Some data encoded in the recipient address %1 is malformed. There might be something wrong with the software of your acquaintance. - Erreur : quelques données codées dans l’adresse destinataire %1 sont mal formées. Il pourrait y avoir un soucis avec le logiciel de votre connaissance. + Error: Some data encoded in the recipient address {0} is malformed. There might be something wrong with the software of your acquaintance. + Erreur : quelques données codées dans l’adresse destinataire {0} sont mal formées. Il pourrait y avoir un soucis avec le logiciel de votre connaissance. - Error: Something is wrong with the recipient address %1. - Erreur : quelque chose ne va pas avec l'adresse de destinataire %1. + Error: Something is wrong with the recipient address {0}. + Erreur : quelque chose ne va pas avec l'adresse de destinataire {0}. - Error: %1 - Erreur : %1 + Error: {0} + Erreur : {0} - From %1 - De %1 + From {0} + De {0} @@ -1628,8 +1628,8 @@ Bienvenue dans le facile et sécurisé Bitmessage - The link "%1" will open in a browser. It may be a security risk, it could de-anonymise you or download malicious data. Are you sure? - Le lien "%1" s'ouvrira dans un navigateur. Cela pourrait être un risque de sécurité, cela pourrait vous désanonymiser ou télécharger des données malveillantes. Êtes-vous sûr(e) ? + The link "{0}" will open in a browser. It may be a security risk, it could de-anonymise you or download malicious data. Are you sure? + Le lien "{0}" s'ouvrira dans un navigateur. Cela pourrait être un risque de sécurité, cela pourrait vous désanonymiser ou télécharger des données malveillantes. Êtes-vous sûr(e) ? @@ -1964,8 +1964,8 @@ L’option "Nombre Aléatoire" est sélectionnée par défaut mais les - You are using TCP port %1. (This can be changed in the settings). - Vous utilisez le port TCP %1. (Ceci peut être changé dans les paramètres). + You are using TCP port {0}. (This can be changed in the settings). + Vous utilisez le port TCP {0}. (Ceci peut être changé dans les paramètres). @@ -2017,28 +2017,28 @@ L’option "Nombre Aléatoire" est sélectionnée par défaut mais les - Since startup on %1 - Démarré depuis le %1 + Since startup on {0} + Démarré depuis le {0} - Down: %1/s Total: %2 - Téléchargées : %1/s Total : %2 + Down: {0}/s Total: {1} + Téléchargées : {0}/s Total : {1} - Up: %1/s Total: %2 - Téléversées : %1/s Total : %2 + Up: {0}/s Total: {1} + Téléversées : {0}/s Total : {1} - Total Connections: %1 - Total des connexions : %1 + Total Connections: {0} + Total des connexions : {0} - Inventory lookups per second: %1 - Consultations d’inventaire par seconde : %1 + Inventory lookups per second: {0} + Consultations d’inventaire par seconde : {0} @@ -2203,8 +2203,8 @@ L’option "Nombre Aléatoire" est sélectionnée par défaut mais les newchandialog - Successfully created / joined chan %1 - Le canal %1 a été rejoint ou créé avec succès. + Successfully created / joined chan {0} + Le canal {0} a été rejoint ou créé avec succès. diff --git a/src/translations/bitmessage_it.qm b/src/translations/bitmessage_it.qm index d38e68bcbefa8b2931e7cd8aa7d982c5c33a8a48..8b2e991529957789d98dd66a9869c2332225a637 100644 GIT binary patch delta 1198 zcmY*XdrVVz6#j1SqmNstAfm!d%d|i{Xesh4PvvQ{ftxU$Zs8H=1m@a=V#Xs_5;NCq z1R)pE2;q@18OX!Q1`&+gBH1R}I?T+>7M94EI41&&Y%vV79ptb5aqqdm-#zC$-}$~X z*U9v@F-?KS6dAxZ1Ho4Tei(@Q8p!(!FwO(78|nNAC`|_r6f|dOT}9vB{AiOfU~5w-YB(Tvu$MRwxh zW55t6>n!{Y(7I)p9E29UTh@F37SXMc-L1O`q?gJbw{9m|iLAPTCzLN)U3)SRbDxcI zoC5Y)*^c~oY3!ryxO$TEjqKEUIvc=xzRhTz;WWD%fyAwxrr>?RmHL!R8cPRK z&75u6MEZ?$@2sZ*v2mO`rUwYi<1U|NXxuB@fPsLbeYk{7Xn0tdZp>X4a zfZ5F$yS5pv$K=z8^8q1B{vc%zF6-RHhP=12q`UF{EI;WWWh$J`9DE;Ph z$@oHLVDDd)*C>UvAwk8;_EFla|Qu%w{8W}RLQn{>j-zc4AwJwXww(t^> z{6IC7yh`@nR9zESXy_Hy=N_s~a*N7p8cJU-2Cv+p-V0*WXFrpgM)BegoZm-@B3w`k40)h#IjcA~A$oq&+nhG| zytl`^6R8&fO)YV4RNgtd2Mv6_#GR9lVvsn0Nb&}gM8(4eLZqqs5 z)Kxo9R_KaKN-7A#<_y~?8aW;LkA^Wxu2h5m|Bd|f9F;{UbZHK|-Bw&#=CC{CpLOxs RzkOsjbyOvH6B`-B{0A6jN8tbf delta 1618 zcmaJ=4@{J082^2D-*@occgN8M9_i|i;vn$&bEv=}g7Qal1tk!aChj;c?%=#L?qjDo zIMcadQouenCq%kYrh=51Ofa*w*=*rl4p*zCV_F$1O=_k#d+>nS)Sm6W=g<2-zvuTn z&wG2?nUVLI)>(0xe*b|vXnyjWciEE-4AnxgP7sNeva8#5R6IkjYUb$fXL3VFCXn*8JjK%pEKHJjmT#iwO63EplXO2) z>S1*LVOI0xJ3xk-)vSCA$iB`l=+7k`&DwhtXe6JozJGFn)MU0Pr3)}EW%su*)WOGW zcdQ+lC$Qb756HjB_HHZ#GEcC59bptNXTKPYB^)1na;*_Cj&Z4DJE&ucvz(^UrZ;iv z4(cR*PCNJfg>%$;1XtepDUck+ZCp>li%s0l8(tu*hih-5#H2&qp_eHk<`-_DiijnP zQiDuq=~8t4c!oBct>_P;th9Q?xqUSGJd@(5Qo5CMJV@J08!^2Xl&Tz}Hfw_lz9*fe zl)jbe_`iboH;(|866vZ;XC4oJ_1IRxFhBU{APp{|CHVA5G^oU3KJ0QaEoB)$YtNsA zy@`+h<_{n?O^TPtM6TdF4%6;4XY;!Kt) zYLKCEnlApSBmJwkqUhHQii9=qHz!rRBrVA(Jjh*pmdTW^$Imw!VGgFh z3>5T>D6o6I)+)QfYj=wYhGO~}tfIkamYBq_zSk4RWQ;7-?O8QFyMa7@Dh(`bs2IzZnxbgIz4W0`UK$JEM4D~?88cbBDJv)?^5*% zp{IMFOc2xD=LgJ)>Bv*l)`USVlbG&(ANHYbKPY}Ic`*3MNYUg8?P6LgrY+Y!>y2rD z%2+pLJVevu|37*2(T8fcUG#ZsYrLXWtn-rR%W+uUxlXIgQx#fh_bsZdtfh4Z0uZbf zo;oq$C>?g!>dCk!#A_Etr@LzMqI4#AmUL9m`w>b2|Ha@7tWKBBQD>_OC;Z~N3a_o! zxq4!!0Whu8=5gn{JoJWY*G}T|6)vl-#^v;i+Pqbio^KWHKI_z}k`UcxPIslp2Q?*6 PJdr?RP!n}7W0-#d - One of your addresses, %1, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? - Uno dei tuoi indirizzi, %1, è un indirizzo vecchio versione 1. Gli indirizzi versione 1 non sono più supportati. Posso eliminarlo ora? + One of your addresses, {0}, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? + Uno dei tuoi indirizzi, {0}, è un indirizzo vecchio versione 1. Gli indirizzi versione 1 non sono più supportati. Posso eliminarlo ora? @@ -299,13 +299,13 @@ Il gateway email non condurrà operazioni PGP a vostro nome. È possibile - Message sent. Waiting for acknowledgement. Sent at %1 + Message sent. Waiting for acknowledgement. Sent at {0} - Message sent. Sent at %1 - Messaggio inviato. Inviato a %1 + Message sent. Sent at {0} + Messaggio inviato. Inviato a {0} @@ -314,7 +314,7 @@ Il gateway email non condurrà operazioni PGP a vostro nome. È possibile - Acknowledgement of the message received %1 + Acknowledgement of the message received {0} @@ -324,17 +324,17 @@ Il gateway email non condurrà operazioni PGP a vostro nome. È possibile - Broadcast on %1 + Broadcast on {0} - Problem: The work demanded by the recipient is more difficult than you are willing to do. %1 + Problem: The work demanded by the recipient is more difficult than you are willing to do. {0} - Problem: The recipient's encryption key is no good. Could not encrypt message. %1 + Problem: The recipient's encryption key is no good. Could not encrypt message. {0} @@ -344,7 +344,7 @@ Il gateway email non condurrà operazioni PGP a vostro nome. È possibile - Unknown status: %1 %2 + Unknown status: {0} {1} @@ -385,7 +385,7 @@ Il gateway email non condurrà operazioni PGP a vostro nome. È possibile You may manage your keys by editing the keys.dat file stored in - %1 + {0} It is important that you back up this file. @@ -402,7 +402,7 @@ It is important that you back up this file. You may manage your keys by editing the keys.dat file stored in - %1 + {0} 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.) @@ -468,7 +468,7 @@ It is important that you back up this file. Would you like to open the file now? - Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: %1. This address also appears in 'Your Identities'. + Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: {0}. This address also appears in 'Your Identities'. @@ -536,52 +536,52 @@ It is important that you back up this file. Would you like to open the file now? - The message that you are trying to send is too long by %1 bytes. (The maximum is 261644 bytes). Please cut it down before sending. + The message that you are trying to send is too long by {0} bytes. (The maximum is 261644 bytes). Please cut it down before sending. - Error: Your account wasn't registered at an email gateway. Sending registration now as %1, please wait for the registration to be processed before retrying sending. + Error: Your account wasn't registered at an email gateway. Sending registration now as {0}, please wait for the registration to be processed before retrying sending. - Error: Bitmessage addresses start with BM- Please check %1 + Error: Bitmessage addresses start with BM- Please check {0} - Error: The address %1 is not typed or copied correctly. Please check it. + Error: The address {0} is not typed or copied correctly. Please check it. - Error: The address %1 contains invalid characters. Please check it. + Error: The address {0} contains invalid characters. Please check it. - Error: The address version in %1 is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. + Error: The address version in {0} is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. - Error: Some data encoded in the address %1 is too short. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is too short. There might be something wrong with the software of your acquaintance. - Error: Some data encoded in the address %1 is too long. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is too long. There might be something wrong with the software of your acquaintance. - Error: Some data encoded in the address %1 is malformed. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is malformed. There might be something wrong with the software of your acquaintance. - Error: Something is wrong with the address %1. + Error: Something is wrong with the address {0}. @@ -596,7 +596,7 @@ It is important that you back up this file. Would you like to open the file now? - Concerning the address %1, Bitmessage cannot understand address version numbers of %2. Perhaps upgrade Bitmessage to the latest version. + Concerning the address {0}, Bitmessage cannot understand address version numbers of {1}. Perhaps upgrade Bitmessage to the latest version. @@ -606,7 +606,7 @@ It is important that you back up this file. Would you like to open the file now? - Concerning the address %1, Bitmessage cannot handle stream numbers of %2. Perhaps upgrade Bitmessage to the latest version. + Concerning the address {0}, Bitmessage cannot handle stream numbers of {1}. Perhaps upgrade Bitmessage to the latest version. @@ -741,7 +741,7 @@ It is important that you back up this file. Would you like to open the file now? - Bitmessage cannot find your address %1. Perhaps you removed it? + Bitmessage cannot find your address {0}. Perhaps you removed it? @@ -895,7 +895,7 @@ Are you sure you want to delete the channel? - You are using TCP port %1. (This can be changed in the settings). + You are using TCP port {0}. (This can be changed in the settings). @@ -1090,7 +1090,7 @@ Are you sure you want to delete the channel? - Zoom level %1% + Zoom level {0}% @@ -1105,47 +1105,47 @@ Are you sure you want to delete the channel? - Display the %1 recent broadcast(s) from this address. + Display the {0} recent broadcast(s) from this address. - New version of PyBitmessage is available: %1. Download it from https://github.com/Bitmessage/PyBitmessage/releases/latest + New version of PyBitmessage is available: {0}. Download it from https://github.com/Bitmessage/PyBitmessage/releases/latest - Waiting for PoW to finish... %1% + Waiting for PoW to finish... {0}% - Shutting down Pybitmessage... %1% + Shutting down Pybitmessage... {0}% - Waiting for objects to be sent... %1% + Waiting for objects to be sent... {0}% - Saving settings... %1% + Saving settings... {0}% - Shutting down core... %1% + Shutting down core... {0}% - Stopping notifications... %1% + Stopping notifications... {0}% - Shutdown imminent... %1% + Shutdown imminent... {0}% @@ -1166,7 +1166,7 @@ Are you sure you want to delete the channel? - Shutting down PyBitmessage... %1% + Shutting down PyBitmessage... {0}% @@ -1186,12 +1186,12 @@ Are you sure you want to delete the channel? - Generating %1 new addresses. + Generating {0} new addresses. - %1 is already in 'Your Identities'. Not adding it again. + {0} is already in 'Your Identities'. Not adding it again. @@ -1201,7 +1201,7 @@ Are you sure you want to delete the channel? - SOCKS5 Authentication problem: %1 + SOCKS5 Authentication problem: {0} @@ -1226,7 +1226,7 @@ Are you sure you want to delete the channel? - Broadcast sent on %1 + Broadcast sent on {0} @@ -1246,7 +1246,7 @@ Are you sure you want to delete the channel? - Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. %1 + Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. {0} @@ -1258,17 +1258,17 @@ There is no required difficulty for version 2 addresses like this. Doing work necessary to send message. -Receiver's required difficulty: %1 and %2 +Receiver's required difficulty: {0} and {1} - Problem: The work demanded by the recipient (%1 and %2) is more difficult than you are willing to do. %3 + Problem: The work demanded by the recipient ({0} and {1}) is more difficult than you are willing to do. {2} - Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. %1 + Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. {0} @@ -1278,7 +1278,7 @@ Receiver's required difficulty: %1 and %2 - Message sent. Waiting for acknowledgement. Sent on %1 + Message sent. Waiting for acknowledgement. Sent on {0} @@ -1293,12 +1293,12 @@ Receiver's required difficulty: %1 and %2 - Sending public key request. Waiting for reply. Requested at %1 + Sending public key request. Waiting for reply. Requested at {0} - UPnP port mapping established on port %1 + UPnP port mapping established on port {0} @@ -1660,27 +1660,27 @@ The 'Random Number' option is selected by default but deterministic ad - Since startup on %1 + Since startup on {0} - Down: %1/s Total: %2 + Down: {0}/s Total: {1} - Up: %1/s Total: %2 + Up: {0}/s Total: {1} - Total Connections: %1 - Connessioni totali: %1 + Total Connections: {0} + Connessioni totali: {0} - Inventory lookups per second: %1 + Inventory lookups per second: {0} diff --git a/src/translations/bitmessage_ja.qm b/src/translations/bitmessage_ja.qm index 77fa63d1a56a57cc9ccf7027e4239bd296202a80..8637aa2e127307a220983e1c4b545ed2d0b9f72b 100644 GIT binary patch delta 6170 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 diff --git a/src/translations/bitmessage_ja.ts b/src/translations/bitmessage_ja.ts index f11289f5..2b1ebe97 100644 --- a/src/translations/bitmessage_ja.ts +++ b/src/translations/bitmessage_ja.ts @@ -352,8 +352,8 @@ Please type the desired email address (including @mailchuck.com) below: - One of your addresses, %1, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? - %1は古いバージョン1のアドレスです。バージョン1のアドレスはサポートが終了しています。すぐに削除しますか? + One of your addresses, {0}, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? + {0}は古いバージョン1のアドレスです。バージョン1のアドレスはサポートが終了しています。すぐに削除しますか? @@ -372,13 +372,13 @@ Please type the desired email address (including @mailchuck.com) below: - Message sent. Waiting for acknowledgement. Sent at %1 - メッセージを送信しました。 確認応答を待っています。 %1 で送信されました + Message sent. Waiting for acknowledgement. Sent at {0} + メッセージを送信しました。 確認応答を待っています。 {0} で送信されました - Message sent. Sent at %1 - メッセージは送信されました。送信先: %1 + Message sent. Sent at {0} + メッセージは送信されました。送信先: {0} @@ -387,8 +387,8 @@ Please type the desired email address (including @mailchuck.com) below: - Acknowledgement of the message received %1 - メッセージの確認を受け取りました %1 + Acknowledgement of the message received {0} + メッセージの確認を受け取りました {0} @@ -397,18 +397,18 @@ Please type the desired email address (including @mailchuck.com) below: - Broadcast on %1 - 配信: %1 + Broadcast on {0} + 配信: {0} - Problem: The work demanded by the recipient is more difficult than you are willing to do. %1 - 問題: 受信者が要求している処理は現在あなたが設定しているよりも高い難易度です。 %1 + Problem: The work demanded by the recipient is more difficult than you are willing to do. {0} + 問題: 受信者が要求している処理は現在あなたが設定しているよりも高い難易度です。 {0} - Problem: The recipient's encryption key is no good. Could not encrypt message. %1 - 問題: 受信者の暗号鍵は正当でない物です。メッセージを暗号化できません。 %1 + Problem: The recipient's encryption key is no good. Could not encrypt message. {0} + 問題: 受信者の暗号鍵は正当でない物です。メッセージを暗号化できません。 {0} @@ -417,8 +417,8 @@ Please type the desired email address (including @mailchuck.com) below: - Unknown status: %1 %2 - 不明なステータス: %1 %2 + Unknown status: {0} {1} + 不明なステータス: {0} {1} @@ -458,9 +458,9 @@ Please type the desired email address (including @mailchuck.com) below: You may manage your keys by editing the keys.dat file stored in - %1 + {0} It is important that you back up this file. - %1 + {0} に保存されているkeys.datファイルを編集することで鍵を管理できます。 このファイルをバックアップしておくことは重要です。 @@ -477,9 +477,9 @@ It is important that you back up this file. You may manage your keys by editing the keys.dat file stored in - %1 + {0} 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.) - %1 + {0} に保存されているkeys.datファイルを編集することで鍵を管理できます。 ファイルをバックアップしておくことは重要です。すぐにファイルを開きますか?(必ず編集する前にBitmessageを終了してください) @@ -545,7 +545,7 @@ It is important that you back up this file. Would you like to open the file now? - Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: %1. This address also appears in 'Your Identities'. + Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: {0}. This address also appears in 'Your Identities'. @@ -616,52 +616,52 @@ It is important that you back up this file. Would you like to open the file now? - The message that you are trying to send is too long by %1 bytes. (The maximum is 261644 bytes). Please cut it down before sending. - 送信しようとしているメッセージが %1 バイト長すぎます。 (最大は261644バイトです)。 送信する前に短くしてください。 + The message that you are trying to send is too long by {0} bytes. (The maximum is 261644 bytes). Please cut it down before sending. + 送信しようとしているメッセージが {0} バイト長すぎます。 (最大は261644バイトです)。 送信する前に短くしてください。 - Error: Your account wasn't registered at an email gateway. Sending registration now as %1, please wait for the registration to be processed before retrying sending. - エラー: アカウントがメールゲートウェイに登録されていません。 今 %1 として登録を送信しています。送信を再試行する前に、登録が処理されるのをお待ちください。 + Error: Your account wasn't registered at an email gateway. Sending registration now as {0}, please wait for the registration to be processed before retrying sending. + エラー: アカウントがメールゲートウェイに登録されていません。 今 {0} として登録を送信しています。送信を再試行する前に、登録が処理されるのをお待ちください。 - Error: Bitmessage addresses start with BM- Please check %1 + Error: Bitmessage addresses start with BM- Please check {0} - Error: The address %1 is not typed or copied correctly. Please check it. + Error: The address {0} is not typed or copied correctly. Please check it. - Error: The address %1 contains invalid characters. Please check it. + Error: The address {0} contains invalid characters. Please check it. - Error: The address version in %1 is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. + Error: The address version in {0} is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. - Error: Some data encoded in the address %1 is too short. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is too short. There might be something wrong with the software of your acquaintance. - Error: Some data encoded in the address %1 is too long. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is too long. There might be something wrong with the software of your acquaintance. - Error: Some data encoded in the address %1 is malformed. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is malformed. There might be something wrong with the software of your acquaintance. - Error: Something is wrong with the address %1. + Error: Something is wrong with the address {0}. @@ -676,8 +676,8 @@ It is important that you back up this file. Would you like to open the file now? - Concerning the address %1, Bitmessage cannot understand address version numbers of %2. Perhaps upgrade Bitmessage to the latest version. - アドレス %1 に接続しています。%2 のバージョン番号は処理できません。Bitmessageを最新のバージョンへアップデートしてください。 + Concerning the address {0}, Bitmessage cannot understand address version numbers of {1}. Perhaps upgrade Bitmessage to the latest version. + アドレス {0} に接続しています。{1} のバージョン番号は処理できません。Bitmessageを最新のバージョンへアップデートしてください。 @@ -686,8 +686,8 @@ It is important that you back up this file. Would you like to open the file now? - Concerning the address %1, Bitmessage cannot handle stream numbers of %2. Perhaps upgrade Bitmessage to the latest version. - アドレス %1 に接続しています。%2 のストリーム番号は処理できません。Bitmessageを最新のバージョンへアップデートしてください。 + Concerning the address {0}, Bitmessage cannot handle stream numbers of {1}. Perhaps upgrade Bitmessage to the latest version. + アドレス {0} に接続しています。{1} のストリーム番号は処理できません。Bitmessageを最新のバージョンへアップデートしてください。 @@ -821,8 +821,8 @@ It is important that you back up this file. Would you like to open the file now? - Bitmessage cannot find your address %1. Perhaps you removed it? - アドレス %1 が見つかりません。既に削除していませんか? + Bitmessage cannot find your address {0}. Perhaps you removed it? + アドレス {0} が見つかりません。既に削除していませんか? @@ -979,7 +979,7 @@ Are you sure you want to delete the channel? - You are using TCP port %1. (This can be changed in the settings). + You are using TCP port {0}. (This can be changed in the settings). @@ -1174,8 +1174,8 @@ Are you sure you want to delete the channel? - Zoom level %1% - ズーム レベル %1% + Zoom level {0}% + ズーム レベル {0}% @@ -1189,48 +1189,48 @@ Are you sure you want to delete the channel? - Display the %1 recent broadcast(s) from this address. + Display the {0} recent broadcast(s) from this address. - New version of PyBitmessage is available: %1. Download it from https://github.com/Bitmessage/PyBitmessage/releases/latest - 新しいバージョンの PyBitmessage が利用可能です: %1。 https://github.com/Bitmessage/PyBitmessage/releases/latest からダウンロードしてください + New version of PyBitmessage is available: {0}. Download it from https://github.com/Bitmessage/PyBitmessage/releases/latest + 新しいバージョンの PyBitmessage が利用可能です: {0}。 https://github.com/Bitmessage/PyBitmessage/releases/latest からダウンロードしてください - Waiting for PoW to finish... %1% - PoW(プルーフオブワーク)が完了するのを待っています... %1% + Waiting for PoW to finish... {0}% + PoW(プルーフオブワーク)が完了するのを待っています... {0}% - Shutting down Pybitmessage... %1% - Pybitmessageをシャットダウンしています... %1% + Shutting down Pybitmessage... {0}% + Pybitmessageをシャットダウンしています... {0}% - Waiting for objects to be sent... %1% - オブジェクトの送信待ち... %1% + Waiting for objects to be sent... {0}% + オブジェクトの送信待ち... {0}% - Saving settings... %1% - 設定を保存しています... %1% + Saving settings... {0}% + 設定を保存しています... {0}% - Shutting down core... %1% - コアをシャットダウンしています... %1% + Shutting down core... {0}% + コアをシャットダウンしています... {0}% - Stopping notifications... %1% - 通知を停止しています... %1% + Stopping notifications... {0}% + 通知を停止しています... {0}% - Shutdown imminent... %1% - すぐにシャットダウンします... %1% + Shutdown imminent... {0}% + すぐにシャットダウンします... {0}% @@ -1244,8 +1244,8 @@ Are you sure you want to delete the channel? - Shutting down PyBitmessage... %1% - PyBitmessageをシャットダウンしています... %1% + Shutting down PyBitmessage... {0}% + PyBitmessageをシャットダウンしています... {0}% @@ -1264,13 +1264,13 @@ Are you sure you want to delete the channel? - Generating %1 new addresses. - %1 の新しいアドレスを生成しています。 + Generating {0} new addresses. + {0} の新しいアドレスを生成しています。 - %1 is already in 'Your Identities'. Not adding it again. - %1はすでに「アドレス一覧」にあります。 もう一度追加できません。 + {0} is already in 'Your Identities'. Not adding it again. + {0}はすでに「アドレス一覧」にあります。 もう一度追加できません。 @@ -1279,7 +1279,7 @@ Are you sure you want to delete the channel? - SOCKS5 Authentication problem: %1 + SOCKS5 Authentication problem: {0} @@ -1304,8 +1304,8 @@ Are you sure you want to delete the channel? - Broadcast sent on %1 - 配信が送信されました %1 + Broadcast sent on {0} + 配信が送信されました {0} @@ -1324,8 +1324,8 @@ Are you sure you want to delete the channel? - Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. %1 - 問題: メッセージに含まれた宛先のリクエストはモバイルデバイスですが、設定では許可されていません。 %1 + Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. {0} + 問題: メッセージに含まれた宛先のリクエストはモバイルデバイスですが、設定では許可されていません。 {0} @@ -1337,18 +1337,18 @@ There is no required difficulty for version 2 addresses like this. Doing work necessary to send message. -Receiver's required difficulty: %1 and %2 +Receiver's required difficulty: {0} and {1} メッセージの送信に必要な処理を行っています。 -受信者の必要な難易度: %1 および %2 +受信者の必要な難易度: {0} および {1} - Problem: The work demanded by the recipient (%1 and %2) is more difficult than you are willing to do. %3 - 問題: 受信者が要求している処理 (%1 および %2) は、現在あなたが設定しているよりも高い難易度です。 %3 + Problem: The work demanded by the recipient ({0} and {1}) is more difficult than you are willing to do. {2} + 問題: 受信者が要求している処理 ({0} および {1}) は、現在あなたが設定しているよりも高い難易度です。 {2} - Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. %1 + Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. {0} 問題: あなた自身またはチャンネルにメッセージを送信しようとしていますが、暗号鍵がkeys.datファイルに見つかりませんでした。 メッセージを暗号化できませんでした。 %1 @@ -1358,8 +1358,8 @@ Receiver's required difficulty: %1 and %2 - Message sent. Waiting for acknowledgement. Sent on %1 - メッセージを送信しました。 確認応答を待っています。 %1 で送信しました + Message sent. Waiting for acknowledgement. Sent on {0} + メッセージを送信しました。 確認応答を待っています。 {0} で送信しました @@ -1373,13 +1373,13 @@ Receiver's required difficulty: %1 and %2 - Sending public key request. Waiting for reply. Requested at %1 - 公開鍵のリクエストを送信しています。 返信を待っています。 %1 でリクエストしました + Sending public key request. Waiting for reply. Requested at {0} + 公開鍵のリクエストを送信しています。 返信を待っています。 {0} でリクエストしました - UPnP port mapping established on port %1 - ポート%1でUPnPポートマッピングが確立しました + UPnP port mapping established on port {0} + ポート{0}でUPnPポートマッピングが確立しました @@ -1423,18 +1423,18 @@ Receiver's required difficulty: %1 and %2 - The name %1 was not found. - 名前 %1 が見つかりませんでした。 + The name {0} was not found. + 名前 {0} が見つかりませんでした。 - The namecoin query failed (%1) - namecoin のクエリに失敗しました (%1) + The namecoin query failed ({0}) + namecoin のクエリに失敗しました ({0}) - Unknown namecoin interface type: %1 - 不明な namecoin インターフェースタイプ: %1 + Unknown namecoin interface type: {0} + 不明な namecoin インターフェースタイプ: {0} @@ -1443,13 +1443,13 @@ Receiver's required difficulty: %1 and %2 - The name %1 has no associated Bitmessage address. - 名前 %1 は関連付けられた Bitmessage アドレスがありません。 + The name {0} has no associated Bitmessage address. + 名前 {0} は関連付けられた Bitmessage アドレスがありません。 - Success! Namecoind version %1 running. - 成功! Namecoind バージョン %1 が実行中。 + Success! Namecoind version {0} running. + 成功! Namecoind バージョン {0} が実行中。 @@ -1513,53 +1513,53 @@ Receiver's required difficulty: %1 and %2 - Error: Bitmessage addresses start with BM- Please check the recipient address %1 - エラー: BitmessageのアドレスはBM-で始まります。 受信者のアドレス %1 を確認してください + Error: Bitmessage addresses start with BM- Please check the recipient address {0} + エラー: BitmessageのアドレスはBM-で始まります。 受信者のアドレス {0} を確認してください - Error: The recipient address %1 is not typed or copied correctly. Please check it. - エラー: 受信者のアドレス %1 は正しく入力、またはコピーされていません。確認して下さい。 + Error: The recipient address {0} is not typed or copied correctly. Please check it. + エラー: 受信者のアドレス {0} は正しく入力、またはコピーされていません。確認して下さい。 - Error: The recipient address %1 contains invalid characters. Please check it. - エラー: 受信者のアドレス %1 は不正な文字を含んでいます。確認して下さい。 + Error: The recipient address {0} contains invalid characters. Please check it. + エラー: 受信者のアドレス {0} は不正な文字を含んでいます。確認して下さい。 - Error: The version of the recipient address %1 is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. - エラー: 受信者アドレスのバージョン %1 は高すぎます。 Bitmessageソフトウェアをアップグレードする必要があるか、連絡先が賢明になっているかのいずれかです。 + Error: The version of the recipient address {0} is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. + エラー: 受信者アドレスのバージョン {0} は高すぎます。 Bitmessageソフトウェアをアップグレードする必要があるか、連絡先が賢明になっているかのいずれかです。 - Error: Some data encoded in the recipient address %1 is too short. There might be something wrong with the software of your acquaintance. - エラー: アドレス %1 でエンコードされたデータが短すぎます。連絡先のソフトウェアが何かしら誤っている可能性があります。 + Error: Some data encoded in the recipient address {0} is too short. There might be something wrong with the software of your acquaintance. + エラー: アドレス {0} でエンコードされたデータが短すぎます。連絡先のソフトウェアが何かしら誤っている可能性があります。 - Error: Some data encoded in the recipient address %1 is too long. There might be something wrong with the software of your acquaintance. - エラー: 受信者のアドレス %1 でエンコードされたデータが短すぎます。連絡先のソフトウェアが何かしら誤っている可能性があります。 + Error: Some data encoded in the recipient address {0} is too long. There might be something wrong with the software of your acquaintance. + エラー: 受信者のアドレス {0} でエンコードされたデータが短すぎます。連絡先のソフトウェアが何かしら誤っている可能性があります。 - Error: Some data encoded in the recipient address %1 is malformed. There might be something wrong with the software of your acquaintance. - エラー: 受信者のアドレス %1 でエンコードされたデータの一部が不正です。連絡先のソフトウェアが何かしら誤っている可能性があります。 + Error: Some data encoded in the recipient address {0} is malformed. There might be something wrong with the software of your acquaintance. + エラー: 受信者のアドレス {0} でエンコードされたデータの一部が不正です。連絡先のソフトウェアが何かしら誤っている可能性があります。 - Error: Something is wrong with the recipient address %1. - エラー: 受信者のアドレス %1 には何かしら誤りがあります。 + Error: Something is wrong with the recipient address {0}. + エラー: 受信者のアドレス {0} には何かしら誤りがあります。 - Error: %1 - エラー: %1 + Error: {0} + エラー: {0} - From %1 - 送信元 %1 + From {0} + 送信元 {0} @@ -1671,8 +1671,8 @@ Receiver's required difficulty: %1 and %2 - The link "%1" will open in a browser. It may be a security risk, it could de-anonymise you or download malicious data. Are you sure? - リンク "%1" はブラウザで開きます。 セキュリティリスクの可能性があります。匿名性がなくなったり、悪意のあるデータをダウンロードする可能性があります。 よろしいですか? + The link "{0}" will open in a browser. It may be a security risk, it could de-anonymise you or download malicious data. Are you sure? + リンク "{0}" はブラウザで開きます。 セキュリティリスクの可能性があります。匿名性がなくなったり、悪意のあるデータをダウンロードする可能性があります。 よろしいですか? @@ -2006,8 +2006,8 @@ The 'Random Number' option is selected by default but deterministic ad - You are using TCP port %1. (This can be changed in the settings). - 使用中のポート %1 (設定で変更できます)。 + You are using TCP port {0}. (This can be changed in the settings). + 使用中のポート {0} (設定で変更できます)。 @@ -2059,28 +2059,28 @@ The 'Random Number' option is selected by default but deterministic ad - Since startup on %1 - 起動日時 %1 + Since startup on {0} + 起動日時 {0} - Down: %1/s Total: %2 - ダウン: %1/秒 合計: %2 + Down: {0}/s Total: {1} + ダウン: {0}/秒 合計: {1} - Up: %1/s Total: %2 - アップ: %1/秒 合計: %2 + Up: {0}/s Total: {1} + アップ: {0}/秒 合計: {1} - Total Connections: %1 - 接続数: %1 + Total Connections: {0} + 接続数: {0} - Inventory lookups per second: %1 - 毎秒のインベントリ検索: %1 + Inventory lookups per second: {0} + 毎秒のインベントリ検索: {0} @@ -2245,8 +2245,8 @@ The 'Random Number' option is selected by default but deterministic ad newchandialog - Successfully created / joined chan %1 - チャンネル %1 を正常に作成 / 参加しました + Successfully created / joined chan {0} + チャンネル {0} を正常に作成 / 参加しました diff --git a/src/translations/bitmessage_nb.ts b/src/translations/bitmessage_nb.ts index 21f641c0..0ee74d6a 100644 --- a/src/translations/bitmessage_nb.ts +++ b/src/translations/bitmessage_nb.ts @@ -240,7 +240,7 @@ Please type the desired email address (including @mailchuck.com) below: - One of your addresses, %1, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? + One of your addresses, {0}, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? @@ -250,12 +250,12 @@ Please type the desired email address (including @mailchuck.com) below: - %1 hours + {0} hours - %1 days + {0} days @@ -275,12 +275,12 @@ Please type the desired email address (including @mailchuck.com) below: - Message sent. Waiting for acknowledgement. Sent at %1 + Message sent. Waiting for acknowledgement. Sent at {0} - Message sent. Sent at %1 + Message sent. Sent at {0} @@ -290,7 +290,7 @@ Please type the desired email address (including @mailchuck.com) below: - Acknowledgement of the message received %1 + Acknowledgement of the message received {0} @@ -300,17 +300,17 @@ Please type the desired email address (including @mailchuck.com) below: - Broadcast on %1 + Broadcast on {0} - Problem: The work demanded by the recipient is more difficult than you are willing to do. %1 + Problem: The work demanded by the recipient is more difficult than you are willing to do. {0} - Problem: The recipient's encryption key is no good. Could not encrypt message. %1 + Problem: The recipient's encryption key is no good. Could not encrypt message. {0} @@ -320,7 +320,7 @@ Please type the desired email address (including @mailchuck.com) below: - Unknown status: %1 %2 + Unknown status: {0} {1} @@ -361,7 +361,7 @@ Please type the desired email address (including @mailchuck.com) below: You may manage your keys by editing the keys.dat file stored in - %1 + {0} It is important that you back up this file. @@ -378,7 +378,7 @@ It is important that you back up this file. You may manage your keys by editing the keys.dat file stored in - %1 + {0} 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.) @@ -444,7 +444,7 @@ It is important that you back up this file. Would you like to open the file now? - Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: %1. This address also appears in 'Your Identities'. + Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: {0}. This address also appears in 'Your Identities'. @@ -512,52 +512,52 @@ It is important that you back up this file. Would you like to open the file now? - The message that you are trying to send is too long by %1 bytes. (The maximum is 261644 bytes). Please cut it down before sending. + The message that you are trying to send is too long by {0} bytes. (The maximum is 261644 bytes). Please cut it down before sending. - Error: Your account wasn't registered at an email gateway. Sending registration now as %1, please wait for the registration to be processed before retrying sending. + Error: Your account wasn't registered at an email gateway. Sending registration now as {0}, please wait for the registration to be processed before retrying sending. - Error: Bitmessage addresses start with BM- Please check %1 + Error: Bitmessage addresses start with BM- Please check {0} - Error: The address %1 is not typed or copied correctly. Please check it. + Error: The address {0} is not typed or copied correctly. Please check it. - Error: The address %1 contains invalid characters. Please check it. + Error: The address {0} contains invalid characters. Please check it. - Error: The address version in %1 is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. + Error: The address version in {0} is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. - Error: Some data encoded in the address %1 is too short. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is too short. There might be something wrong with the software of your acquaintance. - Error: Some data encoded in the address %1 is too long. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is too long. There might be something wrong with the software of your acquaintance. - Error: Some data encoded in the address %1 is malformed. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is malformed. There might be something wrong with the software of your acquaintance. - Error: Something is wrong with the address %1. + Error: Something is wrong with the address {0}. @@ -572,7 +572,7 @@ It is important that you back up this file. Would you like to open the file now? - Concerning the address %1, Bitmessage cannot understand address version numbers of %2. Perhaps upgrade Bitmessage to the latest version. + Concerning the address {0}, Bitmessage cannot understand address version numbers of {1}. Perhaps upgrade Bitmessage to the latest version. @@ -582,7 +582,7 @@ It is important that you back up this file. Would you like to open the file now? - Concerning the address %1, Bitmessage cannot handle stream numbers of %2. Perhaps upgrade Bitmessage to the latest version. + Concerning the address {0}, Bitmessage cannot handle stream numbers of {1}. Perhaps upgrade Bitmessage to the latest version. @@ -722,7 +722,7 @@ It is important that you back up this file. Would you like to open the file now? - Bitmessage cannot find your address %1. Perhaps you removed it? + Bitmessage cannot find your address {0}. Perhaps you removed it? @@ -876,7 +876,7 @@ Are you sure you want to delete the channel? - You are using TCP port %1. (This can be changed in the settings). + You are using TCP port {0}. (This can be changed in the settings). @@ -1081,7 +1081,7 @@ Are you sure you want to delete the channel? - Zoom level %1% + Zoom level {0}% @@ -1096,7 +1096,7 @@ Are you sure you want to delete the channel? - Display the %1 recent broadcast(s) from this address. + Display the {0} recent broadcast(s) from this address. @@ -1449,47 +1449,47 @@ The 'Random Number' option is selected by default but deterministic ad - Since startup on %1 + Since startup on {0} - Objects to be synced: %1 + Objects to be synced: {0} - Processed %1 person-to-person messages. + Processed {0} person-to-person messages. - Processed %1 broadcast messages. + Processed {0} broadcast messages. - Processed %1 public keys. + Processed {0} public keys. - Down: %1/s Total: %2 + Down: {0}/s Total: {1} - Up: %1/s Total: %2 + Up: {0}/s Total: {1} - Total Connections: %1 + Total Connections: {0} - Inventory lookups per second: %1 + Inventory lookups per second: {0} diff --git a/src/translations/bitmessage_nl.qm b/src/translations/bitmessage_nl.qm index 72a7ade246f4d25a7a10aafa654fa76faccfbfa6..94ba152484a43c901f5f47efd3270b39da63a5c8 100644 GIT binary patch delta 1180 zcmZ8feN0t#7=F$@ANQVn&*1{Xy<9-JaQPAe0SOJ3R%)3J+R~H?Fh^{B?cO;c1Hy|l zH)kx+Q`D4OKni+C*ol@ULY9U>mVy&h!G27c6zZ(w*>=mJeRO1*mhDj{ za=Xh-Cq1IpE>q}wQNR2d&lRG#dmRvWQ_K(S3j#^a;)(KuZ0He3%W3H{pE&U@&*6K- zNoysbZ8On#RC?^}Mo##XwD|{46uL{Q9LS=jg;HG_9kI+ydlxA%{%5JbLjXczrBfLv ziAB<2cLW`(lg68pDX>IdbLTxe(IFR91vzPSkGyqeibS1q`Mx1K(I+2hBXR1OeEbj# zqn?p3_2dEepnOl{nN=D)Nu2tp(tG0~GY?hHE(uPYP^La%1gW{!qG>wn z9!^pKe+V6S7H67m;&@T+gjxhUVPIwGE9qHWwwcr$JwA!T~k`Y zow%m1U0PHnL9H+5_t07O*wsfkK$U%2C5Z%=y=I1I@8c#WW!X=!`6t!2hF zTJ5J#GP3j9+v}s5X_xjzfWo|YwPB&21T`k6ZPhM2c`vd|x6RVg_!K>+?iR604+M8I z;yJx}LkD@^*b*|i%0p{lq8edh!UYq3A|Xt#YH-XQr3%@`4X-cjJ}f9RECb&vSRry})sDcf5!kF9%2{f*OXVqA(qH^u|k@fS&LK2iJ4S9U~lg zkx}L-(MxE=3>`U%l1(gQSZ+bOS%EaP(fWf8v^kAzGFzJ27ak}`YwNe&eSW|1@B90F zKi`)<^#yhI#)aMqfIR@{Qvj|DSa=-RoB(Kgfb8=?;5e`~p6o+FX*#fY2<$~G`JV(k zQUCd$`M?l6cz~aHCrhdSyoRBt= zZ^3rxCJ{XiTa%iw7SFtN2EaiHBXf|uuMCLUi9E+H!k>|^*ayV@ff}&|ux`N-hk*kB zj@w^SQlXO!-!=*8-eAH*NKjxhlNxXWFkfe~F4I|io)I5A3@?I>%mL#7Jt$>*+evBA zQRcJd9TfPSg#J3_zHB3)>X9uOZ3m2JWvfT)fCXW)_qLA%{B_we7ZLk6%D$`ZBVj?Z zpPI~6L6cnDz)|MQh$-2E{S+{W#BnFPe1 z;@;g$jzR0Wi)||abq#l0PMI4bxnI)*s1hLx*QI32XiQPrNJ3(-DcXM+q|z%Dr>7E# z>{SeZK&^<4QrbqSvgTvT&W16nXugE%CnSsvQFeN#E~2uPKW32-U8ri6;um^YqdL<| zr7~r!E*$SC0w*8y71<3(`IP)3nvG$8l|B_vMDXq`y4R2KEtghOM%&a21PaKQ)McY| zwj@ay9j-pH_71hCOWmWHq(pD1ds=A-L+)z4jE#C1xfx zqaE_6cgAd;>MB(@+^h?AjuV#YT;4pIp(`1>T^sjP;5xs7#9%5BB;*4mjOdXt^1gqf zl>%|6{FB8>3Vg@E*F(f%;|>~#L%s=ZW_L6@td!?sgKxdr=+kT0=&VRmO;IZ77w_Au zjgwiEd`FCd-7VT{Jd^Hw)s$wP>l0)X+-`e`U~vngXQ|~``nT9U7U>b=A^%w4Vsqv^ z-j%*r%*$tazcvT)OoH!8=c2A`{m3S@I?nwRddJ6$Ev*mt-pJ<>s4DmY)9vHQ6NkH;aF%=!ga z2ql6jRMh!j9nMYksLEbF!>qR1 a9b%qCEOu2vSL6~!p=c)lUJ@>2m_Gpt{9+>j diff --git a/src/translations/bitmessage_nl.ts b/src/translations/bitmessage_nl.ts index 3e7c1640..dd77549e 100644 --- a/src/translations/bitmessage_nl.ts +++ b/src/translations/bitmessage_nl.ts @@ -242,7 +242,7 @@ Voer het gewenste e-mail adres (inclusief @mailchuck.com) hieronder in: - One of your addresses, %1, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? + One of your addresses, {0}, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? @@ -262,13 +262,13 @@ Voer het gewenste e-mail adres (inclusief @mailchuck.com) hieronder in: - Message sent. Waiting for acknowledgement. Sent at %1 - Bericht verzonden. Wachten op bevestiging. Verzonden op %1 + Message sent. Waiting for acknowledgement. Sent at {0} + Bericht verzonden. Wachten op bevestiging. Verzonden op {0} - Message sent. Sent at %1 - Bericht verzonden. Verzonden op %1 + Message sent. Sent at {0} + Bericht verzonden. Verzonden op {0} @@ -277,8 +277,8 @@ Voer het gewenste e-mail adres (inclusief @mailchuck.com) hieronder in: - Acknowledgement of the message received %1 - Bevestiging van het bericht ontvangen op %1 + Acknowledgement of the message received {0} + Bevestiging van het bericht ontvangen op {0} @@ -287,17 +287,17 @@ Voer het gewenste e-mail adres (inclusief @mailchuck.com) hieronder in: - Broadcast on %1 + Broadcast on {0} - Problem: The work demanded by the recipient is more difficult than you are willing to do. %1 + Problem: The work demanded by the recipient is more difficult than you are willing to do. {0} - Problem: The recipient's encryption key is no good. Could not encrypt message. %1 + Problem: The recipient's encryption key is no good. Could not encrypt message. {0} @@ -307,8 +307,8 @@ Voer het gewenste e-mail adres (inclusief @mailchuck.com) hieronder in: - Unknown status: %1 %2 - Status onbekend: %1 %2 + Unknown status: {0} {1} + Status onbekend: {0} {1} @@ -348,7 +348,7 @@ Voer het gewenste e-mail adres (inclusief @mailchuck.com) hieronder in: You may manage your keys by editing the keys.dat file stored in - %1 + {0} It is important that you back up this file. @@ -365,7 +365,7 @@ It is important that you back up this file. You may manage your keys by editing the keys.dat file stored in - %1 + {0} 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.) @@ -431,7 +431,7 @@ It is important that you back up this file. Would you like to open the file now? - Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: %1. This address also appears in 'Your Identities'. + Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: {0}. This address also appears in 'Your Identities'. @@ -499,52 +499,52 @@ It is important that you back up this file. Would you like to open the file now? - The message that you are trying to send is too long by %1 bytes. (The maximum is 261644 bytes). Please cut it down before sending. + The message that you are trying to send is too long by {0} bytes. (The maximum is 261644 bytes). Please cut it down before sending. - Error: Your account wasn't registered at an email gateway. Sending registration now as %1, please wait for the registration to be processed before retrying sending. + Error: Your account wasn't registered at an email gateway. Sending registration now as {0}, please wait for the registration to be processed before retrying sending. - Error: Bitmessage addresses start with BM- Please check %1 + Error: Bitmessage addresses start with BM- Please check {0} - Error: The address %1 is not typed or copied correctly. Please check it. + Error: The address {0} is not typed or copied correctly. Please check it. - Error: The address %1 contains invalid characters. Please check it. + Error: The address {0} contains invalid characters. Please check it. - Error: The address version in %1 is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. + Error: The address version in {0} is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. - Error: Some data encoded in the address %1 is too short. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is too short. There might be something wrong with the software of your acquaintance. - Error: Some data encoded in the address %1 is too long. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is too long. There might be something wrong with the software of your acquaintance. - Error: Some data encoded in the address %1 is malformed. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is malformed. There might be something wrong with the software of your acquaintance. - Error: Something is wrong with the address %1. + Error: Something is wrong with the address {0}. @@ -559,7 +559,7 @@ It is important that you back up this file. Would you like to open the file now? - Concerning the address %1, Bitmessage cannot understand address version numbers of %2. Perhaps upgrade Bitmessage to the latest version. + Concerning the address {0}, Bitmessage cannot understand address version numbers of {1}. Perhaps upgrade Bitmessage to the latest version. @@ -569,7 +569,7 @@ It is important that you back up this file. Would you like to open the file now? - Concerning the address %1, Bitmessage cannot handle stream numbers of %2. Perhaps upgrade Bitmessage to the latest version. + Concerning the address {0}, Bitmessage cannot handle stream numbers of {1}. Perhaps upgrade Bitmessage to the latest version. @@ -704,7 +704,7 @@ It is important that you back up this file. Would you like to open the file now? - Bitmessage cannot find your address %1. Perhaps you removed it? + Bitmessage cannot find your address {0}. Perhaps you removed it? @@ -858,7 +858,7 @@ Are you sure you want to delete the channel? - You are using TCP port %1. (This can be changed in the settings). + You are using TCP port {0}. (This can be changed in the settings). @@ -1053,7 +1053,7 @@ Are you sure you want to delete the channel? - Zoom level %1% + Zoom level {0}% @@ -1068,47 +1068,47 @@ Are you sure you want to delete the channel? - Display the %1 recent broadcast(s) from this address. + Display the {0} recent broadcast(s) from this address. - New version of PyBitmessage is available: %1. Download it from https://github.com/Bitmessage/PyBitmessage/releases/latest + New version of PyBitmessage is available: {0}. Download it from https://github.com/Bitmessage/PyBitmessage/releases/latest - Waiting for PoW to finish... %1% + Waiting for PoW to finish... {0}% - Shutting down Pybitmessage... %1% + Shutting down Pybitmessage... {0}% - Waiting for objects to be sent... %1% + Waiting for objects to be sent... {0}% - Saving settings... %1% + Saving settings... {0}% - Shutting down core... %1% + Shutting down core... {0}% - Stopping notifications... %1% + Stopping notifications... {0}% - Shutdown imminent... %1% + Shutdown imminent... {0}% @@ -1129,7 +1129,7 @@ Are you sure you want to delete the channel? - Shutting down PyBitmessage... %1% + Shutting down PyBitmessage... {0}% @@ -1149,12 +1149,12 @@ Are you sure you want to delete the channel? - Generating %1 new addresses. + Generating {0} new addresses. - %1 is already in 'Your Identities'. Not adding it again. + {0} is already in 'Your Identities'. Not adding it again. @@ -1164,7 +1164,7 @@ Are you sure you want to delete the channel? - SOCKS5 Authentication problem: %1 + SOCKS5 Authentication problem: {0} @@ -1189,7 +1189,7 @@ Are you sure you want to delete the channel? - Broadcast sent on %1 + Broadcast sent on {0} @@ -1209,7 +1209,7 @@ Are you sure you want to delete the channel? - Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. %1 + Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. {0} @@ -1221,17 +1221,17 @@ There is no required difficulty for version 2 addresses like this. Doing work necessary to send message. -Receiver's required difficulty: %1 and %2 +Receiver's required difficulty: {0} and {1} - Problem: The work demanded by the recipient (%1 and %2) is more difficult than you are willing to do. %3 + Problem: The work demanded by the recipient ({0} and {1}) is more difficult than you are willing to do. {2} - Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. %1 + Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. {0} @@ -1241,7 +1241,7 @@ Receiver's required difficulty: %1 and %2 - Message sent. Waiting for acknowledgement. Sent on %1 + Message sent. Waiting for acknowledgement. Sent on {0} @@ -1256,12 +1256,12 @@ Receiver's required difficulty: %1 and %2 - Sending public key request. Waiting for reply. Requested at %1 + Sending public key request. Waiting for reply. Requested at {0} - UPnP port mapping established on port %1 + UPnP port mapping established on port {0} @@ -1623,27 +1623,27 @@ The 'Random Number' option is selected by default but deterministic ad - Since startup on %1 + Since startup on {0} - Down: %1/s Total: %2 + Down: {0}/s Total: {1} - Up: %1/s Total: %2 + Up: {0}/s Total: {1} - Total Connections: %1 + Total Connections: {0} - Inventory lookups per second: %1 + Inventory lookups per second: {0} diff --git a/src/translations/bitmessage_no.qm b/src/translations/bitmessage_no.qm index 493d09ef7b51950aec8162fdd7ca145657d77c5e..9f2d9efbeb9540ff17539a3d439bcd96bb75c880 100644 GIT binary patch delta 3967 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 LT1}gi$1wi_?e>J4 delta 4332 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 - One of your addresses, %1, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? - En av dine gamle adresser er av den første typen og derfor ikke lenger støttet: %1. Derfor kan den vel slettes? + One of your addresses, {0}, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? + En av dine gamle adresser er av den første typen og derfor ikke lenger støttet: {0}. Derfor kan den vel slettes? @@ -261,13 +261,13 @@ Please type the desired email address (including @mailchuck.com) below: - Message sent. Waiting for acknowledgement. Sent at %1 - Beskjed sendt. Venter på bekreftelse. Sendt %1 + Message sent. Waiting for acknowledgement. Sent at {0} + Beskjed sendt. Venter på bekreftelse. Sendt {0} - Message sent. Sent at %1 - Beskjed sendt. Sendt %1 + Message sent. Sent at {0} + Beskjed sendt. Sendt {0} @@ -276,8 +276,8 @@ Please type the desired email address (including @mailchuck.com) below: - Acknowledgement of the message received %1 - Bekreftelse på beskjeden mottatt %1 + Acknowledgement of the message received {0} + Bekreftelse på beskjeden mottatt {0} @@ -286,18 +286,18 @@ Please type the desired email address (including @mailchuck.com) below: - Broadcast on %1 - Kringkasting på %1 + Broadcast on {0} + Kringkasting på {0} - Problem: The work demanded by the recipient is more difficult than you are willing to do. %1 - Problem: Det nødvendige arbeidet som kreves utført av mottaker er mer krevende enn det som er satt som akseptabelt. %1 + Problem: The work demanded by the recipient is more difficult than you are willing to do. {0} + Problem: Det nødvendige arbeidet som kreves utført av mottaker er mer krevende enn det som er satt som akseptabelt. {0} - Problem: The recipient's encryption key is no good. Could not encrypt message. %1 - Problem: Mottakerens nøkkel kunne ikke brukes til å kryptere beskjeden. %1 + Problem: The recipient's encryption key is no good. Could not encrypt message. {0} + Problem: Mottakerens nøkkel kunne ikke brukes til å kryptere beskjeden. {0} @@ -306,8 +306,8 @@ Please type the desired email address (including @mailchuck.com) below: - Unknown status: %1 %2 - Ukjent status: %1 %2 + Unknown status: {0} {1} + Ukjent status: {0} {1} @@ -347,10 +347,10 @@ Please type the desired email address (including @mailchuck.com) below: You may manage your keys by editing the keys.dat file stored in - %1 + {0} It is important that you back up this file. Du kan administrere nøklene dine ved å endre filen keys.dat lagret i - %1 + {0} Det er viktig at du tar en sikkerhetskopi av denne filen. @@ -366,10 +366,10 @@ Det er viktig at du tar en sikkerhetskopi av denne filen. You may manage your keys by editing the keys.dat file stored in - %1 + {0} 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.) Du kan administrere dine nøkler ved å endre på filen keys.dat lagret i - %1 + {0} Det er viktig at du tar sikkerhetskopi av denne filen. Vil du åpne denne filen nå? (Vær sikker på å få avsluttet Bitmessage før du gjør endringer.) @@ -434,8 +434,8 @@ Det er viktig at du tar sikkerhetskopi av denne filen. Vil du åpne denne filen - Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: %1. This address also appears in 'Your Identities'. - Opprettet ny kanal. For å la andre delta i din nye kanal gir du dem dem kanalnavnet og denne Bitmessage-adressen: %1. Denne adressen vises også i 'Dine identiteter'. + Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: {0}. This address also appears in 'Your Identities'. + Opprettet ny kanal. For å la andre delta i din nye kanal gir du dem dem kanalnavnet og denne Bitmessage-adressen: {0}. Denne adressen vises også i 'Dine identiteter'. @@ -502,53 +502,53 @@ Det er viktig at du tar sikkerhetskopi av denne filen. Vil du åpne denne filen - The message that you are trying to send is too long by %1 bytes. (The maximum is 261644 bytes). Please cut it down before sending. + The message that you are trying to send is too long by {0} bytes. (The maximum is 261644 bytes). Please cut it down before sending. - Error: Your account wasn't registered at an email gateway. Sending registration now as %1, please wait for the registration to be processed before retrying sending. + Error: Your account wasn't registered at an email gateway. Sending registration now as {0}, please wait for the registration to be processed before retrying sending. - Error: Bitmessage addresses start with BM- Please check %1 - Feil: Bitmessage-adresser begynner med BM-. Vennligst sjekk %1 + Error: Bitmessage addresses start with BM- Please check {0} + Feil: Bitmessage-adresser begynner med BM-. Vennligst sjekk {0} - Error: The address %1 is not typed or copied correctly. Please check it. - Feil: Adressen %1 er skrevet eller kopiert inn feil. Vennligst sjekk den. + Error: The address {0} is not typed or copied correctly. Please check it. + Feil: Adressen {0} er skrevet eller kopiert inn feil. Vennligst sjekk den. - Error: The address %1 contains invalid characters. Please check it. - Feil: Adressen %1 innerholder ugyldige tegn. Vennligst sjekk den. + Error: The address {0} contains invalid characters. Please check it. + Feil: Adressen {0} innerholder ugyldige tegn. Vennligst sjekk den. - Error: The address version in %1 is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. - Feil: Typenummeret for adressen %1 er for høy. Enten trenger du å oppgradere Bitmessaage-programvaren eller så er det fordi kontakten din har funnet på noe smart. + Error: The address version in {0} is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. + Feil: Typenummeret for adressen {0} er for høy. Enten trenger du å oppgradere Bitmessaage-programvaren eller så er det fordi kontakten din har funnet på noe smart. - Error: Some data encoded in the address %1 is too short. There might be something wrong with the software of your acquaintance. - Feil: Noen av de kodede dataene i adressen %1 er for korte. Det kan hende det er noe galt med programvaren til kontakten din. + Error: Some data encoded in the address {0} is too short. There might be something wrong with the software of your acquaintance. + Feil: Noen av de kodede dataene i adressen {0} er for korte. Det kan hende det er noe galt med programvaren til kontakten din. - Error: Some data encoded in the address %1 is too long. There might be something wrong with the software of your acquaintance. - Feil: Noen av de kodede dataene i adressen %1 er for lange. Det kan hende det er noe galt med programvaren til kontakten din. + Error: Some data encoded in the address {0} is too long. There might be something wrong with the software of your acquaintance. + Feil: Noen av de kodede dataene i adressen {0} er for lange. Det kan hende det er noe galt med programvaren til kontakten din. - Error: Some data encoded in the address %1 is malformed. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is malformed. There might be something wrong with the software of your acquaintance. - Error: Something is wrong with the address %1. - Feil: Noe er galt med adressen %1. + Error: Something is wrong with the address {0}. + Feil: Noe er galt med adressen {0}. @@ -562,8 +562,8 @@ Det er viktig at du tar sikkerhetskopi av denne filen. Vil du åpne denne filen - Concerning the address %1, Bitmessage cannot understand address version numbers of %2. Perhaps upgrade Bitmessage to the latest version. - Angående adressen %1, Bitmessage forstår ikke adressetypenumre for %2. Oppdater Bitmessage til siste versjon. + Concerning the address {0}, Bitmessage cannot understand address version numbers of {1}. Perhaps upgrade Bitmessage to the latest version. + Angående adressen {0}, Bitmessage forstår ikke adressetypenumre for {1}. Oppdater Bitmessage til siste versjon. @@ -572,8 +572,8 @@ Det er viktig at du tar sikkerhetskopi av denne filen. Vil du åpne denne filen - Concerning the address %1, Bitmessage cannot handle stream numbers of %2. Perhaps upgrade Bitmessage to the latest version. - Angående adressen %1, Bitmessage kan ikke håndtere strømnumre for %2. Oppdater Bitmessage til siste utgivelse. + Concerning the address {0}, Bitmessage cannot handle stream numbers of {1}. Perhaps upgrade Bitmessage to the latest version. + Angående adressen {0}, Bitmessage kan ikke håndtere strømnumre for {1}. Oppdater Bitmessage til siste utgivelse. @@ -707,8 +707,8 @@ Det er viktig at du tar sikkerhetskopi av denne filen. Vil du åpne denne filen - Bitmessage cannot find your address %1. Perhaps you removed it? - Bitmessage kan ikke finne adressen %1. Kanskje du fjernet den? + Bitmessage cannot find your address {0}. Perhaps you removed it? + Bitmessage kan ikke finne adressen {0}. Kanskje du fjernet den? @@ -861,8 +861,8 @@ Are you sure you want to delete the channel? - You are using TCP port %1. (This can be changed in the settings). - Du benytter TCP-port %1. (Dette kan endres på i innstillingene). + You are using TCP port {0}. (This can be changed in the settings). + Du benytter TCP-port {0}. (Dette kan endres på i innstillingene). @@ -1056,8 +1056,8 @@ Are you sure you want to delete the channel? - Zoom level %1% - Zoom nivå %1% + Zoom level {0}% + Zoom nivå {0}% @@ -1071,47 +1071,47 @@ Are you sure you want to delete the channel? - Display the %1 recent broadcast(s) from this address. + Display the {0} recent broadcast(s) from this address. - New version of PyBitmessage is available: %1. Download it from https://github.com/Bitmessage/PyBitmessage/releases/latest + New version of PyBitmessage is available: {0}. Download it from https://github.com/Bitmessage/PyBitmessage/releases/latest - Waiting for PoW to finish... %1% + Waiting for PoW to finish... {0}% - Shutting down Pybitmessage... %1% + Shutting down Pybitmessage... {0}% - Waiting for objects to be sent... %1% + Waiting for objects to be sent... {0}% - Saving settings... %1% + Saving settings... {0}% - Shutting down core... %1% + Shutting down core... {0}% - Stopping notifications... %1% + Stopping notifications... {0}% - Shutdown imminent... %1% + Shutdown imminent... {0}% @@ -1132,7 +1132,7 @@ Are you sure you want to delete the channel? - Shutting down PyBitmessage... %1% + Shutting down PyBitmessage... {0}% @@ -1152,12 +1152,12 @@ Are you sure you want to delete the channel? - Generating %1 new addresses. + Generating {0} new addresses. - %1 is already in 'Your Identities'. Not adding it again. + {0} is already in 'Your Identities'. Not adding it again. @@ -1167,7 +1167,7 @@ Are you sure you want to delete the channel? - SOCKS5 Authentication problem: %1 + SOCKS5 Authentication problem: {0} @@ -1192,7 +1192,7 @@ Are you sure you want to delete the channel? - Broadcast sent on %1 + Broadcast sent on {0} @@ -1212,7 +1212,7 @@ Are you sure you want to delete the channel? - Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. %1 + Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. {0} @@ -1224,17 +1224,17 @@ There is no required difficulty for version 2 addresses like this. Doing work necessary to send message. -Receiver's required difficulty: %1 and %2 +Receiver's required difficulty: {0} and {1} - Problem: The work demanded by the recipient (%1 and %2) is more difficult than you are willing to do. %3 + Problem: The work demanded by the recipient ({0} and {1}) is more difficult than you are willing to do. {2} - Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. %1 + Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. {0} @@ -1244,7 +1244,7 @@ Receiver's required difficulty: %1 and %2 - Message sent. Waiting for acknowledgement. Sent on %1 + Message sent. Waiting for acknowledgement. Sent on {0} @@ -1259,12 +1259,12 @@ Receiver's required difficulty: %1 and %2 - Sending public key request. Waiting for reply. Requested at %1 + Sending public key request. Waiting for reply. Requested at {0} - UPnP port mapping established on port %1 + UPnP port mapping established on port {0} @@ -1627,27 +1627,27 @@ The 'Random Number' option is selected by default but deterministic ad - Since startup on %1 - Siden oppstart på %1 + Since startup on {0} + Siden oppstart på {0} - Down: %1/s Total: %2 - Ned: %1/s Totalt: %2 + Down: {0}/s Total: {1} + Ned: {0}/s Totalt: {1} - Up: %1/s Total: %2 - Opp: %1/s Totalt: %2 + Up: {0}/s Total: {1} + Opp: {0}/s Totalt: {1} - Total Connections: %1 - Antall tilkoblinger: %1 + Total Connections: {0} + Antall tilkoblinger: {0} - Inventory lookups per second: %1 + Inventory lookups per second: {0} diff --git a/src/translations/bitmessage_pl.qm b/src/translations/bitmessage_pl.qm index fb31e8d552193358b8243a8b0faa5c265c14fc51..215ad8cffdbd5cd8052d9b16f13ca532327d0223 100644 GIT binary patch delta 6129 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 - One of your addresses, %1, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? - Jeden z adresów, %1, jest starym adresem wersji 1. Adresy tej wersji nie są już wspierane. Usunąć go? + One of your addresses, {0}, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? + Jeden z adresów, {0}, jest starym adresem wersji 1. Adresy tej wersji nie są już wspierane. Usunąć go? @@ -374,13 +374,13 @@ Please type the desired email address (including @mailchuck.com) below: - Message sent. Waiting for acknowledgement. Sent at %1 - Wiadomość wysłana. Oczekiwanie na potwierdzenie odbioru. Wysłano o %1 + Message sent. Waiting for acknowledgement. Sent at {0} + Wiadomość wysłana. Oczekiwanie na potwierdzenie odbioru. Wysłano o {0} - Message sent. Sent at %1 - Wiadomość wysłana. Wysłano o %1 + Message sent. Sent at {0} + Wiadomość wysłana. Wysłano o {0} @@ -389,8 +389,8 @@ Please type the desired email address (including @mailchuck.com) below: - Acknowledgement of the message received %1 - Otrzymano potwierdzenie odbioru wiadomości %1 + Acknowledgement of the message received {0} + Otrzymano potwierdzenie odbioru wiadomości {0} @@ -399,18 +399,18 @@ Please type the desired email address (including @mailchuck.com) below: - Broadcast on %1 - Wysłana o %1 + Broadcast on {0} + Wysłana o {0} - Problem: The work demanded by the recipient is more difficult than you are willing to do. %1 - Problem: dowód pracy wymagany przez odbiorcę jest trudniejszy niż zaakceptowany przez Ciebie. %1 + Problem: The work demanded by the recipient is more difficult than you are willing to do. {0} + Problem: dowód pracy wymagany przez odbiorcę jest trudniejszy niż zaakceptowany przez Ciebie. {0} - Problem: The recipient's encryption key is no good. Could not encrypt message. %1 - Problem: klucz szyfrujący odbiorcy jest nieprawidłowy. Nie można zaszyfrować wiadomości. %1 + Problem: The recipient's encryption key is no good. Could not encrypt message. {0} + Problem: klucz szyfrujący odbiorcy jest nieprawidłowy. Nie można zaszyfrować wiadomości. {0} @@ -419,8 +419,8 @@ Please type the desired email address (including @mailchuck.com) below: - Unknown status: %1 %2 - Nieznany status: %1 %2 + Unknown status: {0} {1} + Nieznany status: {0} {1} @@ -460,10 +460,10 @@ Please type the desired email address (including @mailchuck.com) below: You may manage your keys by editing the keys.dat file stored in - %1 + {0} It is important that you back up this file. Możesz zarządzać swoimi kluczami edytując plik keys.dat znajdujący się -%1 +{0} Zaleca się zrobienie kopii zapasowej tego pliku. @@ -479,10 +479,10 @@ Zaleca się zrobienie kopii zapasowej tego pliku. You may manage your keys by editing the keys.dat file stored in - %1 + {0} 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.) Możesz zarządzać swoimi kluczami edytując plik keys.dat znajdujący się -%1 +{0} Zaleca się zrobienie kopii zapasowej tego pliku. Czy chcesz otworzyć ten plik teraz? (Zamknij Bitmessage przed wprowadzeniem jakichkolwiek zmian.) @@ -547,7 +547,7 @@ Zaleca się zrobienie kopii zapasowej tego pliku. Czy chcesz otworzyć ten plik - Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: %1. This address also appears in 'Your Identities'. + Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: {0}. This address also appears in 'Your Identities'. @@ -618,52 +618,52 @@ Zwykle 4-5 dniowy TTL jest odpowiedni. - The message that you are trying to send is too long by %1 bytes. (The maximum is 261644 bytes). Please cut it down before sending. - Wiadomość jest za długa o %1 bajtów (maksymalna długość wynosi 261644 bajty). Przed wysłaniem należy ją skrócić. + The message that you are trying to send is too long by {0} bytes. (The maximum is 261644 bytes). Please cut it down before sending. + Wiadomość jest za długa o {0} bajtów (maksymalna długość wynosi 261644 bajty). Przed wysłaniem należy ją skrócić. - Error: Your account wasn't registered at an email gateway. Sending registration now as %1, please wait for the registration to be processed before retrying sending. - Błąd: Twoje konto nie było zarejestrowane w bramce poczty. Rejestrowanie jako %1, proszę poczekać na zakończenie procesu przed ponowną próbą wysłania wiadomości. + Error: Your account wasn't registered at an email gateway. Sending registration now as {0}, please wait for the registration to be processed before retrying sending. + Błąd: Twoje konto nie było zarejestrowane w bramce poczty. Rejestrowanie jako {0}, proszę poczekać na zakończenie procesu przed ponowną próbą wysłania wiadomości. - Error: Bitmessage addresses start with BM- Please check %1 + Error: Bitmessage addresses start with BM- Please check {0} - Error: The address %1 is not typed or copied correctly. Please check it. + Error: The address {0} is not typed or copied correctly. Please check it. - Error: The address %1 contains invalid characters. Please check it. + Error: The address {0} contains invalid characters. Please check it. - Error: The address version in %1 is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. + Error: The address version in {0} is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. - Error: Some data encoded in the address %1 is too short. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is too short. There might be something wrong with the software of your acquaintance. - Error: Some data encoded in the address %1 is too long. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is too long. There might be something wrong with the software of your acquaintance. - Error: Some data encoded in the address %1 is malformed. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is malformed. There might be something wrong with the software of your acquaintance. - Error: Something is wrong with the address %1. + Error: Something is wrong with the address {0}. @@ -678,8 +678,8 @@ Zwykle 4-5 dniowy TTL jest odpowiedni. - Concerning the address %1, Bitmessage cannot understand address version numbers of %2. Perhaps upgrade Bitmessage to the latest version. - Odnośnie adresu %1, Bitmessage nie potrafi odczytać wersji adresu %2. Może uaktualnij Bitmessage do najnowszej wersji. + Concerning the address {0}, Bitmessage cannot understand address version numbers of {1}. Perhaps upgrade Bitmessage to the latest version. + Odnośnie adresu {0}, Bitmessage nie potrafi odczytać wersji adresu {1}. Może uaktualnij Bitmessage do najnowszej wersji. @@ -688,8 +688,8 @@ Zwykle 4-5 dniowy TTL jest odpowiedni. - Concerning the address %1, Bitmessage cannot handle stream numbers of %2. Perhaps upgrade Bitmessage to the latest version. - Odnośnie adresu %1, Bitmessage nie potrafi operować na strumieniu adresu %2. Może uaktualnij Bitmessage do najnowszej wersji. + Concerning the address {0}, Bitmessage cannot handle stream numbers of {1}. Perhaps upgrade Bitmessage to the latest version. + Odnośnie adresu {0}, Bitmessage nie potrafi operować na strumieniu adresu {1}. Może uaktualnij Bitmessage do najnowszej wersji. @@ -823,8 +823,8 @@ Zwykle 4-5 dniowy TTL jest odpowiedni. - Bitmessage cannot find your address %1. Perhaps you removed it? - Bitmessage nie może odnaleźć Twojego adresu %1. Może go usunąłeś? + Bitmessage cannot find your address {0}. Perhaps you removed it? + Bitmessage nie może odnaleźć Twojego adresu {0}. Może go usunąłeś? @@ -981,7 +981,7 @@ Czy na pewno chcesz usunąć ten kanał? - You are using TCP port %1. (This can be changed in the settings). + You are using TCP port {0}. (This can be changed in the settings). @@ -1176,8 +1176,8 @@ Czy na pewno chcesz usunąć ten kanał? - Zoom level %1% - Poziom powiększenia %1% + Zoom level {0}% + Poziom powiększenia {0}% @@ -1191,48 +1191,48 @@ Czy na pewno chcesz usunąć ten kanał? - Display the %1 recent broadcast(s) from this address. + Display the {0} recent broadcast(s) from this address. - New version of PyBitmessage is available: %1. Download it from https://github.com/Bitmessage/PyBitmessage/releases/latest - Nowa wersja Bitmessage jest dostępna: %1. Pobierz ją z https://github.com/Bitmessage/PyBitmessage/releases/latest + New version of PyBitmessage is available: {0}. Download it from https://github.com/Bitmessage/PyBitmessage/releases/latest + Nowa wersja Bitmessage jest dostępna: {0}. Pobierz ją z https://github.com/Bitmessage/PyBitmessage/releases/latest - Waiting for PoW to finish... %1% - Oczekiwanie na wykonanie dowodu pracy… %1% + Waiting for PoW to finish... {0}% + Oczekiwanie na wykonanie dowodu pracy… {0}% - Shutting down Pybitmessage... %1% - Zamykanie PyBitmessage… %1% + Shutting down Pybitmessage... {0}% + Zamykanie PyBitmessage… {0}% - Waiting for objects to be sent... %1% - Oczekiwanie na wysłanie obiektów… %1% + Waiting for objects to be sent... {0}% + Oczekiwanie na wysłanie obiektów… {0}% - Saving settings... %1% - Zapisywanie ustawień… %1% + Saving settings... {0}% + Zapisywanie ustawień… {0}% - Shutting down core... %1% - Zamykanie rdzenia programu… %1% + Shutting down core... {0}% + Zamykanie rdzenia programu… {0}% - Stopping notifications... %1% - Zatrzymywanie powiadomień… %1% + Stopping notifications... {0}% + Zatrzymywanie powiadomień… {0}% - Shutdown imminent... %1% - Zaraz zamknę… %1% + Shutdown imminent... {0}% + Zaraz zamknę… {0}% @@ -1246,8 +1246,8 @@ Czy na pewno chcesz usunąć ten kanał? - Shutting down PyBitmessage... %1% - Zamykanie PyBitmessage… %1% + Shutting down PyBitmessage... {0}% + Zamykanie PyBitmessage… {0}% @@ -1266,13 +1266,13 @@ Czy na pewno chcesz usunąć ten kanał? - Generating %1 new addresses. - Generowanie %1 nowych adresów. + Generating {0} new addresses. + Generowanie {0} nowych adresów. - %1 is already in 'Your Identities'. Not adding it again. - %1 jest już w 'Twoich tożsamościach'. Nie zostanie tu dodany. + {0} is already in 'Your Identities'. Not adding it again. + {0} jest już w 'Twoich tożsamościach'. Nie zostanie tu dodany. @@ -1281,7 +1281,7 @@ Czy na pewno chcesz usunąć ten kanał? - SOCKS5 Authentication problem: %1 + SOCKS5 Authentication problem: {0} @@ -1306,8 +1306,8 @@ Czy na pewno chcesz usunąć ten kanał? - Broadcast sent on %1 - Wysłano: %1 + Broadcast sent on {0} + Wysłano: {0} @@ -1326,8 +1326,8 @@ Czy na pewno chcesz usunąć ten kanał? - Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. %1 - Problem: adres docelowy jest urządzeniem przenośnym, które wymaga, aby adres docelowy był zawarty w wiadomości, ale jest to zabronione w Twoich ustawieniach. %1 + Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. {0} + Problem: adres docelowy jest urządzeniem przenośnym, które wymaga, aby adres docelowy był zawarty w wiadomości, ale jest to zabronione w Twoich ustawieniach. {0} @@ -1339,19 +1339,19 @@ Nie ma wymaganej trudności dla adresów w wersji 2, takich jak ten adres. Doing work necessary to send message. -Receiver's required difficulty: %1 and %2 +Receiver's required difficulty: {0} and {1} Wykonywanie dowodu pracy niezbędnego do wysłania wiadomości. -Odbiorca wymaga trudności: %1 i %2 +Odbiorca wymaga trudności: {0} i {1} - Problem: The work demanded by the recipient (%1 and %2) is more difficult than you are willing to do. %3 - Problem: dowód pracy wymagany przez odbiorcę (%1 i %2) jest trudniejszy niż chciałbyś wykonać. %3 + Problem: The work demanded by the recipient ({0} and {1}) is more difficult than you are willing to do. {2} + Problem: dowód pracy wymagany przez odbiorcę ({0} i {1}) jest trudniejszy niż chciałbyś wykonać. {2} - Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. %1 - Problem: próbujesz wysłać wiadomość do siebie lub na kanał, ale Twój klucz szyfrujący nie został znaleziony w pliku keys.dat. Nie można zaszyfrować wiadomości. %1 + Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. {0} + Problem: próbujesz wysłać wiadomość do siebie lub na kanał, ale Twój klucz szyfrujący nie został znaleziony w pliku keys.dat. Nie można zaszyfrować wiadomości. {0} @@ -1360,8 +1360,8 @@ Odbiorca wymaga trudności: %1 i %2 - Message sent. Waiting for acknowledgement. Sent on %1 - Wiadomość wysłana. Oczekiwanie na potwierdzenie odbioru. Wysłano o %1 + Message sent. Waiting for acknowledgement. Sent on {0} + Wiadomość wysłana. Oczekiwanie na potwierdzenie odbioru. Wysłano o {0} @@ -1375,13 +1375,13 @@ Odbiorca wymaga trudności: %1 i %2 - Sending public key request. Waiting for reply. Requested at %1 - Wysyłanie prośby o klucz publiczny. Oczekiwanie na odpowiedź. Zapytano o %1 + Sending public key request. Waiting for reply. Requested at {0} + Wysyłanie prośby o klucz publiczny. Oczekiwanie na odpowiedź. Zapytano o {0} - UPnP port mapping established on port %1 - Mapowanie portów UPnP wykonano na porcie %1 + UPnP port mapping established on port {0} + Mapowanie portów UPnP wykonano na porcie {0} @@ -1425,18 +1425,18 @@ Odbiorca wymaga trudności: %1 i %2 - The name %1 was not found. - Ksywka %1 nie została znaleziona. + The name {0} was not found. + Ksywka {0} nie została znaleziona. - The namecoin query failed (%1) - Zapytanie namecoin nie powiodło się (%1) + The namecoin query failed ({0}) + Zapytanie namecoin nie powiodło się ({0}) - Unknown namecoin interface type: %1 - Nieznany typ interfejsu namecoin: %1 + Unknown namecoin interface type: {0} + Nieznany typ interfejsu namecoin: {0} @@ -1445,13 +1445,13 @@ Odbiorca wymaga trudności: %1 i %2 - The name %1 has no associated Bitmessage address. - Ksywka %1 nie ma powiązanego adresu Bitmessage. + The name {0} has no associated Bitmessage address. + Ksywka {0} nie ma powiązanego adresu Bitmessage. - Success! Namecoind version %1 running. - Namecoind wersja %1 działa poprawnie! + Success! Namecoind version {0} running. + Namecoind wersja {0} działa poprawnie! @@ -1514,53 +1514,53 @@ Witamy w przyjaznym i bezpiecznym Bitmessage - Error: Bitmessage addresses start with BM- Please check the recipient address %1 - Błąd: adresy Bitmessage zaczynają się od BM-. Proszę sprawdzić adres odbiorcy %1. + Error: Bitmessage addresses start with BM- Please check the recipient address {0} + Błąd: adresy Bitmessage zaczynają się od BM-. Proszę sprawdzić adres odbiorcy {0}. - Error: The recipient address %1 is not typed or copied correctly. Please check it. - Błąd: adres odbiorcy %1 nie został skopiowany lub przepisany poprawnie. Proszę go sprawdzić. + Error: The recipient address {0} is not typed or copied correctly. Please check it. + Błąd: adres odbiorcy {0} nie został skopiowany lub przepisany poprawnie. Proszę go sprawdzić. - Error: The recipient address %1 contains invalid characters. Please check it. - Błąd: adres odbiorcy %1 zawiera nieprawidłowe znaki. Proszę go sprawdzić. + Error: The recipient address {0} contains invalid characters. Please check it. + Błąd: adres odbiorcy {0} zawiera nieprawidłowe znaki. Proszę go sprawdzić. - Error: The version of the recipient address %1 is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. - Błąd: wersja adresu odbiorcy %1 jest za wysoka. Musisz albo zaktualizować Twoje oprogramowanie Bitmessage, albo twój znajomy Cię trolluje. + Error: The version of the recipient address {0} is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. + Błąd: wersja adresu odbiorcy {0} jest za wysoka. Musisz albo zaktualizować Twoje oprogramowanie Bitmessage, albo twój znajomy Cię trolluje. - Error: Some data encoded in the recipient address %1 is too short. There might be something wrong with the software of your acquaintance. - Błąd: niektóre dane zakodowane w adresie odbiorcy %1 są zbyt krótkie. Być może coś nie działa należycie w programie Twojego znajomego. + Error: Some data encoded in the recipient address {0} is too short. There might be something wrong with the software of your acquaintance. + Błąd: niektóre dane zakodowane w adresie odbiorcy {0} są zbyt krótkie. Być może coś nie działa należycie w programie Twojego znajomego. - Error: Some data encoded in the recipient address %1 is too long. There might be something wrong with the software of your acquaintance. - Błąd: niektóre dane zakodowane w adresie odbiorcy %1 są zbyt długie. Być może coś nie działa należycie w programie Twojego znajomego. + Error: Some data encoded in the recipient address {0} is too long. There might be something wrong with the software of your acquaintance. + Błąd: niektóre dane zakodowane w adresie odbiorcy {0} są zbyt długie. Być może coś nie działa należycie w programie Twojego znajomego. - Error: Some data encoded in the recipient address %1 is malformed. There might be something wrong with the software of your acquaintance. - Błąd: niektóre dane zakodowane w adresie odbiorcy %1 są uszkodzone. Być może coś nie działa należycie w programie Twojego znajomego. + Error: Some data encoded in the recipient address {0} is malformed. There might be something wrong with the software of your acquaintance. + Błąd: niektóre dane zakodowane w adresie odbiorcy {0} są uszkodzone. Być może coś nie działa należycie w programie Twojego znajomego. - Error: Something is wrong with the recipient address %1. - Błąd: coś jest nie tak z adresem odbiorcy %1. + Error: Something is wrong with the recipient address {0}. + Błąd: coś jest nie tak z adresem odbiorcy {0}. - Error: %1 - Błąd: %1 + Error: {0} + Błąd: {0} - From %1 - Od %1 + From {0} + Od {0} @@ -1672,8 +1672,8 @@ Witamy w przyjaznym i bezpiecznym Bitmessage - The link "%1" will open in a browser. It may be a security risk, it could de-anonymise you or download malicious data. Are you sure? - Odnośnik "%1" zostanie otwarty w przeglądarce. Może to spowodować zagrożenie bezpieczeństwa, może on ujawnić Twoją anonimowość lub pobrać złośliwe dane. Czy jesteś pewien? + The link "{0}" will open in a browser. It may be a security risk, it could de-anonymise you or download malicious data. Are you sure? + Odnośnik "{0}" zostanie otwarty w przeglądarce. Może to spowodować zagrożenie bezpieczeństwa, może on ujawnić Twoją anonimowość lub pobrać złośliwe dane. Czy jesteś pewien? @@ -2008,8 +2008,8 @@ Generowanie adresów „losowych” jest wybrane domyślnie, jednak deterministy - You are using TCP port %1. (This can be changed in the settings). - Btimessage używa portu TCP %1. (Można go zmienić w ustawieniach). + You are using TCP port {0}. (This can be changed in the settings). + Btimessage używa portu TCP {0}. (Można go zmienić w ustawieniach). @@ -2061,28 +2061,28 @@ Generowanie adresów „losowych” jest wybrane domyślnie, jednak deterministy - Since startup on %1 - Od startu programu o %1 + Since startup on {0} + Od startu programu o {0} - Down: %1/s Total: %2 - Pobieranie: %1/s W całości: %2 + Down: {0}/s Total: {1} + Pobieranie: {0}/s W całości: {1} - Up: %1/s Total: %2 - Wysyłanie: %1/s W całości: %2 + Up: {0}/s Total: {1} + Wysyłanie: {0}/s W całości: {1} - Total Connections: %1 - Wszystkich połączeń: %1 + Total Connections: {0} + Wszystkich połączeń: {0} - Inventory lookups per second: %1 - Zapytań o elementy na sekundę: %1 + Inventory lookups per second: {0} + Zapytań o elementy na sekundę: {0} @@ -2247,8 +2247,8 @@ Generowanie adresów „losowych” jest wybrane domyślnie, jednak deterministy newchandialog - Successfully created / joined chan %1 - Pomyślnie utworzono / dołączono do kanału %1 + Successfully created / joined chan {0} + Pomyślnie utworzono / dołączono do kanału {0} diff --git a/src/translations/bitmessage_pt.qm b/src/translations/bitmessage_pt.qm index 9c6b34023dc9c6675307ce3a13886583b2edc05b..6a8aed93eaeb0b4f0b7f9477b1aa934b15cd5110 100644 GIT binary patch delta 470 zcmdm@@mghqO#NvFh71=52L2-qtUW9Y3~b#DtaE^TwtWn&YnCuD@I7Z>TgeQRf5X5Y z=E}ez;LqSb?Fa({V;6+xvSJ9T*u%iUFa<(${$~i!tODv|WaM1%g@J+T1molhfgvM1gZmo#OKtJ})Jz`l~Txgiy3Z!X*2FrXry zgOhm~#p@5TukLvaG%B3Kg6$(v)|6wKh-RDa~B#?0x~Au#@|ZkUG$u4(>M!SwL}Do+}D(m>d%1C ze2aM1W&-&vQ+Qn>JsB7#uVz#fOXNGJFA3Dk#J{`b9RmZ$%uJvknkGNs@!G7zbd5zy z(l@oZI59m{p*S_KL{A|YNGc?jC{!ENPM*Lj!k9PNfIXAHn!$jfmID}W3~WGbHhCGl UF*8)f=J)J{Tr<-g(6Hu(jHp4f)(6t|K`ngSG!kMLAymk z5k|&cpGFwygZa^e`QkK!0;Qn0>?sI*F&aTs5PhF^_aL@G2X=q^o!|eQ^E>x{-*0|Y zGf<_^1N8U-Tu*@QX8^d1z}`j9%>X+-4B%V>Zq$PMGVtAP0A+ii{l+r@>avNpCfIj! z7639P3g00pp9TW*j(5tYpZ;Ivl-@>9tP+*ka7sRSLioV#aGn5U;R1d$6_D#~w~k z1Mnm4`LhJA%iNo8taHrqWBp4wGGros#6;n-iMl;t-NAjt0-tp@+l(FqLiG#e%%ZS8 z6hZ71?!0Qm#$SY?-M`Vmys*6g2kv&uMsl4vK(|dce?z0w_FVZEG=9OJ^Bl!|t0U7= ziMuO~ETv+7)I{e!vHCW0CL{U}c7XAK+O*-2^JTpoTmN!pwGX(_M346qec-0<+$v$;O5^0{~7qQiw2+1x{7KglR8wD)JhB9qSCf}7O!Siw5;MQslJl@`yapY zQel_Ei9XFQOYua^sS-_-m6&Q$a3@KOC?qLqq%|5%;vJEKREE5e%AXC!VC`O#3iO55 zNK!to$qB{mA%x>nq&F_BT6xL&$x2XGqKOoUk%Xd - One of your addresses, %1, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? + One of your addresses, {0}, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? @@ -261,12 +261,12 @@ Please type the desired email address (including @mailchuck.com) below: - Message sent. Waiting for acknowledgement. Sent at %1 - Mensagem enviada. Aguardando confirmação. Enviada a %1 + Message sent. Waiting for acknowledgement. Sent at {0} + Mensagem enviada. Aguardando confirmação. Enviada a {0} - Message sent. Sent at %1 + Message sent. Sent at {0} Mensagem enviada. Enviada a 1% @@ -276,7 +276,7 @@ Please type the desired email address (including @mailchuck.com) below: - Acknowledgement of the message received %1 + Acknowledgement of the message received {0} @@ -286,17 +286,17 @@ Please type the desired email address (including @mailchuck.com) below: - Broadcast on %1 + Broadcast on {0} - Problem: The work demanded by the recipient is more difficult than you are willing to do. %1 + Problem: The work demanded by the recipient is more difficult than you are willing to do. {0} - Problem: The recipient's encryption key is no good. Could not encrypt message. %1 + Problem: The recipient's encryption key is no good. Could not encrypt message. {0} @@ -306,7 +306,7 @@ Please type the desired email address (including @mailchuck.com) below: - Unknown status: %1 %2 + Unknown status: {0} {1} @@ -347,7 +347,7 @@ Please type the desired email address (including @mailchuck.com) below: You may manage your keys by editing the keys.dat file stored in - %1 + {0} It is important that you back up this file. @@ -364,7 +364,7 @@ It is important that you back up this file. You may manage your keys by editing the keys.dat file stored in - %1 + {0} 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.) @@ -430,7 +430,7 @@ It is important that you back up this file. Would you like to open the file now? - Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: %1. This address also appears in 'Your Identities'. + Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: {0}. This address also appears in 'Your Identities'. @@ -498,52 +498,52 @@ It is important that you back up this file. Would you like to open the file now? - The message that you are trying to send is too long by %1 bytes. (The maximum is 261644 bytes). Please cut it down before sending. + The message that you are trying to send is too long by {0} bytes. (The maximum is 261644 bytes). Please cut it down before sending. - Error: Your account wasn't registered at an email gateway. Sending registration now as %1, please wait for the registration to be processed before retrying sending. + Error: Your account wasn't registered at an email gateway. Sending registration now as {0}, please wait for the registration to be processed before retrying sending. - Error: Bitmessage addresses start with BM- Please check %1 + Error: Bitmessage addresses start with BM- Please check {0} - Error: The address %1 is not typed or copied correctly. Please check it. + Error: The address {0} is not typed or copied correctly. Please check it. - Error: The address %1 contains invalid characters. Please check it. + Error: The address {0} contains invalid characters. Please check it. - Error: The address version in %1 is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. + Error: The address version in {0} is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. - Error: Some data encoded in the address %1 is too short. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is too short. There might be something wrong with the software of your acquaintance. - Error: Some data encoded in the address %1 is too long. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is too long. There might be something wrong with the software of your acquaintance. - Error: Some data encoded in the address %1 is malformed. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is malformed. There might be something wrong with the software of your acquaintance. - Error: Something is wrong with the address %1. + Error: Something is wrong with the address {0}. @@ -558,7 +558,7 @@ It is important that you back up this file. Would you like to open the file now? - Concerning the address %1, Bitmessage cannot understand address version numbers of %2. Perhaps upgrade Bitmessage to the latest version. + Concerning the address {0}, Bitmessage cannot understand address version numbers of {1}. Perhaps upgrade Bitmessage to the latest version. @@ -568,7 +568,7 @@ It is important that you back up this file. Would you like to open the file now? - Concerning the address %1, Bitmessage cannot handle stream numbers of %2. Perhaps upgrade Bitmessage to the latest version. + Concerning the address {0}, Bitmessage cannot handle stream numbers of {1}. Perhaps upgrade Bitmessage to the latest version. @@ -703,7 +703,7 @@ It is important that you back up this file. Would you like to open the file now? - Bitmessage cannot find your address %1. Perhaps you removed it? + Bitmessage cannot find your address {0}. Perhaps you removed it? @@ -857,7 +857,7 @@ Are you sure you want to delete the channel? - You are using TCP port %1. (This can be changed in the settings). + You are using TCP port {0}. (This can be changed in the settings). @@ -1052,7 +1052,7 @@ Are you sure you want to delete the channel? - Zoom level %1% + Zoom level {0}% @@ -1067,47 +1067,47 @@ Are you sure you want to delete the channel? - Display the %1 recent broadcast(s) from this address. + Display the {0} recent broadcast(s) from this address. - New version of PyBitmessage is available: %1. Download it from https://github.com/Bitmessage/PyBitmessage/releases/latest + New version of PyBitmessage is available: {0}. Download it from https://github.com/Bitmessage/PyBitmessage/releases/latest - Waiting for PoW to finish... %1% + Waiting for PoW to finish... {0}% - Shutting down Pybitmessage... %1% + Shutting down Pybitmessage... {0}% - Waiting for objects to be sent... %1% + Waiting for objects to be sent... {0}% - Saving settings... %1% + Saving settings... {0}% - Shutting down core... %1% + Shutting down core... {0}% - Stopping notifications... %1% + Stopping notifications... {0}% - Shutdown imminent... %1% + Shutdown imminent... {0}% @@ -1128,7 +1128,7 @@ Are you sure you want to delete the channel? - Shutting down PyBitmessage... %1% + Shutting down PyBitmessage... {0}% @@ -1148,12 +1148,12 @@ Are you sure you want to delete the channel? - Generating %1 new addresses. + Generating {0} new addresses. - %1 is already in 'Your Identities'. Not adding it again. + {0} is already in 'Your Identities'. Not adding it again. @@ -1163,7 +1163,7 @@ Are you sure you want to delete the channel? - SOCKS5 Authentication problem: %1 + SOCKS5 Authentication problem: {0} @@ -1188,7 +1188,7 @@ Are you sure you want to delete the channel? - Broadcast sent on %1 + Broadcast sent on {0} @@ -1208,7 +1208,7 @@ Are you sure you want to delete the channel? - Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. %1 + Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. {0} @@ -1220,17 +1220,17 @@ There is no required difficulty for version 2 addresses like this. Doing work necessary to send message. -Receiver's required difficulty: %1 and %2 +Receiver's required difficulty: {0} and {1} - Problem: The work demanded by the recipient (%1 and %2) is more difficult than you are willing to do. %3 + Problem: The work demanded by the recipient ({0} and {1}) is more difficult than you are willing to do. {2} - Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. %1 + Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. {0} @@ -1240,7 +1240,7 @@ Receiver's required difficulty: %1 and %2 - Message sent. Waiting for acknowledgement. Sent on %1 + Message sent. Waiting for acknowledgement. Sent on {0} @@ -1255,12 +1255,12 @@ Receiver's required difficulty: %1 and %2 - Sending public key request. Waiting for reply. Requested at %1 + Sending public key request. Waiting for reply. Requested at {0} - UPnP port mapping established on port %1 + UPnP port mapping established on port {0} @@ -1622,27 +1622,27 @@ The 'Random Number' option is selected by default but deterministic ad - Since startup on %1 + Since startup on {0} - Down: %1/s Total: %2 + Down: {0}/s Total: {1} - Up: %1/s Total: %2 + Up: {0}/s Total: {1} - Total Connections: %1 + Total Connections: {0} - Inventory lookups per second: %1 + Inventory lookups per second: {0} diff --git a/src/translations/bitmessage_ru.qm b/src/translations/bitmessage_ru.qm index 8c0269b9e18ecc2f219729d227bb411c4f72f23e..2642035b4cc8479c6b87d7ac4bdd4b231f0342da 100644 GIT binary patch delta 6265 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 delta 6032 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 diff --git a/src/translations/bitmessage_ru.ts b/src/translations/bitmessage_ru.ts index 4a80f62e..0fac3766 100644 --- a/src/translations/bitmessage_ru.ts +++ b/src/translations/bitmessage_ru.ts @@ -314,8 +314,8 @@ Please type the desired email address (including @mailchuck.com) below: - One of your addresses, %1, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? - Один из Ваших адресов, %1, является устаревшим адресом версии 1. Адреса версии 1 больше не поддерживаются. Хотите ли Вы удалить его сейчас? + One of your addresses, {0}, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? + Один из Ваших адресов, {0}, является устаревшим адресом версии 1. Адреса версии 1 больше не поддерживаются. Хотите ли Вы удалить его сейчас? @@ -334,13 +334,13 @@ Please type the desired email address (including @mailchuck.com) below: - Message sent. Waiting for acknowledgement. Sent at %1 - Сообщение отправлено. Ожидаем подтверждения. Отправлено в %1 + Message sent. Waiting for acknowledgement. Sent at {0} + Сообщение отправлено. Ожидаем подтверждения. Отправлено в {0} - Message sent. Sent at %1 - Сообщение отправлено в %1 + Message sent. Sent at {0} + Сообщение отправлено в {0} @@ -349,8 +349,8 @@ Please type the desired email address (including @mailchuck.com) below: - Acknowledgement of the message received %1 - Доставлено в %1 + Acknowledgement of the message received {0} + Доставлено в {0} @@ -359,18 +359,18 @@ Please type the desired email address (including @mailchuck.com) below: - Broadcast on %1 - Рассылка на %1 + Broadcast on {0} + Рассылка на {0} - Problem: The work demanded by the recipient is more difficult than you are willing to do. %1 - Проблема: Ваш получатель требует более сложных вычислений, чем максимум, указанный в Ваших настройках. %1 + Problem: The work demanded by the recipient is more difficult than you are willing to do. {0} + Проблема: Ваш получатель требует более сложных вычислений, чем максимум, указанный в Ваших настройках. {0} - Problem: The recipient's encryption key is no good. Could not encrypt message. %1 - Проблема: ключ получателя неправильный. Невозможно зашифровать сообщение. %1 + Problem: The recipient's encryption key is no good. Could not encrypt message. {0} + Проблема: ключ получателя неправильный. Невозможно зашифровать сообщение. {0} @@ -379,8 +379,8 @@ Please type the desired email address (including @mailchuck.com) below: - Unknown status: %1 %2 - Неизвестный статус: %1 %2 + Unknown status: {0} {1} + Неизвестный статус: {0} {1} @@ -421,10 +421,10 @@ Please type the desired email address (including @mailchuck.com) below: You may manage your keys by editing the keys.dat file stored in - %1 + {0} It is important that you back up this file. Вы можете управлять Вашими ключами, редактируя файл keys.dat, находящийся в - %1 + {0} Создайте резервную копию этого файла перед тем как будете его редактировать. @@ -442,7 +442,7 @@ It is important that you back up this file. You may manage your keys by editing the keys.dat file stored in - %1 + {0} 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.) @@ -508,7 +508,7 @@ It is important that you back up this file. Would you like to open the file now? - Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: %1. This address also appears in 'Your Identities'. + Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: {0}. This address also appears in 'Your Identities'. @@ -579,52 +579,52 @@ It is important that you back up this file. Would you like to open the file now? - The message that you are trying to send is too long by %1 bytes. (The maximum is 261644 bytes). Please cut it down before sending. - Сообщение, которое вы пытаетесь отправить, длиннее максимально допустимого на %1 байт. (Максимально допустимое значение 261644 байта). Пожалуйста, сократите сообщение перед отправкой. + The message that you are trying to send is too long by {0} bytes. (The maximum is 261644 bytes). Please cut it down before sending. + Сообщение, которое вы пытаетесь отправить, длиннее максимально допустимого на {0} байт. (Максимально допустимое значение 261644 байта). Пожалуйста, сократите сообщение перед отправкой. - Error: Your account wasn't registered at an email gateway. Sending registration now as %1, please wait for the registration to be processed before retrying sending. - Ошибка: ваш аккаунт не зарегистрирован на Email-шлюзе. Отправка регистрации %1, пожалуйста, подождите пока процесс регистрации не завершится, прежде чем попытаться отправить сообщение заново. + Error: Your account wasn't registered at an email gateway. Sending registration now as {0}, please wait for the registration to be processed before retrying sending. + Ошибка: ваш аккаунт не зарегистрирован на Email-шлюзе. Отправка регистрации {0}, пожалуйста, подождите пока процесс регистрации не завершится, прежде чем попытаться отправить сообщение заново. - Error: Bitmessage addresses start with BM- Please check %1 + Error: Bitmessage addresses start with BM- Please check {0} - Error: The address %1 is not typed or copied correctly. Please check it. + Error: The address {0} is not typed or copied correctly. Please check it. - Error: The address %1 contains invalid characters. Please check it. + Error: The address {0} contains invalid characters. Please check it. - Error: The address version in %1 is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. + Error: The address version in {0} is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. - Error: Some data encoded in the address %1 is too short. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is too short. There might be something wrong with the software of your acquaintance. - Error: Some data encoded in the address %1 is too long. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is too long. There might be something wrong with the software of your acquaintance. - Error: Some data encoded in the address %1 is malformed. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is malformed. There might be something wrong with the software of your acquaintance. - Error: Something is wrong with the address %1. + Error: Something is wrong with the address {0}. @@ -639,8 +639,8 @@ It is important that you back up this file. Would you like to open the file now? - Concerning the address %1, Bitmessage cannot understand address version numbers of %2. Perhaps upgrade Bitmessage to the latest version. - По поводу адреса %1: Bitmessage не поддерживает адреса версии %2. Возможно вам нужно обновить клиент Bitmessage. + Concerning the address {0}, Bitmessage cannot understand address version numbers of {1}. Perhaps upgrade Bitmessage to the latest version. + По поводу адреса {0}: Bitmessage не поддерживает адреса версии {1}. Возможно вам нужно обновить клиент Bitmessage. @@ -649,8 +649,8 @@ It is important that you back up this file. Would you like to open the file now? - Concerning the address %1, Bitmessage cannot handle stream numbers of %2. Perhaps upgrade Bitmessage to the latest version. - По поводу адреса %1: Bitmessage не поддерживает поток номер %2. Возможно вам нужно обновить клиент Bitmessage. + Concerning the address {0}, Bitmessage cannot handle stream numbers of {1}. Perhaps upgrade Bitmessage to the latest version. + По поводу адреса {0}: Bitmessage не поддерживает поток номер {1}. Возможно вам нужно обновить клиент Bitmessage. @@ -784,8 +784,8 @@ It is important that you back up this file. Would you like to open the file now? - Bitmessage cannot find your address %1. Perhaps you removed it? - Bitmessage не может найти Ваш адрес %1. Возможно Вы удалили его? + Bitmessage cannot find your address {0}. Perhaps you removed it? + Bitmessage не может найти Ваш адрес {0}. Возможно Вы удалили его? @@ -942,7 +942,7 @@ Are you sure you want to delete the channel? - You are using TCP port %1. (This can be changed in the settings). + You are using TCP port {0}. (This can be changed in the settings). @@ -1137,8 +1137,8 @@ Are you sure you want to delete the channel? - Zoom level %1% - Увеличение %1% + Zoom level {0}% + Увеличение {0}% @@ -1152,48 +1152,48 @@ Are you sure you want to delete the channel? - Display the %1 recent broadcast(s) from this address. + Display the {0} recent broadcast(s) from this address. - New version of PyBitmessage is available: %1. Download it from https://github.com/Bitmessage/PyBitmessage/releases/latest - Доступна новая версия PyBitmessage: %1. Загрузите её: https://github.com/Bitmessage/PyBitmessage/releases/latest + New version of PyBitmessage is available: {0}. Download it from https://github.com/Bitmessage/PyBitmessage/releases/latest + Доступна новая версия PyBitmessage: {0}. Загрузите её: https://github.com/Bitmessage/PyBitmessage/releases/latest - Waiting for PoW to finish... %1% - Ожидание окончания PoW... %1% + Waiting for PoW to finish... {0}% + Ожидание окончания PoW... {0}% - Shutting down Pybitmessage... %1% - Завершение PyBitmessage... %1% + Shutting down Pybitmessage... {0}% + Завершение PyBitmessage... {0}% - Waiting for objects to be sent... %1% - Ожидание отправки объектов... %1% + Waiting for objects to be sent... {0}% + Ожидание отправки объектов... {0}% - Saving settings... %1% - Сохранение настроек... %1% + Saving settings... {0}% + Сохранение настроек... {0}% - Shutting down core... %1% - Завершение работы ядра... %1% + Shutting down core... {0}% + Завершение работы ядра... {0}% - Stopping notifications... %1% - Остановка сервиса уведомлений... %1% + Stopping notifications... {0}% + Остановка сервиса уведомлений... {0}% - Shutdown imminent... %1% - Завершение вот-вот произойдет... %1% + Shutdown imminent... {0}% + Завершение вот-вот произойдет... {0}% @@ -1207,8 +1207,8 @@ Are you sure you want to delete the channel? - Shutting down PyBitmessage... %1% - Завершение PyBitmessage... %1% + Shutting down PyBitmessage... {0}% + Завершение PyBitmessage... {0}% @@ -1227,13 +1227,13 @@ Are you sure you want to delete the channel? - Generating %1 new addresses. - Создание %1 новых адресов. + Generating {0} new addresses. + Создание {0} новых адресов. - %1 is already in 'Your Identities'. Not adding it again. - %1 уже имеется в ваших адресах. Не добавляю его снова. + {0} is already in 'Your Identities'. Not adding it again. + {0} уже имеется в ваших адресах. Не добавляю его снова. @@ -1242,7 +1242,7 @@ Are you sure you want to delete the channel? - SOCKS5 Authentication problem: %1 + SOCKS5 Authentication problem: {0} @@ -1267,8 +1267,8 @@ Are you sure you want to delete the channel? - Broadcast sent on %1 - Рассылка отправлена на %1 + Broadcast sent on {0} + Рассылка отправлена на {0} @@ -1287,8 +1287,8 @@ Are you sure you want to delete the channel? - Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. %1 - Проблема: адресат является мобильным устройством, которое требует, чтобы адрес назначения был включен в сообщение, однако, это запрещено в ваших настройках. %1 + Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. {0} + Проблема: адресат является мобильным устройством, которое требует, чтобы адрес назначения был включен в сообщение, однако, это запрещено в ваших настройках. {0} @@ -1300,19 +1300,19 @@ There is no required difficulty for version 2 addresses like this. Doing work necessary to send message. -Receiver's required difficulty: %1 and %2 +Receiver's required difficulty: {0} and {1} Выполнение работы, требуемой для отправки сообщения. -Получатель запросил сложность: %1 и %2 +Получатель запросил сложность: {0} и {1} - Problem: The work demanded by the recipient (%1 and %2) is more difficult than you are willing to do. %3 - Проблема: сложность, затребованная получателем (%1 и %2) гораздо больше, чем вы готовы сделать. %3 + Problem: The work demanded by the recipient ({0} and {1}) is more difficult than you are willing to do. {2} + Проблема: сложность, затребованная получателем ({0} и {1}) гораздо больше, чем вы готовы сделать. {2} - Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. %1 - Проблема: вы пытаетесь отправить сообщение самому себе или в чан, но ваш ключ шифрования не найден в файле ключей keys.dat. Невозможно зашифровать сообщение. %1 + Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. {0} + Проблема: вы пытаетесь отправить сообщение самому себе или в чан, но ваш ключ шифрования не найден в файле ключей keys.dat. Невозможно зашифровать сообщение. {0} @@ -1321,8 +1321,8 @@ Receiver's required difficulty: %1 and %2 - Message sent. Waiting for acknowledgement. Sent on %1 - Отправлено. Ожидаем подтверждения. Отправлено в %1 + Message sent. Waiting for acknowledgement. Sent on {0} + Отправлено. Ожидаем подтверждения. Отправлено в {0} @@ -1336,13 +1336,13 @@ Receiver's required difficulty: %1 and %2 - Sending public key request. Waiting for reply. Requested at %1 - Отправка запроса открытого ключа шифрования. Ожидание ответа. Запрошено в %1 + Sending public key request. Waiting for reply. Requested at {0} + Отправка запроса открытого ключа шифрования. Ожидание ответа. Запрошено в {0} - UPnP port mapping established on port %1 - Распределение портов UPnP завершилось выделением порта %1 + UPnP port mapping established on port {0} + Распределение портов UPnP завершилось выделением порта {0} @@ -1386,13 +1386,13 @@ Receiver's required difficulty: %1 and %2 - The name %1 was not found. - Имя %1 не найдено. + The name {0} was not found. + Имя {0} не найдено. - The namecoin query failed (%1) - Запрос к namecoin не удался (%1). + The namecoin query failed ({0}) + Запрос к namecoin не удался ({0}). @@ -1401,18 +1401,18 @@ Receiver's required difficulty: %1 and %2 - The name %1 has no valid JSON data. - Имя %1 не содержит корректных данных JSON. + The name {0} has no valid JSON data. + Имя {0} не содержит корректных данных JSON. - The name %1 has no associated Bitmessage address. - Имя %1 не имеет связанного адреса Bitmessage. + The name {0} has no associated Bitmessage address. + Имя {0} не имеет связанного адреса Bitmessage. - Success! Namecoind version %1 running. - Успех! Namecoind версии %1 работает. + Success! Namecoind version {0} running. + Успех! Namecoind версии {0} работает. @@ -1475,53 +1475,53 @@ Receiver's required difficulty: %1 and %2 - Error: Bitmessage addresses start with BM- Please check the recipient address %1 - Ошибка: адреса Bitmessage начинаются с "BM-". Пожалуйста, проверьте адрес получателя %1. + Error: Bitmessage addresses start with BM- Please check the recipient address {0} + Ошибка: адреса Bitmessage начинаются с "BM-". Пожалуйста, проверьте адрес получателя {0}. - Error: The recipient address %1 is not typed or copied correctly. Please check it. - Ошибка: адрес получателя %1 набран или скопирован неправильно. Пожалуйста, проверьте его. + Error: The recipient address {0} is not typed or copied correctly. Please check it. + Ошибка: адрес получателя {0} набран или скопирован неправильно. Пожалуйста, проверьте его. - Error: The recipient address %1 contains invalid characters. Please check it. - Ошибка: адрес получателя %1 содержит недопустимые символы. Пожалуйста, проверьте его. + Error: The recipient address {0} contains invalid characters. Please check it. + Ошибка: адрес получателя {0} содержит недопустимые символы. Пожалуйста, проверьте его. - Error: The version of the recipient address %1 is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. - Ошибка: версия адреса получателя %1 слишком высокая. Либо вам нужно обновить программу Bitmessage, либо ваш знакомый - умник. + Error: The version of the recipient address {0} is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. + Ошибка: версия адреса получателя {0} слишком высокая. Либо вам нужно обновить программу Bitmessage, либо ваш знакомый - умник. - Error: Some data encoded in the recipient address %1 is too short. There might be something wrong with the software of your acquaintance. - Ошибка: часть данных, закодированных в адресе получателя %1 слишком короткая. Видимо, что-то не так с программой, используемой вашим знакомым. + Error: Some data encoded in the recipient address {0} is too short. There might be something wrong with the software of your acquaintance. + Ошибка: часть данных, закодированных в адресе получателя {0} слишком короткая. Видимо, что-то не так с программой, используемой вашим знакомым. - Error: Some data encoded in the recipient address %1 is too long. There might be something wrong with the software of your acquaintance. - Ошибка: часть данных, закодированных в адресе получателя %1 слишком длинная. Видимо, что-то не так с программой, используемой вашим знакомым. + Error: Some data encoded in the recipient address {0} is too long. There might be something wrong with the software of your acquaintance. + Ошибка: часть данных, закодированных в адресе получателя {0} слишком длинная. Видимо, что-то не так с программой, используемой вашим знакомым. - Error: Some data encoded in the recipient address %1 is malformed. There might be something wrong with the software of your acquaintance. - Ошибка: часть данных, закодированных в адресе получателя %1 сформирована неправильно. Видимо, что-то не так с программой, используемой вашим знакомым. + Error: Some data encoded in the recipient address {0} is malformed. There might be something wrong with the software of your acquaintance. + Ошибка: часть данных, закодированных в адресе получателя {0} сформирована неправильно. Видимо, что-то не так с программой, используемой вашим знакомым. - Error: Something is wrong with the recipient address %1. - Ошибка: что-то не так с адресом получателя %1. + Error: Something is wrong with the recipient address {0}. + Ошибка: что-то не так с адресом получателя {0}. - Error: %1 - Ошибка: %1 + Error: {0} + Ошибка: {0} - From %1 - От %1 + From {0} + От {0} @@ -1566,7 +1566,7 @@ Receiver's required difficulty: %1 and %2 Display the %n recent broadcast(s) from this address. - Показать %1 прошлую рассылку с этого адреса.Показать %1 прошлых рассылки с этого адреса.Показать %1 прошлых рассылок с этого адреса.Показать %1 прошлых рассылок с этого адреса. + Показать {0} прошлую рассылку с этого адреса.Показать {0} прошлых рассылки с этого адреса.Показать {0} прошлых рассылок с этого адреса.Показать {0} прошлых рассылок с этого адреса. @@ -1613,8 +1613,8 @@ Receiver's required difficulty: %1 and %2 - The link "%1" will open in a browser. It may be a security risk, it could de-anonymise you or download malicious data. Are you sure? - Ссылка "%1" откроется в браузере. Это может быть угрозой безопасности, например деанонимизировать вас или привести к скачиванию вредоносных данных. Вы уверены? + The link "{0}" will open in a browser. It may be a security risk, it could de-anonymise you or download malicious data. Are you sure? + Ссылка "{0}" откроется в браузере. Это может быть угрозой безопасности, например деанонимизировать вас или привести к скачиванию вредоносных данных. Вы уверены? @@ -1948,8 +1948,8 @@ The 'Random Number' option is selected by default but deterministic ad - You are using TCP port %1. (This can be changed in the settings). - Вы используете TCP порт %1. (Его можно поменять в настройках). + You are using TCP port {0}. (This can be changed in the settings). + Вы используете TCP порт {0}. (Его можно поменять в настройках). @@ -2001,28 +2001,28 @@ The 'Random Number' option is selected by default but deterministic ad - Since startup on %1 - С начала работы, %1 + Since startup on {0} + С начала работы, {0} - Down: %1/s Total: %2 - Загрузка: %1/s Всего: %2 + Down: {0}/s Total: {1} + Загрузка: {0}/s Всего: {1} - Up: %1/s Total: %2 - Отправка: %1/s Всего: %2 + Up: {0}/s Total: {1} + Отправка: {0}/s Всего: {1} - Total Connections: %1 - Всего соединений: %1 + Total Connections: {0} + Всего соединений: {0} - Inventory lookups per second: %1 - Поисков в каталоге в секунду: %1 + Inventory lookups per second: {0} + Поисков в каталоге в секунду: {0} @@ -2187,8 +2187,8 @@ The 'Random Number' option is selected by default but deterministic ad newchandialog - Successfully created / joined chan %1 - Успешно создан / подключен чан %1 + Successfully created / joined chan {0} + Успешно создан / подключен чан {0} diff --git a/src/translations/bitmessage_sk.qm b/src/translations/bitmessage_sk.qm index 26c2a24d6b127a7fe5aa2c47d03ac662cf8029e2..b963125f798ab3d9448975f2efdda7f03767b943 100644 GIT binary patch delta 6331 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 - One of your addresses, %1, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? - Jedna z vašich adries, %1, je stará verzia adresy, 1. Verzie adresy 1 už nie sú podporované. Odstrániť ju teraz? + One of your addresses, {0}, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? + Jedna z vašich adries, {0}, je stará verzia adresy, 1. Verzie adresy 1 už nie sú podporované. Odstrániť ju teraz? @@ -331,13 +331,13 @@ Please type the desired email address (including @mailchuck.com) below: - Message sent. Waiting for acknowledgement. Sent at %1 - Správa odoslaná. Čakanie na potvrdenie. Odoslaná %1 + Message sent. Waiting for acknowledgement. Sent at {0} + Správa odoslaná. Čakanie na potvrdenie. Odoslaná {0} - Message sent. Sent at %1 - Správa odoslaná. Odoslaná %1 + Message sent. Sent at {0} + Správa odoslaná. Odoslaná {0} @@ -346,8 +346,8 @@ Please type the desired email address (including @mailchuck.com) below: - Acknowledgement of the message received %1 - Potvrdenie prijatia správy %1 + Acknowledgement of the message received {0} + Potvrdenie prijatia správy {0} @@ -356,18 +356,18 @@ Please type the desired email address (including @mailchuck.com) below: - Broadcast on %1 + Broadcast on {0} Rozoslané 1% - Problem: The work demanded by the recipient is more difficult than you are willing to do. %1 - Problém: práca požadovná príjemcom je oveľa ťažšia, než je povolené v nastaveniach. %1 + Problem: The work demanded by the recipient is more difficult than you are willing to do. {0} + Problém: práca požadovná príjemcom je oveľa ťažšia, než je povolené v nastaveniach. {0} - Problem: The recipient's encryption key is no good. Could not encrypt message. %1 - Problém: šifrovací kľúč príjemcu je nesprávny. Nie je možné zašifrovať správu. %1 + Problem: The recipient's encryption key is no good. Could not encrypt message. {0} + Problém: šifrovací kľúč príjemcu je nesprávny. Nie je možné zašifrovať správu. {0} @@ -376,8 +376,8 @@ Please type the desired email address (including @mailchuck.com) below: - Unknown status: %1 %2 - Neznámy stav: %1 %2 + Unknown status: {0} {1} + Neznámy stav: {0} {1} @@ -417,10 +417,10 @@ Please type the desired email address (including @mailchuck.com) below: You may manage your keys by editing the keys.dat file stored in - %1 + {0} It is important that you back up this file. Kľúče môžete spravovať úpravou súboru keys.dat, ktorý je uložený v adresári -%1 +{0} Tento súbor je dôležité zálohovať. @@ -436,10 +436,10 @@ Tento súbor je dôležité zálohovať. You may manage your keys by editing the keys.dat file stored in - %1 + {0} 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.) Kľúče môžete spravovať úpravou súboru keys.dat, ktorý je uložený v adresári -%1 +{0} Tento súbor je dôležité zálohovať. Chcete tento súbor teraz otvoriť? (Nezabudnite zatvoriť Bitmessage pred vykonaním akýchkoľvek zmien.) @@ -504,7 +504,7 @@ Tento súbor je dôležité zálohovať. Chcete tento súbor teraz otvoriť? (Ne - Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: %1. This address also appears in 'Your Identities'. + Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: {0}. This address also appears in 'Your Identities'. @@ -572,52 +572,52 @@ Tento súbor je dôležité zálohovať. Chcete tento súbor teraz otvoriť? (Ne - The message that you are trying to send is too long by %1 bytes. (The maximum is 261644 bytes). Please cut it down before sending. - Správa, ktorú skúšate poslať, má %1 bajtov naviac. (Maximum je 261 644 bajtov). Prosím pred odoslaním skrátiť. + The message that you are trying to send is too long by {0} bytes. (The maximum is 261644 bytes). Please cut it down before sending. + Správa, ktorú skúšate poslať, má {0} bajtov naviac. (Maximum je 261 644 bajtov). Prosím pred odoslaním skrátiť. - Error: Your account wasn't registered at an email gateway. Sending registration now as %1, please wait for the registration to be processed before retrying sending. - Chyba: Váš účet nebol registrovaný na e-mailovej bráne. Skúšam registrovať ako %1, prosím počkajte na spracovanie registrácie pred opakovaným odoslaním správy. + Error: Your account wasn't registered at an email gateway. Sending registration now as {0}, please wait for the registration to be processed before retrying sending. + Chyba: Váš účet nebol registrovaný na e-mailovej bráne. Skúšam registrovať ako {0}, prosím počkajte na spracovanie registrácie pred opakovaným odoslaním správy. - Error: Bitmessage addresses start with BM- Please check %1 + Error: Bitmessage addresses start with BM- Please check {0} - Error: The address %1 is not typed or copied correctly. Please check it. + Error: The address {0} is not typed or copied correctly. Please check it. - Error: The address %1 contains invalid characters. Please check it. + Error: The address {0} contains invalid characters. Please check it. - Error: The address version in %1 is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. + Error: The address version in {0} is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. - Error: Some data encoded in the address %1 is too short. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is too short. There might be something wrong with the software of your acquaintance. - Error: Some data encoded in the address %1 is too long. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is too long. There might be something wrong with the software of your acquaintance. - Error: Some data encoded in the address %1 is malformed. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is malformed. There might be something wrong with the software of your acquaintance. - Error: Something is wrong with the address %1. + Error: Something is wrong with the address {0}. @@ -632,8 +632,8 @@ Tento súbor je dôležité zálohovať. Chcete tento súbor teraz otvoriť? (Ne - Concerning the address %1, Bitmessage cannot understand address version numbers of %2. Perhaps upgrade Bitmessage to the latest version. - Čo sa týka adresy %1, Bitmessage nepozná číslo verzie adresy %2. Možno by ste mali upgradenúť Bitmessage na najnovšiu verziu. + Concerning the address {0}, Bitmessage cannot understand address version numbers of {1}. Perhaps upgrade Bitmessage to the latest version. + Čo sa týka adresy {0}, Bitmessage nepozná číslo verzie adresy {1}. Možno by ste mali upgradenúť Bitmessage na najnovšiu verziu. @@ -642,8 +642,8 @@ Tento súbor je dôležité zálohovať. Chcete tento súbor teraz otvoriť? (Ne - Concerning the address %1, Bitmessage cannot handle stream numbers of %2. Perhaps upgrade Bitmessage to the latest version. - Čo sa týka adresy %1, Bitmessage nespracováva číslo prúdu %2. Možno by ste mali upgradenúť Bitmessage na najnovšiu verziu. + Concerning the address {0}, Bitmessage cannot handle stream numbers of {1}. Perhaps upgrade Bitmessage to the latest version. + Čo sa týka adresy {0}, Bitmessage nespracováva číslo prúdu {1}. Možno by ste mali upgradenúť Bitmessage na najnovšiu verziu. @@ -777,8 +777,8 @@ Tento súbor je dôležité zálohovať. Chcete tento súbor teraz otvoriť? (Ne - Bitmessage cannot find your address %1. Perhaps you removed it? - Bitmessage nemôže nájsť vašu adresu %1. Možno ste ju odstránili? + Bitmessage cannot find your address {0}. Perhaps you removed it? + Bitmessage nemôže nájsť vašu adresu {0}. Možno ste ju odstránili? @@ -935,7 +935,7 @@ Ste si istý, že chcete kanál odstrániť? - You are using TCP port %1. (This can be changed in the settings). + You are using TCP port {0}. (This can be changed in the settings). @@ -1130,8 +1130,8 @@ Ste si istý, že chcete kanál odstrániť? - Zoom level %1% - Úroveň priblíženia %1% + Zoom level {0}% + Úroveň priblíženia {0}% @@ -1145,48 +1145,48 @@ Ste si istý, že chcete kanál odstrániť? - Display the %1 recent broadcast(s) from this address. + Display the {0} recent broadcast(s) from this address. - New version of PyBitmessage is available: %1. Download it from https://github.com/Bitmessage/PyBitmessage/releases/latest - K dispozícii je nová verzia PyBitmessage: %1. Môžete ju stiahnuť na https://github.com/Bitmessage/PyBitmessage/releases/latest + New version of PyBitmessage is available: {0}. Download it from https://github.com/Bitmessage/PyBitmessage/releases/latest + K dispozícii je nová verzia PyBitmessage: {0}. Môžete ju stiahnuť na https://github.com/Bitmessage/PyBitmessage/releases/latest - Waiting for PoW to finish... %1% - Čakám na ukončenie práce... %1% + Waiting for PoW to finish... {0}% + Čakám na ukončenie práce... {0}% - Shutting down Pybitmessage... %1% - Ukončujem PyBitmessage... %1% + Shutting down Pybitmessage... {0}% + Ukončujem PyBitmessage... {0}% - Waiting for objects to be sent... %1% - Čakám na odoslanie objektov... %1% + Waiting for objects to be sent... {0}% + Čakám na odoslanie objektov... {0}% - Saving settings... %1% - Ukladám nastavenia... %1% + Saving settings... {0}% + Ukladám nastavenia... {0}% - Shutting down core... %1% - Ukončujem jadro... %1% + Shutting down core... {0}% + Ukončujem jadro... {0}% - Stopping notifications... %1% - Zastavujem oznámenia... %1% + Stopping notifications... {0}% + Zastavujem oznámenia... {0}% - Shutdown imminent... %1% - Posledná fáza ukončenia... %1% + Shutdown imminent... {0}% + Posledná fáza ukončenia... {0}% @@ -1200,8 +1200,8 @@ Ste si istý, že chcete kanál odstrániť? - Shutting down PyBitmessage... %1% - Ukončujem PyBitmessage... %1% + Shutting down PyBitmessage... {0}% + Ukončujem PyBitmessage... {0}% @@ -1220,13 +1220,13 @@ Ste si istý, že chcete kanál odstrániť? - Generating %1 new addresses. - Vytváram %1 nových adries. + Generating {0} new addresses. + Vytváram {0} nových adries. - %1 is already in 'Your Identities'. Not adding it again. - %1 sa už nachádza medzi vášmi identitami, nepridávam dvojmo. + {0} is already in 'Your Identities'. Not adding it again. + {0} sa už nachádza medzi vášmi identitami, nepridávam dvojmo. @@ -1235,7 +1235,7 @@ Ste si istý, že chcete kanál odstrániť? - SOCKS5 Authentication problem: %1 + SOCKS5 Authentication problem: {0} @@ -1260,8 +1260,8 @@ Ste si istý, že chcete kanál odstrániť? - Broadcast sent on %1 - Rozoslané %1 + Broadcast sent on {0} + Rozoslané {0} @@ -1280,8 +1280,8 @@ Ste si istý, že chcete kanál odstrániť? - Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. %1 - Problém: adresa príjemcu je na mobilnom zariadení a požaduje, aby správy obsahovali nezašifrovanú adresu príjemcu. Vaše nastavenia však túto možnost nemajú povolenú. %1 + Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. {0} + Problém: adresa príjemcu je na mobilnom zariadení a požaduje, aby správy obsahovali nezašifrovanú adresu príjemcu. Vaše nastavenia však túto možnost nemajú povolenú. {0} @@ -1293,19 +1293,19 @@ Adresy verzie dva, ako táto, nepožadujú obtiažnosť. Doing work necessary to send message. -Receiver's required difficulty: %1 and %2 +Receiver's required difficulty: {0} and {1} Vykonávam prácu potrebnú na odoslanie správy. -Priímcova požadovaná obtiažnosť: %1 a %2 +Priímcova požadovaná obtiažnosť: {0} a {1} - Problem: The work demanded by the recipient (%1 and %2) is more difficult than you are willing to do. %3 - Problém: Práca požadovná príjemcom (%1 a %2) je obtiažnejšia, ako máte povolené. %3 + Problem: The work demanded by the recipient ({0} and {1}) is more difficult than you are willing to do. {2} + Problém: Práca požadovná príjemcom ({0} a {1}) je obtiažnejšia, ako máte povolené. {2} - Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. %1 - Problém: skúšate odslať správu sami sebe, ale nemôžem nájsť šifrovací kľúč v súbore keys.dat. Nemožno správu zašifrovať: %1 + Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. {0} + Problém: skúšate odslať správu sami sebe, ale nemôžem nájsť šifrovací kľúč v súbore keys.dat. Nemožno správu zašifrovať: {0} @@ -1314,8 +1314,8 @@ Priímcova požadovaná obtiažnosť: %1 a %2 - Message sent. Waiting for acknowledgement. Sent on %1 - Správa odoslaná. Čakanie na potvrdenie. Odoslaná %1 + Message sent. Waiting for acknowledgement. Sent on {0} + Správa odoslaná. Čakanie na potvrdenie. Odoslaná {0} @@ -1329,13 +1329,13 @@ Priímcova požadovaná obtiažnosť: %1 a %2 - Sending public key request. Waiting for reply. Requested at %1 - Odosielam požiadavku na verejný kľúč. Čakám na odpoveď. Vyžiadaný %1 + Sending public key request. Waiting for reply. Requested at {0} + Odosielam požiadavku na verejný kľúč. Čakám na odpoveď. Vyžiadaný {0} - UPnP port mapping established on port %1 - Mapovanie portov UPnP vytvorené na porte %1 + UPnP port mapping established on port {0} + Mapovanie portov UPnP vytvorené na porte {0} @@ -1379,28 +1379,28 @@ Priímcova požadovaná obtiažnosť: %1 a %2 - Problem communicating with proxy: %1. Please check your network settings. - Problém komunikácie s proxy: %1. Prosím skontrolujte nastavenia siete. + Problem communicating with proxy: {0}. Please check your network settings. + Problém komunikácie s proxy: {0}. Prosím skontrolujte nastavenia siete. - SOCKS5 Authentication problem: %1. Please check your SOCKS5 settings. - Problém autentikácie SOCKS5: %1. Prosím skontrolujte nastavenia SOCKS5. + SOCKS5 Authentication problem: {0}. Please check your SOCKS5 settings. + Problém autentikácie SOCKS5: {0}. Prosím skontrolujte nastavenia SOCKS5. - The time on your computer, %1, may be wrong. Please verify your settings. - Čas na vašom počítači, %1, možno nie je správny. Prosím, skontrolujete nastavenia. + The time on your computer, {0}, may be wrong. Please verify your settings. + Čas na vašom počítači, {0}, možno nie je správny. Prosím, skontrolujete nastavenia. - The name %1 was not found. + The name {0} was not found. Meno % nenájdené. - The namecoin query failed (%1) - Dotaz prostredníctvom namecoinu zlyhal (%1) + The namecoin query failed ({0}) + Dotaz prostredníctvom namecoinu zlyhal ({0}) @@ -1409,18 +1409,18 @@ Priímcova požadovaná obtiažnosť: %1 a %2 - The name %1 has no valid JSON data. - Meno %1 neobsahuje planté JSON dáta. + The name {0} has no valid JSON data. + Meno {0} neobsahuje planté JSON dáta. - The name %1 has no associated Bitmessage address. - Meno %1 nemá priradenú žiadnu adresu Bitmessage. + The name {0} has no associated Bitmessage address. + Meno {0} nemá priradenú žiadnu adresu Bitmessage. - Success! Namecoind version %1 running. - Úspech! Namecoind verzia %1 spustený. + Success! Namecoind version {0} running. + Úspech! Namecoind verzia {0} spustený. @@ -1479,53 +1479,53 @@ Vitajte v jednoduchom a bezpečnom Bitmessage - Error: Bitmessage addresses start with BM- Please check the recipient address %1 - Chyba: Bitmessage adresy začínajú s BM- Prosím skontrolujte adresu príjemcu %1 + Error: Bitmessage addresses start with BM- Please check the recipient address {0} + Chyba: Bitmessage adresy začínajú s BM- Prosím skontrolujte adresu príjemcu {0} - Error: The recipient address %1 is not typed or copied correctly. Please check it. - Chyba: adresa príjemcu %1 nie je na správne napísaná alebo skopírovaná. Prosím skontrolujte ju. + Error: The recipient address {0} is not typed or copied correctly. Please check it. + Chyba: adresa príjemcu {0} nie je na správne napísaná alebo skopírovaná. Prosím skontrolujte ju. - Error: The recipient address %1 contains invalid characters. Please check it. - Chyba: adresa príjemcu %1 obsahuje neplatné znaky. Prosím skontrolujte ju. + Error: The recipient address {0} contains invalid characters. Please check it. + Chyba: adresa príjemcu {0} obsahuje neplatné znaky. Prosím skontrolujte ju. - Error: The version of the recipient address %1 is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. - Chyba: verzia adresy príjemcu %1 je príliš veľká. Buď musíte aktualizovať program Bitmessage alebo váš známy s vami žartuje. + Error: The version of the recipient address {0} is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. + Chyba: verzia adresy príjemcu {0} je príliš veľká. Buď musíte aktualizovať program Bitmessage alebo váš známy s vami žartuje. - Error: Some data encoded in the recipient address %1 is too short. There might be something wrong with the software of your acquaintance. - Chyba: niektoré údaje zakódované v adrese príjemcu %1 sú príliš krátke. Softér vášho známeho možno nefunguje správne. + Error: Some data encoded in the recipient address {0} is too short. There might be something wrong with the software of your acquaintance. + Chyba: niektoré údaje zakódované v adrese príjemcu {0} sú príliš krátke. Softér vášho známeho možno nefunguje správne. - Error: Some data encoded in the recipient address %1 is too long. There might be something wrong with the software of your acquaintance. - Chyba: niektoré údaje zakódované v adrese príjemcu %1 sú príliš dlhé. Softvér vášho známeho možno nefunguje správne. + Error: Some data encoded in the recipient address {0} is too long. There might be something wrong with the software of your acquaintance. + Chyba: niektoré údaje zakódované v adrese príjemcu {0} sú príliš dlhé. Softvér vášho známeho možno nefunguje správne. - Error: Some data encoded in the recipient address %1 is malformed. There might be something wrong with the software of your acquaintance. - Chyba: niektoré údaje zakódované v adrese príjemcu %1 sú poškodené. Softvér vášho známeho možno nefunguje správne. + Error: Some data encoded in the recipient address {0} is malformed. There might be something wrong with the software of your acquaintance. + Chyba: niektoré údaje zakódované v adrese príjemcu {0} sú poškodené. Softvér vášho známeho možno nefunguje správne. - Error: Something is wrong with the recipient address %1. - Chyba: niečo s adresou príjemcu %1 je nie je v poriadku. + Error: Something is wrong with the recipient address {0}. + Chyba: niečo s adresou príjemcu {0} je nie je v poriadku. - Error: %1 - Chyba: %1 + Error: {0} + Chyba: {0} - From %1 - Od %1 + From {0} + Od {0} @@ -1570,7 +1570,7 @@ Vitajte v jednoduchom a bezpečnom Bitmessage Display the %n recent broadcast(s) from this address. - Zobraziť poslednú %1 hromadnú správu z tejto adresy.Zobraziť posledné %1 hromadné správy z tejto adresy.Zobraziť posledných %1 hromadných správ z tejto adresy. + Zobraziť poslednú {0} hromadnú správu z tejto adresy.Zobraziť posledné {0} hromadné správy z tejto adresy.Zobraziť posledných {0} hromadných správ z tejto adresy. @@ -1617,8 +1617,8 @@ Vitajte v jednoduchom a bezpečnom Bitmessage - The link "%1" will open in a browser. It may be a security risk, it could de-anonymise you or download malicious data. Are you sure? - Odkaz "%1" bude otvorený v prehliadači. Tento úkon môže predstavovať bezpečnostné riziko a Vás deanonymizovať, alebo vykonať škodlivú činnost. Ste si istý? + The link "{0}" will open in a browser. It may be a security risk, it could de-anonymise you or download malicious data. Are you sure? + Odkaz "{0}" bude otvorený v prehliadači. Tento úkon môže predstavovať bezpečnostné riziko a Vás deanonymizovať, alebo vykonať škodlivú činnost. Ste si istý? @@ -1953,8 +1953,8 @@ Predvoľba je pomocou generátora náhodných čísiel, ale deterministické adr - You are using TCP port %1. (This can be changed in the settings). - Používate port TCP %1. (Možno zmeniť v nastaveniach). + You are using TCP port {0}. (This can be changed in the settings). + Používate port TCP {0}. (Možno zmeniť v nastaveniach). @@ -2006,28 +2006,28 @@ Predvoľba je pomocou generátora náhodných čísiel, ale deterministické adr - Since startup on %1 - Od spustenia %1 + Since startup on {0} + Od spustenia {0} - Down: %1/s Total: %2 - Prijatých: %1/s Spolu: %2 + Down: {0}/s Total: {1} + Prijatých: {0}/s Spolu: {1} - Up: %1/s Total: %2 - Odoslaných: %1/s Spolu: %2 + Up: {0}/s Total: {1} + Odoslaných: {0}/s Spolu: {1} - Total Connections: %1 - Spojení spolu: %1 + Total Connections: {0} + Spojení spolu: {0} - Inventory lookups per second: %1 - Vyhľadaní v inventári za sekundu: %1 + Inventory lookups per second: {0} + Vyhľadaní v inventári za sekundu: {0} @@ -2192,8 +2192,8 @@ Predvoľba je pomocou generátora náhodných čísiel, ale deterministické adr newchandialog - Successfully created / joined chan %1 - Kanál %1 úspešne vytvorený/pripojený + Successfully created / joined chan {0} + Kanál {0} úspešne vytvorený/pripojený diff --git a/src/translations/bitmessage_sv.ts b/src/translations/bitmessage_sv.ts index 015546b3..8b854d5d 100644 --- a/src/translations/bitmessage_sv.ts +++ b/src/translations/bitmessage_sv.ts @@ -240,7 +240,7 @@ Please type the desired email address (including @mailchuck.com) below: - One of your addresses, %1, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? + One of your addresses, {0}, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? @@ -260,12 +260,12 @@ Please type the desired email address (including @mailchuck.com) below: - Message sent. Waiting for acknowledgement. Sent at %1 + Message sent. Waiting for acknowledgement. Sent at {0} - Message sent. Sent at %1 + Message sent. Sent at {0} @@ -275,7 +275,7 @@ Please type the desired email address (including @mailchuck.com) below: - Acknowledgement of the message received %1 + Acknowledgement of the message received {0} @@ -285,17 +285,17 @@ Please type the desired email address (including @mailchuck.com) below: - Broadcast on %1 + Broadcast on {0} - Problem: The work demanded by the recipient is more difficult than you are willing to do. %1 + Problem: The work demanded by the recipient is more difficult than you are willing to do. {0} - Problem: The recipient's encryption key is no good. Could not encrypt message. %1 + Problem: The recipient's encryption key is no good. Could not encrypt message. {0} @@ -305,7 +305,7 @@ Please type the desired email address (including @mailchuck.com) below: - Unknown status: %1 %2 + Unknown status: {0} {1} @@ -346,7 +346,7 @@ Please type the desired email address (including @mailchuck.com) below: You may manage your keys by editing the keys.dat file stored in - %1 + {0} It is important that you back up this file. @@ -363,7 +363,7 @@ It is important that you back up this file. You may manage your keys by editing the keys.dat file stored in - %1 + {0} 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.) @@ -429,7 +429,7 @@ It is important that you back up this file. Would you like to open the file now? - Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: %1. This address also appears in 'Your Identities'. + Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: {0}. This address also appears in 'Your Identities'. @@ -497,52 +497,52 @@ It is important that you back up this file. Would you like to open the file now? - The message that you are trying to send is too long by %1 bytes. (The maximum is 261644 bytes). Please cut it down before sending. + The message that you are trying to send is too long by {0} bytes. (The maximum is 261644 bytes). Please cut it down before sending. - Error: Your account wasn't registered at an email gateway. Sending registration now as %1, please wait for the registration to be processed before retrying sending. + Error: Your account wasn't registered at an email gateway. Sending registration now as {0}, please wait for the registration to be processed before retrying sending. - Error: Bitmessage addresses start with BM- Please check %1 + Error: Bitmessage addresses start with BM- Please check {0} - Error: The address %1 is not typed or copied correctly. Please check it. + Error: The address {0} is not typed or copied correctly. Please check it. - Error: The address %1 contains invalid characters. Please check it. + Error: The address {0} contains invalid characters. Please check it. - Error: The address version in %1 is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. + Error: The address version in {0} is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. - Error: Some data encoded in the address %1 is too short. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is too short. There might be something wrong with the software of your acquaintance. - Error: Some data encoded in the address %1 is too long. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is too long. There might be something wrong with the software of your acquaintance. - Error: Some data encoded in the address %1 is malformed. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is malformed. There might be something wrong with the software of your acquaintance. - Error: Something is wrong with the address %1. + Error: Something is wrong with the address {0}. @@ -557,7 +557,7 @@ It is important that you back up this file. Would you like to open the file now? - Concerning the address %1, Bitmessage cannot understand address version numbers of %2. Perhaps upgrade Bitmessage to the latest version. + Concerning the address {0}, Bitmessage cannot understand address version numbers of {1}. Perhaps upgrade Bitmessage to the latest version. @@ -567,7 +567,7 @@ It is important that you back up this file. Would you like to open the file now? - Concerning the address %1, Bitmessage cannot handle stream numbers of %2. Perhaps upgrade Bitmessage to the latest version. + Concerning the address {0}, Bitmessage cannot handle stream numbers of {1}. Perhaps upgrade Bitmessage to the latest version. @@ -702,7 +702,7 @@ It is important that you back up this file. Would you like to open the file now? - Bitmessage cannot find your address %1. Perhaps you removed it? + Bitmessage cannot find your address {0}. Perhaps you removed it? @@ -856,7 +856,7 @@ Are you sure you want to delete the channel? - You are using TCP port %1. (This can be changed in the settings). + You are using TCP port {0}. (This can be changed in the settings). @@ -1051,7 +1051,7 @@ Are you sure you want to delete the channel? - Zoom level %1% + Zoom level {0}% @@ -1066,47 +1066,47 @@ Are you sure you want to delete the channel? - Display the %1 recent broadcast(s) from this address. + Display the {0} recent broadcast(s) from this address. - New version of PyBitmessage is available: %1. Download it from https://github.com/Bitmessage/PyBitmessage/releases/latest + New version of PyBitmessage is available: {0}. Download it from https://github.com/Bitmessage/PyBitmessage/releases/latest - Waiting for PoW to finish... %1% + Waiting for PoW to finish... {0}% - Shutting down Pybitmessage... %1% + Shutting down Pybitmessage... {0}% - Waiting for objects to be sent... %1% + Waiting for objects to be sent... {0}% - Saving settings... %1% + Saving settings... {0}% - Shutting down core... %1% + Shutting down core... {0}% - Stopping notifications... %1% + Stopping notifications... {0}% - Shutdown imminent... %1% + Shutdown imminent... {0}% @@ -1121,7 +1121,7 @@ Are you sure you want to delete the channel? - Shutting down PyBitmessage... %1% + Shutting down PyBitmessage... {0}% @@ -1141,12 +1141,12 @@ Are you sure you want to delete the channel? - Generating %1 new addresses. + Generating {0} new addresses. - %1 is already in 'Your Identities'. Not adding it again. + {0} is already in 'Your Identities'. Not adding it again. @@ -1156,7 +1156,7 @@ Are you sure you want to delete the channel? - SOCKS5 Authentication problem: %1 + SOCKS5 Authentication problem: {0} @@ -1181,7 +1181,7 @@ Are you sure you want to delete the channel? - Broadcast sent on %1 + Broadcast sent on {0} @@ -1201,7 +1201,7 @@ Are you sure you want to delete the channel? - Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. %1 + Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. {0} @@ -1213,17 +1213,17 @@ There is no required difficulty for version 2 addresses like this. Doing work necessary to send message. -Receiver's required difficulty: %1 and %2 +Receiver's required difficulty: {0} and {1} - Problem: The work demanded by the recipient (%1 and %2) is more difficult than you are willing to do. %3 + Problem: The work demanded by the recipient ({0} and {1}) is more difficult than you are willing to do. {2} - Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. %1 + Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. {0} @@ -1233,7 +1233,7 @@ Receiver's required difficulty: %1 and %2 - Message sent. Waiting for acknowledgement. Sent on %1 + Message sent. Waiting for acknowledgement. Sent on {0} @@ -1248,12 +1248,12 @@ Receiver's required difficulty: %1 and %2 - Sending public key request. Waiting for reply. Requested at %1 + Sending public key request. Waiting for reply. Requested at {0} - UPnP port mapping established on port %1 + UPnP port mapping established on port {0} @@ -1601,27 +1601,27 @@ The 'Random Number' option is selected by default but deterministic ad - Since startup on %1 + Since startup on {0} - Down: %1/s Total: %2 + Down: {0}/s Total: {1} - Up: %1/s Total: %2 + Up: {0}/s Total: {1} - Total Connections: %1 + Total Connections: {0} - Inventory lookups per second: %1 + Inventory lookups per second: {0} diff --git a/src/translations/bitmessage_zh_cn.ts b/src/translations/bitmessage_zh_cn.ts index 474f8c6c..534e2f7a 100644 --- a/src/translations/bitmessage_zh_cn.ts +++ b/src/translations/bitmessage_zh_cn.ts @@ -352,8 +352,8 @@ Please type the desired email address (including @mailchuck.com) below: - One of your addresses, %1, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? - 您的地址中的一个, %1,是一个过时的版本1地址. 版本1地址已经不再受到支持了. 我们可以将它删除掉么? + One of your addresses, {0}, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? + 您的地址中的一个, {0},是一个过时的版本1地址. 版本1地址已经不再受到支持了. 我们可以将它删除掉么? @@ -372,13 +372,13 @@ Please type the desired email address (including @mailchuck.com) below: - Message sent. Waiting for acknowledgement. Sent at %1 - 消息已经发送. 正在等待回执. 发送于 %1 + Message sent. Waiting for acknowledgement. Sent at {0} + 消息已经发送. 正在等待回执. 发送于 {0} - Message sent. Sent at %1 - 消息已经发送. 发送于 %1 + Message sent. Sent at {0} + 消息已经发送. 发送于 {0} @@ -387,8 +387,8 @@ Please type the desired email address (including @mailchuck.com) below: - Acknowledgement of the message received %1 - 消息的回执已经收到于 %1 + Acknowledgement of the message received {0} + 消息的回执已经收到于 {0} @@ -397,18 +397,18 @@ Please type the desired email address (including @mailchuck.com) below: - Broadcast on %1 - 已经广播于 %1 + Broadcast on {0} + 已经广播于 {0} - Problem: The work demanded by the recipient is more difficult than you are willing to do. %1 - 错误: 收件人要求的做工量大于我们的最大接受做工量。 %1 + Problem: The work demanded by the recipient is more difficult than you are willing to do. {0} + 错误: 收件人要求的做工量大于我们的最大接受做工量。 {0} - Problem: The recipient's encryption key is no good. Could not encrypt message. %1 - 错误: 收件人的加密密钥是无效的。不能加密消息。 %1 + Problem: The recipient's encryption key is no good. Could not encrypt message. {0} + 错误: 收件人的加密密钥是无效的。不能加密消息。 {0} @@ -417,8 +417,8 @@ Please type the desired email address (including @mailchuck.com) below: - Unknown status: %1 %2 - 未知状态: %1 %2 + Unknown status: {0} {1} + 未知状态: {0} {1} @@ -458,9 +458,9 @@ Please type the desired email address (including @mailchuck.com) below: You may manage your keys by editing the keys.dat file stored in - %1 + {0} It is important that you back up this file. - 您可以通过编辑储存在 %1 的 keys.dat 来编辑密钥。备份这个文件十分重要。 + 您可以通过编辑储存在 {0} 的 keys.dat 来编辑密钥。备份这个文件十分重要。 @@ -475,9 +475,9 @@ It is important that you back up this file. You may manage your keys by editing the keys.dat file stored in - %1 + {0} 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.) - 您可以通过编辑储存在 %1 的 keys.dat 来编辑密钥。备份这个文件十分重要。您现在想打开这个文件么?(请在进行任何修改前关闭比特信) + 您可以通过编辑储存在 {0} 的 keys.dat 来编辑密钥。备份这个文件十分重要。您现在想打开这个文件么?(请在进行任何修改前关闭比特信) @@ -541,7 +541,7 @@ It is important that you back up this file. Would you like to open the file now? - Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: %1. This address also appears in 'Your Identities'. + Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: {0}. This address also appears in 'Your Identities'. @@ -610,52 +610,52 @@ It is important that you back up this file. Would you like to open the file now? - The message that you are trying to send is too long by %1 bytes. (The maximum is 261644 bytes). Please cut it down before sending. + The message that you are trying to send is too long by {0} bytes. (The maximum is 261644 bytes). Please cut it down before sending. 您正在尝试发送的信息已超过 %1 个字节太长(最大为261644个字节),发送前请先缩短一些。 - Error: Your account wasn't registered at an email gateway. Sending registration now as %1, please wait for the registration to be processed before retrying sending. + Error: Your account wasn't registered at an email gateway. Sending registration now as {0}, please wait for the registration to be processed before retrying sending. 错误: 您的帐户没有在电子邮件网关注册。现在发送注册为%1​​, 注册正在处理请稍候重试发送. - Error: Bitmessage addresses start with BM- Please check %1 + Error: Bitmessage addresses start with BM- Please check {0} - Error: The address %1 is not typed or copied correctly. Please check it. + Error: The address {0} is not typed or copied correctly. Please check it. - Error: The address %1 contains invalid characters. Please check it. + Error: The address {0} contains invalid characters. Please check it. - Error: The address version in %1 is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. + Error: The address version in {0} is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. - Error: Some data encoded in the address %1 is too short. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is too short. There might be something wrong with the software of your acquaintance. - Error: Some data encoded in the address %1 is too long. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is too long. There might be something wrong with the software of your acquaintance. - Error: Some data encoded in the address %1 is malformed. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is malformed. There might be something wrong with the software of your acquaintance. - Error: Something is wrong with the address %1. + Error: Something is wrong with the address {0}. @@ -670,8 +670,8 @@ It is important that you back up this file. Would you like to open the file now? - Concerning the address %1, Bitmessage cannot understand address version numbers of %2. Perhaps upgrade Bitmessage to the latest version. - 地址 %1 的地址版本号 %2 无法被比特信理解。也许您应该升级您的比特信到最新版本。 + Concerning the address {0}, Bitmessage cannot understand address version numbers of {1}. Perhaps upgrade Bitmessage to the latest version. + 地址 {0} 的地址版本号 {1} 无法被比特信理解。也许您应该升级您的比特信到最新版本。 @@ -680,8 +680,8 @@ It is important that you back up this file. Would you like to open the file now? - Concerning the address %1, Bitmessage cannot handle stream numbers of %2. Perhaps upgrade Bitmessage to the latest version. - 地址 %1 的节点流序号 %2 无法被比特信所理解。也许您应该升级您的比特信到最新版本。 + Concerning the address {0}, Bitmessage cannot handle stream numbers of {1}. Perhaps upgrade Bitmessage to the latest version. + 地址 {0} 的节点流序号 {1} 无法被比特信所理解。也许您应该升级您的比特信到最新版本。 @@ -815,8 +815,8 @@ It is important that you back up this file. Would you like to open the file now? - Bitmessage cannot find your address %1. Perhaps you removed it? - 比特信无法找到您的地址 %1 ,也许您已经把它删掉了? + Bitmessage cannot find your address {0}. Perhaps you removed it? + 比特信无法找到您的地址 {0} ,也许您已经把它删掉了? @@ -973,7 +973,7 @@ Are you sure you want to delete the channel? - You are using TCP port %1. (This can be changed in the settings). + You are using TCP port {0}. (This can be changed in the settings). @@ -1168,7 +1168,7 @@ Are you sure you want to delete the channel? - Zoom level %1% + Zoom level {0}% 缩放级别%1% @@ -1183,48 +1183,48 @@ Are you sure you want to delete the channel? - Display the %1 recent broadcast(s) from this address. + Display the {0} recent broadcast(s) from this address. - New version of PyBitmessage is available: %1. Download it from https://github.com/Bitmessage/PyBitmessage/releases/latest - PyBitmessage的新版本可用: %1. 从https://github.com/Bitmessage/PyBitmessage/releases/latest下载 + New version of PyBitmessage is available: {0}. Download it from https://github.com/Bitmessage/PyBitmessage/releases/latest + PyBitmessage的新版本可用: {0}. 从https://github.com/Bitmessage/PyBitmessage/releases/latest下载 - Waiting for PoW to finish... %1% - 等待PoW完成...%1% + Waiting for PoW to finish... {0}% + 等待PoW完成...{0}% - Shutting down Pybitmessage... %1% - 关闭Pybitmessage ...%1% + Shutting down Pybitmessage... {0}% + 关闭Pybitmessage ...{0}% - Waiting for objects to be sent... %1% - 等待要发送对象...%1% + Waiting for objects to be sent... {0}% + 等待要发送对象...{0}% - Saving settings... %1% - 保存设置...%1% + Saving settings... {0}% + 保存设置...{0}% - Shutting down core... %1% - 关闭核心...%1% + Shutting down core... {0}% + 关闭核心...{0}% - Stopping notifications... %1% - 停止通知...%1% + Stopping notifications... {0}% + 停止通知...{0}% - Shutdown imminent... %1% - 关闭即将来临...%1% + Shutdown imminent... {0}% + 关闭即将来临...{0}% @@ -1238,8 +1238,8 @@ Are you sure you want to delete the channel? - Shutting down PyBitmessage... %1% - 关闭PyBitmessage...%1% + Shutting down PyBitmessage... {0}% + 关闭PyBitmessage...{0}% @@ -1258,13 +1258,13 @@ Are you sure you want to delete the channel? - Generating %1 new addresses. - 生成%1个新地址. + Generating {0} new addresses. + 生成{0}个新地址. - %1 is already in 'Your Identities'. Not adding it again. - %1已经在'您的身份'. 不必重新添加. + {0} is already in 'Your Identities'. Not adding it again. + {0}已经在'您的身份'. 不必重新添加. @@ -1273,7 +1273,7 @@ Are you sure you want to delete the channel? - SOCKS5 Authentication problem: %1 + SOCKS5 Authentication problem: {0} @@ -1298,8 +1298,8 @@ Are you sure you want to delete the channel? - Broadcast sent on %1 - 广播发送%1 + Broadcast sent on {0} + 广播发送{0} @@ -1318,8 +1318,8 @@ Are you sure you want to delete the channel? - Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. %1 - 问题:对方是移动设备,并且对方的地址包含在此消息中,但是您的设置禁止了。 %1 + Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. {0} + 问题:对方是移动设备,并且对方的地址包含在此消息中,但是您的设置禁止了。 {0} @@ -1331,19 +1331,19 @@ There is no required difficulty for version 2 addresses like this. Doing work necessary to send message. -Receiver's required difficulty: %1 and %2 +Receiver's required difficulty: {0} and {1} 做必要的工作, 以发送短信. -接收者的要求难度: %1与%2 +接收者的要求难度: {0}与{1} - Problem: The work demanded by the recipient (%1 and %2) is more difficult than you are willing to do. %3 - 问题: 由接收者(%1%2)要求的工作量比您愿意做的工作量來得更困难. %3 + Problem: The work demanded by the recipient ({0} and {1}) is more difficult than you are willing to do. {2} + 问题: 由接收者({0}{1})要求的工作量比您愿意做的工作量來得更困难. {2} - Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. %1 - 问题: 您正在尝试将信息发送给自己或频道, 但您的加密密钥无法在keys.dat文件中找到. 无法加密信息. %1 + Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. {0} + 问题: 您正在尝试将信息发送给自己或频道, 但您的加密密钥无法在keys.dat文件中找到. 无法加密信息. {0} @@ -1352,8 +1352,8 @@ Receiver's required difficulty: %1 and %2 - Message sent. Waiting for acknowledgement. Sent on %1 - 信息发送. 等待确认. 已发送%1 + Message sent. Waiting for acknowledgement. Sent on {0} + 信息发送. 等待确认. 已发送{0} @@ -1367,13 +1367,13 @@ Receiver's required difficulty: %1 and %2 - Sending public key request. Waiting for reply. Requested at %1 - 发送公钥的请求. 等待回复. 请求在%1 + Sending public key request. Waiting for reply. Requested at {0} + 发送公钥的请求. 等待回复. 请求在{0} - UPnP port mapping established on port %1 - UPnP端口映射建立在端口%1 + UPnP port mapping established on port {0} + UPnP端口映射建立在端口{0} @@ -1417,18 +1417,18 @@ Receiver's required difficulty: %1 and %2 - The name %1 was not found. - 名字%1未找到。 + The name {0} was not found. + 名字{0}未找到。 - The namecoin query failed (%1) - 域名币查询失败(%1) + The namecoin query failed ({0}) + 域名币查询失败({0}) - Unknown namecoin interface type: %1 - 未知的 Namecoin 界面类型: %1 + Unknown namecoin interface type: {0} + 未知的 Namecoin 界面类型: {0} @@ -1437,13 +1437,13 @@ Receiver's required difficulty: %1 and %2 - The name %1 has no associated Bitmessage address. - 名字%1没有关联比特信地址。 + The name {0} has no associated Bitmessage address. + 名字{0}没有关联比特信地址。 - Success! Namecoind version %1 running. - 成功!域名币系统%1运行中。 + Success! Namecoind version {0} running. + 成功!域名币系统{0}运行中。 @@ -1506,53 +1506,53 @@ Receiver's required difficulty: %1 and %2 - Error: Bitmessage addresses start with BM- Please check the recipient address %1 - 错误:Bitmessage地址是以BM-开头的,请检查收信地址%1. + Error: Bitmessage addresses start with BM- Please check the recipient address {0} + 错误:Bitmessage地址是以BM-开头的,请检查收信地址{0}. - Error: The recipient address %1 is not typed or copied correctly. Please check it. - 错误:收信地址%1未填写或复制错误。请检查。 + Error: The recipient address {0} is not typed or copied correctly. Please check it. + 错误:收信地址{0}未填写或复制错误。请检查。 - Error: The recipient address %1 contains invalid characters. Please check it. - 错误:收信地址%1还有非法字符。请检查。 + Error: The recipient address {0} contains invalid characters. Please check it. + 错误:收信地址{0}还有非法字符。请检查。 - Error: The version of the recipient address %1 is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. - 错误:收信地址 %1 版本太高。要么您需要更新您的软件,要么对方需要降级 。 + Error: The version of the recipient address {0} is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. + 错误:收信地址 {0} 版本太高。要么您需要更新您的软件,要么对方需要降级 。 - Error: Some data encoded in the recipient address %1 is too short. There might be something wrong with the software of your acquaintance. - 错误:收信地址%1编码数据太短。可能对方使用的软件有问题。 + Error: Some data encoded in the recipient address {0} is too short. There might be something wrong with the software of your acquaintance. + 错误:收信地址{0}编码数据太短。可能对方使用的软件有问题。 - Error: Some data encoded in the recipient address %1 is too long. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the recipient address {0} is too long. There might be something wrong with the software of your acquaintance. 错误: - Error: Some data encoded in the recipient address %1 is malformed. There might be something wrong with the software of your acquaintance. - 错误:收信地址%1编码数据太长。可能对方使用的软件有问题。 + Error: Some data encoded in the recipient address {0} is malformed. There might be something wrong with the software of your acquaintance. + 错误:收信地址{0}编码数据太长。可能对方使用的软件有问题。 - Error: Something is wrong with the recipient address %1. - 错误:收信地址%1有问题。 + Error: Something is wrong with the recipient address {0}. + 错误:收信地址{0}有问题。 - Error: %1 - 错误:%1 + Error: {0} + 错误:{0} - From %1 - 来自 %1 + From {0} + 来自 {0} @@ -1664,8 +1664,8 @@ Receiver's required difficulty: %1 and %2 - The link "%1" will open in a browser. It may be a security risk, it could de-anonymise you or download malicious data. Are you sure? - 此链接“%1”将在浏览器中打开。可能会有安全风险,可能会暴露您或下载恶意数据。确定吗? + The link "{0}" will open in a browser. It may be a security risk, it could de-anonymise you or download malicious data. Are you sure? + 此链接“{0}”将在浏览器中打开。可能会有安全风险,可能会暴露您或下载恶意数据。确定吗? @@ -1999,8 +1999,8 @@ The 'Random Number' option is selected by default but deterministic ad - You are using TCP port %1. (This can be changed in the settings). - 您正在使用TCP端口 %1 。(可以在设置中修改)。 + You are using TCP port {0}. (This can be changed in the settings). + 您正在使用TCP端口 {0} 。(可以在设置中修改)。 @@ -2052,28 +2052,28 @@ The 'Random Number' option is selected by default but deterministic ad - Since startup on %1 - 自从%1启动 + Since startup on {0} + 自从{0}启动 - Down: %1/s Total: %2 - 下: %1/秒 总计: %2 + Down: {0}/s Total: {1} + 下: {0}/秒 总计: {1} - Up: %1/s Total: %2 - 上: %1/秒 总计: %2 + Up: {0}/s Total: {1} + 上: {0}/秒 总计: {1} - Total Connections: %1 - 总的连接数: %1 + Total Connections: {0} + 总的连接数: {0} - Inventory lookups per second: %1 - 每秒库存查询: %1 + Inventory lookups per second: {0} + 每秒库存查询: {0} @@ -2238,8 +2238,8 @@ The 'Random Number' option is selected by default but deterministic ad newchandialog - Successfully created / joined chan %1 - 成功创建或加入频道%1 + Successfully created / joined chan {0} + 成功创建或加入频道{0} diff --git a/src/translations/noarg.sh b/src/translations/noarg.sh new file mode 100755 index 00000000..50d45d32 --- /dev/null +++ b/src/translations/noarg.sh @@ -0,0 +1,7 @@ +#!/bin/sh +files=`ls *.ts` +tmp_file=/tmp/noarg.sh.txt +for file in $files; do + cat $file | sed 's/%1/{0}/g' | sed 's/%2/{1}/g' | sed 's/%3/{2}/g' > $tmp_file + mv $tmp_file $file +done diff --git a/src/translations/update.sh b/src/translations/update.sh new file mode 100755 index 00000000..b3221486 --- /dev/null +++ b/src/translations/update.sh @@ -0,0 +1,2 @@ +#!/bin/sh +lrelease-qt4 bitmessage.pro -- 2.45.1 From 0f858bca891a7405ab9f0abadfd3fa134c9df4e7 Mon Sep 17 00:00:00 2001 From: Kashiko Koibumi Date: Mon, 27 May 2024 04:45:40 +0900 Subject: [PATCH 050/105] read from and write to SQLite database in binary mode This modification is a preparation for migration to Python3. --- src/addresses.py | 24 ++++++++-------- src/bitmessageqt/__init__.py | 44 ++++++++++++++++++++++++------ src/bitmessageqt/account.py | 19 +++++++------ src/bitmessageqt/blacklist.py | 18 ++++++------ src/bitmessageqt/foldertree.py | 11 ++++---- src/bitmessageqt/safehtmlparser.py | 2 ++ src/class_singleCleaner.py | 2 ++ src/class_singleWorker.py | 9 ++++++ src/class_sqlThread.py | 6 ++-- src/helper_msgcoding.py | 3 +- src/shared.py | 3 +- src/tests/test_shared.py | 6 ++-- 12 files changed, 97 insertions(+), 50 deletions(-) diff --git a/src/addresses.py b/src/addresses.py index 885c1f64..6859a9ca 100644 --- a/src/addresses.py +++ b/src/addresses.py @@ -187,7 +187,7 @@ def decodeAddress(address): integer = decodeBase58(address) if integer == 0: status = 'invalidcharacters' - return status, 0, 0, '' + return status, 0, 0, b'' # after converting to hex, the string will be prepended # with a 0x and appended with a L in python2 hexdata = hex(integer)[2:].rstrip('L') @@ -200,23 +200,23 @@ def decodeAddress(address): if checksum != double_sha512(data[:-4])[0:4]: status = 'checksumfailed' - return status, 0, 0, '' + return status, 0, 0, b'' try: addressVersionNumber, bytesUsedByVersionNumber = decodeVarint(data[:9]) except varintDecodeError as e: logger.error(str(e)) status = 'varintmalformed' - return status, 0, 0, '' + return status, 0, 0, b'' if addressVersionNumber > 4: logger.error('cannot decode address version numbers this high') status = 'versiontoohigh' - return status, 0, 0, '' + return status, 0, 0, b'' elif addressVersionNumber == 0: logger.error('cannot decode address version numbers of zero.') status = 'versiontoohigh' - return status, 0, 0, '' + return status, 0, 0, b'' try: streamNumber, bytesUsedByStreamNumber = \ @@ -224,7 +224,7 @@ def decodeAddress(address): except varintDecodeError as e: logger.error(str(e)) status = 'varintmalformed' - return status, 0, 0, '' + return status, 0, 0, b'' status = 'success' if addressVersionNumber == 1: @@ -242,21 +242,21 @@ def decodeAddress(address): return status, addressVersionNumber, streamNumber, \ b'\x00\x00' + embeddedRipeData elif len(embeddedRipeData) < 18: - return 'ripetooshort', 0, 0, '' + return 'ripetooshort', 0, 0, b'' elif len(embeddedRipeData) > 20: - return 'ripetoolong', 0, 0, '' - return 'otherproblem', 0, 0, '' + return 'ripetoolong', 0, 0, b'' + return 'otherproblem', 0, 0, b'' elif addressVersionNumber == 4: embeddedRipeData = \ data[bytesUsedByVersionNumber + bytesUsedByStreamNumber:-4] if embeddedRipeData[0:1] == b'\x00': # In order to enforce address non-malleability, encoded # RIPE data must have NULL bytes removed from the front - return 'encodingproblem', 0, 0, '' + return 'encodingproblem', 0, 0, b'' elif len(embeddedRipeData) > 20: - return 'ripetoolong', 0, 0, '' + return 'ripetoolong', 0, 0, b'' elif len(embeddedRipeData) < 4: - return 'ripetooshort', 0, 0, '' + return 'ripetooshort', 0, 0, b'' x00string = b'\x00' * (20 - len(embeddedRipeData)) return status, addressVersionNumber, streamNumber, \ x00string + embeddedRipeData diff --git a/src/bitmessageqt/__init__.py b/src/bitmessageqt/__init__.py index 40113b5a..fd012e04 100644 --- a/src/bitmessageqt/__init__.py +++ b/src/bitmessageqt/__init__.py @@ -552,6 +552,8 @@ class MyForm(settingsmixin.SMainWindow): "GROUP BY toaddress, folder") for row in queryreturn: toaddress, folder, cnt = row + toaddress = toaddress.decode("utf-8", "replace") + folder = folder.decode("utf-8", "replace") total += cnt if toaddress in db and folder in db[toaddress]: db[toaddress][folder] = cnt @@ -1044,6 +1046,8 @@ class MyForm(settingsmixin.SMainWindow): normalUnread = {} broadcastsUnread = {} for addr, fld, count in queryReturn: + addr = addr.decode("utf-8", "replace") + fld = fld.decode("utf-8", "replace") try: normalUnread[addr][fld] = count except KeyError: @@ -1211,11 +1215,11 @@ class MyForm(settingsmixin.SMainWindow): items = [ MessageList_AddressWidget( - toAddress, unicode(acct.toLabel, 'utf-8'), not read), + toAddress, acct.toLabel, not read), MessageList_AddressWidget( - fromAddress, unicode(acct.fromLabel, 'utf-8'), not read), + fromAddress, acct.fromLabel, not read), MessageList_SubjectWidget( - str(subject), unicode(acct.subject, 'utf-8', 'replace'), + subject, acct.subject, not read), MessageList_TimeWidget( l10n.formatTimestamp(received), not read, received, msgid) @@ -1243,7 +1247,14 @@ class MyForm(settingsmixin.SMainWindow): xAddress, account, "sent", where, what, False) for row in queryreturn: - self.addMessageListItemSent(tableWidget, *row) + r = [] + r.append(row[0].decode("utf-8", "replace")) # toaddress + r.append(row[1].decode("utf-8", "replace")) # fromaddress + r.append(row[2].decode("utf-8", "replace")) # subject + r.append(row[3].decode("utf-8", "replace")) # status + r.append(row[3]) # ackdata + r.append(row[4]) # lastactiontime + self.addMessageListItemSent(tableWidget, *r) tableWidget.horizontalHeader().setSortIndicator( 3, QtCore.Qt.DescendingOrder) @@ -1284,6 +1295,10 @@ class MyForm(settingsmixin.SMainWindow): for row in queryreturn: toAddress, fromAddress, subject, _, msgid, received, read = row + toAddress = toAddress.decode("utf-8", "replace") + fromAddress = fromAddress.decode("utf-8", "replace") + subject = subject.decode("utf-8", "replace") + received = received.decode("utf-8", "replace") self.addMessageListItemInbox( tableWidget, toAddress, fromAddress, subject, msgid, received, read) @@ -1369,6 +1384,7 @@ class MyForm(settingsmixin.SMainWindow): SELECT msgid, toaddress, read FROM inbox where folder='inbox' ''') for msgid, toAddress, read in queryreturn: + toAddress = toAddress.decode("utf-8", "replace") if not read: # increment the unread subscriptions if True (1) @@ -1447,7 +1463,7 @@ class MyForm(settingsmixin.SMainWindow): # Adapters and converters for QT <-> sqlite def sqlInit(self): - register_adapter(QtCore.QByteArray, str) + register_adapter(QtCore.QByteArray, bytes) def indicatorInit(self): """ @@ -1995,9 +2011,9 @@ class MyForm(settingsmixin.SMainWindow): def rerenderAddressBook(self): def addRow (address, label, type): self.ui.tableWidgetAddressBook.insertRow(0) - newItem = Ui_AddressBookWidgetItemLabel(address, unicode(label, 'utf-8'), type) + newItem = Ui_AddressBookWidgetItemLabel(address, label, type) self.ui.tableWidgetAddressBook.setItem(0, 0, newItem) - newItem = Ui_AddressBookWidgetItemAddress(address, unicode(label, 'utf-8'), type) + newItem = Ui_AddressBookWidgetItemAddress(address, label, type) self.ui.tableWidgetAddressBook.setItem(0, 1, newItem) oldRows = {} @@ -2015,6 +2031,8 @@ class MyForm(settingsmixin.SMainWindow): queryreturn = sqlQuery('SELECT label, address FROM subscriptions WHERE enabled = 1') for row in queryreturn: label, address = row + label = label.decode("utf-8", "replace") + address = address.decode("utf-8", "replace") newRows[address] = [label, AccountMixin.SUBSCRIPTION] # chans for address in config.addresses(True): @@ -2025,6 +2043,8 @@ class MyForm(settingsmixin.SMainWindow): queryreturn = sqlQuery('SELECT * FROM addressbook') for row in queryreturn: label, address = row + label = label.decode("utf-8", "replace") + address = address.decode("utf-8", "replace") newRows[address] = [label, AccountMixin.NORMAL] completerList = [] @@ -2038,7 +2058,7 @@ class MyForm(settingsmixin.SMainWindow): self.ui.tableWidgetAddressBook.removeRow(oldRows[address][2]) for address in newRows: addRow(address, newRows[address][0], newRows[address][1]) - completerList.append(unicode(newRows[address][0], encoding="UTF-8") + " <" + address + ">") + completerList.append(newRows[address][0] + " <" + address + ">") # sort self.ui.tableWidgetAddressBook.sortByColumn( @@ -2273,6 +2293,7 @@ class MyForm(settingsmixin.SMainWindow): if queryreturn != []: for row in queryreturn: toLabel, = row + toLabel = toLabel.decode("utf-8", "replace") self.displayNewSentMessage( toAddress, toLabel, fromAddress, subject, message, ackdata) @@ -2920,6 +2941,7 @@ class MyForm(settingsmixin.SMainWindow): if queryreturn != []: for row in queryreturn: messageText, = row + messageText = messageText.decode("utf-8", "replace") lines = messageText.split('\n') totalLines = len(lines) @@ -3043,6 +3065,7 @@ class MyForm(settingsmixin.SMainWindow): if queryreturn != []: for row in queryreturn: messageAtCurrentInboxRow, = row + messageAtCurrentInboxRow = messageAtCurrentInboxRow.decode("utf-8", "replace") acct.parseMessage( toAddressAtCurrentInboxRow, fromAddressAtCurrentInboxRow, tableWidget.item(currentInboxRow, 2).subject, @@ -3274,6 +3297,7 @@ class MyForm(settingsmixin.SMainWindow): if queryreturn != []: for row in queryreturn: message, = row + message = message.decode("utf-8", "replace") defaultFilename = "".join(x for x in subjectAtCurrentInboxRow if x.isalnum()) + '.txt' filename = QtGui.QFileDialog.getSaveFileName( @@ -3285,7 +3309,7 @@ class MyForm(settingsmixin.SMainWindow): return try: f = open(filename, 'w') - f.write(message) + f.write(message.encode("utf-8", "replace")) f.close() except Exception: logger.exception('Message not saved', exc_info=True) @@ -4020,6 +4044,7 @@ class MyForm(settingsmixin.SMainWindow): queryreturn = sqlQuery('''SELECT status FROM sent where ackdata=?''', ackData) for row in queryreturn: status, = row + status = status.decode("utf-8", "replace") if status == 'toodifficult': self.popMenuSent.addAction(self.actionForceSend) @@ -4124,6 +4149,7 @@ class MyForm(settingsmixin.SMainWindow): try: message = queryreturn[-1][0] + message = message.decode("utf-8", "replace") except NameError: message = "" except IndexError: diff --git a/src/bitmessageqt/account.py b/src/bitmessageqt/account.py index 8c82c6f6..794c276e 100644 --- a/src/bitmessageqt/account.py +++ b/src/bitmessageqt/account.py @@ -38,6 +38,8 @@ def getSortedSubscriptions(count=False): ret = {} for row in queryreturn: label, address, enabled = row + label = label.decode("utf-8", "replace") + address = address.decode("utf-8", "replace") ret[address] = {} ret[address]["inbox"] = {} ret[address]["inbox"]['label'] = label @@ -50,6 +52,8 @@ def getSortedSubscriptions(count=False): GROUP BY inbox.fromaddress, folder''', str_broadcast_subscribers) for row in queryreturn: address, folder, cnt = row + address = address.decode("utf-8", "replace") + folder = folder.decode("utf-8", "replace") if folder not in ret[address]: ret[address][folder] = { 'label': ret[address]['inbox']['label'], @@ -137,12 +141,14 @@ class BMAccount(object): if queryreturn != []: for row in queryreturn: label, = row + label = label.decode("utf-8", "replace") else: queryreturn = sqlQuery( '''select label from subscriptions where address=?''', address) if queryreturn != []: for row in queryreturn: label, = row + label = label.replace("utf-8", "replace") return label def parseMessage(self, toAddress, fromAddress, subject, message): @@ -150,10 +156,7 @@ class BMAccount(object): self.toAddress = toAddress self.fromAddress = fromAddress - if isinstance(subject, unicode): - self.subject = str(subject) - else: - self.subject = subject + self.subject = subject self.message = message self.fromLabel = self.getLabel(fromAddress) self.toLabel = self.getLabel(toAddress) @@ -202,11 +205,11 @@ class GatewayAccount(BMAccount): sqlExecute( '''INSERT INTO sent VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)''', '', - self.toAddress, + self.toAddress.encode("utf-8", "replace"), ripe, - self.fromAddress, - self.subject, - self.message, + self.fromAddress.encode("utf-8", "replace"), + self.subject.encode("utf-8", "replace"), + self.message.encode("utf-8", "replace"), ackdata, int(time.time()), # sentTime (this will never change) int(time.time()), # lastActionTime diff --git a/src/bitmessageqt/blacklist.py b/src/bitmessageqt/blacklist.py index 093f23d8..41342bce 100644 --- a/src/bitmessageqt/blacklist.py +++ b/src/bitmessageqt/blacklist.py @@ -111,10 +111,10 @@ class Blacklist(QtGui.QWidget, RetranslateMixin): if isinstance(addressitem, QtGui.QTableWidgetItem): if self.radioButtonBlacklist.isChecked(): sqlExecute('''UPDATE blacklist SET label=? WHERE address=?''', - str(item.text()), str(addressitem.text())) + item.text().encode("utf-8", "replace"), addressitem.text().encode("utf-8", "replace")) else: sqlExecute('''UPDATE whitelist SET label=? WHERE address=?''', - str(item.text()), str(addressitem.text())) + item.text().encode("utf-8", "replace"), addressitem.text().encode("utf-8", "replace")) def init_blacklist_popup_menu(self, connectSignal=True): # Popup menu for the Blacklist page @@ -171,6 +171,8 @@ class Blacklist(QtGui.QWidget, RetranslateMixin): self.tableWidgetBlacklist.setSortingEnabled(False) for row in queryreturn: label, address, enabled = row + label = label.decode("utf-8", "replace") + address = address.decode("utf-8", "replace") self.tableWidgetBlacklist.insertRow(0) newItem = QtGui.QTableWidgetItem(unicode(label, 'utf-8')) if not enabled: @@ -198,11 +200,11 @@ class Blacklist(QtGui.QWidget, RetranslateMixin): if config.get('bitmessagesettings', 'blackwhitelist') == 'black': sqlExecute( '''DELETE FROM blacklist WHERE label=? AND address=?''', - str(labelAtCurrentRow), str(addressAtCurrentRow)) + labelAtCurrentRow.encode("utf-8", "replace"), addressAtCurrentRow.encode("utf-8", "replace")) else: sqlExecute( '''DELETE FROM whitelist WHERE label=? AND address=?''', - str(labelAtCurrentRow), str(addressAtCurrentRow)) + labelAtCurrentRow.encode("utf-8", "replace"), addressAtCurrentRow.encode("utf-8", "replace")) self.tableWidgetBlacklist.removeRow(currentRow) def on_action_BlacklistClipboard(self): @@ -227,11 +229,11 @@ class Blacklist(QtGui.QWidget, RetranslateMixin): if config.get('bitmessagesettings', 'blackwhitelist') == 'black': sqlExecute( '''UPDATE blacklist SET enabled=1 WHERE address=?''', - str(addressAtCurrentRow)) + addressAtCurrentRow.encode("utf-8", "replace")) else: sqlExecute( '''UPDATE whitelist SET enabled=1 WHERE address=?''', - str(addressAtCurrentRow)) + addressAtCurrentRow.encode("utf-8", "replace")) def on_action_BlacklistDisable(self): currentRow = self.tableWidgetBlacklist.currentRow() @@ -243,10 +245,10 @@ class Blacklist(QtGui.QWidget, RetranslateMixin): currentRow, 1).setTextColor(QtGui.QColor(128, 128, 128)) if config.get('bitmessagesettings', 'blackwhitelist') == 'black': sqlExecute( - '''UPDATE blacklist SET enabled=0 WHERE address=?''', str(addressAtCurrentRow)) + '''UPDATE blacklist SET enabled=0 WHERE address=?''', addressAtCurrentRow.encode("utf-8", "replace")) else: sqlExecute( - '''UPDATE whitelist SET enabled=0 WHERE address=?''', str(addressAtCurrentRow)) + '''UPDATE whitelist SET enabled=0 WHERE address=?''', addressAtCurrentRow.encode("utf-8", "replace")) def on_action_BlacklistSetAvatar(self): self.window().on_action_SetAvatar(self.tableWidgetBlacklist) diff --git a/src/bitmessageqt/foldertree.py b/src/bitmessageqt/foldertree.py index c50b7d3d..2acf215d 100644 --- a/src/bitmessageqt/foldertree.py +++ b/src/bitmessageqt/foldertree.py @@ -136,7 +136,7 @@ class AccountMixin(object): if queryreturn != []: for row in queryreturn: retval, = row - retval = unicode(retval, 'utf-8') + retval = retval.decode("utf-8", "replace") elif self.address is None or self.type == AccountMixin.ALL: return unicode( str(_translate("MainWindow", "All accounts")), 'utf-8') @@ -311,8 +311,8 @@ class Ui_SubscriptionWidget(Ui_AddressWidget): if queryreturn != []: for row in queryreturn: retval, = row - return unicode(retval, 'utf-8', 'ignore') - return unicode(self.address, 'utf-8') + return retval.decode("utf-8", "replace") + return self.address def setType(self): """Set account type""" @@ -418,7 +418,8 @@ class MessageList_AddressWidget(BMAddressWidget): '''select label from subscriptions where address=?''', self.address) if queryreturn: for row in queryreturn: - newLabel = unicode(row[0], 'utf-8', 'ignore') + newLabel = row[0] + newLabel = newLabel.decode("utf-8", "replace") self.label = newLabel @@ -456,7 +457,7 @@ class MessageList_SubjectWidget(BMTableWidgetItem): if role == QtCore.Qt.UserRole: return self.subject if role == QtCore.Qt.ToolTipRole: - return escape(unicode(self.subject, 'utf-8')) + return escape(self.subject) return super(MessageList_SubjectWidget, self).data(role) # label (or address) alphabetically, disabled at the end diff --git a/src/bitmessageqt/safehtmlparser.py b/src/bitmessageqt/safehtmlparser.py index d408d2c7..d027ec44 100644 --- a/src/bitmessageqt/safehtmlparser.py +++ b/src/bitmessageqt/safehtmlparser.py @@ -125,6 +125,8 @@ class SafeHTMLParser(HTMLParser): def feed(self, data): try: data = unicode(data, 'utf-8') + except TypeError: + pass except UnicodeDecodeError: data = unicode(data, 'utf-8', errors='replace') HTMLParser.feed(self, data) diff --git a/src/class_singleCleaner.py b/src/class_singleCleaner.py index 06153dcf..21aadfad 100644 --- a/src/class_singleCleaner.py +++ b/src/class_singleCleaner.py @@ -99,6 +99,8 @@ class singleCleaner(StoppableThread): tick - state.maximumLengthOfTimeToBotherResendingMessages ) for toAddress, ackData, status in queryreturn: + toAddress = toAddress.decode("utf-8", "replace") + status = status.decode("utf-8", "replace") if status == 'awaitingpubkey': self.resendPubkeyRequest(toAddress) elif status == 'msgsent': diff --git a/src/class_singleWorker.py b/src/class_singleWorker.py index f2821f65..71e24c2e 100644 --- a/src/class_singleWorker.py +++ b/src/class_singleWorker.py @@ -73,6 +73,7 @@ class singleWorker(StoppableThread): '''SELECT DISTINCT toaddress FROM sent''' ''' WHERE (status='awaitingpubkey' AND folder='sent')''') for toAddress, in queryreturn: + toAddress = toAddress.decode("utf-8", "replace") toAddressVersionNumber, toStreamNumber, toRipe = \ decodeAddress(toAddress)[1:] if toAddressVersionNumber <= 3: @@ -538,6 +539,9 @@ class singleWorker(StoppableThread): for row in queryreturn: fromaddress, subject, body, ackdata, TTL, encoding = row + fromaddress = fromaddress.decode("utf-8", "replace") + subject = subject.decode("utf-8", "replace") + body = body.decode("utf-8", "replace") # status _, addressVersionNumber, streamNumber, ripe = \ decodeAddress(fromaddress) @@ -726,6 +730,11 @@ class singleWorker(StoppableThread): for row in queryreturn: toaddress, fromaddress, subject, message, \ ackdata, status, TTL, retryNumber, encoding = row + toaddress = toaddress.decode("utf-8", "replace") + fromaddress = fromaddress.decode("utf-8", "replace") + subject = subject.decode("utf-8", "replace") + message = message.decode("utf-8", "replace") + status = status.decode("utf-8", "replace") # toStatus _, toAddressVersionNumber, toStreamNumber, toRipe = \ decodeAddress(toaddress) diff --git a/src/class_sqlThread.py b/src/class_sqlThread.py index 7df9e253..49e4b98b 100644 --- a/src/class_sqlThread.py +++ b/src/class_sqlThread.py @@ -38,7 +38,7 @@ class sqlThread(threading.Thread): helper_sql.sql_available = True config_ready.wait() self.conn = sqlite3.connect(state.appdata + 'messages.dat') - self.conn.text_factory = str + self.conn.text_factory = bytes self.cur = self.conn.cursor() self.cur.execute('PRAGMA secure_delete = true') @@ -542,7 +542,7 @@ class sqlThread(threading.Thread): shutil.move( paths.lookupAppdataFolder() + 'messages.dat', paths.lookupExeFolder() + 'messages.dat') self.conn = sqlite3.connect(paths.lookupExeFolder() + 'messages.dat') - self.conn.text_factory = str + self.conn.text_factory = bytes self.cur = self.conn.cursor() elif item == 'movemessagstoappdata': logger.debug('the sqlThread is moving the messages.dat file to the Appdata folder.') @@ -568,7 +568,7 @@ class sqlThread(threading.Thread): shutil.move( paths.lookupExeFolder() + 'messages.dat', paths.lookupAppdataFolder() + 'messages.dat') self.conn = sqlite3.connect(paths.lookupAppdataFolder() + 'messages.dat') - self.conn.text_factory = str + self.conn.text_factory = bytes self.cur = self.conn.cursor() elif item == 'deleteandvacuume': self.cur.execute('''delete from inbox where folder='trash' ''') diff --git a/src/helper_msgcoding.py b/src/helper_msgcoding.py index 05fa1c1b..62214525 100644 --- a/src/helper_msgcoding.py +++ b/src/helper_msgcoding.py @@ -71,7 +71,8 @@ class MsgEncode(object): def encodeSimple(self, message): """Handle simple encoding""" - self.data = 'Subject:%(subject)s\nBody:%(body)s' % message + data = 'Subject:%(subject)s\nBody:%(body)s' % message + self.data = data.encode("utf-8", "replace") self.length = len(self.data) def encodeTrivial(self, message): diff --git a/src/shared.py b/src/shared.py index b85ddb20..aa7b6bb4 100644 --- a/src/shared.py +++ b/src/shared.py @@ -47,7 +47,7 @@ def isAddressInMySubscriptionsList(address): """Am I subscribed to this address?""" queryreturn = sqlQuery( '''select * from subscriptions where address=?''', - str(address)) + address.encode("utf-8", "replace")) return queryreturn != [] @@ -136,6 +136,7 @@ def reloadBroadcastSendersForWhichImWatching(): logger.debug('reloading subscriptions...') for row in queryreturn: address, = row + address = address.decode("utf-8", "replace") # status addressVersionNumber, streamNumber, hashobj = decodeAddress(address)[1:] if addressVersionNumber == 2: diff --git a/src/tests/test_shared.py b/src/tests/test_shared.py index 39bedf32..3e9be107 100644 --- a/src/tests/test_shared.py +++ b/src/tests/test_shared.py @@ -46,7 +46,7 @@ class TestShared(unittest.TestCase): address = sample_address # if address is in MyAddressbook - mock_sql_query.return_value = [address] + mock_sql_query.return_value = [address.encode("utf-8", "replace")] return_val = isAddressInMyAddressBook(address) mock_sql_query.assert_called_once() self.assertTrue(return_val) @@ -64,7 +64,7 @@ class TestShared(unittest.TestCase): address = sample_address # if address is in MySubscriptionsList - mock_sql_query.return_value = [address] + mock_sql_query.return_value = [address.encode("utf-8", "replace")] return_val = isAddressInMySubscriptionsList(address) self.assertTrue(return_val) @@ -78,7 +78,7 @@ class TestShared(unittest.TestCase): def test_reloadBroadcastSendersForWhichImWatching(self, mock_sql_query): """Test for reload Broadcast Senders For Which Im Watching""" mock_sql_query.return_value = [ - (sample_address,), + (sample_address.encode("utf-8", "replace"),), ] # before reload self.assertEqual(len(MyECSubscriptionCryptorObjects), 0) -- 2.45.1 From d38f42517cf9a0d57bc91ba99d2d8e4d11b9dba2 Mon Sep 17 00:00:00 2001 From: Kashiko Koibumi Date: Mon, 27 May 2024 05:49:26 +0900 Subject: [PATCH 051/105] fix address validator to work --- src/bitmessageqt/addressvalidator.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/bitmessageqt/addressvalidator.py b/src/bitmessageqt/addressvalidator.py index 382e5c25..0dd87eb4 100644 --- a/src/bitmessageqt/addressvalidator.py +++ b/src/bitmessageqt/addressvalidator.py @@ -122,13 +122,13 @@ class AddressPassPhraseValidatorMixin(object): # no chan name if passPhrase is None: self.setError(_translate("AddressValidator", "Chan name/passphrase needed. You didn't enter a chan name.")) - return (QtGui.QValidator.Intermediate, pos) + return (QtGui.QValidator.Intermediate, s, pos) if self.addressMandatory or address is not None: # check if address already exists: if address in config.addresses(): self.setError(_translate("AddressValidator", "Address already present as one of your identities.")) - return (QtGui.QValidator.Intermediate, pos) + return (QtGui.QValidator.Intermediate, s, pos) # version too high if decodeAddress(address)[0] == 'versiontoohigh': @@ -139,12 +139,12 @@ class AddressPassPhraseValidatorMixin(object): " address might be valid, its version number" " is too new for us to handle. Perhaps you need" " to upgrade Bitmessage.")) - return (QtGui.QValidator.Intermediate, pos) + return (QtGui.QValidator.Intermediate, s, pos) # invalid if decodeAddress(address)[0] != 'success': self.setError(_translate("AddressValidator", "The Bitmessage address is not valid.")) - return (QtGui.QValidator.Intermediate, pos) + return (QtGui.QValidator.Intermediate, s, pos) # this just disables the OK button without changing the feedback text # but only if triggered by textEdited, not by clicking the Ok button @@ -160,8 +160,8 @@ class AddressPassPhraseValidatorMixin(object): "{} {}".format(str_chan, passPhrase), passPhrase, False)) if self.buttonBox.button(QtGui.QDialogButtonBox.Ok).hasFocus(): - return (self.returnValid(), pos) - return (QtGui.QValidator.Intermediate, pos) + return (self.returnValid(), s, pos) + return (QtGui.QValidator.Intermediate, s, pos) def checkData(self): """Validator Qt signal interface""" -- 2.45.1 From 96c764bd9424c0a8c573525e691b46b958034b36 Mon Sep 17 00:00:00 2001 From: Kashiko Koibumi Date: Mon, 27 May 2024 22:43:01 +0900 Subject: [PATCH 052/105] refined: read from and write to SQLite database in binary mode This modification is a preparation for migration to Python3. --- src/api.py | 34 +++++----- src/bitmessagecurses/__init__.py | 71 +++++++++++++-------- src/bitmessagekivy/baseclass/addressbook.py | 16 +++-- src/bitmessagekivy/baseclass/maildetail.py | 10 +-- src/bitmessagekivy/baseclass/popup.py | 13 ++-- src/bitmessagekivy/kivy_helper_search.py | 13 ++-- src/bitmessageqt/__init__.py | 23 ++++--- src/bitmessageqt/account.py | 25 ++++---- src/bitmessageqt/blacklist.py | 21 +++--- src/bitmessageqt/foldertree.py | 19 +++--- src/bitmessageqt/support.py | 7 +- src/class_objectProcessor.py | 33 +++++----- src/class_singleCleaner.py | 3 +- src/class_singleWorker.py | 27 ++++---- src/class_smtpServer.py | 13 ++-- src/dbcompat.py | 22 +++++++ src/helper_addressbook.py | 3 +- src/helper_inbox.py | 4 +- src/helper_search.py | 13 ++-- src/helper_sent.py | 5 +- src/protocol.py | 3 +- src/shared.py | 11 ++-- src/storage/sqlite.py | 2 +- src/tests/core.py | 9 +-- src/tests/test_helper_inbox.py | 8 +-- src/tests/test_helper_sent.py | 18 +++--- src/tests/test_helper_sql.py | 10 +-- src/tests/test_shared.py | 6 +- src/tests/test_sqlthread.py | 2 +- 29 files changed, 259 insertions(+), 185 deletions(-) create mode 100644 src/dbcompat.py diff --git a/src/api.py b/src/api.py index a4445569..d69f6506 100644 --- a/src/api.py +++ b/src/api.py @@ -70,6 +70,7 @@ from struct import pack, unpack import six from six.moves import configparser, http_client, xmlrpc_server +from dbcompat import dbstr import helper_inbox import helper_sent @@ -531,12 +532,12 @@ class BMRPCDispatcher(object): message = shared.fixPotentiallyInvalidUTF8Data(message) return { 'msgid': hexlify(msgid), - 'toAddress': toAddress, - 'fromAddress': fromAddress, + 'toAddress': toAddress.decode("utf-8", "replace"), + 'fromAddress': fromAddress.decode("utf-8", "replace"), 'subject': base64.b64encode(subject), 'message': base64.b64encode(message), 'encodingType': encodingtype, - 'receivedTime': received, + 'receivedTime': received.decode("utf-8", "replace"), 'read': read } @@ -598,11 +599,12 @@ class BMRPCDispatcher(object): """ queryreturn = sqlQuery( "SELECT label, address from addressbook WHERE label = ?", - label + dbstr(label) ) if label else sqlQuery("SELECT label, address from addressbook") data = [] for label, address in queryreturn: label = shared.fixPotentiallyInvalidUTF8Data(label) + address = address.decode("utf-8", "replace") data.append({ 'label': base64.b64encode(label), 'address': address @@ -618,12 +620,12 @@ class BMRPCDispatcher(object): self._verifyAddress(address) # TODO: add unique together constraint in the table queryreturn = sqlQuery( - "SELECT address FROM addressbook WHERE address=?", address) + "SELECT address FROM addressbook WHERE address=?", dbstr(address)) if queryreturn != []: raise APIError( 16, 'You already have this address in your address book.') - sqlExecute("INSERT INTO addressbook VALUES(?,?)", label, address) + sqlExecute("INSERT INTO addressbook VALUES(?,?)", dbstr(label), dbstr(address)) queues.UISignalQueue.put(('rerenderMessagelistFromLabels', '')) queues.UISignalQueue.put(('rerenderMessagelistToLabels', '')) queues.UISignalQueue.put(('rerenderAddressBook', '')) @@ -635,7 +637,7 @@ class BMRPCDispatcher(object): """Delete an entry from address book.""" address = addBMIfNotPresent(address) self._verifyAddress(address) - sqlExecute('DELETE FROM addressbook WHERE address=?', address) + sqlExecute('DELETE FROM addressbook WHERE address=?', dbstr(address)) queues.UISignalQueue.put(('rerenderMessagelistFromLabels', '')) queues.UISignalQueue.put(('rerenderMessagelistToLabels', '')) queues.UISignalQueue.put(('rerenderAddressBook', '')) @@ -919,6 +921,7 @@ class BMRPCDispatcher(object): " ORDER BY received" ) return {"inboxMessages": [ + self._dump_inbox_message(*data) for data in queryreturn ]} @@ -1018,7 +1021,7 @@ class BMRPCDispatcher(object): queryreturn = sqlQuery( "SELECT msgid, toaddress, fromaddress, subject, received," " message, encodingtype, read FROM inbox WHERE folder='inbox'" - " AND toAddress=?", toAddress) + " AND toAddress=?", dbstr(toAddress)) return {"inboxMessages": [ self._dump_inbox_message(*data) for data in queryreturn ]} @@ -1055,7 +1058,7 @@ class BMRPCDispatcher(object): "SELECT msgid, toaddress, fromaddress, subject, lastactiontime," " message, encodingtype, status, ackdata FROM sent" " WHERE folder='sent' AND fromAddress=? ORDER BY lastactiontime", - fromAddress + dbstr(fromAddress) ) return {"sentMessages": [ self._dump_sent_message(*data) for data in queryreturn @@ -1150,9 +1153,9 @@ class BMRPCDispatcher(object): toLabel = '' queryreturn = sqlQuery( - "SELECT label FROM addressbook WHERE address=?", toAddress) + "SELECT label FROM addressbook WHERE address=?", dbstr(toAddress)) try: - toLabel = queryreturn[0][0] + toLabel = queryreturn[0][0].decode("utf-8", "replace") except IndexError: pass @@ -1219,7 +1222,7 @@ class BMRPCDispatcher(object): queryreturn = sqlQuery( "SELECT status FROM sent where ackdata=?", ackdata) try: - return queryreturn[0][0] + return queryreturn[0][0].decode("utf-8", "replace") except IndexError: return 'notfound' @@ -1238,11 +1241,11 @@ class BMRPCDispatcher(object): # First we must check to see if the address is already in the # subscriptions list. queryreturn = sqlQuery( - "SELECT * FROM subscriptions WHERE address=?", address) + "SELECT * FROM subscriptions WHERE address=?", dbstr(address)) if queryreturn: raise APIError(16, 'You are already subscribed to that address.') sqlExecute( - "INSERT INTO subscriptions VALUES (?,?,?)", label, address, True) + "INSERT INTO subscriptions VALUES (?,?,?)", dbstr(label), dbstr(address), True) shared.reloadBroadcastSendersForWhichImWatching() queues.UISignalQueue.put(('rerenderMessagelistFromLabels', '')) queues.UISignalQueue.put(('rerenderSubscriptions', '')) @@ -1256,7 +1259,7 @@ class BMRPCDispatcher(object): """ address = addBMIfNotPresent(address) - sqlExecute("DELETE FROM subscriptions WHERE address=?", address) + sqlExecute("DELETE FROM subscriptions WHERE address=?", dbstr(address)) shared.reloadBroadcastSendersForWhichImWatching() queues.UISignalQueue.put(('rerenderMessagelistFromLabels', '')) queues.UISignalQueue.put(('rerenderSubscriptions', '')) @@ -1274,6 +1277,7 @@ class BMRPCDispatcher(object): data = [] for label, address, enabled in queryreturn: label = shared.fixPotentiallyInvalidUTF8Data(label) + address = address.decode("utf-8", "replace") data.append({ 'label': base64.b64encode(label), 'address': address, diff --git a/src/bitmessagecurses/__init__.py b/src/bitmessagecurses/__init__.py index 64fd735b..f63f820a 100644 --- a/src/bitmessagecurses/__init__.py +++ b/src/bitmessagecurses/__init__.py @@ -30,6 +30,7 @@ import state from addresses import addBMIfNotPresent, decodeAddress from bmconfigparser import config from helper_sql import sqlExecute, sqlQuery +from dbcompat import dbstr # pylint: disable=global-statement @@ -401,6 +402,7 @@ def handlech(c, stdscr): body = "\n\n------------------------------------------------------\n" for row in ret: body, = row + body = body.decode("utf-8", "replace") sendMessage(fromaddr, toaddr, ischan, subject, body, True) dialogreset(stdscr) @@ -410,7 +412,7 @@ def handlech(c, stdscr): r, t = d.inputbox("Label for address \"" + addr + "\"") if r == d.DIALOG_OK: label = t - sqlExecute("INSERT INTO addressbook VALUES (?,?)", label, addr) + sqlExecute("INSERT INTO addressbook VALUES (?,?)", dbstr(label), dbstr(addr)) # Prepend entry addrbook.reverse() addrbook.append([label, addr]) @@ -426,6 +428,7 @@ def handlech(c, stdscr): if ret != []: for row in ret: msg, = row + msg = msg.decode("utf-8", "replace") fh = open(t, "a") # Open in append mode just in case fh.write(msg) fh.close() @@ -463,7 +466,7 @@ def handlech(c, stdscr): data = "" ret = sqlQuery( "SELECT message FROM sent WHERE subject=? AND ackdata=?", - sentbox[sentcur][4], + dbstr(sentbox[sentcur][4]), sentbox[sentcur][6]) if ret != []: for row in ret: @@ -478,7 +481,7 @@ def handlech(c, stdscr): elif t == "2": # Move to trash sqlExecute( "UPDATE sent SET folder='trash' WHERE subject=? AND ackdata=?", - sentbox[sentcur][4], + dbstr(sentbox[sentcur][4]), sentbox[sentcur][6]) del sentbox[sentcur] scrollbox(d, unicode( @@ -711,29 +714,29 @@ def handlech(c, stdscr): subscriptions.append([label, addr, True]) subscriptions.reverse() - sqlExecute("INSERT INTO subscriptions VALUES (?,?,?)", label, addr, True) + sqlExecute("INSERT INTO subscriptions VALUES (?,?,?)", dbstr(label), dbstr(addr), True) shared.reloadBroadcastSendersForWhichImWatching() elif t == "2": r, t = d.inputbox("Type in \"I want to delete this subscription\"") if r == d.DIALOG_OK and t == "I want to delete this subscription": sqlExecute( "DELETE FROM subscriptions WHERE label=? AND address=?", - subscriptions[subcur][0], - subscriptions[subcur][1]) + dbstr(subscriptions[subcur][0]), + dbstr(subscriptions[subcur][1])) shared.reloadBroadcastSendersForWhichImWatching() del subscriptions[subcur] elif t == "3": sqlExecute( "UPDATE subscriptions SET enabled=1 WHERE label=? AND address=?", - subscriptions[subcur][0], - subscriptions[subcur][1]) + dbstr(subscriptions[subcur][0]), + dbstr(subscriptions[subcur][1])) shared.reloadBroadcastSendersForWhichImWatching() subscriptions[subcur][2] = True elif t == "4": sqlExecute( "UPDATE subscriptions SET enabled=0 WHERE label=? AND address=?", - subscriptions[subcur][0], - subscriptions[subcur][1]) + dbstr(subscriptions[subcur][0]), + dbstr(subscriptions[subcur][1])) shared.reloadBroadcastSendersForWhichImWatching() subscriptions[subcur][2] = False elif menutab == 6: @@ -762,7 +765,7 @@ def handlech(c, stdscr): subscriptions.append([label, addr, True]) subscriptions.reverse() - sqlExecute("INSERT INTO subscriptions VALUES (?,?,?)", label, addr, True) + sqlExecute("INSERT INTO subscriptions VALUES (?,?,?)", dbstr(label), dbstr(addr), True) shared.reloadBroadcastSendersForWhichImWatching() elif t == "3": r, t = d.inputbox("Input new address") @@ -771,7 +774,7 @@ def handlech(c, stdscr): if addr not in [item[1] for i, item in enumerate(addrbook)]: r, t = d.inputbox("Label for address \"" + addr + "\"") if r == d.DIALOG_OK: - sqlExecute("INSERT INTO addressbook VALUES (?,?)", t, addr) + sqlExecute("INSERT INTO addressbook VALUES (?,?)", dbstr(t), dbstr(addr)) # Prepend entry addrbook.reverse() addrbook.append([t, addr]) @@ -783,8 +786,8 @@ def handlech(c, stdscr): if r == d.DIALOG_OK and t == "I want to delete this Address Book entry": sqlExecute( "DELETE FROM addressbook WHERE label=? AND address=?", - addrbook[abookcur][0], - addrbook[abookcur][1]) + dbstr(addrbook[abookcur][0]), + dbstr(addrbook[abookcur][1])) del addrbook[abookcur] elif menutab == 7: set_background_title(d, "Blacklist Dialog Box") @@ -800,20 +803,20 @@ def handlech(c, stdscr): if r == d.DIALOG_OK and t == "I want to delete this Blacklist entry": sqlExecute( "DELETE FROM blacklist WHERE label=? AND address=?", - blacklist[blackcur][0], - blacklist[blackcur][1]) + dbstr(blacklist[blackcur][0]), + dbstr(blacklist[blackcur][1])) del blacklist[blackcur] elif t == "2": sqlExecute( "UPDATE blacklist SET enabled=1 WHERE label=? AND address=?", - blacklist[blackcur][0], - blacklist[blackcur][1]) + dbstr(blacklist[blackcur][0]), + dbstr(blacklist[blackcur][1])) blacklist[blackcur][2] = True elif t == "3": sqlExecute( "UPDATE blacklist SET enabled=0 WHERE label=? AND address=?", - blacklist[blackcur][0], - blacklist[blackcur][1]) + dbstr(blacklist[blackcur][0]), + dbstr(blacklist[blackcur][1])) blacklist[blackcur][2] = False dialogreset(stdscr) else: @@ -991,10 +994,13 @@ def loadInbox(): ret = sqlQuery("""SELECT msgid, toaddress, fromaddress, subject, received, read FROM inbox WHERE folder='inbox' AND %s LIKE ? ORDER BY received - """ % (where,), what) + """ % (where,), dbstr(what)) for row in ret: msgid, toaddr, fromaddr, subject, received, read = row + toaddr = toaddr.decode("utf-8", "replace") + fromaddr = fromaddr.decode("utf-8", "replace") subject = ascii(shared.fixPotentiallyInvalidUTF8Data(subject)) + received = received.decode("utf-8", "replace") # Set label for to address try: @@ -1013,18 +1019,19 @@ def loadInbox(): if config.has_section(fromaddr): fromlabel = config.get(fromaddr, "label") if fromlabel == "": # Check Address Book - qr = sqlQuery("SELECT label FROM addressbook WHERE address=?", fromaddr) + qr = sqlQuery("SELECT label FROM addressbook WHERE address=?", dbstr(fromaddr)) if qr != []: for r in qr: fromlabel, = r + fromlabel = shared.fixPotentiallyInvalidUTF8Data(fromlabel) if fromlabel == "": # Check Subscriptions - qr = sqlQuery("SELECT label FROM subscriptions WHERE address=?", fromaddr) + qr = sqlQuery("SELECT label FROM subscriptions WHERE address=?", dbstr(fromaddr)) if qr != []: for r in qr: fromlabel, = r + fromlabel = shared.fixPotentiallyInvalidUTF8Data(fromlabel) if fromlabel == "": fromlabel = fromaddr - fromlabel = shared.fixPotentiallyInvalidUTF8Data(fromlabel) # Load into array inbox.append([ @@ -1044,22 +1051,27 @@ def loadSent(): ret = sqlQuery("""SELECT toaddress, fromaddress, subject, status, ackdata, lastactiontime FROM sent WHERE folder='sent' AND %s LIKE ? ORDER BY lastactiontime - """ % (where,), what) + """ % (where,), dbstr(what)) for row in ret: toaddr, fromaddr, subject, status, ackdata, lastactiontime = row + toaddr = toaddr.decode("utf-8", "replace") + fromaddr = fromaddr.decode("utf-8", "replace") subject = ascii(shared.fixPotentiallyInvalidUTF8Data(subject)) + status = status.decode("utf-8", "replace") # Set label for to address tolabel = "" - qr = sqlQuery("SELECT label FROM addressbook WHERE address=?", toaddr) + qr = sqlQuery("SELECT label FROM addressbook WHERE address=?", dbstr(toaddr)) if qr != []: for r in qr: tolabel, = r + tolabel = tolabel.decode("utf-8", "replace") if tolabel == "": - qr = sqlQuery("SELECT label FROM subscriptions WHERE address=?", toaddr) + qr = sqlQuery("SELECT label FROM subscriptions WHERE address=?", dbstr(toaddr)) if qr != []: for r in qr: tolabel, = r + tolabel = tolabel.decode("utf-8", "replace") if tolabel == "": if config.has_section(toaddr): tolabel = config.get(toaddr, "label") @@ -1129,6 +1141,7 @@ def loadAddrBook(): for row in ret: label, addr = row label = shared.fixPotentiallyInvalidUTF8Data(label) + addr = addr.decode("utf-8", "replace") addrbook.append([label, addr]) addrbook.reverse() @@ -1138,6 +1151,8 @@ def loadSubscriptions(): ret = sqlQuery("SELECT label, address, enabled FROM subscriptions") for row in ret: label, address, enabled = row + label = label.decode("utf-8", "replace") + address = address.decode("utf-8", "replace") subscriptions.append([label, address, enabled]) subscriptions.reverse() @@ -1152,6 +1167,8 @@ def loadBlackWhiteList(): ret = sqlQuery("SELECT label, address, enabled FROM whitelist") for row in ret: label, address, enabled = row + label = label.decode("utf-8", "replace") + address = address.decode("utf-8", "replace") blacklist.append([label, address, enabled]) blacklist.reverse() diff --git a/src/bitmessagekivy/baseclass/addressbook.py b/src/bitmessagekivy/baseclass/addressbook.py index f18a0142..1000bd53 100644 --- a/src/bitmessagekivy/baseclass/addressbook.py +++ b/src/bitmessagekivy/baseclass/addressbook.py @@ -29,6 +29,7 @@ from pybitmessage.bitmessagekivy.baseclass.common import ( from pybitmessage.bitmessagekivy.baseclass.popup import SavedAddressDetailPopup from pybitmessage.bitmessagekivy.baseclass.addressbook_widgets import HelperAddressBook from pybitmessage.helper_sql import sqlExecute +from dbcompat import dbstr logger = logging.getLogger('default') @@ -59,7 +60,7 @@ class AddressBook(Screen, HelperAddressBook): self.ids.tag_label.text = '' self.queryreturn = kivy_helper_search.search_sql( xAddress, account, "addressbook", where, what, False) - self.queryreturn = [obj for obj in reversed(self.queryreturn)] + self.queryreturn = [[obj[0].decode("utf-8", "replace"), obj[1].decode("utf-8", "replace")] for obj in reversed(self.queryreturn)] if self.queryreturn: self.ids.tag_label.text = 'Address Book' self.has_refreshed = True @@ -131,7 +132,7 @@ class AddressBook(Screen, HelperAddressBook): if self.ids.ml.children is not None: self.ids.tag_label.text = '' sqlExecute( - "DELETE FROM addressbook WHERE address = ?", address) + "DELETE FROM addressbook WHERE address = ?", dbstr(address)) toast('Address Deleted') def close_pop(self, instance): @@ -142,8 +143,13 @@ class AddressBook(Screen, HelperAddressBook): def update_addbook_label(self, instance): """Updating the label of address book address""" address_list = kivy_helper_search.search_sql(folder="addressbook") - stored_labels = [labels[0] for labels in address_list] - add_dict = dict(address_list) + stored_labels = [labels[0].decode("utf-8", "replace") for labels in address_list] + add_dict = {} + for row in address_list: + label, address = row + label = label.decode("utf-8", "replace") + address = address.decode("utf-8", "replace") + add_dict[label] = address label = str(self.addbook_popup.content_cls.ids.add_label.text) if label in stored_labels and self.address == add_dict[label]: stored_labels.remove(label) @@ -151,7 +157,7 @@ class AddressBook(Screen, HelperAddressBook): sqlExecute(""" UPDATE addressbook SET label = ? - WHERE address = ?""", label, self.addbook_popup.content_cls.address) + WHERE address = ?""", dbstr(label), dbstr(self.addbook_popup.content_cls.address)) App.get_running_app().root.ids.id_addressbook.ids.ml.clear_widgets() App.get_running_app().root.ids.id_addressbook.loadAddresslist(None, 'All', '') self.addbook_popup.dismiss() diff --git a/src/bitmessagekivy/baseclass/maildetail.py b/src/bitmessagekivy/baseclass/maildetail.py index 6ddf322d..5168a522 100644 --- a/src/bitmessagekivy/baseclass/maildetail.py +++ b/src/bitmessagekivy/baseclass/maildetail.py @@ -119,16 +119,16 @@ class MailDetail(Screen): # pylint: disable=too-many-instance-attributes def assign_mail_details(self, data): """Assigning mail details""" - subject = data[0][2].decode() if isinstance(data[0][2], bytes) else data[0][2] - body = data[0][3].decode() if isinstance(data[0][2], bytes) else data[0][3] - self.to_addr = data[0][0] if len(data[0][0]) > 4 else ' ' - self.from_addr = data[0][1] + subject = data[0][2].decode("utf-8", "replace") if isinstance(data[0][2], bytes) else data[0][2] + body = data[0][3].decode("utf-8", "replace") if isinstance(data[0][2], bytes) else data[0][3] + self.to_addr = data[0][0].decode("utf-8", "replace") if len(data[0][0]) > 4 else ' ' + self.from_addr = data[0][1].decode("utf-8", "replace") self.subject = subject.capitalize( ) if subject.capitalize() else self.no_subject self.message = body if len(data[0]) == 7: - self.status = data[0][4] + self.status = data[0][4].decode("utf-8", "replace") self.time_tag = show_time_history(data[0][4]) if self.kivy_state.detail_page_type == 'inbox' \ else show_time_history(data[0][6]) self.avatarImg = os.path.join(self.kivy_state.imageDir, 'draft-icon.png') \ diff --git a/src/bitmessagekivy/baseclass/popup.py b/src/bitmessagekivy/baseclass/popup.py index d2a4c859..48868f68 100644 --- a/src/bitmessagekivy/baseclass/popup.py +++ b/src/bitmessagekivy/baseclass/popup.py @@ -59,7 +59,7 @@ class AddAddressPopup(BoxLayout): """Checking address is valid or not""" my_addresses = ( App.get_running_app().root.ids.content_drawer.ids.identity_dropdown.values) - add_book = [addr[1] for addr in kivy_helper_search.search_sql( + add_book = [addr[1].decode("utf-8", "replace") for addr in kivy_helper_search.search_sql( folder="addressbook")] entered_text = str(instance.text).strip() if entered_text in add_book: @@ -84,7 +84,7 @@ class AddAddressPopup(BoxLayout): def checkLabel_valid(self, instance): """Checking address label is unique or not""" entered_label = instance.text.strip() - addr_labels = [labels[0] for labels in kivy_helper_search.search_sql( + addr_labels = [labels[0].decode("utf-8", "replace") for labels in kivy_helper_search.search_sql( folder="addressbook")] if entered_label in addr_labels: self.ids.label.error = True @@ -125,8 +125,13 @@ class SavedAddressDetailPopup(BoxLayout): """Checking address label is unique of not""" entered_label = str(instance.text.strip()) address_list = kivy_helper_search.search_sql(folder="addressbook") - addr_labels = [labels[0] for labels in address_list] - add_dict = dict(address_list) + addr_labels = [labels[0].decode("utf-8", "replace") for labels in address_list] + add_dict = {} + for row in address_list: + label, address = row + label = label.decode("utf-8", "replace") + address = address.decode("utf-8", "replace") + add_dict[label] = address if self.address and entered_label in addr_labels \ and self.address != add_dict[entered_label]: self.ids.add_label.error = True diff --git a/src/bitmessagekivy/kivy_helper_search.py b/src/bitmessagekivy/kivy_helper_search.py index c48ca3ad..82283481 100644 --- a/src/bitmessagekivy/kivy_helper_search.py +++ b/src/bitmessagekivy/kivy_helper_search.py @@ -2,6 +2,7 @@ Sql queries for bitmessagekivy """ from pybitmessage.helper_sql import sqlQuery +from dbcompat import dbstr def search_sql( @@ -30,21 +31,21 @@ def search_sql( if account is not None: if xAddress == 'both': sqlStatementParts.append("(fromaddress = ? OR toaddress = ?)") - sqlArguments.append(account) - sqlArguments.append(account) + sqlArguments.append(dbstr(account)) + sqlArguments.append(dbstr(account)) else: sqlStatementParts.append(xAddress + " = ? ") - sqlArguments.append(account) + sqlArguments.append(dbstr(account)) if folder != "addressbook": if folder is not None: if folder == "new": folder = "inbox" unreadOnly = True sqlStatementParts.append("folder = ? ") - sqlArguments.append(folder) + sqlArguments.append(dbstr(folder)) else: sqlStatementParts.append("folder != ?") - sqlArguments.append("trash") + sqlArguments.append(dbstr("trash")) if what is not None: for colmns in where: if len(where) > 1: @@ -54,7 +55,7 @@ def search_sql( filter_col += " or %s LIKE ? )" % (colmns) else: filter_col = "%s LIKE ?" % (colmns) - sqlArguments.append(what) + sqlArguments.append(dbstr(what)) sqlStatementParts.append(filter_col) if unreadOnly: sqlStatementParts.append("read = 0") diff --git a/src/bitmessageqt/__init__.py b/src/bitmessageqt/__init__.py index fd012e04..df58e403 100644 --- a/src/bitmessageqt/__init__.py +++ b/src/bitmessageqt/__init__.py @@ -17,6 +17,7 @@ from sqlite3 import register_adapter from PyQt4 import QtCore, QtGui from PyQt4.QtNetwork import QLocalSocket, QLocalServer +from dbcompat import dbstr import shared import state @@ -1067,8 +1068,10 @@ class MyForm(settingsmixin.SMainWindow): queryReturn = sqlQuery( 'SELECT fromaddress, folder, COUNT(msgid) AS cnt' ' FROM inbox WHERE read = 0 AND toaddress = ?' - ' GROUP BY fromaddress, folder', str_broadcast_subscribers) + ' GROUP BY fromaddress, folder', dbstr(str_broadcast_subscribers)) for addr, fld, count in queryReturn: + addr = addr.decode("utf-8", "replace") + fld = fld.decode("utf-8", "replace") try: broadcastsUnread[addr][fld] = count except KeyError: @@ -2289,7 +2292,7 @@ class MyForm(settingsmixin.SMainWindow): subject=subject, message=message, encoding=encoding) toLabel = '' queryreturn = sqlQuery('''select label from addressbook where address=?''', - toAddress) + dbstr(toAddress)) if queryreturn != []: for row in queryreturn: toLabel, = row @@ -2578,7 +2581,7 @@ class MyForm(settingsmixin.SMainWindow): # Add to database (perhaps this should be separated from the MyForm class) sqlExecute( '''INSERT INTO subscriptions VALUES (?,?,?)''', - label, address, True + dbstr(label), dbstr(address), True ) self.rerenderMessagelistFromLabels() shared.reloadBroadcastSendersForWhichImWatching() @@ -3177,13 +3180,13 @@ class MyForm(settingsmixin.SMainWindow): currentInboxRow, 0).data(QtCore.Qt.UserRole) # Let's make sure that it isn't already in the address book queryreturn = sqlQuery('''select * from blacklist where address=?''', - addressAtCurrentInboxRow) + dbstr(addressAtCurrentInboxRow)) if queryreturn == []: label = "\"" + tableWidget.item(currentInboxRow, 2).subject + "\" in " + config.get( recipientAddress, "label") sqlExecute('''INSERT INTO blacklist VALUES (?,?, ?)''', - label, - addressAtCurrentInboxRow, True) + dbstr(label), + dbstr(addressAtCurrentInboxRow), True) self.ui.blackwhitelist.rerenderBlackWhiteList() self.updateStatusBar(_translate( "MainWindow", @@ -3370,7 +3373,7 @@ class MyForm(settingsmixin.SMainWindow): 0].row() item = self.ui.tableWidgetAddressBook.item(currentRow, 0) sqlExecute( - 'DELETE FROM addressbook WHERE address=?', item.address) + 'DELETE FROM addressbook WHERE address=?', dbstr(item.address)) self.ui.tableWidgetAddressBook.removeRow(currentRow) self.rerenderMessagelistFromLabels() self.rerenderMessagelistToLabels() @@ -3470,7 +3473,7 @@ class MyForm(settingsmixin.SMainWindow): return address = self.getCurrentAccount() sqlExecute('''DELETE FROM subscriptions WHERE address=?''', - address) + dbstr(address)) self.rerenderTabTreeSubscriptions() self.rerenderMessagelistFromLabels() self.rerenderAddressBook() @@ -3485,7 +3488,7 @@ class MyForm(settingsmixin.SMainWindow): address = self.getCurrentAccount() sqlExecute( '''update subscriptions set enabled=1 WHERE address=?''', - address) + dbstr(address)) account = self.getCurrentItem() account.setEnabled(True) self.rerenderAddressBook() @@ -3495,7 +3498,7 @@ class MyForm(settingsmixin.SMainWindow): address = self.getCurrentAccount() sqlExecute( '''update subscriptions set enabled=0 WHERE address=?''', - address) + dbstr(address)) account = self.getCurrentItem() account.setEnabled(False) self.rerenderAddressBook() diff --git a/src/bitmessageqt/account.py b/src/bitmessageqt/account.py index 794c276e..acb611c8 100644 --- a/src/bitmessageqt/account.py +++ b/src/bitmessageqt/account.py @@ -15,6 +15,7 @@ import sys import time from PyQt4 import QtGui +from dbcompat import dbstr import queues from addresses import decodeAddress @@ -49,7 +50,7 @@ def getSortedSubscriptions(count=False): queryreturn = sqlQuery('''SELECT fromaddress, folder, count(msgid) as cnt FROM inbox, subscriptions ON subscriptions.address = inbox.fromaddress WHERE read = 0 AND toaddress = ? - GROUP BY inbox.fromaddress, folder''', str_broadcast_subscribers) + GROUP BY inbox.fromaddress, folder''', dbstr(str_broadcast_subscribers)) for row in queryreturn: address, folder, cnt = row address = address.decode("utf-8", "replace") @@ -104,7 +105,7 @@ class AccountColor(AccountMixin): # pylint: disable=too-few-public-methods elif config.safeGetBoolean(self.address, 'chan'): self.type = AccountMixin.CHAN elif sqlQuery( - '''select label from subscriptions where address=?''', self.address): + '''select label from subscriptions where address=?''', dbstr(self.address)): self.type = AccountMixin.SUBSCRIPTION else: self.type = AccountMixin.NORMAL @@ -127,7 +128,7 @@ class BMAccount(object): self.type = AccountMixin.BROADCAST else: queryreturn = sqlQuery( - '''select label from subscriptions where address=?''', self.address) + '''select label from subscriptions where address=?''', dbstr(self.address)) if queryreturn: self.type = AccountMixin.SUBSCRIPTION @@ -137,18 +138,18 @@ class BMAccount(object): address = self.address label = config.safeGet(address, 'label', address) queryreturn = sqlQuery( - '''select label from addressbook where address=?''', address) + '''select label from addressbook where address=?''', dbstr(address)) if queryreturn != []: for row in queryreturn: label, = row label = label.decode("utf-8", "replace") else: queryreturn = sqlQuery( - '''select label from subscriptions where address=?''', address) + '''select label from subscriptions where address=?''', dbstr(address)) if queryreturn != []: for row in queryreturn: label, = row - label = label.replace("utf-8", "replace") + label = label.decode("utf-8", "replace") return label def parseMessage(self, toAddress, fromAddress, subject, message): @@ -205,18 +206,18 @@ class GatewayAccount(BMAccount): sqlExecute( '''INSERT INTO sent VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)''', '', - self.toAddress.encode("utf-8", "replace"), + dbstr(self.toAddress), ripe, - self.fromAddress.encode("utf-8", "replace"), - self.subject.encode("utf-8", "replace"), - self.message.encode("utf-8", "replace"), + dbstr(self.fromAddress), + dbstr(self.subject), + dbstr(self.message), ackdata, int(time.time()), # sentTime (this will never change) int(time.time()), # lastActionTime 0, # sleepTill time. This will get set when the POW gets done. - 'msgqueued', + dbstr('msgqueued'), 0, # retryNumber - 'sent', # folder + dbstr('sent'), # folder 2, # encodingtype # not necessary to have a TTL higher than 2 days min(config.getint('bitmessagesettings', 'ttl'), 86400 * 2) diff --git a/src/bitmessageqt/blacklist.py b/src/bitmessageqt/blacklist.py index 41342bce..0ce60541 100644 --- a/src/bitmessageqt/blacklist.py +++ b/src/bitmessageqt/blacklist.py @@ -1,4 +1,5 @@ from PyQt4 import QtCore, QtGui +from dbcompat import dbstr import widgets from addresses import addBMIfNotPresent @@ -64,7 +65,7 @@ class Blacklist(QtGui.QWidget, RetranslateMixin): # First we must check to see if the address is already in the # address book. The user cannot add it again or else it will # cause problems when updating and deleting the entry. - t = (address,) + t = (dbstr(address),) if config.get('bitmessagesettings', 'blackwhitelist') == 'black': sql = '''select * from blacklist where address=?''' else: @@ -82,7 +83,7 @@ class Blacklist(QtGui.QWidget, RetranslateMixin): QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) self.tableWidgetBlacklist.setItem(0, 1, newItem) self.tableWidgetBlacklist.setSortingEnabled(True) - t = (str(self.NewBlacklistDialogInstance.lineEditLabel.text().toUtf8()), address, True) + t = (dbstr(self.NewBlacklistDialogInstance.lineEditLabel.text().toUtf8()), dbstr(address), True) if config.get('bitmessagesettings', 'blackwhitelist') == 'black': sql = '''INSERT INTO blacklist VALUES (?,?,?)''' else: @@ -111,10 +112,10 @@ class Blacklist(QtGui.QWidget, RetranslateMixin): if isinstance(addressitem, QtGui.QTableWidgetItem): if self.radioButtonBlacklist.isChecked(): sqlExecute('''UPDATE blacklist SET label=? WHERE address=?''', - item.text().encode("utf-8", "replace"), addressitem.text().encode("utf-8", "replace")) + dbstr(item.text()), dbstr(addressitem.text())) else: sqlExecute('''UPDATE whitelist SET label=? WHERE address=?''', - item.text().encode("utf-8", "replace"), addressitem.text().encode("utf-8", "replace")) + dbstr(item.text()), dbstr(addressitem.text())) def init_blacklist_popup_menu(self, connectSignal=True): # Popup menu for the Blacklist page @@ -200,11 +201,11 @@ class Blacklist(QtGui.QWidget, RetranslateMixin): if config.get('bitmessagesettings', 'blackwhitelist') == 'black': sqlExecute( '''DELETE FROM blacklist WHERE label=? AND address=?''', - labelAtCurrentRow.encode("utf-8", "replace"), addressAtCurrentRow.encode("utf-8", "replace")) + dbstr(labelAtCurrentRow), dbstr(addressAtCurrentRow)) else: sqlExecute( '''DELETE FROM whitelist WHERE label=? AND address=?''', - labelAtCurrentRow.encode("utf-8", "replace"), addressAtCurrentRow.encode("utf-8", "replace")) + dbstr(labelAtCurrentRow), dbstr(addressAtCurrentRow)) self.tableWidgetBlacklist.removeRow(currentRow) def on_action_BlacklistClipboard(self): @@ -229,11 +230,11 @@ class Blacklist(QtGui.QWidget, RetranslateMixin): if config.get('bitmessagesettings', 'blackwhitelist') == 'black': sqlExecute( '''UPDATE blacklist SET enabled=1 WHERE address=?''', - addressAtCurrentRow.encode("utf-8", "replace")) + dbstr(addressAtCurrentRow)) else: sqlExecute( '''UPDATE whitelist SET enabled=1 WHERE address=?''', - addressAtCurrentRow.encode("utf-8", "replace")) + dbstr(addressAtCurrentRow)) def on_action_BlacklistDisable(self): currentRow = self.tableWidgetBlacklist.currentRow() @@ -245,10 +246,10 @@ class Blacklist(QtGui.QWidget, RetranslateMixin): currentRow, 1).setTextColor(QtGui.QColor(128, 128, 128)) if config.get('bitmessagesettings', 'blackwhitelist') == 'black': sqlExecute( - '''UPDATE blacklist SET enabled=0 WHERE address=?''', addressAtCurrentRow.encode("utf-8", "replace")) + '''UPDATE blacklist SET enabled=0 WHERE address=?''', dbstr(addressAtCurrentRow)) else: sqlExecute( - '''UPDATE whitelist SET enabled=0 WHERE address=?''', addressAtCurrentRow.encode("utf-8", "replace")) + '''UPDATE whitelist SET enabled=0 WHERE address=?''', dbstr(addressAtCurrentRow)) def on_action_BlacklistSetAvatar(self): self.window().on_action_SetAvatar(self.tableWidgetBlacklist) diff --git a/src/bitmessageqt/foldertree.py b/src/bitmessageqt/foldertree.py index 2acf215d..b2581051 100644 --- a/src/bitmessageqt/foldertree.py +++ b/src/bitmessageqt/foldertree.py @@ -7,6 +7,7 @@ Folder tree and messagelist widgets definitions. from cgi import escape from PyQt4 import QtCore, QtGui +from dbcompat import dbstr from bmconfigparser import config from helper_sql import sqlExecute, sqlQuery @@ -111,7 +112,7 @@ class AccountMixin(object): elif config.safeGetBoolean(self.address, 'mailinglist'): self.type = self.MAILINGLIST elif sqlQuery( - '''select label from subscriptions where address=?''', self.address): + '''select label from subscriptions where address=?''', dbstr(self.address)): self.type = AccountMixin.SUBSCRIPTION else: self.type = self.NORMAL @@ -128,10 +129,10 @@ class AccountMixin(object): config.get(self.address, 'label'), 'utf-8') except Exception: queryreturn = sqlQuery( - '''select label from addressbook where address=?''', self.address) + '''select label from addressbook where address=?''', dbstr(self.address)) elif self.type == AccountMixin.SUBSCRIPTION: queryreturn = sqlQuery( - '''select label from subscriptions where address=?''', self.address) + '''select label from subscriptions where address=?''', dbstr(self.address)) if queryreturn is not None: if queryreturn != []: for row in queryreturn: @@ -307,7 +308,7 @@ class Ui_SubscriptionWidget(Ui_AddressWidget): def _getLabel(self): queryreturn = sqlQuery( - '''select label from subscriptions where address=?''', self.address) + '''select label from subscriptions where address=?''', dbstr(self.address)) if queryreturn != []: for row in queryreturn: retval, = row @@ -329,7 +330,7 @@ class Ui_SubscriptionWidget(Ui_AddressWidget): label = unicode(value, 'utf-8', 'ignore') sqlExecute( '''UPDATE subscriptions SET label=? WHERE address=?''', - label, self.address) + dbstr(label), dbstr(self.address)) return super(Ui_SubscriptionWidget, self).setData(column, role, value) @@ -412,10 +413,10 @@ class MessageList_AddressWidget(BMAddressWidget): 'utf-8', 'ignore') except: queryreturn = sqlQuery( - '''select label from addressbook where address=?''', self.address) + '''select label from addressbook where address=?''', dbstr(self.address)) elif self.type == AccountMixin.SUBSCRIPTION: queryreturn = sqlQuery( - '''select label from subscriptions where address=?''', self.address) + '''select label from subscriptions where address=?''', dbstr(self.address)) if queryreturn: for row in queryreturn: newLabel = row[0] @@ -526,9 +527,9 @@ class Ui_AddressBookWidgetItem(BMAddressWidget): config.set(self.address, 'label', self.label) config.save() except: - sqlExecute('''UPDATE addressbook set label=? WHERE address=?''', self.label, self.address) + sqlExecute('''UPDATE addressbook set label=? WHERE address=?''', dbstr(self.label), dbstr(self.address)) elif self.type == AccountMixin.SUBSCRIPTION: - sqlExecute('''UPDATE subscriptions set label=? WHERE address=?''', self.label, self.address) + sqlExecute('''UPDATE subscriptions set label=? WHERE address=?''', dbstr(self.label), dbstr(self.address)) else: pass return super(Ui_AddressBookWidgetItem, self).setData(role, value) diff --git a/src/bitmessageqt/support.py b/src/bitmessageqt/support.py index a84affa4..7f239003 100644 --- a/src/bitmessageqt/support.py +++ b/src/bitmessageqt/support.py @@ -7,6 +7,7 @@ import sys import time from PyQt4 import QtCore +from dbcompat import dbstr import account import defaults @@ -67,12 +68,12 @@ Connected hosts: {} def checkAddressBook(myapp): - sqlExecute('DELETE from addressbook WHERE address=?', OLD_SUPPORT_ADDRESS) - queryreturn = sqlQuery('SELECT * FROM addressbook WHERE address=?', SUPPORT_ADDRESS) + sqlExecute('DELETE from addressbook WHERE address=?', dbstr(OLD_SUPPORT_ADDRESS)) + queryreturn = sqlQuery('SELECT * FROM addressbook WHERE address=?', dbstr(SUPPORT_ADDRESS)) if queryreturn == []: sqlExecute( 'INSERT INTO addressbook VALUES (?,?)', - SUPPORT_LABEL.toUtf8(), SUPPORT_ADDRESS) + dbstr(SUPPORT_LABEL.toUtf8()), dbstr(SUPPORT_ADDRESS)) myapp.rerenderAddressBook() diff --git a/src/class_objectProcessor.py b/src/class_objectProcessor.py index 469ccbfa..9a0a9b9a 100644 --- a/src/class_objectProcessor.py +++ b/src/class_objectProcessor.py @@ -33,6 +33,7 @@ from helper_sql import ( from network import knownnodes from network.node import Peer from tr import _translate +from dbcompat import dbstr logger = logging.getLogger('default') @@ -327,19 +328,19 @@ class objectProcessor(threading.Thread): queryreturn = sqlQuery( "SELECT usedpersonally FROM pubkeys WHERE address=?" - " AND usedpersonally='yes'", address) + " AND usedpersonally='yes'", dbstr(address)) # if this pubkey is already in our database and if we have # used it personally: if queryreturn != []: logger.info( 'We HAVE used this pubkey personally. Updating time.') - t = (address, addressVersion, dataToStore, + t = (dbstr(address), addressVersion, dataToStore, int(time.time()), 'yes') else: logger.info( 'We have NOT used this pubkey personally. Inserting' ' in database.') - t = (address, addressVersion, dataToStore, + t = (dbstr(address), addressVersion, dataToStore, int(time.time()), 'no') sqlExecute('''INSERT INTO pubkeys VALUES (?,?,?,?,?)''', *t) self.possibleNewPubkey(address) @@ -389,20 +390,20 @@ class objectProcessor(threading.Thread): address = encodeAddress(addressVersion, streamNumber, ripe) queryreturn = sqlQuery( "SELECT usedpersonally FROM pubkeys WHERE address=?" - " AND usedpersonally='yes'", address) + " AND usedpersonally='yes'", dbstr(address)) # if this pubkey is already in our database and if we have # used it personally: if queryreturn != []: logger.info( 'We HAVE used this pubkey personally. Updating time.') - t = (address, addressVersion, dataToStore, - int(time.time()), 'yes') + t = (dbstr(address), addressVersion, dataToStore, + int(time.time()), dbstr('yes')) else: logger.info( 'We have NOT used this pubkey personally. Inserting' ' in database.') - t = (address, addressVersion, dataToStore, - int(time.time()), 'no') + t = (dbstr(address), addressVersion, dataToStore, + int(time.time()), dbstr('no')) sqlExecute('''INSERT INTO pubkeys VALUES (?,?,?,?,?)''', *t) self.possibleNewPubkey(address) @@ -590,11 +591,11 @@ class objectProcessor(threading.Thread): # person. sqlExecute( '''INSERT INTO pubkeys VALUES (?,?,?,?,?)''', - fromAddress, + dbstr(fromAddress), sendersAddressVersionNumber, decryptedData[:endOfThePublicKeyPosition], int(time.time()), - 'yes') + dbstr('yes')) # Check to see whether we happen to be awaiting this # pubkey in order to send a message. If we are, it will do the POW @@ -631,7 +632,7 @@ class objectProcessor(threading.Thread): 'bitmessagesettings', 'blackwhitelist') == 'black': queryreturn = sqlQuery( "SELECT label FROM blacklist where address=? and enabled='1'", - fromAddress) + dbstr(fromAddress)) if queryreturn != []: logger.info('Message ignored because address is in blacklist.') @@ -639,7 +640,7 @@ class objectProcessor(threading.Thread): else: # We're using a whitelist queryreturn = sqlQuery( "SELECT label FROM whitelist where address=? and enabled='1'", - fromAddress) + dbstr(fromAddress)) if queryreturn == []: logger.info( 'Message ignored because address not in whitelist.') @@ -927,11 +928,11 @@ class objectProcessor(threading.Thread): # Let's store the public key in case we want to reply to this person. sqlExecute('''INSERT INTO pubkeys VALUES (?,?,?,?,?)''', - fromAddress, - sendersAddressVersion, + dbstr(fromAddress), + dbstr(sendersAddressVersion), decryptedData[:endOfPubkeyPosition], int(time.time()), - 'yes') + dbstr('yes')) # Check to see whether we happen to be awaiting this # pubkey in order to send a message. If we are, it will do the POW @@ -1012,7 +1013,7 @@ class objectProcessor(threading.Thread): "UPDATE sent SET status='doingmsgpow', retrynumber=0" " WHERE toaddress=?" " AND (status='awaitingpubkey' OR status='doingpubkeypow')" - " AND folder='sent'", address) + " AND folder='sent'", dbstr(address)) queues.workerQueue.put(('sendmessage', '')) @staticmethod diff --git a/src/class_singleCleaner.py b/src/class_singleCleaner.py index 21aadfad..83cb48b1 100644 --- a/src/class_singleCleaner.py +++ b/src/class_singleCleaner.py @@ -29,6 +29,7 @@ from bmconfigparser import config from helper_sql import sqlExecute, sqlQuery from network import connectionpool, knownnodes, StoppableThread from tr import _translate +from dbcompat import dbstr #: Equals 4 weeks. You could make this longer if you want @@ -170,7 +171,7 @@ class singleCleaner(StoppableThread): )) sqlExecute( "UPDATE sent SET status = 'msgqueued'" - " WHERE toaddress = ? AND folder = 'sent'", address) + " WHERE toaddress = ? AND folder = 'sent'", dbstr(address)) queues.workerQueue.put(('sendmessage', '')) def resendMsg(self, ackdata): diff --git a/src/class_singleWorker.py b/src/class_singleWorker.py index 71e24c2e..7ee5138b 100644 --- a/src/class_singleWorker.py +++ b/src/class_singleWorker.py @@ -30,6 +30,7 @@ from bmconfigparser import config from helper_sql import sqlExecute, sqlQuery from network import knownnodes, StoppableThread from six.moves import configparser, queue +from dbcompat import dbstr def sizeof_fmt(num, suffix='h/s'): @@ -535,7 +536,7 @@ class singleWorker(StoppableThread): queryreturn = sqlQuery( '''SELECT fromaddress, subject, message, ''' ''' ackdata, ttl, encodingtype FROM sent ''' - ''' WHERE status=? and folder='sent' ''', 'broadcastqueued') + ''' WHERE status=? and folder='sent' ''', dbstr('broadcastqueued')) for row in queryreturn: fromaddress, subject, body, ackdata, TTL, encoding = row @@ -710,7 +711,7 @@ class singleWorker(StoppableThread): sqlExecute( '''UPDATE sent SET msgid=?, status=?, lastactiontime=? ''' ''' WHERE ackdata=? AND folder='sent' ''', - inventoryHash, 'broadcastsent', int(time.time()), ackdata + inventoryHash, dbstr('broadcastsent'), int(time.time()), ackdata ) def sendMsg(self): @@ -764,7 +765,7 @@ class singleWorker(StoppableThread): if not sqlExecute( '''UPDATE sent SET status='doingmsgpow' ''' ''' WHERE toaddress=? AND status='msgqueued' AND folder='sent' ''', - toaddress + dbstr(toaddress) ): continue status = 'doingmsgpow' @@ -772,7 +773,7 @@ class singleWorker(StoppableThread): # Let's see if we already have the pubkey in our pubkeys table queryreturn = sqlQuery( '''SELECT address FROM pubkeys WHERE address=?''', - toaddress + dbstr(toaddress) ) # If we have the needed pubkey in the pubkey table already, if queryreturn != []: @@ -780,7 +781,7 @@ class singleWorker(StoppableThread): if not sqlExecute( '''UPDATE sent SET status='doingmsgpow' ''' ''' WHERE toaddress=? AND status='msgqueued' AND folder='sent' ''', - toaddress + dbstr(toaddress) ): continue status = 'doingmsgpow' @@ -792,7 +793,7 @@ class singleWorker(StoppableThread): sqlExecute( '''UPDATE pubkeys SET usedpersonally='yes' ''' ''' WHERE address=?''', - toaddress + dbstr(toaddress) ) # We don't have the needed pubkey in the pubkeys table already. else: @@ -811,7 +812,7 @@ class singleWorker(StoppableThread): ''' sleeptill=? WHERE toaddress=? ''' ''' AND status='msgqueued' ''', int(time.time()) + 2.5 * 24 * 60 * 60, - toaddress + dbstr(toaddress) ) queues.UISignalQueue.put(( 'updateSentItemStatusByToAddress', ( @@ -867,7 +868,7 @@ class singleWorker(StoppableThread): ''' status='awaitingpubkey' or ''' ''' status='doingpubkeypow') AND ''' ''' folder='sent' ''', - toaddress) + dbstr(toaddress)) del state.neededPubkeys[tag] break # else: @@ -884,7 +885,7 @@ class singleWorker(StoppableThread): '''UPDATE sent SET ''' ''' status='doingpubkeypow' WHERE ''' ''' toaddress=? AND status='msgqueued' AND folder='sent' ''', - toaddress + dbstr(toaddress) ) queues.UISignalQueue.put(( 'updateSentItemStatusByToAddress', ( @@ -929,7 +930,7 @@ class singleWorker(StoppableThread): # is too hard then we'll abort. queryreturn = sqlQuery( 'SELECT transmitdata FROM pubkeys WHERE address=?', - toaddress) + dbstr(toaddress)) for row in queryreturn: # pylint: disable=redefined-outer-name pubkeyPayload, = row @@ -1349,7 +1350,7 @@ class singleWorker(StoppableThread): sqlExecute( '''UPDATE sent SET msgid=?, status=?, retrynumber=?, ''' ''' sleeptill=?, lastactiontime=? WHERE ackdata=? AND folder='sent' ''', - inventoryHash, newStatus, retryNumber + 1, + inventoryHash, dbstr(newStatus), retryNumber + 1, sleepTill, int(time.time()), ackdata ) @@ -1395,7 +1396,7 @@ class singleWorker(StoppableThread): '''SELECT retrynumber FROM sent WHERE toaddress=? ''' ''' AND (status='doingpubkeypow' OR status='awaitingpubkey') ''' ''' AND folder='sent' LIMIT 1''', - toAddress + dbstr(toAddress) ) if not queryReturn: self.logger.critical( @@ -1477,7 +1478,7 @@ class singleWorker(StoppableThread): ''' status='awaitingpubkey', retrynumber=?, sleeptill=? ''' ''' WHERE toaddress=? AND (status='doingpubkeypow' OR ''' ''' status='awaitingpubkey') AND folder='sent' ''', - int(time.time()), retryNumber + 1, sleeptill, toAddress) + int(time.time()), retryNumber + 1, sleeptill, dbstr(toAddress)) queues.UISignalQueue.put(( 'updateStatusBar', diff --git a/src/class_smtpServer.py b/src/class_smtpServer.py index 44ea7c9c..f753bd4e 100644 --- a/src/class_smtpServer.py +++ b/src/class_smtpServer.py @@ -20,6 +20,7 @@ from helper_ackPayload import genAckPayload from helper_sql import sqlExecute from network.threads import StoppableThread from version import softwareVersion +from dbcompat import dbstr SMTPDOMAIN = "bmaddr.lan" LISTENPORT = 8425 @@ -89,18 +90,18 @@ class smtpServerPyBitmessage(smtpd.SMTPServer): sqlExecute( '''INSERT INTO sent VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)''', '', - toAddress, + dbstr(toAddress), ripe, - fromAddress, - subject, - message, + dbstr(fromAddress), + dbstr(subject), + dbstr(message), ackdata, int(time.time()), # sentTime (this will never change) int(time.time()), # lastActionTime 0, # sleepTill time. This will get set when the POW gets done. - 'msgqueued', + dbstr('msgqueued'), 0, # retryNumber - 'sent', # folder + dbstr('sent'), # folder 2, # encodingtype # not necessary to have a TTL higher than 2 days min(config.getint('bitmessagesettings', 'ttl'), 86400 * 2) diff --git a/src/dbcompat.py b/src/dbcompat.py new file mode 100644 index 00000000..6a865630 --- /dev/null +++ b/src/dbcompat.py @@ -0,0 +1,22 @@ +import logging +import six + +logger = logging.getLogger("default") + +def dbstr(v): + if six.PY3: + if isinstance(v, str): + return v + elif isinstance(v, bytes): + return v.decode("utf-8", "replace") + logger.debug("unexpected type in dbstr(): {}".format(type(v))) + return v # hope this never happens.. + else: # assume six.PY2 + if isinstance(v, unicode): + return v.encode("utf-8", "replace") + elif isinstance(v, str): + return v + elif isinstance(v, bytes): + return str(v) + logger.debug("unexpected type in dbstr(): {}".format(type(v))) + return v # hope this never happens.. diff --git a/src/helper_addressbook.py b/src/helper_addressbook.py index 6d354113..6f1d40d2 100644 --- a/src/helper_addressbook.py +++ b/src/helper_addressbook.py @@ -4,11 +4,12 @@ Insert value into addressbook from bmconfigparser import config from helper_sql import sqlExecute +from dbcompat import dbstr def insert(address, label): """perform insert into addressbook""" if address not in config.addresses(): - return sqlExecute('''INSERT INTO addressbook VALUES (?,?)''', label, address) == 1 + return sqlExecute('''INSERT INTO addressbook VALUES (?,?)''', dbstr(label), dbstr(address)) == 1 return False diff --git a/src/helper_inbox.py b/src/helper_inbox.py index 555795df..1e490680 100644 --- a/src/helper_inbox.py +++ b/src/helper_inbox.py @@ -2,11 +2,13 @@ import queues from helper_sql import sqlExecute, sqlQuery +from dbcompat import dbstr def insert(t): """Perform an insert into the "inbox" table""" - sqlExecute('''INSERT INTO inbox VALUES (?,?,?,?,?,?,?,?,?,?)''', *t) + u = [t[0], dbstr(t[1]), dbstr(t[2]), dbstr(t[3]), dbstr(t[4]), dbstr(t[5]), dbstr(t[6]), t[7], t[8], t[9]] + sqlExecute('''INSERT INTO inbox VALUES (?,?,?,?,?,?,?,?,?,?)''', *u) # shouldn't emit changedInboxUnread and displayNewInboxMessage # at the same time # queues.UISignalQueue.put(('changedInboxUnread', None)) diff --git a/src/helper_search.py b/src/helper_search.py index 9fcb88b5..46cc4e80 100644 --- a/src/helper_search.py +++ b/src/helper_search.py @@ -5,6 +5,7 @@ Used by :mod:`.bitmessageqt`. from helper_sql import sqlQuery from tr import _translate +from dbcompat import dbstr def search_sql( @@ -52,23 +53,23 @@ def search_sql( if account is not None: if xAddress == 'both': sqlStatementParts.append('(fromaddress = ? OR toaddress = ?)') - sqlArguments.append(account) - sqlArguments.append(account) + sqlArguments.append(dbstr(account)) + sqlArguments.append(dbstr(account)) else: sqlStatementParts.append(xAddress + ' = ? ') - sqlArguments.append(account) + sqlArguments.append(dbstr(account)) if folder is not None: if folder == 'new': folder = 'inbox' unreadOnly = True sqlStatementParts.append('folder = ? ') - sqlArguments.append(folder) + sqlArguments.append(dbstr(folder)) else: sqlStatementParts.append('folder != ?') - sqlArguments.append('trash') + sqlArguments.append(dbstr('trash')) if what: sqlStatementParts.append('%s LIKE ?' % (where)) - sqlArguments.append(what) + sqlArguments.append(dbstr(what)) if unreadOnly: sqlStatementParts.append('read = 0') if sqlStatementParts: diff --git a/src/helper_sent.py b/src/helper_sent.py index aa76e756..2f24a619 100644 --- a/src/helper_sent.py +++ b/src/helper_sent.py @@ -8,6 +8,7 @@ from addresses import decodeAddress from bmconfigparser import config from helper_ackPayload import genAckPayload from helper_sql import sqlExecute, sqlQuery +from dbcompat import dbstr # pylint: disable=too-many-arguments @@ -38,8 +39,8 @@ def insert(msgid=None, toAddress='[Broadcast subscribers]', fromAddress=None, su ttl = ttl if ttl else config.getint('bitmessagesettings', 'ttl') - t = (msgid, toAddress, ripe, fromAddress, subject, message, ackdata, - sentTime, lastActionTime, sleeptill, status, retryNumber, folder, + t = (msgid, dbstr(toAddress), ripe, dbstr(fromAddress), dbstr(subject), dbstr(message), ackdata, + sentTime, lastActionTime, sleeptill, dbstr(status), retryNumber, dbstr(folder), encoding, ttl) sqlExecute('''INSERT INTO sent VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)''', *t) diff --git a/src/protocol.py b/src/protocol.py index 7f9830e5..9117cc7c 100644 --- a/src/protocol.py +++ b/src/protocol.py @@ -23,6 +23,7 @@ from debug import logger from helper_sql import sqlExecute from network.node import Peer from version import softwareVersion +from dbcompat import dbstr # Network constants magic = 0xE9BEB4D9 @@ -558,7 +559,7 @@ def decryptAndCheckPubkeyPayload(data, address): hexlify(pubSigningKey), hexlify(pubEncryptionKey) ) - t = (address, addressVersion, storedData, int(time.time()), 'yes') + t = (dbstr(address), addressVersion, storedData, int(time.time()), dbstr('yes')) sqlExecute('''INSERT INTO pubkeys VALUES (?,?,?,?,?)''', *t) return 'successful' except varintDecodeError: diff --git a/src/shared.py b/src/shared.py index aa7b6bb4..050dfa7b 100644 --- a/src/shared.py +++ b/src/shared.py @@ -22,6 +22,7 @@ from addresses import decodeAddress, encodeVarint from bmconfigparser import config from debug import logger from helper_sql import sqlQuery +from dbcompat import dbstr myECCryptorObjects = {} @@ -38,7 +39,7 @@ def isAddressInMyAddressBook(address): """Is address in my addressbook?""" queryreturn = sqlQuery( '''select address from addressbook where address=?''', - address) + dbstr(address)) return queryreturn != [] @@ -47,7 +48,7 @@ def isAddressInMySubscriptionsList(address): """Am I subscribed to this address?""" queryreturn = sqlQuery( '''select * from subscriptions where address=?''', - address.encode("utf-8", "replace")) + dbstr(address)) return queryreturn != [] @@ -61,14 +62,14 @@ def isAddressInMyAddressBookSubscriptionsListOrWhitelist(address): queryreturn = sqlQuery( '''SELECT address FROM whitelist where address=?''' ''' and enabled = '1' ''', - address) + dbstr(address)) if queryreturn != []: return True queryreturn = sqlQuery( '''select address from subscriptions where address=?''' ''' and enabled = '1' ''', - address) + dbstr(address)) if queryreturn != []: return True return False @@ -170,7 +171,7 @@ def fixPotentiallyInvalidUTF8Data(text): return text except UnicodeDecodeError: return 'Part of the message is corrupt. The message cannot be' \ - ' displayed the normal way.\n\n' + repr(text) + ' displayed the normal way.\n\n' + text.decode("utf-8", "replace") def checkSensitiveFilePermissions(filename): diff --git a/src/storage/sqlite.py b/src/storage/sqlite.py index eb5df098..2296175f 100644 --- a/src/storage/sqlite.py +++ b/src/storage/sqlite.py @@ -95,7 +95,7 @@ class SqliteInventory(InventoryStorage): t = int(time.time()) hashes = [x for x, value in self._inventory.items() if value.stream == stream and value.expires > t] - hashes += (str(payload) for payload, in sqlQuery( + hashes += (bytes(payload) for payload, in sqlQuery( 'SELECT hash FROM inventory WHERE streamnumber=?' ' AND expirestime>?', stream, t)) return hashes diff --git a/src/tests/core.py b/src/tests/core.py index f1a11a06..bf58f9f3 100644 --- a/src/tests/core.py +++ b/src/tests/core.py @@ -31,6 +31,7 @@ from network.node import Node, Peer from network.tcp import Socks4aBMConnection, Socks5BMConnection, TCPConnection from queues import excQueue from version import softwareVersion +from dbcompat import dbstr from common import cleanup @@ -346,11 +347,11 @@ class TestCore(unittest.TestCase): ) queryreturn = sqlQuery( '''select msgid from sent where ackdata=?''', result) - self.assertNotEqual(queryreturn[0][0] if queryreturn else '', '') + self.assertNotEqual(queryreturn[0][0] if queryreturn else b'', b'') column_type = sqlQuery( '''select typeof(msgid) from sent where ackdata=?''', result) - self.assertEqual(column_type[0][0] if column_type else '', 'text') + self.assertEqual(column_type[0][0] if column_type else '', 'blob') @unittest.skipIf(frozen, 'not packed test_pattern into the bundle') def test_old_knownnodes_pickle(self): @@ -368,7 +369,7 @@ class TestCore(unittest.TestCase): @staticmethod def delete_address_from_addressbook(address): """Clean up addressbook""" - sqlQuery('''delete from addressbook where address=?''', address) + sqlQuery('''delete from addressbook where address=?''', dbstr(address)) def test_add_same_address_twice_in_addressbook(self): """checking same address is added twice in addressbook""" @@ -382,7 +383,7 @@ class TestCore(unittest.TestCase): """checking is address added in addressbook or not""" helper_addressbook.insert(label='test1', address=self.addr) queryreturn = sqlQuery( - 'select count(*) from addressbook where address=?', self.addr) + 'select count(*) from addressbook where address=?', dbstr(self.addr)) self.assertEqual(queryreturn[0][0], 1) self.delete_address_from_addressbook(self.addr) diff --git a/src/tests/test_helper_inbox.py b/src/tests/test_helper_inbox.py index a0b6de1b..8ff60e18 100644 --- a/src/tests/test_helper_inbox.py +++ b/src/tests/test_helper_inbox.py @@ -26,7 +26,7 @@ class TestHelperInbox(unittest.TestCase): def test_insert(self, mock_sql_execute): # pylint: disable=no-self-use """Test to perform an insert into the "inbox" table""" mock_message_data = ( - "ruyv87bv", + b"ruyv87bv", "BM-2cUGaEcGz9Zft1SPAo8FJtfzyADTpEgU9U", "BM-2cUGaEcGz9Zft1SPAo8FJtfzyADTp5g99U", "Test subject", @@ -35,7 +35,7 @@ class TestHelperInbox(unittest.TestCase): "inbox", 2, 0, - "658gvjhtghv", + b"658gvjhtghv", ) insert(t=mock_message_data) mock_sql_execute.assert_called_once() @@ -43,7 +43,7 @@ class TestHelperInbox(unittest.TestCase): @patch("pybitmessage.helper_inbox.sqlExecute") def test_trash(self, mock_sql_execute): # pylint: disable=no-self-use """Test marking a message in the `inbox` as `trash`""" - mock_msg_id = "fefkosghsbse92" + mock_msg_id = b"fefkosghsbse92" trash(msgid=mock_msg_id) mock_sql_execute.assert_called_once() @@ -57,7 +57,7 @@ class TestHelperInbox(unittest.TestCase): @patch("pybitmessage.helper_inbox.sqlExecute") def test_undeleteMessage(self, mock_sql_execute): # pylint: disable=no-self-use """Test for Undelete the message""" - mock_msg_id = "fefkosghsbse92" + mock_msg_id = b"fefkosghsbse92" undeleteMessage(msgid=mock_msg_id) mock_sql_execute.assert_called_once() diff --git a/src/tests/test_helper_sent.py b/src/tests/test_helper_sent.py index 9227e43a..36bb8bb7 100644 --- a/src/tests/test_helper_sent.py +++ b/src/tests/test_helper_sent.py @@ -19,7 +19,7 @@ class TestHelperSent(unittest.TestCase): """Test insert with valid address""" VALID_ADDRESS = "BM-2cUGaEcGz9Zft1SPAo8FJtfzyADTpEgU9U" ackdata = insert( - msgid="123456", + msgid=b"123456", toAddress="[Broadcast subscribers]", fromAddress=VALID_ADDRESS, subject="Test Subject", @@ -45,10 +45,10 @@ class TestHelperSent(unittest.TestCase): @patch("pybitmessage.helper_sent.sqlExecute") def test_delete(self, mock_sql_execute): """Test delete function""" - delete("ack_data") + delete(b"ack_data") self.assertTrue(mock_sql_execute.called) mock_sql_execute.assert_called_once_with( - "DELETE FROM sent WHERE ackdata = ?", "ack_data" + "DELETE FROM sent WHERE ackdata = ?", b"ack_data" ) @patch("pybitmessage.helper_sent.sqlQuery") @@ -56,11 +56,11 @@ class TestHelperSent(unittest.TestCase): """Test retrieving valid message details""" return_data = [ ( - "to@example.com", - "from@example.com", - "Test Subject", - "Test Message", - "2022-01-01", + b"to@example.com", + b"from@example.com", + b"Test Subject", + b"Test Message", + b"2022-01-01", ) ] mock_sql_query.return_value = return_data @@ -70,7 +70,7 @@ class TestHelperSent(unittest.TestCase): @patch("pybitmessage.helper_sent.sqlExecute") def test_trash(self, mock_sql_execute): """Test marking a message as 'trash'""" - ackdata = "ack_data" + ackdata = b"ack_data" mock_sql_execute.return_value = 1 rowcount = trash(ackdata) self.assertEqual(rowcount, 1) diff --git a/src/tests/test_helper_sql.py b/src/tests/test_helper_sql.py index 036bd2c9..2e0a1776 100644 --- a/src/tests/test_helper_sql.py +++ b/src/tests/test_helper_sql.py @@ -23,23 +23,23 @@ class TestHelperSql(unittest.TestCase): @patch("pybitmessage.helper_sql.sqlReturnQueue.get") def test_sqlquery_no_args(self, mock_sqlreturnqueue_get, mock_sqlsubmitqueue_put): """Test sqlQuery with no additional arguments""" - mock_sqlreturnqueue_get.return_value = ("dummy_result", None) + mock_sqlreturnqueue_get.return_value = (b"dummy_result", None) result = helper_sql.sqlQuery( "SELECT msgid FROM inbox where folder='inbox' ORDER BY received" ) self.assertEqual(mock_sqlsubmitqueue_put.call_count, 2) - self.assertEqual(result, "dummy_result") + self.assertEqual(result.decode("utf-8", "replace"), "dummy_result") @patch("pybitmessage.helper_sql.sqlSubmitQueue.put") @patch("pybitmessage.helper_sql.sqlReturnQueue.get") def test_sqlquery_with_args(self, mock_sqlreturnqueue_get, mock_sqlsubmitqueue_put): """Test sqlQuery with additional arguments""" - mock_sqlreturnqueue_get.return_value = ("dummy_result", None) + mock_sqlreturnqueue_get.return_value = (b"dummy_result", None) result = helper_sql.sqlQuery( "SELECT address FROM addressbook WHERE address=?", "PB-5yfds868gbkj" ) self.assertEqual(mock_sqlsubmitqueue_put.call_count, 2) - self.assertEqual(result, "dummy_result") + self.assertEqual(result.decode("utf-8", "replace"), "dummy_result") @patch("pybitmessage.helper_sql.sqlSubmitQueue.put") @patch("pybitmessage.helper_sql.sqlReturnQueue.get") @@ -49,7 +49,7 @@ class TestHelperSql(unittest.TestCase): rowcount = helper_sql.sqlExecute( "UPDATE sent SET status = 'msgqueued'" "WHERE ackdata = ? AND folder = 'sent'", - "1710652313", + b"1710652313", ) self.assertEqual(mock_sqlsubmitqueue_put.call_count, 3) self.assertEqual(rowcount, 1) diff --git a/src/tests/test_shared.py b/src/tests/test_shared.py index 3e9be107..073f94e7 100644 --- a/src/tests/test_shared.py +++ b/src/tests/test_shared.py @@ -46,7 +46,7 @@ class TestShared(unittest.TestCase): address = sample_address # if address is in MyAddressbook - mock_sql_query.return_value = [address.encode("utf-8", "replace")] + mock_sql_query.return_value = [bytes(address)] return_val = isAddressInMyAddressBook(address) mock_sql_query.assert_called_once() self.assertTrue(return_val) @@ -64,7 +64,7 @@ class TestShared(unittest.TestCase): address = sample_address # if address is in MySubscriptionsList - mock_sql_query.return_value = [address.encode("utf-8", "replace")] + mock_sql_query.return_value = [bytes(address)] return_val = isAddressInMySubscriptionsList(address) self.assertTrue(return_val) @@ -78,7 +78,7 @@ class TestShared(unittest.TestCase): def test_reloadBroadcastSendersForWhichImWatching(self, mock_sql_query): """Test for reload Broadcast Senders For Which Im Watching""" mock_sql_query.return_value = [ - (sample_address.encode("utf-8", "replace"),), + (bytes(sample_address),), ] # before reload self.assertEqual(len(MyECSubscriptionCryptorObjects), 0) diff --git a/src/tests/test_sqlthread.py b/src/tests/test_sqlthread.py index a612df3a..7c6318e6 100644 --- a/src/tests/test_sqlthread.py +++ b/src/tests/test_sqlthread.py @@ -41,4 +41,4 @@ class TestSqlThread(unittest.TestCase): query = sqlQuery('SELECT enaddr(4, 1, "21122112211221122112")') self.assertEqual( - query[0][-1], encoded_str, "test case fail for create_function") + query[0][-1].decode("utf-8", "replace"), encoded_str, "test case fail for create_function") -- 2.45.1 From 2a0d2d3a10a5c520eec9b39c269262424b4f68f4 Mon Sep 17 00:00:00 2001 From: Kashiko Koibumi Date: Mon, 27 May 2024 01:52:39 +0900 Subject: [PATCH 053/105] update translation files for using format() instead of arg() --- src/translations/bitmessage_ar.qm | Bin 39410 -> 38947 bytes src/translations/bitmessage_ar.ts | 146 ++++++------- src/translations/bitmessage_cs.qm | Bin 55998 -> 55524 bytes src/translations/bitmessage_cs.ts | 152 ++++++------- src/translations/bitmessage_da.qm | Bin 51755 -> 51240 bytes src/translations/bitmessage_da.ts | 146 ++++++------- src/translations/bitmessage_de.qm | Bin 97474 -> 97681 bytes src/translations/bitmessage_de.ts | 266 +++++++++++------------ src/translations/bitmessage_en.qm | Bin 81265 -> 80955 bytes src/translations/bitmessage_en.ts | 208 +++++++++--------- src/translations/bitmessage_en_pirate.qm | Bin 17497 -> 16990 bytes src/translations/bitmessage_en_pirate.ts | 104 ++++----- src/translations/bitmessage_eo.qm | Bin 87362 -> 87560 bytes src/translations/bitmessage_eo.ts | 256 +++++++++++----------- src/translations/bitmessage_fr.qm | Bin 92731 -> 92929 bytes src/translations/bitmessage_fr.ts | 256 +++++++++++----------- src/translations/bitmessage_it.qm | Bin 20451 -> 19879 bytes src/translations/bitmessage_it.ts | 110 +++++----- src/translations/bitmessage_ja.qm | Bin 66472 -> 66668 bytes src/translations/bitmessage_ja.ts | 254 +++++++++++----------- src/translations/bitmessage_nb.ts | 76 +++---- src/translations/bitmessage_nl.qm | Bin 12417 -> 11909 bytes src/translations/bitmessage_nl.ts | 112 +++++----- src/translations/bitmessage_no.qm | Bin 59534 -> 59029 bytes src/translations/bitmessage_no.ts | 158 +++++++------- src/translations/bitmessage_pl.qm | Bin 91161 -> 91359 bytes src/translations/bitmessage_pl.ts | 256 +++++++++++----------- src/translations/bitmessage_pt.qm | Bin 5172 -> 4715 bytes src/translations/bitmessage_pt.ts | 106 ++++----- src/translations/bitmessage_ru.qm | Bin 86534 -> 86735 bytes src/translations/bitmessage_ru.ts | 256 +++++++++++----------- src/translations/bitmessage_sk.qm | Bin 90043 -> 90252 bytes src/translations/bitmessage_sk.ts | 266 +++++++++++------------ src/translations/bitmessage_sv.ts | 104 ++++----- src/translations/bitmessage_zh_cn.ts | 248 ++++++++++----------- src/translations/noarg.sh | 7 + src/translations/update.sh | 2 + 37 files changed, 1749 insertions(+), 1740 deletions(-) create mode 100755 src/translations/noarg.sh create mode 100755 src/translations/update.sh diff --git a/src/translations/bitmessage_ar.qm b/src/translations/bitmessage_ar.qm index 892f61604c7d0314c27d1fad99d42ddc84a73641..6f2795451a825180ddc1bf77e6c00a0394580a1c 100644 GIT binary patch delta 2894 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 JzPR06@*jZVK*|6B diff --git a/src/translations/bitmessage_ar.ts b/src/translations/bitmessage_ar.ts index 6bf906d7..4b3ba9c1 100644 --- a/src/translations/bitmessage_ar.ts +++ b/src/translations/bitmessage_ar.ts @@ -241,8 +241,8 @@ Please type the desired email address (including @mailchuck.com) below: - One of your addresses, %1, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? - واحد من العناوين، %1، حاصل على رقم إصدار 1، العناوين ذات رقم الإصدار 1 غير مدعومه حالياً، هل باستطاعتنا حذفه الآن؟ + One of your addresses, {0}, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? + واحد من العناوين، {0}، حاصل على رقم إصدار 1، العناوين ذات رقم الإصدار 1 غير مدعومه حالياً، هل باستطاعتنا حذفه الآن؟ @@ -261,13 +261,13 @@ Please type the desired email address (including @mailchuck.com) below: - Message sent. Waiting for acknowledgement. Sent at %1 + Message sent. Waiting for acknowledgement. Sent at {0} - Message sent. Sent at %1 - تم إرسال الرسالة في %1 + Message sent. Sent at {0} + تم إرسال الرسالة في {0} @@ -276,8 +276,8 @@ Please type the desired email address (including @mailchuck.com) below: - Acknowledgement of the message received %1 - تم استلام إشعار الاستلام للرسالة %1 + Acknowledgement of the message received {0} + تم استلام إشعار الاستلام للرسالة {0} @@ -286,18 +286,18 @@ Please type the desired email address (including @mailchuck.com) below: - Broadcast on %1 - البث في %1 + Broadcast on {0} + البث في {0} - Problem: The work demanded by the recipient is more difficult than you are willing to do. %1 - مشكلة: العمل المطلوب من قبل المستلم أصعب من ما كنت مستعد للقيام به %1 + Problem: The work demanded by the recipient is more difficult than you are willing to do. {0} + مشكلة: العمل المطلوب من قبل المستلم أصعب من ما كنت مستعد للقيام به {0} - Problem: The recipient's encryption key is no good. Could not encrypt message. %1 - مشكلة: مفتاح تشفير المرسل إليه غير جيد، لا يمكن تشفير الرسالة. %1 + Problem: The recipient's encryption key is no good. Could not encrypt message. {0} + مشكلة: مفتاح تشفير المرسل إليه غير جيد، لا يمكن تشفير الرسالة. {0} @@ -306,8 +306,8 @@ Please type the desired email address (including @mailchuck.com) below: - Unknown status: %1 %2 - حالة غير معروفه: %1 %2 + Unknown status: {0} {1} + حالة غير معروفه: {0} {1} @@ -347,10 +347,10 @@ Please type the desired email address (including @mailchuck.com) below: You may manage your keys by editing the keys.dat file stored in - %1 + {0} It is important that you back up this file. يمكنك إدارة مفاتيحك بواسطة تعديل ملف keys.dat المحفوظ في -%1 +{0} مهم جداً أن تحتفظ بنسخة إضافية من هذا الملف. @@ -366,10 +366,10 @@ It is important that you back up this file. You may manage your keys by editing the keys.dat file stored in - %1 + {0} 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.) يمكنك إدارة مفاتيحك بواسطة تعديل ملف keys.dat المحفوظ في -%1 +{0} مهم جداً أن تحتفظ بنسخة إضافية من هذا الملف. هل ترغب بفتح الملف الآن؟ تأكد من إغلاق البرنامج Bitmessage قبل تعديل الملف. @@ -434,8 +434,8 @@ It is important that you back up this file. Would you like to open the file now? - Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: %1. This address also appears in 'Your Identities'. - تم تكوين زمرة بنجاح، لإتاحة الفرصة للأخرين بالإنضمام لمجموعتك أعطهم إسم الزمرة و هذا العنوان %1، هذا العنوان سيظهر ضمن هوياتك. + Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: {0}. This address also appears in 'Your Identities'. + تم تكوين زمرة بنجاح، لإتاحة الفرصة للأخرين بالإنضمام لمجموعتك أعطهم إسم الزمرة و هذا العنوان {0}، هذا العنوان سيظهر ضمن هوياتك. @@ -502,53 +502,53 @@ It is important that you back up this file. Would you like to open the file now? - The message that you are trying to send is too long by %1 bytes. (The maximum is 261644 bytes). Please cut it down before sending. + The message that you are trying to send is too long by {0} bytes. (The maximum is 261644 bytes). Please cut it down before sending. - Error: Your account wasn't registered at an email gateway. Sending registration now as %1, please wait for the registration to be processed before retrying sending. + Error: Your account wasn't registered at an email gateway. Sending registration now as {0}, please wait for the registration to be processed before retrying sending. - Error: Bitmessage addresses start with BM- Please check %1 - خطأ: عناوين ال Bitmessage تبدأ ب BM-، يرجى فحص %1 + Error: Bitmessage addresses start with BM- Please check {0} + خطأ: عناوين ال Bitmessage تبدأ ب BM-، يرجى فحص {0} - Error: The address %1 is not typed or copied correctly. Please check it. - خطأ: لم يتم إدخال أو نسخ العنوان %1 بطريقة صحيحة، يرجى فحصه. + Error: The address {0} is not typed or copied correctly. Please check it. + خطأ: لم يتم إدخال أو نسخ العنوان {0} بطريقة صحيحة، يرجى فحصه. - Error: The address %1 contains invalid characters. Please check it. - خطأ: العنوان %1 يحتوي على حروف غير صالحة، يرجى فحصه. + Error: The address {0} contains invalid characters. Please check it. + خطأ: العنوان {0} يحتوي على حروف غير صالحة، يرجى فحصه. - Error: The address version in %1 is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. - خطأ: رقم إصدار العنوان %1 عالي جداً، إما أن تقوم بتحديث برنامج Bitmessage أو أن شريكك ذكي جدأ. + Error: The address version in {0} is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. + خطأ: رقم إصدار العنوان {0} عالي جداً، إما أن تقوم بتحديث برنامج Bitmessage أو أن شريكك ذكي جدأ. - Error: Some data encoded in the address %1 is too short. There might be something wrong with the software of your acquaintance. - بعض البيانات المشفرة ضمن العنوان %1 قصيرة جداً. يمكن أن يكون هناك خطأ في برنامج شريكك. + Error: Some data encoded in the address {0} is too short. There might be something wrong with the software of your acquaintance. + بعض البيانات المشفرة ضمن العنوان {0} قصيرة جداً. يمكن أن يكون هناك خطأ في برنامج شريكك. - Error: Some data encoded in the address %1 is too long. There might be something wrong with the software of your acquaintance. - بعض البيانات المشفرة ضمن العنوان %1 طويلة جداً. يمكن أن يكون هناك خطأ في برنامج شريكك. + Error: Some data encoded in the address {0} is too long. There might be something wrong with the software of your acquaintance. + بعض البيانات المشفرة ضمن العنوان {0} طويلة جداً. يمكن أن يكون هناك خطأ في برنامج شريكك. - Error: Some data encoded in the address %1 is malformed. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is malformed. There might be something wrong with the software of your acquaintance. - Error: Something is wrong with the address %1. - خطأ: هناك خطأ في هذا العنوان %1. + Error: Something is wrong with the address {0}. + خطأ: هناك خطأ في هذا العنوان {0}. @@ -562,8 +562,8 @@ It is important that you back up this file. Would you like to open the file now? - Concerning the address %1, Bitmessage cannot understand address version numbers of %2. Perhaps upgrade Bitmessage to the latest version. - بالنظر إلى العنوان %1, Bitmessage لم يستطع فهم رقم إصدار العنوان %2، ربما يجب عليك تحديث برنامج Bitmessage لإصداره الأخير. + Concerning the address {0}, Bitmessage cannot understand address version numbers of {1}. Perhaps upgrade Bitmessage to the latest version. + بالنظر إلى العنوان {0}, Bitmessage لم يستطع فهم رقم إصدار العنوان {1}، ربما يجب عليك تحديث برنامج Bitmessage لإصداره الأخير. @@ -572,8 +572,8 @@ It is important that you back up this file. Would you like to open the file now? - Concerning the address %1, Bitmessage cannot handle stream numbers of %2. Perhaps upgrade Bitmessage to the latest version. - بالنظر إلى العنوان %1, Bitmessage لم يستطع فهم رقم إصدار العنوان %2، ربما يجب عليك تحديث برنامج Bitmessage لإصداره الأخير. + Concerning the address {0}, Bitmessage cannot handle stream numbers of {1}. Perhaps upgrade Bitmessage to the latest version. + بالنظر إلى العنوان {0}, Bitmessage لم يستطع فهم رقم إصدار العنوان {1}، ربما يجب عليك تحديث برنامج Bitmessage لإصداره الأخير. @@ -707,8 +707,8 @@ It is important that you back up this file. Would you like to open the file now? - Bitmessage cannot find your address %1. Perhaps you removed it? - لم يستطع Bitmessage العثور على عنوانك %1, ربما قمت بحذف العنوان؟ + Bitmessage cannot find your address {0}. Perhaps you removed it? + لم يستطع Bitmessage العثور على عنوانك {0}, ربما قمت بحذف العنوان؟ @@ -861,8 +861,8 @@ Are you sure you want to delete the channel? - You are using TCP port %1. (This can be changed in the settings). - أنت تستخدم نقطة عبور TCP %1 - يمكنك تغييره في قائمة الضبط. + You are using TCP port {0}. (This can be changed in the settings). + أنت تستخدم نقطة عبور TCP {0} - يمكنك تغييره في قائمة الضبط. @@ -1056,7 +1056,7 @@ Are you sure you want to delete the channel? - Zoom level %1% + Zoom level {0}% @@ -1071,47 +1071,47 @@ Are you sure you want to delete the channel? - Display the %1 recent broadcast(s) from this address. + Display the {0} recent broadcast(s) from this address. - New version of PyBitmessage is available: %1. Download it from https://github.com/Bitmessage/PyBitmessage/releases/latest + New version of PyBitmessage is available: {0}. Download it from https://github.com/Bitmessage/PyBitmessage/releases/latest - Waiting for PoW to finish... %1% + Waiting for PoW to finish... {0}% - Shutting down Pybitmessage... %1% + Shutting down Pybitmessage... {0}% - Waiting for objects to be sent... %1% + Waiting for objects to be sent... {0}% - Saving settings... %1% + Saving settings... {0}% - Shutting down core... %1% + Shutting down core... {0}% - Stopping notifications... %1% + Stopping notifications... {0}% - Shutdown imminent... %1% + Shutdown imminent... {0}% @@ -1140,7 +1140,7 @@ Are you sure you want to delete the channel? - Shutting down PyBitmessage... %1% + Shutting down PyBitmessage... {0}% @@ -1160,12 +1160,12 @@ Are you sure you want to delete the channel? - Generating %1 new addresses. + Generating {0} new addresses. - %1 is already in 'Your Identities'. Not adding it again. + {0} is already in 'Your Identities'. Not adding it again. @@ -1175,7 +1175,7 @@ Are you sure you want to delete the channel? - SOCKS5 Authentication problem: %1 + SOCKS5 Authentication problem: {0} @@ -1200,7 +1200,7 @@ Are you sure you want to delete the channel? - Broadcast sent on %1 + Broadcast sent on {0} @@ -1220,7 +1220,7 @@ Are you sure you want to delete the channel? - Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. %1 + Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. {0} @@ -1232,17 +1232,17 @@ There is no required difficulty for version 2 addresses like this. Doing work necessary to send message. -Receiver's required difficulty: %1 and %2 +Receiver's required difficulty: {0} and {1} - Problem: The work demanded by the recipient (%1 and %2) is more difficult than you are willing to do. %3 + Problem: The work demanded by the recipient ({0} and {1}) is more difficult than you are willing to do. {2} - Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. %1 + Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. {0} @@ -1252,7 +1252,7 @@ Receiver's required difficulty: %1 and %2 - Message sent. Waiting for acknowledgement. Sent on %1 + Message sent. Waiting for acknowledgement. Sent on {0} @@ -1267,12 +1267,12 @@ Receiver's required difficulty: %1 and %2 - Sending public key request. Waiting for reply. Requested at %1 + Sending public key request. Waiting for reply. Requested at {0} - UPnP port mapping established on port %1 + UPnP port mapping established on port {0} @@ -1635,27 +1635,27 @@ The 'Random Number' option is selected by default but deterministic ad - Since startup on %1 + Since startup on {0} - Down: %1/s Total: %2 + Down: {0}/s Total: {1} - Up: %1/s Total: %2 + Up: {0}/s Total: {1} - Total Connections: %1 + Total Connections: {0} - Inventory lookups per second: %1 + Inventory lookups per second: {0} diff --git a/src/translations/bitmessage_cs.qm b/src/translations/bitmessage_cs.qm index c25ccafac3de70f43735d13ce56b870a4f452c24..8fde0714829146363a484a3e9d35ed0f36890845 100644 GIT binary patch delta 3298 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 - One of your addresses, %1, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? - Jedna z Vašich adres, %1, je stará adresa verze 1. Adresy verze 1 již nejsou podporovány. Můžeme ji nyní smazat? + One of your addresses, {0}, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? + Jedna z Vašich adres, {0}, je stará adresa verze 1. Adresy verze 1 již nejsou podporovány. Můžeme ji nyní smazat? @@ -261,13 +261,13 @@ Please type the desired email address (including @mailchuck.com) below: - Message sent. Waiting for acknowledgement. Sent at %1 - Zpráva odeslána. Čekám na potvrzení. Odesláno v %1 + Message sent. Waiting for acknowledgement. Sent at {0} + Zpráva odeslána. Čekám na potvrzení. Odesláno v {0} - Message sent. Sent at %1 - Zpráva odeslána. Odesláno v %1 + Message sent. Sent at {0} + Zpráva odeslána. Odesláno v {0} @@ -276,8 +276,8 @@ Please type the desired email address (including @mailchuck.com) below: - Acknowledgement of the message received %1 - Potvrzení o přijetí zprávy %1 + Acknowledgement of the message received {0} + Potvrzení o přijetí zprávy {0} @@ -286,18 +286,18 @@ Please type the desired email address (including @mailchuck.com) below: - Broadcast on %1 - Rozesláno v %1 + Broadcast on {0} + Rozesláno v {0} - Problem: The work demanded by the recipient is more difficult than you are willing to do. %1 - Problém: Obtížnost práce požadovaná adresátem je vyšší než Vámi povolené maximum. %1 + Problem: The work demanded by the recipient is more difficult than you are willing to do. {0} + Problém: Obtížnost práce požadovaná adresátem je vyšší než Vámi povolené maximum. {0} - Problem: The recipient's encryption key is no good. Could not encrypt message. %1 - Problém: Šifrovací klíč adresáta je nepoužitelný. Zprávu nelze zašifrovat. %1 + Problem: The recipient's encryption key is no good. Could not encrypt message. {0} + Problém: Šifrovací klíč adresáta je nepoužitelný. Zprávu nelze zašifrovat. {0} @@ -306,8 +306,8 @@ Please type the desired email address (including @mailchuck.com) below: - Unknown status: %1 %2 - Neznámý stav: %1 %2 + Unknown status: {0} {1} + Neznámý stav: {0} {1} @@ -347,10 +347,10 @@ Please type the desired email address (including @mailchuck.com) below: You may manage your keys by editing the keys.dat file stored in - %1 + {0} It is important that you back up this file. Své klíče můžete spravovat editováním souboru keys.dat, který najdete zde: - %1 + {0} Je důležité si tento soubor zazálohovat. @@ -366,10 +366,10 @@ Je důležité si tento soubor zazálohovat. You may manage your keys by editing the keys.dat file stored in - %1 + {0} 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.) Své klíče můžete spravovat editováním souboru keys.dat, který najdete zde: - %1 + {0} Je důležité si tento soubor zazálohovat. Přejete si tento soubor nyní otevřít? (Nezapomeňte zavřít Bitmessage předtím, než provedete jakékoli změny.) @@ -434,8 +434,8 @@ Je důležité si tento soubor zazálohovat. Přejete si tento soubor nyní otev - Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: %1. This address also appears in 'Your Identities'. - Kanál byl úspěšně vytvořen. Když chcete jiným lidem povolit připojit se k Vašemu kanálu, řekněte jim jméno kanálu a tuto adresu Bitmessage: %1. Tuto adresu také najdete v sekci "Vaše identity". + Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: {0}. This address also appears in 'Your Identities'. + Kanál byl úspěšně vytvořen. Když chcete jiným lidem povolit připojit se k Vašemu kanálu, řekněte jim jméno kanálu a tuto adresu Bitmessage: {0}. Tuto adresu také najdete v sekci "Vaše identity". @@ -502,53 +502,53 @@ Je důležité si tento soubor zazálohovat. Přejete si tento soubor nyní otev - The message that you are trying to send is too long by %1 bytes. (The maximum is 261644 bytes). Please cut it down before sending. - Zpráva, kterou se snažíte poslat, je o %1 bajtů delší, než je dovoleno. (Maximum je 261644 bajtů). Zkuste ji prosím před odesláním zkrátit. + The message that you are trying to send is too long by {0} bytes. (The maximum is 261644 bytes). Please cut it down before sending. + Zpráva, kterou se snažíte poslat, je o {0} bajtů delší, než je dovoleno. (Maximum je 261644 bajtů). Zkuste ji prosím před odesláním zkrátit. - Error: Your account wasn't registered at an email gateway. Sending registration now as %1, please wait for the registration to be processed before retrying sending. + Error: Your account wasn't registered at an email gateway. Sending registration now as {0}, please wait for the registration to be processed before retrying sending. - Error: Bitmessage addresses start with BM- Please check %1 - Chyba: Adresy Bitmessage začínají na BM- Zkontroluje prosím %1 + Error: Bitmessage addresses start with BM- Please check {0} + Chyba: Adresy Bitmessage začínají na BM- Zkontroluje prosím {0} - Error: The address %1 is not typed or copied correctly. Please check it. - Chyba: Adresa %1 nebyla správně opsána nebo zkopírována. Zkontrolujte ji prosím. + Error: The address {0} is not typed or copied correctly. Please check it. + Chyba: Adresa {0} nebyla správně opsána nebo zkopírována. Zkontrolujte ji prosím. - Error: The address %1 contains invalid characters. Please check it. - Chyba: Adresa %1 obsahuje neplatné znaky. Zkontrolujte ji prosím. + Error: The address {0} contains invalid characters. Please check it. + Chyba: Adresa {0} obsahuje neplatné znaky. Zkontrolujte ji prosím. - Error: The address version in %1 is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. - Chyba: Verze adresy %1 je příliš vysoká. Buď používáte starou verzi Bitmessage a je čas na aktualizaci, nebo si Váš známý dělá legraci. + Error: The address version in {0} is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. + Chyba: Verze adresy {0} je příliš vysoká. Buď používáte starou verzi Bitmessage a je čas na aktualizaci, nebo si Váš známý dělá legraci. - Error: Some data encoded in the address %1 is too short. There might be something wrong with the software of your acquaintance. - Chyba: Některá data zakódovaná v adrese %1 jsou příliš krátká. Možná je to chyba softwaru, který Váš známý používá. + Error: Some data encoded in the address {0} is too short. There might be something wrong with the software of your acquaintance. + Chyba: Některá data zakódovaná v adrese {0} jsou příliš krátká. Možná je to chyba softwaru, který Váš známý používá. - Error: Some data encoded in the address %1 is too long. There might be something wrong with the software of your acquaintance. - Chyba: Některá data zakódovaná v adrese %1 jsou příliš dlouhá. Možná je to chyba softwaru, který Váš známý používá. + Error: Some data encoded in the address {0} is too long. There might be something wrong with the software of your acquaintance. + Chyba: Některá data zakódovaná v adrese {0} jsou příliš dlouhá. Možná je to chyba softwaru, který Váš známý používá. - Error: Some data encoded in the address %1 is malformed. There might be something wrong with the software of your acquaintance. - Chyba: Některá data zakódovaná v adrese %1 mají neplatný formát. Možná je to chyba softwaru, který Váš známý používá. + Error: Some data encoded in the address {0} is malformed. There might be something wrong with the software of your acquaintance. + Chyba: Některá data zakódovaná v adrese {0} mají neplatný formát. Možná je to chyba softwaru, který Váš známý používá. - Error: Something is wrong with the address %1. - Chyba: Nastal problém s adresou %1. + Error: Something is wrong with the address {0}. + Chyba: Nastal problém s adresou {0}. @@ -562,8 +562,8 @@ Je důležité si tento soubor zazálohovat. Přejete si tento soubor nyní otev - Concerning the address %1, Bitmessage cannot understand address version numbers of %2. Perhaps upgrade Bitmessage to the latest version. - Co se týče adresy %1, Bitmessage nerozumí jejímu číslu verze "%2". Možná byste měl(a) aktualizovat Bitmessage na nejnovější verzi. + Concerning the address {0}, Bitmessage cannot understand address version numbers of {1}. Perhaps upgrade Bitmessage to the latest version. + Co se týče adresy {0}, Bitmessage nerozumí jejímu číslu verze "{1}". Možná byste měl(a) aktualizovat Bitmessage na nejnovější verzi. @@ -572,8 +572,8 @@ Je důležité si tento soubor zazálohovat. Přejete si tento soubor nyní otev - Concerning the address %1, Bitmessage cannot handle stream numbers of %2. Perhaps upgrade Bitmessage to the latest version. - Co se týče adresy %1, Bitmessage neumí zpracovat její číslo proudu "%2". Možná byste měl(a) aktualizovat Bitmessage na nejnovější verzi. + Concerning the address {0}, Bitmessage cannot handle stream numbers of {1}. Perhaps upgrade Bitmessage to the latest version. + Co se týče adresy {0}, Bitmessage neumí zpracovat její číslo proudu "{1}". Možná byste měl(a) aktualizovat Bitmessage na nejnovější verzi. @@ -707,8 +707,8 @@ Je důležité si tento soubor zazálohovat. Přejete si tento soubor nyní otev - Bitmessage cannot find your address %1. Perhaps you removed it? - Bitmessage nemůže najít Vaši adresu %1. Možná jste ji odstranil(a)? + Bitmessage cannot find your address {0}. Perhaps you removed it? + Bitmessage nemůže najít Vaši adresu {0}. Možná jste ji odstranil(a)? @@ -861,8 +861,8 @@ Are you sure you want to delete the channel? - You are using TCP port %1. (This can be changed in the settings). - Používáte TCP port %1. (To lze změnit v nastavení). + You are using TCP port {0}. (This can be changed in the settings). + Používáte TCP port {0}. (To lze změnit v nastavení). @@ -1056,7 +1056,7 @@ Are you sure you want to delete the channel? - Zoom level %1% + Zoom level {0}% @@ -1071,47 +1071,47 @@ Are you sure you want to delete the channel? - Display the %1 recent broadcast(s) from this address. + Display the {0} recent broadcast(s) from this address. - New version of PyBitmessage is available: %1. Download it from https://github.com/Bitmessage/PyBitmessage/releases/latest + New version of PyBitmessage is available: {0}. Download it from https://github.com/Bitmessage/PyBitmessage/releases/latest - Waiting for PoW to finish... %1% + Waiting for PoW to finish... {0}% - Shutting down Pybitmessage... %1% + Shutting down Pybitmessage... {0}% - Waiting for objects to be sent... %1% + Waiting for objects to be sent... {0}% - Saving settings... %1% + Saving settings... {0}% - Shutting down core... %1% + Shutting down core... {0}% - Stopping notifications... %1% + Stopping notifications... {0}% - Shutdown imminent... %1% + Shutdown imminent... {0}% @@ -1134,7 +1134,7 @@ Are you sure you want to delete the channel? - Shutting down PyBitmessage... %1% + Shutting down PyBitmessage... {0}% @@ -1154,12 +1154,12 @@ Are you sure you want to delete the channel? - Generating %1 new addresses. + Generating {0} new addresses. - %1 is already in 'Your Identities'. Not adding it again. + {0} is already in 'Your Identities'. Not adding it again. @@ -1169,7 +1169,7 @@ Are you sure you want to delete the channel? - SOCKS5 Authentication problem: %1 + SOCKS5 Authentication problem: {0} @@ -1194,7 +1194,7 @@ Are you sure you want to delete the channel? - Broadcast sent on %1 + Broadcast sent on {0} @@ -1214,7 +1214,7 @@ Are you sure you want to delete the channel? - Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. %1 + Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. {0} @@ -1226,17 +1226,17 @@ There is no required difficulty for version 2 addresses like this. Doing work necessary to send message. -Receiver's required difficulty: %1 and %2 +Receiver's required difficulty: {0} and {1} - Problem: The work demanded by the recipient (%1 and %2) is more difficult than you are willing to do. %3 + Problem: The work demanded by the recipient ({0} and {1}) is more difficult than you are willing to do. {2} - Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. %1 + Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. {0} @@ -1246,7 +1246,7 @@ Receiver's required difficulty: %1 and %2 - Message sent. Waiting for acknowledgement. Sent on %1 + Message sent. Waiting for acknowledgement. Sent on {0} @@ -1261,12 +1261,12 @@ Receiver's required difficulty: %1 and %2 - Sending public key request. Waiting for reply. Requested at %1 + Sending public key request. Waiting for reply. Requested at {0} - UPnP port mapping established on port %1 + UPnP port mapping established on port {0} @@ -1629,27 +1629,27 @@ Možnost "Náhodné číslo" je nastavena jako výchozí, deterministi - Since startup on %1 + Since startup on {0} - Down: %1/s Total: %2 + Down: {0}/s Total: {1} - Up: %1/s Total: %2 + Up: {0}/s Total: {1} - Total Connections: %1 + Total Connections: {0} - Inventory lookups per second: %1 + Inventory lookups per second: {0} diff --git a/src/translations/bitmessage_da.qm b/src/translations/bitmessage_da.qm index e5588987d61b2cbd158dd2b8b9444f3daa08fb46..1b4366011f9a29afbab0e833797b0c7327ffe3f8 100644 GIT binary patch delta 3458 zcmaJ@2~<;O7XDsdUiL*4MWsqqK$d_=Q4z}`f-GuqMFnJ0qavCp!37b5Vp|0q(T6Qi z3RJQN#7G~6Q5XXiC z^#(}8k5a%LunT_(tiFdqS6%>aO1MgbfH+@x_Pt1;#PHo*0VJhi#I-yi_jg3Rcb1ZP zZnODzi288~&{Kd3TYn~i4=~|983A-e%)(W`PA5!Wc>+L@)tZ5|hY_2<5ZJ#C(^F}~ z{&vhbL;<@i5oZb@q#KbS$|oC-qyQx_s}4(^lS94&%llJCkynxVkvA|R}bDTs#5j@hz*oTt}jv z$g1DI0_3e^d({1t7`eu3%7X~lQFgd72iRd^M>P@fp6l2^orccuFtekRnt;^%Z0YZb zz=U$PBJph!;a&Ea;w(^mkF8H6l@E7gFT79hhlR2i#d@IIJ)14q&Nj6b1Cr(JPtz%p zal6>Il@w@!n^2uZn%UPb4E!_<*t@#bUnUMUmrDEtd{-R%q$pexpLDL9OlVoOnF)=bovLf8< zP5u3=Buh_$RPRgjcf^qfvL%~6NGv9$gg-@rjm?r1$Af63o|0VHeU`c+SMs&FKeb_r zRH@vP#nWtb)3z)MnR)OP;J<3gldt_E@|D(6>k(cTsyDm@4%x$t0ku z(h=r_Il!AwrQ`7um@`Rg(oq19QYqg}NR!P?T6T39i3ZYbZ_#>wi}b+u7^<~J`s38! ziORprHJ6isb0Q?|3lS`tEsgO0kL#6R~ zOU_KFrGZo*Bo-A+5 zY@?BTSbigND+SWY?{^;z6xPe{Ye@A~_40?c6mU?bLS9LJgZvdfR!xjgRfK3M-Z_53Dy{AV>VHX#D)LD_QL9i*1eJhyRV9>BrgJk?n;y`{c)6UH+cktdYKiLNkUk_n*sSQW&92#JvjtA7CLLW$*)=v>c3bsek~7@_ zr`1DTh-u+EwXb2B8Q9&Z9`+>#+&M`-?l5II(peo-6$C6gqE0SbM}0g+o#Eg`>UB{U zT%pS*BwM|=;RW#FWp!Y6t7@r*Va#ii=gJ;}~csvFik2Q)F9U(gvq5NmTL;2gPzIIvgK{hlJYjz^~dh!yr z8=K{m%`a8kTgIyA$eHy#bJBs2a_Y`s>FdmO9N?ez4Q4|407qx*R!g#DJ2SKwMq?gK z(8GYa$N>FEvHE`Pxm#$uF=g(Y6jO%AXwY;7A=1uybpzYi$V=W zHlG~e#E)}u<1ab+J7$kD8s_NJ4XK9tnv4Z{P0HN4>3Wl?!`lFj7n?OSo1dtO*fLwh zi=CYR;_$Y{|GzlQ|Gy6H`SSx@JDpmF4}2_U7V=sTz51`21@aXh0iB#Nllcc8<6iOV z{W|+0e3YkW$DRQLds>pc%nXymr+7KN;6lzyEME#HbeY_$px4k2~G2XmeuzMH0efY%SUN$U!dhvz98C}+g^U9DnJM*!` zhKv?7kNA=Z&sSK_MKm~O#TfJ&<2+5Kaanq274#;pwGft?NG-$v5^c}7Ms4Zhc`{!Z z9nR delta 3802 zcmaJ@3tY{28~^^#IsbFNR5F)F$E8rIL?M(U-E^>0D^W)sm2ys6uh02B{cg|Y`+T40_uo;@-(ATs zcQRL=1q2nq5PyJe1ZI2%gn0n+4M5E2fPXBlxzX=2kUkM;;UGBY0=Pv&aB(K!UJt=t zZ@|OVCd(CIR|$X#r@&S{1KyefwwCTqDg?V{D{vqR?7>o!Z4mC{!;F>|h+;#4W3G^d z93q27un+kKD5}GN^S=Xw?!r|Z0K`9sd+$~t`dj!^kaJ017}>TISbPAX>rPS-FKn{( zG{SF31CGBUYVFVDU@M~5Nl8A#l(`Fm`gXika1=nfRhoe%dc>B^1sca9E`tsz#EnI8hZd5m*!0Wfk9)6a_#*m8>*EFSW$`!6T1H&^*vvmHKS>7b_-Edy z1>b)BR*?>{yJeFrxyrPK~d66hK|scP;DGG!ECnV%s41tFVzMNqJ{l~Ql660GneNXNAZ zcCTRorzXLkA>=^fuYx@u^)$aOXj~dcr12A2Y8`=@-wFP4cL*6;D>%8pg&;gAXmdD0 z>qRW{JsIj=$d3HE3K+GQ9esw_|K2dxKb=o06tWW@YJeX0Y~qyM6^Jo-~zhC}qizJ9}U{DfWnF z52umg$krhV0&9i4 z)W@hCuL&)yy8(+X2|u!?uJnQM+g((4jXw%6$C6_W6NUGMq&L=8A%sfB&o7fy*GrtXQ@QS! zOI*!gkVn3C5}&FCs zm(@!4*G(Y~yeGLG^PC_(EtTaEXK+H=pSeM~ekpZbN(ij_LK<7Thd9& z-N}?1q0~J0Dk&^Vm3GMLKxxq^ig5NiX+yv>%3-ebknABD%#j|d{e@WEB>iNug`{43 zZaJmK+evyYkvL%-BV(c(sKYIkNfrLc~C!7Z~0 znL9FX;UXZ1Z2dDA#0)w_qh$(sAO7s?MBC}rjx`4PrM9PqNqCTDqzBRR&clb@SQa_N`yuT|ur z|8Me(kNS}QVEOlj=jmQ^zWhnd2I|$<72;dX1Z9CjIf)MTOIJ8$Q4Vv96a!N}p_Y3} z;aW`wMwBXsa=U=>n+^|cz&SLvZyPp$Ww zGVE~~u>PcSDkvrIT~V(2iS`pND60=ps+h^jO*2MOKe(=}QmQ$PX#9 zQ7=?ewgv!MCRK9HJ5<*Js$FM)2R- zo8yS2p;fA9@6x@dR3gx^I6iqe5Zw040Ly2Rn*!!7ZjUlb<$_^Qi>=-Z>F35tRf8E9 z?ms@=E#ayZ8MBHq~4D%wf2CwL5FI?!o0`_u^u`9k@BpZe+rTEAe;c zG(84$KRAzK3c0=gdXOp3OFfk5;=?7WLz$%)gULoM6f%}kS5m>uK6 zg$E9K&AXmlN#Glu-W70-fqAd(`f|g^5ARG^@%SJS^MLy})V;&MpF++NJniSfx=aKvsvxIw|Jkq-7r{xKm!QALH=fT!=TiM~$g>Cog`b@nc zU#~XhYIE~U{)C>IvYgZ3(NdFki_a8rC7FXdbPlVD>m3wt$Wv>LI(42YL!YLO37)FX zHW+iQkk{3CSR%6;8RiPtm{TH>S~&_xq465h9#(w_!> zXrbfsYdiK`Gy3FwWl+1M;quDL>;KZn%AbcB)Xo2LME>QfZ871MJ$lDFhoM8}{xR*6 z)Rg{qP-FXlgZj|l4TWBpADph$Pt4F}8Pe=Dy8IwpDcKev)6O>J<=Q6FbX`_<=ep9Q z%grSom^$W68mHdu#3d=69biWaUem#Otm(^Tuj~=+kdb20hh`Z}CarNnryj}dENx0= uR)#6pA!MF5BP&#!tIOB^u`7+zX6WNG^r?n?DCn|Ym(uCW3JQqFF#iQ;MEF?% diff --git a/src/translations/bitmessage_da.ts b/src/translations/bitmessage_da.ts index fcf80470..707967e7 100644 --- a/src/translations/bitmessage_da.ts +++ b/src/translations/bitmessage_da.ts @@ -241,8 +241,8 @@ Please type the desired email address (including @mailchuck.com) below: - One of your addresses, %1, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? - En af dine adresser, %1 er en gammel version 1-addresse. Version 1-addresser understøttes ikke længere. Må vi slette den? + One of your addresses, {0}, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? + En af dine adresser, {0} er en gammel version 1-addresse. Version 1-addresser understøttes ikke længere. Må vi slette den? @@ -261,13 +261,13 @@ Please type the desired email address (including @mailchuck.com) below: - Message sent. Waiting for acknowledgement. Sent at %1 - Besked afsendt. Afventer bekræftelse på modtagelse. Sendt %1 + Message sent. Waiting for acknowledgement. Sent at {0} + Besked afsendt. Afventer bekræftelse på modtagelse. Sendt {0} - Message sent. Sent at %1 - Besked sendt. Sendt %1 + Message sent. Sent at {0} + Besked sendt. Sendt {0} @@ -276,8 +276,8 @@ Please type the desired email address (including @mailchuck.com) below: - Acknowledgement of the message received %1 - Bekræftelse på modtagelse er modtaget %1 + Acknowledgement of the message received {0} + Bekræftelse på modtagelse er modtaget {0} @@ -286,18 +286,18 @@ Please type the desired email address (including @mailchuck.com) below: - Broadcast on %1 - Afsendt %1 + Broadcast on {0} + Afsendt {0} - Problem: The work demanded by the recipient is more difficult than you are willing to do. %1 - Problem: Beregningen som kræves af modtageren er mere besværlig end du accepterer. %1 + Problem: The work demanded by the recipient is more difficult than you are willing to do. {0} + Problem: Beregningen som kræves af modtageren er mere besværlig end du accepterer. {0} - Problem: The recipient's encryption key is no good. Could not encrypt message. %1 - Problem: Modtagerens krypteringsnøgle virker ikke. Beskeden kunne ikke krypteres. %1 + Problem: The recipient's encryption key is no good. Could not encrypt message. {0} + Problem: Modtagerens krypteringsnøgle virker ikke. Beskeden kunne ikke krypteres. {0} @@ -306,8 +306,8 @@ Please type the desired email address (including @mailchuck.com) below: - Unknown status: %1 %2 - Ukendt status: %1 %2 + Unknown status: {0} {1} + Ukendt status: {0} {1} @@ -347,10 +347,10 @@ Please type the desired email address (including @mailchuck.com) below: You may manage your keys by editing the keys.dat file stored in - %1 + {0} It is important that you back up this file. Du kan administrere dine nøgler ved at redigere keys.dat-filen i -%1 +{0} Det er vigtigt at tage backup af denne fil. @@ -366,10 +366,10 @@ Det er vigtigt at tage backup af denne fil. You may manage your keys by editing the keys.dat file stored in - %1 + {0} 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.) Du kan administrere dine nøgler ved at redigere keys.dat-filen i -%1 +{0} Det er vigtigt at tage backup af denne fil. (Sørg for at lukke Bitmessage før du foretager ændringer.) @@ -434,8 +434,8 @@ Det er vigtigt at tage backup af denne fil. (Sørg for at lukke Bitmessage før - Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: %1. This address also appears in 'Your Identities'. - Ny kanal oprettet. For at andre kan blive medlem skal du oplyse dem kanalnavnet og denne Bitmessage-adresse: %1. Denne adresse vises også i 'Dine identiteter'. + Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: {0}. This address also appears in 'Your Identities'. + Ny kanal oprettet. For at andre kan blive medlem skal du oplyse dem kanalnavnet og denne Bitmessage-adresse: {0}. Denne adresse vises også i 'Dine identiteter'. @@ -502,53 +502,53 @@ Det er vigtigt at tage backup af denne fil. (Sørg for at lukke Bitmessage før - The message that you are trying to send is too long by %1 bytes. (The maximum is 261644 bytes). Please cut it down before sending. - Beskeden som du prøver at sende er %1 byte for lang. (Den maksimale størrelse er 261644 byte). Prøv at gøre den kortere før afsendelsen. + The message that you are trying to send is too long by {0} bytes. (The maximum is 261644 bytes). Please cut it down before sending. + Beskeden som du prøver at sende er {0} byte for lang. (Den maksimale størrelse er 261644 byte). Prøv at gøre den kortere før afsendelsen. - Error: Your account wasn't registered at an email gateway. Sending registration now as %1, please wait for the registration to be processed before retrying sending. + Error: Your account wasn't registered at an email gateway. Sending registration now as {0}, please wait for the registration to be processed before retrying sending. - Error: Bitmessage addresses start with BM- Please check %1 - Fejl: Bitmessage-adresser starter med BM- Check %1 + Error: Bitmessage addresses start with BM- Please check {0} + Fejl: Bitmessage-adresser starter med BM- Check {0} - Error: The address %1 is not typed or copied correctly. Please check it. - Fejl: Adressen %1 er skrever eller kopieret forkert. Tjek den venligst. + Error: The address {0} is not typed or copied correctly. Please check it. + Fejl: Adressen {0} er skrever eller kopieret forkert. Tjek den venligst. - Error: The address %1 contains invalid characters. Please check it. - Fejl: Adressen %1 indeholder ugyldige tegn. Tjek den venligst. + Error: The address {0} contains invalid characters. Please check it. + Fejl: Adressen {0} indeholder ugyldige tegn. Tjek den venligst. - Error: The address version in %1 is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. + Error: The address version in {0} is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. - Error: Some data encoded in the address %1 is too short. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is too short. There might be something wrong with the software of your acquaintance. - Error: Some data encoded in the address %1 is too long. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is too long. There might be something wrong with the software of your acquaintance. - Error: Some data encoded in the address %1 is malformed. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is malformed. There might be something wrong with the software of your acquaintance. - Error: Something is wrong with the address %1. - Fejl: Der er noget galt med adressen %1. + Error: Something is wrong with the address {0}. + Fejl: Der er noget galt med adressen {0}. @@ -562,8 +562,8 @@ Det er vigtigt at tage backup af denne fil. (Sørg for at lukke Bitmessage før - Concerning the address %1, Bitmessage cannot understand address version numbers of %2. Perhaps upgrade Bitmessage to the latest version. - Vedrørende adressen %1, Bitmessage forstår ikke addreseversion %2. Måske bør du opgradere Bitmessage til den nyeste version. + Concerning the address {0}, Bitmessage cannot understand address version numbers of {1}. Perhaps upgrade Bitmessage to the latest version. + Vedrørende adressen {0}, Bitmessage forstår ikke addreseversion {1}. Måske bør du opgradere Bitmessage til den nyeste version. @@ -572,8 +572,8 @@ Det er vigtigt at tage backup af denne fil. (Sørg for at lukke Bitmessage før - Concerning the address %1, Bitmessage cannot handle stream numbers of %2. Perhaps upgrade Bitmessage to the latest version. - Vedrørende adressen %1, Bitmessage kan ikke håndtere flod nummer %2. Måske bør du opgradere Bitmessage til den nyeste version. + Concerning the address {0}, Bitmessage cannot handle stream numbers of {1}. Perhaps upgrade Bitmessage to the latest version. + Vedrørende adressen {0}, Bitmessage kan ikke håndtere flod nummer {1}. Måske bør du opgradere Bitmessage til den nyeste version. @@ -707,8 +707,8 @@ Det er vigtigt at tage backup af denne fil. (Sørg for at lukke Bitmessage før - Bitmessage cannot find your address %1. Perhaps you removed it? - Bitmessage kan ikke finde din adresse %1. Måske har du fjernet den? + Bitmessage cannot find your address {0}. Perhaps you removed it? + Bitmessage kan ikke finde din adresse {0}. Måske har du fjernet den? @@ -865,8 +865,8 @@ Er du sikker på at du vil slette denne kanal? - You are using TCP port %1. (This can be changed in the settings). - Du bruger TCP-port %1. (Dette kan ændres i indstillingerne). + You are using TCP port {0}. (This can be changed in the settings). + Du bruger TCP-port {0}. (Dette kan ændres i indstillingerne). @@ -1060,8 +1060,8 @@ Er du sikker på at du vil slette denne kanal? - Zoom level %1% - Zoom %1% + Zoom level {0}% + Zoom {0}% @@ -1075,47 +1075,47 @@ Er du sikker på at du vil slette denne kanal? - Display the %1 recent broadcast(s) from this address. + Display the {0} recent broadcast(s) from this address. - New version of PyBitmessage is available: %1. Download it from https://github.com/Bitmessage/PyBitmessage/releases/latest + New version of PyBitmessage is available: {0}. Download it from https://github.com/Bitmessage/PyBitmessage/releases/latest - Waiting for PoW to finish... %1% + Waiting for PoW to finish... {0}% - Shutting down Pybitmessage... %1% + Shutting down Pybitmessage... {0}% - Waiting for objects to be sent... %1% + Waiting for objects to be sent... {0}% - Saving settings... %1% + Saving settings... {0}% - Shutting down core... %1% + Shutting down core... {0}% - Stopping notifications... %1% + Stopping notifications... {0}% - Shutdown imminent... %1% + Shutdown imminent... {0}% @@ -1136,7 +1136,7 @@ Er du sikker på at du vil slette denne kanal? - Shutting down PyBitmessage... %1% + Shutting down PyBitmessage... {0}% @@ -1156,12 +1156,12 @@ Er du sikker på at du vil slette denne kanal? - Generating %1 new addresses. + Generating {0} new addresses. - %1 is already in 'Your Identities'. Not adding it again. + {0} is already in 'Your Identities'. Not adding it again. @@ -1171,7 +1171,7 @@ Er du sikker på at du vil slette denne kanal? - SOCKS5 Authentication problem: %1 + SOCKS5 Authentication problem: {0} @@ -1196,7 +1196,7 @@ Er du sikker på at du vil slette denne kanal? - Broadcast sent on %1 + Broadcast sent on {0} @@ -1216,7 +1216,7 @@ Er du sikker på at du vil slette denne kanal? - Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. %1 + Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. {0} @@ -1228,17 +1228,17 @@ There is no required difficulty for version 2 addresses like this. Doing work necessary to send message. -Receiver's required difficulty: %1 and %2 +Receiver's required difficulty: {0} and {1} - Problem: The work demanded by the recipient (%1 and %2) is more difficult than you are willing to do. %3 + Problem: The work demanded by the recipient ({0} and {1}) is more difficult than you are willing to do. {2} - Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. %1 + Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. {0} @@ -1248,7 +1248,7 @@ Receiver's required difficulty: %1 and %2 - Message sent. Waiting for acknowledgement. Sent on %1 + Message sent. Waiting for acknowledgement. Sent on {0} @@ -1263,12 +1263,12 @@ Receiver's required difficulty: %1 and %2 - Sending public key request. Waiting for reply. Requested at %1 + Sending public key request. Waiting for reply. Requested at {0} - UPnP port mapping established on port %1 + UPnP port mapping established on port {0} @@ -1631,27 +1631,27 @@ Som standard er tilfældige tal valgt, men der er både fordele og ulemper ved a - Since startup on %1 + Since startup on {0} - Down: %1/s Total: %2 + Down: {0}/s Total: {1} - Up: %1/s Total: %2 + Up: {0}/s Total: {1} - Total Connections: %1 + Total Connections: {0} - Inventory lookups per second: %1 + Inventory lookups per second: {0} diff --git a/src/translations/bitmessage_de.qm b/src/translations/bitmessage_de.qm index ef443a619e0e40e55aede8479d45b488e57652f4..e42c1760a3ef57b38624c14f3ff0d4606f57589b 100644 GIT binary patch delta 6500 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 - One of your addresses, %1, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? - Eine Ihrer Adressen, %1, ist eine alte Adresse der Version 1 und wird nicht mehr unterstützt. Soll sie jetzt gelöscht werden? + One of your addresses, {0}, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? + Eine Ihrer Adressen, {0}, ist eine alte Adresse der Version 1 und wird nicht mehr unterstützt. Soll sie jetzt gelöscht werden? @@ -334,13 +334,13 @@ Please type the desired email address (including @mailchuck.com) below: - Message sent. Waiting for acknowledgement. Sent at %1 - Nachricht gesendet. Warte auf Bestätigung. Zeitpunkt der Sendung: %1 + Message sent. Waiting for acknowledgement. Sent at {0} + Nachricht gesendet. Warte auf Bestätigung. Zeitpunkt der Sendung: {0} - Message sent. Sent at %1 - Nachricht gesendet. Zeitpunkt der Sendung: %1 + Message sent. Sent at {0} + Nachricht gesendet. Zeitpunkt der Sendung: {0} @@ -349,8 +349,8 @@ Please type the desired email address (including @mailchuck.com) below: - Acknowledgement of the message received %1 - Bestätigung der Nachricht erhalten %1 + Acknowledgement of the message received {0} + Bestätigung der Nachricht erhalten {0} @@ -359,18 +359,18 @@ Please type the desired email address (including @mailchuck.com) below: - Broadcast on %1 - Rundruf um %1 + Broadcast on {0} + Rundruf um {0} - Problem: The work demanded by the recipient is more difficult than you are willing to do. %1 - Problem: Die vom Empfänger geforderte Arbeit ist schwerer als Sie bereit sind, zu berechnen. %1 + Problem: The work demanded by the recipient is more difficult than you are willing to do. {0} + Problem: Die vom Empfänger geforderte Arbeit ist schwerer als Sie bereit sind, zu berechnen. {0} - Problem: The recipient's encryption key is no good. Could not encrypt message. %1 - Problem: Der Verschlüsselungscode des Empfängers ist nicht in Ordnung. Nachricht konnte nicht verschlüsselt werden. %1 + Problem: The recipient's encryption key is no good. Could not encrypt message. {0} + Problem: Der Verschlüsselungscode des Empfängers ist nicht in Ordnung. Nachricht konnte nicht verschlüsselt werden. {0} @@ -379,8 +379,8 @@ Please type the desired email address (including @mailchuck.com) below: - Unknown status: %1 %2 - Unbekannter Status: %1 %2 + Unknown status: {0} {1} + Unbekannter Status: {0} {1} @@ -420,10 +420,10 @@ Please type the desired email address (including @mailchuck.com) below: You may manage your keys by editing the keys.dat file stored in - %1 + {0} It is important that you back up this file. Sie können Ihre Schlüssel verwalten, indem Sie die keys.dat bearbeiten, die im Ordner -%1 liegt. +{0} liegt. Es ist empfehlenswert, vorher ein Backup dieser Datei anzulegen. @@ -439,10 +439,10 @@ Es ist empfehlenswert, vorher ein Backup dieser Datei anzulegen. You may manage your keys by editing the keys.dat file stored in - %1 + {0} 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.) Sie können Ihre Schlüssel verwalten, indem Sie die keys.dat bearbeiten, -die im Ordner %1 liegt. +die im Ordner {0} liegt. Es ist empfehlenswert, vorher ein Backup dieser Datei anzulegen. Möchten Sie die Datei jetzt öffnen? (Stellen Sie sicher, dass Sie Bitmessage beendet haben, bevor Sie etwas ändern.) @@ -508,7 +508,7 @@ Es ist empfehlenswert, vorher ein Backup dieser Datei anzulegen. Möchten Sie di - Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: %1. This address also appears in 'Your Identities'. + Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: {0}. This address also appears in 'Your Identities'. @@ -576,52 +576,52 @@ Es ist empfehlenswert, vorher ein Backup dieser Datei anzulegen. Möchten Sie di - The message that you are trying to send is too long by %1 bytes. (The maximum is 261644 bytes). Please cut it down before sending. - Die Nachricht, die Sie zu senden versuchen, ist %1 Byte zu lang. (Maximum 261.644 Bytes). Bitte verringern Sie ihre Größe vor dem Senden. + The message that you are trying to send is too long by {0} bytes. (The maximum is 261644 bytes). Please cut it down before sending. + Die Nachricht, die Sie zu senden versuchen, ist {0} Byte zu lang. (Maximum 261.644 Bytes). Bitte verringern Sie ihre Größe vor dem Senden. - Error: Your account wasn't registered at an email gateway. Sending registration now as %1, please wait for the registration to be processed before retrying sending. - Fehler: Ihr Konto war an keiner E-Mail Schnittstelle registriert. Registrierung als %1 wird versandt, bitte vor einem erneutem Sendeversuch auf die Registrierungsverarbeitung warten. + Error: Your account wasn't registered at an email gateway. Sending registration now as {0}, please wait for the registration to be processed before retrying sending. + Fehler: Ihr Konto war an keiner E-Mail Schnittstelle registriert. Registrierung als {0} wird versandt, bitte vor einem erneutem Sendeversuch auf die Registrierungsverarbeitung warten. - Error: Bitmessage addresses start with BM- Please check %1 + Error: Bitmessage addresses start with BM- Please check {0} - Error: The address %1 is not typed or copied correctly. Please check it. + Error: The address {0} is not typed or copied correctly. Please check it. - Error: The address %1 contains invalid characters. Please check it. + Error: The address {0} contains invalid characters. Please check it. - Error: The address version in %1 is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. + Error: The address version in {0} is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. - Error: Some data encoded in the address %1 is too short. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is too short. There might be something wrong with the software of your acquaintance. - Error: Some data encoded in the address %1 is too long. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is too long. There might be something wrong with the software of your acquaintance. - Error: Some data encoded in the address %1 is malformed. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is malformed. There might be something wrong with the software of your acquaintance. - Error: Something is wrong with the address %1. + Error: Something is wrong with the address {0}. @@ -636,8 +636,8 @@ Es ist empfehlenswert, vorher ein Backup dieser Datei anzulegen. Möchten Sie di - Concerning the address %1, Bitmessage cannot understand address version numbers of %2. Perhaps upgrade Bitmessage to the latest version. - Aufgrund der Adresse %1 kann Bitmessage Adressen mit der Version %2 nicht verarbeiten. Möglicherweise müssen Sie Bitmessage auf die aktuelle Version aktualisieren. + Concerning the address {0}, Bitmessage cannot understand address version numbers of {1}. Perhaps upgrade Bitmessage to the latest version. + Aufgrund der Adresse {0} kann Bitmessage Adressen mit der Version {1} nicht verarbeiten. Möglicherweise müssen Sie Bitmessage auf die aktuelle Version aktualisieren. @@ -646,8 +646,8 @@ Es ist empfehlenswert, vorher ein Backup dieser Datei anzulegen. Möchten Sie di - Concerning the address %1, Bitmessage cannot handle stream numbers of %2. Perhaps upgrade Bitmessage to the latest version. - Aufgrund der Adresse %1 kann Bitmessage den Datenstrom mit der Version %2 nicht verarbeiten. Möglicherweise müssen Sie Bitmessage auf die aktuelle Version aktualisieren. + Concerning the address {0}, Bitmessage cannot handle stream numbers of {1}. Perhaps upgrade Bitmessage to the latest version. + Aufgrund der Adresse {0} kann Bitmessage den Datenstrom mit der Version {1} nicht verarbeiten. Möglicherweise müssen Sie Bitmessage auf die aktuelle Version aktualisieren. @@ -781,8 +781,8 @@ Es ist empfehlenswert, vorher ein Backup dieser Datei anzulegen. Möchten Sie di - Bitmessage cannot find your address %1. Perhaps you removed it? - Bitmessage kann Ihre Adresse %1 nicht finden. Haben Sie sie gelöscht? + Bitmessage cannot find your address {0}. Perhaps you removed it? + Bitmessage kann Ihre Adresse {0} nicht finden. Haben Sie sie gelöscht? @@ -939,7 +939,7 @@ Sind Sie sicher, dass Sie das Chan löschen möchten? - You are using TCP port %1. (This can be changed in the settings). + You are using TCP port {0}. (This can be changed in the settings). @@ -1134,8 +1134,8 @@ Sind Sie sicher, dass Sie das Chan löschen möchten? - Zoom level %1% - Zoom-Stufe %1% + Zoom level {0}% + Zoom-Stufe {0}% @@ -1149,48 +1149,48 @@ Sind Sie sicher, dass Sie das Chan löschen möchten? - Display the %1 recent broadcast(s) from this address. + Display the {0} recent broadcast(s) from this address. - New version of PyBitmessage is available: %1. Download it from https://github.com/Bitmessage/PyBitmessage/releases/latest - Neue Version von PyBitmessage steht zur Verfügung: %1. Sie können sie von https://github.com/Bitmessage/PyBitmessage/releases/latest herunterladen. + New version of PyBitmessage is available: {0}. Download it from https://github.com/Bitmessage/PyBitmessage/releases/latest + Neue Version von PyBitmessage steht zur Verfügung: {0}. Sie können sie von https://github.com/Bitmessage/PyBitmessage/releases/latest herunterladen. - Waiting for PoW to finish... %1% - Warte auf Abschluss von Berechnungen (PoW)... %1% + Waiting for PoW to finish... {0}% + Warte auf Abschluss von Berechnungen (PoW)... {0}% - Shutting down Pybitmessage... %1% - PyBitmessage wird beendet... %1% + Shutting down Pybitmessage... {0}% + PyBitmessage wird beendet... {0}% - Waiting for objects to be sent... %1% - Warte auf Versand von Objekten... %1% + Waiting for objects to be sent... {0}% + Warte auf Versand von Objekten... {0}% - Saving settings... %1% - Einstellungen werden gespeichert... %1% + Saving settings... {0}% + Einstellungen werden gespeichert... {0}% - Shutting down core... %1% - Kern wird beendet... %1% + Shutting down core... {0}% + Kern wird beendet... {0}% - Stopping notifications... %1% - Beende Benachrichtigungen... %1% + Stopping notifications... {0}% + Beende Benachrichtigungen... {0}% - Shutdown imminent... %1% - Unmittelbar vor Beendung... %1% + Shutdown imminent... {0}% + Unmittelbar vor Beendung... {0}% @@ -1204,8 +1204,8 @@ Sind Sie sicher, dass Sie das Chan löschen möchten? - Shutting down PyBitmessage... %1% - PyBitmessage wird beendet... %1% + Shutting down PyBitmessage... {0}% + PyBitmessage wird beendet... {0}% @@ -1224,13 +1224,13 @@ Sind Sie sicher, dass Sie das Chan löschen möchten? - Generating %1 new addresses. - Erzeuge %1 neue Addressen. + Generating {0} new addresses. + Erzeuge {0} neue Addressen. - %1 is already in 'Your Identities'. Not adding it again. - %1 befindet sich bereits unter Ihren Identitäten, wird nicht doppelt hinzugefügt. + {0} is already in 'Your Identities'. Not adding it again. + {0} befindet sich bereits unter Ihren Identitäten, wird nicht doppelt hinzugefügt. @@ -1239,7 +1239,7 @@ Sind Sie sicher, dass Sie das Chan löschen möchten? - SOCKS5 Authentication problem: %1 + SOCKS5 Authentication problem: {0} @@ -1264,8 +1264,8 @@ Sind Sie sicher, dass Sie das Chan löschen möchten? - Broadcast sent on %1 - Rundruf verschickt um %1 + Broadcast sent on {0} + Rundruf verschickt um {0} @@ -1284,7 +1284,7 @@ Sind Sie sicher, dass Sie das Chan löschen möchten? - Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. %1 + Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. {0} Problem: Der Empfänger benutzt ein mobiles Gerät und erfordert eine unverschlüsselte Empfängeraddresse. Dies ist in Ihren Einstellungen jedoch nicht zulässig. 1% @@ -1297,17 +1297,17 @@ Version-2-Addressen wie die des Empfängers haben keine Schweirigkeitserforderun Doing work necessary to send message. -Receiver's required difficulty: %1 and %2 - Arbeit für Nachrichtenversand wird errichtet. Vom Empfänger geforderte Schwierigkeit: %1 und %2 +Receiver's required difficulty: {0} and {1} + Arbeit für Nachrichtenversand wird errichtet. Vom Empfänger geforderte Schwierigkeit: {0} und {1} - Problem: The work demanded by the recipient (%1 and %2) is more difficult than you are willing to do. %3 - Problem: Die vom Empfänger verlangte Arbeit (%1 und %2) ist schwieriger, als Sie in den Einstellungen erlaubt haben. %3 + Problem: The work demanded by the recipient ({0} and {1}) is more difficult than you are willing to do. {2} + Problem: Die vom Empfänger verlangte Arbeit ({0} und {1}) ist schwieriger, als Sie in den Einstellungen erlaubt haben. {2} - Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. %1 + Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. {0} Problem: Sie versuchen, eine Nachricht an sich zu versenden, aber Ihr Schlüssel befindet sich nicht in der keys.dat-Datei. Die Nachricht kann nicht verschlüsselt werden. 1% @@ -1317,8 +1317,8 @@ Receiver's required difficulty: %1 and %2 - Message sent. Waiting for acknowledgement. Sent on %1 - Nachricht gesendet. Auf Bestätigung wird gewartet. Zeitpunkt der Sendung: %1 + Message sent. Waiting for acknowledgement. Sent on {0} + Nachricht gesendet. Auf Bestätigung wird gewartet. Zeitpunkt der Sendung: {0} @@ -1332,13 +1332,13 @@ Receiver's required difficulty: %1 and %2 - Sending public key request. Waiting for reply. Requested at %1 - Nachfrage nach dem öffentlichen Schlüssel läuft, auf Antwort wird gewartet. Nachgefragt am %1 + Sending public key request. Waiting for reply. Requested at {0} + Nachfrage nach dem öffentlichen Schlüssel läuft, auf Antwort wird gewartet. Nachgefragt am {0} - UPnP port mapping established on port %1 - UPnP Port-Mapping eingerichtet auf Port %1 + UPnP port mapping established on port {0} + UPnP Port-Mapping eingerichtet auf Port {0} @@ -1382,28 +1382,28 @@ Receiver's required difficulty: %1 and %2 - Problem communicating with proxy: %1. Please check your network settings. - Kommunikationsfehler mit dem Proxy: %1. Bitte überprüfen Sie Ihre Netzwerkeinstellungen. + Problem communicating with proxy: {0}. Please check your network settings. + Kommunikationsfehler mit dem Proxy: {0}. Bitte überprüfen Sie Ihre Netzwerkeinstellungen. - SOCKS5 Authentication problem: %1. Please check your SOCKS5 settings. - SOCKS5-Authentizierung fehlgeschlagen: %1. Bitte überprüfen Sie Ihre SOCKS5-Einstellungen. + SOCKS5 Authentication problem: {0}. Please check your SOCKS5 settings. + SOCKS5-Authentizierung fehlgeschlagen: {0}. Bitte überprüfen Sie Ihre SOCKS5-Einstellungen. - The time on your computer, %1, may be wrong. Please verify your settings. - Die Uhrzeit ihres Computers, %1, ist möglicherweise falsch. Bitte überprüfen Sie Ihre einstellungen. + The time on your computer, {0}, may be wrong. Please verify your settings. + Die Uhrzeit ihres Computers, {0}, ist möglicherweise falsch. Bitte überprüfen Sie Ihre einstellungen. - The name %1 was not found. - Der Name %1 wurde nicht gefunden. + The name {0} was not found. + Der Name {0} wurde nicht gefunden. - The namecoin query failed (%1) - Namecoin-abfrage fehlgeschlagen (%1) + The namecoin query failed ({0}) + Namecoin-abfrage fehlgeschlagen ({0}) @@ -1412,18 +1412,18 @@ Receiver's required difficulty: %1 and %2 - The name %1 has no valid JSON data. - Der Name %1 beinhaltet keine gültige JSON-Daten. + The name {0} has no valid JSON data. + Der Name {0} beinhaltet keine gültige JSON-Daten. - The name %1 has no associated Bitmessage address. - Der Name %1 hat keine zugewiesene Bitmessageaddresse. + The name {0} has no associated Bitmessage address. + Der Name {0} hat keine zugewiesene Bitmessageaddresse. - Success! Namecoind version %1 running. - Erfolg! Namecoind Version %1 läuft. + Success! Namecoind version {0} running. + Erfolg! Namecoind Version {0} läuft. @@ -1481,53 +1481,53 @@ Willkommen zu einfachem und sicherem Bitmessage - Error: Bitmessage addresses start with BM- Please check the recipient address %1 - Fehler: Bitmessage Adressen starten mit BM- Bitte überprüfen Sie die Empfängeradresse %1 + Error: Bitmessage addresses start with BM- Please check the recipient address {0} + Fehler: Bitmessage Adressen starten mit BM- Bitte überprüfen Sie die Empfängeradresse {0} - Error: The recipient address %1 is not typed or copied correctly. Please check it. - Fehler: Die Empfängeradresse %1 wurde nicht korrekt getippt oder kopiert. Bitte überprüfen. + Error: The recipient address {0} is not typed or copied correctly. Please check it. + Fehler: Die Empfängeradresse {0} wurde nicht korrekt getippt oder kopiert. Bitte überprüfen. - Error: The recipient address %1 contains invalid characters. Please check it. - Fehler: Die Empfängeradresse %1 beinhaltet ungültig Zeichen. Bitte überprüfen. + Error: The recipient address {0} contains invalid characters. Please check it. + Fehler: Die Empfängeradresse {0} beinhaltet ungültig Zeichen. Bitte überprüfen. - Error: The version of the recipient address %1 is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. - Fehler: Die Empfängerdresseversion von %1 ist zu hoch. Entweder Sie müssen Ihre Bitmessage Software aktualisieren oder Ihr Bekannter ist sehr clever. + Error: The version of the recipient address {0} is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. + Fehler: Die Empfängerdresseversion von {0} ist zu hoch. Entweder Sie müssen Ihre Bitmessage Software aktualisieren oder Ihr Bekannter ist sehr clever. - Error: Some data encoded in the recipient address %1 is too short. There might be something wrong with the software of your acquaintance. - Fehler: Einige Daten die in der Empfängerdresse %1 codiert sind, sind zu kurz. Es könnte sein, dass etwas mit der Software Ihres Bekannten nicht stimmt. + Error: Some data encoded in the recipient address {0} is too short. There might be something wrong with the software of your acquaintance. + Fehler: Einige Daten die in der Empfängerdresse {0} codiert sind, sind zu kurz. Es könnte sein, dass etwas mit der Software Ihres Bekannten nicht stimmt. - Error: Some data encoded in the recipient address %1 is too long. There might be something wrong with the software of your acquaintance. - Fehler: Einige Daten die in der Empfängeradresse %1 codiert sind, sind zu lang. Es könnte sein, dass etwas mit der Software Ihres Bekannten nicht stimmt. + Error: Some data encoded in the recipient address {0} is too long. There might be something wrong with the software of your acquaintance. + Fehler: Einige Daten die in der Empfängeradresse {0} codiert sind, sind zu lang. Es könnte sein, dass etwas mit der Software Ihres Bekannten nicht stimmt. - Error: Some data encoded in the recipient address %1 is malformed. There might be something wrong with the software of your acquaintance. - Fehler: Einige codierte Daten in der Empfängeradresse %1 sind ungültig. Es könnte etwas mit der Software Ihres Bekannten sein. + Error: Some data encoded in the recipient address {0} is malformed. There might be something wrong with the software of your acquaintance. + Fehler: Einige codierte Daten in der Empfängeradresse {0} sind ungültig. Es könnte etwas mit der Software Ihres Bekannten sein. - Error: Something is wrong with the recipient address %1. - Fehler: Mit der Empfängeradresse %1 stimmt etwas nicht. + Error: Something is wrong with the recipient address {0}. + Fehler: Mit der Empfängeradresse {0} stimmt etwas nicht. - Error: %1 - Fehler: %1 + Error: {0} + Fehler: {0} - From %1 - Von %1 + From {0} + Von {0} @@ -1572,7 +1572,7 @@ Willkommen zu einfachem und sicherem Bitmessage Display the %n recent broadcast(s) from this address. - Den letzten %1 Rundruf von dieser Addresse anzeigen.Die letzten %1 Rundrufe von dieser Addresse anzeigen. + Den letzten {0} Rundruf von dieser Addresse anzeigen.Die letzten {0} Rundrufe von dieser Addresse anzeigen. @@ -1619,8 +1619,8 @@ Willkommen zu einfachem und sicherem Bitmessage - The link "%1" will open in a browser. It may be a security risk, it could de-anonymise you or download malicious data. Are you sure? - Der Link "%1" wird in Browser geöffnet. Es kann ein Sicherheitsrisiko darstellen, es könnte Sie de-anonymisieren oder schädliche Aktivitäten durchführen. Sind Sie sicher? + The link "{0}" will open in a browser. It may be a security risk, it could de-anonymise you or download malicious data. Are you sure? + Der Link "{0}" wird in Browser geöffnet. Es kann ein Sicherheitsrisiko darstellen, es könnte Sie de-anonymisieren oder schädliche Aktivitäten durchführen. Sind Sie sicher? @@ -1955,8 +1955,8 @@ Die Zufallszahlen-Option ist standardmässig gewählt, jedoch haben deterministi - You are using TCP port %1. (This can be changed in the settings). - Sie benutzen TCP-Port %1 (Dieser kann in den Einstellungen verändert werden). + You are using TCP port {0}. (This can be changed in the settings). + Sie benutzen TCP-Port {0} (Dieser kann in den Einstellungen verändert werden). @@ -2008,28 +2008,28 @@ Die Zufallszahlen-Option ist standardmässig gewählt, jedoch haben deterministi - Since startup on %1 - Seit Start der Anwendung am %1 + Since startup on {0} + Seit Start der Anwendung am {0} - Down: %1/s Total: %2 - Herunter: %1/s Insg.: %2 + Down: {0}/s Total: {1} + Herunter: {0}/s Insg.: {1} - Up: %1/s Total: %2 - Hoch: %1/s Insg.: %2 + Up: {0}/s Total: {1} + Hoch: {0}/s Insg.: {1} - Total Connections: %1 - Verbindungen insgesamt: %1 + Total Connections: {0} + Verbindungen insgesamt: {0} - Inventory lookups per second: %1 - Inventory lookups pro Sekunde: %1 + Inventory lookups per second: {0} + Inventory lookups pro Sekunde: {0} @@ -2194,8 +2194,8 @@ Die Zufallszahlen-Option ist standardmässig gewählt, jedoch haben deterministi newchandialog - Successfully created / joined chan %1 - Chan %1 erfolgreich erstellt/beigetreten + Successfully created / joined chan {0} + Chan {0} erfolgreich erstellt/beigetreten diff --git a/src/translations/bitmessage_en.qm b/src/translations/bitmessage_en.qm index 4751f4ca1a79835180d272a4b023afb6b34b38c9..71a25005981bf7a657344b246fa16f1201b279fa 100644 GIT binary patch delta 5926 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 diff --git a/src/translations/bitmessage_en.ts b/src/translations/bitmessage_en.ts index 05e9cc4b..8525b52c 100644 --- a/src/translations/bitmessage_en.ts +++ b/src/translations/bitmessage_en.ts @@ -281,8 +281,8 @@ Please type the desired email address (including @mailchuck.com) below: - One of your addresses, %1, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? - One of your addresses, %1, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? + One of your addresses, {0}, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? + One of your addresses, {0}, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? @@ -301,13 +301,13 @@ Please type the desired email address (including @mailchuck.com) below: - Message sent. Waiting for acknowledgement. Sent at %1 - Message sent. Waiting for acknowledgement. Sent at %1 + Message sent. Waiting for acknowledgement. Sent at {0} + Message sent. Waiting for acknowledgement. Sent at {0} - Message sent. Sent at %1 - Message sent. Sent at %1 + Message sent. Sent at {0} + Message sent. Sent at {0} @@ -316,8 +316,8 @@ Please type the desired email address (including @mailchuck.com) below: - Acknowledgement of the message received %1 - Acknowledgement of the message received %1 + Acknowledgement of the message received {0} + Acknowledgement of the message received {0} @@ -326,18 +326,18 @@ Please type the desired email address (including @mailchuck.com) below: - Broadcast on %1 - Broadcast on %1 + Broadcast on {0} + Broadcast on {0} - Problem: The work demanded by the recipient is more difficult than you are willing to do. %1 - Problem: The work demanded by the recipient is more difficult than you are willing to do. %1 + Problem: The work demanded by the recipient is more difficult than you are willing to do. {0} + Problem: The work demanded by the recipient is more difficult than you are willing to do. {0} - Problem: The recipient's encryption key is no good. Could not encrypt message. %1 - Problem: The recipient's encryption key is no good. Could not encrypt message. %1 + Problem: The recipient's encryption key is no good. Could not encrypt message. {0} + Problem: The recipient's encryption key is no good. Could not encrypt message. {0} @@ -346,8 +346,8 @@ Please type the desired email address (including @mailchuck.com) below: - Unknown status: %1 %2 - Unknown status: %1 %2 + Unknown status: {0} {1} + Unknown status: {0} {1} @@ -387,10 +387,10 @@ Please type the desired email address (including @mailchuck.com) below: You may manage your keys by editing the keys.dat file stored in - %1 + {0} It is important that you back up this file. You may manage your keys by editing the keys.dat file stored in - %1 + {0} It is important that you back up this file. @@ -406,10 +406,10 @@ It is important that you back up this file. You may manage your keys by editing the keys.dat file stored in - %1 + {0} 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.) You may manage your keys by editing the keys.dat file stored in - %1 + {0} 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.) @@ -474,8 +474,8 @@ It is important that you back up this file. Would you like to open the file now? - Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: %1. This address also appears in 'Your Identities'. - Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: %1. This address also appears in 'Your Identities'. + Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: {0}. This address also appears in 'Your Identities'. + Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: {0}. This address also appears in 'Your Identities'. @@ -545,53 +545,53 @@ It is important that you back up this file. Would you like to open the file now? - The message that you are trying to send is too long by %1 bytes. (The maximum is 261644 bytes). Please cut it down before sending. - The message that you are trying to send is too long by %1 bytes. (The maximum is 261644 bytes). Please cut it down before sending. + The message that you are trying to send is too long by {0} bytes. (The maximum is 261644 bytes). Please cut it down before sending. + The message that you are trying to send is too long by {0} bytes. (The maximum is 261644 bytes). Please cut it down before sending. - Error: Your account wasn't registered at an email gateway. Sending registration now as %1, please wait for the registration to be processed before retrying sending. - Error: Your account wasn't registered at an email gateway. Sending registration now as %1, please wait for the registration to be processed before retrying sending. + Error: Your account wasn't registered at an email gateway. Sending registration now as {0}, please wait for the registration to be processed before retrying sending. + Error: Your account wasn't registered at an email gateway. Sending registration now as {0}, please wait for the registration to be processed before retrying sending. - Error: Bitmessage addresses start with BM- Please check %1 - Error: Bitmessage addresses start with BM- Please check %1 + Error: Bitmessage addresses start with BM- Please check {0} + Error: Bitmessage addresses start with BM- Please check {0} - Error: The address %1 is not typed or copied correctly. Please check it. - Error: The address %1 is not typed or copied correctly. Please check it. + Error: The address {0} is not typed or copied correctly. Please check it. + Error: The address {0} is not typed or copied correctly. Please check it. - Error: The address %1 contains invalid characters. Please check it. - Error: The address %1 contains invalid characters. Please check it. + Error: The address {0} contains invalid characters. Please check it. + Error: The address {0} contains invalid characters. Please check it. - Error: The address version in %1 is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. - Error: The address version in %1 is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. + Error: The address version in {0} is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. + Error: The address version in {0} is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. - Error: Some data encoded in the address %1 is too short. There might be something wrong with the software of your acquaintance. - Error: Some data encoded in the address %1 is too short. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is too short. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is too short. There might be something wrong with the software of your acquaintance. - Error: Some data encoded in the address %1 is too long. There might be something wrong with the software of your acquaintance. - Error: Some data encoded in the address %1 is too long. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is too long. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is too long. There might be something wrong with the software of your acquaintance. - Error: Some data encoded in the address %1 is malformed. There might be something wrong with the software of your acquaintance. - Error: Some data encoded in the address %1 is malformed. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is malformed. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is malformed. There might be something wrong with the software of your acquaintance. - Error: Something is wrong with the address %1. - Error: Something is wrong with the address %1. + Error: Something is wrong with the address {0}. + Error: Something is wrong with the address {0}. @@ -605,8 +605,8 @@ It is important that you back up this file. Would you like to open the file now? - Concerning the address %1, Bitmessage cannot understand address version numbers of %2. Perhaps upgrade Bitmessage to the latest version. - Concerning the address %1, Bitmessage cannot understand address version numbers of %2. Perhaps upgrade Bitmessage to the latest version. + Concerning the address {0}, Bitmessage cannot understand address version numbers of {1}. Perhaps upgrade Bitmessage to the latest version. + Concerning the address {0}, Bitmessage cannot understand address version numbers of {1}. Perhaps upgrade Bitmessage to the latest version. @@ -615,8 +615,8 @@ It is important that you back up this file. Would you like to open the file now? - Concerning the address %1, Bitmessage cannot handle stream numbers of %2. Perhaps upgrade Bitmessage to the latest version. - Concerning the address %1, Bitmessage cannot handle stream numbers of %2. Perhaps upgrade Bitmessage to the latest version. + Concerning the address {0}, Bitmessage cannot handle stream numbers of {1}. Perhaps upgrade Bitmessage to the latest version. + Concerning the address {0}, Bitmessage cannot handle stream numbers of {1}. Perhaps upgrade Bitmessage to the latest version. @@ -750,8 +750,8 @@ It is important that you back up this file. Would you like to open the file now? - Bitmessage cannot find your address %1. Perhaps you removed it? - Bitmessage cannot find your address %1. Perhaps you removed it? + Bitmessage cannot find your address {0}. Perhaps you removed it? + Bitmessage cannot find your address {0}. Perhaps you removed it? @@ -908,8 +908,8 @@ Are you sure you want to delete the channel? - You are using TCP port %1. (This can be changed in the settings). - You are using TCP port %1. (This can be changed in the settings). + You are using TCP port {0}. (This can be changed in the settings). + You are using TCP port {0}. (This can be changed in the settings). @@ -1103,8 +1103,8 @@ Are you sure you want to delete the channel? - Zoom level %1% - Zoom level %1% + Zoom level {0}% + Zoom level {0}% @@ -1118,48 +1118,48 @@ Are you sure you want to delete the channel? - Display the %1 recent broadcast(s) from this address. - Display the %1 recent broadcast(s) from this address. + Display the {0} recent broadcast(s) from this address. + Display the {0} recent broadcast(s) from this address. - New version of PyBitmessage is available: %1. Download it from https://github.com/Bitmessage/PyBitmessage/releases/latest - New version of PyBitmessage is available: %1. Download it from https://github.com/Bitmessage/PyBitmessage/releases/latest + New version of PyBitmessage is available: {0}. Download it from https://github.com/Bitmessage/PyBitmessage/releases/latest + New version of PyBitmessage is available: {0}. Download it from https://github.com/Bitmessage/PyBitmessage/releases/latest - Waiting for PoW to finish... %1% - Waiting for PoW to finish... %1% + Waiting for PoW to finish... {0}% + Waiting for PoW to finish... {0}% - Shutting down Pybitmessage... %1% - Shutting down Pybitmessage... %1% + Shutting down Pybitmessage... {0}% + Shutting down Pybitmessage... {0}% - Waiting for objects to be sent... %1% - Waiting for objects to be sent... %1% + Waiting for objects to be sent... {0}% + Waiting for objects to be sent... {0}% - Saving settings... %1% - Saving settings... %1% + Saving settings... {0}% + Saving settings... {0}% - Shutting down core... %1% - Shutting down core... %1% + Shutting down core... {0}% + Shutting down core... {0}% - Stopping notifications... %1% - Stopping notifications... %1% + Stopping notifications... {0}% + Stopping notifications... {0}% - Shutdown imminent... %1% - Shutdown imminent... %1% + Shutdown imminent... {0}% + Shutdown imminent... {0}% @@ -1179,8 +1179,8 @@ Are you sure you want to delete the channel? - Shutting down PyBitmessage... %1% - Shutting down PyBitmessage... %1% + Shutting down PyBitmessage... {0}% + Shutting down PyBitmessage... {0}% @@ -1199,13 +1199,13 @@ Are you sure you want to delete the channel? - Generating %1 new addresses. - Generating %1 new addresses. + Generating {0} new addresses. + Generating {0} new addresses. - %1 is already in 'Your Identities'. Not adding it again. - %1 is already in 'Your Identities'. Not adding it again. + {0} is already in 'Your Identities'. Not adding it again. + {0} is already in 'Your Identities'. Not adding it again. @@ -1214,8 +1214,8 @@ Are you sure you want to delete the channel? - SOCKS5 Authentication problem: %1 - SOCKS5 Authentication problem: %1 + SOCKS5 Authentication problem: {0} + SOCKS5 Authentication problem: {0} @@ -1239,8 +1239,8 @@ Are you sure you want to delete the channel? - Broadcast sent on %1 - Broadcast sent on %1 + Broadcast sent on {0} + Broadcast sent on {0} @@ -1259,8 +1259,8 @@ Are you sure you want to delete the channel? - Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. %1 - Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. %1 + Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. {0} + Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. {0} @@ -1272,19 +1272,19 @@ There is no required difficulty for version 2 addresses like this. Doing work necessary to send message. -Receiver's required difficulty: %1 and %2 +Receiver's required difficulty: {0} and {1} Doing work necessary to send message. -Receiver's required difficulty: %1 and %2 +Receiver's required difficulty: {0} and {1} - Problem: The work demanded by the recipient (%1 and %2) is more difficult than you are willing to do. %3 - Problem: The work demanded by the recipient (%1 and %2) is more difficult than you are willing to do. %3 + Problem: The work demanded by the recipient ({0} and {1}) is more difficult than you are willing to do. {2} + Problem: The work demanded by the recipient ({0} and {1}) is more difficult than you are willing to do. {2} - Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. %1 - Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. %1 + Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. {0} + Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. {0} @@ -1293,8 +1293,8 @@ Receiver's required difficulty: %1 and %2 - Message sent. Waiting for acknowledgement. Sent on %1 - Message sent. Waiting for acknowledgement. Sent on %1 + Message sent. Waiting for acknowledgement. Sent on {0} + Message sent. Waiting for acknowledgement. Sent on {0} @@ -1308,13 +1308,13 @@ Receiver's required difficulty: %1 and %2 - Sending public key request. Waiting for reply. Requested at %1 - Sending public key request. Waiting for reply. Requested at %1 + Sending public key request. Waiting for reply. Requested at {0} + Sending public key request. Waiting for reply. Requested at {0} - UPnP port mapping established on port %1 - UPnP port mapping established on port %1 + UPnP port mapping established on port {0} + UPnP port mapping established on port {0} @@ -1703,28 +1703,28 @@ The 'Random Number' option is selected by default but deterministic ad - Since startup on %1 - Since startup on %1 + Since startup on {0} + Since startup on {0} - Down: %1/s Total: %2 - Down: %1/s Total: %2 + Down: {0}/s Total: {1} + Down: {0}/s Total: {1} - Up: %1/s Total: %2 - Up: %1/s Total: %2 + Up: {0}/s Total: {1} + Up: {0}/s Total: {1} - Total Connections: %1 - Total Connections: %1 + Total Connections: {0} + Total Connections: {0} - Inventory lookups per second: %1 - Inventory lookups per second: %1 + Inventory lookups per second: {0} + Inventory lookups per second: {0} diff --git a/src/translations/bitmessage_en_pirate.qm b/src/translations/bitmessage_en_pirate.qm index 69e6bde80093b2b1fb33eac0eba92e595a373db1..753e7e1aa6f9eb30367c1489a9e77030178e29fc 100644 GIT binary patch delta 17 YcmccF!FaEQaYMKhdj|sp0}~@706Q)Oq5uE@ delta 445 zcmccD!g#ZTaYMLMy*>j2<2Q!s47dOzh6EQ}L;%hLF~q<;ITSI1oO%Xr9BNE(h=YWk zk>vc~>aQh=x^wHPKUATKwWS6bXqC^I=f&pju5^4fxQchxWc1~t- X372nTW?pz^UP^vBLkG}(OpJ^G^OP~O diff --git a/src/translations/bitmessage_en_pirate.ts b/src/translations/bitmessage_en_pirate.ts index 69642a96..48f60e6c 100644 --- a/src/translations/bitmessage_en_pirate.ts +++ b/src/translations/bitmessage_en_pirate.ts @@ -241,7 +241,7 @@ Please type the desired email address (including @mailchuck.com) below: - One of your addresses, %1, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? + One of your addresses, {0}, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? @@ -261,12 +261,12 @@ Please type the desired email address (including @mailchuck.com) below: - Message sent. Waiting for acknowledgement. Sent at %1 + Message sent. Waiting for acknowledgement. Sent at {0} - Message sent. Sent at %1 + Message sent. Sent at {0} @@ -276,7 +276,7 @@ Please type the desired email address (including @mailchuck.com) below: - Acknowledgement of the message received %1 + Acknowledgement of the message received {0} @@ -286,17 +286,17 @@ Please type the desired email address (including @mailchuck.com) below: - Broadcast on %1 + Broadcast on {0} - Problem: The work demanded by the recipient is more difficult than you are willing to do. %1 + Problem: The work demanded by the recipient is more difficult than you are willing to do. {0} - Problem: The recipient's encryption key is no good. Could not encrypt message. %1 + Problem: The recipient's encryption key is no good. Could not encrypt message. {0} @@ -306,7 +306,7 @@ Please type the desired email address (including @mailchuck.com) below: - Unknown status: %1 %2 + Unknown status: {0} {1} @@ -347,7 +347,7 @@ Please type the desired email address (including @mailchuck.com) below: You may manage your keys by editing the keys.dat file stored in - %1 + {0} It is important that you back up this file. @@ -364,7 +364,7 @@ It is important that you back up this file. You may manage your keys by editing the keys.dat file stored in - %1 + {0} 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.) @@ -430,7 +430,7 @@ It is important that you back up this file. Would you like to open the file now? - Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: %1. This address also appears in 'Your Identities'. + Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: {0}. This address also appears in 'Your Identities'. @@ -498,52 +498,52 @@ It is important that you back up this file. Would you like to open the file now? - The message that you are trying to send is too long by %1 bytes. (The maximum is 261644 bytes). Please cut it down before sending. + The message that you are trying to send is too long by {0} bytes. (The maximum is 261644 bytes). Please cut it down before sending. - Error: Your account wasn't registered at an email gateway. Sending registration now as %1, please wait for the registration to be processed before retrying sending. + Error: Your account wasn't registered at an email gateway. Sending registration now as {0}, please wait for the registration to be processed before retrying sending. - Error: Bitmessage addresses start with BM- Please check %1 + Error: Bitmessage addresses start with BM- Please check {0} - Error: The address %1 is not typed or copied correctly. Please check it. + Error: The address {0} is not typed or copied correctly. Please check it. - Error: The address %1 contains invalid characters. Please check it. + Error: The address {0} contains invalid characters. Please check it. - Error: The address version in %1 is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. + Error: The address version in {0} is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. - Error: Some data encoded in the address %1 is too short. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is too short. There might be something wrong with the software of your acquaintance. - Error: Some data encoded in the address %1 is too long. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is too long. There might be something wrong with the software of your acquaintance. - Error: Some data encoded in the address %1 is malformed. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is malformed. There might be something wrong with the software of your acquaintance. - Error: Something is wrong with the address %1. + Error: Something is wrong with the address {0}. @@ -558,7 +558,7 @@ It is important that you back up this file. Would you like to open the file now? - Concerning the address %1, Bitmessage cannot understand address version numbers of %2. Perhaps upgrade Bitmessage to the latest version. + Concerning the address {0}, Bitmessage cannot understand address version numbers of {1}. Perhaps upgrade Bitmessage to the latest version. @@ -568,7 +568,7 @@ It is important that you back up this file. Would you like to open the file now? - Concerning the address %1, Bitmessage cannot handle stream numbers of %2. Perhaps upgrade Bitmessage to the latest version. + Concerning the address {0}, Bitmessage cannot handle stream numbers of {1}. Perhaps upgrade Bitmessage to the latest version. @@ -703,7 +703,7 @@ It is important that you back up this file. Would you like to open the file now? - Bitmessage cannot find your address %1. Perhaps you removed it? + Bitmessage cannot find your address {0}. Perhaps you removed it? @@ -857,7 +857,7 @@ Are you sure you want to delete the channel? - You are using TCP port %1. (This can be changed in the settings). + You are using TCP port {0}. (This can be changed in the settings). @@ -1052,7 +1052,7 @@ Are you sure you want to delete the channel? - Zoom level %1% + Zoom level {0}% @@ -1067,47 +1067,47 @@ Are you sure you want to delete the channel? - Display the %1 recent broadcast(s) from this address. + Display the {0} recent broadcast(s) from this address. - New version of PyBitmessage is available: %1. Download it from https://github.com/Bitmessage/PyBitmessage/releases/latest + New version of PyBitmessage is available: {0}. Download it from https://github.com/Bitmessage/PyBitmessage/releases/latest - Waiting for PoW to finish... %1% + Waiting for PoW to finish... {0}% - Shutting down Pybitmessage... %1% + Shutting down Pybitmessage... {0}% - Waiting for objects to be sent... %1% + Waiting for objects to be sent... {0}% - Saving settings... %1% + Saving settings... {0}% - Shutting down core... %1% + Shutting down core... {0}% - Stopping notifications... %1% + Stopping notifications... {0}% - Shutdown imminent... %1% + Shutdown imminent... {0}% @@ -1128,7 +1128,7 @@ Are you sure you want to delete the channel? - Shutting down PyBitmessage... %1% + Shutting down PyBitmessage... {0}% @@ -1148,12 +1148,12 @@ Are you sure you want to delete the channel? - Generating %1 new addresses. + Generating {0} new addresses. - %1 is already in 'Your Identities'. Not adding it again. + {0} is already in 'Your Identities'. Not adding it again. @@ -1163,7 +1163,7 @@ Are you sure you want to delete the channel? - SOCKS5 Authentication problem: %1 + SOCKS5 Authentication problem: {0} @@ -1188,7 +1188,7 @@ Are you sure you want to delete the channel? - Broadcast sent on %1 + Broadcast sent on {0} @@ -1208,7 +1208,7 @@ Are you sure you want to delete the channel? - Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. %1 + Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. {0} @@ -1220,17 +1220,17 @@ There is no required difficulty for version 2 addresses like this. Doing work necessary to send message. -Receiver's required difficulty: %1 and %2 +Receiver's required difficulty: {0} and {1} - Problem: The work demanded by the recipient (%1 and %2) is more difficult than you are willing to do. %3 + Problem: The work demanded by the recipient ({0} and {1}) is more difficult than you are willing to do. {2} - Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. %1 + Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. {0} @@ -1240,7 +1240,7 @@ Receiver's required difficulty: %1 and %2 - Message sent. Waiting for acknowledgement. Sent on %1 + Message sent. Waiting for acknowledgement. Sent on {0} @@ -1255,12 +1255,12 @@ Receiver's required difficulty: %1 and %2 - Sending public key request. Waiting for reply. Requested at %1 + Sending public key request. Waiting for reply. Requested at {0} - UPnP port mapping established on port %1 + UPnP port mapping established on port {0} @@ -1623,27 +1623,27 @@ T' 'Random Number' option be selected by default but deterministi - Since startup on %1 + Since startup on {0} - Down: %1/s Total: %2 + Down: {0}/s Total: {1} - Up: %1/s Total: %2 + Up: {0}/s Total: {1} - Total Connections: %1 + Total Connections: {0} - Inventory lookups per second: %1 + Inventory lookups per second: {0} diff --git a/src/translations/bitmessage_eo.qm b/src/translations/bitmessage_eo.qm index 77c20edfbc100594577d3e66405b12d4c0e33e21..76fac0960defd52d61cd0e5895ffd01e9e7096f2 100644 GIT binary patch delta 6327 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 delta 6230 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 diff --git a/src/translations/bitmessage_eo.ts b/src/translations/bitmessage_eo.ts index 5707a390..835de58d 100644 --- a/src/translations/bitmessage_eo.ts +++ b/src/translations/bitmessage_eo.ts @@ -350,8 +350,8 @@ Please type the desired email address (including @mailchuck.com) below: - One of your addresses, %1, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? - Iu de viaj adresoj, %1, estas malnova versio 1 adreso. Versioj 1 adresoj ne estas jam subtenataj. Ĉu ni povas forigi ĝin? + One of your addresses, {0}, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? + Iu de viaj adresoj, {0}, estas malnova versio 1 adreso. Versioj 1 adresoj ne estas jam subtenataj. Ĉu ni povas forigi ĝin? @@ -370,13 +370,13 @@ Please type the desired email address (including @mailchuck.com) below: - Message sent. Waiting for acknowledgement. Sent at %1 - Mesaĝo sendita. Atendado je konfirmo. Sendita je %1 + Message sent. Waiting for acknowledgement. Sent at {0} + Mesaĝo sendita. Atendado je konfirmo. Sendita je {0} - Message sent. Sent at %1 - Mesaĝo sendita. Sendita je %1 + Message sent. Sent at {0} + Mesaĝo sendita. Sendita je {0} @@ -385,8 +385,8 @@ Please type the desired email address (including @mailchuck.com) below: - Acknowledgement of the message received %1 - Ricevis konfirmon de la mesaĝo je %1 + Acknowledgement of the message received {0} + Ricevis konfirmon de la mesaĝo je {0} @@ -395,18 +395,18 @@ Please type the desired email address (including @mailchuck.com) below: - Broadcast on %1 - Elsendo je %1 + Broadcast on {0} + Elsendo je {0} - Problem: The work demanded by the recipient is more difficult than you are willing to do. %1 - Problemo: la demandita laboro de la ricevonto estas pli malfacila ol vi pretas fari. %1 + Problem: The work demanded by the recipient is more difficult than you are willing to do. {0} + Problemo: la demandita laboro de la ricevonto estas pli malfacila ol vi pretas fari. {0} - Problem: The recipient's encryption key is no good. Could not encrypt message. %1 - Problemo: la ĉifroŝlosilo de la ricevonto estas rompita. Ne povis ĉifri la mesaĝon. %1 + Problem: The recipient's encryption key is no good. Could not encrypt message. {0} + Problemo: la ĉifroŝlosilo de la ricevonto estas rompita. Ne povis ĉifri la mesaĝon. {0} @@ -415,8 +415,8 @@ Please type the desired email address (including @mailchuck.com) below: - Unknown status: %1 %2 - Nekonata stato: %1 %2 + Unknown status: {0} {1} + Nekonata stato: {0} {1} @@ -456,10 +456,10 @@ Please type the desired email address (including @mailchuck.com) below: You may manage your keys by editing the keys.dat file stored in - %1 + {0} It is important that you back up this file. Vi povas administri viajn ŝlosilojn per redakti la dosieron “keys.dat” en la dosierujo -%1. +{0}. Estas grava, ke vi faru sekurkopion de tiu dosiero. @@ -475,10 +475,10 @@ Estas grava, ke vi faru sekurkopion de tiu dosiero. You may manage your keys by editing the keys.dat file stored in - %1 + {0} 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.) Vi povas administri viajn ŝlosilojn per redakti la dosieron “keys.dat” en la dosierujo -%1. +{0}. Estas grava, ke vi faru sekurkopion de tiu dosiero. Ĉu vi volas malfermi la dosieron nun? (Bonvolu certigi ke Bitmesaĝo estas fermita antaŭ fari ŝanĝojn.) @@ -543,7 +543,7 @@ Estas grava, ke vi faru sekurkopion de tiu dosiero. Ĉu vi volas malfermi la dos - Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: %1. This address also appears in 'Your Identities'. + Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: {0}. This address also appears in 'Your Identities'. @@ -611,52 +611,52 @@ Estas grava, ke vi faru sekurkopion de tiu dosiero. Ĉu vi volas malfermi la dos - The message that you are trying to send is too long by %1 bytes. (The maximum is 261644 bytes). Please cut it down before sending. - La mesaĝon kiun vi provis sendi estas tro longa je %1 bitokoj. (La maksimumo estas 261644 bitokoj.) Bonvolu mallongigi ĝin antaŭ sendado. + The message that you are trying to send is too long by {0} bytes. (The maximum is 261644 bytes). Please cut it down before sending. + La mesaĝon kiun vi provis sendi estas tro longa je {0} bitokoj. (La maksimumo estas 261644 bitokoj.) Bonvolu mallongigi ĝin antaŭ sendado. - Error: Your account wasn't registered at an email gateway. Sending registration now as %1, please wait for the registration to be processed before retrying sending. - Eraro: via konto ne estas registrita je retpoŝta kluzo. Registranta nun kiel %1, bonvolu atendi ĝis la registrado finos antaŭ vi reprovos sendi iun ajn. + Error: Your account wasn't registered at an email gateway. Sending registration now as {0}, please wait for the registration to be processed before retrying sending. + Eraro: via konto ne estas registrita je retpoŝta kluzo. Registranta nun kiel {0}, bonvolu atendi ĝis la registrado finos antaŭ vi reprovos sendi iun ajn. - Error: Bitmessage addresses start with BM- Please check %1 + Error: Bitmessage addresses start with BM- Please check {0} - Error: The address %1 is not typed or copied correctly. Please check it. + Error: The address {0} is not typed or copied correctly. Please check it. - Error: The address %1 contains invalid characters. Please check it. + Error: The address {0} contains invalid characters. Please check it. - Error: The address version in %1 is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. + Error: The address version in {0} is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. - Error: Some data encoded in the address %1 is too short. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is too short. There might be something wrong with the software of your acquaintance. - Error: Some data encoded in the address %1 is too long. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is too long. There might be something wrong with the software of your acquaintance. - Error: Some data encoded in the address %1 is malformed. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is malformed. There might be something wrong with the software of your acquaintance. - Error: Something is wrong with the address %1. + Error: Something is wrong with the address {0}. @@ -671,8 +671,8 @@ Estas grava, ke vi faru sekurkopion de tiu dosiero. Ĉu vi volas malfermi la dos - Concerning the address %1, Bitmessage cannot understand address version numbers of %2. Perhaps upgrade Bitmessage to the latest version. - Dum prilaborado de adreso adreso %1, Bitmesaĝo ne povas kompreni numerojn %2 de adresversioj. Eble ĝisdatigu Bitmesaĝon al la plej nova versio. + Concerning the address {0}, Bitmessage cannot understand address version numbers of {1}. Perhaps upgrade Bitmessage to the latest version. + Dum prilaborado de adreso adreso {0}, Bitmesaĝo ne povas kompreni numerojn {1} de adresversioj. Eble ĝisdatigu Bitmesaĝon al la plej nova versio. @@ -681,8 +681,8 @@ Estas grava, ke vi faru sekurkopion de tiu dosiero. Ĉu vi volas malfermi la dos - Concerning the address %1, Bitmessage cannot handle stream numbers of %2. Perhaps upgrade Bitmessage to the latest version. - Dum prilaborado de adreso %1, Bitmesaĝo ne povas priservi %2 fluojn numerojn. Eble ĝisdatigu Bitmesaĝon al la plej nova versio. + Concerning the address {0}, Bitmessage cannot handle stream numbers of {1}. Perhaps upgrade Bitmessage to the latest version. + Dum prilaborado de adreso {0}, Bitmesaĝo ne povas priservi {1} fluojn numerojn. Eble ĝisdatigu Bitmesaĝon al la plej nova versio. @@ -816,8 +816,8 @@ Estas grava, ke vi faru sekurkopion de tiu dosiero. Ĉu vi volas malfermi la dos - Bitmessage cannot find your address %1. Perhaps you removed it? - Bitmesaĝo ne povas trovi vian adreson %1. Ĉu eble vi forviŝis ĝin? + Bitmessage cannot find your address {0}. Perhaps you removed it? + Bitmesaĝo ne povas trovi vian adreson {0}. Ĉu eble vi forviŝis ĝin? @@ -974,7 +974,7 @@ Are you sure you want to delete the channel? - You are using TCP port %1. (This can be changed in the settings). + You are using TCP port {0}. (This can be changed in the settings). @@ -1169,8 +1169,8 @@ Are you sure you want to delete the channel? - Zoom level %1% - Pligrandigo: %1 + Zoom level {0}% + Pligrandigo: {0} @@ -1184,48 +1184,48 @@ Are you sure you want to delete the channel? - Display the %1 recent broadcast(s) from this address. + Display the {0} recent broadcast(s) from this address. - New version of PyBitmessage is available: %1. Download it from https://github.com/Bitmessage/PyBitmessage/releases/latest - La nova versio de PyBitmessage estas disponebla: %1. Elŝutu ĝin de https://github.com/Bitmessage/PyBitmessage/releases/latest + New version of PyBitmessage is available: {0}. Download it from https://github.com/Bitmessage/PyBitmessage/releases/latest + La nova versio de PyBitmessage estas disponebla: {0}. Elŝutu ĝin de https://github.com/Bitmessage/PyBitmessage/releases/latest - Waiting for PoW to finish... %1% - Atendado ĝis laborpruvo finiĝos… %1% + Waiting for PoW to finish... {0}% + Atendado ĝis laborpruvo finiĝos… {0}% - Shutting down Pybitmessage... %1% - Fermado de PyBitmessage… %1% + Shutting down Pybitmessage... {0}% + Fermado de PyBitmessage… {0}% - Waiting for objects to be sent... %1% - Atendado ĝis objektoj estos senditaj… %1% + Waiting for objects to be sent... {0}% + Atendado ĝis objektoj estos senditaj… {0}% - Saving settings... %1% - Konservado de agordoj… %1% + Saving settings... {0}% + Konservado de agordoj… {0}% - Shutting down core... %1% - Fermado de kerno… %1% + Shutting down core... {0}% + Fermado de kerno… {0}% - Stopping notifications... %1% - Haltigado de sciigoj… %1% + Stopping notifications... {0}% + Haltigado de sciigoj… {0}% - Shutdown imminent... %1% - Fermado tuj… %1% + Shutdown imminent... {0}% + Fermado tuj… {0}% @@ -1239,8 +1239,8 @@ Are you sure you want to delete the channel? - Shutting down PyBitmessage... %1% - Fermado de PyBitmessage… %1% + Shutting down PyBitmessage... {0}% + Fermado de PyBitmessage… {0}% @@ -1259,13 +1259,13 @@ Are you sure you want to delete the channel? - Generating %1 new addresses. - Kreado de %1 novaj adresoj. + Generating {0} new addresses. + Kreado de {0} novaj adresoj. - %1 is already in 'Your Identities'. Not adding it again. - %1 jam estas en ‘Viaj Identigoj’. Ĝi ne estos aldonita ree. + {0} is already in 'Your Identities'. Not adding it again. + {0} jam estas en ‘Viaj Identigoj’. Ĝi ne estos aldonita ree. @@ -1274,7 +1274,7 @@ Are you sure you want to delete the channel? - SOCKS5 Authentication problem: %1 + SOCKS5 Authentication problem: {0} @@ -1299,8 +1299,8 @@ Are you sure you want to delete the channel? - Broadcast sent on %1 - Elsendo sendita je %1 + Broadcast sent on {0} + Elsendo sendita je {0} @@ -1319,8 +1319,8 @@ Are you sure you want to delete the channel? - Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. %1 - Eraro: celadreso estas portebla aparato kiu necesas, ke la celadreso estu enhavita en la mesaĝo, sed tio estas malpermesita ne viaj agordoj. %1 + Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. {0} + Eraro: celadreso estas portebla aparato kiu necesas, ke la celadreso estu enhavita en la mesaĝo, sed tio estas malpermesita ne viaj agordoj. {0} @@ -1332,19 +1332,19 @@ Malfacilaĵo ne estas bezonata por adresoj versioj 2, kiel tiu ĉi adreso. Doing work necessary to send message. -Receiver's required difficulty: %1 and %2 +Receiver's required difficulty: {0} and {1} Kalkulado de laborpruvo, kiu endas por sendi mesaĝon. -Ricevonto postulas malfacilaĵon: %1 kaj %2 +Ricevonto postulas malfacilaĵon: {0} kaj {1} - Problem: The work demanded by the recipient (%1 and %2) is more difficult than you are willing to do. %3 - Eraro: la demandita laboro de la ricevonto (%1 kaj %2) estas pli malfacila ol vi pretas fari. %3 + Problem: The work demanded by the recipient ({0} and {1}) is more difficult than you are willing to do. {2} + Eraro: la demandita laboro de la ricevonto ({0} kaj {1}) estas pli malfacila ol vi pretas fari. {2} - Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. %1 - Eraro: Vi provis sendi mesaĝon al vi mem aŭ al kanalo, tamen via ĉifroŝlosilo ne estas trovebla en la dosiero keys.dat. Mesaĝo ne povis esti ĉifrita. %1 + Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. {0} + Eraro: Vi provis sendi mesaĝon al vi mem aŭ al kanalo, tamen via ĉifroŝlosilo ne estas trovebla en la dosiero keys.dat. Mesaĝo ne povis esti ĉifrita. {0} @@ -1353,8 +1353,8 @@ Ricevonto postulas malfacilaĵon: %1 kaj %2 - Message sent. Waiting for acknowledgement. Sent on %1 - Mesaĝo sendita. Atendado je konfirmo. Sendita je %1 + Message sent. Waiting for acknowledgement. Sent on {0} + Mesaĝo sendita. Atendado je konfirmo. Sendita je {0} @@ -1368,13 +1368,13 @@ Ricevonto postulas malfacilaĵon: %1 kaj %2 - Sending public key request. Waiting for reply. Requested at %1 - Sendado de peto pri publika ĉifroŝlosilo. Atendado je respondo. Petis je %1 + Sending public key request. Waiting for reply. Requested at {0} + Sendado de peto pri publika ĉifroŝlosilo. Atendado je respondo. Petis je {0} - UPnP port mapping established on port %1 - UPnP pord-mapigo farita je pordo %1 + UPnP port mapping established on port {0} + UPnP pord-mapigo farita je pordo {0} @@ -1418,18 +1418,18 @@ Ricevonto postulas malfacilaĵon: %1 kaj %2 - The name %1 was not found. - La nomo %1 ne trovita. + The name {0} was not found. + La nomo {0} ne trovita. - The namecoin query failed (%1) - La namecoin-peto fiaskis (%1) + The namecoin query failed ({0}) + La namecoin-peto fiaskis ({0}) - Unknown namecoin interface type: %1 - Nekonata tipo de namecoin-fasado: %1 + Unknown namecoin interface type: {0} + Nekonata tipo de namecoin-fasado: {0} @@ -1438,13 +1438,13 @@ Ricevonto postulas malfacilaĵon: %1 kaj %2 - The name %1 has no associated Bitmessage address. - La nomo %1 ne estas atribuita kun bitmesaĝa adreso. + The name {0} has no associated Bitmessage address. + La nomo {0} ne estas atribuita kun bitmesaĝa adreso. - Success! Namecoind version %1 running. - Sukceso! Namecoind versio %1 funkcias. + Success! Namecoind version {0} running. + Sukceso! Namecoind versio {0} funkcias. @@ -1507,53 +1507,53 @@ Bonvenon al facila kaj sekura Bitmesaĝo - Error: Bitmessage addresses start with BM- Please check the recipient address %1 - Eraro: bitmesaĝaj adresoj komenciĝas kun BM-. Bonvolu kontroli la adreson de ricevonto %1 + Error: Bitmessage addresses start with BM- Please check the recipient address {0} + Eraro: bitmesaĝaj adresoj komenciĝas kun BM-. Bonvolu kontroli la adreson de ricevonto {0} - Error: The recipient address %1 is not typed or copied correctly. Please check it. - Eraro: la adreso de ricevonto %1 estas malprave tajpita aŭ kopiita. Bonvolu kontroli ĝin. + Error: The recipient address {0} is not typed or copied correctly. Please check it. + Eraro: la adreso de ricevonto {0} estas malprave tajpita aŭ kopiita. Bonvolu kontroli ĝin. - Error: The recipient address %1 contains invalid characters. Please check it. - Eraro: la adreso de ricevonto %1 enhavas malpermesatajn simbolojn. Bonvolu kontroli ĝin. + Error: The recipient address {0} contains invalid characters. Please check it. + Eraro: la adreso de ricevonto {0} enhavas malpermesatajn simbolojn. Bonvolu kontroli ĝin. - Error: The version of the recipient address %1 is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. - Eraro: la versio de adreso de ricevonto %1 estas tro alta. Eble vi devas ĝisdatigi vian bitmesaĝan programon aŭ via sagaca konato uzas alian programon. + Error: The version of the recipient address {0} is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. + Eraro: la versio de adreso de ricevonto {0} estas tro alta. Eble vi devas ĝisdatigi vian bitmesaĝan programon aŭ via sagaca konato uzas alian programon. - Error: Some data encoded in the recipient address %1 is too short. There might be something wrong with the software of your acquaintance. - Eraro: kelkaj datumoj koditaj en la adreso de ricevonto %1 estas tro mallongaj. Povus esti ke io en la programo de via konato malfunkcias. + Error: Some data encoded in the recipient address {0} is too short. There might be something wrong with the software of your acquaintance. + Eraro: kelkaj datumoj koditaj en la adreso de ricevonto {0} estas tro mallongaj. Povus esti ke io en la programo de via konato malfunkcias. - Error: Some data encoded in the recipient address %1 is too long. There might be something wrong with the software of your acquaintance. - Eraro: kelkaj datumoj koditaj en la adreso de ricevonto %1 estas tro longaj. Povus esti ke io en la programo de via konato malfunkcias. + Error: Some data encoded in the recipient address {0} is too long. There might be something wrong with the software of your acquaintance. + Eraro: kelkaj datumoj koditaj en la adreso de ricevonto {0} estas tro longaj. Povus esti ke io en la programo de via konato malfunkcias. - Error: Some data encoded in the recipient address %1 is malformed. There might be something wrong with the software of your acquaintance. - Eraro: kelkaj datumoj koditaj en la adreso de ricevonto %1 estas misformitaj. Povus esti ke io en la programo de via konato malfunkcias. + Error: Some data encoded in the recipient address {0} is malformed. There might be something wrong with the software of your acquaintance. + Eraro: kelkaj datumoj koditaj en la adreso de ricevonto {0} estas misformitaj. Povus esti ke io en la programo de via konato malfunkcias. - Error: Something is wrong with the recipient address %1. - Eraro: io malĝustas kun la adreso de ricevonto %1. + Error: Something is wrong with the recipient address {0}. + Eraro: io malĝustas kun la adreso de ricevonto {0}. - Error: %1 - Eraro: %1 + Error: {0} + Eraro: {0} - From %1 - De %1 + From {0} + De {0} @@ -1665,8 +1665,8 @@ Bonvenon al facila kaj sekura Bitmesaĝo - The link "%1" will open in a browser. It may be a security risk, it could de-anonymise you or download malicious data. Are you sure? - La ligilo "%1" estos malfermita per foliumilo. Tio povas esti malsekura, ĝi povos malanonimigi vin aŭ elŝuti malicajn datumojn. Ĉu vi certas? + The link "{0}" will open in a browser. It may be a security risk, it could de-anonymise you or download malicious data. Are you sure? + La ligilo "{0}" estos malfermita per foliumilo. Tio povas esti malsekura, ĝi povos malanonimigi vin aŭ elŝuti malicajn datumojn. Ĉu vi certas? @@ -2001,8 +2001,8 @@ La “hazardnombra” adreso estas antaŭagordita, sed antaŭkalkuleblaj adresoj - You are using TCP port %1. (This can be changed in the settings). - Vi uzas TCP-pordon %1 (tio ĉi estas ŝanĝebla en la agordoj). + You are using TCP port {0}. (This can be changed in the settings). + Vi uzas TCP-pordon {0} (tio ĉi estas ŝanĝebla en la agordoj). @@ -2054,28 +2054,28 @@ La “hazardnombra” adreso estas antaŭagordita, sed antaŭkalkuleblaj adresoj - Since startup on %1 - Ekde lanĉo de la programo je %1 + Since startup on {0} + Ekde lanĉo de la programo je {0} - Down: %1/s Total: %2 - Elŝuto: %1/s Sume: %2 + Down: {0}/s Total: {1} + Elŝuto: {0}/s Sume: {1} - Up: %1/s Total: %2 - Alŝuto: %1/s Sume: %2 + Up: {0}/s Total: {1} + Alŝuto: {0}/s Sume: {1} - Total Connections: %1 - Ĉiuj konektoj: %1 + Total Connections: {0} + Ĉiuj konektoj: {0} - Inventory lookups per second: %1 - Petoj pri inventaro en sekundo: %1 + Inventory lookups per second: {0} + Petoj pri inventaro en sekundo: {0} @@ -2240,8 +2240,8 @@ La “hazardnombra” adreso estas antaŭagordita, sed antaŭkalkuleblaj adresoj newchandialog - Successfully created / joined chan %1 - Sukcese kreis / anigis al la kanalo %1 + Successfully created / joined chan {0} + Sukcese kreis / anigis al la kanalo {0} diff --git a/src/translations/bitmessage_fr.qm b/src/translations/bitmessage_fr.qm index 8cb08a3ad728c12b465349fc4b3be1cb1c2a9230..d54bf1649533cafe0ae660f2a3a35bfb1c7d5ff5 100644 GIT binary patch delta 6280 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 diff --git a/src/translations/bitmessage_fr.ts b/src/translations/bitmessage_fr.ts index 149fd1ef..44fa0248 100644 --- a/src/translations/bitmessage_fr.ts +++ b/src/translations/bitmessage_fr.ts @@ -314,8 +314,8 @@ Please type the desired email address (including @mailchuck.com) below: - One of your addresses, %1, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? - Une de vos adresses, %1, est une vieille adresse de la version 1. Les adresses de la version 1 ne sont plus supportées. Nous pourrions la supprimer maintenant? + One of your addresses, {0}, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? + Une de vos adresses, {0}, est une vieille adresse de la version 1. Les adresses de la version 1 ne sont plus supportées. Nous pourrions la supprimer maintenant? @@ -334,13 +334,13 @@ Please type the desired email address (including @mailchuck.com) below: - Message sent. Waiting for acknowledgement. Sent at %1 - Message envoyé. En attente de l’accusé de réception. Envoyé %1 + Message sent. Waiting for acknowledgement. Sent at {0} + Message envoyé. En attente de l’accusé de réception. Envoyé {0} - Message sent. Sent at %1 - Message envoyé. Envoyé %1 + Message sent. Sent at {0} + Message envoyé. Envoyé {0} @@ -349,8 +349,8 @@ Please type the desired email address (including @mailchuck.com) below: - Acknowledgement of the message received %1 - Accusé de réception reçu %1 + Acknowledgement of the message received {0} + Accusé de réception reçu {0} @@ -359,18 +359,18 @@ Please type the desired email address (including @mailchuck.com) below: - Broadcast on %1 - Message de diffusion du %1 + Broadcast on {0} + Message de diffusion du {0} - Problem: The work demanded by the recipient is more difficult than you are willing to do. %1 - Problème : Le travail demandé par le destinataire est plus difficile que ce que vous avez paramétré. %1 + Problem: The work demanded by the recipient is more difficult than you are willing to do. {0} + Problème : Le travail demandé par le destinataire est plus difficile que ce que vous avez paramétré. {0} - Problem: The recipient's encryption key is no good. Could not encrypt message. %1 - Problème : la clé de chiffrement du destinataire n’est pas bonne. Il n’a pas été possible de chiffrer le message. %1 + Problem: The recipient's encryption key is no good. Could not encrypt message. {0} + Problème : la clé de chiffrement du destinataire n’est pas bonne. Il n’a pas été possible de chiffrer le message. {0} @@ -379,8 +379,8 @@ Please type the desired email address (including @mailchuck.com) below: - Unknown status: %1 %2 - Statut inconnu : %1 %2 + Unknown status: {0} {1} + Statut inconnu : {0} {1} @@ -420,9 +420,9 @@ Please type the desired email address (including @mailchuck.com) below: You may manage your keys by editing the keys.dat file stored in - %1 + {0} It is important that you back up this file. - Vous pouvez éditer vos clés en éditant le fichier keys.dat stocké dans le répertoire %1. + Vous pouvez éditer vos clés en éditant le fichier keys.dat stocké dans le répertoire {0}. Il est important de faire des sauvegardes de ce fichier. @@ -438,9 +438,9 @@ Il est important de faire des sauvegardes de ce fichier. You may manage your keys by editing the keys.dat file stored in - %1 + {0} 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.) - Vous pouvez éditer vos clés en éditant le fichier keys.dat stocké dans le répertoire %1. Il est important de faire des sauvegardes de ce fichier. Souhaitez-vous l’ouvrir maintenant? (Assurez-vous de fermer Bitmessage avant d’effectuer des changements.) + Vous pouvez éditer vos clés en éditant le fichier keys.dat stocké dans le répertoire {0}. Il est important de faire des sauvegardes de ce fichier. Souhaitez-vous l’ouvrir maintenant? (Assurez-vous de fermer Bitmessage avant d’effectuer des changements.) @@ -504,7 +504,7 @@ It is important that you back up this file. Would you like to open the file now? - Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: %1. This address also appears in 'Your Identities'. + Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: {0}. This address also appears in 'Your Identities'. @@ -573,52 +573,52 @@ Le destinataire doit l’obtenir avant ce temps. Si votre client Bitmessage ne r - The message that you are trying to send is too long by %1 bytes. (The maximum is 261644 bytes). Please cut it down before sending. - Le message que vous essayez d’envoyer est trop long de %1 octets (le maximum est 261644 octets). Veuillez le réduire avant de l’envoyer. + The message that you are trying to send is too long by {0} bytes. (The maximum is 261644 bytes). Please cut it down before sending. + Le message que vous essayez d’envoyer est trop long de {0} octets (le maximum est 261644 octets). Veuillez le réduire avant de l’envoyer. - Error: Your account wasn't registered at an email gateway. Sending registration now as %1, please wait for the registration to be processed before retrying sending. - Erreur : votre compte n’a pas été inscrit à une passerelle de courrier électronique. Envoi de l’inscription maintenant en tant que %1, veuillez patienter tandis que l’inscription est en cours de traitement, avant de retenter l’envoi. + Error: Your account wasn't registered at an email gateway. Sending registration now as {0}, please wait for the registration to be processed before retrying sending. + Erreur : votre compte n’a pas été inscrit à une passerelle de courrier électronique. Envoi de l’inscription maintenant en tant que {0}, veuillez patienter tandis que l’inscription est en cours de traitement, avant de retenter l’envoi. - Error: Bitmessage addresses start with BM- Please check %1 + Error: Bitmessage addresses start with BM- Please check {0} - Error: The address %1 is not typed or copied correctly. Please check it. + Error: The address {0} is not typed or copied correctly. Please check it. - Error: The address %1 contains invalid characters. Please check it. + Error: The address {0} contains invalid characters. Please check it. - Error: The address version in %1 is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. + Error: The address version in {0} is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. - Error: Some data encoded in the address %1 is too short. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is too short. There might be something wrong with the software of your acquaintance. - Error: Some data encoded in the address %1 is too long. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is too long. There might be something wrong with the software of your acquaintance. - Error: Some data encoded in the address %1 is malformed. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is malformed. There might be something wrong with the software of your acquaintance. - Error: Something is wrong with the address %1. + Error: Something is wrong with the address {0}. @@ -633,8 +633,8 @@ Le destinataire doit l’obtenir avant ce temps. Si votre client Bitmessage ne r - Concerning the address %1, Bitmessage cannot understand address version numbers of %2. Perhaps upgrade Bitmessage to the latest version. - Concernant l’adresse %1, Bitmessage ne peut pas comprendre les numéros de version de %2. Essayez de mettre à jour Bitmessage vers la dernière version. + Concerning the address {0}, Bitmessage cannot understand address version numbers of {1}. Perhaps upgrade Bitmessage to the latest version. + Concernant l’adresse {0}, Bitmessage ne peut pas comprendre les numéros de version de {1}. Essayez de mettre à jour Bitmessage vers la dernière version. @@ -643,8 +643,8 @@ Le destinataire doit l’obtenir avant ce temps. Si votre client Bitmessage ne r - Concerning the address %1, Bitmessage cannot handle stream numbers of %2. Perhaps upgrade Bitmessage to the latest version. - Concernant l’adresse %1, Bitmessage ne peut pas supporter les nombres de flux de %2. Essayez de mettre à jour Bitmessage vers la dernière version. + Concerning the address {0}, Bitmessage cannot handle stream numbers of {1}. Perhaps upgrade Bitmessage to the latest version. + Concernant l’adresse {0}, Bitmessage ne peut pas supporter les nombres de flux de {1}. Essayez de mettre à jour Bitmessage vers la dernière version. @@ -778,8 +778,8 @@ Le destinataire doit l’obtenir avant ce temps. Si votre client Bitmessage ne r - Bitmessage cannot find your address %1. Perhaps you removed it? - Bitmessage ne peut pas trouver votre adresse %1. Peut-être l’avez-vous supprimée? + Bitmessage cannot find your address {0}. Perhaps you removed it? + Bitmessage ne peut pas trouver votre adresse {0}. Peut-être l’avez-vous supprimée? @@ -936,7 +936,7 @@ Are you sure you want to delete the channel? - You are using TCP port %1. (This can be changed in the settings). + You are using TCP port {0}. (This can be changed in the settings). @@ -1131,8 +1131,8 @@ Are you sure you want to delete the channel? - Zoom level %1% - Niveau de zoom %1% + Zoom level {0}% + Niveau de zoom {0}% @@ -1146,48 +1146,48 @@ Are you sure you want to delete the channel? - Display the %1 recent broadcast(s) from this address. + Display the {0} recent broadcast(s) from this address. - New version of PyBitmessage is available: %1. Download it from https://github.com/Bitmessage/PyBitmessage/releases/latest - Une nouvelle version de PyBitmessage est disponible : %1. Veuillez la télécharger depuis https://github.com/Bitmessage/PyBitmessage/releases/latest + New version of PyBitmessage is available: {0}. Download it from https://github.com/Bitmessage/PyBitmessage/releases/latest + Une nouvelle version de PyBitmessage est disponible : {0}. Veuillez la télécharger depuis https://github.com/Bitmessage/PyBitmessage/releases/latest - Waiting for PoW to finish... %1% - En attente de la fin de la PoW… %1% + Waiting for PoW to finish... {0}% + En attente de la fin de la PoW… {0}% - Shutting down Pybitmessage... %1% - Pybitmessage en cours d’arrêt… %1% + Shutting down Pybitmessage... {0}% + Pybitmessage en cours d’arrêt… {0}% - Waiting for objects to be sent... %1% - En attente de l’envoi des objets… %1% + Waiting for objects to be sent... {0}% + En attente de l’envoi des objets… {0}% - Saving settings... %1% - Enregistrement des paramètres… %1% + Saving settings... {0}% + Enregistrement des paramètres… {0}% - Shutting down core... %1% - Cœur en cours d’arrêt… %1% + Shutting down core... {0}% + Cœur en cours d’arrêt… {0}% - Stopping notifications... %1% - Arrêt des notifications… %1% + Stopping notifications... {0}% + Arrêt des notifications… {0}% - Shutdown imminent... %1% - Arrêt imminent… %1% + Shutdown imminent... {0}% + Arrêt imminent… {0}% @@ -1201,8 +1201,8 @@ Are you sure you want to delete the channel? - Shutting down PyBitmessage... %1% - PyBitmessage en cours d’arrêt… %1% + Shutting down PyBitmessage... {0}% + PyBitmessage en cours d’arrêt… {0}% @@ -1221,13 +1221,13 @@ Are you sure you want to delete the channel? - Generating %1 new addresses. - Production de %1 nouvelles adresses. + Generating {0} new addresses. + Production de {0} nouvelles adresses. - %1 is already in 'Your Identities'. Not adding it again. - %1 est déjà dans "Vos identités". Il ne sera pas ajouté de nouveau. + {0} is already in 'Your Identities'. Not adding it again. + {0} est déjà dans "Vos identités". Il ne sera pas ajouté de nouveau. @@ -1236,7 +1236,7 @@ Are you sure you want to delete the channel? - SOCKS5 Authentication problem: %1 + SOCKS5 Authentication problem: {0} @@ -1261,8 +1261,8 @@ Are you sure you want to delete the channel? - Broadcast sent on %1 - Message de diffusion envoyé %1 + Broadcast sent on {0} + Message de diffusion envoyé {0} @@ -1281,8 +1281,8 @@ Are you sure you want to delete the channel? - Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. %1 - Problème : la destination est un dispositif mobile qui nécessite que la destination soit incluse dans le message mais ceci n’est pas autorisé dans vos paramètres. %1 + Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. {0} + Problème : la destination est un dispositif mobile qui nécessite que la destination soit incluse dans le message mais ceci n’est pas autorisé dans vos paramètres. {0} @@ -1294,19 +1294,19 @@ Il n’y a pas de difficulté requise pour les adresses version 2 comme celle-ci Doing work necessary to send message. -Receiver's required difficulty: %1 and %2 +Receiver's required difficulty: {0} and {1} Travail en cours afin d’envoyer le message. -Difficulté requise du destinataire : %1 et %2 +Difficulté requise du destinataire : {0} et {1} - Problem: The work demanded by the recipient (%1 and %2) is more difficult than you are willing to do. %3 - Problème : Le travail demandé par le destinataire (%1 and %2) est plus difficile que ce que vous avez paramétré. %3 + Problem: The work demanded by the recipient ({0} and {1}) is more difficult than you are willing to do. {2} + Problème : Le travail demandé par le destinataire ({0} and {1}) est plus difficile que ce que vous avez paramétré. {2} - Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. %1 - Problème : Vous essayez d’envoyer un message à un canal ou à vous-même mais votre clef de chiffrement n’a pas été trouvée dans le fichier keys.dat. Le message ne peut pas être chiffré. %1 + Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. {0} + Problème : Vous essayez d’envoyer un message à un canal ou à vous-même mais votre clef de chiffrement n’a pas été trouvée dans le fichier keys.dat. Le message ne peut pas être chiffré. {0} @@ -1315,8 +1315,8 @@ Difficulté requise du destinataire : %1 et %2 - Message sent. Waiting for acknowledgement. Sent on %1 - Message envoyé. En attente de l’accusé de réception. Envoyé %1 + Message sent. Waiting for acknowledgement. Sent on {0} + Message envoyé. En attente de l’accusé de réception. Envoyé {0} @@ -1330,13 +1330,13 @@ Difficulté requise du destinataire : %1 et %2 - Sending public key request. Waiting for reply. Requested at %1 - Envoi d’une demande de clef publique. En attente d’une réponse. Demandée à %1 + Sending public key request. Waiting for reply. Requested at {0} + Envoi d’une demande de clef publique. En attente d’une réponse. Demandée à {0} - UPnP port mapping established on port %1 - Transfert de port UPnP établi sur le port %1 + UPnP port mapping established on port {0} + Transfert de port UPnP établi sur le port {0} @@ -1380,13 +1380,13 @@ Difficulté requise du destinataire : %1 et %2 - The name %1 was not found. - Le nom %1 n'a pas été trouvé. + The name {0} was not found. + Le nom {0} n'a pas été trouvé. - The namecoin query failed (%1) - La requête Namecoin a échouée (%1) + The namecoin query failed ({0}) + La requête Namecoin a échouée ({0}) @@ -1395,18 +1395,18 @@ Difficulté requise du destinataire : %1 et %2 - The name %1 has no valid JSON data. - Le nom %1 n'a aucune donnée JSON valide. + The name {0} has no valid JSON data. + Le nom {0} n'a aucune donnée JSON valide. - The name %1 has no associated Bitmessage address. - Le nom %1 n'a aucune adresse Bitmessage d'associée. + The name {0} has no associated Bitmessage address. + Le nom {0} n'a aucune adresse Bitmessage d'associée. - Success! Namecoind version %1 running. - Succès ! Namecoind version %1 en cours d'exécution. + Success! Namecoind version {0} running. + Succès ! Namecoind version {0} en cours d'exécution. @@ -1470,53 +1470,53 @@ Bienvenue dans le facile et sécurisé Bitmessage - Error: Bitmessage addresses start with BM- Please check the recipient address %1 - Erreur : Les adresses Bitmessage commencent par BM- Veuillez vérifier l'adresse du destinataire %1 + Error: Bitmessage addresses start with BM- Please check the recipient address {0} + Erreur : Les adresses Bitmessage commencent par BM- Veuillez vérifier l'adresse du destinataire {0} - Error: The recipient address %1 is not typed or copied correctly. Please check it. - Erreur : L’adresse du destinataire %1 n’est pas correctement tapée ou recopiée. Veuillez la vérifier. + Error: The recipient address {0} is not typed or copied correctly. Please check it. + Erreur : L’adresse du destinataire {0} n’est pas correctement tapée ou recopiée. Veuillez la vérifier. - Error: The recipient address %1 contains invalid characters. Please check it. - Erreur : L’adresse du destinataire %1 contient des caractères invalides. Veuillez la vérifier. + Error: The recipient address {0} contains invalid characters. Please check it. + Erreur : L’adresse du destinataire {0} contient des caractères invalides. Veuillez la vérifier. - Error: The version of the recipient address %1 is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. - Erreur : la version de l’adresse destinataire %1 est trop élevée. Vous devez mettre à niveau votre logiciel Bitmessage ou alors celui de votre connaissance est plus intelligent. + Error: The version of the recipient address {0} is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. + Erreur : la version de l’adresse destinataire {0} est trop élevée. Vous devez mettre à niveau votre logiciel Bitmessage ou alors celui de votre connaissance est plus intelligent. - Error: Some data encoded in the recipient address %1 is too short. There might be something wrong with the software of your acquaintance. - Erreur : quelques données codées dans l’adresse destinataire %1 sont trop courtes. Il pourrait y avoir un soucis avec le logiciel de votre connaissance. + Error: Some data encoded in the recipient address {0} is too short. There might be something wrong with the software of your acquaintance. + Erreur : quelques données codées dans l’adresse destinataire {0} sont trop courtes. Il pourrait y avoir un soucis avec le logiciel de votre connaissance. - Error: Some data encoded in the recipient address %1 is too long. There might be something wrong with the software of your acquaintance. - Erreur : quelques données codées dans l’adresse destinataire %1 sont trop longues. Il pourrait y avoir un soucis avec le logiciel de votre connaissance. + Error: Some data encoded in the recipient address {0} is too long. There might be something wrong with the software of your acquaintance. + Erreur : quelques données codées dans l’adresse destinataire {0} sont trop longues. Il pourrait y avoir un soucis avec le logiciel de votre connaissance. - Error: Some data encoded in the recipient address %1 is malformed. There might be something wrong with the software of your acquaintance. - Erreur : quelques données codées dans l’adresse destinataire %1 sont mal formées. Il pourrait y avoir un soucis avec le logiciel de votre connaissance. + Error: Some data encoded in the recipient address {0} is malformed. There might be something wrong with the software of your acquaintance. + Erreur : quelques données codées dans l’adresse destinataire {0} sont mal formées. Il pourrait y avoir un soucis avec le logiciel de votre connaissance. - Error: Something is wrong with the recipient address %1. - Erreur : quelque chose ne va pas avec l'adresse de destinataire %1. + Error: Something is wrong with the recipient address {0}. + Erreur : quelque chose ne va pas avec l'adresse de destinataire {0}. - Error: %1 - Erreur : %1 + Error: {0} + Erreur : {0} - From %1 - De %1 + From {0} + De {0} @@ -1628,8 +1628,8 @@ Bienvenue dans le facile et sécurisé Bitmessage - The link "%1" will open in a browser. It may be a security risk, it could de-anonymise you or download malicious data. Are you sure? - Le lien "%1" s'ouvrira dans un navigateur. Cela pourrait être un risque de sécurité, cela pourrait vous désanonymiser ou télécharger des données malveillantes. Êtes-vous sûr(e) ? + The link "{0}" will open in a browser. It may be a security risk, it could de-anonymise you or download malicious data. Are you sure? + Le lien "{0}" s'ouvrira dans un navigateur. Cela pourrait être un risque de sécurité, cela pourrait vous désanonymiser ou télécharger des données malveillantes. Êtes-vous sûr(e) ? @@ -1964,8 +1964,8 @@ L’option "Nombre Aléatoire" est sélectionnée par défaut mais les - You are using TCP port %1. (This can be changed in the settings). - Vous utilisez le port TCP %1. (Ceci peut être changé dans les paramètres). + You are using TCP port {0}. (This can be changed in the settings). + Vous utilisez le port TCP {0}. (Ceci peut être changé dans les paramètres). @@ -2017,28 +2017,28 @@ L’option "Nombre Aléatoire" est sélectionnée par défaut mais les - Since startup on %1 - Démarré depuis le %1 + Since startup on {0} + Démarré depuis le {0} - Down: %1/s Total: %2 - Téléchargées : %1/s Total : %2 + Down: {0}/s Total: {1} + Téléchargées : {0}/s Total : {1} - Up: %1/s Total: %2 - Téléversées : %1/s Total : %2 + Up: {0}/s Total: {1} + Téléversées : {0}/s Total : {1} - Total Connections: %1 - Total des connexions : %1 + Total Connections: {0} + Total des connexions : {0} - Inventory lookups per second: %1 - Consultations d’inventaire par seconde : %1 + Inventory lookups per second: {0} + Consultations d’inventaire par seconde : {0} @@ -2203,8 +2203,8 @@ L’option "Nombre Aléatoire" est sélectionnée par défaut mais les newchandialog - Successfully created / joined chan %1 - Le canal %1 a été rejoint ou créé avec succès. + Successfully created / joined chan {0} + Le canal {0} a été rejoint ou créé avec succès. diff --git a/src/translations/bitmessage_it.qm b/src/translations/bitmessage_it.qm index d38e68bcbefa8b2931e7cd8aa7d982c5c33a8a48..8b2e991529957789d98dd66a9869c2332225a637 100644 GIT binary patch delta 1198 zcmY*XdrVVz6#j1SqmNstAfm!d%d|i{Xesh4PvvQ{ftxU$Zs8H=1m@a=V#Xs_5;NCq z1R)pE2;q@18OX!Q1`&+gBH1R}I?T+>7M94EI41&&Y%vV79ptb5aqqdm-#zC$-}$~X z*U9v@F-?KS6dAxZ1Ho4Tei(@Q8p!(!FwO(78|nNAC`|_r6f|dOT}9vB{AiOfU~5w-YB(Tvu$MRwxh zW55t6>n!{Y(7I)p9E29UTh@F37SXMc-L1O`q?gJbw{9m|iLAPTCzLN)U3)SRbDxcI zoC5Y)*^c~oY3!ryxO$TEjqKEUIvc=xzRhTz;WWD%fyAwxrr>?RmHL!R8cPRK z&75u6MEZ?$@2sZ*v2mO`rUwYi<1U|NXxuB@fPsLbeYk{7Xn0tdZp>X4a zfZ5F$yS5pv$K=z8^8q1B{vc%zF6-RHhP=12q`UF{EI;WWWh$J`9DE;Ph z$@oHLVDDd)*C>UvAwk8;_EFla|Qu%w{8W}RLQn{>j-zc4AwJwXww(t^> z{6IC7yh`@nR9zESXy_Hy=N_s~a*N7p8cJU-2Cv+p-V0*WXFrpgM)BegoZm-@B3w`k40)h#IjcA~A$oq&+nhG| zytl`^6R8&fO)YV4RNgtd2Mv6_#GR9lVvsn0Nb&}gM8(4eLZqqs5 z)Kxo9R_KaKN-7A#<_y~?8aW;LkA^Wxu2h5m|Bd|f9F;{UbZHK|-Bw&#=CC{CpLOxs RzkOsjbyOvH6B`-B{0A6jN8tbf delta 1618 zcmaJ=4@{J082^2D-*@occgN8M9_i|i;vn$&bEv=}g7Qal1tk!aChj;c?%=#L?qjDo zIMcadQouenCq%kYrh=51Ofa*w*=*rl4p*zCV_F$1O=_k#d+>nS)Sm6W=g<2-zvuTn z&wG2?nUVLI)>(0xe*b|vXnyjWciEE-4AnxgP7sNeva8#5R6IkjYUb$fXL3VFCXn*8JjK%pEKHJjmT#iwO63EplXO2) z>S1*LVOI0xJ3xk-)vSCA$iB`l=+7k`&DwhtXe6JozJGFn)MU0Pr3)}EW%su*)WOGW zcdQ+lC$Qb756HjB_HHZ#GEcC59bptNXTKPYB^)1na;*_Cj&Z4DJE&ucvz(^UrZ;iv z4(cR*PCNJfg>%$;1XtepDUck+ZCp>li%s0l8(tu*hih-5#H2&qp_eHk<`-_DiijnP zQiDuq=~8t4c!oBct>_P;th9Q?xqUSGJd@(5Qo5CMJV@J08!^2Xl&Tz}Hfw_lz9*fe zl)jbe_`iboH;(|866vZ;XC4oJ_1IRxFhBU{APp{|CHVA5G^oU3KJ0QaEoB)$YtNsA zy@`+h<_{n?O^TPtM6TdF4%6;4XY;!Kt) zYLKCEnlApSBmJwkqUhHQii9=qHz!rRBrVA(Jjh*pmdTW^$Imw!VGgFh z3>5T>D6o6I)+)QfYj=wYhGO~}tfIkamYBq_zSk4RWQ;7-?O8QFyMa7@Dh(`bs2IzZnxbgIz4W0`UK$JEM4D~?88cbBDJv)?^5*% zp{IMFOc2xD=LgJ)>Bv*l)`USVlbG&(ANHYbKPY}Ic`*3MNYUg8?P6LgrY+Y!>y2rD z%2+pLJVevu|37*2(T8fcUG#ZsYrLXWtn-rR%W+uUxlXIgQx#fh_bsZdtfh4Z0uZbf zo;oq$C>?g!>dCk!#A_Etr@LzMqI4#AmUL9m`w>b2|Ha@7tWKBBQD>_OC;Z~N3a_o! zxq4!!0Whu8=5gn{JoJWY*G}T|6)vl-#^v;i+Pqbio^KWHKI_z}k`UcxPIslp2Q?*6 PJdr?RP!n}7W0-#d - One of your addresses, %1, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? - Uno dei tuoi indirizzi, %1, è un indirizzo vecchio versione 1. Gli indirizzi versione 1 non sono più supportati. Posso eliminarlo ora? + One of your addresses, {0}, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? + Uno dei tuoi indirizzi, {0}, è un indirizzo vecchio versione 1. Gli indirizzi versione 1 non sono più supportati. Posso eliminarlo ora? @@ -299,13 +299,13 @@ Il gateway email non condurrà operazioni PGP a vostro nome. È possibile - Message sent. Waiting for acknowledgement. Sent at %1 + Message sent. Waiting for acknowledgement. Sent at {0} - Message sent. Sent at %1 - Messaggio inviato. Inviato a %1 + Message sent. Sent at {0} + Messaggio inviato. Inviato a {0} @@ -314,7 +314,7 @@ Il gateway email non condurrà operazioni PGP a vostro nome. È possibile - Acknowledgement of the message received %1 + Acknowledgement of the message received {0} @@ -324,17 +324,17 @@ Il gateway email non condurrà operazioni PGP a vostro nome. È possibile - Broadcast on %1 + Broadcast on {0} - Problem: The work demanded by the recipient is more difficult than you are willing to do. %1 + Problem: The work demanded by the recipient is more difficult than you are willing to do. {0} - Problem: The recipient's encryption key is no good. Could not encrypt message. %1 + Problem: The recipient's encryption key is no good. Could not encrypt message. {0} @@ -344,7 +344,7 @@ Il gateway email non condurrà operazioni PGP a vostro nome. È possibile - Unknown status: %1 %2 + Unknown status: {0} {1} @@ -385,7 +385,7 @@ Il gateway email non condurrà operazioni PGP a vostro nome. È possibile You may manage your keys by editing the keys.dat file stored in - %1 + {0} It is important that you back up this file. @@ -402,7 +402,7 @@ It is important that you back up this file. You may manage your keys by editing the keys.dat file stored in - %1 + {0} 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.) @@ -468,7 +468,7 @@ It is important that you back up this file. Would you like to open the file now? - Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: %1. This address also appears in 'Your Identities'. + Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: {0}. This address also appears in 'Your Identities'. @@ -536,52 +536,52 @@ It is important that you back up this file. Would you like to open the file now? - The message that you are trying to send is too long by %1 bytes. (The maximum is 261644 bytes). Please cut it down before sending. + The message that you are trying to send is too long by {0} bytes. (The maximum is 261644 bytes). Please cut it down before sending. - Error: Your account wasn't registered at an email gateway. Sending registration now as %1, please wait for the registration to be processed before retrying sending. + Error: Your account wasn't registered at an email gateway. Sending registration now as {0}, please wait for the registration to be processed before retrying sending. - Error: Bitmessage addresses start with BM- Please check %1 + Error: Bitmessage addresses start with BM- Please check {0} - Error: The address %1 is not typed or copied correctly. Please check it. + Error: The address {0} is not typed or copied correctly. Please check it. - Error: The address %1 contains invalid characters. Please check it. + Error: The address {0} contains invalid characters. Please check it. - Error: The address version in %1 is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. + Error: The address version in {0} is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. - Error: Some data encoded in the address %1 is too short. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is too short. There might be something wrong with the software of your acquaintance. - Error: Some data encoded in the address %1 is too long. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is too long. There might be something wrong with the software of your acquaintance. - Error: Some data encoded in the address %1 is malformed. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is malformed. There might be something wrong with the software of your acquaintance. - Error: Something is wrong with the address %1. + Error: Something is wrong with the address {0}. @@ -596,7 +596,7 @@ It is important that you back up this file. Would you like to open the file now? - Concerning the address %1, Bitmessage cannot understand address version numbers of %2. Perhaps upgrade Bitmessage to the latest version. + Concerning the address {0}, Bitmessage cannot understand address version numbers of {1}. Perhaps upgrade Bitmessage to the latest version. @@ -606,7 +606,7 @@ It is important that you back up this file. Would you like to open the file now? - Concerning the address %1, Bitmessage cannot handle stream numbers of %2. Perhaps upgrade Bitmessage to the latest version. + Concerning the address {0}, Bitmessage cannot handle stream numbers of {1}. Perhaps upgrade Bitmessage to the latest version. @@ -741,7 +741,7 @@ It is important that you back up this file. Would you like to open the file now? - Bitmessage cannot find your address %1. Perhaps you removed it? + Bitmessage cannot find your address {0}. Perhaps you removed it? @@ -895,7 +895,7 @@ Are you sure you want to delete the channel? - You are using TCP port %1. (This can be changed in the settings). + You are using TCP port {0}. (This can be changed in the settings). @@ -1090,7 +1090,7 @@ Are you sure you want to delete the channel? - Zoom level %1% + Zoom level {0}% @@ -1105,47 +1105,47 @@ Are you sure you want to delete the channel? - Display the %1 recent broadcast(s) from this address. + Display the {0} recent broadcast(s) from this address. - New version of PyBitmessage is available: %1. Download it from https://github.com/Bitmessage/PyBitmessage/releases/latest + New version of PyBitmessage is available: {0}. Download it from https://github.com/Bitmessage/PyBitmessage/releases/latest - Waiting for PoW to finish... %1% + Waiting for PoW to finish... {0}% - Shutting down Pybitmessage... %1% + Shutting down Pybitmessage... {0}% - Waiting for objects to be sent... %1% + Waiting for objects to be sent... {0}% - Saving settings... %1% + Saving settings... {0}% - Shutting down core... %1% + Shutting down core... {0}% - Stopping notifications... %1% + Stopping notifications... {0}% - Shutdown imminent... %1% + Shutdown imminent... {0}% @@ -1166,7 +1166,7 @@ Are you sure you want to delete the channel? - Shutting down PyBitmessage... %1% + Shutting down PyBitmessage... {0}% @@ -1186,12 +1186,12 @@ Are you sure you want to delete the channel? - Generating %1 new addresses. + Generating {0} new addresses. - %1 is already in 'Your Identities'. Not adding it again. + {0} is already in 'Your Identities'. Not adding it again. @@ -1201,7 +1201,7 @@ Are you sure you want to delete the channel? - SOCKS5 Authentication problem: %1 + SOCKS5 Authentication problem: {0} @@ -1226,7 +1226,7 @@ Are you sure you want to delete the channel? - Broadcast sent on %1 + Broadcast sent on {0} @@ -1246,7 +1246,7 @@ Are you sure you want to delete the channel? - Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. %1 + Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. {0} @@ -1258,17 +1258,17 @@ There is no required difficulty for version 2 addresses like this. Doing work necessary to send message. -Receiver's required difficulty: %1 and %2 +Receiver's required difficulty: {0} and {1} - Problem: The work demanded by the recipient (%1 and %2) is more difficult than you are willing to do. %3 + Problem: The work demanded by the recipient ({0} and {1}) is more difficult than you are willing to do. {2} - Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. %1 + Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. {0} @@ -1278,7 +1278,7 @@ Receiver's required difficulty: %1 and %2 - Message sent. Waiting for acknowledgement. Sent on %1 + Message sent. Waiting for acknowledgement. Sent on {0} @@ -1293,12 +1293,12 @@ Receiver's required difficulty: %1 and %2 - Sending public key request. Waiting for reply. Requested at %1 + Sending public key request. Waiting for reply. Requested at {0} - UPnP port mapping established on port %1 + UPnP port mapping established on port {0} @@ -1660,27 +1660,27 @@ The 'Random Number' option is selected by default but deterministic ad - Since startup on %1 + Since startup on {0} - Down: %1/s Total: %2 + Down: {0}/s Total: {1} - Up: %1/s Total: %2 + Up: {0}/s Total: {1} - Total Connections: %1 - Connessioni totali: %1 + Total Connections: {0} + Connessioni totali: {0} - Inventory lookups per second: %1 + Inventory lookups per second: {0} diff --git a/src/translations/bitmessage_ja.qm b/src/translations/bitmessage_ja.qm index 77fa63d1a56a57cc9ccf7027e4239bd296202a80..8637aa2e127307a220983e1c4b545ed2d0b9f72b 100644 GIT binary patch delta 6170 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 diff --git a/src/translations/bitmessage_ja.ts b/src/translations/bitmessage_ja.ts index f11289f5..2b1ebe97 100644 --- a/src/translations/bitmessage_ja.ts +++ b/src/translations/bitmessage_ja.ts @@ -352,8 +352,8 @@ Please type the desired email address (including @mailchuck.com) below: - One of your addresses, %1, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? - %1は古いバージョン1のアドレスです。バージョン1のアドレスはサポートが終了しています。すぐに削除しますか? + One of your addresses, {0}, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? + {0}は古いバージョン1のアドレスです。バージョン1のアドレスはサポートが終了しています。すぐに削除しますか? @@ -372,13 +372,13 @@ Please type the desired email address (including @mailchuck.com) below: - Message sent. Waiting for acknowledgement. Sent at %1 - メッセージを送信しました。 確認応答を待っています。 %1 で送信されました + Message sent. Waiting for acknowledgement. Sent at {0} + メッセージを送信しました。 確認応答を待っています。 {0} で送信されました - Message sent. Sent at %1 - メッセージは送信されました。送信先: %1 + Message sent. Sent at {0} + メッセージは送信されました。送信先: {0} @@ -387,8 +387,8 @@ Please type the desired email address (including @mailchuck.com) below: - Acknowledgement of the message received %1 - メッセージの確認を受け取りました %1 + Acknowledgement of the message received {0} + メッセージの確認を受け取りました {0} @@ -397,18 +397,18 @@ Please type the desired email address (including @mailchuck.com) below: - Broadcast on %1 - 配信: %1 + Broadcast on {0} + 配信: {0} - Problem: The work demanded by the recipient is more difficult than you are willing to do. %1 - 問題: 受信者が要求している処理は現在あなたが設定しているよりも高い難易度です。 %1 + Problem: The work demanded by the recipient is more difficult than you are willing to do. {0} + 問題: 受信者が要求している処理は現在あなたが設定しているよりも高い難易度です。 {0} - Problem: The recipient's encryption key is no good. Could not encrypt message. %1 - 問題: 受信者の暗号鍵は正当でない物です。メッセージを暗号化できません。 %1 + Problem: The recipient's encryption key is no good. Could not encrypt message. {0} + 問題: 受信者の暗号鍵は正当でない物です。メッセージを暗号化できません。 {0} @@ -417,8 +417,8 @@ Please type the desired email address (including @mailchuck.com) below: - Unknown status: %1 %2 - 不明なステータス: %1 %2 + Unknown status: {0} {1} + 不明なステータス: {0} {1} @@ -458,9 +458,9 @@ Please type the desired email address (including @mailchuck.com) below: You may manage your keys by editing the keys.dat file stored in - %1 + {0} It is important that you back up this file. - %1 + {0} に保存されているkeys.datファイルを編集することで鍵を管理できます。 このファイルをバックアップしておくことは重要です。 @@ -477,9 +477,9 @@ It is important that you back up this file. You may manage your keys by editing the keys.dat file stored in - %1 + {0} 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.) - %1 + {0} に保存されているkeys.datファイルを編集することで鍵を管理できます。 ファイルをバックアップしておくことは重要です。すぐにファイルを開きますか?(必ず編集する前にBitmessageを終了してください) @@ -545,7 +545,7 @@ It is important that you back up this file. Would you like to open the file now? - Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: %1. This address also appears in 'Your Identities'. + Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: {0}. This address also appears in 'Your Identities'. @@ -616,52 +616,52 @@ It is important that you back up this file. Would you like to open the file now? - The message that you are trying to send is too long by %1 bytes. (The maximum is 261644 bytes). Please cut it down before sending. - 送信しようとしているメッセージが %1 バイト長すぎます。 (最大は261644バイトです)。 送信する前に短くしてください。 + The message that you are trying to send is too long by {0} bytes. (The maximum is 261644 bytes). Please cut it down before sending. + 送信しようとしているメッセージが {0} バイト長すぎます。 (最大は261644バイトです)。 送信する前に短くしてください。 - Error: Your account wasn't registered at an email gateway. Sending registration now as %1, please wait for the registration to be processed before retrying sending. - エラー: アカウントがメールゲートウェイに登録されていません。 今 %1 として登録を送信しています。送信を再試行する前に、登録が処理されるのをお待ちください。 + Error: Your account wasn't registered at an email gateway. Sending registration now as {0}, please wait for the registration to be processed before retrying sending. + エラー: アカウントがメールゲートウェイに登録されていません。 今 {0} として登録を送信しています。送信を再試行する前に、登録が処理されるのをお待ちください。 - Error: Bitmessage addresses start with BM- Please check %1 + Error: Bitmessage addresses start with BM- Please check {0} - Error: The address %1 is not typed or copied correctly. Please check it. + Error: The address {0} is not typed or copied correctly. Please check it. - Error: The address %1 contains invalid characters. Please check it. + Error: The address {0} contains invalid characters. Please check it. - Error: The address version in %1 is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. + Error: The address version in {0} is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. - Error: Some data encoded in the address %1 is too short. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is too short. There might be something wrong with the software of your acquaintance. - Error: Some data encoded in the address %1 is too long. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is too long. There might be something wrong with the software of your acquaintance. - Error: Some data encoded in the address %1 is malformed. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is malformed. There might be something wrong with the software of your acquaintance. - Error: Something is wrong with the address %1. + Error: Something is wrong with the address {0}. @@ -676,8 +676,8 @@ It is important that you back up this file. Would you like to open the file now? - Concerning the address %1, Bitmessage cannot understand address version numbers of %2. Perhaps upgrade Bitmessage to the latest version. - アドレス %1 に接続しています。%2 のバージョン番号は処理できません。Bitmessageを最新のバージョンへアップデートしてください。 + Concerning the address {0}, Bitmessage cannot understand address version numbers of {1}. Perhaps upgrade Bitmessage to the latest version. + アドレス {0} に接続しています。{1} のバージョン番号は処理できません。Bitmessageを最新のバージョンへアップデートしてください。 @@ -686,8 +686,8 @@ It is important that you back up this file. Would you like to open the file now? - Concerning the address %1, Bitmessage cannot handle stream numbers of %2. Perhaps upgrade Bitmessage to the latest version. - アドレス %1 に接続しています。%2 のストリーム番号は処理できません。Bitmessageを最新のバージョンへアップデートしてください。 + Concerning the address {0}, Bitmessage cannot handle stream numbers of {1}. Perhaps upgrade Bitmessage to the latest version. + アドレス {0} に接続しています。{1} のストリーム番号は処理できません。Bitmessageを最新のバージョンへアップデートしてください。 @@ -821,8 +821,8 @@ It is important that you back up this file. Would you like to open the file now? - Bitmessage cannot find your address %1. Perhaps you removed it? - アドレス %1 が見つかりません。既に削除していませんか? + Bitmessage cannot find your address {0}. Perhaps you removed it? + アドレス {0} が見つかりません。既に削除していませんか? @@ -979,7 +979,7 @@ Are you sure you want to delete the channel? - You are using TCP port %1. (This can be changed in the settings). + You are using TCP port {0}. (This can be changed in the settings). @@ -1174,8 +1174,8 @@ Are you sure you want to delete the channel? - Zoom level %1% - ズーム レベル %1% + Zoom level {0}% + ズーム レベル {0}% @@ -1189,48 +1189,48 @@ Are you sure you want to delete the channel? - Display the %1 recent broadcast(s) from this address. + Display the {0} recent broadcast(s) from this address. - New version of PyBitmessage is available: %1. Download it from https://github.com/Bitmessage/PyBitmessage/releases/latest - 新しいバージョンの PyBitmessage が利用可能です: %1。 https://github.com/Bitmessage/PyBitmessage/releases/latest からダウンロードしてください + New version of PyBitmessage is available: {0}. Download it from https://github.com/Bitmessage/PyBitmessage/releases/latest + 新しいバージョンの PyBitmessage が利用可能です: {0}。 https://github.com/Bitmessage/PyBitmessage/releases/latest からダウンロードしてください - Waiting for PoW to finish... %1% - PoW(プルーフオブワーク)が完了するのを待っています... %1% + Waiting for PoW to finish... {0}% + PoW(プルーフオブワーク)が完了するのを待っています... {0}% - Shutting down Pybitmessage... %1% - Pybitmessageをシャットダウンしています... %1% + Shutting down Pybitmessage... {0}% + Pybitmessageをシャットダウンしています... {0}% - Waiting for objects to be sent... %1% - オブジェクトの送信待ち... %1% + Waiting for objects to be sent... {0}% + オブジェクトの送信待ち... {0}% - Saving settings... %1% - 設定を保存しています... %1% + Saving settings... {0}% + 設定を保存しています... {0}% - Shutting down core... %1% - コアをシャットダウンしています... %1% + Shutting down core... {0}% + コアをシャットダウンしています... {0}% - Stopping notifications... %1% - 通知を停止しています... %1% + Stopping notifications... {0}% + 通知を停止しています... {0}% - Shutdown imminent... %1% - すぐにシャットダウンします... %1% + Shutdown imminent... {0}% + すぐにシャットダウンします... {0}% @@ -1244,8 +1244,8 @@ Are you sure you want to delete the channel? - Shutting down PyBitmessage... %1% - PyBitmessageをシャットダウンしています... %1% + Shutting down PyBitmessage... {0}% + PyBitmessageをシャットダウンしています... {0}% @@ -1264,13 +1264,13 @@ Are you sure you want to delete the channel? - Generating %1 new addresses. - %1 の新しいアドレスを生成しています。 + Generating {0} new addresses. + {0} の新しいアドレスを生成しています。 - %1 is already in 'Your Identities'. Not adding it again. - %1はすでに「アドレス一覧」にあります。 もう一度追加できません。 + {0} is already in 'Your Identities'. Not adding it again. + {0}はすでに「アドレス一覧」にあります。 もう一度追加できません。 @@ -1279,7 +1279,7 @@ Are you sure you want to delete the channel? - SOCKS5 Authentication problem: %1 + SOCKS5 Authentication problem: {0} @@ -1304,8 +1304,8 @@ Are you sure you want to delete the channel? - Broadcast sent on %1 - 配信が送信されました %1 + Broadcast sent on {0} + 配信が送信されました {0} @@ -1324,8 +1324,8 @@ Are you sure you want to delete the channel? - Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. %1 - 問題: メッセージに含まれた宛先のリクエストはモバイルデバイスですが、設定では許可されていません。 %1 + Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. {0} + 問題: メッセージに含まれた宛先のリクエストはモバイルデバイスですが、設定では許可されていません。 {0} @@ -1337,18 +1337,18 @@ There is no required difficulty for version 2 addresses like this. Doing work necessary to send message. -Receiver's required difficulty: %1 and %2 +Receiver's required difficulty: {0} and {1} メッセージの送信に必要な処理を行っています。 -受信者の必要な難易度: %1 および %2 +受信者の必要な難易度: {0} および {1} - Problem: The work demanded by the recipient (%1 and %2) is more difficult than you are willing to do. %3 - 問題: 受信者が要求している処理 (%1 および %2) は、現在あなたが設定しているよりも高い難易度です。 %3 + Problem: The work demanded by the recipient ({0} and {1}) is more difficult than you are willing to do. {2} + 問題: 受信者が要求している処理 ({0} および {1}) は、現在あなたが設定しているよりも高い難易度です。 {2} - Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. %1 + Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. {0} 問題: あなた自身またはチャンネルにメッセージを送信しようとしていますが、暗号鍵がkeys.datファイルに見つかりませんでした。 メッセージを暗号化できませんでした。 %1 @@ -1358,8 +1358,8 @@ Receiver's required difficulty: %1 and %2 - Message sent. Waiting for acknowledgement. Sent on %1 - メッセージを送信しました。 確認応答を待っています。 %1 で送信しました + Message sent. Waiting for acknowledgement. Sent on {0} + メッセージを送信しました。 確認応答を待っています。 {0} で送信しました @@ -1373,13 +1373,13 @@ Receiver's required difficulty: %1 and %2 - Sending public key request. Waiting for reply. Requested at %1 - 公開鍵のリクエストを送信しています。 返信を待っています。 %1 でリクエストしました + Sending public key request. Waiting for reply. Requested at {0} + 公開鍵のリクエストを送信しています。 返信を待っています。 {0} でリクエストしました - UPnP port mapping established on port %1 - ポート%1でUPnPポートマッピングが確立しました + UPnP port mapping established on port {0} + ポート{0}でUPnPポートマッピングが確立しました @@ -1423,18 +1423,18 @@ Receiver's required difficulty: %1 and %2 - The name %1 was not found. - 名前 %1 が見つかりませんでした。 + The name {0} was not found. + 名前 {0} が見つかりませんでした。 - The namecoin query failed (%1) - namecoin のクエリに失敗しました (%1) + The namecoin query failed ({0}) + namecoin のクエリに失敗しました ({0}) - Unknown namecoin interface type: %1 - 不明な namecoin インターフェースタイプ: %1 + Unknown namecoin interface type: {0} + 不明な namecoin インターフェースタイプ: {0} @@ -1443,13 +1443,13 @@ Receiver's required difficulty: %1 and %2 - The name %1 has no associated Bitmessage address. - 名前 %1 は関連付けられた Bitmessage アドレスがありません。 + The name {0} has no associated Bitmessage address. + 名前 {0} は関連付けられた Bitmessage アドレスがありません。 - Success! Namecoind version %1 running. - 成功! Namecoind バージョン %1 が実行中。 + Success! Namecoind version {0} running. + 成功! Namecoind バージョン {0} が実行中。 @@ -1513,53 +1513,53 @@ Receiver's required difficulty: %1 and %2 - Error: Bitmessage addresses start with BM- Please check the recipient address %1 - エラー: BitmessageのアドレスはBM-で始まります。 受信者のアドレス %1 を確認してください + Error: Bitmessage addresses start with BM- Please check the recipient address {0} + エラー: BitmessageのアドレスはBM-で始まります。 受信者のアドレス {0} を確認してください - Error: The recipient address %1 is not typed or copied correctly. Please check it. - エラー: 受信者のアドレス %1 は正しく入力、またはコピーされていません。確認して下さい。 + Error: The recipient address {0} is not typed or copied correctly. Please check it. + エラー: 受信者のアドレス {0} は正しく入力、またはコピーされていません。確認して下さい。 - Error: The recipient address %1 contains invalid characters. Please check it. - エラー: 受信者のアドレス %1 は不正な文字を含んでいます。確認して下さい。 + Error: The recipient address {0} contains invalid characters. Please check it. + エラー: 受信者のアドレス {0} は不正な文字を含んでいます。確認して下さい。 - Error: The version of the recipient address %1 is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. - エラー: 受信者アドレスのバージョン %1 は高すぎます。 Bitmessageソフトウェアをアップグレードする必要があるか、連絡先が賢明になっているかのいずれかです。 + Error: The version of the recipient address {0} is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. + エラー: 受信者アドレスのバージョン {0} は高すぎます。 Bitmessageソフトウェアをアップグレードする必要があるか、連絡先が賢明になっているかのいずれかです。 - Error: Some data encoded in the recipient address %1 is too short. There might be something wrong with the software of your acquaintance. - エラー: アドレス %1 でエンコードされたデータが短すぎます。連絡先のソフトウェアが何かしら誤っている可能性があります。 + Error: Some data encoded in the recipient address {0} is too short. There might be something wrong with the software of your acquaintance. + エラー: アドレス {0} でエンコードされたデータが短すぎます。連絡先のソフトウェアが何かしら誤っている可能性があります。 - Error: Some data encoded in the recipient address %1 is too long. There might be something wrong with the software of your acquaintance. - エラー: 受信者のアドレス %1 でエンコードされたデータが短すぎます。連絡先のソフトウェアが何かしら誤っている可能性があります。 + Error: Some data encoded in the recipient address {0} is too long. There might be something wrong with the software of your acquaintance. + エラー: 受信者のアドレス {0} でエンコードされたデータが短すぎます。連絡先のソフトウェアが何かしら誤っている可能性があります。 - Error: Some data encoded in the recipient address %1 is malformed. There might be something wrong with the software of your acquaintance. - エラー: 受信者のアドレス %1 でエンコードされたデータの一部が不正です。連絡先のソフトウェアが何かしら誤っている可能性があります。 + Error: Some data encoded in the recipient address {0} is malformed. There might be something wrong with the software of your acquaintance. + エラー: 受信者のアドレス {0} でエンコードされたデータの一部が不正です。連絡先のソフトウェアが何かしら誤っている可能性があります。 - Error: Something is wrong with the recipient address %1. - エラー: 受信者のアドレス %1 には何かしら誤りがあります。 + Error: Something is wrong with the recipient address {0}. + エラー: 受信者のアドレス {0} には何かしら誤りがあります。 - Error: %1 - エラー: %1 + Error: {0} + エラー: {0} - From %1 - 送信元 %1 + From {0} + 送信元 {0} @@ -1671,8 +1671,8 @@ Receiver's required difficulty: %1 and %2 - The link "%1" will open in a browser. It may be a security risk, it could de-anonymise you or download malicious data. Are you sure? - リンク "%1" はブラウザで開きます。 セキュリティリスクの可能性があります。匿名性がなくなったり、悪意のあるデータをダウンロードする可能性があります。 よろしいですか? + The link "{0}" will open in a browser. It may be a security risk, it could de-anonymise you or download malicious data. Are you sure? + リンク "{0}" はブラウザで開きます。 セキュリティリスクの可能性があります。匿名性がなくなったり、悪意のあるデータをダウンロードする可能性があります。 よろしいですか? @@ -2006,8 +2006,8 @@ The 'Random Number' option is selected by default but deterministic ad - You are using TCP port %1. (This can be changed in the settings). - 使用中のポート %1 (設定で変更できます)。 + You are using TCP port {0}. (This can be changed in the settings). + 使用中のポート {0} (設定で変更できます)。 @@ -2059,28 +2059,28 @@ The 'Random Number' option is selected by default but deterministic ad - Since startup on %1 - 起動日時 %1 + Since startup on {0} + 起動日時 {0} - Down: %1/s Total: %2 - ダウン: %1/秒 合計: %2 + Down: {0}/s Total: {1} + ダウン: {0}/秒 合計: {1} - Up: %1/s Total: %2 - アップ: %1/秒 合計: %2 + Up: {0}/s Total: {1} + アップ: {0}/秒 合計: {1} - Total Connections: %1 - 接続数: %1 + Total Connections: {0} + 接続数: {0} - Inventory lookups per second: %1 - 毎秒のインベントリ検索: %1 + Inventory lookups per second: {0} + 毎秒のインベントリ検索: {0} @@ -2245,8 +2245,8 @@ The 'Random Number' option is selected by default but deterministic ad newchandialog - Successfully created / joined chan %1 - チャンネル %1 を正常に作成 / 参加しました + Successfully created / joined chan {0} + チャンネル {0} を正常に作成 / 参加しました diff --git a/src/translations/bitmessage_nb.ts b/src/translations/bitmessage_nb.ts index 21f641c0..0ee74d6a 100644 --- a/src/translations/bitmessage_nb.ts +++ b/src/translations/bitmessage_nb.ts @@ -240,7 +240,7 @@ Please type the desired email address (including @mailchuck.com) below: - One of your addresses, %1, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? + One of your addresses, {0}, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? @@ -250,12 +250,12 @@ Please type the desired email address (including @mailchuck.com) below: - %1 hours + {0} hours - %1 days + {0} days @@ -275,12 +275,12 @@ Please type the desired email address (including @mailchuck.com) below: - Message sent. Waiting for acknowledgement. Sent at %1 + Message sent. Waiting for acknowledgement. Sent at {0} - Message sent. Sent at %1 + Message sent. Sent at {0} @@ -290,7 +290,7 @@ Please type the desired email address (including @mailchuck.com) below: - Acknowledgement of the message received %1 + Acknowledgement of the message received {0} @@ -300,17 +300,17 @@ Please type the desired email address (including @mailchuck.com) below: - Broadcast on %1 + Broadcast on {0} - Problem: The work demanded by the recipient is more difficult than you are willing to do. %1 + Problem: The work demanded by the recipient is more difficult than you are willing to do. {0} - Problem: The recipient's encryption key is no good. Could not encrypt message. %1 + Problem: The recipient's encryption key is no good. Could not encrypt message. {0} @@ -320,7 +320,7 @@ Please type the desired email address (including @mailchuck.com) below: - Unknown status: %1 %2 + Unknown status: {0} {1} @@ -361,7 +361,7 @@ Please type the desired email address (including @mailchuck.com) below: You may manage your keys by editing the keys.dat file stored in - %1 + {0} It is important that you back up this file. @@ -378,7 +378,7 @@ It is important that you back up this file. You may manage your keys by editing the keys.dat file stored in - %1 + {0} 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.) @@ -444,7 +444,7 @@ It is important that you back up this file. Would you like to open the file now? - Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: %1. This address also appears in 'Your Identities'. + Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: {0}. This address also appears in 'Your Identities'. @@ -512,52 +512,52 @@ It is important that you back up this file. Would you like to open the file now? - The message that you are trying to send is too long by %1 bytes. (The maximum is 261644 bytes). Please cut it down before sending. + The message that you are trying to send is too long by {0} bytes. (The maximum is 261644 bytes). Please cut it down before sending. - Error: Your account wasn't registered at an email gateway. Sending registration now as %1, please wait for the registration to be processed before retrying sending. + Error: Your account wasn't registered at an email gateway. Sending registration now as {0}, please wait for the registration to be processed before retrying sending. - Error: Bitmessage addresses start with BM- Please check %1 + Error: Bitmessage addresses start with BM- Please check {0} - Error: The address %1 is not typed or copied correctly. Please check it. + Error: The address {0} is not typed or copied correctly. Please check it. - Error: The address %1 contains invalid characters. Please check it. + Error: The address {0} contains invalid characters. Please check it. - Error: The address version in %1 is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. + Error: The address version in {0} is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. - Error: Some data encoded in the address %1 is too short. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is too short. There might be something wrong with the software of your acquaintance. - Error: Some data encoded in the address %1 is too long. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is too long. There might be something wrong with the software of your acquaintance. - Error: Some data encoded in the address %1 is malformed. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is malformed. There might be something wrong with the software of your acquaintance. - Error: Something is wrong with the address %1. + Error: Something is wrong with the address {0}. @@ -572,7 +572,7 @@ It is important that you back up this file. Would you like to open the file now? - Concerning the address %1, Bitmessage cannot understand address version numbers of %2. Perhaps upgrade Bitmessage to the latest version. + Concerning the address {0}, Bitmessage cannot understand address version numbers of {1}. Perhaps upgrade Bitmessage to the latest version. @@ -582,7 +582,7 @@ It is important that you back up this file. Would you like to open the file now? - Concerning the address %1, Bitmessage cannot handle stream numbers of %2. Perhaps upgrade Bitmessage to the latest version. + Concerning the address {0}, Bitmessage cannot handle stream numbers of {1}. Perhaps upgrade Bitmessage to the latest version. @@ -722,7 +722,7 @@ It is important that you back up this file. Would you like to open the file now? - Bitmessage cannot find your address %1. Perhaps you removed it? + Bitmessage cannot find your address {0}. Perhaps you removed it? @@ -876,7 +876,7 @@ Are you sure you want to delete the channel? - You are using TCP port %1. (This can be changed in the settings). + You are using TCP port {0}. (This can be changed in the settings). @@ -1081,7 +1081,7 @@ Are you sure you want to delete the channel? - Zoom level %1% + Zoom level {0}% @@ -1096,7 +1096,7 @@ Are you sure you want to delete the channel? - Display the %1 recent broadcast(s) from this address. + Display the {0} recent broadcast(s) from this address. @@ -1449,47 +1449,47 @@ The 'Random Number' option is selected by default but deterministic ad - Since startup on %1 + Since startup on {0} - Objects to be synced: %1 + Objects to be synced: {0} - Processed %1 person-to-person messages. + Processed {0} person-to-person messages. - Processed %1 broadcast messages. + Processed {0} broadcast messages. - Processed %1 public keys. + Processed {0} public keys. - Down: %1/s Total: %2 + Down: {0}/s Total: {1} - Up: %1/s Total: %2 + Up: {0}/s Total: {1} - Total Connections: %1 + Total Connections: {0} - Inventory lookups per second: %1 + Inventory lookups per second: {0} diff --git a/src/translations/bitmessage_nl.qm b/src/translations/bitmessage_nl.qm index 72a7ade246f4d25a7a10aafa654fa76faccfbfa6..94ba152484a43c901f5f47efd3270b39da63a5c8 100644 GIT binary patch delta 1180 zcmZ8feN0t#7=F$@ANQVn&*1{Xy<9-JaQPAe0SOJ3R%)3J+R~H?Fh^{B?cO;c1Hy|l zH)kx+Q`D4OKni+C*ol@ULY9U>mVy&h!G27c6zZ(w*>=mJeRO1*mhDj{ za=Xh-Cq1IpE>q}wQNR2d&lRG#dmRvWQ_K(S3j#^a;)(KuZ0He3%W3H{pE&U@&*6K- zNoysbZ8On#RC?^}Mo##XwD|{46uL{Q9LS=jg;HG_9kI+ydlxA%{%5JbLjXczrBfLv ziAB<2cLW`(lg68pDX>IdbLTxe(IFR91vzPSkGyqeibS1q`Mx1K(I+2hBXR1OeEbj# zqn?p3_2dEepnOl{nN=D)Nu2tp(tG0~GY?hHE(uPYP^La%1gW{!qG>wn z9!^pKe+V6S7H67m;&@T+gjxhUVPIwGE9qHWwwcr$JwA!T~k`Y zow%m1U0PHnL9H+5_t07O*wsfkK$U%2C5Z%=y=I1I@8c#WW!X=!`6t!2hF zTJ5J#GP3j9+v}s5X_xjzfWo|YwPB&21T`k6ZPhM2c`vd|x6RVg_!K>+?iR604+M8I z;yJx}LkD@^*b*|i%0p{lq8edh!UYq3A|Xt#YH-XQr3%@`4X-cjJ}f9RECb&vSRry})sDcf5!kF9%2{f*OXVqA(qH^u|k@fS&LK2iJ4S9U~lg zkx}L-(MxE=3>`U%l1(gQSZ+bOS%EaP(fWf8v^kAzGFzJ27ak}`YwNe&eSW|1@B90F zKi`)<^#yhI#)aMqfIR@{Qvj|DSa=-RoB(Kgfb8=?;5e`~p6o+FX*#fY2<$~G`JV(k zQUCd$`M?l6cz~aHCrhdSyoRBt= zZ^3rxCJ{XiTa%iw7SFtN2EaiHBXf|uuMCLUi9E+H!k>|^*ayV@ff}&|ux`N-hk*kB zj@w^SQlXO!-!=*8-eAH*NKjxhlNxXWFkfe~F4I|io)I5A3@?I>%mL#7Jt$>*+evBA zQRcJd9TfPSg#J3_zHB3)>X9uOZ3m2JWvfT)fCXW)_qLA%{B_we7ZLk6%D$`ZBVj?Z zpPI~6L6cnDz)|MQh$-2E{S+{W#BnFPe1 z;@;g$jzR0Wi)||abq#l0PMI4bxnI)*s1hLx*QI32XiQPrNJ3(-DcXM+q|z%Dr>7E# z>{SeZK&^<4QrbqSvgTvT&W16nXugE%CnSsvQFeN#E~2uPKW32-U8ri6;um^YqdL<| zr7~r!E*$SC0w*8y71<3(`IP)3nvG$8l|B_vMDXq`y4R2KEtghOM%&a21PaKQ)McY| zwj@ay9j-pH_71hCOWmWHq(pD1ds=A-L+)z4jE#C1xfx zqaE_6cgAd;>MB(@+^h?AjuV#YT;4pIp(`1>T^sjP;5xs7#9%5BB;*4mjOdXt^1gqf zl>%|6{FB8>3Vg@E*F(f%;|>~#L%s=ZW_L6@td!?sgKxdr=+kT0=&VRmO;IZ77w_Au zjgwiEd`FCd-7VT{Jd^Hw)s$wP>l0)X+-`e`U~vngXQ|~``nT9U7U>b=A^%w4Vsqv^ z-j%*r%*$tazcvT)OoH!8=c2A`{m3S@I?nwRddJ6$Ev*mt-pJ<>s4DmY)9vHQ6NkH;aF%=!ga z2ql6jRMh!j9nMYksLEbF!>qR1 a9b%qCEOu2vSL6~!p=c)lUJ@>2m_Gpt{9+>j diff --git a/src/translations/bitmessage_nl.ts b/src/translations/bitmessage_nl.ts index 3e7c1640..dd77549e 100644 --- a/src/translations/bitmessage_nl.ts +++ b/src/translations/bitmessage_nl.ts @@ -242,7 +242,7 @@ Voer het gewenste e-mail adres (inclusief @mailchuck.com) hieronder in: - One of your addresses, %1, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? + One of your addresses, {0}, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? @@ -262,13 +262,13 @@ Voer het gewenste e-mail adres (inclusief @mailchuck.com) hieronder in: - Message sent. Waiting for acknowledgement. Sent at %1 - Bericht verzonden. Wachten op bevestiging. Verzonden op %1 + Message sent. Waiting for acknowledgement. Sent at {0} + Bericht verzonden. Wachten op bevestiging. Verzonden op {0} - Message sent. Sent at %1 - Bericht verzonden. Verzonden op %1 + Message sent. Sent at {0} + Bericht verzonden. Verzonden op {0} @@ -277,8 +277,8 @@ Voer het gewenste e-mail adres (inclusief @mailchuck.com) hieronder in: - Acknowledgement of the message received %1 - Bevestiging van het bericht ontvangen op %1 + Acknowledgement of the message received {0} + Bevestiging van het bericht ontvangen op {0} @@ -287,17 +287,17 @@ Voer het gewenste e-mail adres (inclusief @mailchuck.com) hieronder in: - Broadcast on %1 + Broadcast on {0} - Problem: The work demanded by the recipient is more difficult than you are willing to do. %1 + Problem: The work demanded by the recipient is more difficult than you are willing to do. {0} - Problem: The recipient's encryption key is no good. Could not encrypt message. %1 + Problem: The recipient's encryption key is no good. Could not encrypt message. {0} @@ -307,8 +307,8 @@ Voer het gewenste e-mail adres (inclusief @mailchuck.com) hieronder in: - Unknown status: %1 %2 - Status onbekend: %1 %2 + Unknown status: {0} {1} + Status onbekend: {0} {1} @@ -348,7 +348,7 @@ Voer het gewenste e-mail adres (inclusief @mailchuck.com) hieronder in: You may manage your keys by editing the keys.dat file stored in - %1 + {0} It is important that you back up this file. @@ -365,7 +365,7 @@ It is important that you back up this file. You may manage your keys by editing the keys.dat file stored in - %1 + {0} 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.) @@ -431,7 +431,7 @@ It is important that you back up this file. Would you like to open the file now? - Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: %1. This address also appears in 'Your Identities'. + Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: {0}. This address also appears in 'Your Identities'. @@ -499,52 +499,52 @@ It is important that you back up this file. Would you like to open the file now? - The message that you are trying to send is too long by %1 bytes. (The maximum is 261644 bytes). Please cut it down before sending. + The message that you are trying to send is too long by {0} bytes. (The maximum is 261644 bytes). Please cut it down before sending. - Error: Your account wasn't registered at an email gateway. Sending registration now as %1, please wait for the registration to be processed before retrying sending. + Error: Your account wasn't registered at an email gateway. Sending registration now as {0}, please wait for the registration to be processed before retrying sending. - Error: Bitmessage addresses start with BM- Please check %1 + Error: Bitmessage addresses start with BM- Please check {0} - Error: The address %1 is not typed or copied correctly. Please check it. + Error: The address {0} is not typed or copied correctly. Please check it. - Error: The address %1 contains invalid characters. Please check it. + Error: The address {0} contains invalid characters. Please check it. - Error: The address version in %1 is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. + Error: The address version in {0} is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. - Error: Some data encoded in the address %1 is too short. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is too short. There might be something wrong with the software of your acquaintance. - Error: Some data encoded in the address %1 is too long. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is too long. There might be something wrong with the software of your acquaintance. - Error: Some data encoded in the address %1 is malformed. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is malformed. There might be something wrong with the software of your acquaintance. - Error: Something is wrong with the address %1. + Error: Something is wrong with the address {0}. @@ -559,7 +559,7 @@ It is important that you back up this file. Would you like to open the file now? - Concerning the address %1, Bitmessage cannot understand address version numbers of %2. Perhaps upgrade Bitmessage to the latest version. + Concerning the address {0}, Bitmessage cannot understand address version numbers of {1}. Perhaps upgrade Bitmessage to the latest version. @@ -569,7 +569,7 @@ It is important that you back up this file. Would you like to open the file now? - Concerning the address %1, Bitmessage cannot handle stream numbers of %2. Perhaps upgrade Bitmessage to the latest version. + Concerning the address {0}, Bitmessage cannot handle stream numbers of {1}. Perhaps upgrade Bitmessage to the latest version. @@ -704,7 +704,7 @@ It is important that you back up this file. Would you like to open the file now? - Bitmessage cannot find your address %1. Perhaps you removed it? + Bitmessage cannot find your address {0}. Perhaps you removed it? @@ -858,7 +858,7 @@ Are you sure you want to delete the channel? - You are using TCP port %1. (This can be changed in the settings). + You are using TCP port {0}. (This can be changed in the settings). @@ -1053,7 +1053,7 @@ Are you sure you want to delete the channel? - Zoom level %1% + Zoom level {0}% @@ -1068,47 +1068,47 @@ Are you sure you want to delete the channel? - Display the %1 recent broadcast(s) from this address. + Display the {0} recent broadcast(s) from this address. - New version of PyBitmessage is available: %1. Download it from https://github.com/Bitmessage/PyBitmessage/releases/latest + New version of PyBitmessage is available: {0}. Download it from https://github.com/Bitmessage/PyBitmessage/releases/latest - Waiting for PoW to finish... %1% + Waiting for PoW to finish... {0}% - Shutting down Pybitmessage... %1% + Shutting down Pybitmessage... {0}% - Waiting for objects to be sent... %1% + Waiting for objects to be sent... {0}% - Saving settings... %1% + Saving settings... {0}% - Shutting down core... %1% + Shutting down core... {0}% - Stopping notifications... %1% + Stopping notifications... {0}% - Shutdown imminent... %1% + Shutdown imminent... {0}% @@ -1129,7 +1129,7 @@ Are you sure you want to delete the channel? - Shutting down PyBitmessage... %1% + Shutting down PyBitmessage... {0}% @@ -1149,12 +1149,12 @@ Are you sure you want to delete the channel? - Generating %1 new addresses. + Generating {0} new addresses. - %1 is already in 'Your Identities'. Not adding it again. + {0} is already in 'Your Identities'. Not adding it again. @@ -1164,7 +1164,7 @@ Are you sure you want to delete the channel? - SOCKS5 Authentication problem: %1 + SOCKS5 Authentication problem: {0} @@ -1189,7 +1189,7 @@ Are you sure you want to delete the channel? - Broadcast sent on %1 + Broadcast sent on {0} @@ -1209,7 +1209,7 @@ Are you sure you want to delete the channel? - Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. %1 + Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. {0} @@ -1221,17 +1221,17 @@ There is no required difficulty for version 2 addresses like this. Doing work necessary to send message. -Receiver's required difficulty: %1 and %2 +Receiver's required difficulty: {0} and {1} - Problem: The work demanded by the recipient (%1 and %2) is more difficult than you are willing to do. %3 + Problem: The work demanded by the recipient ({0} and {1}) is more difficult than you are willing to do. {2} - Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. %1 + Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. {0} @@ -1241,7 +1241,7 @@ Receiver's required difficulty: %1 and %2 - Message sent. Waiting for acknowledgement. Sent on %1 + Message sent. Waiting for acknowledgement. Sent on {0} @@ -1256,12 +1256,12 @@ Receiver's required difficulty: %1 and %2 - Sending public key request. Waiting for reply. Requested at %1 + Sending public key request. Waiting for reply. Requested at {0} - UPnP port mapping established on port %1 + UPnP port mapping established on port {0} @@ -1623,27 +1623,27 @@ The 'Random Number' option is selected by default but deterministic ad - Since startup on %1 + Since startup on {0} - Down: %1/s Total: %2 + Down: {0}/s Total: {1} - Up: %1/s Total: %2 + Up: {0}/s Total: {1} - Total Connections: %1 + Total Connections: {0} - Inventory lookups per second: %1 + Inventory lookups per second: {0} diff --git a/src/translations/bitmessage_no.qm b/src/translations/bitmessage_no.qm index 493d09ef7b51950aec8162fdd7ca145657d77c5e..9f2d9efbeb9540ff17539a3d439bcd96bb75c880 100644 GIT binary patch delta 3967 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 LT1}gi$1wi_?e>J4 delta 4332 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 - One of your addresses, %1, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? - En av dine gamle adresser er av den første typen og derfor ikke lenger støttet: %1. Derfor kan den vel slettes? + One of your addresses, {0}, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? + En av dine gamle adresser er av den første typen og derfor ikke lenger støttet: {0}. Derfor kan den vel slettes? @@ -261,13 +261,13 @@ Please type the desired email address (including @mailchuck.com) below: - Message sent. Waiting for acknowledgement. Sent at %1 - Beskjed sendt. Venter på bekreftelse. Sendt %1 + Message sent. Waiting for acknowledgement. Sent at {0} + Beskjed sendt. Venter på bekreftelse. Sendt {0} - Message sent. Sent at %1 - Beskjed sendt. Sendt %1 + Message sent. Sent at {0} + Beskjed sendt. Sendt {0} @@ -276,8 +276,8 @@ Please type the desired email address (including @mailchuck.com) below: - Acknowledgement of the message received %1 - Bekreftelse på beskjeden mottatt %1 + Acknowledgement of the message received {0} + Bekreftelse på beskjeden mottatt {0} @@ -286,18 +286,18 @@ Please type the desired email address (including @mailchuck.com) below: - Broadcast on %1 - Kringkasting på %1 + Broadcast on {0} + Kringkasting på {0} - Problem: The work demanded by the recipient is more difficult than you are willing to do. %1 - Problem: Det nødvendige arbeidet som kreves utført av mottaker er mer krevende enn det som er satt som akseptabelt. %1 + Problem: The work demanded by the recipient is more difficult than you are willing to do. {0} + Problem: Det nødvendige arbeidet som kreves utført av mottaker er mer krevende enn det som er satt som akseptabelt. {0} - Problem: The recipient's encryption key is no good. Could not encrypt message. %1 - Problem: Mottakerens nøkkel kunne ikke brukes til å kryptere beskjeden. %1 + Problem: The recipient's encryption key is no good. Could not encrypt message. {0} + Problem: Mottakerens nøkkel kunne ikke brukes til å kryptere beskjeden. {0} @@ -306,8 +306,8 @@ Please type the desired email address (including @mailchuck.com) below: - Unknown status: %1 %2 - Ukjent status: %1 %2 + Unknown status: {0} {1} + Ukjent status: {0} {1} @@ -347,10 +347,10 @@ Please type the desired email address (including @mailchuck.com) below: You may manage your keys by editing the keys.dat file stored in - %1 + {0} It is important that you back up this file. Du kan administrere nøklene dine ved å endre filen keys.dat lagret i - %1 + {0} Det er viktig at du tar en sikkerhetskopi av denne filen. @@ -366,10 +366,10 @@ Det er viktig at du tar en sikkerhetskopi av denne filen. You may manage your keys by editing the keys.dat file stored in - %1 + {0} 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.) Du kan administrere dine nøkler ved å endre på filen keys.dat lagret i - %1 + {0} Det er viktig at du tar sikkerhetskopi av denne filen. Vil du åpne denne filen nå? (Vær sikker på å få avsluttet Bitmessage før du gjør endringer.) @@ -434,8 +434,8 @@ Det er viktig at du tar sikkerhetskopi av denne filen. Vil du åpne denne filen - Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: %1. This address also appears in 'Your Identities'. - Opprettet ny kanal. For å la andre delta i din nye kanal gir du dem dem kanalnavnet og denne Bitmessage-adressen: %1. Denne adressen vises også i 'Dine identiteter'. + Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: {0}. This address also appears in 'Your Identities'. + Opprettet ny kanal. For å la andre delta i din nye kanal gir du dem dem kanalnavnet og denne Bitmessage-adressen: {0}. Denne adressen vises også i 'Dine identiteter'. @@ -502,53 +502,53 @@ Det er viktig at du tar sikkerhetskopi av denne filen. Vil du åpne denne filen - The message that you are trying to send is too long by %1 bytes. (The maximum is 261644 bytes). Please cut it down before sending. + The message that you are trying to send is too long by {0} bytes. (The maximum is 261644 bytes). Please cut it down before sending. - Error: Your account wasn't registered at an email gateway. Sending registration now as %1, please wait for the registration to be processed before retrying sending. + Error: Your account wasn't registered at an email gateway. Sending registration now as {0}, please wait for the registration to be processed before retrying sending. - Error: Bitmessage addresses start with BM- Please check %1 - Feil: Bitmessage-adresser begynner med BM-. Vennligst sjekk %1 + Error: Bitmessage addresses start with BM- Please check {0} + Feil: Bitmessage-adresser begynner med BM-. Vennligst sjekk {0} - Error: The address %1 is not typed or copied correctly. Please check it. - Feil: Adressen %1 er skrevet eller kopiert inn feil. Vennligst sjekk den. + Error: The address {0} is not typed or copied correctly. Please check it. + Feil: Adressen {0} er skrevet eller kopiert inn feil. Vennligst sjekk den. - Error: The address %1 contains invalid characters. Please check it. - Feil: Adressen %1 innerholder ugyldige tegn. Vennligst sjekk den. + Error: The address {0} contains invalid characters. Please check it. + Feil: Adressen {0} innerholder ugyldige tegn. Vennligst sjekk den. - Error: The address version in %1 is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. - Feil: Typenummeret for adressen %1 er for høy. Enten trenger du å oppgradere Bitmessaage-programvaren eller så er det fordi kontakten din har funnet på noe smart. + Error: The address version in {0} is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. + Feil: Typenummeret for adressen {0} er for høy. Enten trenger du å oppgradere Bitmessaage-programvaren eller så er det fordi kontakten din har funnet på noe smart. - Error: Some data encoded in the address %1 is too short. There might be something wrong with the software of your acquaintance. - Feil: Noen av de kodede dataene i adressen %1 er for korte. Det kan hende det er noe galt med programvaren til kontakten din. + Error: Some data encoded in the address {0} is too short. There might be something wrong with the software of your acquaintance. + Feil: Noen av de kodede dataene i adressen {0} er for korte. Det kan hende det er noe galt med programvaren til kontakten din. - Error: Some data encoded in the address %1 is too long. There might be something wrong with the software of your acquaintance. - Feil: Noen av de kodede dataene i adressen %1 er for lange. Det kan hende det er noe galt med programvaren til kontakten din. + Error: Some data encoded in the address {0} is too long. There might be something wrong with the software of your acquaintance. + Feil: Noen av de kodede dataene i adressen {0} er for lange. Det kan hende det er noe galt med programvaren til kontakten din. - Error: Some data encoded in the address %1 is malformed. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is malformed. There might be something wrong with the software of your acquaintance. - Error: Something is wrong with the address %1. - Feil: Noe er galt med adressen %1. + Error: Something is wrong with the address {0}. + Feil: Noe er galt med adressen {0}. @@ -562,8 +562,8 @@ Det er viktig at du tar sikkerhetskopi av denne filen. Vil du åpne denne filen - Concerning the address %1, Bitmessage cannot understand address version numbers of %2. Perhaps upgrade Bitmessage to the latest version. - Angående adressen %1, Bitmessage forstår ikke adressetypenumre for %2. Oppdater Bitmessage til siste versjon. + Concerning the address {0}, Bitmessage cannot understand address version numbers of {1}. Perhaps upgrade Bitmessage to the latest version. + Angående adressen {0}, Bitmessage forstår ikke adressetypenumre for {1}. Oppdater Bitmessage til siste versjon. @@ -572,8 +572,8 @@ Det er viktig at du tar sikkerhetskopi av denne filen. Vil du åpne denne filen - Concerning the address %1, Bitmessage cannot handle stream numbers of %2. Perhaps upgrade Bitmessage to the latest version. - Angående adressen %1, Bitmessage kan ikke håndtere strømnumre for %2. Oppdater Bitmessage til siste utgivelse. + Concerning the address {0}, Bitmessage cannot handle stream numbers of {1}. Perhaps upgrade Bitmessage to the latest version. + Angående adressen {0}, Bitmessage kan ikke håndtere strømnumre for {1}. Oppdater Bitmessage til siste utgivelse. @@ -707,8 +707,8 @@ Det er viktig at du tar sikkerhetskopi av denne filen. Vil du åpne denne filen - Bitmessage cannot find your address %1. Perhaps you removed it? - Bitmessage kan ikke finne adressen %1. Kanskje du fjernet den? + Bitmessage cannot find your address {0}. Perhaps you removed it? + Bitmessage kan ikke finne adressen {0}. Kanskje du fjernet den? @@ -861,8 +861,8 @@ Are you sure you want to delete the channel? - You are using TCP port %1. (This can be changed in the settings). - Du benytter TCP-port %1. (Dette kan endres på i innstillingene). + You are using TCP port {0}. (This can be changed in the settings). + Du benytter TCP-port {0}. (Dette kan endres på i innstillingene). @@ -1056,8 +1056,8 @@ Are you sure you want to delete the channel? - Zoom level %1% - Zoom nivå %1% + Zoom level {0}% + Zoom nivå {0}% @@ -1071,47 +1071,47 @@ Are you sure you want to delete the channel? - Display the %1 recent broadcast(s) from this address. + Display the {0} recent broadcast(s) from this address. - New version of PyBitmessage is available: %1. Download it from https://github.com/Bitmessage/PyBitmessage/releases/latest + New version of PyBitmessage is available: {0}. Download it from https://github.com/Bitmessage/PyBitmessage/releases/latest - Waiting for PoW to finish... %1% + Waiting for PoW to finish... {0}% - Shutting down Pybitmessage... %1% + Shutting down Pybitmessage... {0}% - Waiting for objects to be sent... %1% + Waiting for objects to be sent... {0}% - Saving settings... %1% + Saving settings... {0}% - Shutting down core... %1% + Shutting down core... {0}% - Stopping notifications... %1% + Stopping notifications... {0}% - Shutdown imminent... %1% + Shutdown imminent... {0}% @@ -1132,7 +1132,7 @@ Are you sure you want to delete the channel? - Shutting down PyBitmessage... %1% + Shutting down PyBitmessage... {0}% @@ -1152,12 +1152,12 @@ Are you sure you want to delete the channel? - Generating %1 new addresses. + Generating {0} new addresses. - %1 is already in 'Your Identities'. Not adding it again. + {0} is already in 'Your Identities'. Not adding it again. @@ -1167,7 +1167,7 @@ Are you sure you want to delete the channel? - SOCKS5 Authentication problem: %1 + SOCKS5 Authentication problem: {0} @@ -1192,7 +1192,7 @@ Are you sure you want to delete the channel? - Broadcast sent on %1 + Broadcast sent on {0} @@ -1212,7 +1212,7 @@ Are you sure you want to delete the channel? - Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. %1 + Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. {0} @@ -1224,17 +1224,17 @@ There is no required difficulty for version 2 addresses like this. Doing work necessary to send message. -Receiver's required difficulty: %1 and %2 +Receiver's required difficulty: {0} and {1} - Problem: The work demanded by the recipient (%1 and %2) is more difficult than you are willing to do. %3 + Problem: The work demanded by the recipient ({0} and {1}) is more difficult than you are willing to do. {2} - Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. %1 + Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. {0} @@ -1244,7 +1244,7 @@ Receiver's required difficulty: %1 and %2 - Message sent. Waiting for acknowledgement. Sent on %1 + Message sent. Waiting for acknowledgement. Sent on {0} @@ -1259,12 +1259,12 @@ Receiver's required difficulty: %1 and %2 - Sending public key request. Waiting for reply. Requested at %1 + Sending public key request. Waiting for reply. Requested at {0} - UPnP port mapping established on port %1 + UPnP port mapping established on port {0} @@ -1627,27 +1627,27 @@ The 'Random Number' option is selected by default but deterministic ad - Since startup on %1 - Siden oppstart på %1 + Since startup on {0} + Siden oppstart på {0} - Down: %1/s Total: %2 - Ned: %1/s Totalt: %2 + Down: {0}/s Total: {1} + Ned: {0}/s Totalt: {1} - Up: %1/s Total: %2 - Opp: %1/s Totalt: %2 + Up: {0}/s Total: {1} + Opp: {0}/s Totalt: {1} - Total Connections: %1 - Antall tilkoblinger: %1 + Total Connections: {0} + Antall tilkoblinger: {0} - Inventory lookups per second: %1 + Inventory lookups per second: {0} diff --git a/src/translations/bitmessage_pl.qm b/src/translations/bitmessage_pl.qm index fb31e8d552193358b8243a8b0faa5c265c14fc51..215ad8cffdbd5cd8052d9b16f13ca532327d0223 100644 GIT binary patch delta 6129 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 - One of your addresses, %1, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? - Jeden z adresów, %1, jest starym adresem wersji 1. Adresy tej wersji nie są już wspierane. Usunąć go? + One of your addresses, {0}, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? + Jeden z adresów, {0}, jest starym adresem wersji 1. Adresy tej wersji nie są już wspierane. Usunąć go? @@ -374,13 +374,13 @@ Please type the desired email address (including @mailchuck.com) below: - Message sent. Waiting for acknowledgement. Sent at %1 - Wiadomość wysłana. Oczekiwanie na potwierdzenie odbioru. Wysłano o %1 + Message sent. Waiting for acknowledgement. Sent at {0} + Wiadomość wysłana. Oczekiwanie na potwierdzenie odbioru. Wysłano o {0} - Message sent. Sent at %1 - Wiadomość wysłana. Wysłano o %1 + Message sent. Sent at {0} + Wiadomość wysłana. Wysłano o {0} @@ -389,8 +389,8 @@ Please type the desired email address (including @mailchuck.com) below: - Acknowledgement of the message received %1 - Otrzymano potwierdzenie odbioru wiadomości %1 + Acknowledgement of the message received {0} + Otrzymano potwierdzenie odbioru wiadomości {0} @@ -399,18 +399,18 @@ Please type the desired email address (including @mailchuck.com) below: - Broadcast on %1 - Wysłana o %1 + Broadcast on {0} + Wysłana o {0} - Problem: The work demanded by the recipient is more difficult than you are willing to do. %1 - Problem: dowód pracy wymagany przez odbiorcę jest trudniejszy niż zaakceptowany przez Ciebie. %1 + Problem: The work demanded by the recipient is more difficult than you are willing to do. {0} + Problem: dowód pracy wymagany przez odbiorcę jest trudniejszy niż zaakceptowany przez Ciebie. {0} - Problem: The recipient's encryption key is no good. Could not encrypt message. %1 - Problem: klucz szyfrujący odbiorcy jest nieprawidłowy. Nie można zaszyfrować wiadomości. %1 + Problem: The recipient's encryption key is no good. Could not encrypt message. {0} + Problem: klucz szyfrujący odbiorcy jest nieprawidłowy. Nie można zaszyfrować wiadomości. {0} @@ -419,8 +419,8 @@ Please type the desired email address (including @mailchuck.com) below: - Unknown status: %1 %2 - Nieznany status: %1 %2 + Unknown status: {0} {1} + Nieznany status: {0} {1} @@ -460,10 +460,10 @@ Please type the desired email address (including @mailchuck.com) below: You may manage your keys by editing the keys.dat file stored in - %1 + {0} It is important that you back up this file. Możesz zarządzać swoimi kluczami edytując plik keys.dat znajdujący się -%1 +{0} Zaleca się zrobienie kopii zapasowej tego pliku. @@ -479,10 +479,10 @@ Zaleca się zrobienie kopii zapasowej tego pliku. You may manage your keys by editing the keys.dat file stored in - %1 + {0} 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.) Możesz zarządzać swoimi kluczami edytując plik keys.dat znajdujący się -%1 +{0} Zaleca się zrobienie kopii zapasowej tego pliku. Czy chcesz otworzyć ten plik teraz? (Zamknij Bitmessage przed wprowadzeniem jakichkolwiek zmian.) @@ -547,7 +547,7 @@ Zaleca się zrobienie kopii zapasowej tego pliku. Czy chcesz otworzyć ten plik - Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: %1. This address also appears in 'Your Identities'. + Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: {0}. This address also appears in 'Your Identities'. @@ -618,52 +618,52 @@ Zwykle 4-5 dniowy TTL jest odpowiedni. - The message that you are trying to send is too long by %1 bytes. (The maximum is 261644 bytes). Please cut it down before sending. - Wiadomość jest za długa o %1 bajtów (maksymalna długość wynosi 261644 bajty). Przed wysłaniem należy ją skrócić. + The message that you are trying to send is too long by {0} bytes. (The maximum is 261644 bytes). Please cut it down before sending. + Wiadomość jest za długa o {0} bajtów (maksymalna długość wynosi 261644 bajty). Przed wysłaniem należy ją skrócić. - Error: Your account wasn't registered at an email gateway. Sending registration now as %1, please wait for the registration to be processed before retrying sending. - Błąd: Twoje konto nie było zarejestrowane w bramce poczty. Rejestrowanie jako %1, proszę poczekać na zakończenie procesu przed ponowną próbą wysłania wiadomości. + Error: Your account wasn't registered at an email gateway. Sending registration now as {0}, please wait for the registration to be processed before retrying sending. + Błąd: Twoje konto nie było zarejestrowane w bramce poczty. Rejestrowanie jako {0}, proszę poczekać na zakończenie procesu przed ponowną próbą wysłania wiadomości. - Error: Bitmessage addresses start with BM- Please check %1 + Error: Bitmessage addresses start with BM- Please check {0} - Error: The address %1 is not typed or copied correctly. Please check it. + Error: The address {0} is not typed or copied correctly. Please check it. - Error: The address %1 contains invalid characters. Please check it. + Error: The address {0} contains invalid characters. Please check it. - Error: The address version in %1 is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. + Error: The address version in {0} is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. - Error: Some data encoded in the address %1 is too short. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is too short. There might be something wrong with the software of your acquaintance. - Error: Some data encoded in the address %1 is too long. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is too long. There might be something wrong with the software of your acquaintance. - Error: Some data encoded in the address %1 is malformed. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is malformed. There might be something wrong with the software of your acquaintance. - Error: Something is wrong with the address %1. + Error: Something is wrong with the address {0}. @@ -678,8 +678,8 @@ Zwykle 4-5 dniowy TTL jest odpowiedni. - Concerning the address %1, Bitmessage cannot understand address version numbers of %2. Perhaps upgrade Bitmessage to the latest version. - Odnośnie adresu %1, Bitmessage nie potrafi odczytać wersji adresu %2. Może uaktualnij Bitmessage do najnowszej wersji. + Concerning the address {0}, Bitmessage cannot understand address version numbers of {1}. Perhaps upgrade Bitmessage to the latest version. + Odnośnie adresu {0}, Bitmessage nie potrafi odczytać wersji adresu {1}. Może uaktualnij Bitmessage do najnowszej wersji. @@ -688,8 +688,8 @@ Zwykle 4-5 dniowy TTL jest odpowiedni. - Concerning the address %1, Bitmessage cannot handle stream numbers of %2. Perhaps upgrade Bitmessage to the latest version. - Odnośnie adresu %1, Bitmessage nie potrafi operować na strumieniu adresu %2. Może uaktualnij Bitmessage do najnowszej wersji. + Concerning the address {0}, Bitmessage cannot handle stream numbers of {1}. Perhaps upgrade Bitmessage to the latest version. + Odnośnie adresu {0}, Bitmessage nie potrafi operować na strumieniu adresu {1}. Może uaktualnij Bitmessage do najnowszej wersji. @@ -823,8 +823,8 @@ Zwykle 4-5 dniowy TTL jest odpowiedni. - Bitmessage cannot find your address %1. Perhaps you removed it? - Bitmessage nie może odnaleźć Twojego adresu %1. Może go usunąłeś? + Bitmessage cannot find your address {0}. Perhaps you removed it? + Bitmessage nie może odnaleźć Twojego adresu {0}. Może go usunąłeś? @@ -981,7 +981,7 @@ Czy na pewno chcesz usunąć ten kanał? - You are using TCP port %1. (This can be changed in the settings). + You are using TCP port {0}. (This can be changed in the settings). @@ -1176,8 +1176,8 @@ Czy na pewno chcesz usunąć ten kanał? - Zoom level %1% - Poziom powiększenia %1% + Zoom level {0}% + Poziom powiększenia {0}% @@ -1191,48 +1191,48 @@ Czy na pewno chcesz usunąć ten kanał? - Display the %1 recent broadcast(s) from this address. + Display the {0} recent broadcast(s) from this address. - New version of PyBitmessage is available: %1. Download it from https://github.com/Bitmessage/PyBitmessage/releases/latest - Nowa wersja Bitmessage jest dostępna: %1. Pobierz ją z https://github.com/Bitmessage/PyBitmessage/releases/latest + New version of PyBitmessage is available: {0}. Download it from https://github.com/Bitmessage/PyBitmessage/releases/latest + Nowa wersja Bitmessage jest dostępna: {0}. Pobierz ją z https://github.com/Bitmessage/PyBitmessage/releases/latest - Waiting for PoW to finish... %1% - Oczekiwanie na wykonanie dowodu pracy… %1% + Waiting for PoW to finish... {0}% + Oczekiwanie na wykonanie dowodu pracy… {0}% - Shutting down Pybitmessage... %1% - Zamykanie PyBitmessage… %1% + Shutting down Pybitmessage... {0}% + Zamykanie PyBitmessage… {0}% - Waiting for objects to be sent... %1% - Oczekiwanie na wysłanie obiektów… %1% + Waiting for objects to be sent... {0}% + Oczekiwanie na wysłanie obiektów… {0}% - Saving settings... %1% - Zapisywanie ustawień… %1% + Saving settings... {0}% + Zapisywanie ustawień… {0}% - Shutting down core... %1% - Zamykanie rdzenia programu… %1% + Shutting down core... {0}% + Zamykanie rdzenia programu… {0}% - Stopping notifications... %1% - Zatrzymywanie powiadomień… %1% + Stopping notifications... {0}% + Zatrzymywanie powiadomień… {0}% - Shutdown imminent... %1% - Zaraz zamknę… %1% + Shutdown imminent... {0}% + Zaraz zamknę… {0}% @@ -1246,8 +1246,8 @@ Czy na pewno chcesz usunąć ten kanał? - Shutting down PyBitmessage... %1% - Zamykanie PyBitmessage… %1% + Shutting down PyBitmessage... {0}% + Zamykanie PyBitmessage… {0}% @@ -1266,13 +1266,13 @@ Czy na pewno chcesz usunąć ten kanał? - Generating %1 new addresses. - Generowanie %1 nowych adresów. + Generating {0} new addresses. + Generowanie {0} nowych adresów. - %1 is already in 'Your Identities'. Not adding it again. - %1 jest już w 'Twoich tożsamościach'. Nie zostanie tu dodany. + {0} is already in 'Your Identities'. Not adding it again. + {0} jest już w 'Twoich tożsamościach'. Nie zostanie tu dodany. @@ -1281,7 +1281,7 @@ Czy na pewno chcesz usunąć ten kanał? - SOCKS5 Authentication problem: %1 + SOCKS5 Authentication problem: {0} @@ -1306,8 +1306,8 @@ Czy na pewno chcesz usunąć ten kanał? - Broadcast sent on %1 - Wysłano: %1 + Broadcast sent on {0} + Wysłano: {0} @@ -1326,8 +1326,8 @@ Czy na pewno chcesz usunąć ten kanał? - Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. %1 - Problem: adres docelowy jest urządzeniem przenośnym, które wymaga, aby adres docelowy był zawarty w wiadomości, ale jest to zabronione w Twoich ustawieniach. %1 + Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. {0} + Problem: adres docelowy jest urządzeniem przenośnym, które wymaga, aby adres docelowy był zawarty w wiadomości, ale jest to zabronione w Twoich ustawieniach. {0} @@ -1339,19 +1339,19 @@ Nie ma wymaganej trudności dla adresów w wersji 2, takich jak ten adres. Doing work necessary to send message. -Receiver's required difficulty: %1 and %2 +Receiver's required difficulty: {0} and {1} Wykonywanie dowodu pracy niezbędnego do wysłania wiadomości. -Odbiorca wymaga trudności: %1 i %2 +Odbiorca wymaga trudności: {0} i {1} - Problem: The work demanded by the recipient (%1 and %2) is more difficult than you are willing to do. %3 - Problem: dowód pracy wymagany przez odbiorcę (%1 i %2) jest trudniejszy niż chciałbyś wykonać. %3 + Problem: The work demanded by the recipient ({0} and {1}) is more difficult than you are willing to do. {2} + Problem: dowód pracy wymagany przez odbiorcę ({0} i {1}) jest trudniejszy niż chciałbyś wykonać. {2} - Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. %1 - Problem: próbujesz wysłać wiadomość do siebie lub na kanał, ale Twój klucz szyfrujący nie został znaleziony w pliku keys.dat. Nie można zaszyfrować wiadomości. %1 + Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. {0} + Problem: próbujesz wysłać wiadomość do siebie lub na kanał, ale Twój klucz szyfrujący nie został znaleziony w pliku keys.dat. Nie można zaszyfrować wiadomości. {0} @@ -1360,8 +1360,8 @@ Odbiorca wymaga trudności: %1 i %2 - Message sent. Waiting for acknowledgement. Sent on %1 - Wiadomość wysłana. Oczekiwanie na potwierdzenie odbioru. Wysłano o %1 + Message sent. Waiting for acknowledgement. Sent on {0} + Wiadomość wysłana. Oczekiwanie na potwierdzenie odbioru. Wysłano o {0} @@ -1375,13 +1375,13 @@ Odbiorca wymaga trudności: %1 i %2 - Sending public key request. Waiting for reply. Requested at %1 - Wysyłanie prośby o klucz publiczny. Oczekiwanie na odpowiedź. Zapytano o %1 + Sending public key request. Waiting for reply. Requested at {0} + Wysyłanie prośby o klucz publiczny. Oczekiwanie na odpowiedź. Zapytano o {0} - UPnP port mapping established on port %1 - Mapowanie portów UPnP wykonano na porcie %1 + UPnP port mapping established on port {0} + Mapowanie portów UPnP wykonano na porcie {0} @@ -1425,18 +1425,18 @@ Odbiorca wymaga trudności: %1 i %2 - The name %1 was not found. - Ksywka %1 nie została znaleziona. + The name {0} was not found. + Ksywka {0} nie została znaleziona. - The namecoin query failed (%1) - Zapytanie namecoin nie powiodło się (%1) + The namecoin query failed ({0}) + Zapytanie namecoin nie powiodło się ({0}) - Unknown namecoin interface type: %1 - Nieznany typ interfejsu namecoin: %1 + Unknown namecoin interface type: {0} + Nieznany typ interfejsu namecoin: {0} @@ -1445,13 +1445,13 @@ Odbiorca wymaga trudności: %1 i %2 - The name %1 has no associated Bitmessage address. - Ksywka %1 nie ma powiązanego adresu Bitmessage. + The name {0} has no associated Bitmessage address. + Ksywka {0} nie ma powiązanego adresu Bitmessage. - Success! Namecoind version %1 running. - Namecoind wersja %1 działa poprawnie! + Success! Namecoind version {0} running. + Namecoind wersja {0} działa poprawnie! @@ -1514,53 +1514,53 @@ Witamy w przyjaznym i bezpiecznym Bitmessage - Error: Bitmessage addresses start with BM- Please check the recipient address %1 - Błąd: adresy Bitmessage zaczynają się od BM-. Proszę sprawdzić adres odbiorcy %1. + Error: Bitmessage addresses start with BM- Please check the recipient address {0} + Błąd: adresy Bitmessage zaczynają się od BM-. Proszę sprawdzić adres odbiorcy {0}. - Error: The recipient address %1 is not typed or copied correctly. Please check it. - Błąd: adres odbiorcy %1 nie został skopiowany lub przepisany poprawnie. Proszę go sprawdzić. + Error: The recipient address {0} is not typed or copied correctly. Please check it. + Błąd: adres odbiorcy {0} nie został skopiowany lub przepisany poprawnie. Proszę go sprawdzić. - Error: The recipient address %1 contains invalid characters. Please check it. - Błąd: adres odbiorcy %1 zawiera nieprawidłowe znaki. Proszę go sprawdzić. + Error: The recipient address {0} contains invalid characters. Please check it. + Błąd: adres odbiorcy {0} zawiera nieprawidłowe znaki. Proszę go sprawdzić. - Error: The version of the recipient address %1 is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. - Błąd: wersja adresu odbiorcy %1 jest za wysoka. Musisz albo zaktualizować Twoje oprogramowanie Bitmessage, albo twój znajomy Cię trolluje. + Error: The version of the recipient address {0} is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. + Błąd: wersja adresu odbiorcy {0} jest za wysoka. Musisz albo zaktualizować Twoje oprogramowanie Bitmessage, albo twój znajomy Cię trolluje. - Error: Some data encoded in the recipient address %1 is too short. There might be something wrong with the software of your acquaintance. - Błąd: niektóre dane zakodowane w adresie odbiorcy %1 są zbyt krótkie. Być może coś nie działa należycie w programie Twojego znajomego. + Error: Some data encoded in the recipient address {0} is too short. There might be something wrong with the software of your acquaintance. + Błąd: niektóre dane zakodowane w adresie odbiorcy {0} są zbyt krótkie. Być może coś nie działa należycie w programie Twojego znajomego. - Error: Some data encoded in the recipient address %1 is too long. There might be something wrong with the software of your acquaintance. - Błąd: niektóre dane zakodowane w adresie odbiorcy %1 są zbyt długie. Być może coś nie działa należycie w programie Twojego znajomego. + Error: Some data encoded in the recipient address {0} is too long. There might be something wrong with the software of your acquaintance. + Błąd: niektóre dane zakodowane w adresie odbiorcy {0} są zbyt długie. Być może coś nie działa należycie w programie Twojego znajomego. - Error: Some data encoded in the recipient address %1 is malformed. There might be something wrong with the software of your acquaintance. - Błąd: niektóre dane zakodowane w adresie odbiorcy %1 są uszkodzone. Być może coś nie działa należycie w programie Twojego znajomego. + Error: Some data encoded in the recipient address {0} is malformed. There might be something wrong with the software of your acquaintance. + Błąd: niektóre dane zakodowane w adresie odbiorcy {0} są uszkodzone. Być może coś nie działa należycie w programie Twojego znajomego. - Error: Something is wrong with the recipient address %1. - Błąd: coś jest nie tak z adresem odbiorcy %1. + Error: Something is wrong with the recipient address {0}. + Błąd: coś jest nie tak z adresem odbiorcy {0}. - Error: %1 - Błąd: %1 + Error: {0} + Błąd: {0} - From %1 - Od %1 + From {0} + Od {0} @@ -1672,8 +1672,8 @@ Witamy w przyjaznym i bezpiecznym Bitmessage - The link "%1" will open in a browser. It may be a security risk, it could de-anonymise you or download malicious data. Are you sure? - Odnośnik "%1" zostanie otwarty w przeglądarce. Może to spowodować zagrożenie bezpieczeństwa, może on ujawnić Twoją anonimowość lub pobrać złośliwe dane. Czy jesteś pewien? + The link "{0}" will open in a browser. It may be a security risk, it could de-anonymise you or download malicious data. Are you sure? + Odnośnik "{0}" zostanie otwarty w przeglądarce. Może to spowodować zagrożenie bezpieczeństwa, może on ujawnić Twoją anonimowość lub pobrać złośliwe dane. Czy jesteś pewien? @@ -2008,8 +2008,8 @@ Generowanie adresów „losowych” jest wybrane domyślnie, jednak deterministy - You are using TCP port %1. (This can be changed in the settings). - Btimessage używa portu TCP %1. (Można go zmienić w ustawieniach). + You are using TCP port {0}. (This can be changed in the settings). + Btimessage używa portu TCP {0}. (Można go zmienić w ustawieniach). @@ -2061,28 +2061,28 @@ Generowanie adresów „losowych” jest wybrane domyślnie, jednak deterministy - Since startup on %1 - Od startu programu o %1 + Since startup on {0} + Od startu programu o {0} - Down: %1/s Total: %2 - Pobieranie: %1/s W całości: %2 + Down: {0}/s Total: {1} + Pobieranie: {0}/s W całości: {1} - Up: %1/s Total: %2 - Wysyłanie: %1/s W całości: %2 + Up: {0}/s Total: {1} + Wysyłanie: {0}/s W całości: {1} - Total Connections: %1 - Wszystkich połączeń: %1 + Total Connections: {0} + Wszystkich połączeń: {0} - Inventory lookups per second: %1 - Zapytań o elementy na sekundę: %1 + Inventory lookups per second: {0} + Zapytań o elementy na sekundę: {0} @@ -2247,8 +2247,8 @@ Generowanie adresów „losowych” jest wybrane domyślnie, jednak deterministy newchandialog - Successfully created / joined chan %1 - Pomyślnie utworzono / dołączono do kanału %1 + Successfully created / joined chan {0} + Pomyślnie utworzono / dołączono do kanału {0} diff --git a/src/translations/bitmessage_pt.qm b/src/translations/bitmessage_pt.qm index 9c6b34023dc9c6675307ce3a13886583b2edc05b..6a8aed93eaeb0b4f0b7f9477b1aa934b15cd5110 100644 GIT binary patch delta 470 zcmdm@@mghqO#NvFh71=52L2-qtUW9Y3~b#DtaE^TwtWn&YnCuD@I7Z>TgeQRf5X5Y z=E}ez;LqSb?Fa({V;6+xvSJ9T*u%iUFa<(${$~i!tODv|WaM1%g@J+T1molhfgvM1gZmo#OKtJ})Jz`l~Txgiy3Z!X*2FrXry zgOhm~#p@5TukLvaG%B3Kg6$(v)|6wKh-RDa~B#?0x~Au#@|ZkUG$u4(>M!SwL}Do+}D(m>d%1C ze2aM1W&-&vQ+Qn>JsB7#uVz#fOXNGJFA3Dk#J{`b9RmZ$%uJvknkGNs@!G7zbd5zy z(l@oZI59m{p*S_KL{A|YNGc?jC{!ENPM*Lj!k9PNfIXAHn!$jfmID}W3~WGbHhCGl UF*8)f=J)J{Tr<-g(6Hu(jHp4f)(6t|K`ngSG!kMLAymk z5k|&cpGFwygZa^e`QkK!0;Qn0>?sI*F&aTs5PhF^_aL@G2X=q^o!|eQ^E>x{-*0|Y zGf<_^1N8U-Tu*@QX8^d1z}`j9%>X+-4B%V>Zq$PMGVtAP0A+ii{l+r@>avNpCfIj! z7639P3g00pp9TW*j(5tYpZ;Ivl-@>9tP+*ka7sRSLioV#aGn5U;R1d$6_D#~w~k z1Mnm4`LhJA%iNo8taHrqWBp4wGGros#6;n-iMl;t-NAjt0-tp@+l(FqLiG#e%%ZS8 z6hZ71?!0Qm#$SY?-M`Vmys*6g2kv&uMsl4vK(|dce?z0w_FVZEG=9OJ^Bl!|t0U7= ziMuO~ETv+7)I{e!vHCW0CL{U}c7XAK+O*-2^JTpoTmN!pwGX(_M346qec-0<+$v$;O5^0{~7qQiw2+1x{7KglR8wD)JhB9qSCf}7O!Siw5;MQslJl@`yapY zQel_Ei9XFQOYua^sS-_-m6&Q$a3@KOC?qLqq%|5%;vJEKREE5e%AXC!VC`O#3iO55 zNK!to$qB{mA%x>nq&F_BT6xL&$x2XGqKOoUk%Xd - One of your addresses, %1, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? + One of your addresses, {0}, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? @@ -261,12 +261,12 @@ Please type the desired email address (including @mailchuck.com) below: - Message sent. Waiting for acknowledgement. Sent at %1 - Mensagem enviada. Aguardando confirmação. Enviada a %1 + Message sent. Waiting for acknowledgement. Sent at {0} + Mensagem enviada. Aguardando confirmação. Enviada a {0} - Message sent. Sent at %1 + Message sent. Sent at {0} Mensagem enviada. Enviada a 1% @@ -276,7 +276,7 @@ Please type the desired email address (including @mailchuck.com) below: - Acknowledgement of the message received %1 + Acknowledgement of the message received {0} @@ -286,17 +286,17 @@ Please type the desired email address (including @mailchuck.com) below: - Broadcast on %1 + Broadcast on {0} - Problem: The work demanded by the recipient is more difficult than you are willing to do. %1 + Problem: The work demanded by the recipient is more difficult than you are willing to do. {0} - Problem: The recipient's encryption key is no good. Could not encrypt message. %1 + Problem: The recipient's encryption key is no good. Could not encrypt message. {0} @@ -306,7 +306,7 @@ Please type the desired email address (including @mailchuck.com) below: - Unknown status: %1 %2 + Unknown status: {0} {1} @@ -347,7 +347,7 @@ Please type the desired email address (including @mailchuck.com) below: You may manage your keys by editing the keys.dat file stored in - %1 + {0} It is important that you back up this file. @@ -364,7 +364,7 @@ It is important that you back up this file. You may manage your keys by editing the keys.dat file stored in - %1 + {0} 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.) @@ -430,7 +430,7 @@ It is important that you back up this file. Would you like to open the file now? - Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: %1. This address also appears in 'Your Identities'. + Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: {0}. This address also appears in 'Your Identities'. @@ -498,52 +498,52 @@ It is important that you back up this file. Would you like to open the file now? - The message that you are trying to send is too long by %1 bytes. (The maximum is 261644 bytes). Please cut it down before sending. + The message that you are trying to send is too long by {0} bytes. (The maximum is 261644 bytes). Please cut it down before sending. - Error: Your account wasn't registered at an email gateway. Sending registration now as %1, please wait for the registration to be processed before retrying sending. + Error: Your account wasn't registered at an email gateway. Sending registration now as {0}, please wait for the registration to be processed before retrying sending. - Error: Bitmessage addresses start with BM- Please check %1 + Error: Bitmessage addresses start with BM- Please check {0} - Error: The address %1 is not typed or copied correctly. Please check it. + Error: The address {0} is not typed or copied correctly. Please check it. - Error: The address %1 contains invalid characters. Please check it. + Error: The address {0} contains invalid characters. Please check it. - Error: The address version in %1 is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. + Error: The address version in {0} is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. - Error: Some data encoded in the address %1 is too short. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is too short. There might be something wrong with the software of your acquaintance. - Error: Some data encoded in the address %1 is too long. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is too long. There might be something wrong with the software of your acquaintance. - Error: Some data encoded in the address %1 is malformed. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is malformed. There might be something wrong with the software of your acquaintance. - Error: Something is wrong with the address %1. + Error: Something is wrong with the address {0}. @@ -558,7 +558,7 @@ It is important that you back up this file. Would you like to open the file now? - Concerning the address %1, Bitmessage cannot understand address version numbers of %2. Perhaps upgrade Bitmessage to the latest version. + Concerning the address {0}, Bitmessage cannot understand address version numbers of {1}. Perhaps upgrade Bitmessage to the latest version. @@ -568,7 +568,7 @@ It is important that you back up this file. Would you like to open the file now? - Concerning the address %1, Bitmessage cannot handle stream numbers of %2. Perhaps upgrade Bitmessage to the latest version. + Concerning the address {0}, Bitmessage cannot handle stream numbers of {1}. Perhaps upgrade Bitmessage to the latest version. @@ -703,7 +703,7 @@ It is important that you back up this file. Would you like to open the file now? - Bitmessage cannot find your address %1. Perhaps you removed it? + Bitmessage cannot find your address {0}. Perhaps you removed it? @@ -857,7 +857,7 @@ Are you sure you want to delete the channel? - You are using TCP port %1. (This can be changed in the settings). + You are using TCP port {0}. (This can be changed in the settings). @@ -1052,7 +1052,7 @@ Are you sure you want to delete the channel? - Zoom level %1% + Zoom level {0}% @@ -1067,47 +1067,47 @@ Are you sure you want to delete the channel? - Display the %1 recent broadcast(s) from this address. + Display the {0} recent broadcast(s) from this address. - New version of PyBitmessage is available: %1. Download it from https://github.com/Bitmessage/PyBitmessage/releases/latest + New version of PyBitmessage is available: {0}. Download it from https://github.com/Bitmessage/PyBitmessage/releases/latest - Waiting for PoW to finish... %1% + Waiting for PoW to finish... {0}% - Shutting down Pybitmessage... %1% + Shutting down Pybitmessage... {0}% - Waiting for objects to be sent... %1% + Waiting for objects to be sent... {0}% - Saving settings... %1% + Saving settings... {0}% - Shutting down core... %1% + Shutting down core... {0}% - Stopping notifications... %1% + Stopping notifications... {0}% - Shutdown imminent... %1% + Shutdown imminent... {0}% @@ -1128,7 +1128,7 @@ Are you sure you want to delete the channel? - Shutting down PyBitmessage... %1% + Shutting down PyBitmessage... {0}% @@ -1148,12 +1148,12 @@ Are you sure you want to delete the channel? - Generating %1 new addresses. + Generating {0} new addresses. - %1 is already in 'Your Identities'. Not adding it again. + {0} is already in 'Your Identities'. Not adding it again. @@ -1163,7 +1163,7 @@ Are you sure you want to delete the channel? - SOCKS5 Authentication problem: %1 + SOCKS5 Authentication problem: {0} @@ -1188,7 +1188,7 @@ Are you sure you want to delete the channel? - Broadcast sent on %1 + Broadcast sent on {0} @@ -1208,7 +1208,7 @@ Are you sure you want to delete the channel? - Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. %1 + Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. {0} @@ -1220,17 +1220,17 @@ There is no required difficulty for version 2 addresses like this. Doing work necessary to send message. -Receiver's required difficulty: %1 and %2 +Receiver's required difficulty: {0} and {1} - Problem: The work demanded by the recipient (%1 and %2) is more difficult than you are willing to do. %3 + Problem: The work demanded by the recipient ({0} and {1}) is more difficult than you are willing to do. {2} - Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. %1 + Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. {0} @@ -1240,7 +1240,7 @@ Receiver's required difficulty: %1 and %2 - Message sent. Waiting for acknowledgement. Sent on %1 + Message sent. Waiting for acknowledgement. Sent on {0} @@ -1255,12 +1255,12 @@ Receiver's required difficulty: %1 and %2 - Sending public key request. Waiting for reply. Requested at %1 + Sending public key request. Waiting for reply. Requested at {0} - UPnP port mapping established on port %1 + UPnP port mapping established on port {0} @@ -1622,27 +1622,27 @@ The 'Random Number' option is selected by default but deterministic ad - Since startup on %1 + Since startup on {0} - Down: %1/s Total: %2 + Down: {0}/s Total: {1} - Up: %1/s Total: %2 + Up: {0}/s Total: {1} - Total Connections: %1 + Total Connections: {0} - Inventory lookups per second: %1 + Inventory lookups per second: {0} diff --git a/src/translations/bitmessage_ru.qm b/src/translations/bitmessage_ru.qm index 8c0269b9e18ecc2f219729d227bb411c4f72f23e..2642035b4cc8479c6b87d7ac4bdd4b231f0342da 100644 GIT binary patch delta 6265 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 delta 6032 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 diff --git a/src/translations/bitmessage_ru.ts b/src/translations/bitmessage_ru.ts index 4a80f62e..0fac3766 100644 --- a/src/translations/bitmessage_ru.ts +++ b/src/translations/bitmessage_ru.ts @@ -314,8 +314,8 @@ Please type the desired email address (including @mailchuck.com) below: - One of your addresses, %1, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? - Один из Ваших адресов, %1, является устаревшим адресом версии 1. Адреса версии 1 больше не поддерживаются. Хотите ли Вы удалить его сейчас? + One of your addresses, {0}, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? + Один из Ваших адресов, {0}, является устаревшим адресом версии 1. Адреса версии 1 больше не поддерживаются. Хотите ли Вы удалить его сейчас? @@ -334,13 +334,13 @@ Please type the desired email address (including @mailchuck.com) below: - Message sent. Waiting for acknowledgement. Sent at %1 - Сообщение отправлено. Ожидаем подтверждения. Отправлено в %1 + Message sent. Waiting for acknowledgement. Sent at {0} + Сообщение отправлено. Ожидаем подтверждения. Отправлено в {0} - Message sent. Sent at %1 - Сообщение отправлено в %1 + Message sent. Sent at {0} + Сообщение отправлено в {0} @@ -349,8 +349,8 @@ Please type the desired email address (including @mailchuck.com) below: - Acknowledgement of the message received %1 - Доставлено в %1 + Acknowledgement of the message received {0} + Доставлено в {0} @@ -359,18 +359,18 @@ Please type the desired email address (including @mailchuck.com) below: - Broadcast on %1 - Рассылка на %1 + Broadcast on {0} + Рассылка на {0} - Problem: The work demanded by the recipient is more difficult than you are willing to do. %1 - Проблема: Ваш получатель требует более сложных вычислений, чем максимум, указанный в Ваших настройках. %1 + Problem: The work demanded by the recipient is more difficult than you are willing to do. {0} + Проблема: Ваш получатель требует более сложных вычислений, чем максимум, указанный в Ваших настройках. {0} - Problem: The recipient's encryption key is no good. Could not encrypt message. %1 - Проблема: ключ получателя неправильный. Невозможно зашифровать сообщение. %1 + Problem: The recipient's encryption key is no good. Could not encrypt message. {0} + Проблема: ключ получателя неправильный. Невозможно зашифровать сообщение. {0} @@ -379,8 +379,8 @@ Please type the desired email address (including @mailchuck.com) below: - Unknown status: %1 %2 - Неизвестный статус: %1 %2 + Unknown status: {0} {1} + Неизвестный статус: {0} {1} @@ -421,10 +421,10 @@ Please type the desired email address (including @mailchuck.com) below: You may manage your keys by editing the keys.dat file stored in - %1 + {0} It is important that you back up this file. Вы можете управлять Вашими ключами, редактируя файл keys.dat, находящийся в - %1 + {0} Создайте резервную копию этого файла перед тем как будете его редактировать. @@ -442,7 +442,7 @@ It is important that you back up this file. You may manage your keys by editing the keys.dat file stored in - %1 + {0} 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.) @@ -508,7 +508,7 @@ It is important that you back up this file. Would you like to open the file now? - Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: %1. This address also appears in 'Your Identities'. + Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: {0}. This address also appears in 'Your Identities'. @@ -579,52 +579,52 @@ It is important that you back up this file. Would you like to open the file now? - The message that you are trying to send is too long by %1 bytes. (The maximum is 261644 bytes). Please cut it down before sending. - Сообщение, которое вы пытаетесь отправить, длиннее максимально допустимого на %1 байт. (Максимально допустимое значение 261644 байта). Пожалуйста, сократите сообщение перед отправкой. + The message that you are trying to send is too long by {0} bytes. (The maximum is 261644 bytes). Please cut it down before sending. + Сообщение, которое вы пытаетесь отправить, длиннее максимально допустимого на {0} байт. (Максимально допустимое значение 261644 байта). Пожалуйста, сократите сообщение перед отправкой. - Error: Your account wasn't registered at an email gateway. Sending registration now as %1, please wait for the registration to be processed before retrying sending. - Ошибка: ваш аккаунт не зарегистрирован на Email-шлюзе. Отправка регистрации %1, пожалуйста, подождите пока процесс регистрации не завершится, прежде чем попытаться отправить сообщение заново. + Error: Your account wasn't registered at an email gateway. Sending registration now as {0}, please wait for the registration to be processed before retrying sending. + Ошибка: ваш аккаунт не зарегистрирован на Email-шлюзе. Отправка регистрации {0}, пожалуйста, подождите пока процесс регистрации не завершится, прежде чем попытаться отправить сообщение заново. - Error: Bitmessage addresses start with BM- Please check %1 + Error: Bitmessage addresses start with BM- Please check {0} - Error: The address %1 is not typed or copied correctly. Please check it. + Error: The address {0} is not typed or copied correctly. Please check it. - Error: The address %1 contains invalid characters. Please check it. + Error: The address {0} contains invalid characters. Please check it. - Error: The address version in %1 is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. + Error: The address version in {0} is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. - Error: Some data encoded in the address %1 is too short. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is too short. There might be something wrong with the software of your acquaintance. - Error: Some data encoded in the address %1 is too long. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is too long. There might be something wrong with the software of your acquaintance. - Error: Some data encoded in the address %1 is malformed. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is malformed. There might be something wrong with the software of your acquaintance. - Error: Something is wrong with the address %1. + Error: Something is wrong with the address {0}. @@ -639,8 +639,8 @@ It is important that you back up this file. Would you like to open the file now? - Concerning the address %1, Bitmessage cannot understand address version numbers of %2. Perhaps upgrade Bitmessage to the latest version. - По поводу адреса %1: Bitmessage не поддерживает адреса версии %2. Возможно вам нужно обновить клиент Bitmessage. + Concerning the address {0}, Bitmessage cannot understand address version numbers of {1}. Perhaps upgrade Bitmessage to the latest version. + По поводу адреса {0}: Bitmessage не поддерживает адреса версии {1}. Возможно вам нужно обновить клиент Bitmessage. @@ -649,8 +649,8 @@ It is important that you back up this file. Would you like to open the file now? - Concerning the address %1, Bitmessage cannot handle stream numbers of %2. Perhaps upgrade Bitmessage to the latest version. - По поводу адреса %1: Bitmessage не поддерживает поток номер %2. Возможно вам нужно обновить клиент Bitmessage. + Concerning the address {0}, Bitmessage cannot handle stream numbers of {1}. Perhaps upgrade Bitmessage to the latest version. + По поводу адреса {0}: Bitmessage не поддерживает поток номер {1}. Возможно вам нужно обновить клиент Bitmessage. @@ -784,8 +784,8 @@ It is important that you back up this file. Would you like to open the file now? - Bitmessage cannot find your address %1. Perhaps you removed it? - Bitmessage не может найти Ваш адрес %1. Возможно Вы удалили его? + Bitmessage cannot find your address {0}. Perhaps you removed it? + Bitmessage не может найти Ваш адрес {0}. Возможно Вы удалили его? @@ -942,7 +942,7 @@ Are you sure you want to delete the channel? - You are using TCP port %1. (This can be changed in the settings). + You are using TCP port {0}. (This can be changed in the settings). @@ -1137,8 +1137,8 @@ Are you sure you want to delete the channel? - Zoom level %1% - Увеличение %1% + Zoom level {0}% + Увеличение {0}% @@ -1152,48 +1152,48 @@ Are you sure you want to delete the channel? - Display the %1 recent broadcast(s) from this address. + Display the {0} recent broadcast(s) from this address. - New version of PyBitmessage is available: %1. Download it from https://github.com/Bitmessage/PyBitmessage/releases/latest - Доступна новая версия PyBitmessage: %1. Загрузите её: https://github.com/Bitmessage/PyBitmessage/releases/latest + New version of PyBitmessage is available: {0}. Download it from https://github.com/Bitmessage/PyBitmessage/releases/latest + Доступна новая версия PyBitmessage: {0}. Загрузите её: https://github.com/Bitmessage/PyBitmessage/releases/latest - Waiting for PoW to finish... %1% - Ожидание окончания PoW... %1% + Waiting for PoW to finish... {0}% + Ожидание окончания PoW... {0}% - Shutting down Pybitmessage... %1% - Завершение PyBitmessage... %1% + Shutting down Pybitmessage... {0}% + Завершение PyBitmessage... {0}% - Waiting for objects to be sent... %1% - Ожидание отправки объектов... %1% + Waiting for objects to be sent... {0}% + Ожидание отправки объектов... {0}% - Saving settings... %1% - Сохранение настроек... %1% + Saving settings... {0}% + Сохранение настроек... {0}% - Shutting down core... %1% - Завершение работы ядра... %1% + Shutting down core... {0}% + Завершение работы ядра... {0}% - Stopping notifications... %1% - Остановка сервиса уведомлений... %1% + Stopping notifications... {0}% + Остановка сервиса уведомлений... {0}% - Shutdown imminent... %1% - Завершение вот-вот произойдет... %1% + Shutdown imminent... {0}% + Завершение вот-вот произойдет... {0}% @@ -1207,8 +1207,8 @@ Are you sure you want to delete the channel? - Shutting down PyBitmessage... %1% - Завершение PyBitmessage... %1% + Shutting down PyBitmessage... {0}% + Завершение PyBitmessage... {0}% @@ -1227,13 +1227,13 @@ Are you sure you want to delete the channel? - Generating %1 new addresses. - Создание %1 новых адресов. + Generating {0} new addresses. + Создание {0} новых адресов. - %1 is already in 'Your Identities'. Not adding it again. - %1 уже имеется в ваших адресах. Не добавляю его снова. + {0} is already in 'Your Identities'. Not adding it again. + {0} уже имеется в ваших адресах. Не добавляю его снова. @@ -1242,7 +1242,7 @@ Are you sure you want to delete the channel? - SOCKS5 Authentication problem: %1 + SOCKS5 Authentication problem: {0} @@ -1267,8 +1267,8 @@ Are you sure you want to delete the channel? - Broadcast sent on %1 - Рассылка отправлена на %1 + Broadcast sent on {0} + Рассылка отправлена на {0} @@ -1287,8 +1287,8 @@ Are you sure you want to delete the channel? - Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. %1 - Проблема: адресат является мобильным устройством, которое требует, чтобы адрес назначения был включен в сообщение, однако, это запрещено в ваших настройках. %1 + Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. {0} + Проблема: адресат является мобильным устройством, которое требует, чтобы адрес назначения был включен в сообщение, однако, это запрещено в ваших настройках. {0} @@ -1300,19 +1300,19 @@ There is no required difficulty for version 2 addresses like this. Doing work necessary to send message. -Receiver's required difficulty: %1 and %2 +Receiver's required difficulty: {0} and {1} Выполнение работы, требуемой для отправки сообщения. -Получатель запросил сложность: %1 и %2 +Получатель запросил сложность: {0} и {1} - Problem: The work demanded by the recipient (%1 and %2) is more difficult than you are willing to do. %3 - Проблема: сложность, затребованная получателем (%1 и %2) гораздо больше, чем вы готовы сделать. %3 + Problem: The work demanded by the recipient ({0} and {1}) is more difficult than you are willing to do. {2} + Проблема: сложность, затребованная получателем ({0} и {1}) гораздо больше, чем вы готовы сделать. {2} - Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. %1 - Проблема: вы пытаетесь отправить сообщение самому себе или в чан, но ваш ключ шифрования не найден в файле ключей keys.dat. Невозможно зашифровать сообщение. %1 + Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. {0} + Проблема: вы пытаетесь отправить сообщение самому себе или в чан, но ваш ключ шифрования не найден в файле ключей keys.dat. Невозможно зашифровать сообщение. {0} @@ -1321,8 +1321,8 @@ Receiver's required difficulty: %1 and %2 - Message sent. Waiting for acknowledgement. Sent on %1 - Отправлено. Ожидаем подтверждения. Отправлено в %1 + Message sent. Waiting for acknowledgement. Sent on {0} + Отправлено. Ожидаем подтверждения. Отправлено в {0} @@ -1336,13 +1336,13 @@ Receiver's required difficulty: %1 and %2 - Sending public key request. Waiting for reply. Requested at %1 - Отправка запроса открытого ключа шифрования. Ожидание ответа. Запрошено в %1 + Sending public key request. Waiting for reply. Requested at {0} + Отправка запроса открытого ключа шифрования. Ожидание ответа. Запрошено в {0} - UPnP port mapping established on port %1 - Распределение портов UPnP завершилось выделением порта %1 + UPnP port mapping established on port {0} + Распределение портов UPnP завершилось выделением порта {0} @@ -1386,13 +1386,13 @@ Receiver's required difficulty: %1 and %2 - The name %1 was not found. - Имя %1 не найдено. + The name {0} was not found. + Имя {0} не найдено. - The namecoin query failed (%1) - Запрос к namecoin не удался (%1). + The namecoin query failed ({0}) + Запрос к namecoin не удался ({0}). @@ -1401,18 +1401,18 @@ Receiver's required difficulty: %1 and %2 - The name %1 has no valid JSON data. - Имя %1 не содержит корректных данных JSON. + The name {0} has no valid JSON data. + Имя {0} не содержит корректных данных JSON. - The name %1 has no associated Bitmessage address. - Имя %1 не имеет связанного адреса Bitmessage. + The name {0} has no associated Bitmessage address. + Имя {0} не имеет связанного адреса Bitmessage. - Success! Namecoind version %1 running. - Успех! Namecoind версии %1 работает. + Success! Namecoind version {0} running. + Успех! Namecoind версии {0} работает. @@ -1475,53 +1475,53 @@ Receiver's required difficulty: %1 and %2 - Error: Bitmessage addresses start with BM- Please check the recipient address %1 - Ошибка: адреса Bitmessage начинаются с "BM-". Пожалуйста, проверьте адрес получателя %1. + Error: Bitmessage addresses start with BM- Please check the recipient address {0} + Ошибка: адреса Bitmessage начинаются с "BM-". Пожалуйста, проверьте адрес получателя {0}. - Error: The recipient address %1 is not typed or copied correctly. Please check it. - Ошибка: адрес получателя %1 набран или скопирован неправильно. Пожалуйста, проверьте его. + Error: The recipient address {0} is not typed or copied correctly. Please check it. + Ошибка: адрес получателя {0} набран или скопирован неправильно. Пожалуйста, проверьте его. - Error: The recipient address %1 contains invalid characters. Please check it. - Ошибка: адрес получателя %1 содержит недопустимые символы. Пожалуйста, проверьте его. + Error: The recipient address {0} contains invalid characters. Please check it. + Ошибка: адрес получателя {0} содержит недопустимые символы. Пожалуйста, проверьте его. - Error: The version of the recipient address %1 is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. - Ошибка: версия адреса получателя %1 слишком высокая. Либо вам нужно обновить программу Bitmessage, либо ваш знакомый - умник. + Error: The version of the recipient address {0} is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. + Ошибка: версия адреса получателя {0} слишком высокая. Либо вам нужно обновить программу Bitmessage, либо ваш знакомый - умник. - Error: Some data encoded in the recipient address %1 is too short. There might be something wrong with the software of your acquaintance. - Ошибка: часть данных, закодированных в адресе получателя %1 слишком короткая. Видимо, что-то не так с программой, используемой вашим знакомым. + Error: Some data encoded in the recipient address {0} is too short. There might be something wrong with the software of your acquaintance. + Ошибка: часть данных, закодированных в адресе получателя {0} слишком короткая. Видимо, что-то не так с программой, используемой вашим знакомым. - Error: Some data encoded in the recipient address %1 is too long. There might be something wrong with the software of your acquaintance. - Ошибка: часть данных, закодированных в адресе получателя %1 слишком длинная. Видимо, что-то не так с программой, используемой вашим знакомым. + Error: Some data encoded in the recipient address {0} is too long. There might be something wrong with the software of your acquaintance. + Ошибка: часть данных, закодированных в адресе получателя {0} слишком длинная. Видимо, что-то не так с программой, используемой вашим знакомым. - Error: Some data encoded in the recipient address %1 is malformed. There might be something wrong with the software of your acquaintance. - Ошибка: часть данных, закодированных в адресе получателя %1 сформирована неправильно. Видимо, что-то не так с программой, используемой вашим знакомым. + Error: Some data encoded in the recipient address {0} is malformed. There might be something wrong with the software of your acquaintance. + Ошибка: часть данных, закодированных в адресе получателя {0} сформирована неправильно. Видимо, что-то не так с программой, используемой вашим знакомым. - Error: Something is wrong with the recipient address %1. - Ошибка: что-то не так с адресом получателя %1. + Error: Something is wrong with the recipient address {0}. + Ошибка: что-то не так с адресом получателя {0}. - Error: %1 - Ошибка: %1 + Error: {0} + Ошибка: {0} - From %1 - От %1 + From {0} + От {0} @@ -1566,7 +1566,7 @@ Receiver's required difficulty: %1 and %2 Display the %n recent broadcast(s) from this address. - Показать %1 прошлую рассылку с этого адреса.Показать %1 прошлых рассылки с этого адреса.Показать %1 прошлых рассылок с этого адреса.Показать %1 прошлых рассылок с этого адреса. + Показать {0} прошлую рассылку с этого адреса.Показать {0} прошлых рассылки с этого адреса.Показать {0} прошлых рассылок с этого адреса.Показать {0} прошлых рассылок с этого адреса. @@ -1613,8 +1613,8 @@ Receiver's required difficulty: %1 and %2 - The link "%1" will open in a browser. It may be a security risk, it could de-anonymise you or download malicious data. Are you sure? - Ссылка "%1" откроется в браузере. Это может быть угрозой безопасности, например деанонимизировать вас или привести к скачиванию вредоносных данных. Вы уверены? + The link "{0}" will open in a browser. It may be a security risk, it could de-anonymise you or download malicious data. Are you sure? + Ссылка "{0}" откроется в браузере. Это может быть угрозой безопасности, например деанонимизировать вас или привести к скачиванию вредоносных данных. Вы уверены? @@ -1948,8 +1948,8 @@ The 'Random Number' option is selected by default but deterministic ad - You are using TCP port %1. (This can be changed in the settings). - Вы используете TCP порт %1. (Его можно поменять в настройках). + You are using TCP port {0}. (This can be changed in the settings). + Вы используете TCP порт {0}. (Его можно поменять в настройках). @@ -2001,28 +2001,28 @@ The 'Random Number' option is selected by default but deterministic ad - Since startup on %1 - С начала работы, %1 + Since startup on {0} + С начала работы, {0} - Down: %1/s Total: %2 - Загрузка: %1/s Всего: %2 + Down: {0}/s Total: {1} + Загрузка: {0}/s Всего: {1} - Up: %1/s Total: %2 - Отправка: %1/s Всего: %2 + Up: {0}/s Total: {1} + Отправка: {0}/s Всего: {1} - Total Connections: %1 - Всего соединений: %1 + Total Connections: {0} + Всего соединений: {0} - Inventory lookups per second: %1 - Поисков в каталоге в секунду: %1 + Inventory lookups per second: {0} + Поисков в каталоге в секунду: {0} @@ -2187,8 +2187,8 @@ The 'Random Number' option is selected by default but deterministic ad newchandialog - Successfully created / joined chan %1 - Успешно создан / подключен чан %1 + Successfully created / joined chan {0} + Успешно создан / подключен чан {0} diff --git a/src/translations/bitmessage_sk.qm b/src/translations/bitmessage_sk.qm index 26c2a24d6b127a7fe5aa2c47d03ac662cf8029e2..b963125f798ab3d9448975f2efdda7f03767b943 100644 GIT binary patch delta 6331 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 - One of your addresses, %1, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? - Jedna z vašich adries, %1, je stará verzia adresy, 1. Verzie adresy 1 už nie sú podporované. Odstrániť ju teraz? + One of your addresses, {0}, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? + Jedna z vašich adries, {0}, je stará verzia adresy, 1. Verzie adresy 1 už nie sú podporované. Odstrániť ju teraz? @@ -331,13 +331,13 @@ Please type the desired email address (including @mailchuck.com) below: - Message sent. Waiting for acknowledgement. Sent at %1 - Správa odoslaná. Čakanie na potvrdenie. Odoslaná %1 + Message sent. Waiting for acknowledgement. Sent at {0} + Správa odoslaná. Čakanie na potvrdenie. Odoslaná {0} - Message sent. Sent at %1 - Správa odoslaná. Odoslaná %1 + Message sent. Sent at {0} + Správa odoslaná. Odoslaná {0} @@ -346,8 +346,8 @@ Please type the desired email address (including @mailchuck.com) below: - Acknowledgement of the message received %1 - Potvrdenie prijatia správy %1 + Acknowledgement of the message received {0} + Potvrdenie prijatia správy {0} @@ -356,18 +356,18 @@ Please type the desired email address (including @mailchuck.com) below: - Broadcast on %1 + Broadcast on {0} Rozoslané 1% - Problem: The work demanded by the recipient is more difficult than you are willing to do. %1 - Problém: práca požadovná príjemcom je oveľa ťažšia, než je povolené v nastaveniach. %1 + Problem: The work demanded by the recipient is more difficult than you are willing to do. {0} + Problém: práca požadovná príjemcom je oveľa ťažšia, než je povolené v nastaveniach. {0} - Problem: The recipient's encryption key is no good. Could not encrypt message. %1 - Problém: šifrovací kľúč príjemcu je nesprávny. Nie je možné zašifrovať správu. %1 + Problem: The recipient's encryption key is no good. Could not encrypt message. {0} + Problém: šifrovací kľúč príjemcu je nesprávny. Nie je možné zašifrovať správu. {0} @@ -376,8 +376,8 @@ Please type the desired email address (including @mailchuck.com) below: - Unknown status: %1 %2 - Neznámy stav: %1 %2 + Unknown status: {0} {1} + Neznámy stav: {0} {1} @@ -417,10 +417,10 @@ Please type the desired email address (including @mailchuck.com) below: You may manage your keys by editing the keys.dat file stored in - %1 + {0} It is important that you back up this file. Kľúče môžete spravovať úpravou súboru keys.dat, ktorý je uložený v adresári -%1 +{0} Tento súbor je dôležité zálohovať. @@ -436,10 +436,10 @@ Tento súbor je dôležité zálohovať. You may manage your keys by editing the keys.dat file stored in - %1 + {0} 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.) Kľúče môžete spravovať úpravou súboru keys.dat, ktorý je uložený v adresári -%1 +{0} Tento súbor je dôležité zálohovať. Chcete tento súbor teraz otvoriť? (Nezabudnite zatvoriť Bitmessage pred vykonaním akýchkoľvek zmien.) @@ -504,7 +504,7 @@ Tento súbor je dôležité zálohovať. Chcete tento súbor teraz otvoriť? (Ne - Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: %1. This address also appears in 'Your Identities'. + Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: {0}. This address also appears in 'Your Identities'. @@ -572,52 +572,52 @@ Tento súbor je dôležité zálohovať. Chcete tento súbor teraz otvoriť? (Ne - The message that you are trying to send is too long by %1 bytes. (The maximum is 261644 bytes). Please cut it down before sending. - Správa, ktorú skúšate poslať, má %1 bajtov naviac. (Maximum je 261 644 bajtov). Prosím pred odoslaním skrátiť. + The message that you are trying to send is too long by {0} bytes. (The maximum is 261644 bytes). Please cut it down before sending. + Správa, ktorú skúšate poslať, má {0} bajtov naviac. (Maximum je 261 644 bajtov). Prosím pred odoslaním skrátiť. - Error: Your account wasn't registered at an email gateway. Sending registration now as %1, please wait for the registration to be processed before retrying sending. - Chyba: Váš účet nebol registrovaný na e-mailovej bráne. Skúšam registrovať ako %1, prosím počkajte na spracovanie registrácie pred opakovaným odoslaním správy. + Error: Your account wasn't registered at an email gateway. Sending registration now as {0}, please wait for the registration to be processed before retrying sending. + Chyba: Váš účet nebol registrovaný na e-mailovej bráne. Skúšam registrovať ako {0}, prosím počkajte na spracovanie registrácie pred opakovaným odoslaním správy. - Error: Bitmessage addresses start with BM- Please check %1 + Error: Bitmessage addresses start with BM- Please check {0} - Error: The address %1 is not typed or copied correctly. Please check it. + Error: The address {0} is not typed or copied correctly. Please check it. - Error: The address %1 contains invalid characters. Please check it. + Error: The address {0} contains invalid characters. Please check it. - Error: The address version in %1 is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. + Error: The address version in {0} is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. - Error: Some data encoded in the address %1 is too short. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is too short. There might be something wrong with the software of your acquaintance. - Error: Some data encoded in the address %1 is too long. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is too long. There might be something wrong with the software of your acquaintance. - Error: Some data encoded in the address %1 is malformed. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is malformed. There might be something wrong with the software of your acquaintance. - Error: Something is wrong with the address %1. + Error: Something is wrong with the address {0}. @@ -632,8 +632,8 @@ Tento súbor je dôležité zálohovať. Chcete tento súbor teraz otvoriť? (Ne - Concerning the address %1, Bitmessage cannot understand address version numbers of %2. Perhaps upgrade Bitmessage to the latest version. - Čo sa týka adresy %1, Bitmessage nepozná číslo verzie adresy %2. Možno by ste mali upgradenúť Bitmessage na najnovšiu verziu. + Concerning the address {0}, Bitmessage cannot understand address version numbers of {1}. Perhaps upgrade Bitmessage to the latest version. + Čo sa týka adresy {0}, Bitmessage nepozná číslo verzie adresy {1}. Možno by ste mali upgradenúť Bitmessage na najnovšiu verziu. @@ -642,8 +642,8 @@ Tento súbor je dôležité zálohovať. Chcete tento súbor teraz otvoriť? (Ne - Concerning the address %1, Bitmessage cannot handle stream numbers of %2. Perhaps upgrade Bitmessage to the latest version. - Čo sa týka adresy %1, Bitmessage nespracováva číslo prúdu %2. Možno by ste mali upgradenúť Bitmessage na najnovšiu verziu. + Concerning the address {0}, Bitmessage cannot handle stream numbers of {1}. Perhaps upgrade Bitmessage to the latest version. + Čo sa týka adresy {0}, Bitmessage nespracováva číslo prúdu {1}. Možno by ste mali upgradenúť Bitmessage na najnovšiu verziu. @@ -777,8 +777,8 @@ Tento súbor je dôležité zálohovať. Chcete tento súbor teraz otvoriť? (Ne - Bitmessage cannot find your address %1. Perhaps you removed it? - Bitmessage nemôže nájsť vašu adresu %1. Možno ste ju odstránili? + Bitmessage cannot find your address {0}. Perhaps you removed it? + Bitmessage nemôže nájsť vašu adresu {0}. Možno ste ju odstránili? @@ -935,7 +935,7 @@ Ste si istý, že chcete kanál odstrániť? - You are using TCP port %1. (This can be changed in the settings). + You are using TCP port {0}. (This can be changed in the settings). @@ -1130,8 +1130,8 @@ Ste si istý, že chcete kanál odstrániť? - Zoom level %1% - Úroveň priblíženia %1% + Zoom level {0}% + Úroveň priblíženia {0}% @@ -1145,48 +1145,48 @@ Ste si istý, že chcete kanál odstrániť? - Display the %1 recent broadcast(s) from this address. + Display the {0} recent broadcast(s) from this address. - New version of PyBitmessage is available: %1. Download it from https://github.com/Bitmessage/PyBitmessage/releases/latest - K dispozícii je nová verzia PyBitmessage: %1. Môžete ju stiahnuť na https://github.com/Bitmessage/PyBitmessage/releases/latest + New version of PyBitmessage is available: {0}. Download it from https://github.com/Bitmessage/PyBitmessage/releases/latest + K dispozícii je nová verzia PyBitmessage: {0}. Môžete ju stiahnuť na https://github.com/Bitmessage/PyBitmessage/releases/latest - Waiting for PoW to finish... %1% - Čakám na ukončenie práce... %1% + Waiting for PoW to finish... {0}% + Čakám na ukončenie práce... {0}% - Shutting down Pybitmessage... %1% - Ukončujem PyBitmessage... %1% + Shutting down Pybitmessage... {0}% + Ukončujem PyBitmessage... {0}% - Waiting for objects to be sent... %1% - Čakám na odoslanie objektov... %1% + Waiting for objects to be sent... {0}% + Čakám na odoslanie objektov... {0}% - Saving settings... %1% - Ukladám nastavenia... %1% + Saving settings... {0}% + Ukladám nastavenia... {0}% - Shutting down core... %1% - Ukončujem jadro... %1% + Shutting down core... {0}% + Ukončujem jadro... {0}% - Stopping notifications... %1% - Zastavujem oznámenia... %1% + Stopping notifications... {0}% + Zastavujem oznámenia... {0}% - Shutdown imminent... %1% - Posledná fáza ukončenia... %1% + Shutdown imminent... {0}% + Posledná fáza ukončenia... {0}% @@ -1200,8 +1200,8 @@ Ste si istý, že chcete kanál odstrániť? - Shutting down PyBitmessage... %1% - Ukončujem PyBitmessage... %1% + Shutting down PyBitmessage... {0}% + Ukončujem PyBitmessage... {0}% @@ -1220,13 +1220,13 @@ Ste si istý, že chcete kanál odstrániť? - Generating %1 new addresses. - Vytváram %1 nových adries. + Generating {0} new addresses. + Vytváram {0} nových adries. - %1 is already in 'Your Identities'. Not adding it again. - %1 sa už nachádza medzi vášmi identitami, nepridávam dvojmo. + {0} is already in 'Your Identities'. Not adding it again. + {0} sa už nachádza medzi vášmi identitami, nepridávam dvojmo. @@ -1235,7 +1235,7 @@ Ste si istý, že chcete kanál odstrániť? - SOCKS5 Authentication problem: %1 + SOCKS5 Authentication problem: {0} @@ -1260,8 +1260,8 @@ Ste si istý, že chcete kanál odstrániť? - Broadcast sent on %1 - Rozoslané %1 + Broadcast sent on {0} + Rozoslané {0} @@ -1280,8 +1280,8 @@ Ste si istý, že chcete kanál odstrániť? - Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. %1 - Problém: adresa príjemcu je na mobilnom zariadení a požaduje, aby správy obsahovali nezašifrovanú adresu príjemcu. Vaše nastavenia však túto možnost nemajú povolenú. %1 + Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. {0} + Problém: adresa príjemcu je na mobilnom zariadení a požaduje, aby správy obsahovali nezašifrovanú adresu príjemcu. Vaše nastavenia však túto možnost nemajú povolenú. {0} @@ -1293,19 +1293,19 @@ Adresy verzie dva, ako táto, nepožadujú obtiažnosť. Doing work necessary to send message. -Receiver's required difficulty: %1 and %2 +Receiver's required difficulty: {0} and {1} Vykonávam prácu potrebnú na odoslanie správy. -Priímcova požadovaná obtiažnosť: %1 a %2 +Priímcova požadovaná obtiažnosť: {0} a {1} - Problem: The work demanded by the recipient (%1 and %2) is more difficult than you are willing to do. %3 - Problém: Práca požadovná príjemcom (%1 a %2) je obtiažnejšia, ako máte povolené. %3 + Problem: The work demanded by the recipient ({0} and {1}) is more difficult than you are willing to do. {2} + Problém: Práca požadovná príjemcom ({0} a {1}) je obtiažnejšia, ako máte povolené. {2} - Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. %1 - Problém: skúšate odslať správu sami sebe, ale nemôžem nájsť šifrovací kľúč v súbore keys.dat. Nemožno správu zašifrovať: %1 + Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. {0} + Problém: skúšate odslať správu sami sebe, ale nemôžem nájsť šifrovací kľúč v súbore keys.dat. Nemožno správu zašifrovať: {0} @@ -1314,8 +1314,8 @@ Priímcova požadovaná obtiažnosť: %1 a %2 - Message sent. Waiting for acknowledgement. Sent on %1 - Správa odoslaná. Čakanie na potvrdenie. Odoslaná %1 + Message sent. Waiting for acknowledgement. Sent on {0} + Správa odoslaná. Čakanie na potvrdenie. Odoslaná {0} @@ -1329,13 +1329,13 @@ Priímcova požadovaná obtiažnosť: %1 a %2 - Sending public key request. Waiting for reply. Requested at %1 - Odosielam požiadavku na verejný kľúč. Čakám na odpoveď. Vyžiadaný %1 + Sending public key request. Waiting for reply. Requested at {0} + Odosielam požiadavku na verejný kľúč. Čakám na odpoveď. Vyžiadaný {0} - UPnP port mapping established on port %1 - Mapovanie portov UPnP vytvorené na porte %1 + UPnP port mapping established on port {0} + Mapovanie portov UPnP vytvorené na porte {0} @@ -1379,28 +1379,28 @@ Priímcova požadovaná obtiažnosť: %1 a %2 - Problem communicating with proxy: %1. Please check your network settings. - Problém komunikácie s proxy: %1. Prosím skontrolujte nastavenia siete. + Problem communicating with proxy: {0}. Please check your network settings. + Problém komunikácie s proxy: {0}. Prosím skontrolujte nastavenia siete. - SOCKS5 Authentication problem: %1. Please check your SOCKS5 settings. - Problém autentikácie SOCKS5: %1. Prosím skontrolujte nastavenia SOCKS5. + SOCKS5 Authentication problem: {0}. Please check your SOCKS5 settings. + Problém autentikácie SOCKS5: {0}. Prosím skontrolujte nastavenia SOCKS5. - The time on your computer, %1, may be wrong. Please verify your settings. - Čas na vašom počítači, %1, možno nie je správny. Prosím, skontrolujete nastavenia. + The time on your computer, {0}, may be wrong. Please verify your settings. + Čas na vašom počítači, {0}, možno nie je správny. Prosím, skontrolujete nastavenia. - The name %1 was not found. + The name {0} was not found. Meno % nenájdené. - The namecoin query failed (%1) - Dotaz prostredníctvom namecoinu zlyhal (%1) + The namecoin query failed ({0}) + Dotaz prostredníctvom namecoinu zlyhal ({0}) @@ -1409,18 +1409,18 @@ Priímcova požadovaná obtiažnosť: %1 a %2 - The name %1 has no valid JSON data. - Meno %1 neobsahuje planté JSON dáta. + The name {0} has no valid JSON data. + Meno {0} neobsahuje planté JSON dáta. - The name %1 has no associated Bitmessage address. - Meno %1 nemá priradenú žiadnu adresu Bitmessage. + The name {0} has no associated Bitmessage address. + Meno {0} nemá priradenú žiadnu adresu Bitmessage. - Success! Namecoind version %1 running. - Úspech! Namecoind verzia %1 spustený. + Success! Namecoind version {0} running. + Úspech! Namecoind verzia {0} spustený. @@ -1479,53 +1479,53 @@ Vitajte v jednoduchom a bezpečnom Bitmessage - Error: Bitmessage addresses start with BM- Please check the recipient address %1 - Chyba: Bitmessage adresy začínajú s BM- Prosím skontrolujte adresu príjemcu %1 + Error: Bitmessage addresses start with BM- Please check the recipient address {0} + Chyba: Bitmessage adresy začínajú s BM- Prosím skontrolujte adresu príjemcu {0} - Error: The recipient address %1 is not typed or copied correctly. Please check it. - Chyba: adresa príjemcu %1 nie je na správne napísaná alebo skopírovaná. Prosím skontrolujte ju. + Error: The recipient address {0} is not typed or copied correctly. Please check it. + Chyba: adresa príjemcu {0} nie je na správne napísaná alebo skopírovaná. Prosím skontrolujte ju. - Error: The recipient address %1 contains invalid characters. Please check it. - Chyba: adresa príjemcu %1 obsahuje neplatné znaky. Prosím skontrolujte ju. + Error: The recipient address {0} contains invalid characters. Please check it. + Chyba: adresa príjemcu {0} obsahuje neplatné znaky. Prosím skontrolujte ju. - Error: The version of the recipient address %1 is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. - Chyba: verzia adresy príjemcu %1 je príliš veľká. Buď musíte aktualizovať program Bitmessage alebo váš známy s vami žartuje. + Error: The version of the recipient address {0} is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. + Chyba: verzia adresy príjemcu {0} je príliš veľká. Buď musíte aktualizovať program Bitmessage alebo váš známy s vami žartuje. - Error: Some data encoded in the recipient address %1 is too short. There might be something wrong with the software of your acquaintance. - Chyba: niektoré údaje zakódované v adrese príjemcu %1 sú príliš krátke. Softér vášho známeho možno nefunguje správne. + Error: Some data encoded in the recipient address {0} is too short. There might be something wrong with the software of your acquaintance. + Chyba: niektoré údaje zakódované v adrese príjemcu {0} sú príliš krátke. Softér vášho známeho možno nefunguje správne. - Error: Some data encoded in the recipient address %1 is too long. There might be something wrong with the software of your acquaintance. - Chyba: niektoré údaje zakódované v adrese príjemcu %1 sú príliš dlhé. Softvér vášho známeho možno nefunguje správne. + Error: Some data encoded in the recipient address {0} is too long. There might be something wrong with the software of your acquaintance. + Chyba: niektoré údaje zakódované v adrese príjemcu {0} sú príliš dlhé. Softvér vášho známeho možno nefunguje správne. - Error: Some data encoded in the recipient address %1 is malformed. There might be something wrong with the software of your acquaintance. - Chyba: niektoré údaje zakódované v adrese príjemcu %1 sú poškodené. Softvér vášho známeho možno nefunguje správne. + Error: Some data encoded in the recipient address {0} is malformed. There might be something wrong with the software of your acquaintance. + Chyba: niektoré údaje zakódované v adrese príjemcu {0} sú poškodené. Softvér vášho známeho možno nefunguje správne. - Error: Something is wrong with the recipient address %1. - Chyba: niečo s adresou príjemcu %1 je nie je v poriadku. + Error: Something is wrong with the recipient address {0}. + Chyba: niečo s adresou príjemcu {0} je nie je v poriadku. - Error: %1 - Chyba: %1 + Error: {0} + Chyba: {0} - From %1 - Od %1 + From {0} + Od {0} @@ -1570,7 +1570,7 @@ Vitajte v jednoduchom a bezpečnom Bitmessage Display the %n recent broadcast(s) from this address. - Zobraziť poslednú %1 hromadnú správu z tejto adresy.Zobraziť posledné %1 hromadné správy z tejto adresy.Zobraziť posledných %1 hromadných správ z tejto adresy. + Zobraziť poslednú {0} hromadnú správu z tejto adresy.Zobraziť posledné {0} hromadné správy z tejto adresy.Zobraziť posledných {0} hromadných správ z tejto adresy. @@ -1617,8 +1617,8 @@ Vitajte v jednoduchom a bezpečnom Bitmessage - The link "%1" will open in a browser. It may be a security risk, it could de-anonymise you or download malicious data. Are you sure? - Odkaz "%1" bude otvorený v prehliadači. Tento úkon môže predstavovať bezpečnostné riziko a Vás deanonymizovať, alebo vykonať škodlivú činnost. Ste si istý? + The link "{0}" will open in a browser. It may be a security risk, it could de-anonymise you or download malicious data. Are you sure? + Odkaz "{0}" bude otvorený v prehliadači. Tento úkon môže predstavovať bezpečnostné riziko a Vás deanonymizovať, alebo vykonať škodlivú činnost. Ste si istý? @@ -1953,8 +1953,8 @@ Predvoľba je pomocou generátora náhodných čísiel, ale deterministické adr - You are using TCP port %1. (This can be changed in the settings). - Používate port TCP %1. (Možno zmeniť v nastaveniach). + You are using TCP port {0}. (This can be changed in the settings). + Používate port TCP {0}. (Možno zmeniť v nastaveniach). @@ -2006,28 +2006,28 @@ Predvoľba je pomocou generátora náhodných čísiel, ale deterministické adr - Since startup on %1 - Od spustenia %1 + Since startup on {0} + Od spustenia {0} - Down: %1/s Total: %2 - Prijatých: %1/s Spolu: %2 + Down: {0}/s Total: {1} + Prijatých: {0}/s Spolu: {1} - Up: %1/s Total: %2 - Odoslaných: %1/s Spolu: %2 + Up: {0}/s Total: {1} + Odoslaných: {0}/s Spolu: {1} - Total Connections: %1 - Spojení spolu: %1 + Total Connections: {0} + Spojení spolu: {0} - Inventory lookups per second: %1 - Vyhľadaní v inventári za sekundu: %1 + Inventory lookups per second: {0} + Vyhľadaní v inventári za sekundu: {0} @@ -2192,8 +2192,8 @@ Predvoľba je pomocou generátora náhodných čísiel, ale deterministické adr newchandialog - Successfully created / joined chan %1 - Kanál %1 úspešne vytvorený/pripojený + Successfully created / joined chan {0} + Kanál {0} úspešne vytvorený/pripojený diff --git a/src/translations/bitmessage_sv.ts b/src/translations/bitmessage_sv.ts index 015546b3..8b854d5d 100644 --- a/src/translations/bitmessage_sv.ts +++ b/src/translations/bitmessage_sv.ts @@ -240,7 +240,7 @@ Please type the desired email address (including @mailchuck.com) below: - One of your addresses, %1, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? + One of your addresses, {0}, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? @@ -260,12 +260,12 @@ Please type the desired email address (including @mailchuck.com) below: - Message sent. Waiting for acknowledgement. Sent at %1 + Message sent. Waiting for acknowledgement. Sent at {0} - Message sent. Sent at %1 + Message sent. Sent at {0} @@ -275,7 +275,7 @@ Please type the desired email address (including @mailchuck.com) below: - Acknowledgement of the message received %1 + Acknowledgement of the message received {0} @@ -285,17 +285,17 @@ Please type the desired email address (including @mailchuck.com) below: - Broadcast on %1 + Broadcast on {0} - Problem: The work demanded by the recipient is more difficult than you are willing to do. %1 + Problem: The work demanded by the recipient is more difficult than you are willing to do. {0} - Problem: The recipient's encryption key is no good. Could not encrypt message. %1 + Problem: The recipient's encryption key is no good. Could not encrypt message. {0} @@ -305,7 +305,7 @@ Please type the desired email address (including @mailchuck.com) below: - Unknown status: %1 %2 + Unknown status: {0} {1} @@ -346,7 +346,7 @@ Please type the desired email address (including @mailchuck.com) below: You may manage your keys by editing the keys.dat file stored in - %1 + {0} It is important that you back up this file. @@ -363,7 +363,7 @@ It is important that you back up this file. You may manage your keys by editing the keys.dat file stored in - %1 + {0} 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.) @@ -429,7 +429,7 @@ It is important that you back up this file. Would you like to open the file now? - Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: %1. This address also appears in 'Your Identities'. + Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: {0}. This address also appears in 'Your Identities'. @@ -497,52 +497,52 @@ It is important that you back up this file. Would you like to open the file now? - The message that you are trying to send is too long by %1 bytes. (The maximum is 261644 bytes). Please cut it down before sending. + The message that you are trying to send is too long by {0} bytes. (The maximum is 261644 bytes). Please cut it down before sending. - Error: Your account wasn't registered at an email gateway. Sending registration now as %1, please wait for the registration to be processed before retrying sending. + Error: Your account wasn't registered at an email gateway. Sending registration now as {0}, please wait for the registration to be processed before retrying sending. - Error: Bitmessage addresses start with BM- Please check %1 + Error: Bitmessage addresses start with BM- Please check {0} - Error: The address %1 is not typed or copied correctly. Please check it. + Error: The address {0} is not typed or copied correctly. Please check it. - Error: The address %1 contains invalid characters. Please check it. + Error: The address {0} contains invalid characters. Please check it. - Error: The address version in %1 is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. + Error: The address version in {0} is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. - Error: Some data encoded in the address %1 is too short. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is too short. There might be something wrong with the software of your acquaintance. - Error: Some data encoded in the address %1 is too long. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is too long. There might be something wrong with the software of your acquaintance. - Error: Some data encoded in the address %1 is malformed. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is malformed. There might be something wrong with the software of your acquaintance. - Error: Something is wrong with the address %1. + Error: Something is wrong with the address {0}. @@ -557,7 +557,7 @@ It is important that you back up this file. Would you like to open the file now? - Concerning the address %1, Bitmessage cannot understand address version numbers of %2. Perhaps upgrade Bitmessage to the latest version. + Concerning the address {0}, Bitmessage cannot understand address version numbers of {1}. Perhaps upgrade Bitmessage to the latest version. @@ -567,7 +567,7 @@ It is important that you back up this file. Would you like to open the file now? - Concerning the address %1, Bitmessage cannot handle stream numbers of %2. Perhaps upgrade Bitmessage to the latest version. + Concerning the address {0}, Bitmessage cannot handle stream numbers of {1}. Perhaps upgrade Bitmessage to the latest version. @@ -702,7 +702,7 @@ It is important that you back up this file. Would you like to open the file now? - Bitmessage cannot find your address %1. Perhaps you removed it? + Bitmessage cannot find your address {0}. Perhaps you removed it? @@ -856,7 +856,7 @@ Are you sure you want to delete the channel? - You are using TCP port %1. (This can be changed in the settings). + You are using TCP port {0}. (This can be changed in the settings). @@ -1051,7 +1051,7 @@ Are you sure you want to delete the channel? - Zoom level %1% + Zoom level {0}% @@ -1066,47 +1066,47 @@ Are you sure you want to delete the channel? - Display the %1 recent broadcast(s) from this address. + Display the {0} recent broadcast(s) from this address. - New version of PyBitmessage is available: %1. Download it from https://github.com/Bitmessage/PyBitmessage/releases/latest + New version of PyBitmessage is available: {0}. Download it from https://github.com/Bitmessage/PyBitmessage/releases/latest - Waiting for PoW to finish... %1% + Waiting for PoW to finish... {0}% - Shutting down Pybitmessage... %1% + Shutting down Pybitmessage... {0}% - Waiting for objects to be sent... %1% + Waiting for objects to be sent... {0}% - Saving settings... %1% + Saving settings... {0}% - Shutting down core... %1% + Shutting down core... {0}% - Stopping notifications... %1% + Stopping notifications... {0}% - Shutdown imminent... %1% + Shutdown imminent... {0}% @@ -1121,7 +1121,7 @@ Are you sure you want to delete the channel? - Shutting down PyBitmessage... %1% + Shutting down PyBitmessage... {0}% @@ -1141,12 +1141,12 @@ Are you sure you want to delete the channel? - Generating %1 new addresses. + Generating {0} new addresses. - %1 is already in 'Your Identities'. Not adding it again. + {0} is already in 'Your Identities'. Not adding it again. @@ -1156,7 +1156,7 @@ Are you sure you want to delete the channel? - SOCKS5 Authentication problem: %1 + SOCKS5 Authentication problem: {0} @@ -1181,7 +1181,7 @@ Are you sure you want to delete the channel? - Broadcast sent on %1 + Broadcast sent on {0} @@ -1201,7 +1201,7 @@ Are you sure you want to delete the channel? - Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. %1 + Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. {0} @@ -1213,17 +1213,17 @@ There is no required difficulty for version 2 addresses like this. Doing work necessary to send message. -Receiver's required difficulty: %1 and %2 +Receiver's required difficulty: {0} and {1} - Problem: The work demanded by the recipient (%1 and %2) is more difficult than you are willing to do. %3 + Problem: The work demanded by the recipient ({0} and {1}) is more difficult than you are willing to do. {2} - Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. %1 + Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. {0} @@ -1233,7 +1233,7 @@ Receiver's required difficulty: %1 and %2 - Message sent. Waiting for acknowledgement. Sent on %1 + Message sent. Waiting for acknowledgement. Sent on {0} @@ -1248,12 +1248,12 @@ Receiver's required difficulty: %1 and %2 - Sending public key request. Waiting for reply. Requested at %1 + Sending public key request. Waiting for reply. Requested at {0} - UPnP port mapping established on port %1 + UPnP port mapping established on port {0} @@ -1601,27 +1601,27 @@ The 'Random Number' option is selected by default but deterministic ad - Since startup on %1 + Since startup on {0} - Down: %1/s Total: %2 + Down: {0}/s Total: {1} - Up: %1/s Total: %2 + Up: {0}/s Total: {1} - Total Connections: %1 + Total Connections: {0} - Inventory lookups per second: %1 + Inventory lookups per second: {0} diff --git a/src/translations/bitmessage_zh_cn.ts b/src/translations/bitmessage_zh_cn.ts index 474f8c6c..534e2f7a 100644 --- a/src/translations/bitmessage_zh_cn.ts +++ b/src/translations/bitmessage_zh_cn.ts @@ -352,8 +352,8 @@ Please type the desired email address (including @mailchuck.com) below: - One of your addresses, %1, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? - 您的地址中的一个, %1,是一个过时的版本1地址. 版本1地址已经不再受到支持了. 我们可以将它删除掉么? + One of your addresses, {0}, is an old version 1 address. Version 1 addresses are no longer supported. May we delete it now? + 您的地址中的一个, {0},是一个过时的版本1地址. 版本1地址已经不再受到支持了. 我们可以将它删除掉么? @@ -372,13 +372,13 @@ Please type the desired email address (including @mailchuck.com) below: - Message sent. Waiting for acknowledgement. Sent at %1 - 消息已经发送. 正在等待回执. 发送于 %1 + Message sent. Waiting for acknowledgement. Sent at {0} + 消息已经发送. 正在等待回执. 发送于 {0} - Message sent. Sent at %1 - 消息已经发送. 发送于 %1 + Message sent. Sent at {0} + 消息已经发送. 发送于 {0} @@ -387,8 +387,8 @@ Please type the desired email address (including @mailchuck.com) below: - Acknowledgement of the message received %1 - 消息的回执已经收到于 %1 + Acknowledgement of the message received {0} + 消息的回执已经收到于 {0} @@ -397,18 +397,18 @@ Please type the desired email address (including @mailchuck.com) below: - Broadcast on %1 - 已经广播于 %1 + Broadcast on {0} + 已经广播于 {0} - Problem: The work demanded by the recipient is more difficult than you are willing to do. %1 - 错误: 收件人要求的做工量大于我们的最大接受做工量。 %1 + Problem: The work demanded by the recipient is more difficult than you are willing to do. {0} + 错误: 收件人要求的做工量大于我们的最大接受做工量。 {0} - Problem: The recipient's encryption key is no good. Could not encrypt message. %1 - 错误: 收件人的加密密钥是无效的。不能加密消息。 %1 + Problem: The recipient's encryption key is no good. Could not encrypt message. {0} + 错误: 收件人的加密密钥是无效的。不能加密消息。 {0} @@ -417,8 +417,8 @@ Please type the desired email address (including @mailchuck.com) below: - Unknown status: %1 %2 - 未知状态: %1 %2 + Unknown status: {0} {1} + 未知状态: {0} {1} @@ -458,9 +458,9 @@ Please type the desired email address (including @mailchuck.com) below: You may manage your keys by editing the keys.dat file stored in - %1 + {0} It is important that you back up this file. - 您可以通过编辑储存在 %1 的 keys.dat 来编辑密钥。备份这个文件十分重要。 + 您可以通过编辑储存在 {0} 的 keys.dat 来编辑密钥。备份这个文件十分重要。 @@ -475,9 +475,9 @@ It is important that you back up this file. You may manage your keys by editing the keys.dat file stored in - %1 + {0} 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.) - 您可以通过编辑储存在 %1 的 keys.dat 来编辑密钥。备份这个文件十分重要。您现在想打开这个文件么?(请在进行任何修改前关闭比特信) + 您可以通过编辑储存在 {0} 的 keys.dat 来编辑密钥。备份这个文件十分重要。您现在想打开这个文件么?(请在进行任何修改前关闭比特信) @@ -541,7 +541,7 @@ It is important that you back up this file. Would you like to open the file now? - Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: %1. This address also appears in 'Your Identities'. + Successfully created chan. To let others join your chan, give them the chan name and this Bitmessage address: {0}. This address also appears in 'Your Identities'. @@ -610,52 +610,52 @@ It is important that you back up this file. Would you like to open the file now? - The message that you are trying to send is too long by %1 bytes. (The maximum is 261644 bytes). Please cut it down before sending. + The message that you are trying to send is too long by {0} bytes. (The maximum is 261644 bytes). Please cut it down before sending. 您正在尝试发送的信息已超过 %1 个字节太长(最大为261644个字节),发送前请先缩短一些。 - Error: Your account wasn't registered at an email gateway. Sending registration now as %1, please wait for the registration to be processed before retrying sending. + Error: Your account wasn't registered at an email gateway. Sending registration now as {0}, please wait for the registration to be processed before retrying sending. 错误: 您的帐户没有在电子邮件网关注册。现在发送注册为%1​​, 注册正在处理请稍候重试发送. - Error: Bitmessage addresses start with BM- Please check %1 + Error: Bitmessage addresses start with BM- Please check {0} - Error: The address %1 is not typed or copied correctly. Please check it. + Error: The address {0} is not typed or copied correctly. Please check it. - Error: The address %1 contains invalid characters. Please check it. + Error: The address {0} contains invalid characters. Please check it. - Error: The address version in %1 is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. + Error: The address version in {0} is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. - Error: Some data encoded in the address %1 is too short. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is too short. There might be something wrong with the software of your acquaintance. - Error: Some data encoded in the address %1 is too long. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is too long. There might be something wrong with the software of your acquaintance. - Error: Some data encoded in the address %1 is malformed. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the address {0} is malformed. There might be something wrong with the software of your acquaintance. - Error: Something is wrong with the address %1. + Error: Something is wrong with the address {0}. @@ -670,8 +670,8 @@ It is important that you back up this file. Would you like to open the file now? - Concerning the address %1, Bitmessage cannot understand address version numbers of %2. Perhaps upgrade Bitmessage to the latest version. - 地址 %1 的地址版本号 %2 无法被比特信理解。也许您应该升级您的比特信到最新版本。 + Concerning the address {0}, Bitmessage cannot understand address version numbers of {1}. Perhaps upgrade Bitmessage to the latest version. + 地址 {0} 的地址版本号 {1} 无法被比特信理解。也许您应该升级您的比特信到最新版本。 @@ -680,8 +680,8 @@ It is important that you back up this file. Would you like to open the file now? - Concerning the address %1, Bitmessage cannot handle stream numbers of %2. Perhaps upgrade Bitmessage to the latest version. - 地址 %1 的节点流序号 %2 无法被比特信所理解。也许您应该升级您的比特信到最新版本。 + Concerning the address {0}, Bitmessage cannot handle stream numbers of {1}. Perhaps upgrade Bitmessage to the latest version. + 地址 {0} 的节点流序号 {1} 无法被比特信所理解。也许您应该升级您的比特信到最新版本。 @@ -815,8 +815,8 @@ It is important that you back up this file. Would you like to open the file now? - Bitmessage cannot find your address %1. Perhaps you removed it? - 比特信无法找到您的地址 %1 ,也许您已经把它删掉了? + Bitmessage cannot find your address {0}. Perhaps you removed it? + 比特信无法找到您的地址 {0} ,也许您已经把它删掉了? @@ -973,7 +973,7 @@ Are you sure you want to delete the channel? - You are using TCP port %1. (This can be changed in the settings). + You are using TCP port {0}. (This can be changed in the settings). @@ -1168,7 +1168,7 @@ Are you sure you want to delete the channel? - Zoom level %1% + Zoom level {0}% 缩放级别%1% @@ -1183,48 +1183,48 @@ Are you sure you want to delete the channel? - Display the %1 recent broadcast(s) from this address. + Display the {0} recent broadcast(s) from this address. - New version of PyBitmessage is available: %1. Download it from https://github.com/Bitmessage/PyBitmessage/releases/latest - PyBitmessage的新版本可用: %1. 从https://github.com/Bitmessage/PyBitmessage/releases/latest下载 + New version of PyBitmessage is available: {0}. Download it from https://github.com/Bitmessage/PyBitmessage/releases/latest + PyBitmessage的新版本可用: {0}. 从https://github.com/Bitmessage/PyBitmessage/releases/latest下载 - Waiting for PoW to finish... %1% - 等待PoW完成...%1% + Waiting for PoW to finish... {0}% + 等待PoW完成...{0}% - Shutting down Pybitmessage... %1% - 关闭Pybitmessage ...%1% + Shutting down Pybitmessage... {0}% + 关闭Pybitmessage ...{0}% - Waiting for objects to be sent... %1% - 等待要发送对象...%1% + Waiting for objects to be sent... {0}% + 等待要发送对象...{0}% - Saving settings... %1% - 保存设置...%1% + Saving settings... {0}% + 保存设置...{0}% - Shutting down core... %1% - 关闭核心...%1% + Shutting down core... {0}% + 关闭核心...{0}% - Stopping notifications... %1% - 停止通知...%1% + Stopping notifications... {0}% + 停止通知...{0}% - Shutdown imminent... %1% - 关闭即将来临...%1% + Shutdown imminent... {0}% + 关闭即将来临...{0}% @@ -1238,8 +1238,8 @@ Are you sure you want to delete the channel? - Shutting down PyBitmessage... %1% - 关闭PyBitmessage...%1% + Shutting down PyBitmessage... {0}% + 关闭PyBitmessage...{0}% @@ -1258,13 +1258,13 @@ Are you sure you want to delete the channel? - Generating %1 new addresses. - 生成%1个新地址. + Generating {0} new addresses. + 生成{0}个新地址. - %1 is already in 'Your Identities'. Not adding it again. - %1已经在'您的身份'. 不必重新添加. + {0} is already in 'Your Identities'. Not adding it again. + {0}已经在'您的身份'. 不必重新添加. @@ -1273,7 +1273,7 @@ Are you sure you want to delete the channel? - SOCKS5 Authentication problem: %1 + SOCKS5 Authentication problem: {0} @@ -1298,8 +1298,8 @@ Are you sure you want to delete the channel? - Broadcast sent on %1 - 广播发送%1 + Broadcast sent on {0} + 广播发送{0} @@ -1318,8 +1318,8 @@ Are you sure you want to delete the channel? - Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. %1 - 问题:对方是移动设备,并且对方的地址包含在此消息中,但是您的设置禁止了。 %1 + Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. {0} + 问题:对方是移动设备,并且对方的地址包含在此消息中,但是您的设置禁止了。 {0} @@ -1331,19 +1331,19 @@ There is no required difficulty for version 2 addresses like this. Doing work necessary to send message. -Receiver's required difficulty: %1 and %2 +Receiver's required difficulty: {0} and {1} 做必要的工作, 以发送短信. -接收者的要求难度: %1与%2 +接收者的要求难度: {0}与{1} - Problem: The work demanded by the recipient (%1 and %2) is more difficult than you are willing to do. %3 - 问题: 由接收者(%1%2)要求的工作量比您愿意做的工作量來得更困难. %3 + Problem: The work demanded by the recipient ({0} and {1}) is more difficult than you are willing to do. {2} + 问题: 由接收者({0}{1})要求的工作量比您愿意做的工作量來得更困难. {2} - Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. %1 - 问题: 您正在尝试将信息发送给自己或频道, 但您的加密密钥无法在keys.dat文件中找到. 无法加密信息. %1 + Problem: You are trying to send a message to yourself or a chan but your encryption key could not be found in the keys.dat file. Could not encrypt message. {0} + 问题: 您正在尝试将信息发送给自己或频道, 但您的加密密钥无法在keys.dat文件中找到. 无法加密信息. {0} @@ -1352,8 +1352,8 @@ Receiver's required difficulty: %1 and %2 - Message sent. Waiting for acknowledgement. Sent on %1 - 信息发送. 等待确认. 已发送%1 + Message sent. Waiting for acknowledgement. Sent on {0} + 信息发送. 等待确认. 已发送{0} @@ -1367,13 +1367,13 @@ Receiver's required difficulty: %1 and %2 - Sending public key request. Waiting for reply. Requested at %1 - 发送公钥的请求. 等待回复. 请求在%1 + Sending public key request. Waiting for reply. Requested at {0} + 发送公钥的请求. 等待回复. 请求在{0} - UPnP port mapping established on port %1 - UPnP端口映射建立在端口%1 + UPnP port mapping established on port {0} + UPnP端口映射建立在端口{0} @@ -1417,18 +1417,18 @@ Receiver's required difficulty: %1 and %2 - The name %1 was not found. - 名字%1未找到。 + The name {0} was not found. + 名字{0}未找到。 - The namecoin query failed (%1) - 域名币查询失败(%1) + The namecoin query failed ({0}) + 域名币查询失败({0}) - Unknown namecoin interface type: %1 - 未知的 Namecoin 界面类型: %1 + Unknown namecoin interface type: {0} + 未知的 Namecoin 界面类型: {0} @@ -1437,13 +1437,13 @@ Receiver's required difficulty: %1 and %2 - The name %1 has no associated Bitmessage address. - 名字%1没有关联比特信地址。 + The name {0} has no associated Bitmessage address. + 名字{0}没有关联比特信地址。 - Success! Namecoind version %1 running. - 成功!域名币系统%1运行中。 + Success! Namecoind version {0} running. + 成功!域名币系统{0}运行中。 @@ -1506,53 +1506,53 @@ Receiver's required difficulty: %1 and %2 - Error: Bitmessage addresses start with BM- Please check the recipient address %1 - 错误:Bitmessage地址是以BM-开头的,请检查收信地址%1. + Error: Bitmessage addresses start with BM- Please check the recipient address {0} + 错误:Bitmessage地址是以BM-开头的,请检查收信地址{0}. - Error: The recipient address %1 is not typed or copied correctly. Please check it. - 错误:收信地址%1未填写或复制错误。请检查。 + Error: The recipient address {0} is not typed or copied correctly. Please check it. + 错误:收信地址{0}未填写或复制错误。请检查。 - Error: The recipient address %1 contains invalid characters. Please check it. - 错误:收信地址%1还有非法字符。请检查。 + Error: The recipient address {0} contains invalid characters. Please check it. + 错误:收信地址{0}还有非法字符。请检查。 - Error: The version of the recipient address %1 is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. - 错误:收信地址 %1 版本太高。要么您需要更新您的软件,要么对方需要降级 。 + Error: The version of the recipient address {0} is too high. Either you need to upgrade your Bitmessage software or your acquaintance is being clever. + 错误:收信地址 {0} 版本太高。要么您需要更新您的软件,要么对方需要降级 。 - Error: Some data encoded in the recipient address %1 is too short. There might be something wrong with the software of your acquaintance. - 错误:收信地址%1编码数据太短。可能对方使用的软件有问题。 + Error: Some data encoded in the recipient address {0} is too short. There might be something wrong with the software of your acquaintance. + 错误:收信地址{0}编码数据太短。可能对方使用的软件有问题。 - Error: Some data encoded in the recipient address %1 is too long. There might be something wrong with the software of your acquaintance. + Error: Some data encoded in the recipient address {0} is too long. There might be something wrong with the software of your acquaintance. 错误: - Error: Some data encoded in the recipient address %1 is malformed. There might be something wrong with the software of your acquaintance. - 错误:收信地址%1编码数据太长。可能对方使用的软件有问题。 + Error: Some data encoded in the recipient address {0} is malformed. There might be something wrong with the software of your acquaintance. + 错误:收信地址{0}编码数据太长。可能对方使用的软件有问题。 - Error: Something is wrong with the recipient address %1. - 错误:收信地址%1有问题。 + Error: Something is wrong with the recipient address {0}. + 错误:收信地址{0}有问题。 - Error: %1 - 错误:%1 + Error: {0} + 错误:{0} - From %1 - 来自 %1 + From {0} + 来自 {0} @@ -1664,8 +1664,8 @@ Receiver's required difficulty: %1 and %2 - The link "%1" will open in a browser. It may be a security risk, it could de-anonymise you or download malicious data. Are you sure? - 此链接“%1”将在浏览器中打开。可能会有安全风险,可能会暴露您或下载恶意数据。确定吗? + The link "{0}" will open in a browser. It may be a security risk, it could de-anonymise you or download malicious data. Are you sure? + 此链接“{0}”将在浏览器中打开。可能会有安全风险,可能会暴露您或下载恶意数据。确定吗? @@ -1999,8 +1999,8 @@ The 'Random Number' option is selected by default but deterministic ad - You are using TCP port %1. (This can be changed in the settings). - 您正在使用TCP端口 %1 。(可以在设置中修改)。 + You are using TCP port {0}. (This can be changed in the settings). + 您正在使用TCP端口 {0} 。(可以在设置中修改)。 @@ -2052,28 +2052,28 @@ The 'Random Number' option is selected by default but deterministic ad - Since startup on %1 - 自从%1启动 + Since startup on {0} + 自从{0}启动 - Down: %1/s Total: %2 - 下: %1/秒 总计: %2 + Down: {0}/s Total: {1} + 下: {0}/秒 总计: {1} - Up: %1/s Total: %2 - 上: %1/秒 总计: %2 + Up: {0}/s Total: {1} + 上: {0}/秒 总计: {1} - Total Connections: %1 - 总的连接数: %1 + Total Connections: {0} + 总的连接数: {0} - Inventory lookups per second: %1 - 每秒库存查询: %1 + Inventory lookups per second: {0} + 每秒库存查询: {0} @@ -2238,8 +2238,8 @@ The 'Random Number' option is selected by default but deterministic ad newchandialog - Successfully created / joined chan %1 - 成功创建或加入频道%1 + Successfully created / joined chan {0} + 成功创建或加入频道{0} diff --git a/src/translations/noarg.sh b/src/translations/noarg.sh new file mode 100755 index 00000000..50d45d32 --- /dev/null +++ b/src/translations/noarg.sh @@ -0,0 +1,7 @@ +#!/bin/sh +files=`ls *.ts` +tmp_file=/tmp/noarg.sh.txt +for file in $files; do + cat $file | sed 's/%1/{0}/g' | sed 's/%2/{1}/g' | sed 's/%3/{2}/g' > $tmp_file + mv $tmp_file $file +done diff --git a/src/translations/update.sh b/src/translations/update.sh new file mode 100755 index 00000000..b3221486 --- /dev/null +++ b/src/translations/update.sh @@ -0,0 +1,2 @@ +#!/bin/sh +lrelease-qt4 bitmessage.pro -- 2.45.1 From 9c64db0d2a0f4614ab45ce9208d0a1e7253113b0 Mon Sep 17 00:00:00 2001 From: Kashiko Koibumi Date: Mon, 27 May 2024 23:01:19 +0900 Subject: [PATCH 054/105] remove restriction for Python3 and add startup script for Python3 --- src/depends.py | 9 ++------- start3.sh | 3 +++ 2 files changed, 5 insertions(+), 7 deletions(-) create mode 100755 start3.sh diff --git a/src/depends.py b/src/depends.py index a2b0d6c6..0afae7af 100755 --- a/src/depends.py +++ b/src/depends.py @@ -450,14 +450,9 @@ def check_dependencies(verbose=False, optional=False): logger.info('Python version: %s', sys.version) if sys.hexversion < 0x20704F0: logger.error( - 'PyBitmessage requires Python 2.7.4 or greater' - ' (but not Python 3+)') + 'PyBitmessage requires Python 2.7.4 or greater.' + ' Python 2.7.18 is recommended.') has_all_dependencies = False - if six.PY3: - logger.error( - 'PyBitmessage does not support Python 3+. Python 2.7.4' - ' or greater is required. Python 2.7.18 is recommended.') - sys.exit() # FIXME: This needs to be uncommented when more of the code is python3 compatible # if sys.hexversion >= 0x3000000 and sys.hexversion < 0x3060000: diff --git a/start3.sh b/start3.sh new file mode 100755 index 00000000..bf571e12 --- /dev/null +++ b/start3.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +python3 pybitmessage/bitmessagemain.py "$@" -- 2.45.1 From b9bfa5184485f29291b4db649082efef813f10b3 Mon Sep 17 00:00:00 2001 From: Kashiko Koibumi Date: Mon, 27 May 2024 23:04:39 +0900 Subject: [PATCH 055/105] fix import path compatible with both Python2 and Python3 --- src/bitmessageqt/blacklist.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bitmessageqt/blacklist.py b/src/bitmessageqt/blacklist.py index fc5d462b..1011dab8 100644 --- a/src/bitmessageqt/blacklist.py +++ b/src/bitmessageqt/blacklist.py @@ -1,7 +1,7 @@ from unqstr import ustr, unic from PyQt4 import QtCore, QtGui -import widgets +from bitmessageqt import widgets from addresses import addBMIfNotPresent from bmconfigparser import config from .dialogs import AddAddressDialog -- 2.45.1 From 5fa08f4b3b0bf0525e4d643800a81578f5cf5f01 Mon Sep 17 00:00:00 2001 From: Kashiko Koibumi Date: Tue, 28 May 2024 00:12:27 +0900 Subject: [PATCH 056/105] misc fixes to run with Python3 --- src/bitmessageqt/__init__.py | 6 +++--- src/bitmessageqt/addressvalidator.py | 4 ++-- src/bitmessageqt/newchandialog.py | 4 ++-- src/bitmessageqt/utils.py | 4 ++-- src/network/connectionpool.py | 4 ++-- src/network/knownnodes.py | 2 +- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/bitmessageqt/__init__.py b/src/bitmessageqt/__init__.py index 30bb898e..a6133efb 100644 --- a/src/bitmessageqt/__init__.py +++ b/src/bitmessageqt/__init__.py @@ -424,7 +424,7 @@ class MyForm(settingsmixin.SMainWindow): def rerenderTabTreeSubscriptions(self): treeWidget = self.ui.treeWidgetSubscriptions folders = Ui_FolderWidget.folderWeight.keys() - folders.remove("new") + Ui_FolderWidget.folderWeight.pop("new", None) # sort ascending when creating if treeWidget.topLevelItemCount() == 0: @@ -1702,7 +1702,7 @@ class MyForm(settingsmixin.SMainWindow): addressVersionNumber, streamNumberForAddress, "regenerated deterministic address", dialog.spinBoxNumberOfAddressesToMake.value(), - ustr(dialog.lineEditPassphrase.text()), + ustr(dialog.lineEditPassphrase.text()).encode("utf-8", "replace"), dialog.checkBoxEighteenByteRipe.isChecked() )) self.ui.tabWidget.setCurrentIndex( @@ -3770,7 +3770,7 @@ class MyForm(settingsmixin.SMainWindow): def setAvatar(self, addressAtCurrentRow): if not os.path.exists(state.appdata + 'avatars/'): os.makedirs(state.appdata + 'avatars/') - hash = hashlib.md5(addBMIfNotPresent(addressAtCurrentRow)).hexdigest() + hash = hashlib.md5(addBMIfNotPresent(addressAtCurrentRow).encode("utf-8", "replace")).hexdigest() extensions = [ 'PNG', 'GIF', 'JPG', 'JPEG', 'SVG', 'BMP', 'MNG', 'PBM', 'PGM', 'PPM', 'TIFF', 'XBM', 'XPM', 'TGA'] diff --git a/src/bitmessageqt/addressvalidator.py b/src/bitmessageqt/addressvalidator.py index 0dd87eb4..f1817437 100644 --- a/src/bitmessageqt/addressvalidator.py +++ b/src/bitmessageqt/addressvalidator.py @@ -153,11 +153,11 @@ class AddressPassPhraseValidatorMixin(object): # check through generator if address is None: - addressGeneratorQueue.put(('createChan', 4, 1, str_chan + ' ' + ustr(passPhrase), passPhrase, False)) + addressGeneratorQueue.put(('createChan', 4, 1, str_chan + ' ' + ustr(passPhrase), passPhrase.encode("utf-8", "replace"), False)) else: addressGeneratorQueue.put( ('joinChan', addBMIfNotPresent(address), - "{} {}".format(str_chan, passPhrase), passPhrase, False)) + "{} {}".format(str_chan, passPhrase), passPhrase.encode("utf-8", "replace"), False)) if self.buttonBox.button(QtGui.QDialogButtonBox.Ok).hasFocus(): return (self.returnValid(), s, pos) diff --git a/src/bitmessageqt/newchandialog.py b/src/bitmessageqt/newchandialog.py index c8088f76..aef4cd04 100644 --- a/src/bitmessageqt/newchandialog.py +++ b/src/bitmessageqt/newchandialog.py @@ -56,13 +56,13 @@ class NewChanDialog(QtGui.QDialog): if ustr(self.chanAddress.text()) == "": addressGeneratorQueue.put( ('createChan', 4, 1, str_chan + ' ' + ustr(self.chanPassPhrase.text()), - ustr(self.chanPassPhrase.text()), + ustr(self.chanPassPhrase.text()).encode("utf-8", "replace"), True)) else: addressGeneratorQueue.put( ('joinChan', addBMIfNotPresent(ustr(self.chanAddress.text())), str_chan + ' ' + ustr(self.chanPassPhrase.text()), - ustr(self.chanPassPhrase.text()), + ustr(self.chanPassPhrase.text()).encode("utf-8", "replace"), True)) addressGeneratorReturnValue = apiAddressGeneratorReturnQueue.get(True) if addressGeneratorReturnValue and addressGeneratorReturnValue[0] != 'chan name does not match address': diff --git a/src/bitmessageqt/utils.py b/src/bitmessageqt/utils.py index 9f849b3b..3637e3ec 100644 --- a/src/bitmessageqt/utils.py +++ b/src/bitmessageqt/utils.py @@ -38,7 +38,7 @@ def identiconize(address): # stripped from PIL and uses QT instead (by sendiulo, same license) import qidenticon icon_hash = hashlib.md5( - addBMIfNotPresent(address) + identiconsuffix).hexdigest() + (addBMIfNotPresent(address) + identiconsuffix).encode("utf-8", "replace")).hexdigest() use_two_colors = identicon_lib[:len('qidenticon_two')] == 'qidenticon_two' opacity = int( identicon_lib not in ( @@ -81,7 +81,7 @@ def avatarize(address): falls back to identiconize(address) """ idcon = QtGui.QIcon() - icon_hash = hashlib.md5(addBMIfNotPresent(address)).hexdigest() + icon_hash = hashlib.md5(addBMIfNotPresent(address).encode("utf-8", "replace")).hexdigest() if address == str_broadcast_subscribers: # don't hash [Broadcast subscribers] icon_hash = address diff --git a/src/network/connectionpool.py b/src/network/connectionpool.py index fcac9e7e..d8cd68b8 100644 --- a/src/network/connectionpool.py +++ b/src/network/connectionpool.py @@ -78,7 +78,7 @@ class BMConnectionPool(object): Shortcut for combined list of connections from `inboundConnections` and `outboundConnections` dicts """ - return self.inboundConnections.values() + self.outboundConnections.values() + return list(self.inboundConnections.values()) + list(self.outboundConnections.values()) def establishedConnections(self): """Shortcut for list of connections having fullyEstablished == True""" @@ -388,7 +388,7 @@ class BMConnectionPool(object): i.set_state("close") for i in ( self.connections() - + self.listeningSockets.values() + self.udpSockets.values() + + list(self.listeningSockets.values()) + list(self.udpSockets.values()) ): if not (i.accepting or i.connecting or i.connected): reaper.append(i) diff --git a/src/network/knownnodes.py b/src/network/knownnodes.py index 702f59c6..d8b9178b 100644 --- a/src/network/knownnodes.py +++ b/src/network/knownnodes.py @@ -95,7 +95,7 @@ def saveKnownNodes(dirName=None): if dirName is None: dirName = state.appdata with knownNodesLock: - with open(os.path.join(dirName, 'knownnodes.dat'), 'wb') as output: + with open(os.path.join(dirName, 'knownnodes.dat'), 'w') as output: json_serialize_knownnodes(output) -- 2.45.1 From df2631c4ee2ae7bc24f26edbad9e149d34d33d88 Mon Sep 17 00:00:00 2001 From: Kashiko Koibumi Date: Tue, 28 May 2024 12:22:36 +0900 Subject: [PATCH 057/105] misc fixes to run with Python3; part 2 --- src/bitmessageqt/foldertree.py | 2 +- src/inventory.py | 6 ++++-- src/network/asyncore_pollchoose.py | 15 --------------- src/network/bmproto.py | 23 ++++++++++++++++++----- src/network/connectionchooser.py | 14 ++++++++++---- src/network/connectionpool.py | 12 +++++++++--- src/network/dandelion.py | 4 ++-- src/network/knownnodes.py | 8 +++++++- src/network/proxy.py | 8 +++++++- src/network/tcp.py | 8 +++++++- src/network/udp.py | 2 +- src/protocol.py | 6 ++++-- 12 files changed, 70 insertions(+), 38 deletions(-) diff --git a/src/bitmessageqt/foldertree.py b/src/bitmessageqt/foldertree.py index b1133f56..41a5da83 100644 --- a/src/bitmessageqt/foldertree.py +++ b/src/bitmessageqt/foldertree.py @@ -476,7 +476,7 @@ class MessageList_TimeWidget(BMTableWidgetItem): msgid is available by QtCore.Qt.UserRole """ - def __init__(self, label=None, unread=False, timestamp=None, msgid=''): + def __init__(self, label=None, unread=False, timestamp=None, msgid=b''): super(MessageList_TimeWidget, self).__init__(label, unread) self.setData(QtCore.Qt.UserRole, QtCore.QByteArray(msgid)) self.setData(TimestampRole, int(timestamp)) diff --git a/src/inventory.py b/src/inventory.py index 5b739e84..8356262c 100644 --- a/src/inventory.py +++ b/src/inventory.py @@ -28,8 +28,6 @@ class Inventory: # cheap inheritance copied from asyncore def __getattr__(self, attr): - if attr == "__contains__": - self.numberOfInventoryLookupsPerformed += 1 try: realRet = getattr(self._realInventory, attr) except AttributeError: @@ -40,6 +38,10 @@ class Inventory: else: return realRet + def __contains__(self, key): + self.numberOfInventoryLookupsPerformed += 1 + return key in self._realInventory + # hint for pylint: this is dictionary like object def __getitem__(self, key): return self._realInventory[key] diff --git a/src/network/asyncore_pollchoose.py b/src/network/asyncore_pollchoose.py index a41145a1..5de3a18f 100644 --- a/src/network/asyncore_pollchoose.py +++ b/src/network/asyncore_pollchoose.py @@ -724,21 +724,6 @@ class dispatcher(object): if why.args[0] not in (ENOTCONN, EBADF): raise - # cheap inheritance, used to pass all other attribute - # references to the underlying socket object. - def __getattr__(self, attr): - try: - retattr = getattr(self.socket, attr) - except AttributeError: - raise AttributeError( - "%s instance has no attribute '%s'" - % (self.__class__.__name__, attr)) - else: - msg = "%(me)s.%(attr)s is deprecated; use %(me)s.socket.%(attr)s"\ - " instead" % {'me': self.__class__.__name__, 'attr': attr} - warnings.warn(msg, DeprecationWarning, stacklevel=2) - return retattr - # log and log_info may be overridden to provide more sophisticated # logging and warning methods. In general, log is for 'hit' logging # and 'log_info' is for informational, warning and error logging. diff --git a/src/network/bmproto.py b/src/network/bmproto.py index ab23cce5..c051c252 100644 --- a/src/network/bmproto.py +++ b/src/network/bmproto.py @@ -9,6 +9,7 @@ import re import socket import struct import time +import six # magic imports! import addresses @@ -34,6 +35,18 @@ from .objectracker import ObjectTracker, missingObjects logger = logging.getLogger('default') +def _hoststr(v): + if six.PY3: + return v + else: # assume six.PY2 + return str(v) + +def _restr(v): + if six.PY3: + return v.decode("utf-8", "replace") + else: # assume six.PY2 + return v + class BMProtoError(ProxyError): """A Bitmessage Protocol Base Error""" errorCodes = ("Protocol error") @@ -115,7 +128,7 @@ class BMProto(AdvancedDispatcher, ObjectTracker): if not self.invalid: try: retval = getattr( - self, "bm_command_" + str(self.command).lower())() + self, "bm_command_" + self.command.decode("utf-8", "replace").lower())() except AttributeError: # unimplemented command logger.debug('unimplemented command %s', self.command) @@ -169,16 +182,16 @@ class BMProto(AdvancedDispatcher, ObjectTracker): # protocol.checkIPAddress() services, host, port = self.decode_payload_content("Q16sH") if host[0:12] == b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF': - host = socket.inet_ntop(socket.AF_INET, str(host[12:16])) + host = socket.inet_ntop(socket.AF_INET, _hoststr(host[12:16])) elif host[0:6] == b'\xfd\x87\xd8\x7e\xeb\x43': # Onion, based on BMD/bitcoind host = base64.b32encode(host[6:]).lower() + b".onion" else: - host = socket.inet_ntop(socket.AF_INET6, str(host)) + host = socket.inet_ntop(socket.AF_INET6, _hoststr(host)) if host == b"": # This can happen on Windows systems which are not 64-bit # compatible so let us drop the IPv6 address. - host = socket.inet_ntop(socket.AF_INET, str(host[12:16])) + host = socket.inet_ntop(socket.AF_INET, _hoststr(host[12:16])) return Node(services, host, port) @@ -534,7 +547,7 @@ class BMProto(AdvancedDispatcher, ObjectTracker): self.append_write_buf(protocol.CreatePacket(b'verack')) self.verackSent = True ua_valid = re.match( - r'^/[a-zA-Z]+:[0-9]+\.?[\w\s\(\)\./:;-]*/$', self.userAgent) + r'^/[a-zA-Z]+:[0-9]+\.?[\w\s\(\)\./:;-]*/$', _restr(self.userAgent)) if not ua_valid: self.userAgent = b'/INVALID:0/' if not self.isOutbound: diff --git a/src/network/connectionchooser.py b/src/network/connectionchooser.py index f4ae075d..03764dfc 100644 --- a/src/network/connectionchooser.py +++ b/src/network/connectionchooser.py @@ -14,10 +14,16 @@ from queues import queue, portCheckerQueue logger = logging.getLogger('default') +def _ends_with(s, tail): + try: + return s.endswith(tail) + except: + return s.decode("utf-8", "replace").endswith(tail) + def getDiscoveredPeer(): """Get a peer from the local peer discovery list""" try: - peer = random.choice(state.discoveredPeers.keys()) # nosec B311 + peer = random.choice(list(state.discoveredPeers.keys())) # nosec B311 except (IndexError, KeyError): raise ValueError try: @@ -45,7 +51,7 @@ def chooseConnection(stream): return getDiscoveredPeer() for _ in range(50): peer = random.choice( # nosec B311 - knownnodes.knownNodes[stream].keys()) + list(knownnodes.knownNodes[stream].keys())) try: peer_info = knownnodes.knownNodes[stream][peer] if peer_info.get('self'): @@ -57,10 +63,10 @@ def chooseConnection(stream): if haveOnion: # do not connect to raw IP addresses # --keep all traffic within Tor overlay - if onionOnly and not peer.host.endswith('.onion'): + if onionOnly and not _ends_with(peer.host, '.onion'): continue # onion addresses have a higher priority when SOCKS - if peer.host.endswith('.onion') and rating > 0: + if _ends_with(peer.host, '.onion') and rating > 0: rating = 1 # TODO: need better check elif not peer.host.startswith('bootstrap'): diff --git a/src/network/connectionpool.py b/src/network/connectionpool.py index d8cd68b8..7611d87d 100644 --- a/src/network/connectionpool.py +++ b/src/network/connectionpool.py @@ -25,6 +25,12 @@ from .udp import UDPSocket logger = logging.getLogger('default') +def _ends_with(s, tail): + try: + return s.endswith(tail) + except: + return s.decode("utf-8", "replace").endswith(tail) + class BMConnectionPool(object): """Pool of all existing connections""" # pylint: disable=too-many-instance-attributes @@ -160,8 +166,8 @@ class BMConnectionPool(object): @staticmethod def getListeningIP(): """What IP are we supposed to be listening on?""" - if config.safeGet( - "bitmessagesettings", "onionhostname", "").endswith(".onion"): + if _ends_with(config.safeGet( + "bitmessagesettings", "onionhostname", ""), ".onion"): host = config.safeGet( "bitmessagesettings", "onionbindip") else: @@ -314,7 +320,7 @@ class BMConnectionPool(object): continue try: - if chosen.host.endswith(".onion") and Proxy.onion_proxy: + if _ends_with(chosen.host, ".onion") and Proxy.onion_proxy: if onionsocksproxytype == "SOCKS5": self.addConnection(Socks5BMConnection(chosen)) elif onionsocksproxytype == "SOCKS4a": diff --git a/src/network/dandelion.py b/src/network/dandelion.py index 466f031e..3e67d1a7 100644 --- a/src/network/dandelion.py +++ b/src/network/dandelion.py @@ -185,8 +185,8 @@ class Dandelion: # pylint: disable=old-style-class try: # random two connections self.stem = sample( - connectionpool.BMConnectionPool( - ).outboundConnections.values(), MAX_STEMS) + sorted(connectionpool.BMConnectionPool( + ).outboundConnections.values()), MAX_STEMS) # not enough stems available except ValueError: self.stem = connectionpool.BMConnectionPool( diff --git a/src/network/knownnodes.py b/src/network/knownnodes.py index d8b9178b..2ce698f9 100644 --- a/src/network/knownnodes.py +++ b/src/network/knownnodes.py @@ -106,6 +106,12 @@ def addKnownNode(stream, peer, lastseen=None, is_self=False): Returns True if added a new node. """ # pylint: disable=too-many-branches + if not isinstance(peer.host, str): + try: + peer = Peer(peer.host.decode("ascii"), peer.port) + except UnicodeDecodeError as err: + logger.warning("Invalid host: {}".format(peer.host.decode("ascii", "backslashreplace"))) + return if isinstance(stream, Iterable): with knownNodesLock: for s in stream: @@ -151,7 +157,7 @@ def createDefaultKnownNodes(): def readKnownNodes(): """Load knownnodes from filesystem""" try: - with open(state.appdata + 'knownnodes.dat', 'rb') as source: + with open(state.appdata + 'knownnodes.dat', 'r') as source: with knownNodesLock: try: json_deserialize_knownnodes(source) diff --git a/src/network/proxy.py b/src/network/proxy.py index eb76ce97..9cce6bf6 100644 --- a/src/network/proxy.py +++ b/src/network/proxy.py @@ -14,6 +14,12 @@ from .node import Peer logger = logging.getLogger('default') +def _ends_with(s, tail): + try: + return s.endswith(tail) + except: + return s.decode("utf-8", "replace").endswith(tail) + class ProxyError(Exception): """Base proxy exception class""" errorCodes = ("Unknown error",) @@ -125,7 +131,7 @@ class Proxy(AdvancedDispatcher): self.auth = None self.connect( self.onion_proxy - if address.host.endswith(".onion") and self.onion_proxy else + if _ends_with(address.host, ".onion") and self.onion_proxy else self.proxy ) diff --git a/src/network/tcp.py b/src/network/tcp.py index 0ef719ec..95b7eb58 100644 --- a/src/network/tcp.py +++ b/src/network/tcp.py @@ -40,6 +40,12 @@ maximumAgeOfNodesThatIAdvertiseToOthers = 10800 #: Equals three hours maximumTimeOffsetWrongCount = 3 #: Connections with wrong time offset +def _ends_with(s, tail): + try: + return s.endswith(tail) + except: + return s.decode("utf-8", "replace").endswith(tail) + class TCPConnection(BMProto, TLSDispatcher): # pylint: disable=too-many-instance-attributes """ @@ -195,7 +201,7 @@ class TCPConnection(BMProto, TLSDispatcher): (k, v) for k, v in six.iteritems(nodes) if v["lastseen"] > int(time.time()) - maximumAgeOfNodesThatIAdvertiseToOthers - and v["rating"] >= 0 and not k.host.endswith('.onion') + and v["rating"] >= 0 and not _ends_with(k.host, '.onion') ] # sent 250 only if the remote isn't interested in it elemCount = min( diff --git a/src/network/udp.py b/src/network/udp.py index e0abe110..d40b2f1b 100644 --- a/src/network/udp.py +++ b/src/network/udp.py @@ -81,7 +81,7 @@ class UDPSocket(BMProto): # pylint: disable=too-many-instance-attributes return True remoteport = False for seenTime, stream, _, ip, port in addresses: - decodedIP = protocol.checkIPAddress(str(ip)) + decodedIP = protocol.checkIPAddress(ip) if stream not in network.connectionpool.pool.streams: continue if (seenTime < time.time() - protocol.MAX_TIME_OFFSET diff --git a/src/protocol.py b/src/protocol.py index 493fefe5..125204fc 100644 --- a/src/protocol.py +++ b/src/protocol.py @@ -170,7 +170,7 @@ def checkIPAddress(host, private=False): otherwise returns False """ if host[0:12] == b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF': - hostStandardFormat = socket.inet_ntop(socket.AF_INET, host[12:]) + hostStandardFormat = socket.inet_ntop(socket.AF_INET, bytes(host[12:])) return checkIPv4Address(host[12:], hostStandardFormat, private) elif host[0:6] == b'\xfd\x87\xd8\x7e\xeb\x43': # Onion, based on BMD/bitcoind @@ -419,7 +419,7 @@ def assembleVersionMessage( return CreatePacket(b'version', payload) -def assembleErrorMessage(fatal=0, banTime=0, inventoryVector='', errorText=''): +def assembleErrorMessage(fatal=0, banTime=0, inventoryVector=b'', errorText=''): """ Construct the payload of an error message, return the resulting bytes of running `CreatePacket` on it @@ -428,6 +428,8 @@ def assembleErrorMessage(fatal=0, banTime=0, inventoryVector='', errorText=''): payload += encodeVarint(banTime) payload += encodeVarint(len(inventoryVector)) payload += inventoryVector + if isinstance(errorText, str): + errorText = errorText.encode("utf-8", "replace") payload += encodeVarint(len(errorText)) payload += errorText return CreatePacket(b'error', payload) -- 2.45.1 From 10e5563d4502f77f1d2d1e9e435a447e89f9d817 Mon Sep 17 00:00:00 2001 From: Kashiko Koibumi Date: Tue, 28 May 2024 13:40:17 +0900 Subject: [PATCH 058/105] misc fixes to run with Python3; part 3 --- src/network/bmproto.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/network/bmproto.py b/src/network/bmproto.py index c051c252..0d6261a4 100644 --- a/src/network/bmproto.py +++ b/src/network/bmproto.py @@ -347,7 +347,7 @@ class BMProto(AdvancedDispatcher, ObjectTracker): if now < self.skipUntil: return True for i in items: - self.pendingUpload[str(i)] = now + self.pendingUpload[i] = now return True def _command_inv(self, dandelion=False): @@ -366,7 +366,7 @@ class BMProto(AdvancedDispatcher, ObjectTracker): if dandelion and not state.dandelion_enabled: return True - for i in map(str, items): + for i in items: if i in state.Inventory and not state.Dandelion.hasHash(i): continue if dandelion and not state.Dandelion.hasHash(i): @@ -456,11 +456,10 @@ class BMProto(AdvancedDispatcher, ObjectTracker): """Incoming addresses, process them""" # not using services for seenTime, stream, _, ip, port in self._decode_addr(): - ip = str(ip) if ( stream not in network.connectionpool.pool.streams # FIXME: should check against complete list - or ip.startswith('bootstrap') + or ip.decode("utf-8", "replace").startswith('bootstrap') ): continue decodedIP = protocol.checkIPAddress(ip) -- 2.45.1 From 822b90edaa56f6097ac146fa85991b25561d8fe8 Mon Sep 17 00:00:00 2001 From: Kashiko Koibumi Date: Tue, 28 May 2024 13:54:58 +0900 Subject: [PATCH 059/105] fix to connect with TLS in Python3 --- src/network/tls.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/network/tls.py b/src/network/tls.py index a66dfc44..1ad5d1a4 100644 --- a/src/network/tls.py +++ b/src/network/tls.py @@ -6,6 +6,7 @@ import os import socket import ssl import sys +import six import network.asyncore_pollchoose as asyncore import paths @@ -58,7 +59,7 @@ class TLSDispatcher(AdvancedDispatcher): self.tlsDone = False self.tlsVersion = "N/A" self.isSSL = False - if ssl.OPENSSL_VERSION_NUMBER >= 0x30000000: + if six.PY3 or ssl.OPENSSL_VERSION_NUMBER >= 0x30000000: self.tlsPrepared = False def state_tls_init(self): @@ -66,7 +67,7 @@ class TLSDispatcher(AdvancedDispatcher): self.isSSL = True self.tlsStarted = True - if ssl.OPENSSL_VERSION_NUMBER >= 0x30000000: + if six.PY3 or ssl.OPENSSL_VERSION_NUMBER >= 0x30000000: self.want_read = self.want_write = True self.set_state("tls_handshake") return False @@ -107,7 +108,7 @@ class TLSDispatcher(AdvancedDispatcher): ciphers=self.ciphers, do_handshake_on_connect=False) self.sslSocket.setblocking(0) self.want_read = self.want_write = True - if ssl.OPENSSL_VERSION_NUMBER >= 0x30000000: + if six.PY3 or ssl.OPENSSL_VERSION_NUMBER >= 0x30000000: self.tlsPrepared = True else: self.set_state("tls_handshake") @@ -158,7 +159,7 @@ class TLSDispatcher(AdvancedDispatcher): try: # wait for write buffer flush if self.tlsStarted and not self.tlsDone and not self.write_buf: - if ssl.OPENSSL_VERSION_NUMBER >= 0x30000000: + if six.PY3 or ssl.OPENSSL_VERSION_NUMBER >= 0x30000000: if not self.tlsPrepared: self.do_tls_init() return @@ -184,7 +185,7 @@ class TLSDispatcher(AdvancedDispatcher): try: # wait for write buffer flush if self.tlsStarted and not self.tlsDone and not self.write_buf: - if ssl.OPENSSL_VERSION_NUMBER >= 0x30000000: + if six.PY3 or ssl.OPENSSL_VERSION_NUMBER >= 0x30000000: if not self.tlsPrepared: self.do_tls_init() return -- 2.45.1 From 2d9d30e1e1c200e848c8153781d1cf0d220f5aa3 Mon Sep 17 00:00:00 2001 From: Kashiko Koibumi Date: Thu, 30 May 2024 01:12:23 +0900 Subject: [PATCH 060/105] fix one of database compatibility problems; others remained --- src/bitmessageqt/__init__.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/bitmessageqt/__init__.py b/src/bitmessageqt/__init__.py index 64d24310..3dcfcef2 100644 --- a/src/bitmessageqt/__init__.py +++ b/src/bitmessageqt/__init__.py @@ -19,6 +19,8 @@ import six from six.moves import range as xrange if six.PY3: from codecs import escape_decode +if six.PY2: + import sqlite3 from unqstr import ustr, unic from dbcompat import dbstr @@ -2927,6 +2929,14 @@ class MyForm(settingsmixin.SMainWindow): return queryreturn = sqlQuery( 'SELECT message FROM inbox WHERE msgid=?', msgid) + # for compatibility + if len(queryreturn) < 1: + if six.PY3: + queryreturn = sqlQuery( + 'SELECT message FROM inbox WHERE msgid=CAST(? AS TEXT)', msgid) + else: # assume six.PY2 + queryreturn = sqlQuery( + 'SELECT message FROM inbox WHERE msgid=?', sqlite3.Binary(msgid)) try: lines_raw = queryreturn[-1][0].split('\n') lines = [] @@ -4154,6 +4164,22 @@ class MyForm(settingsmixin.SMainWindow): else ('inbox', 'msgid') ), msgid ) + # for compatibility + if len(queryreturn) < 1: + if six.PY3: + queryreturn = sqlQuery( + 'SELECT message FROM %s WHERE %s=CAST(? AS TEXT)' % ( + ('sent', 'ackdata') if folder == 'sent' + else ('inbox', 'msgid') + ), msgid + ) + else: # assume six.PY2 + queryreturn = sqlQuery( + 'SELECT message FROM %s WHERE %s=?' % ( + ('sent', 'ackdata') if folder == 'sent' + else ('inbox', 'msgid') + ), sqlite3.Binary(msgid) + ) try: message = queryreturn[-1][0].decode("utf-8", "replace") -- 2.45.1 From e5c065416f9666745e03d2c647736a5c2037fb1e Mon Sep 17 00:00:00 2001 From: Kashiko Koibumi Date: Thu, 30 May 2024 01:49:57 +0900 Subject: [PATCH 061/105] fix types --- src/class_objectProcessor.py | 2 +- src/helper_msgcoding.py | 13 ++++++------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/class_objectProcessor.py b/src/class_objectProcessor.py index 3b555257..a260df76 100644 --- a/src/class_objectProcessor.py +++ b/src/class_objectProcessor.py @@ -1055,7 +1055,7 @@ class objectProcessor(threading.Thread): logger.info('ackdata checksum wrong. Not sending ackdata.') return False command = command.rstrip(b'\x00') - if command != 'object': + if command != b'object': return False return True diff --git a/src/helper_msgcoding.py b/src/helper_msgcoding.py index 62214525..bddb535c 100644 --- a/src/helper_msgcoding.py +++ b/src/helper_msgcoding.py @@ -2,7 +2,6 @@ Message encoding end decoding functions """ -import string import zlib import messagetypes @@ -100,14 +99,14 @@ class MsgDecode(object): def decodeExtended(self, data): """Handle extended encoding""" dc = zlib.decompressobj() - tmp = "" + tmp = b"" while len(tmp) <= config.safeGetInt("zlib", "maxsize"): try: got = dc.decompress( data, config.safeGetInt("zlib", "maxsize") + 1 - len(tmp)) # EOF - if got == "": + if got == b"": break tmp += got data = dc.unconsumed_tail @@ -143,7 +142,7 @@ class MsgDecode(object): def decodeSimple(self, data): """Handle simple encoding""" - bodyPositionIndex = string.find(data, '\nBody:') + bodyPositionIndex = data.find(b'\nBody:') if bodyPositionIndex > 1: subject = data[8:bodyPositionIndex] # Only save and show the first 500 characters of the subject. @@ -151,10 +150,10 @@ class MsgDecode(object): subject = subject[:500] body = data[bodyPositionIndex + 6:] else: - subject = '' + subject = b'' body = data # Throw away any extra lines (headers) after the subject. if subject: subject = subject.splitlines()[0] - self.subject = subject - self.body = body + self.subject = subject.decode("utf-8", "replace") + self.body = body.decode("utf-8", "replace") -- 2.45.1 From c39dd18212adf09f191f943085975d25212db447 Mon Sep 17 00:00:00 2001 From: Kashiko Koibumi Date: Thu, 30 May 2024 02:10:02 +0900 Subject: [PATCH 062/105] fix one of database compatibility problems; others remained --- src/bitmessageqt/__init__.py | 38 +++++++++++++++++++++++++++++++--- src/bitmessageqt/foldertree.py | 2 +- 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/src/bitmessageqt/__init__.py b/src/bitmessageqt/__init__.py index 1cf83e8d..60ab3c82 100644 --- a/src/bitmessageqt/__init__.py +++ b/src/bitmessageqt/__init__.py @@ -16,6 +16,10 @@ from datetime import datetime, timedelta from sqlite3 import register_adapter import six from six.moves import range as xrange +if six.PY3: + from codecs import escape_decode +if six.PY2: + import sqlite3 from unqstr import ustr, unic from PyQt4 import QtCore, QtGui @@ -2943,7 +2947,15 @@ class MyForm(settingsmixin.SMainWindow): if not msgid: return queryreturn = sqlQuery( - '''select message from inbox where msgid=?''', msgid) + 'SELECT message FROM inbox WHERE msgid=?', msgid) + # for compatibility + if len(queryreturn) < 1: + if six.PY3: + queryreturn = sqlQuery( + 'SELECT message FROM inbox WHERE msgid=CAST(? AS TEXT)', msgid) + else: # assume six.PY2 + queryreturn = sqlQuery( + 'SELECT message FROM inbox WHERE msgid=?', sqlite3.Binary(msgid)) if queryreturn != []: for row in queryreturn: messageText, = row @@ -3603,7 +3615,11 @@ class MyForm(settingsmixin.SMainWindow): if messagelist: currentRow = messagelist.currentRow() if currentRow >= 0: - return messagelist.item(currentRow, 3).data() + msgid_str = messagelist.item(currentRow, 3).data() + if six.PY3: + return escape_decode(msgid_str)[0][2:-1] + else: # assume six.PY2 + return msgid_str def getCurrentMessageTextedit(self): currentIndex = self.ui.tabWidget.currentIndex() @@ -4147,11 +4163,27 @@ class MyForm(settingsmixin.SMainWindow): folder = self.getCurrentFolder() if msgid: queryreturn = sqlQuery( - '''SELECT message FROM %s WHERE %s=?''' % ( + 'SELECT message FROM %s WHERE %s=?' % ( ('sent', 'ackdata') if folder == 'sent' else ('inbox', 'msgid') ), msgid ) + # for compatibility + if len(queryreturn) < 1: + if six.PY3: + queryreturn = sqlQuery( + 'SELECT message FROM %s WHERE %s=CAST(? AS TEXT)' % ( + ('sent', 'ackdata') if folder == 'sent' + else ('inbox', 'msgid') + ), msgid + ) + else: # assume six.PY2 + queryreturn = sqlQuery( + 'SELECT message FROM %s WHERE %s=?' % ( + ('sent', 'ackdata') if folder == 'sent' + else ('inbox', 'msgid') + ), sqlite3.Binary(msgid) + ) try: message = queryreturn[-1][0] diff --git a/src/bitmessageqt/foldertree.py b/src/bitmessageqt/foldertree.py index 41a5da83..2d3cf01d 100644 --- a/src/bitmessageqt/foldertree.py +++ b/src/bitmessageqt/foldertree.py @@ -478,7 +478,7 @@ class MessageList_TimeWidget(BMTableWidgetItem): def __init__(self, label=None, unread=False, timestamp=None, msgid=b''): super(MessageList_TimeWidget, self).__init__(label, unread) - self.setData(QtCore.Qt.UserRole, QtCore.QByteArray(msgid)) + self.setData(QtCore.Qt.UserRole, QtCore.QByteArray(bytes(msgid))) self.setData(TimestampRole, int(timestamp)) def __lt__(self, other): -- 2.45.1 From f04a7882fde32a35d60668ff3ac0b469501c2b12 Mon Sep 17 00:00:00 2001 From: Kashiko Koibumi Date: Thu, 30 May 2024 11:15:11 +0900 Subject: [PATCH 063/105] fix for newer versions of Python3 --- src/bitmessageqt/__init__.py | 2 +- src/bitmessageqt/foldertree.py | 5 ++++- src/shutdown.py | 6 +++++- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/bitmessageqt/__init__.py b/src/bitmessageqt/__init__.py index b448422b..bf82525c 100644 --- a/src/bitmessageqt/__init__.py +++ b/src/bitmessageqt/__init__.py @@ -808,7 +808,7 @@ class MyForm(settingsmixin.SMainWindow): elif TTL > 28 * 24 * 60 * 60: # 28 days TTL = 28 * 24 * 60 * 60 self.ui.horizontalSliderTTL.setSliderPosition( - (TTL - 3600) ** (1 / 3.199)) + int((TTL - 3600) ** (1 / 3.199))) self.updateHumanFriendlyTTLDescription(TTL) self.ui.horizontalSliderTTL.valueChanged.connect(self.updateTTL) diff --git a/src/bitmessageqt/foldertree.py b/src/bitmessageqt/foldertree.py index 5d62b4f3..db09a5d6 100644 --- a/src/bitmessageqt/foldertree.py +++ b/src/bitmessageqt/foldertree.py @@ -4,7 +4,10 @@ Folder tree and messagelist widgets definitions. # pylint: disable=too-many-arguments # pylint: disable=attribute-defined-outside-init -from cgi import escape +try: + from cgi import escape +except ImportError: + from html import escape from unqstr import ustr, unic from dbcompat import dbstr diff --git a/src/shutdown.py b/src/shutdown.py index 441d655e..7b875f64 100644 --- a/src/shutdown.py +++ b/src/shutdown.py @@ -23,7 +23,11 @@ def doCleanShutdown(): objectProcessorQueue.put(('checkShutdownVariable', 'no data')) for thread in threading.enumerate(): - if thread.isAlive() and isinstance(thread, StoppableThread): + try: + alive = thread.isAlive() + except AttributeError: + alive = thread.is_alive() + if alive and isinstance(thread, StoppableThread): thread.stopThread() UISignalQueue.put(( -- 2.45.1 From d9efe1cf46d99cd54620e3b437629e513c3acab3 Mon Sep 17 00:00:00 2001 From: Kashiko Koibumi Date: Thu, 30 May 2024 11:15:11 +0900 Subject: [PATCH 064/105] fix for newer versions of Python3 --- src/bitmessageqt/__init__.py | 7 ++++--- src/bitmessageqt/foldertree.py | 5 ++++- src/shutdown.py | 6 +++++- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/bitmessageqt/__init__.py b/src/bitmessageqt/__init__.py index 60ab3c82..dd55124e 100644 --- a/src/bitmessageqt/__init__.py +++ b/src/bitmessageqt/__init__.py @@ -840,9 +840,10 @@ class MyForm(settingsmixin.SMainWindow): TTL = config.getint('bitmessagesettings', 'ttl') if TTL < 3600: # an hour TTL = 3600 - elif TTL > 28*24*60*60: # 28 days - TTL = 28*24*60*60 - self.ui.horizontalSliderTTL.setSliderPosition((TTL - 3600) ** (1/3.199)) + elif TTL > 28 * 24 * 60 * 60: # 28 days + TTL = 28 * 24 * 60 * 60 + self.ui.horizontalSliderTTL.setSliderPosition( + int((TTL - 3600) ** (1 / 3.199))) self.updateHumanFriendlyTTLDescription(TTL) QtCore.QObject.connect(self.ui.horizontalSliderTTL, QtCore.SIGNAL( diff --git a/src/bitmessageqt/foldertree.py b/src/bitmessageqt/foldertree.py index 2d3cf01d..7b40c669 100644 --- a/src/bitmessageqt/foldertree.py +++ b/src/bitmessageqt/foldertree.py @@ -4,7 +4,10 @@ Folder tree and messagelist widgets definitions. # pylint: disable=too-many-arguments,bad-super-call # pylint: disable=attribute-defined-outside-init -from cgi import escape +try: + from cgi import escape +except ImportError: + from html import escape from unqstr import ustr, unic from PyQt4 import QtCore, QtGui diff --git a/src/shutdown.py b/src/shutdown.py index 441d655e..7b875f64 100644 --- a/src/shutdown.py +++ b/src/shutdown.py @@ -23,7 +23,11 @@ def doCleanShutdown(): objectProcessorQueue.put(('checkShutdownVariable', 'no data')) for thread in threading.enumerate(): - if thread.isAlive() and isinstance(thread, StoppableThread): + try: + alive = thread.isAlive() + except AttributeError: + alive = thread.is_alive() + if alive and isinstance(thread, StoppableThread): thread.stopThread() UISignalQueue.put(( -- 2.45.1 From d676ea3ec2997b4842ccbc847f774751eaf674f0 Mon Sep 17 00:00:00 2001 From: Kashiko Koibumi Date: Thu, 30 May 2024 18:13:15 +0900 Subject: [PATCH 065/105] quick workaround for BLOB as TEXT problem (#2247) --- src/api.py | 74 ++++++++++++--- src/bitmessagecurses/__init__.py | 41 ++++++-- src/bitmessagekivy/baseclass/maildetail.py | 7 +- src/bitmessageqt/__init__.py | 103 ++++++++++++++++----- src/bitmessageqt/account.py | 7 +- src/bitmessageqt/foldertree.py | 2 +- src/class_objectProcessor.py | 23 +++-- src/class_singleCleaner.py | 9 +- src/class_singleWorker.py | 62 ++++++++++--- src/class_smtpServer.py | 7 +- src/class_sqlThread.py | 2 +- src/helper_inbox.py | 22 ++++- src/helper_sent.py | 19 +++- src/helper_sql.py | 13 ++- src/protocol.py | 3 +- src/storage/sqlite.py | 1 + src/tests/core.py | 11 ++- src/tests/test_helper_sql.py | 15 ++- 18 files changed, 320 insertions(+), 101 deletions(-) diff --git a/src/api.py b/src/api.py index a4445569..87af4d32 100644 --- a/src/api.py +++ b/src/api.py @@ -67,6 +67,7 @@ import subprocess # nosec B404 import time from binascii import hexlify, unhexlify from struct import pack, unpack +import sqlite3 import six from six.moves import configparser, http_client, xmlrpc_server @@ -953,20 +954,32 @@ class BMRPCDispatcher(object): 23, 'Bool expected in readStatus, saw %s instead.' % type(readStatus)) queryreturn = sqlQuery( - "SELECT read FROM inbox WHERE msgid=?", msgid) + "SELECT read FROM inbox WHERE msgid=?", sqlite3.Binary(msgid)) + if len(queryreturn) < 1: + queryreturn = sqlQuery( + "SELECT read FROM inbox WHERE msgid=CAST(? AS TEXT)", msgid) # UPDATE is slow, only update if status is different try: if (queryreturn[0][0] == 1) != readStatus: - sqlExecute( + rowcount = sqlExecute( "UPDATE inbox set read = ? WHERE msgid=?", - readStatus, msgid) + readStatus, sqlite3.Binary(msgid)) + if rowcount < 1: + rowcount = sqlExecute( + "UPDATE inbox set read = ? WHERE msgid=CAST(? AS TEXT)", + readStatus, msgid) queues.UISignalQueue.put(('changedInboxUnread', None)) except IndexError: pass queryreturn = sqlQuery( "SELECT msgid, toaddress, fromaddress, subject, received, message," - " encodingtype, read FROM inbox WHERE msgid=?", msgid + " encodingtype, read FROM inbox WHERE msgid=?", sqlite3.Binary(msgid) ) + if len(queryreturn) < 1: + queryreturn = sqlQuery( + "SELECT msgid, toaddress, fromaddress, subject, received, message," + " encodingtype, read FROM inbox WHERE msgid=CAST(? AS TEXT)", msgid + ) try: return {"inboxMessage": [ self._dump_inbox_message(*queryreturn[0])]} @@ -1035,8 +1048,14 @@ class BMRPCDispatcher(object): queryreturn = sqlQuery( "SELECT msgid, toaddress, fromaddress, subject, lastactiontime," " message, encodingtype, status, ackdata FROM sent WHERE msgid=?", - msgid + sqlite3.Binary(msgid) ) + if len(queryreturn) < 1: + queryreturn = sqlQuery( + "SELECT msgid, toaddress, fromaddress, subject, lastactiontime," + " message, encodingtype, status, ackdata FROM sent WHERE msgid=CAST(? AS TEXT)", + msgid + ) try: return {"sentMessage": [ self._dump_sent_message(*queryreturn[0]) @@ -1072,8 +1091,14 @@ class BMRPCDispatcher(object): queryreturn = sqlQuery( "SELECT msgid, toaddress, fromaddress, subject, lastactiontime," " message, encodingtype, status, ackdata FROM sent" - " WHERE ackdata=?", ackData + " WHERE ackdata=?", sqlite3.Binary(ackData) ) + if len(queryreturn) < 1: + queryreturn = sqlQuery( + "SELECT msgid, toaddress, fromaddress, subject, lastactiontime," + " message, encodingtype, status, ackdata FROM sent" + " WHERE ackdata=CAST(? AS TEXT)", ackData + ) try: return {"sentMessage": [ @@ -1093,7 +1118,9 @@ class BMRPCDispatcher(object): # Trash if in inbox table helper_inbox.trash(msgid) # Trash if in sent table - sqlExecute("UPDATE sent SET folder='trash' WHERE msgid=?", msgid) + rowcount = sqlExecute("UPDATE sent SET folder='trash' WHERE msgid=?", sqlite3.Binary(msgid)) + if rowcount < 1: + sqlExecute("UPDATE sent SET folder='trash' WHERE msgid=CAST(? AS TEXT)", msgid) return 'Trashed message (assuming message existed).' @command('trashInboxMessage') @@ -1107,7 +1134,9 @@ class BMRPCDispatcher(object): def HandleTrashSentMessage(self, msgid): """Trash sent message by msgid (encoded in hex).""" msgid = self._decode(msgid, "hex") - sqlExecute('''UPDATE sent SET folder='trash' WHERE msgid=?''', msgid) + rowcount = sqlExecute('''UPDATE sent SET folder='trash' WHERE msgid=?''', sqlite3.Binary(msgid)) + if rowcount < 1: + sqlExecute('''UPDATE sent SET folder='trash' WHERE msgid=CAST(? AS TEXT)''', msgid) return 'Trashed sent message (assuming message existed).' @command('sendMessage') @@ -1217,7 +1246,10 @@ class BMRPCDispatcher(object): raise APIError(15, 'Invalid ackData object size.') ackdata = self._decode(ackdata, "hex") queryreturn = sqlQuery( - "SELECT status FROM sent where ackdata=?", ackdata) + "SELECT status FROM sent where ackdata=?", sqlite3.Binary(ackdata)) + if len(queryreturn) < 1: + queryreturn = sqlQuery( + "SELECT status FROM sent where ackdata=CAST(? AS TEXT)", ackdata) try: return queryreturn[0][0] except IndexError: @@ -1354,7 +1386,9 @@ class BMRPCDispatcher(object): """Trash a sent message by ackdata (hex encoded)""" # This API method should only be used when msgid is not available ackdata = self._decode(ackdata, "hex") - sqlExecute("UPDATE sent SET folder='trash' WHERE ackdata=?", ackdata) + rowcount = sqlExecute("UPDATE sent SET folder='trash' WHERE ackdata=?", sqlite3.Binary(ackdata)) + if rowcount < 1: + sqlExecute("UPDATE sent SET folder='trash' WHERE ackdata=CAST(? AS TEXT)", ackdata) return 'Trashed sent message (assuming message existed).' @command('disseminatePubkey') @@ -1421,19 +1455,29 @@ class BMRPCDispatcher(object): # use it we'll need to fill out a field in our inventory database # which is blank by default (first20bytesofencryptedmessage). queryreturn = sqlQuery( - "SELECT hash, payload FROM inventory WHERE tag = ''" - " and objecttype = 2") + "SELECT hash, payload FROM inventory WHERE tag = ?" + " and objecttype = 2", sqlite3.Binary(b"")) + if len(queryreturn) < 1: + queryreturn = sqlQuery( + "SELECT hash, payload FROM inventory WHERE tag = CAST(? AS TEXT)" + " and objecttype = 2", b"") with SqlBulkExecute() as sql: for hash01, payload in queryreturn: readPosition = 16 # Nonce length + time length # Stream Number length readPosition += decodeVarint( payload[readPosition:readPosition + 10])[1] - t = (payload[readPosition:readPosition + 32], hash01) - sql.execute("UPDATE inventory SET tag=? WHERE hash=?", *t) + t = (payload[readPosition:readPosition + 32], sqlite3.Binary(hash01)) + _, rowcount = sql.execute("UPDATE inventory SET tag=? WHERE hash=?", *t) + if rowcount < 1: + t = (payload[readPosition:readPosition + 32], hash01) + sql.execute("UPDATE inventory SET tag=? WHERE hash=CAST(? AS TEXT)", *t) queryreturn = sqlQuery( - "SELECT payload FROM inventory WHERE tag = ?", requestedHash) + "SELECT payload FROM inventory WHERE tag = ?", sqlite3.Binary(requestedHash)) + if len(queryreturn) < 1: + queryreturn = sqlQuery( + "SELECT payload FROM inventory WHERE tag = CAST(? AS TEXT)", requestedHash) return {"receivedMessageDatas": [ {'data': hexlify(payload)} for payload, in queryreturn ]} diff --git a/src/bitmessagecurses/__init__.py b/src/bitmessagecurses/__init__.py index 64fd735b..b87b9dde 100644 --- a/src/bitmessagecurses/__init__.py +++ b/src/bitmessagecurses/__init__.py @@ -17,6 +17,7 @@ import sys import time from textwrap import fill from threading import Timer +import sqlite3 from dialog import Dialog import helper_sent @@ -358,7 +359,9 @@ def handlech(c, stdscr): inbox[inboxcur][1] + "\"") data = "" # pyint: disable=redefined-outer-name - ret = sqlQuery("SELECT message FROM inbox WHERE msgid=?", inbox[inboxcur][0]) + ret = sqlQuery("SELECT message FROM inbox WHERE msgid=?", sqlite3.Binary(inbox[inboxcur][0])) + if len(ret) < 1: + ret = sqlQuery("SELECT message FROM inbox WHERE msgid=CAST(? AS TEXT)", inbox[inboxcur][0]) if ret != []: for row in ret: data, = row @@ -367,12 +370,16 @@ def handlech(c, stdscr): for i, item in enumerate(data.split("\n")): msg += fill(item, replace_whitespace=False) + "\n" scrollbox(d, unicode(ascii(msg)), 30, 80) - sqlExecute("UPDATE inbox SET read=1 WHERE msgid=?", inbox[inboxcur][0]) + rowcount = sqlExecute("UPDATE inbox SET read=1 WHERE msgid=?", sqlite3.Binary(inbox[inboxcur][0])) + if rowcount < 1: + sqlExecute("UPDATE inbox SET read=1 WHERE msgid=CAST(? AS TEXT)", inbox[inboxcur][0]) inbox[inboxcur][7] = 1 else: scrollbox(d, unicode("Could not fetch message.")) elif t == "2": # Mark unread - sqlExecute("UPDATE inbox SET read=0 WHERE msgid=?", inbox[inboxcur][0]) + rowcount = sqlExecute("UPDATE inbox SET read=0 WHERE msgid=?", sqlite3.Binary(inbox[inboxcur][0])) + if rowcount < 1: + sqlExecute("UPDATE inbox SET read=0 WHERE msgid=CAST(? AS TEXT)", inbox[inboxcur][0]) inbox[inboxcur][7] = 0 elif t == "3": # Reply curses.curs_set(1) @@ -396,7 +403,9 @@ def handlech(c, stdscr): if not m[5][:4] == "Re: ": subject = "Re: " + m[5] body = "" - ret = sqlQuery("SELECT message FROM inbox WHERE msgid=?", m[0]) + ret = sqlQuery("SELECT message FROM inbox WHERE msgid=?", sqlite3.Binary(m[0])) + if len(ret) < 1: + ret = sqlQuery("SELECT message FROM inbox WHERE msgid=CAST(? AS TEXT)", m[0]) if ret != []: body = "\n\n------------------------------------------------------\n" for row in ret: @@ -422,7 +431,9 @@ def handlech(c, stdscr): r, t = d.inputbox("Filename", init=inbox[inboxcur][5] + ".txt") if r == d.DIALOG_OK: msg = "" - ret = sqlQuery("SELECT message FROM inbox WHERE msgid=?", inbox[inboxcur][0]) + ret = sqlQuery("SELECT message FROM inbox WHERE msgid=?", sqlite3.Binary(inbox[inboxcur][0])) + if len(ret) < 1: + ret = sqlQuery("SELECT message FROM inbox WHERE msgid=CAST(? AS TEXT)", inbox[inboxcur][0]) if ret != []: for row in ret: msg, = row @@ -432,7 +443,9 @@ def handlech(c, stdscr): else: scrollbox(d, unicode("Could not fetch message.")) elif t == "6": # Move to trash - sqlExecute("UPDATE inbox SET folder='trash' WHERE msgid=?", inbox[inboxcur][0]) + rowcount = sqlExecute("UPDATE inbox SET folder='trash' WHERE msgid=?", sqlite3.Binary(inbox[inboxcur][0])) + if rowcount < 1: + sqlExecute("UPDATE inbox SET folder='trash' WHERE msgid=CAST(? AS TEXT)", inbox[inboxcur][0]) del inbox[inboxcur] scrollbox(d, unicode( "Message moved to trash. There is no interface to view your trash," @@ -464,7 +477,12 @@ def handlech(c, stdscr): ret = sqlQuery( "SELECT message FROM sent WHERE subject=? AND ackdata=?", sentbox[sentcur][4], - sentbox[sentcur][6]) + sqlite3.Binary(sentbox[sentcur][6])) + if len(ret) < 1: + ret = sqlQuery( + "SELECT message FROM sent WHERE subject=? AND ackdata=CAST(? AS TEXT)", + sentbox[sentcur][4], + sentbox[sentcur][6]) if ret != []: for row in ret: data, = row @@ -476,10 +494,15 @@ def handlech(c, stdscr): else: scrollbox(d, unicode("Could not fetch message.")) elif t == "2": # Move to trash - sqlExecute( + rowcount = sqlExecute( "UPDATE sent SET folder='trash' WHERE subject=? AND ackdata=?", sentbox[sentcur][4], - sentbox[sentcur][6]) + sqlite3.Binary(sentbox[sentcur][6])) + if rowcount < 1: + rowcount = sqlExecute( + "UPDATE sent SET folder='trash' WHERE subject=? AND ackdata=CAST(? AS TEXT)", + sentbox[sentcur][4], + sentbox[sentcur][6]) del sentbox[sentcur] scrollbox(d, unicode( "Message moved to trash. There is no interface to view your trash" diff --git a/src/bitmessagekivy/baseclass/maildetail.py b/src/bitmessagekivy/baseclass/maildetail.py index 6ddf322d..3d57ce88 100644 --- a/src/bitmessagekivy/baseclass/maildetail.py +++ b/src/bitmessagekivy/baseclass/maildetail.py @@ -7,6 +7,7 @@ Maildetail screen for inbox, sent, draft and trash. import os from datetime import datetime +import sqlite3 from kivy.core.clipboard import Clipboard from kivy.clock import Clock @@ -111,7 +112,11 @@ class MailDetail(Screen): # pylint: disable=too-many-instance-attributes elif self.kivy_state.detail_page_type == 'inbox': data = sqlQuery( "select toaddress, fromaddress, subject, message, received from inbox" - " where msgid = ?", self.kivy_state.mail_id) + " where msgid = ?", sqlite3.Binary(self.kivy_state.mail_id)) + if len(data) < 1: + data = sqlQuery( + "select toaddress, fromaddress, subject, message, received from inbox" + " where msgid = CAST(? AS TEXT)", self.kivy_state.mail_id) self.assign_mail_details(data) App.get_running_app().set_mail_detail_header() except Exception as e: # pylint: disable=unused-variable diff --git a/src/bitmessageqt/__init__.py b/src/bitmessageqt/__init__.py index 40113b5a..42ef6f80 100644 --- a/src/bitmessageqt/__init__.py +++ b/src/bitmessageqt/__init__.py @@ -14,6 +14,7 @@ import threading import time from datetime import datetime, timedelta from sqlite3 import register_adapter +import sqlite3 from PyQt4 import QtCore, QtGui from PyQt4.QtNetwork import QLocalSocket, QLocalServer @@ -2671,14 +2672,19 @@ class MyForm(settingsmixin.SMainWindow): msgids = [] for i in range(0, idCount): - msgids.append(tableWidget.item(i, 3).data()) + msgids.append(sqlite3.Binary(tableWidget.item(i, 3).data())) for col in xrange(tableWidget.columnCount()): tableWidget.item(i, col).setUnread(False) markread = sqlExecuteChunked( "UPDATE inbox SET read = 1 WHERE msgid IN({0}) AND read=0", - idCount, *msgids + False, idCount, *msgids ) + if markread < 1: + markread = sqlExecuteChunked( + "UPDATE inbox SET read = 1 WHERE msgid IN({0}) AND read=0", + True, idCount, *msgids + ) if markread > 0: self.propagateUnreadCount() @@ -2916,7 +2922,10 @@ class MyForm(settingsmixin.SMainWindow): if not msgid: return queryreturn = sqlQuery( - '''select message from inbox where msgid=?''', msgid) + '''select message from inbox where msgid=?''', sqlite3.Binary(msgid)) + if len(queryreturn) < 1: + queryreturn = sqlQuery( + '''select message from inbox where msgid=CAST(? AS TEXT)''', msgid) if queryreturn != []: for row in queryreturn: messageText, = row @@ -2946,7 +2955,7 @@ class MyForm(settingsmixin.SMainWindow): # modified = 0 for row in tableWidget.selectedIndexes(): currentRow = row.row() - msgid = tableWidget.item(currentRow, 3).data() + msgid = sqlite3.Binary(tableWidget.item(currentRow, 3).data()) msgids.add(msgid) # if not tableWidget.item(currentRow, 0).unread: # modified += 1 @@ -2955,10 +2964,15 @@ class MyForm(settingsmixin.SMainWindow): # for 1081 idCount = len(msgids) # rowcount = - sqlExecuteChunked( + total_row_count = sqlExecuteChunked( '''UPDATE inbox SET read=0 WHERE msgid IN ({0}) AND read=1''', - idCount, *msgids + False, idCount, *msgids ) + if total_row_count < 1: + sqlExecuteChunked( + '''UPDATE inbox SET read=0 WHERE msgid IN ({0}) AND read=1''', + True, idCount, *msgids + ) self.propagateUnreadCount() # tableWidget.selectRow(currentRow + 1) @@ -3038,8 +3052,12 @@ class MyForm(settingsmixin.SMainWindow): currentInboxRow, column_from).address msgid = tableWidget.item(currentInboxRow, 3).data() queryreturn = sqlQuery( - "SELECT message FROM inbox WHERE msgid=?", msgid - ) or sqlQuery("SELECT message FROM sent WHERE ackdata=?", msgid) + "SELECT message FROM inbox WHERE msgid=?", sqlite3.Binary(msgid) + ) or sqlQuery("SELECT message FROM sent WHERE ackdata=?", sqlite3.Binary(msgid)) + if len(queryreturn) < 1: + queryreturn = sqlQuery( + "SELECT message FROM inbox WHERE msgid=CAST(? AS TEXT)", msgid + ) or sqlQuery("SELECT message FROM sent WHERE ackdata=CAST(? AS TEXT)", msgid) if queryreturn != []: for row in queryreturn: messageAtCurrentInboxRow, = row @@ -3213,16 +3231,21 @@ class MyForm(settingsmixin.SMainWindow): )[::-1]: for i in range(r.bottomRow() - r.topRow() + 1): inventoryHashesToTrash.add( - tableWidget.item(r.topRow() + i, 3).data()) + sqlite3.Binary(tableWidget.item(r.topRow() + i, 3).data())) currentRow = r.topRow() self.getCurrentMessageTextedit().setText("") tableWidget.model().removeRows( r.topRow(), r.bottomRow() - r.topRow() + 1) idCount = len(inventoryHashesToTrash) - sqlExecuteChunked( + total_row_count = sqlExecuteChunked( ("DELETE FROM inbox" if folder == "trash" or shifted else "UPDATE inbox SET folder='trash', read=1") + - " WHERE msgid IN ({0})", idCount, *inventoryHashesToTrash) + " WHERE msgid IN ({0})", False, idCount, *inventoryHashesToTrash) + if total_row_count < 1: + sqlExecuteChunked( + ("DELETE FROM inbox" if folder == "trash" or shifted else + "UPDATE inbox SET folder='trash', read=1") + + " WHERE msgid IN ({0})", True, idCount, *inventoryHashesToTrash) tableWidget.selectRow(0 if currentRow == 0 else currentRow - 1) tableWidget.setUpdatesEnabled(True) self.propagateUnreadCount(folder) @@ -3241,16 +3264,20 @@ class MyForm(settingsmixin.SMainWindow): )[::-1]: for i in range(r.bottomRow() - r.topRow() + 1): inventoryHashesToTrash.add( - tableWidget.item(r.topRow() + i, 3).data()) + sqlite3.Binary(tableWidget.item(r.topRow() + i, 3).data())) currentRow = r.topRow() self.getCurrentMessageTextedit().setText("") tableWidget.model().removeRows( r.topRow(), r.bottomRow() - r.topRow() + 1) tableWidget.selectRow(0 if currentRow == 0 else currentRow - 1) idCount = len(inventoryHashesToTrash) - sqlExecuteChunked( + total_row_count = sqlExecuteChunked( "UPDATE inbox SET folder='inbox' WHERE msgid IN({0})", - idCount, *inventoryHashesToTrash) + False, idCount, *inventoryHashesToTrash) + if total_row_count < 1: + sqlExecuteChunked( + "UPDATE inbox SET folder='inbox' WHERE msgid IN({0})", + True, idCount, *inventoryHashesToTrash, as_text=True) tableWidget.selectRow(0 if currentRow == 0 else currentRow - 1) tableWidget.setUpdatesEnabled(True) self.propagateUnreadCount() @@ -3270,7 +3297,10 @@ class MyForm(settingsmixin.SMainWindow): # Retrieve the message data out of the SQL database msgid = tableWidget.item(currentInboxRow, 3).data() queryreturn = sqlQuery( - '''select message from inbox where msgid=?''', msgid) + '''select message from inbox where msgid=?''', sqlite3.Binary(msgid)) + if len(queryreturn) < 1: + queryreturn = sqlQuery( + '''select message from inbox where msgid=CAST(? AS TEXT)''', msgid) if queryreturn != []: for row in queryreturn: message, = row @@ -3301,11 +3331,17 @@ class MyForm(settingsmixin.SMainWindow): while tableWidget.selectedIndexes() != []: currentRow = tableWidget.selectedIndexes()[0].row() ackdataToTrash = tableWidget.item(currentRow, 3).data() - sqlExecute( + rowcount = sqlExecute( "DELETE FROM sent" if folder == "trash" or shifted else "UPDATE sent SET folder='trash'" - " WHERE ackdata = ?", ackdataToTrash + " WHERE ackdata = ?", sqlite3.Binary(ackdataToTrash) ) + if rowcount < 1: + sqlExecute( + "DELETE FROM sent" if folder == "trash" or shifted else + "UPDATE sent SET folder='trash'" + " WHERE ackdata = CAST(? AS TEXT)", ackdataToTrash + ) self.getCurrentMessageTextedit().setPlainText("") tableWidget.removeRow(currentRow) self.updateStatusBar(_translate( @@ -3319,9 +3355,13 @@ class MyForm(settingsmixin.SMainWindow): addressAtCurrentRow = self.ui.tableWidgetInbox.item( currentRow, 0).data(QtCore.Qt.UserRole) toRipe = decodeAddress(addressAtCurrentRow)[3] - sqlExecute( + rowcount = sqlExecute( '''UPDATE sent SET status='forcepow' WHERE toripe=? AND status='toodifficult' and folder='sent' ''', - toRipe) + sqlite3.Binary(toRipe)) + if rowcount < 1: + sqlExecute( + '''UPDATE sent SET status='forcepow' WHERE toripe=CAST(? AS TEXT) AND status='toodifficult' and folder='sent' ''', + toRipe) queryreturn = sqlQuery('''select ackdata FROM sent WHERE status='forcepow' ''') for row in queryreturn: ackdata, = row @@ -4017,7 +4057,9 @@ class MyForm(settingsmixin.SMainWindow): # menu option (Force Send) if it is. if currentRow >= 0: ackData = self.ui.tableWidgetInbox.item(currentRow, 3).data() - queryreturn = sqlQuery('''SELECT status FROM sent where ackdata=?''', ackData) + queryreturn = sqlQuery('''SELECT status FROM sent where ackdata=?''', sqlite3.Binary(ackData)) + if len(queryreturn) < 1: + queryreturn = sqlQuery('''SELECT status FROM sent where ackdata=CAST(? AS TEXT)''', ackData) for row in queryreturn: status, = row if status == 'toodifficult': @@ -4119,8 +4161,15 @@ class MyForm(settingsmixin.SMainWindow): '''SELECT message FROM %s WHERE %s=?''' % ( ('sent', 'ackdata') if folder == 'sent' else ('inbox', 'msgid') - ), msgid + ), sqlite3.Binary(msgid) ) + if len(queryreturn) < 1: + queryreturn = sqlQuery( + '''SELECT message FROM %s WHERE %s=CAST(? AS TEXT)''' % ( + ('sent', 'ackdata') if folder == 'sent' + else ('inbox', 'msgid') + ), msgid + ) try: message = queryreturn[-1][0] @@ -4138,10 +4187,16 @@ class MyForm(settingsmixin.SMainWindow): if tableWidget.item(currentRow, 0).unread is True: self.updateUnreadStatus(tableWidget, currentRow, msgid) # propagate - if folder != 'sent' and sqlExecute( + rowcount = sqlExecute( '''UPDATE inbox SET read=1 WHERE msgid=? AND read=0''', - msgid - ) > 0: + sqlite3.Binary(msgid) + ) + if rowcount < 1: + rowcount = sqlExecute( + '''UPDATE inbox SET read=1 WHERE msgid=CAST(? AS TEXT) AND read=0''', + msgid + ) + if folder != 'sent' and rowcount > 0: self.propagateUnreadCount() messageTextedit.setCurrentFont(QtGui.QFont()) diff --git a/src/bitmessageqt/account.py b/src/bitmessageqt/account.py index 8c82c6f6..5c58b0ec 100644 --- a/src/bitmessageqt/account.py +++ b/src/bitmessageqt/account.py @@ -13,6 +13,7 @@ import inspect import re import sys import time +import sqlite3 from PyQt4 import QtGui @@ -201,13 +202,13 @@ class GatewayAccount(BMAccount): ackdata = genAckPayload(streamNumber, stealthLevel) sqlExecute( '''INSERT INTO sent VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)''', - '', + sqlite3.Binary(''), self.toAddress, - ripe, + sqlite3.Binary(ripe), self.fromAddress, self.subject, self.message, - ackdata, + sqlite3.Binary(ackdata), int(time.time()), # sentTime (this will never change) int(time.time()), # lastActionTime 0, # sleepTill time. This will get set when the POW gets done. diff --git a/src/bitmessageqt/foldertree.py b/src/bitmessageqt/foldertree.py index c50b7d3d..ea4333fb 100644 --- a/src/bitmessageqt/foldertree.py +++ b/src/bitmessageqt/foldertree.py @@ -478,7 +478,7 @@ class MessageList_TimeWidget(BMTableWidgetItem): def __init__(self, label=None, unread=False, timestamp=None, msgid=''): super(MessageList_TimeWidget, self).__init__(label, unread) - self.setData(QtCore.Qt.UserRole, QtCore.QByteArray(msgid)) + self.setData(QtCore.Qt.UserRole, QtCore.QByteArray(bytes(msgid))) self.setData(TimestampRole, int(timestamp)) def __lt__(self, other): diff --git a/src/class_objectProcessor.py b/src/class_objectProcessor.py index 469ccbfa..dc567d4b 100644 --- a/src/class_objectProcessor.py +++ b/src/class_objectProcessor.py @@ -12,6 +12,7 @@ import subprocess # nosec B404 import threading import time from binascii import hexlify +import sqlite3 import helper_bitcoin import helper_inbox @@ -121,7 +122,7 @@ class objectProcessor(threading.Thread): objectType, data = queues.objectProcessorQueue.get() sql.execute( 'INSERT INTO objectprocessorqueue VALUES (?,?)', - objectType, data) + objectType, sqlite3.Binary(data)) numberOfObjectsThatWereInTheObjectProcessorQueue += 1 logger.debug( 'Saved %s objects from the objectProcessorQueue to' @@ -143,9 +144,13 @@ class objectProcessor(threading.Thread): if data[readPosition:] in state.ackdataForWhichImWatching: logger.info('This object is an acknowledgement bound for me.') del state.ackdataForWhichImWatching[data[readPosition:]] - sqlExecute( + rowcount = sqlExecute( "UPDATE sent SET status='ackreceived', lastactiontime=?" - " WHERE ackdata=?", int(time.time()), data[readPosition:]) + " WHERE ackdata=?", int(time.time()), sqlite3.Binary(data[readPosition:])) + if rowcount < 1: + rowcount = sqlExecute( + "UPDATE sent SET status='ackreceived', lastactiontime=?" + " WHERE ackdata=CAST(? AS TEXT)", int(time.time()), data[readPosition:]) queues.UISignalQueue.put(( 'updateSentItemStatusByAckdata', ( data[readPosition:], @@ -333,13 +338,13 @@ class objectProcessor(threading.Thread): if queryreturn != []: logger.info( 'We HAVE used this pubkey personally. Updating time.') - t = (address, addressVersion, dataToStore, + t = (address, addressVersion, sqlite3.Binary(dataToStore), int(time.time()), 'yes') else: logger.info( 'We have NOT used this pubkey personally. Inserting' ' in database.') - t = (address, addressVersion, dataToStore, + t = (address, addressVersion, sqlite3.Binary(dataToStore), int(time.time()), 'no') sqlExecute('''INSERT INTO pubkeys VALUES (?,?,?,?,?)''', *t) self.possibleNewPubkey(address) @@ -395,13 +400,13 @@ class objectProcessor(threading.Thread): if queryreturn != []: logger.info( 'We HAVE used this pubkey personally. Updating time.') - t = (address, addressVersion, dataToStore, + t = (address, addressVersion, sqlite3.Binary(dataToStore), int(time.time()), 'yes') else: logger.info( 'We have NOT used this pubkey personally. Inserting' ' in database.') - t = (address, addressVersion, dataToStore, + t = (address, addressVersion, sqlite3.Binary(dataToStore), int(time.time()), 'no') sqlExecute('''INSERT INTO pubkeys VALUES (?,?,?,?,?)''', *t) self.possibleNewPubkey(address) @@ -592,7 +597,7 @@ class objectProcessor(threading.Thread): '''INSERT INTO pubkeys VALUES (?,?,?,?,?)''', fromAddress, sendersAddressVersionNumber, - decryptedData[:endOfThePublicKeyPosition], + sqlite3.Binary(decryptedData[:endOfThePublicKeyPosition]), int(time.time()), 'yes') @@ -929,7 +934,7 @@ class objectProcessor(threading.Thread): sqlExecute('''INSERT INTO pubkeys VALUES (?,?,?,?,?)''', fromAddress, sendersAddressVersion, - decryptedData[:endOfPubkeyPosition], + sqlite3.Binary(decryptedData[:endOfPubkeyPosition]), int(time.time()), 'yes') diff --git a/src/class_singleCleaner.py b/src/class_singleCleaner.py index 06153dcf..3f3c9140 100644 --- a/src/class_singleCleaner.py +++ b/src/class_singleCleaner.py @@ -22,6 +22,7 @@ It resends messages when there has been no response: import gc import os import time +import sqlite3 import queues import state @@ -177,9 +178,13 @@ class singleCleaner(StoppableThread): 'It has been a long time and we haven\'t heard an acknowledgement' ' to our msg. Sending again.' ) - sqlExecute( + rowcount = sqlExecute( "UPDATE sent SET status = 'msgqueued'" - " WHERE ackdata = ? AND folder = 'sent'", ackdata) + " WHERE ackdata = ? AND folder = 'sent'", sqlite3.Binary(ackdata)) + if rowcount < 1: + sqlExecute( + "UPDATE sent SET status = 'msgqueued'" + " WHERE ackdata = CAST(? AS TEXT) AND folder = 'sent'", ackdata) queues.workerQueue.put(('sendmessage', '')) queues.UISignalQueue.put(( 'updateStatusBar', diff --git a/src/class_singleWorker.py b/src/class_singleWorker.py index f2821f65..60b18efa 100644 --- a/src/class_singleWorker.py +++ b/src/class_singleWorker.py @@ -11,6 +11,7 @@ import time from binascii import hexlify, unhexlify from struct import pack from subprocess import call # nosec +import sqlite3 import defaults import helper_inbox @@ -107,10 +108,15 @@ class singleWorker(StoppableThread): # attach legacy header, always constant (msg/1/1) newack = '\x00\x00\x00\x02\x01\x01' + oldack state.ackdataForWhichImWatching[newack] = 0 - sqlExecute( + rowcount = sqlExecute( '''UPDATE sent SET ackdata=? WHERE ackdata=? AND folder = 'sent' ''', - newack, oldack + sqlite3.Binary(newack), sqlite3.Binary(oldack) ) + if rowcount < 1: + sqlExecute( + '''UPDATE sent SET ackdata=? WHERE ackdata=CAST(? AS TEXT) AND folder = 'sent' ''', + sqlite3.Binary(newack), oldack + ) del state.ackdataForWhichImWatching[oldack] # For the case if user deleted knownnodes @@ -578,11 +584,18 @@ class singleWorker(StoppableThread): )) continue - if not sqlExecute( + rowcount = sqlExecute( '''UPDATE sent SET status='doingbroadcastpow' ''' ''' WHERE ackdata=? AND status='broadcastqueued' ''' ''' AND folder='sent' ''', - ackdata): + sqlite3.Binary(ackdata)) + if rowcount < 1: + rowcount = sqlExecute( + '''UPDATE sent SET status='doingbroadcastpow' ''' + ''' WHERE ackdata=CAST(? AS TEXT) AND status='broadcastqueued' ''' + ''' AND folder='sent' ''', + ackdata) + if rowcount < 1: continue # At this time these pubkeys are 65 bytes long @@ -703,11 +716,17 @@ class singleWorker(StoppableThread): # Update the status of the message in the 'sent' table to have # a 'broadcastsent' status - sqlExecute( + rowcount = sqlExecute( '''UPDATE sent SET msgid=?, status=?, lastactiontime=? ''' ''' WHERE ackdata=? AND folder='sent' ''', - inventoryHash, 'broadcastsent', int(time.time()), ackdata + sqlite3.Binary(inventoryHash), 'broadcastsent', int(time.time()), sqlite3.Binary(ackdata) ) + if rowcount < 1: + sqlExecute( + '''UPDATE sent SET msgid=?, status=?, lastactiontime=? ''' + ''' WHERE ackdata=CAST(? AS TEXT) AND folder='sent' ''', + sqlite3.Binary(inventoryHash), 'broadcastsent', int(time.time()), ackdata + ) def sendMsg(self): """Send a message-type object (assemble the object, perform PoW and put it to the inv announcement queue)""" @@ -1065,10 +1084,15 @@ class singleWorker(StoppableThread): if cond1 or cond2: # The demanded difficulty is more than # we are willing to do. - sqlExecute( + rowcount = sqlExecute( '''UPDATE sent SET status='toodifficult' ''' ''' WHERE ackdata=? AND folder='sent' ''', - ackdata) + sqlite3.Binary(ackdata)) + if rowcount < 1: + sqlExecute( + '''UPDATE sent SET status='toodifficult' ''' + ''' WHERE ackdata=CAST(? AS TEXT) AND folder='sent' ''', + ackdata) queues.UISignalQueue.put(( 'updateSentItemStatusByAckdata', ( ackdata, @@ -1231,10 +1255,15 @@ class singleWorker(StoppableThread): ) except: # noqa:E722 self.logger.warning("highlevelcrypto.encrypt didn't work") - sqlExecute( + rowcount = sqlExecute( '''UPDATE sent SET status='badkey' WHERE ackdata=? AND folder='sent' ''', - ackdata + sqlite3.Binary(ackdata) ) + if rowcount < 1: + sqlExecute( + '''UPDATE sent SET status='badkey' WHERE ackdata=CAST(? AS TEXT) AND folder='sent' ''', + ackdata + ) queues.UISignalQueue.put(( 'updateSentItemStatusByAckdata', ( ackdata, @@ -1337,12 +1366,19 @@ class singleWorker(StoppableThread): newStatus = 'msgsent' # wait 10% past expiration sleepTill = int(time.time() + TTL * 1.1) - sqlExecute( + rowcount = sqlExecute( '''UPDATE sent SET msgid=?, status=?, retrynumber=?, ''' ''' sleeptill=?, lastactiontime=? WHERE ackdata=? AND folder='sent' ''', - inventoryHash, newStatus, retryNumber + 1, - sleepTill, int(time.time()), ackdata + sqlite3.Binary(inventoryHash), newStatus, retryNumber + 1, + sleepTill, int(time.time()), sqlite3.Binary(ackdata) ) + if rowcount < 1: + sqlExecute( + '''UPDATE sent SET msgid=?, status=?, retrynumber=?, ''' + ''' sleeptill=?, lastactiontime=? WHERE ackdata=CAST(? AS TEXT) AND folder='sent' ''', + sqlite3.Binary(inventoryHash), newStatus, retryNumber + 1, + sleepTill, int(time.time()), ackdata + ) # If we are sending to ourselves or a chan, let's put # the message in our own inbox. diff --git a/src/class_smtpServer.py b/src/class_smtpServer.py index 44ea7c9c..45dbb01e 100644 --- a/src/class_smtpServer.py +++ b/src/class_smtpServer.py @@ -12,6 +12,7 @@ import threading import time from email.header import decode_header from email.parser import Parser +import sqlite3 import queues from addresses import decodeAddress @@ -88,13 +89,13 @@ class smtpServerPyBitmessage(smtpd.SMTPServer): ackdata = genAckPayload(streamNumber, stealthLevel) sqlExecute( '''INSERT INTO sent VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)''', - '', + sqlite3.Binary(''), toAddress, - ripe, + sqlite3.Binary(ripe), fromAddress, subject, message, - ackdata, + sqlite3.Binary(ackdata), int(time.time()), # sentTime (this will never change) int(time.time()), # lastActionTime 0, # sleepTill time. This will get set when the POW gets done. diff --git a/src/class_sqlThread.py b/src/class_sqlThread.py index 7df9e253..a2eab646 100644 --- a/src/class_sqlThread.py +++ b/src/class_sqlThread.py @@ -73,7 +73,7 @@ class sqlThread(threading.Thread): '''INSERT INTO subscriptions VALUES''' '''('Bitmessage new releases/announcements','BM-GtovgYdgs7qXPkoYaRgrLFuFKz1SFpsw',1)''') self.cur.execute( - '''CREATE TABLE settings (key blob, value blob, UNIQUE(key) ON CONFLICT REPLACE)''') + '''CREATE TABLE settings (key text, value blob, UNIQUE(key) ON CONFLICT REPLACE)''') self.cur.execute('''INSERT INTO settings VALUES('version','11')''') self.cur.execute('''INSERT INTO settings VALUES('lastvacuumtime',?)''', ( int(time.time()),)) diff --git a/src/helper_inbox.py b/src/helper_inbox.py index 555795df..b20edf94 100644 --- a/src/helper_inbox.py +++ b/src/helper_inbox.py @@ -1,12 +1,15 @@ """Helper Inbox performs inbox messages related operations""" +import sqlite3 + import queues from helper_sql import sqlExecute, sqlQuery def insert(t): """Perform an insert into the "inbox" table""" - sqlExecute('''INSERT INTO inbox VALUES (?,?,?,?,?,?,?,?,?,?)''', *t) + u = [sqlite3.Binary(t[0]), t[1], t[2], t[3], t[4], t[5], t[6], t[7], t[8], sqlite3.Binary(t[9])] + sqlExecute('''INSERT INTO inbox VALUES (?,?,?,?,?,?,?,?,?,?)''', *u) # shouldn't emit changedInboxUnread and displayNewInboxMessage # at the same time # queues.UISignalQueue.put(('changedInboxUnread', None)) @@ -14,22 +17,31 @@ def insert(t): def trash(msgid): """Mark a message in the `inbox` as `trash`""" - sqlExecute('''UPDATE inbox SET folder='trash' WHERE msgid=?''', msgid) + rowcount = sqlExecute('''UPDATE inbox SET folder='trash' WHERE msgid=?''', sqlite3.Binary(msgid)) + if rowcount < 1: + sqlExecute('''UPDATE inbox SET folder='trash' WHERE msgid=CAST(? AS TEXT)''', msgid) queues.UISignalQueue.put(('removeInboxRowByMsgid', msgid)) def delete(ack_data): """Permanent delete message from trash""" - sqlExecute("DELETE FROM inbox WHERE msgid = ?", ack_data) + rowcount = sqlExecute("DELETE FROM inbox WHERE msgid = ?", sqlite3.Binary(ack_data)) + if rowcount < 1: + sqlExecute("DELETE FROM inbox WHERE msgid = CAST(? AS TEXT)", ack_data) def undeleteMessage(msgid): """Undelte the message""" - sqlExecute('''UPDATE inbox SET folder='inbox' WHERE msgid=?''', msgid) + rowcount = sqlExecute('''UPDATE inbox SET folder='inbox' WHERE msgid=?''', sqlite3.Binary(msgid)) + if rowcount < 1: + sqlExecute('''UPDATE inbox SET folder='inbox' WHERE msgid=CAST(? AS TEXT)''', msgid) def isMessageAlreadyInInbox(sigHash): """Check for previous instances of this message""" queryReturn = sqlQuery( - '''SELECT COUNT(*) FROM inbox WHERE sighash=?''', sigHash) + '''SELECT COUNT(*) FROM inbox WHERE sighash=?''', sqlite3.Binary(sigHash)) + if len(queryReturn) < 1: + queryReturn = sqlQuery( + '''SELECT COUNT(*) FROM inbox WHERE sighash=CAST(? AS TEXT)''', sigHash) return queryReturn[0][0] != 0 diff --git a/src/helper_sent.py b/src/helper_sent.py index aa76e756..8dca93e9 100644 --- a/src/helper_sent.py +++ b/src/helper_sent.py @@ -4,6 +4,7 @@ Insert values into sent table import time import uuid +import sqlite3 from addresses import decodeAddress from bmconfigparser import config from helper_ackPayload import genAckPayload @@ -38,7 +39,7 @@ def insert(msgid=None, toAddress='[Broadcast subscribers]', fromAddress=None, su ttl = ttl if ttl else config.getint('bitmessagesettings', 'ttl') - t = (msgid, toAddress, ripe, fromAddress, subject, message, ackdata, + t = (sqlite3.Binary(msgid), toAddress, sqlite3.Binary(ripe), fromAddress, subject, message, sqlite3.Binary(ackdata), sentTime, lastActionTime, sleeptill, status, retryNumber, folder, encoding, ttl) @@ -50,20 +51,30 @@ def insert(msgid=None, toAddress='[Broadcast subscribers]', fromAddress=None, su def delete(ack_data): """Perform Delete query""" - sqlExecute("DELETE FROM sent WHERE ackdata = ?", ack_data) + rowcount = sqlExecute("DELETE FROM sent WHERE ackdata = ?", sqlite3.Binary(ack_data)) + if rowcount < 1: + sqlExecute("DELETE FROM sent WHERE ackdata = CAST(? AS TEXT)", ack_data) def retrieve_message_details(ack_data): """Retrieving Message details""" data = sqlQuery( - "select toaddress, fromaddress, subject, message, received from inbox where msgid = ?", ack_data + "select toaddress, fromaddress, subject, message, received from inbox where msgid = ?", sqlite3.Binary(ack_data) ) + if len(data) < 1: + data = sqlQuery( + "select toaddress, fromaddress, subject, message, received from inbox where msgid = CAST(? AS TEXT)", ack_data + ) return data def trash(ackdata): """Mark a message in the `sent` as `trash`""" rowcount = sqlExecute( - '''UPDATE sent SET folder='trash' WHERE ackdata=?''', ackdata + '''UPDATE sent SET folder='trash' WHERE ackdata=?''', sqlite3.Binary(ackdata) ) + if rowcount < 1: + rowcount = sqlExecute( + '''UPDATE sent SET folder='trash' WHERE ackdata=CAST(? AS TEXT)''', ackdata + ) return rowcount diff --git a/src/helper_sql.py b/src/helper_sql.py index 8dee9e0c..cfacfde9 100644 --- a/src/helper_sql.py +++ b/src/helper_sql.py @@ -61,7 +61,7 @@ def sqlQuery(sql_statement, *args): return queryreturn -def sqlExecuteChunked(sql_statement, idCount, *args): +def sqlExecuteChunked(sql_statement, as_text, idCount, *args): """Execute chunked SQL statement to avoid argument limit""" # SQLITE_MAX_VARIABLE_NUMBER, # unfortunately getting/setting isn't exposed to python @@ -80,9 +80,14 @@ def sqlExecuteChunked(sql_statement, idCount, *args): chunk_slice = args[ i:i + sqlExecuteChunked.chunkSize - (len(args) - idCount) ] - sqlSubmitQueue.put( - sql_statement.format(','.join('?' * len(chunk_slice))) - ) + if as_text: + sqlSubmitQueue.put( + sql_statement.format(','.join('CAST(? AS TEXT)' * len(chunk_slice))) + ) + else: + sqlSubmitQueue.put( + sql_statement.format(','.join('?' * len(chunk_slice))) + ) # first static args, and then iterative chunk sqlSubmitQueue.put( args[0:len(args) - idCount] + chunk_slice diff --git a/src/protocol.py b/src/protocol.py index 7f9830e5..596e0647 100644 --- a/src/protocol.py +++ b/src/protocol.py @@ -12,6 +12,7 @@ import sys import time from binascii import hexlify from struct import Struct, pack, unpack +import sqlite3 import defaults import highlevelcrypto @@ -558,7 +559,7 @@ def decryptAndCheckPubkeyPayload(data, address): hexlify(pubSigningKey), hexlify(pubEncryptionKey) ) - t = (address, addressVersion, storedData, int(time.time()), 'yes') + t = (address, addressVersion, sqlite3.Binary(storedData), int(time.time()), 'yes') sqlExecute('''INSERT INTO pubkeys VALUES (?,?,?,?,?)''', *t) return 'successful' except varintDecodeError: diff --git a/src/storage/sqlite.py b/src/storage/sqlite.py index eb5df098..aa97c52a 100644 --- a/src/storage/sqlite.py +++ b/src/storage/sqlite.py @@ -107,6 +107,7 @@ class SqliteInventory(InventoryStorage): # always use the inventoryLock OUTSIDE of the sqlLock. with SqlBulkExecute() as sql: for objectHash, value in self._inventory.items(): + value = [value[0], value[1], sqlite3.Binary(value[2]), value[3], sqlite3.Binary(value[4])] sql.execute( 'INSERT INTO inventory VALUES (?, ?, ?, ?, ?, ?)', sqlite3.Binary(objectHash), *value) diff --git a/src/tests/core.py b/src/tests/core.py index f1a11a06..aa42ada0 100644 --- a/src/tests/core.py +++ b/src/tests/core.py @@ -15,6 +15,7 @@ import sys import threading import time import unittest +import sqlite3 import protocol import state @@ -345,11 +346,17 @@ class TestCore(unittest.TestCase): subject=subject, message=message ) queryreturn = sqlQuery( - '''select msgid from sent where ackdata=?''', result) + '''select msgid from sent where ackdata=?''', sqlite3.Binary(result)) + if len(queryreturn) < 1: + queryreturn = sqlQuery( + '''select msgid from sent where ackdata=CAST(? AS TEXT)''', result) self.assertNotEqual(queryreturn[0][0] if queryreturn else '', '') column_type = sqlQuery( - '''select typeof(msgid) from sent where ackdata=?''', result) + '''select typeof(msgid) from sent where ackdata=?''', sqlite3.Binary(result)) + if len(column_type) < 1: + column_type = sqlQuery( + '''select typeof(msgid) from sent where ackdata=CAST(? AS TEXT)''', result) self.assertEqual(column_type[0][0] if column_type else '', 'text') @unittest.skipIf(frozen, 'not packed test_pattern into the bundle') diff --git a/src/tests/test_helper_sql.py b/src/tests/test_helper_sql.py index 036bd2c9..50ffbc13 100644 --- a/src/tests/test_helper_sql.py +++ b/src/tests/test_helper_sql.py @@ -1,6 +1,7 @@ """Test cases for helper_sql""" import unittest +import sqlite3 try: # Python 3 @@ -49,8 +50,14 @@ class TestHelperSql(unittest.TestCase): rowcount = helper_sql.sqlExecute( "UPDATE sent SET status = 'msgqueued'" "WHERE ackdata = ? AND folder = 'sent'", - "1710652313", + sqlite3.Binary("1710652313"), ) + if rowcount < 0: + rowcount = helper_sql.sqlExecute( + "UPDATE sent SET status = 'msgqueued'" + "WHERE ackdata = CAST(? AS TEXT) AND folder = 'sent'", + "1710652313", + ) self.assertEqual(mock_sqlsubmitqueue_put.call_count, 3) self.assertEqual(rowcount, 1) @@ -80,7 +87,7 @@ class TestHelperSql(unittest.TestCase): for i in range(0, ID_COUNT): args.append("arg{}".format(i)) total_row_count_return = helper_sql.sqlExecuteChunked( - "INSERT INTO table VALUES {}", ID_COUNT, *args + "INSERT INTO table VALUES {}", False, ID_COUNT, *args ) self.assertEqual(TOTAL_ROW_COUNT, total_row_count_return) self.assertTrue(mock_sqlsubmitqueue_put.called) @@ -97,7 +104,7 @@ class TestHelperSql(unittest.TestCase): for i in range(0, ID_COUNT): args.append("arg{}".format(i)) total_row_count = helper_sql.sqlExecuteChunked( - "INSERT INTO table VALUES {}", ID_COUNT, *args + "INSERT INTO table VALUES {}", False, ID_COUNT, *args ) self.assertEqual(total_row_count, 0) self.assertFalse(mock_sqlsubmitqueue_put.called) @@ -112,7 +119,7 @@ class TestHelperSql(unittest.TestCase): ID_COUNT = 12 args = ["args0", "arg1"] total_row_count = helper_sql.sqlExecuteChunked( - "INSERT INTO table VALUES {}", ID_COUNT, *args + "INSERT INTO table VALUES {}", False, ID_COUNT, *args ) self.assertEqual(total_row_count, 0) self.assertFalse(mock_sqlsubmitqueue_put.called) -- 2.45.1 From 07953592aa95df670f01b600ab904c39c8008374 Mon Sep 17 00:00:00 2001 From: Kashiko Koibumi Date: Thu, 30 May 2024 20:09:16 +0900 Subject: [PATCH 066/105] fix careless mistakes --- src/api.py | 4 ++-- src/bitmessageqt/__init__.py | 2 +- src/tests/core.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/api.py b/src/api.py index 87af4d32..80e9c24d 100644 --- a/src/api.py +++ b/src/api.py @@ -1467,10 +1467,10 @@ class BMRPCDispatcher(object): # Stream Number length readPosition += decodeVarint( payload[readPosition:readPosition + 10])[1] - t = (payload[readPosition:readPosition + 32], sqlite3.Binary(hash01)) + t = (sqlite3.Binary(payload[readPosition:readPosition + 32]), sqlite3.Binary(hash01)) _, rowcount = sql.execute("UPDATE inventory SET tag=? WHERE hash=?", *t) if rowcount < 1: - t = (payload[readPosition:readPosition + 32], hash01) + t = (sqlite3.Binary(payload[readPosition:readPosition + 32]), hash01) sql.execute("UPDATE inventory SET tag=? WHERE hash=CAST(? AS TEXT)", *t) queryreturn = sqlQuery( diff --git a/src/bitmessageqt/__init__.py b/src/bitmessageqt/__init__.py index 42ef6f80..add5fb95 100644 --- a/src/bitmessageqt/__init__.py +++ b/src/bitmessageqt/__init__.py @@ -3277,7 +3277,7 @@ class MyForm(settingsmixin.SMainWindow): if total_row_count < 1: sqlExecuteChunked( "UPDATE inbox SET folder='inbox' WHERE msgid IN({0})", - True, idCount, *inventoryHashesToTrash, as_text=True) + True, idCount, *inventoryHashesToTrash) tableWidget.selectRow(0 if currentRow == 0 else currentRow - 1) tableWidget.setUpdatesEnabled(True) self.propagateUnreadCount() diff --git a/src/tests/core.py b/src/tests/core.py index aa42ada0..c0de4d3b 100644 --- a/src/tests/core.py +++ b/src/tests/core.py @@ -357,7 +357,7 @@ class TestCore(unittest.TestCase): if len(column_type) < 1: column_type = sqlQuery( '''select typeof(msgid) from sent where ackdata=CAST(? AS TEXT)''', result) - self.assertEqual(column_type[0][0] if column_type else '', 'text') + self.assertEqual(column_type[0][0] if column_type else '', 'blob') @unittest.skipIf(frozen, 'not packed test_pattern into the bundle') def test_old_knownnodes_pickle(self): -- 2.45.1 From 31dcbd6d5f12e4bac9935030c11eca2ea887e566 Mon Sep 17 00:00:00 2001 From: Kashiko Koibumi Date: Thu, 30 May 2024 20:59:59 +0900 Subject: [PATCH 067/105] add script to revert BLOB-keys into TEXT-keys --- revert_blob_to_text.sh | 3 +++ src/revert_blob_to_text.py | 52 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) create mode 100755 revert_blob_to_text.sh create mode 100644 src/revert_blob_to_text.py diff --git a/revert_blob_to_text.sh b/revert_blob_to_text.sh new file mode 100755 index 00000000..fbac98c1 --- /dev/null +++ b/revert_blob_to_text.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +python3 pybitmessage/revert_blob_to_text.py "$@" diff --git a/src/revert_blob_to_text.py b/src/revert_blob_to_text.py new file mode 100644 index 00000000..bd38066d --- /dev/null +++ b/src/revert_blob_to_text.py @@ -0,0 +1,52 @@ +import helper_startup +import state +import shutil +import sqlite3 + +expected_ver = 11 + +print("Looking up database file..") +helper_startup.loadConfig() +db_path = state.appdata + "messages.dat" +print("Database path: {}".format(db_path)) +db_backup_path = db_path + ".blob-keys" +print("Backup path: {}".format(db_backup_path)) +shutil.copyfile(db_path, db_backup_path) +print("Copied to backup") + +print() + +print("Open the database") +conn = sqlite3.connect(db_path) +cur = conn.cursor() + +cur.execute("SELECT value FROM settings WHERE key='version';") +ver = int(cur.fetchall()[0][0]) +print("PyBitmessage database version: {}".format(ver)) +if ver != expected_ver: + print("Error: version must be {}".format(expected_ver)) + conn.close() + print("Quitting..") + quit() +print("Version OK") + +print() + +print("Converting..") +q = "UPDATE inbox SET msgid=CAST(msgid AS TEXT), sighash=CAST(sighash AS TEXT);" +print(q) +cur.execute(q) +q = "UPDATE pubkeys SET transmitdata=CAST(transmitdata AS TEXT);" +print(q) +cur.execute(q) +q = "UPDATE sent SET msgid=CAST(msgid AS TEXT), toripe=CAST(toripe AS TEXT), ackdata=CAST(ackdata AS TEXT);" +print(q) +cur.execute(q) + +print("Commiting..") +conn.commit() +print("Conversion done") + +print("Close the database") +conn.close() +print("Finished") -- 2.45.1 From 0ff6b43d6e2bb62d42a2bf72d6cd8b8e1b5d4258 Mon Sep 17 00:00:00 2001 From: Kashiko Koibumi Date: Thu, 30 May 2024 21:19:16 +0900 Subject: [PATCH 068/105] fix imports --- src/network/bmobject.py | 2 +- src/network/bmproto.py | 2 +- src/network/dandelion.py | 6 +++--- src/network/downloadthread.py | 2 +- src/network/invthread.py | 2 +- src/network/objectracker.py | 2 +- src/network/tcp.py | 2 +- src/network/uploadthread.py | 2 +- 8 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/network/bmobject.py b/src/network/bmobject.py index 35798bb9..67652001 100644 --- a/src/network/bmobject.py +++ b/src/network/bmobject.py @@ -7,7 +7,7 @@ import time import protocol import state import network.connectionpool # use long name to address recursive import -import dandelion +from network import dandelion from highlevelcrypto import calculateInventoryHash logger = logging.getLogger('default') diff --git a/src/network/bmproto.py b/src/network/bmproto.py index 8e3841a4..b3e3fe3c 100644 --- a/src/network/bmproto.py +++ b/src/network/bmproto.py @@ -17,7 +17,7 @@ from network import knownnodes import protocol import state import network.connectionpool # use long name to address recursive import -import dandelion +from network import dandelion from bmconfigparser import config from queues import invQueue, objectProcessorQueue, portCheckerQueue from randomtrackingdict import RandomTrackingDict diff --git a/src/network/dandelion.py b/src/network/dandelion.py index 0736a80a..d78cab39 100644 --- a/src/network/dandelion.py +++ b/src/network/dandelion.py @@ -8,7 +8,7 @@ from threading import RLock from time import time import six -from network import connectionpool +import network.connectionpool # use long name to address recursive import import state from queues import invQueue @@ -185,11 +185,11 @@ class Dandelion: # pylint: disable=old-style-class try: # random two connections self.stem = sample( - sorted(connectionpool.BMConnectionPool( + sorted(network.connectionpool.BMConnectionPool( ).outboundConnections.values()), MAX_STEMS) # not enough stems available except ValueError: - self.stem = connectionpool.BMConnectionPool( + self.stem = network.connectionpool.BMConnectionPool( ).outboundConnections.values() self.nodeMap = {} # hashMap stays to cater for pending stems diff --git a/src/network/downloadthread.py b/src/network/downloadthread.py index 34c4b5c3..0962ee14 100644 --- a/src/network/downloadthread.py +++ b/src/network/downloadthread.py @@ -10,7 +10,7 @@ import protocol from network import connectionpool from .objectracker import missingObjects from .threads import StoppableThread -import dandelion +from network import dandelion class DownloadThread(StoppableThread): diff --git a/src/network/invthread.py b/src/network/invthread.py index 8bc1f837..9705b79a 100644 --- a/src/network/invthread.py +++ b/src/network/invthread.py @@ -9,7 +9,7 @@ import addresses import protocol import state from network import connectionpool -import dandelion +from network import dandelion from queues import invQueue from .threads import StoppableThread diff --git a/src/network/objectracker.py b/src/network/objectracker.py index eccbaee3..be2b4219 100644 --- a/src/network/objectracker.py +++ b/src/network/objectracker.py @@ -6,7 +6,7 @@ from threading import RLock import six import network.connectionpool # use long name to address recursive import -import dandelion +from network import dandelion from randomtrackingdict import RandomTrackingDict haveBloom = False diff --git a/src/network/tcp.py b/src/network/tcp.py index 3b27c0f9..3dbc15d2 100644 --- a/src/network/tcp.py +++ b/src/network/tcp.py @@ -17,7 +17,7 @@ import l10n import protocol import state import network.connectionpool # use long name to address recursive import -import dandelion +from network import dandelion from bmconfigparser import config from highlevelcrypto import randomBytes from queues import invQueue, receiveDataQueue, UISignalQueue diff --git a/src/network/uploadthread.py b/src/network/uploadthread.py index e1e8d121..bd5f2d67 100644 --- a/src/network/uploadthread.py +++ b/src/network/uploadthread.py @@ -7,7 +7,7 @@ import helper_random import protocol import state from network import connectionpool -import dandelion +from network import dandelion from randomtrackingdict import RandomTrackingDict from .threads import StoppableThread -- 2.45.1 From 4702dd259331b37a8331315b16f0365153e41dd5 Mon Sep 17 00:00:00 2001 From: Kashiko Koibumi Date: Fri, 31 May 2024 00:49:37 +0900 Subject: [PATCH 069/105] fix TLS configuration bug --- src/network/tls.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/network/tls.py b/src/network/tls.py index 1ad5d1a4..477ef8c6 100644 --- a/src/network/tls.py +++ b/src/network/tls.py @@ -72,14 +72,15 @@ class TLSDispatcher(AdvancedDispatcher): self.set_state("tls_handshake") return False - self.do_tls_init() + return self.do_tls_init() def do_tls_init(self): # Once the connection has been established, # it's safe to wrap the socket. if sys.version_info >= (2, 7, 9): if ssl.OPENSSL_VERSION_NUMBER >= 0x30000000: - context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) + context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER + if self.server_side else ssl.PROTOCOL_TLS_CLIENT) else: context = ssl.create_default_context( purpose=ssl.Purpose.SERVER_AUTH @@ -92,7 +93,7 @@ class TLSDispatcher(AdvancedDispatcher): if ssl.OPENSSL_VERSION_NUMBER >= 0x30000000: context.options = ssl.OP_ALL | ssl.OP_NO_SSLv2 |\ ssl.OP_NO_SSLv3 | ssl.OP_SINGLE_ECDH_USE |\ - ssl.OP_CIPHER_SERVER_PREFERENCE | ssl.OP_NO_TLS1_3 + ssl.OP_CIPHER_SERVER_PREFERENCE | ssl.OP_NO_TLSv1_3 else: context.options = ssl.OP_ALL | ssl.OP_NO_SSLv2 |\ ssl.OP_NO_SSLv3 | ssl.OP_SINGLE_ECDH_USE |\ -- 2.45.1 From f07af4e80395b33d716d8762680c5a1d1f335339 Mon Sep 17 00:00:00 2001 From: Kashiko Koibumi Date: Fri, 31 May 2024 00:49:37 +0900 Subject: [PATCH 070/105] fix TLS configuration bug --- src/network/tls.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/network/tls.py b/src/network/tls.py index 1ad5d1a4..477ef8c6 100644 --- a/src/network/tls.py +++ b/src/network/tls.py @@ -72,14 +72,15 @@ class TLSDispatcher(AdvancedDispatcher): self.set_state("tls_handshake") return False - self.do_tls_init() + return self.do_tls_init() def do_tls_init(self): # Once the connection has been established, # it's safe to wrap the socket. if sys.version_info >= (2, 7, 9): if ssl.OPENSSL_VERSION_NUMBER >= 0x30000000: - context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) + context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER + if self.server_side else ssl.PROTOCOL_TLS_CLIENT) else: context = ssl.create_default_context( purpose=ssl.Purpose.SERVER_AUTH @@ -92,7 +93,7 @@ class TLSDispatcher(AdvancedDispatcher): if ssl.OPENSSL_VERSION_NUMBER >= 0x30000000: context.options = ssl.OP_ALL | ssl.OP_NO_SSLv2 |\ ssl.OP_NO_SSLv3 | ssl.OP_SINGLE_ECDH_USE |\ - ssl.OP_CIPHER_SERVER_PREFERENCE | ssl.OP_NO_TLS1_3 + ssl.OP_CIPHER_SERVER_PREFERENCE | ssl.OP_NO_TLSv1_3 else: context.options = ssl.OP_ALL | ssl.OP_NO_SSLv2 |\ ssl.OP_NO_SSLv3 | ssl.OP_SINGLE_ECDH_USE |\ -- 2.45.1 From 0acae4c044b7953fad85a3c5ef2ffe2058aabf79 Mon Sep 17 00:00:00 2001 From: Kashiko Koibumi Date: Fri, 31 May 2024 00:59:11 +0900 Subject: [PATCH 071/105] fix user agent display --- src/bitmessageqt/networkstatus.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bitmessageqt/networkstatus.py b/src/bitmessageqt/networkstatus.py index 4d241b37..b1d88535 100644 --- a/src/bitmessageqt/networkstatus.py +++ b/src/bitmessageqt/networkstatus.py @@ -145,7 +145,7 @@ class NetworkStatus(QtWidgets.QWidget, RetranslateMixin): 0, 0, QtWidgets.QTableWidgetItem( "%s:%i" % (destination.host, destination.port))) self.tableWidgetConnectionCount.setItem( - 0, 2, QtWidgets.QTableWidgetItem("%s" % (c.userAgent))) + 0, 2, QtWidgets.QTableWidgetItem("%s" % (c.userAgent.decode("utf-8", "replace")))) self.tableWidgetConnectionCount.setItem( 0, 3, QtWidgets.QTableWidgetItem("%s" % (c.tlsVersion))) self.tableWidgetConnectionCount.setItem( -- 2.45.1 From 05b1294ecadfee6a308b9657af8bcd5dbbc160a3 Mon Sep 17 00:00:00 2001 From: Kashiko Koibumi Date: Fri, 31 May 2024 01:15:20 +0900 Subject: [PATCH 072/105] disable UPnP in Python3 temporally --- src/upnp.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/upnp.py b/src/upnp.py index 004f1c6e..35018e53 100644 --- a/src/upnp.py +++ b/src/upnp.py @@ -4,6 +4,7 @@ Complete UPnP port forwarding implementation in separate thread. Reference: http://mattscodecave.com/posts/using-python-and-upnp-to-forward-a-port """ +import six from six.moves import http_client as httplib import re import socket @@ -221,6 +222,10 @@ class uPnPThread(StoppableThread): def run(self): """Start the thread to manage UPnP activity""" + if six.PY3: + logger.warning("UPnP is disabled currently, due to incompleted migration to Python3.") + return + logger.debug("Starting UPnP thread") logger.debug("Local IP: %s", self.localIP) lastSent = 0 -- 2.45.1 From e1661162b66574abd30ddb84203c9a076cfbafa6 Mon Sep 17 00:00:00 2001 From: Kashiko Koibumi Date: Fri, 31 May 2024 01:15:20 +0900 Subject: [PATCH 073/105] disable UPnP in Python3 temporally --- src/upnp.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/upnp.py b/src/upnp.py index fcaee6f7..e3cb04bd 100644 --- a/src/upnp.py +++ b/src/upnp.py @@ -4,6 +4,7 @@ Complete UPnP port forwarding implementation in separate thread. Reference: http://mattscodecave.com/posts/using-python-and-upnp-to-forward-a-port """ +import six from six.moves import http_client as httplib import re import socket @@ -221,6 +222,10 @@ class uPnPThread(StoppableThread): def run(self): """Start the thread to manage UPnP activity""" + if six.PY3: + logger.warning("UPnP is disabled currently, due to incompleted migration to Python3.") + return + logger.debug("Starting UPnP thread") logger.debug("Local IP: %s", self.localIP) lastSent = 0 -- 2.45.1 From 6bb138e48324ec8319d7367842c88e5dec43be12 Mon Sep 17 00:00:00 2001 From: Kashiko Koibumi Date: Fri, 31 May 2024 02:31:41 +0900 Subject: [PATCH 074/105] use hexlify() to display hash ID --- src/network/dandelion.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/network/dandelion.py b/src/network/dandelion.py index d78cab39..e343d5f2 100644 --- a/src/network/dandelion.py +++ b/src/network/dandelion.py @@ -7,6 +7,7 @@ from random import choice, expovariate, sample from threading import RLock from time import time import six +from binascii import hexlify import network.connectionpool # use long name to address recursive import import state @@ -76,7 +77,7 @@ class Dandelion: # pylint: disable=old-style-class if logger.isEnabledFor(logging.DEBUG): logger.debug( '%s entering fluff mode due to %s.', - ''.join('%02x' % six.byte2int(i) for i in hashId), reason) + hexlify(hashId), reason) with self.lock: try: del self.hashMap[bytes(hashId)] -- 2.45.1 From bfda9fe65e171e2268f956f7ebe871259834fadb Mon Sep 17 00:00:00 2001 From: Kashiko Koibumi Date: Fri, 31 May 2024 02:32:58 +0900 Subject: [PATCH 075/105] workaround to invalid tag type tag sometimes contains str type, which causes an error in Python3. --- src/storage/sqlite.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/storage/sqlite.py b/src/storage/sqlite.py index 9d1f32b0..0064262d 100644 --- a/src/storage/sqlite.py +++ b/src/storage/sqlite.py @@ -1,6 +1,7 @@ """ Sqlite Inventory """ +import six import sqlite3 import time from threading import RLock @@ -110,7 +111,10 @@ class SqliteInventory(InventoryStorage): # always use the inventoryLock OUTSIDE of the sqlLock. with SqlBulkExecute() as sql: for objectHash, value in self._inventory.items(): - value = [value[0], value[1], sqlite3.Binary(value[2]), value[3], sqlite3.Binary(value[4])] + tag = value[4] + if six.PY3 and isinstance(tag, str): + tag = tag.encode("utf-8", "replace") + value = [value[0], value[1], sqlite3.Binary(value[2]), value[3], sqlite3.Binary(tag)] sql.execute( 'INSERT INTO inventory VALUES (?, ?, ?, ?, ?, ?)', sqlite3.Binary(objectHash), *value) -- 2.45.1 From a6e980df2ce2177fe40351049cad162d65dc20d0 Mon Sep 17 00:00:00 2001 From: Kashiko Koibumi Date: Fri, 31 May 2024 02:31:41 +0900 Subject: [PATCH 076/105] use hexlify() to display hash ID --- src/network/dandelion.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/network/dandelion.py b/src/network/dandelion.py index d78cab39..e343d5f2 100644 --- a/src/network/dandelion.py +++ b/src/network/dandelion.py @@ -7,6 +7,7 @@ from random import choice, expovariate, sample from threading import RLock from time import time import six +from binascii import hexlify import network.connectionpool # use long name to address recursive import import state @@ -76,7 +77,7 @@ class Dandelion: # pylint: disable=old-style-class if logger.isEnabledFor(logging.DEBUG): logger.debug( '%s entering fluff mode due to %s.', - ''.join('%02x' % six.byte2int(i) for i in hashId), reason) + hexlify(hashId), reason) with self.lock: try: del self.hashMap[bytes(hashId)] -- 2.45.1 From a1d633dc5fd3d323ca719c6c2e9b286660384ced Mon Sep 17 00:00:00 2001 From: Kashiko Koibumi Date: Fri, 31 May 2024 02:32:58 +0900 Subject: [PATCH 077/105] workaround to invalid tag type tag sometimes contains str type, which causes an error in Python3. --- src/storage/sqlite.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/storage/sqlite.py b/src/storage/sqlite.py index 9d1f32b0..0064262d 100644 --- a/src/storage/sqlite.py +++ b/src/storage/sqlite.py @@ -1,6 +1,7 @@ """ Sqlite Inventory """ +import six import sqlite3 import time from threading import RLock @@ -110,7 +111,10 @@ class SqliteInventory(InventoryStorage): # always use the inventoryLock OUTSIDE of the sqlLock. with SqlBulkExecute() as sql: for objectHash, value in self._inventory.items(): - value = [value[0], value[1], sqlite3.Binary(value[2]), value[3], sqlite3.Binary(value[4])] + tag = value[4] + if six.PY3 and isinstance(tag, str): + tag = tag.encode("utf-8", "replace") + value = [value[0], value[1], sqlite3.Binary(value[2]), value[3], sqlite3.Binary(tag)] sql.execute( 'INSERT INTO inventory VALUES (?, ?, ?, ?, ?, ?)', sqlite3.Binary(objectHash), *value) -- 2.45.1 From 047ee359b323ca0981a49e942b72c49dbde9f49a Mon Sep 17 00:00:00 2001 From: Kashiko Koibumi Date: Fri, 31 May 2024 02:52:00 +0900 Subject: [PATCH 078/105] fix unexpected label string --- src/unqstr.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/unqstr.py b/src/unqstr.py index 7c984df9..4c2994b1 100644 --- a/src/unqstr.py +++ b/src/unqstr.py @@ -5,6 +5,8 @@ def ustr(v): if six.PY3: if isinstance(v, str): return v + elif isinstance(v, bytes): + return v.decode("utf-8", "replace") else: return str(v) # assume six.PY2 -- 2.45.1 From 08650d5e8ea4dc6566b42101bdbd27d7ebe2b274 Mon Sep 17 00:00:00 2001 From: Kashiko Koibumi Date: Fri, 31 May 2024 02:52:00 +0900 Subject: [PATCH 079/105] fix unexpected label string --- src/unqstr.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/unqstr.py b/src/unqstr.py index 7c984df9..4c2994b1 100644 --- a/src/unqstr.py +++ b/src/unqstr.py @@ -5,6 +5,8 @@ def ustr(v): if six.PY3: if isinstance(v, str): return v + elif isinstance(v, bytes): + return v.decode("utf-8", "replace") else: return str(v) # assume six.PY2 -- 2.45.1 From 13c5e676e2bdea8c2760ff5d2a768e9aa93abee1 Mon Sep 17 00:00:00 2001 From: Kashiko Koibumi Date: Fri, 31 May 2024 02:59:54 +0900 Subject: [PATCH 080/105] fix user agent format on debug log --- src/network/bmproto.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/bmproto.py b/src/network/bmproto.py index b3e3fe3c..9fae2305 100644 --- a/src/network/bmproto.py +++ b/src/network/bmproto.py @@ -549,7 +549,7 @@ class BMProto(AdvancedDispatcher, ObjectTracker): logger.debug( 'remote node incoming address: %s:%i', self.destination.host, self.peerNode.port) - logger.debug('user agent: %s', self.userAgent) + logger.debug('user agent: %s', self.userAgent.decode("utf-8", "replace")) logger.debug('streams: [%s]', ','.join(map(str, self.streams))) if not self.peerValidityChecks(): # ABORT afterwards -- 2.45.1 From 5af72b02e9c64526653bc439e977721f0fcc30a2 Mon Sep 17 00:00:00 2001 From: Kashiko Koibumi Date: Fri, 31 May 2024 02:59:54 +0900 Subject: [PATCH 081/105] fix user agent format on debug log --- src/network/bmproto.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/bmproto.py b/src/network/bmproto.py index b3e3fe3c..9fae2305 100644 --- a/src/network/bmproto.py +++ b/src/network/bmproto.py @@ -549,7 +549,7 @@ class BMProto(AdvancedDispatcher, ObjectTracker): logger.debug( 'remote node incoming address: %s:%i', self.destination.host, self.peerNode.port) - logger.debug('user agent: %s', self.userAgent) + logger.debug('user agent: %s', self.userAgent.decode("utf-8", "replace")) logger.debug('streams: [%s]', ','.join(map(str, self.streams))) if not self.peerValidityChecks(): # ABORT afterwards -- 2.45.1 From 1ec1b57190dd909e60e58c09623994d6db88fa17 Mon Sep 17 00:00:00 2001 From: Kashiko Koibumi Date: Fri, 31 May 2024 10:02:57 +0900 Subject: [PATCH 082/105] fix to pass tests --- start3.sh => py3start.sh | 0 src/py3bitmessage | 13 +++++++++++++ src/pybitmessage | 0 src/shared.py | 4 ++-- src/tests/test_api.py | 10 ++++++++-- src/tests/test_config_process.py | 3 --- src/tests/test_helper_inbox.py | 5 ++++- src/tests/test_helper_sent.py | 6 ++++-- src/tests/test_logger.py | 2 +- src/tests/test_network.py | 6 +++--- src/tests/test_process.py | 6 +++++- src/tests/test_shared.py | 8 +++++--- 12 files changed, 45 insertions(+), 18 deletions(-) rename start3.sh => py3start.sh (100%) create mode 100755 src/py3bitmessage mode change 100644 => 100755 src/pybitmessage diff --git a/start3.sh b/py3start.sh similarity index 100% rename from start3.sh rename to py3start.sh diff --git a/src/py3bitmessage b/src/py3bitmessage new file mode 100755 index 00000000..6277ea32 --- /dev/null +++ b/src/py3bitmessage @@ -0,0 +1,13 @@ +#!/usr/bin/python3 + +import os +import pkg_resources + +import pybitmessage + +dist = pkg_resources.get_distribution('pybitmessage') +script_file = os.path.join(dist.location, dist.key, 'bitmessagemain.py') +new_globals = globals() +new_globals.update(__file__=script_file) + +execfile(script_file, new_globals) diff --git a/src/pybitmessage b/src/pybitmessage old mode 100644 new mode 100755 diff --git a/src/shared.py b/src/shared.py index ca0b9306..f710d56d 100644 --- a/src/shared.py +++ b/src/shared.py @@ -39,7 +39,7 @@ broadcastSendersForWhichImWatching = {} def isAddressInMyAddressBook(address): """Is address in my addressbook?""" queryreturn = sqlQuery( - '''select address from addressbook where address=?''', + '''select TRUE from addressbook where address=?''', dbstr(address)) return queryreturn != [] @@ -48,7 +48,7 @@ def isAddressInMyAddressBook(address): def isAddressInMySubscriptionsList(address): """Am I subscribed to this address?""" queryreturn = sqlQuery( - '''select * from subscriptions where address=?''', + '''select TRUE from subscriptions where address=?''', dbstr(address)) return queryreturn != [] diff --git a/src/tests/test_api.py b/src/tests/test_api.py index db52cc9c..3ae547d3 100644 --- a/src/tests/test_api.py +++ b/src/tests/test_api.py @@ -23,7 +23,10 @@ from .test_process import TestProcessProto class TestAPIProto(TestProcessProto): """Test case logic for testing API""" - _process_cmd = ['pybitmessage', '-t'] + if six.PY3: + _process_cmd = ['./py3bitmessage', '-t'] + else: # assume six.PY2 + _process_cmd = ['./pybitmessage', '-t'] @classmethod def setUpClass(cls): @@ -58,7 +61,10 @@ class TestAPIShutdown(TestAPIProto): class TestAPI(TestAPIProto): """Main API test case""" - _seed = base64.encodestring(sample_seed) + if six.PY3: + _seed = base64.encodebytes(sample_seed) + else: # assume six.PY2 + _seed = base64.encodestring(sample_seed) def _add_random_address(self, label): addr = self.api.createRandomAddress(base64.encodestring(label)) diff --git a/src/tests/test_config_process.py b/src/tests/test_config_process.py index 9322a2f0..b221aa6f 100644 --- a/src/tests/test_config_process.py +++ b/src/tests/test_config_process.py @@ -6,9 +6,6 @@ import os import tempfile from pybitmessage.bmconfigparser import config from .test_process import TestProcessProto -from .common import skip_python3 - -skip_python3() class TestProcessConfig(TestProcessProto): diff --git a/src/tests/test_helper_inbox.py b/src/tests/test_helper_inbox.py index 8ff60e18..31ccc208 100644 --- a/src/tests/test_helper_inbox.py +++ b/src/tests/test_helper_inbox.py @@ -43,6 +43,7 @@ class TestHelperInbox(unittest.TestCase): @patch("pybitmessage.helper_inbox.sqlExecute") def test_trash(self, mock_sql_execute): # pylint: disable=no-self-use """Test marking a message in the `inbox` as `trash`""" + mock_sql_execute.return_value = 1 mock_msg_id = b"fefkosghsbse92" trash(msgid=mock_msg_id) mock_sql_execute.assert_called_once() @@ -50,6 +51,7 @@ class TestHelperInbox(unittest.TestCase): @patch("pybitmessage.helper_inbox.sqlExecute") def test_delete(self, mock_sql_execute): # pylint: disable=no-self-use """Test for permanent deletion of message from trash""" + mock_sql_execute.return_value = 1 mock_ack_data = genAckPayload() delete(mock_ack_data) mock_sql_execute.assert_called_once() @@ -57,6 +59,7 @@ class TestHelperInbox(unittest.TestCase): @patch("pybitmessage.helper_inbox.sqlExecute") def test_undeleteMessage(self, mock_sql_execute): # pylint: disable=no-self-use """Test for Undelete the message""" + mock_sql_execute.return_value = 1 mock_msg_id = b"fefkosghsbse92" undeleteMessage(msgid=mock_msg_id) mock_sql_execute.assert_called_once() @@ -64,7 +67,7 @@ class TestHelperInbox(unittest.TestCase): @patch("pybitmessage.helper_inbox.sqlQuery") def test_isMessageAlreadyInInbox(self, mock_sql_query): """Test for check for previous instances of this message""" - fake_sigHash = "h4dkn54546" + fake_sigHash = b"h4dkn54546" # if Message is already in Inbox mock_sql_query.return_value = [(1,)] result = isMessageAlreadyInInbox(sigHash=fake_sigHash) diff --git a/src/tests/test_helper_sent.py b/src/tests/test_helper_sent.py index 36bb8bb7..27e5d970 100644 --- a/src/tests/test_helper_sent.py +++ b/src/tests/test_helper_sent.py @@ -45,10 +45,12 @@ class TestHelperSent(unittest.TestCase): @patch("pybitmessage.helper_sent.sqlExecute") def test_delete(self, mock_sql_execute): """Test delete function""" + mock_sql_execute.return_value = 1 delete(b"ack_data") self.assertTrue(mock_sql_execute.called) + import sqlite3 mock_sql_execute.assert_called_once_with( - "DELETE FROM sent WHERE ackdata = ?", b"ack_data" + "DELETE FROM sent WHERE ackdata = ?", sqlite3.Binary(b"ack_data") ) @patch("pybitmessage.helper_sent.sqlQuery") @@ -64,7 +66,7 @@ class TestHelperSent(unittest.TestCase): ) ] mock_sql_query.return_value = return_data - result = retrieve_message_details("12345") + result = retrieve_message_details(b"12345") self.assertEqual(result, return_data) @patch("pybitmessage.helper_sent.sqlExecute") diff --git a/src/tests/test_logger.py b/src/tests/test_logger.py index 636a209f..6e4068fc 100644 --- a/src/tests/test_logger.py +++ b/src/tests/test_logger.py @@ -43,7 +43,7 @@ handlers=default cls._files = cls._files[2:] + ('logging.dat',) cls.log_file = os.path.join(cls.home, 'debug.log') - with open(os.path.join(cls.home, 'logging.dat'), 'wb') as dst: + with open(os.path.join(cls.home, 'logging.dat'), 'w') as dst: dst.write(cls.conf_template.format(cls.log_file, cls.pattern)) super(TestLogger, cls).setUpClass() diff --git a/src/tests/test_network.py b/src/tests/test_network.py index 206117e0..e54f737f 100644 --- a/src/tests/test_network.py +++ b/src/tests/test_network.py @@ -3,11 +3,8 @@ import threading import time -from .common import skip_python3 from .partial import TestPartialRun -skip_python3() - class TestNetwork(TestPartialRun): """A test case for running the network subsystem""" @@ -24,11 +21,14 @@ class TestNetwork(TestPartialRun): # config variable is still used inside of the network ): import network from network import connectionpool, stats + from network.stats import sentBytes, receivedBytes # beware of singleton connectionpool.config = cls.config cls.pool = connectionpool.pool cls.stats = stats + cls.stats.sentBytes = sentBytes + cls.stats.receivedBytes = receivedBytes network.start(cls.config, cls.state) diff --git a/src/tests/test_process.py b/src/tests/test_process.py index 37b34541..9101fe7c 100644 --- a/src/tests/test_process.py +++ b/src/tests/test_process.py @@ -11,6 +11,7 @@ import time import unittest import psutil +import six from .common import cleanup, put_signal_file, skip_python3 @@ -22,7 +23,10 @@ class TestProcessProto(unittest.TestCase): """Test case implementing common logic for external testing: it starts pybitmessage in setUpClass() and stops it in tearDownClass() """ - _process_cmd = ['pybitmessage', '-d'] + if six.PY3: + _process_cmd = ['./py3bitmessage', '-d'] + else: # assume six.PY2 + _process_cmd = ['./pybitmessage', '-d'] _threads_count_min = 15 _threads_count_max = 16 _threads_names = [ diff --git a/src/tests/test_shared.py b/src/tests/test_shared.py index 073f94e7..f53930a1 100644 --- a/src/tests/test_shared.py +++ b/src/tests/test_shared.py @@ -46,7 +46,8 @@ class TestShared(unittest.TestCase): address = sample_address # if address is in MyAddressbook - mock_sql_query.return_value = [bytes(address)] + TRUE = 1 + mock_sql_query.return_value = [TRUE] return_val = isAddressInMyAddressBook(address) mock_sql_query.assert_called_once() self.assertTrue(return_val) @@ -64,7 +65,8 @@ class TestShared(unittest.TestCase): address = sample_address # if address is in MySubscriptionsList - mock_sql_query.return_value = [bytes(address)] + TRUE = 1 + mock_sql_query.return_value = [TRUE] return_val = isAddressInMySubscriptionsList(address) self.assertTrue(return_val) @@ -78,7 +80,7 @@ class TestShared(unittest.TestCase): def test_reloadBroadcastSendersForWhichImWatching(self, mock_sql_query): """Test for reload Broadcast Senders For Which Im Watching""" mock_sql_query.return_value = [ - (bytes(sample_address),), + (bytes(sample_address.encode("utf-8", "replace")),), ] # before reload self.assertEqual(len(MyECSubscriptionCryptorObjects), 0) -- 2.45.1 From 597372543bdb4800dfe02689514d0fc3d3c0815d Mon Sep 17 00:00:00 2001 From: Kashiko Koibumi Date: Fri, 31 May 2024 10:02:57 +0900 Subject: [PATCH 083/105] fix to pass tests --- start3.sh => py3start.sh | 0 src/py3bitmessage | 13 +++++++++++++ src/pybitmessage | 0 src/shared.py | 4 ++-- src/tests/test_api.py | 10 ++++++++-- src/tests/test_config_process.py | 3 --- src/tests/test_helper_inbox.py | 5 ++++- src/tests/test_helper_sent.py | 6 ++++-- src/tests/test_logger.py | 2 +- src/tests/test_network.py | 6 +++--- src/tests/test_process.py | 6 +++++- src/tests/test_shared.py | 8 +++++--- 12 files changed, 45 insertions(+), 18 deletions(-) rename start3.sh => py3start.sh (100%) create mode 100755 src/py3bitmessage mode change 100644 => 100755 src/pybitmessage diff --git a/start3.sh b/py3start.sh similarity index 100% rename from start3.sh rename to py3start.sh diff --git a/src/py3bitmessage b/src/py3bitmessage new file mode 100755 index 00000000..6277ea32 --- /dev/null +++ b/src/py3bitmessage @@ -0,0 +1,13 @@ +#!/usr/bin/python3 + +import os +import pkg_resources + +import pybitmessage + +dist = pkg_resources.get_distribution('pybitmessage') +script_file = os.path.join(dist.location, dist.key, 'bitmessagemain.py') +new_globals = globals() +new_globals.update(__file__=script_file) + +execfile(script_file, new_globals) diff --git a/src/pybitmessage b/src/pybitmessage old mode 100644 new mode 100755 diff --git a/src/shared.py b/src/shared.py index ca0b9306..f710d56d 100644 --- a/src/shared.py +++ b/src/shared.py @@ -39,7 +39,7 @@ broadcastSendersForWhichImWatching = {} def isAddressInMyAddressBook(address): """Is address in my addressbook?""" queryreturn = sqlQuery( - '''select address from addressbook where address=?''', + '''select TRUE from addressbook where address=?''', dbstr(address)) return queryreturn != [] @@ -48,7 +48,7 @@ def isAddressInMyAddressBook(address): def isAddressInMySubscriptionsList(address): """Am I subscribed to this address?""" queryreturn = sqlQuery( - '''select * from subscriptions where address=?''', + '''select TRUE from subscriptions where address=?''', dbstr(address)) return queryreturn != [] diff --git a/src/tests/test_api.py b/src/tests/test_api.py index db52cc9c..3ae547d3 100644 --- a/src/tests/test_api.py +++ b/src/tests/test_api.py @@ -23,7 +23,10 @@ from .test_process import TestProcessProto class TestAPIProto(TestProcessProto): """Test case logic for testing API""" - _process_cmd = ['pybitmessage', '-t'] + if six.PY3: + _process_cmd = ['./py3bitmessage', '-t'] + else: # assume six.PY2 + _process_cmd = ['./pybitmessage', '-t'] @classmethod def setUpClass(cls): @@ -58,7 +61,10 @@ class TestAPIShutdown(TestAPIProto): class TestAPI(TestAPIProto): """Main API test case""" - _seed = base64.encodestring(sample_seed) + if six.PY3: + _seed = base64.encodebytes(sample_seed) + else: # assume six.PY2 + _seed = base64.encodestring(sample_seed) def _add_random_address(self, label): addr = self.api.createRandomAddress(base64.encodestring(label)) diff --git a/src/tests/test_config_process.py b/src/tests/test_config_process.py index 9322a2f0..b221aa6f 100644 --- a/src/tests/test_config_process.py +++ b/src/tests/test_config_process.py @@ -6,9 +6,6 @@ import os import tempfile from pybitmessage.bmconfigparser import config from .test_process import TestProcessProto -from .common import skip_python3 - -skip_python3() class TestProcessConfig(TestProcessProto): diff --git a/src/tests/test_helper_inbox.py b/src/tests/test_helper_inbox.py index 8ff60e18..31ccc208 100644 --- a/src/tests/test_helper_inbox.py +++ b/src/tests/test_helper_inbox.py @@ -43,6 +43,7 @@ class TestHelperInbox(unittest.TestCase): @patch("pybitmessage.helper_inbox.sqlExecute") def test_trash(self, mock_sql_execute): # pylint: disable=no-self-use """Test marking a message in the `inbox` as `trash`""" + mock_sql_execute.return_value = 1 mock_msg_id = b"fefkosghsbse92" trash(msgid=mock_msg_id) mock_sql_execute.assert_called_once() @@ -50,6 +51,7 @@ class TestHelperInbox(unittest.TestCase): @patch("pybitmessage.helper_inbox.sqlExecute") def test_delete(self, mock_sql_execute): # pylint: disable=no-self-use """Test for permanent deletion of message from trash""" + mock_sql_execute.return_value = 1 mock_ack_data = genAckPayload() delete(mock_ack_data) mock_sql_execute.assert_called_once() @@ -57,6 +59,7 @@ class TestHelperInbox(unittest.TestCase): @patch("pybitmessage.helper_inbox.sqlExecute") def test_undeleteMessage(self, mock_sql_execute): # pylint: disable=no-self-use """Test for Undelete the message""" + mock_sql_execute.return_value = 1 mock_msg_id = b"fefkosghsbse92" undeleteMessage(msgid=mock_msg_id) mock_sql_execute.assert_called_once() @@ -64,7 +67,7 @@ class TestHelperInbox(unittest.TestCase): @patch("pybitmessage.helper_inbox.sqlQuery") def test_isMessageAlreadyInInbox(self, mock_sql_query): """Test for check for previous instances of this message""" - fake_sigHash = "h4dkn54546" + fake_sigHash = b"h4dkn54546" # if Message is already in Inbox mock_sql_query.return_value = [(1,)] result = isMessageAlreadyInInbox(sigHash=fake_sigHash) diff --git a/src/tests/test_helper_sent.py b/src/tests/test_helper_sent.py index 36bb8bb7..27e5d970 100644 --- a/src/tests/test_helper_sent.py +++ b/src/tests/test_helper_sent.py @@ -45,10 +45,12 @@ class TestHelperSent(unittest.TestCase): @patch("pybitmessage.helper_sent.sqlExecute") def test_delete(self, mock_sql_execute): """Test delete function""" + mock_sql_execute.return_value = 1 delete(b"ack_data") self.assertTrue(mock_sql_execute.called) + import sqlite3 mock_sql_execute.assert_called_once_with( - "DELETE FROM sent WHERE ackdata = ?", b"ack_data" + "DELETE FROM sent WHERE ackdata = ?", sqlite3.Binary(b"ack_data") ) @patch("pybitmessage.helper_sent.sqlQuery") @@ -64,7 +66,7 @@ class TestHelperSent(unittest.TestCase): ) ] mock_sql_query.return_value = return_data - result = retrieve_message_details("12345") + result = retrieve_message_details(b"12345") self.assertEqual(result, return_data) @patch("pybitmessage.helper_sent.sqlExecute") diff --git a/src/tests/test_logger.py b/src/tests/test_logger.py index 636a209f..6e4068fc 100644 --- a/src/tests/test_logger.py +++ b/src/tests/test_logger.py @@ -43,7 +43,7 @@ handlers=default cls._files = cls._files[2:] + ('logging.dat',) cls.log_file = os.path.join(cls.home, 'debug.log') - with open(os.path.join(cls.home, 'logging.dat'), 'wb') as dst: + with open(os.path.join(cls.home, 'logging.dat'), 'w') as dst: dst.write(cls.conf_template.format(cls.log_file, cls.pattern)) super(TestLogger, cls).setUpClass() diff --git a/src/tests/test_network.py b/src/tests/test_network.py index 206117e0..e54f737f 100644 --- a/src/tests/test_network.py +++ b/src/tests/test_network.py @@ -3,11 +3,8 @@ import threading import time -from .common import skip_python3 from .partial import TestPartialRun -skip_python3() - class TestNetwork(TestPartialRun): """A test case for running the network subsystem""" @@ -24,11 +21,14 @@ class TestNetwork(TestPartialRun): # config variable is still used inside of the network ): import network from network import connectionpool, stats + from network.stats import sentBytes, receivedBytes # beware of singleton connectionpool.config = cls.config cls.pool = connectionpool.pool cls.stats = stats + cls.stats.sentBytes = sentBytes + cls.stats.receivedBytes = receivedBytes network.start(cls.config, cls.state) diff --git a/src/tests/test_process.py b/src/tests/test_process.py index 37b34541..9101fe7c 100644 --- a/src/tests/test_process.py +++ b/src/tests/test_process.py @@ -11,6 +11,7 @@ import time import unittest import psutil +import six from .common import cleanup, put_signal_file, skip_python3 @@ -22,7 +23,10 @@ class TestProcessProto(unittest.TestCase): """Test case implementing common logic for external testing: it starts pybitmessage in setUpClass() and stops it in tearDownClass() """ - _process_cmd = ['pybitmessage', '-d'] + if six.PY3: + _process_cmd = ['./py3bitmessage', '-d'] + else: # assume six.PY2 + _process_cmd = ['./pybitmessage', '-d'] _threads_count_min = 15 _threads_count_max = 16 _threads_names = [ diff --git a/src/tests/test_shared.py b/src/tests/test_shared.py index 073f94e7..f53930a1 100644 --- a/src/tests/test_shared.py +++ b/src/tests/test_shared.py @@ -46,7 +46,8 @@ class TestShared(unittest.TestCase): address = sample_address # if address is in MyAddressbook - mock_sql_query.return_value = [bytes(address)] + TRUE = 1 + mock_sql_query.return_value = [TRUE] return_val = isAddressInMyAddressBook(address) mock_sql_query.assert_called_once() self.assertTrue(return_val) @@ -64,7 +65,8 @@ class TestShared(unittest.TestCase): address = sample_address # if address is in MySubscriptionsList - mock_sql_query.return_value = [bytes(address)] + TRUE = 1 + mock_sql_query.return_value = [TRUE] return_val = isAddressInMySubscriptionsList(address) self.assertTrue(return_val) @@ -78,7 +80,7 @@ class TestShared(unittest.TestCase): def test_reloadBroadcastSendersForWhichImWatching(self, mock_sql_query): """Test for reload Broadcast Senders For Which Im Watching""" mock_sql_query.return_value = [ - (bytes(sample_address),), + (bytes(sample_address.encode("utf-8", "replace")),), ] # before reload self.assertEqual(len(MyECSubscriptionCryptorObjects), 0) -- 2.45.1 From c59b9e6df1314571fc506dc4177f9efa3c9a9bb1 Mon Sep 17 00:00:00 2001 From: Kashiko Koibumi Date: Fri, 31 May 2024 13:17:17 +0900 Subject: [PATCH 084/105] fix bug on dandelion specific with Python3 --- src/network/dandelion.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/network/dandelion.py b/src/network/dandelion.py index e343d5f2..cbc6729b 100644 --- a/src/network/dandelion.py +++ b/src/network/dandelion.py @@ -190,8 +190,8 @@ class Dandelion: # pylint: disable=old-style-class ).outboundConnections.values()), MAX_STEMS) # not enough stems available except ValueError: - self.stem = network.connectionpool.BMConnectionPool( - ).outboundConnections.values() + self.stem = list(network.connectionpool.BMConnectionPool( + ).outboundConnections.values()) self.nodeMap = {} # hashMap stays to cater for pending stems self.refresh = time() + REASSIGN_INTERVAL -- 2.45.1 From ba8ccfc4887b25c087b196706a271e807550f482 Mon Sep 17 00:00:00 2001 From: Kashiko Koibumi Date: Fri, 31 May 2024 13:17:17 +0900 Subject: [PATCH 085/105] fix bug on dandelion specific with Python3 --- src/network/dandelion.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/network/dandelion.py b/src/network/dandelion.py index e343d5f2..cbc6729b 100644 --- a/src/network/dandelion.py +++ b/src/network/dandelion.py @@ -190,8 +190,8 @@ class Dandelion: # pylint: disable=old-style-class ).outboundConnections.values()), MAX_STEMS) # not enough stems available except ValueError: - self.stem = network.connectionpool.BMConnectionPool( - ).outboundConnections.values() + self.stem = list(network.connectionpool.BMConnectionPool( + ).outboundConnections.values()) self.nodeMap = {} # hashMap stays to cater for pending stems self.refresh = time() + REASSIGN_INTERVAL -- 2.45.1 From 8c8553973131c4de21a21e0f38ed01cf169b3228 Mon Sep 17 00:00:00 2001 From: Kashiko Koibumi Date: Fri, 31 May 2024 18:02:23 +0900 Subject: [PATCH 086/105] fix bug in chunked database access --- src/helper_sql.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/helper_sql.py b/src/helper_sql.py index cfacfde9..c5f30851 100644 --- a/src/helper_sql.py +++ b/src/helper_sql.py @@ -81,9 +81,13 @@ def sqlExecuteChunked(sql_statement, as_text, idCount, *args): i:i + sqlExecuteChunked.chunkSize - (len(args) - idCount) ] if as_text: - sqlSubmitQueue.put( - sql_statement.format(','.join('CAST(? AS TEXT)' * len(chunk_slice))) - ) + q = "" + n = len(chunk_slice) + for i in range(n): + q += "CAST(? AS TEXT)" + if i != n - 1: + q += "," + sqlSubmitQueue.put(sql_statement.format(q)) else: sqlSubmitQueue.put( sql_statement.format(','.join('?' * len(chunk_slice))) -- 2.45.1 From a504384c945e6569901e3ab7bea52de8320cfbc0 Mon Sep 17 00:00:00 2001 From: Kashiko Koibumi Date: Fri, 31 May 2024 18:03:39 +0900 Subject: [PATCH 087/105] fix bug in responsibility of message list on Qt GUI --- src/bitmessageqt/__init__.py | 43 +++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/src/bitmessageqt/__init__.py b/src/bitmessageqt/__init__.py index 999a1eea..34544a3a 100644 --- a/src/bitmessageqt/__init__.py +++ b/src/bitmessageqt/__init__.py @@ -92,6 +92,13 @@ def openKeysFile(): os.startfile(keysfile) # pylint: disable=no-member +def as_msgid(id_data): + if six.PY3: + return escape_decode(id_data)[0][2:-1] + else: # assume six.PY2 + return id_data + + class MyForm(settingsmixin.SMainWindow): # the maximum frequency of message sounds in seconds @@ -994,7 +1001,7 @@ class MyForm(settingsmixin.SMainWindow): # related = related.findItems(msgid, QtCore.Qt.MatchExactly), # returns an empty list for rrow in range(related.rowCount()): - if related.item(rrow, 3).data() == msgid: + if as_msgid(related.item(rrow, 3).data()) == msgid: break for col in range(widget.columnCount()): @@ -1914,7 +1921,7 @@ class MyForm(settingsmixin.SMainWindow): # toAddress = sent.item(i, 0).data(QtCore.Qt.UserRole) # decodeAddress(toAddress) - if sent.item(i, 3).data() == ackdata: + if as_msgid(sent.item(i, 3).data()) == ackdata: sent.item(i, 3).setToolTip(textToDisplay) try: newlinePosition = textToDisplay.find('\n') @@ -1937,7 +1944,7 @@ class MyForm(settingsmixin.SMainWindow): ): i = None for i in range(inbox.rowCount()): - if msgid == inbox.item(i, 3).data(): + if msgid == as_msgid(inbox.item(i, 3).data()): break else: continue @@ -2686,7 +2693,7 @@ class MyForm(settingsmixin.SMainWindow): msgids = [] for i in range(0, idCount): - msgids.append(sqlite3.Binary(tableWidget.item(i, 3).data())) + msgids.append(sqlite3.Binary(as_msgid(tableWidget.item(i, 3).data()))) for col in xrange(tableWidget.columnCount()): tableWidget.item(i, col).setUnread(False) @@ -2975,8 +2982,8 @@ class MyForm(settingsmixin.SMainWindow): # modified = 0 for row in tableWidget.selectedIndexes(): currentRow = row.row() - msgid = sqlite3.Binary(tableWidget.item(currentRow, 3).data()) - msgids.add(msgid) + msgid = as_msgid(tableWidget.item(currentRow, 3).data()) + msgids.add(sqlite3.Binary(msgid)) # if not tableWidget.item(currentRow, 0).unread: # modified += 1 self.updateUnreadStatus(tableWidget, currentRow, msgid, False) @@ -3066,7 +3073,7 @@ class MyForm(settingsmixin.SMainWindow): acct = accountClass(toAddressAtCurrentInboxRow) fromAddressAtCurrentInboxRow = tableWidget.item( currentInboxRow, column_from).address - msgid = tableWidget.item(currentInboxRow, 3).data() + msgid = as_msgid(tableWidget.item(currentInboxRow, 3).data()) queryreturn = sqlQuery( "SELECT message FROM inbox WHERE msgid=?", sqlite3.Binary(msgid) ) or sqlQuery("SELECT message FROM sent WHERE ackdata=?", sqlite3.Binary(msgid)) @@ -3225,15 +3232,15 @@ class MyForm(settingsmixin.SMainWindow): messageLists = (messageLists,) for messageList in messageLists: if row is not None: - inventoryHash = messageList.item(row, 3).data() + inventoryHash = as_msgid(messageList.item(row, 3).data()) messageList.removeRow(row) elif inventoryHash is not None: for i in range(messageList.rowCount() - 1, -1, -1): - if messageList.item(i, 3).data() == inventoryHash: + if as_msgid(messageList.item(i, 3).data()) == inventoryHash: messageList.removeRow(i) elif ackData is not None: for i in range(messageList.rowCount() - 1, -1, -1): - if messageList.item(i, 3).data() == ackData: + if as_msgid(messageList.item(i, 3).data()) == ackData: messageList.removeRow(i) # Send item on the Inbox tab to trash @@ -3253,7 +3260,7 @@ class MyForm(settingsmixin.SMainWindow): )[::-1]: for i in range(r.bottomRow() - r.topRow() + 1): inventoryHashesToTrash.add( - sqlite3.Binary(tableWidget.item(r.topRow() + i, 3).data())) + sqlite3.Binary(as_msgid(tableWidget.item(r.topRow() + i, 3).data()))) currentRow = r.topRow() self.getCurrentMessageTextedit().setText("") tableWidget.model().removeRows( @@ -3286,7 +3293,7 @@ class MyForm(settingsmixin.SMainWindow): )[::-1]: for i in range(r.bottomRow() - r.topRow() + 1): inventoryHashesToTrash.add( - sqlite3.Binary(tableWidget.item(r.topRow() + i, 3).data())) + sqlite3.Binary(as_msgid(tableWidget.item(r.topRow() + i, 3).data()))) currentRow = r.topRow() self.getCurrentMessageTextedit().setText("") tableWidget.model().removeRows( @@ -3317,7 +3324,7 @@ class MyForm(settingsmixin.SMainWindow): subjectAtCurrentInboxRow = '' # Retrieve the message data out of the SQL database - msgid = tableWidget.item(currentInboxRow, 3).data() + msgid = as_msgid(tableWidget.item(currentInboxRow, 3).data()) queryreturn = sqlQuery( 'SELECT message FROM inbox WHERE msgid=?', sqlite3.Binary(msgid)) if len(queryreturn) < 1: @@ -3354,7 +3361,7 @@ class MyForm(settingsmixin.SMainWindow): QtCore.Qt.ShiftModifier) while tableWidget.selectedIndexes() != []: currentRow = tableWidget.selectedIndexes()[0].row() - ackdataToTrash = tableWidget.item(currentRow, 3).data() + ackdataToTrash = as_msgid(tableWidget.item(currentRow, 3).data()) rowcount = sqlExecute( "DELETE FROM sent" if folder == "trash" or shifted else "UPDATE sent SET folder='trash'" @@ -3637,11 +3644,7 @@ class MyForm(settingsmixin.SMainWindow): if messagelist: currentRow = messagelist.currentRow() if currentRow >= 0: - msgid_str = messagelist.item(currentRow, 3).data() - if six.PY3: - return escape_decode(msgid_str)[0][2:-1] - else: # assume six.PY2 - return msgid_str + return as_msgid(messagelist.item(currentRow, 3).data()) def getCurrentMessageTextedit(self): currentIndex = self.ui.tabWidget.currentIndex() @@ -4086,7 +4089,7 @@ class MyForm(settingsmixin.SMainWindow): # Check to see if this item is toodifficult and display an additional # menu option (Force Send) if it is. if currentRow >= 0: - ackData = self.ui.tableWidgetInbox.item(currentRow, 3).data() + ackData = as_msgid(self.ui.tableWidgetInbox.item(currentRow, 3).data()) queryreturn = sqlQuery('''SELECT status FROM sent where ackdata=?''', sqlite3.Binary(ackData)) if len(queryreturn) < 1: queryreturn = sqlQuery('''SELECT status FROM sent where ackdata=CAST(? AS TEXT)''', ackData) -- 2.45.1 From f9d236444fb118df31af13452ed81fbb2351150b Mon Sep 17 00:00:00 2001 From: Kashiko Koibumi Date: Fri, 31 May 2024 18:02:23 +0900 Subject: [PATCH 088/105] fix bug in chunked database access --- src/helper_sql.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/helper_sql.py b/src/helper_sql.py index cfacfde9..c5f30851 100644 --- a/src/helper_sql.py +++ b/src/helper_sql.py @@ -81,9 +81,13 @@ def sqlExecuteChunked(sql_statement, as_text, idCount, *args): i:i + sqlExecuteChunked.chunkSize - (len(args) - idCount) ] if as_text: - sqlSubmitQueue.put( - sql_statement.format(','.join('CAST(? AS TEXT)' * len(chunk_slice))) - ) + q = "" + n = len(chunk_slice) + for i in range(n): + q += "CAST(? AS TEXT)" + if i != n - 1: + q += "," + sqlSubmitQueue.put(sql_statement.format(q)) else: sqlSubmitQueue.put( sql_statement.format(','.join('?' * len(chunk_slice))) -- 2.45.1 From f8919a8f6673f15e78ac40488c5aba98ea9a06b6 Mon Sep 17 00:00:00 2001 From: Kashiko Koibumi Date: Fri, 31 May 2024 18:03:39 +0900 Subject: [PATCH 089/105] fix bug in responsibility of message list on Qt GUI --- src/bitmessageqt/__init__.py | 45 ++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/src/bitmessageqt/__init__.py b/src/bitmessageqt/__init__.py index 7f87122c..9b6461d1 100644 --- a/src/bitmessageqt/__init__.py +++ b/src/bitmessageqt/__init__.py @@ -91,6 +91,13 @@ def openKeysFile(): os.startfile(keysfile) # pylint: disable=no-member +def as_msgid(id_data): + if six.PY3: + return escape_decode(id_data)[0][2:-1] + else: # assume six.PY2 + return id_data + + class MyForm(settingsmixin.SMainWindow): # the maximum frequency of message sounds in seconds @@ -1033,7 +1040,7 @@ class MyForm(settingsmixin.SMainWindow): # related = related.findItems(msgid, QtCore.Qt.MatchExactly), # returns an empty list for rrow in range(related.rowCount()): - if related.item(rrow, 3).data() == msgid: + if as_msgid(related.item(rrow, 3).data()) == msgid: break for col in range(widget.columnCount()): @@ -1938,8 +1945,6 @@ class MyForm(settingsmixin.SMainWindow): sent.item(i, 3).setText(textToDisplay) def updateSentItemStatusByAckdata(self, ackdata, textToDisplay): - if type(ackdata) is str: - ackdata = QtCore.QByteArray(ackdata) for sent in ( self.ui.tableWidgetInbox, self.ui.tableWidgetInboxSubscriptions, @@ -1950,7 +1955,7 @@ class MyForm(settingsmixin.SMainWindow): continue for i in range(sent.rowCount()): toAddress = sent.item(i, 0).data(QtCore.Qt.UserRole) - tableAckdata = sent.item(i, 3).data() + tableAckdata = as_msgid(sent.item(i, 3).data()) status, addressVersionNumber, streamNumber, ripe = decodeAddress( toAddress) if ackdata == tableAckdata: @@ -1976,7 +1981,7 @@ class MyForm(settingsmixin.SMainWindow): ): i = None for i in range(inbox.rowCount()): - if msgid == inbox.item(i, 3).data(): + if msgid == as_msgid(inbox.item(i, 3).data()): break else: continue @@ -2702,7 +2707,7 @@ class MyForm(settingsmixin.SMainWindow): msgids = [] for i in range(0, idCount): - msgids.append(sqlite3.Binary(tableWidget.item(i, 3).data())) + msgids.append(sqlite3.Binary(as_msgid(tableWidget.item(i, 3).data()))) for col in xrange(tableWidget.columnCount()): tableWidget.item(i, col).setUnread(False) @@ -2986,8 +2991,8 @@ class MyForm(settingsmixin.SMainWindow): # modified = 0 for row in tableWidget.selectedIndexes(): currentRow = row.row() - msgid = sqlite3.Binary(tableWidget.item(currentRow, 3).data()) - msgids.add(msgid) + msgid = as_msgid(tableWidget.item(currentRow, 3).data()) + msgids.add(sqlite3.Binary(msgid)) # if not tableWidget.item(currentRow, 0).unread: # modified += 1 self.updateUnreadStatus(tableWidget, currentRow, msgid, False) @@ -3081,7 +3086,7 @@ class MyForm(settingsmixin.SMainWindow): acct = accountClass(toAddressAtCurrentInboxRow) fromAddressAtCurrentInboxRow = tableWidget.item( currentInboxRow, column_from).address - msgid = tableWidget.item(currentInboxRow, 3).data() + msgid = as_msgid(tableWidget.item(currentInboxRow, 3).data()) queryreturn = sqlQuery( "SELECT message FROM inbox WHERE msgid=?", sqlite3.Binary(msgid) ) or sqlQuery("SELECT message FROM sent WHERE ackdata=?", sqlite3.Binary(msgid)) @@ -3235,15 +3240,15 @@ class MyForm(settingsmixin.SMainWindow): messageLists = (messageLists,) for messageList in messageLists: if row is not None: - inventoryHash = messageList.item(row, 3).data() + inventoryHash = as_msgid(messageList.item(row, 3).data()) messageList.removeRow(row) elif inventoryHash is not None: for i in range(messageList.rowCount() - 1, -1, -1): - if messageList.item(i, 3).data() == inventoryHash: + if as_msgid(messageList.item(i, 3).data()) == inventoryHash: messageList.removeRow(i) elif ackData is not None: for i in range(messageList.rowCount() - 1, -1, -1): - if messageList.item(i, 3).data() == ackData: + if as_msgid(messageList.item(i, 3).data()) == ackData: messageList.removeRow(i) # Send item on the Inbox tab to trash @@ -3263,7 +3268,7 @@ class MyForm(settingsmixin.SMainWindow): )[::-1]: for i in range(r.bottomRow() - r.topRow() + 1): inventoryHashesToTrash.add( - sqlite3.Binary(tableWidget.item(r.topRow() + i, 3).data())) + sqlite3.Binary(as_msgid(tableWidget.item(r.topRow() + i, 3).data()))) currentRow = r.topRow() self.getCurrentMessageTextedit().setText("") tableWidget.model().removeRows( @@ -3296,7 +3301,7 @@ class MyForm(settingsmixin.SMainWindow): )[::-1]: for i in range(r.bottomRow() - r.topRow() + 1): inventoryHashesToTrash.add( - sqlite3.Binary(tableWidget.item(r.topRow() + i, 3).data())) + sqlite3.Binary(as_msgid(tableWidget.item(r.topRow() + i, 3).data()))) currentRow = r.topRow() self.getCurrentMessageTextedit().setText("") tableWidget.model().removeRows( @@ -3327,7 +3332,7 @@ class MyForm(settingsmixin.SMainWindow): subjectAtCurrentInboxRow = '' # Retrieve the message data out of the SQL database - msgid = tableWidget.item(currentInboxRow, 3).data() + msgid = as_msgid(tableWidget.item(currentInboxRow, 3).data()) queryreturn = sqlQuery( '''select message from inbox where msgid=?''', sqlite3.Binary(msgid)) if len(queryreturn) < 1: @@ -3363,7 +3368,7 @@ class MyForm(settingsmixin.SMainWindow): shifted = QtGui.QApplication.queryKeyboardModifiers() & QtCore.Qt.ShiftModifier while tableWidget.selectedIndexes() != []: currentRow = tableWidget.selectedIndexes()[0].row() - ackdataToTrash = tableWidget.item(currentRow, 3).data() + ackdataToTrash = as_msgid(tableWidget.item(currentRow, 3).data()) rowcount = sqlExecute( "DELETE FROM sent" if folder == "trash" or shifted else "UPDATE sent SET folder='trash'" @@ -3646,11 +3651,7 @@ class MyForm(settingsmixin.SMainWindow): if messagelist: currentRow = messagelist.currentRow() if currentRow >= 0: - msgid_str = messagelist.item(currentRow, 3).data() - if six.PY3: - return escape_decode(msgid_str)[0][2:-1] - else: # assume six.PY2 - return msgid_str + return as_msgid(messagelist.item(currentRow, 3).data()) def getCurrentMessageTextedit(self): currentIndex = self.ui.tabWidget.currentIndex() @@ -4093,7 +4094,7 @@ class MyForm(settingsmixin.SMainWindow): # Check to see if this item is toodifficult and display an additional # menu option (Force Send) if it is. if currentRow >= 0: - ackData = self.ui.tableWidgetInbox.item(currentRow, 3).data() + ackData = as_msgid(self.ui.tableWidgetInbox.item(currentRow, 3).data()) queryreturn = sqlQuery('''SELECT status FROM sent where ackdata=?''', sqlite3.Binary(ackData)) if len(queryreturn) < 1: queryreturn = sqlQuery('''SELECT status FROM sent where ackdata=CAST(? AS TEXT)''', ackData) -- 2.45.1 From de0cd04772daf6a6e9f1867ee2d3c0057ea23e99 Mon Sep 17 00:00:00 2001 From: Kashiko Koibumi Date: Sat, 1 Jun 2024 06:01:32 +0900 Subject: [PATCH 090/105] fix SOCKS --- src/network/socks4a.py | 12 ++++++------ src/network/socks5.py | 20 ++++++++++---------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/network/socks4a.py b/src/network/socks4a.py index bf0adf29..122114b3 100644 --- a/src/network/socks4a.py +++ b/src/network/socks4a.py @@ -40,11 +40,11 @@ class Socks4a(Proxy): def state_pre_connect(self): """Handle feedback from SOCKS4a while it is connecting on our behalf""" # Get the response - if self.read_buf[0:1] != six.int2byte(0x00).encode(): + if self.read_buf[0:1] != six.int2byte(0x00): # bad data self.close() raise GeneralProxyError(1) - elif self.read_buf[1:2] != six.int2byte(0x5A).encode(): + elif self.read_buf[1:2] != six.int2byte(0x5A): # Connection failed self.close() if six.byte2int(self.read_buf[1:2]) in (91, 92, 93): @@ -103,9 +103,9 @@ class Socks4aConnection(Socks4a): self.append_write_buf(self.ipaddr) if self._auth: self.append_write_buf(self._auth[0]) - self.append_write_buf(six.int2byte(0x00).encode()) + self.append_write_buf(six.int2byte(0x00)) if rmtrslv: - self.append_write_buf(self.destination[0] + six.int2byte(0x00).encode()) + self.append_write_buf(self.destination[0].encode("utf-8", "replace") + six.int2byte(0x00)) self.set_state("pre_connect", length=0, expectBytes=8) return True @@ -133,8 +133,8 @@ class Socks4aResolver(Socks4a): self.append_write_buf(struct.pack("BBBB", 0x00, 0x00, 0x00, 0x01)) if self._auth: self.append_write_buf(self._auth[0]) - self.append_write_buf(six.int2byte(0x00).encode()) - self.append_write_buf(self.host + six.int2byte(0x00).encode()) + self.append_write_buf(six.int2byte(0x00)) + self.append_write_buf(self.host + six.int2byte(0x00)) self.set_state("pre_connect", length=0, expectBytes=8) return True diff --git a/src/network/socks5.py b/src/network/socks5.py index c295480c..ca5a52e8 100644 --- a/src/network/socks5.py +++ b/src/network/socks5.py @@ -98,10 +98,10 @@ class Socks5(Proxy): def state_pre_connect(self): """Handle feedback from socks5 while it is connecting on our behalf.""" # Get the response - if self.read_buf[0:1] != six.int2byte(0x05).encode(): + if self.read_buf[0:1] != six.int2byte(0x05): self.close() raise GeneralProxyError(1) - elif self.read_buf[1:2] != six.int2byte(0x00).encode(): + elif self.read_buf[1:2] != six.int2byte(0x00): # Connection failed self.close() if six.byte2int(self.read_buf[1:2]) <= 8: @@ -109,9 +109,9 @@ class Socks5(Proxy): else: raise Socks5Error(9) # Get the bound address/port - elif self.read_buf[3:4] == six.int2byte(0x01).encode(): + elif self.read_buf[3:4] == six.int2byte(0x01): self.set_state("proxy_addr_1", length=4, expectBytes=4) - elif self.read_buf[3:4] == six.int2byte(0x03).encode(): + elif self.read_buf[3:4] == six.int2byte(0x03): self.set_state("proxy_addr_2_1", length=4, expectBytes=1) else: self.close() @@ -172,19 +172,19 @@ class Socks5Connection(Socks5): # use the IPv4 address request even if remote resolving was specified. try: self.ipaddr = socket.inet_aton(self.destination[0]) - self.append_write_buf(six.int2byte(0x01).encode() + self.ipaddr) + self.append_write_buf(six.int2byte(0x01) + self.ipaddr) except socket.error: # may be IPv6! # Well it's not an IP number, so it's probably a DNS name. if self._remote_dns: # Resolve remotely self.ipaddr = None - self.append_write_buf(six.int2byte(0x03).encode() + six.int2byte( - len(self.destination[0])).encode() + self.destination[0]) + self.append_write_buf(six.int2byte(0x03) + six.int2byte( + len(self.destination[0])) + self.destination[0].encode("utf-8", "replace")) else: # Resolve locally self.ipaddr = socket.inet_aton( socket.gethostbyname(self.destination[0])) - self.append_write_buf(six.int2byte(0x01).encode() + self.ipaddr) + self.append_write_buf(six.int2byte(0x01) + self.ipaddr) self.append_write_buf(struct.pack(">H", self.destination[1])) self.set_state("pre_connect", length=0, expectBytes=4) return True @@ -209,8 +209,8 @@ class Socks5Resolver(Socks5): """Perform resolving""" # Now we can request the actual connection self.append_write_buf(struct.pack('BBB', 0x05, 0xF0, 0x00)) - self.append_write_buf(six.int2byte(0x03).encode() + six.int2byte( - len(self.host)).encode() + str(self.host)) + self.append_write_buf(six.int2byte(0x03) + six.int2byte( + len(self.host)) + bytes(self.host)) self.append_write_buf(struct.pack(">H", self.port)) self.set_state("pre_connect", length=0, expectBytes=4) return True -- 2.45.1 From 9adcd1bdc980b82eeb31adb12113968bf8cc557a Mon Sep 17 00:00:00 2001 From: Kashiko Koibumi Date: Sat, 1 Jun 2024 06:01:32 +0900 Subject: [PATCH 091/105] fix SOCKS --- src/network/socks4a.py | 12 ++++++------ src/network/socks5.py | 20 ++++++++++---------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/network/socks4a.py b/src/network/socks4a.py index bf0adf29..122114b3 100644 --- a/src/network/socks4a.py +++ b/src/network/socks4a.py @@ -40,11 +40,11 @@ class Socks4a(Proxy): def state_pre_connect(self): """Handle feedback from SOCKS4a while it is connecting on our behalf""" # Get the response - if self.read_buf[0:1] != six.int2byte(0x00).encode(): + if self.read_buf[0:1] != six.int2byte(0x00): # bad data self.close() raise GeneralProxyError(1) - elif self.read_buf[1:2] != six.int2byte(0x5A).encode(): + elif self.read_buf[1:2] != six.int2byte(0x5A): # Connection failed self.close() if six.byte2int(self.read_buf[1:2]) in (91, 92, 93): @@ -103,9 +103,9 @@ class Socks4aConnection(Socks4a): self.append_write_buf(self.ipaddr) if self._auth: self.append_write_buf(self._auth[0]) - self.append_write_buf(six.int2byte(0x00).encode()) + self.append_write_buf(six.int2byte(0x00)) if rmtrslv: - self.append_write_buf(self.destination[0] + six.int2byte(0x00).encode()) + self.append_write_buf(self.destination[0].encode("utf-8", "replace") + six.int2byte(0x00)) self.set_state("pre_connect", length=0, expectBytes=8) return True @@ -133,8 +133,8 @@ class Socks4aResolver(Socks4a): self.append_write_buf(struct.pack("BBBB", 0x00, 0x00, 0x00, 0x01)) if self._auth: self.append_write_buf(self._auth[0]) - self.append_write_buf(six.int2byte(0x00).encode()) - self.append_write_buf(self.host + six.int2byte(0x00).encode()) + self.append_write_buf(six.int2byte(0x00)) + self.append_write_buf(self.host + six.int2byte(0x00)) self.set_state("pre_connect", length=0, expectBytes=8) return True diff --git a/src/network/socks5.py b/src/network/socks5.py index c295480c..ca5a52e8 100644 --- a/src/network/socks5.py +++ b/src/network/socks5.py @@ -98,10 +98,10 @@ class Socks5(Proxy): def state_pre_connect(self): """Handle feedback from socks5 while it is connecting on our behalf.""" # Get the response - if self.read_buf[0:1] != six.int2byte(0x05).encode(): + if self.read_buf[0:1] != six.int2byte(0x05): self.close() raise GeneralProxyError(1) - elif self.read_buf[1:2] != six.int2byte(0x00).encode(): + elif self.read_buf[1:2] != six.int2byte(0x00): # Connection failed self.close() if six.byte2int(self.read_buf[1:2]) <= 8: @@ -109,9 +109,9 @@ class Socks5(Proxy): else: raise Socks5Error(9) # Get the bound address/port - elif self.read_buf[3:4] == six.int2byte(0x01).encode(): + elif self.read_buf[3:4] == six.int2byte(0x01): self.set_state("proxy_addr_1", length=4, expectBytes=4) - elif self.read_buf[3:4] == six.int2byte(0x03).encode(): + elif self.read_buf[3:4] == six.int2byte(0x03): self.set_state("proxy_addr_2_1", length=4, expectBytes=1) else: self.close() @@ -172,19 +172,19 @@ class Socks5Connection(Socks5): # use the IPv4 address request even if remote resolving was specified. try: self.ipaddr = socket.inet_aton(self.destination[0]) - self.append_write_buf(six.int2byte(0x01).encode() + self.ipaddr) + self.append_write_buf(six.int2byte(0x01) + self.ipaddr) except socket.error: # may be IPv6! # Well it's not an IP number, so it's probably a DNS name. if self._remote_dns: # Resolve remotely self.ipaddr = None - self.append_write_buf(six.int2byte(0x03).encode() + six.int2byte( - len(self.destination[0])).encode() + self.destination[0]) + self.append_write_buf(six.int2byte(0x03) + six.int2byte( + len(self.destination[0])) + self.destination[0].encode("utf-8", "replace")) else: # Resolve locally self.ipaddr = socket.inet_aton( socket.gethostbyname(self.destination[0])) - self.append_write_buf(six.int2byte(0x01).encode() + self.ipaddr) + self.append_write_buf(six.int2byte(0x01) + self.ipaddr) self.append_write_buf(struct.pack(">H", self.destination[1])) self.set_state("pre_connect", length=0, expectBytes=4) return True @@ -209,8 +209,8 @@ class Socks5Resolver(Socks5): """Perform resolving""" # Now we can request the actual connection self.append_write_buf(struct.pack('BBB', 0x05, 0xF0, 0x00)) - self.append_write_buf(six.int2byte(0x03).encode() + six.int2byte( - len(self.host)).encode() + str(self.host)) + self.append_write_buf(six.int2byte(0x03) + six.int2byte( + len(self.host)) + bytes(self.host)) self.append_write_buf(struct.pack(">H", self.port)) self.set_state("pre_connect", length=0, expectBytes=4) return True -- 2.45.1 From 13aa12c09deb224d52dab863f8f7e3744b55cc60 Mon Sep 17 00:00:00 2001 From: Kashiko Koibumi Date: Sat, 1 Jun 2024 13:08:38 +0900 Subject: [PATCH 092/105] fix UPnP to work with Python3 --- src/upnp.py | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/upnp.py b/src/upnp.py index 35018e53..28d1ee8a 100644 --- a/src/upnp.py +++ b/src/upnp.py @@ -94,12 +94,12 @@ class Router: # pylint: disable=old-style-class self.address = address - row = ssdpResponse.split('\r\n') + row = ssdpResponse.split(b'\r\n') header = {} for i in range(1, len(row)): - part = row[i].split(': ') + part = row[i].split(b': ') if len(part) == 2: - header[part[0].lower()] = part[1] + header[part[0].decode("utf-8", "replace").lower()] = part[1].decode("utf-8", "replace") try: self.routerPath = urlparse(header['location']) @@ -222,10 +222,6 @@ class uPnPThread(StoppableThread): def run(self): """Start the thread to manage UPnP activity""" - if six.PY3: - logger.warning("UPnP is disabled currently, due to incompleted migration to Python3.") - return - logger.debug("Starting UPnP thread") logger.debug("Local IP: %s", self.localIP) lastSent = 0 @@ -323,7 +319,7 @@ class uPnPThread(StoppableThread): try: logger.debug("Sending UPnP query") - self.sock.sendto(ssdpRequest, (uPnPThread.SSDP_ADDR, uPnPThread.SSDP_PORT)) + self.sock.sendto(ssdpRequest.encode("utf8", "replace"), (uPnPThread.SSDP_ADDR, uPnPThread.SSDP_PORT)) except: # noqa:E722 logger.exception("UPnP send query failed") -- 2.45.1 From d103297d06550ef0cefd8737f3f87be072165586 Mon Sep 17 00:00:00 2001 From: Kashiko Koibumi Date: Sat, 1 Jun 2024 13:08:38 +0900 Subject: [PATCH 093/105] fix UPnP to work with Python3 --- src/upnp.py | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/upnp.py b/src/upnp.py index e3cb04bd..72d17343 100644 --- a/src/upnp.py +++ b/src/upnp.py @@ -94,12 +94,12 @@ class Router: # pylint: disable=old-style-class self.address = address - row = ssdpResponse.split('\r\n') + row = ssdpResponse.split(b'\r\n') header = {} for i in range(1, len(row)): - part = row[i].split(': ') + part = row[i].split(b': ') if len(part) == 2: - header[part[0].lower()] = part[1] + header[part[0].decode("utf-8", "replace").lower()] = part[1].decode("utf-8", "replace") try: self.routerPath = urlparse(header['location']) @@ -222,10 +222,6 @@ class uPnPThread(StoppableThread): def run(self): """Start the thread to manage UPnP activity""" - if six.PY3: - logger.warning("UPnP is disabled currently, due to incompleted migration to Python3.") - return - logger.debug("Starting UPnP thread") logger.debug("Local IP: %s", self.localIP) lastSent = 0 @@ -320,7 +316,7 @@ class uPnPThread(StoppableThread): try: logger.debug("Sending UPnP query") - self.sock.sendto(ssdpRequest, (uPnPThread.SSDP_ADDR, uPnPThread.SSDP_PORT)) + self.sock.sendto(ssdpRequest.encode("utf8", "replace"), (uPnPThread.SSDP_ADDR, uPnPThread.SSDP_PORT)) except: # noqa:E722 logger.exception("UPnP send query failed") -- 2.45.1 From 4041fefe133ccbd45c0ec1ee33d3a2d8d4a842a9 Mon Sep 17 00:00:00 2001 From: Kashiko Koibumi Date: Mon, 3 Jun 2024 19:34:32 +0900 Subject: [PATCH 094/105] fix to be runnable with prctl module in Python3 --- src/threads.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/threads.py b/src/threads.py index ac8bf7a6..ce781a77 100644 --- a/src/threads.py +++ b/src/threads.py @@ -14,6 +14,7 @@ There are also other threads in the `.network` package. """ import threading +import six from class_addressGenerator import addressGenerator from class_objectProcessor import objectProcessor @@ -32,12 +33,13 @@ else: """Set the thread name for external use (visible from the OS).""" prctl.set_name(name) - def _thread_name_hack(self): - set_thread_name(self.name) - threading.Thread.__bootstrap_original__(self) - # pylint: disable=protected-access - threading.Thread.__bootstrap_original__ = threading.Thread._Thread__bootstrap - threading.Thread._Thread__bootstrap = _thread_name_hack + if six.PY2: + def _thread_name_hack(self): + set_thread_name(self.name) + threading.Thread.__bootstrap_original__(self) + # pylint: disable=protected-access + threading.Thread.__bootstrap_original__ = threading.Thread._Thread__bootstrap + threading.Thread._Thread__bootstrap = _thread_name_hack printLock = threading.Lock() -- 2.45.1 From 0c110b9debf48cc2876ea35c42ac7676f287a070 Mon Sep 17 00:00:00 2001 From: Kashiko Koibumi Date: Mon, 3 Jun 2024 19:34:32 +0900 Subject: [PATCH 095/105] fix to be runnable with prctl module in Python3 --- src/threads.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/threads.py b/src/threads.py index ac8bf7a6..ce781a77 100644 --- a/src/threads.py +++ b/src/threads.py @@ -14,6 +14,7 @@ There are also other threads in the `.network` package. """ import threading +import six from class_addressGenerator import addressGenerator from class_objectProcessor import objectProcessor @@ -32,12 +33,13 @@ else: """Set the thread name for external use (visible from the OS).""" prctl.set_name(name) - def _thread_name_hack(self): - set_thread_name(self.name) - threading.Thread.__bootstrap_original__(self) - # pylint: disable=protected-access - threading.Thread.__bootstrap_original__ = threading.Thread._Thread__bootstrap - threading.Thread._Thread__bootstrap = _thread_name_hack + if six.PY2: + def _thread_name_hack(self): + set_thread_name(self.name) + threading.Thread.__bootstrap_original__(self) + # pylint: disable=protected-access + threading.Thread.__bootstrap_original__ = threading.Thread._Thread__bootstrap + threading.Thread._Thread__bootstrap = _thread_name_hack printLock = threading.Lock() -- 2.45.1 From 229644cd1d3d71d17cdd4c63891cc47536a46d4a Mon Sep 17 00:00:00 2001 From: Kashiko Koibumi Date: Sun, 23 Jun 2024 00:47:51 +0900 Subject: [PATCH 096/105] fix bug in detecting file system type --- src/shared.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shared.py b/src/shared.py index f710d56d..80147801 100644 --- a/src/shared.py +++ b/src/shared.py @@ -196,7 +196,7 @@ def checkSensitiveFilePermissions(filename): ['/usr/bin/stat', '-f', '-c', '%T', filename], stderr=subprocess.STDOUT ) # nosec B603 - if 'fuseblk' in fstype: + if b'fuseblk' in fstype: logger.info( 'Skipping file permissions check for %s.' ' Filesystem fuseblk detected.', filename) -- 2.45.1 From 11ba0222673ff86134f51b6766ecea5061054782 Mon Sep 17 00:00:00 2001 From: Kashiko Koibumi Date: Sun, 23 Jun 2024 00:47:51 +0900 Subject: [PATCH 097/105] fix bug in detecting file system type --- src/shared.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shared.py b/src/shared.py index f710d56d..80147801 100644 --- a/src/shared.py +++ b/src/shared.py @@ -196,7 +196,7 @@ def checkSensitiveFilePermissions(filename): ['/usr/bin/stat', '-f', '-c', '%T', filename], stderr=subprocess.STDOUT ) # nosec B603 - if 'fuseblk' in fstype: + if b'fuseblk' in fstype: logger.info( 'Skipping file permissions check for %s.' ' Filesystem fuseblk detected.', filename) -- 2.45.1 From bdbe5cca616148e3ae3303b7572675d0c96c05b1 Mon Sep 17 00:00:00 2001 From: Kashiko Koibumi Date: Mon, 24 Jun 2024 11:04:34 +0900 Subject: [PATCH 098/105] fix timestamp type mismatch bug --- src/bitmessageqt/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/bitmessageqt/__init__.py b/src/bitmessageqt/__init__.py index 34544a3a..8e9d87df 100644 --- a/src/bitmessageqt/__init__.py +++ b/src/bitmessageqt/__init__.py @@ -1229,8 +1229,8 @@ class MyForm(settingsmixin.SMainWindow): r.append(row[1].decode("utf-8", "replace")) # fromaddress r.append(row[2].decode("utf-8", "replace")) # subject r.append(row[3].decode("utf-8", "replace")) # status - r.append(row[3]) # ackdata - r.append(row[4]) # lastactiontime + r.append(row[4]) # ackdata + r.append(row[5]) # lastactiontime self.addMessageListItemSent(tableWidget, *r) tableWidget.horizontalHeader().setSortIndicator( -- 2.45.1 From cdcffa4b3eac18a044edeb2dc605293f0a40ca97 Mon Sep 17 00:00:00 2001 From: Kashiko Koibumi Date: Mon, 24 Jun 2024 11:04:34 +0900 Subject: [PATCH 099/105] fix timestamp type mismatch bug --- src/bitmessageqt/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/bitmessageqt/__init__.py b/src/bitmessageqt/__init__.py index 9b6461d1..9a3fe89a 100644 --- a/src/bitmessageqt/__init__.py +++ b/src/bitmessageqt/__init__.py @@ -1269,8 +1269,8 @@ class MyForm(settingsmixin.SMainWindow): r.append(row[1].decode("utf-8", "replace")) # fromaddress r.append(row[2].decode("utf-8", "replace")) # subject r.append(row[3].decode("utf-8", "replace")) # status - r.append(row[3]) # ackdata - r.append(row[4]) # lastactiontime + r.append(row[4]) # ackdata + r.append(row[5]) # lastactiontime self.addMessageListItemSent(tableWidget, *r) tableWidget.horizontalHeader().setSortIndicator( -- 2.45.1 From 605f205a44f5947acc1eefb25b067b47afc47151 Mon Sep 17 00:00:00 2001 From: Kashiko Koibumi Date: Mon, 24 Jun 2024 16:04:37 +0900 Subject: [PATCH 100/105] fix easy typo #2 --- src/bitmessageqt/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bitmessageqt/__init__.py b/src/bitmessageqt/__init__.py index 8e9d87df..1acedd96 100644 --- a/src/bitmessageqt/__init__.py +++ b/src/bitmessageqt/__init__.py @@ -2415,7 +2415,7 @@ class MyForm(settingsmixin.SMainWindow): addressInKeysFile, 'enabled') isChan = config.safeGetBoolean(addressInKeysFile, 'chan') if isEnabled and not isChan: - label = unic(ustr(config.get(addressInKeysFile, 'label')).strip()) or addressInKeyFile + label = unic(ustr(config.get(addressInKeysFile, 'label')).strip()) or addressInKeysFile self.ui.comboBoxSendFromBroadcast.addItem(avatarize(addressInKeysFile), label, addressInKeysFile) for i in range(self.ui.comboBoxSendFromBroadcast.count()): address = ustr(self.ui.comboBoxSendFromBroadcast.itemData( -- 2.45.1 From 909b9f2c8e55e45b2b138a3b0ae7c06d6a5b77c6 Mon Sep 17 00:00:00 2001 From: Kashiko Koibumi Date: Tue, 25 Jun 2024 07:48:03 +0900 Subject: [PATCH 101/105] use SafeConfigParser or ConfigParser, which is available --- src/bitmessageqt/settings.py | 7 ++++++- src/bmconfigparser.py | 5 ++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/bitmessageqt/settings.py b/src/bitmessageqt/settings.py index 9b6f048d..fe1e49bd 100644 --- a/src/bitmessageqt/settings.py +++ b/src/bitmessageqt/settings.py @@ -27,10 +27,15 @@ from network.asyncore_pollchoose import set_rates from tr import _translate +try: + SafeConfigParser = configparser.SafeConfigParser +except AttributeError: + SafeConfigParser = configparser.ConfigParser + def getSOCKSProxyType(config): """Get user socksproxytype setting from *config*""" try: - result = configparser.SafeConfigParser.get( + result = SafeConfigParser.get( config, 'bitmessagesettings', 'socksproxytype') except (configparser.NoSectionError, configparser.NoOptionError): return None diff --git a/src/bmconfigparser.py b/src/bmconfigparser.py index bb4013b9..b6eceb77 100644 --- a/src/bmconfigparser.py +++ b/src/bmconfigparser.py @@ -16,7 +16,10 @@ try: except ImportError: from pybitmessage import state -SafeConfigParser = configparser.SafeConfigParser +try: + SafeConfigParser = configparser.SafeConfigParser +except AttributeError: + SafeConfigParser = configparser.ConfigParser config_ready = Event() -- 2.45.1 From e7b5f2957e8a2b612d9b618c2c15e1d552c5b07d Mon Sep 17 00:00:00 2001 From: Kashiko Koibumi Date: Tue, 25 Jun 2024 07:48:03 +0900 Subject: [PATCH 102/105] use SafeConfigParser or ConfigParser, which is available --- src/bitmessageqt/settings.py | 7 ++++++- src/bmconfigparser.py | 5 ++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/bitmessageqt/settings.py b/src/bitmessageqt/settings.py index 5658651f..11bb55d9 100644 --- a/src/bitmessageqt/settings.py +++ b/src/bitmessageqt/settings.py @@ -27,10 +27,15 @@ from network.asyncore_pollchoose import set_rates from tr import _translate +try: + SafeConfigParser = configparser.SafeConfigParser +except AttributeError: + SafeConfigParser = configparser.ConfigParser + def getSOCKSProxyType(config): """Get user socksproxytype setting from *config*""" try: - result = configparser.SafeConfigParser.get( + result = SafeConfigParser.get( config, 'bitmessagesettings', 'socksproxytype') except (configparser.NoSectionError, configparser.NoOptionError): return None diff --git a/src/bmconfigparser.py b/src/bmconfigparser.py index ec05af3e..7a33a502 100644 --- a/src/bmconfigparser.py +++ b/src/bmconfigparser.py @@ -15,7 +15,10 @@ try: except ImportError: from pybitmessage import state -SafeConfigParser = configparser.SafeConfigParser +try: + SafeConfigParser = configparser.SafeConfigParser +except AttributeError: + SafeConfigParser = configparser.ConfigParser config_ready = Event() -- 2.45.1 From 45d1c62f97539f20861bef8274e66b434e04ea5c Mon Sep 17 00:00:00 2001 From: Kashiko Koibumi Date: Wed, 26 Jun 2024 05:10:44 +0900 Subject: [PATCH 103/105] add comments --- src/bitmessageqt/settings.py | 1 + src/bmconfigparser.py | 1 + 2 files changed, 2 insertions(+) diff --git a/src/bitmessageqt/settings.py b/src/bitmessageqt/settings.py index fe1e49bd..af441afa 100644 --- a/src/bitmessageqt/settings.py +++ b/src/bitmessageqt/settings.py @@ -30,6 +30,7 @@ from tr import _translate try: SafeConfigParser = configparser.SafeConfigParser except AttributeError: + # alpine linux, python3.12 SafeConfigParser = configparser.ConfigParser def getSOCKSProxyType(config): diff --git a/src/bmconfigparser.py b/src/bmconfigparser.py index b6eceb77..4d7684db 100644 --- a/src/bmconfigparser.py +++ b/src/bmconfigparser.py @@ -19,6 +19,7 @@ except ImportError: try: SafeConfigParser = configparser.SafeConfigParser except AttributeError: + # alpine linux, python3.12 SafeConfigParser = configparser.ConfigParser config_ready = Event() -- 2.45.1 From 8bfcc4cf382910e40d0caa969a4a8b666738086e Mon Sep 17 00:00:00 2001 From: Kashiko Koibumi Date: Wed, 26 Jun 2024 05:10:44 +0900 Subject: [PATCH 104/105] add comments --- src/bitmessageqt/settings.py | 1 + src/bmconfigparser.py | 1 + 2 files changed, 2 insertions(+) diff --git a/src/bitmessageqt/settings.py b/src/bitmessageqt/settings.py index 11bb55d9..635d5241 100644 --- a/src/bitmessageqt/settings.py +++ b/src/bitmessageqt/settings.py @@ -30,6 +30,7 @@ from tr import _translate try: SafeConfigParser = configparser.SafeConfigParser except AttributeError: + # alpine linux, python3.12 SafeConfigParser = configparser.ConfigParser def getSOCKSProxyType(config): diff --git a/src/bmconfigparser.py b/src/bmconfigparser.py index 7a33a502..5869255f 100644 --- a/src/bmconfigparser.py +++ b/src/bmconfigparser.py @@ -18,6 +18,7 @@ except ImportError: try: SafeConfigParser = configparser.SafeConfigParser except AttributeError: + # alpine linux, python3.12 SafeConfigParser = configparser.ConfigParser config_ready = Event() -- 2.45.1 From 37bbe441256ce69783a137df12b2226990cd0da2 Mon Sep 17 00:00:00 2001 From: Kashiko Koibumi Date: Sat, 3 Aug 2024 05:52:31 +0900 Subject: [PATCH 105/105] fix bug in generating deterministic address --- src/highlevelcrypto.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/highlevelcrypto.py b/src/highlevelcrypto.py index b83da2f3..d6575a5f 100644 --- a/src/highlevelcrypto.py +++ b/src/highlevelcrypto.py @@ -7,6 +7,8 @@ High level cryptographic functions based on `.pyelliptic` OpenSSL bindings. `More discussion. `_ """ +from unqstr import unic + import hashlib import os from binascii import hexlify @@ -102,7 +104,7 @@ def random_keys(): def deterministic_keys(passphrase, nonce): """Generate keys from *passphrase* and *nonce* (encoded as varint)""" - priv = hashlib.sha512(passphrase + nonce).digest()[:32] + priv = hashlib.sha512(unic(passphrase).encode("utf-8", "replace") + nonce).digest()[:32] pub = pointMult(priv) return priv, pub -- 2.45.1