From 1ab664564b9521cc0fa42978a15b1410f8427cdf Mon Sep 17 00:00:00 2001 From: fuzzgun Date: Mon, 15 Jul 2013 17:01:12 +0100 Subject: [PATCH 01/20] Play sounds on connection/disconnection or when messages arrive --- archpackage/PKGBUILD | 2 +- debian/control | 2 +- generate.sh | 2 +- puppypackage/pybitmessage-0.3.4.pet.specs | 2 +- rpmpackage/pybitmessage.spec | 2 +- src/bitmessageqt/__init__.py | 68 +++++++++++++++++++++-- 6 files changed, 67 insertions(+), 11 deletions(-) diff --git a/archpackage/PKGBUILD b/archpackage/PKGBUILD index 79ee8ded..e9ab0f74 100644 --- a/archpackage/PKGBUILD +++ b/archpackage/PKGBUILD @@ -7,7 +7,7 @@ arch=('i686' 'x86_64') url="https://github.com/Bitmessage/PyBitmessage" license=('MIT') groups=() -depends=('python2' 'qt4' 'python2-pyqt4' 'sqlite' 'openssl') +depends=('python2' 'qt4' 'python2-pyqt4' 'sqlite' 'openssl' 'gst123') makedepends=() optdepends=('python2-gevent') provides=() diff --git a/debian/control b/debian/control index 01bd7d8c..d9ed8704 100644 --- a/debian/control +++ b/debian/control @@ -9,7 +9,7 @@ Vcs-Git: https://github.com/fuzzgun/fin.git Package: pybitmessage Section: mail Architecture: any -Depends: ${shlibs:Depends}, ${misc:Depends}, python (>= 2.7.0), openssl, python-qt4, libqt4-dev (>= 4.8.0), python-qt4-dev, sqlite3, libsqlite3-dev +Depends: ${shlibs:Depends}, ${misc:Depends}, python (>= 2.7.0), openssl, python-qt4, libqt4-dev (>= 4.8.0), python-qt4-dev, sqlite3, libsqlite3-dev, gst123 Suggests: libmessaging-menu-dev Description: Send encrypted messages Bitmessage is a P2P communications protocol used to send encrypted diff --git a/generate.sh b/generate.sh index 8909cf2f..8489f024 100755 --- a/generate.sh +++ b/generate.sh @@ -4,4 +4,4 @@ rm -f Makefile rpmpackage/*.spec -packagemonkey -n "PyBitmessage" --version "0.3.4" --dir "." -l "mit" -e "Bob Mottram (4096 bits) " --brief "Send encrypted messages" --desc "Bitmessage is a P2P communications protocol used to send encrypted messages to another person or to many subscribers. It is decentralized and trustless, meaning that you need-not inherently trust any entities like root certificate authorities. It uses strong authentication which means that the sender of a message cannot be spoofed, and it aims to hide \"non-content\" data, like the sender and receiver of messages, from passive eavesdroppers like those running warrantless wiretapping programs." --homepage "https://github.com/Bitmessage/PyBitmessage" --section "mail" --categories "Office/Email" --dependsdeb "python (>= 2.7.0), openssl, python-qt4, libqt4-dev (>= 4.8.0), python-qt4-dev, sqlite3, libsqlite3-dev" --dependsrpm "python, PyQt4, openssl-compat-bitcoin-libs" --mainscript "bitmessagemain.py" --librarypath "/opt/openssl-compat-bitcoin/lib/" --suggestsdeb "libmessaging-menu-dev" --dependspuppy "openssl, python-qt4, sqlite3, sqlite3-dev, python-openssl, python-sip" --dependsarch "python2, qt4, python2-pyqt4, sqlite, openssl" --suggestsarch "python2-gevent" --pythonversion 2 +packagemonkey -n "PyBitmessage" --version "0.3.4" --dir "." -l "mit" -e "Bob Mottram (4096 bits) " --brief "Send encrypted messages" --desc "Bitmessage is a P2P communications protocol used to send encrypted messages to another person or to many subscribers. It is decentralized and trustless, meaning that you need-not inherently trust any entities like root certificate authorities. It uses strong authentication which means that the sender of a message cannot be spoofed, and it aims to hide \"non-content\" data, like the sender and receiver of messages, from passive eavesdroppers like those running warrantless wiretapping programs." --homepage "https://github.com/Bitmessage/PyBitmessage" --section "mail" --categories "Office/Email" --dependsdeb "python (>= 2.7.0), openssl, python-qt4, libqt4-dev (>= 4.8.0), python-qt4-dev, sqlite3, libsqlite3-dev, gst123" --dependsrpm "python, PyQt4, openssl-compat-bitcoin-libs, gst123" --mainscript "bitmessagemain.py" --librarypath "/opt/openssl-compat-bitcoin/lib/" --suggestsdeb "libmessaging-menu-dev" --dependspuppy "openssl, python-qt4, sqlite3, sqlite3-dev, python-openssl, python-sip, gst123" --dependsarch "python2, qt4, python2-pyqt4, sqlite, openssl, gst123" --suggestsarch "python2-gevent" --pythonversion 2 diff --git a/puppypackage/pybitmessage-0.3.4.pet.specs b/puppypackage/pybitmessage-0.3.4.pet.specs index e346d0c9..42d99ac3 100644 --- a/puppypackage/pybitmessage-0.3.4.pet.specs +++ b/puppypackage/pybitmessage-0.3.4.pet.specs @@ -1 +1 @@ -pybitmessage-0.3.4-1|PyBitmessage|0.3.4|1|Internet;mailnews;|5.1M||pybitmessage-0.3.4-1.pet|+openssl,+python-qt4,+sqlite3,+sqlite3-dev,+python-openssl,+python-sip|Send encrypted messages|ubuntu|precise|5| +pybitmessage-0.3.4-1|PyBitmessage|0.3.4|1|Internet;mailnews;|5.3M||pybitmessage-0.3.4-1.pet|+openssl,+python-qt4,+sqlite3,+sqlite3-dev,+python-openssl,+python-sip,+gst123|Send encrypted messages|ubuntu|precise|5| diff --git a/rpmpackage/pybitmessage.spec b/rpmpackage/pybitmessage.spec index 27485d73..c9254dec 100644 --- a/rpmpackage/pybitmessage.spec +++ b/rpmpackage/pybitmessage.spec @@ -8,7 +8,7 @@ Packager: Bob Mottram (4096 bits) Source0: http://yourdomainname.com/src/%{name}_%{version}.orig.tar.gz Group: Office/Email -Requires: python, PyQt4, openssl-compat-bitcoin-libs +Requires: python, PyQt4, openssl-compat-bitcoin-libs, gst123 %description diff --git a/src/bitmessageqt/__init__.py b/src/bitmessageqt/__init__.py index ce477836..69ef2597 100644 --- a/src/bitmessageqt/__init__.py +++ b/src/bitmessageqt/__init__.py @@ -34,6 +34,7 @@ try: from PyQt4 import QtCore, QtGui from PyQt4.QtCore import * from PyQt4.QtGui import * + 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 it from http://www.riverbankcomputing.com/software/pyqt/download or by searching Google for \'PyQt Download\' (without quotes).' print 'Error message:', err @@ -50,6 +51,14 @@ def _translate(context, text): class MyForm(QtGui.QMainWindow): + # sound type constants + SOUND_NONE = 0 + SOUND_KNOWN = 1 + SOUND_UNKNOWN = 2 + SOUND_CONNECTED = 3 + SOUND_DISCONNECTED = 4 + SOUND_CONNECTION_GREEN = 5 + str_broadcast_subscribers = '[Broadcast subscribers]' def __init__(self, parent=None): @@ -894,6 +903,47 @@ class MyForm(QtGui.QMainWindow): # update the menu entries self.ubuntuMessagingMenuUnread(drawAttention) + # play a sound + def playSound(self, category, label): + soundFilename = None + + if label is not None: + # does a sound file exist for this particular contact? + if (os.path.isfile(shared.appdata + 'sounds/' + label + '.wav') or + os.path.isfile(shared.appdata + 'sounds/' + label + '.mp3')): + soundFilename = shared.appdata + 'sounds/' + label + + if soundFilename is None: + if category is self.SOUND_KNOWN: + soundFilename = shared.appdata + 'sounds/known' + elif category is self.SOUND_UNKNOWN: + soundFilename = shared.appdata + 'sounds/unknown' + elif category is self.SOUND_CONNECTED: + soundFilename = shared.appdata + 'sounds/connected' + elif category is self.SOUND_DISCONNECTED: + soundFilename = shared.appdata + 'sounds/disconnected' + elif category is self.SOUND_CONNECTION_GREEN: + soundFilename = shared.appdata + 'sounds/green' + + if soundFilename is not None: + # if not wav then try mp3 format + if not os.path.isfile(soundFilename + '.wav'): + soundFilename = soundFilename + '.mp3' + else: + soundFilename = soundFilename + '.wav' + + if os.path.isfile(soundFilename): + if 'linux' in sys.platform: + # Note: QSound was a nice idea but it didn't work + if '.mp3' in soundFilename: + os.popen('gst123 ' + soundFilename) + else: + os.popen('aplay ' + soundFilename) + elif sys.platform[0:3] == 'win': + # use winsound on Windows + import winsound + winsound.PlaySound(soundFilename, winsound.SND_FILENAME) + # initialise the message notifier def notifierInit(self): global withMessagingMenu @@ -901,8 +951,11 @@ class MyForm(QtGui.QMainWindow): Notify.init('pybitmessage') # shows a notification - def notifierShow(self, title, subtitle): + def notifierShow(self, title, subtitle, fromCategory, label): global withMessagingMenu + + self.playSound(fromCategory, label); + if withMessagingMenu: n = Notify.Notification.new( title, subtitle, 'notification-message-email') @@ -1075,7 +1128,8 @@ class MyForm(QtGui.QMainWindow): # if the connection is lost then show a notification if self.connected: self.notifierShow('Bitmessage', unicode(_translate( - "MainWindow", "Connection lost").toUtf8(),'utf-8')) + "MainWindow", "Connection lost").toUtf8(),'utf-8'), + self.SOUND_DISCONNECTED, None) self.connected = False if self.actionStatus is not None: @@ -1092,7 +1146,8 @@ class MyForm(QtGui.QMainWindow): # if a new connection has been established then show a notification if not self.connected: self.notifierShow('Bitmessage', unicode(_translate( - "MainWindow", "Connected").toUtf8(),'utf-8')) + "MainWindow", "Connected").toUtf8(),'utf-8'), + self.SOUND_CONNECTED, None) self.connected = True if self.actionStatus is not None: @@ -1108,7 +1163,8 @@ class MyForm(QtGui.QMainWindow): shared.statusIconColor = 'green' if not self.connected: self.notifierShow('Bitmessage', unicode(_translate( - "MainWindow", "Connected").toUtf8(),'utf-8')) + "MainWindow", "Connected").toUtf8(),'utf-8'), + self.SOUND_CONNECTION_GREEN, None) self.connected = True if self.actionStatus is not None: @@ -1580,12 +1636,12 @@ class MyForm(QtGui.QMainWindow): newItem = QtGui.QTableWidgetItem(unicode(fromAddress, 'utf-8')) newItem.setToolTip(unicode(fromAddress, 'utf-8')) if shared.config.getboolean('bitmessagesettings', 'showtraynotifications'): - self.notifierShow(unicode(_translate("MainWindow",'New Message').toUtf8(),'utf-8'), unicode(_translate("MainWindow",'From ').toUtf8(),'utf-8') + unicode(fromAddress, 'utf-8')) + self.notifierShow(unicode(_translate("MainWindow",'New Message').toUtf8(),'utf-8'), unicode(_translate("MainWindow",'From ').toUtf8(),'utf-8') + unicode(fromAddress, 'utf-8'), self.SOUND_UNKNOWN, None) else: newItem = QtGui.QTableWidgetItem(unicode(fromLabel, 'utf-8')) newItem.setToolTip(unicode(unicode(fromLabel, 'utf-8'))) if shared.config.getboolean('bitmessagesettings', 'showtraynotifications'): - self.notifierShow(unicode(_translate("MainWindow",'New Message').toUtf8(),'utf-8'), unicode(_translate("MainWindow",'From ').toUtf8(),'utf-8') + unicode(fromLabel, 'utf-8')) + self.notifierShow(unicode(_translate("MainWindow",'New Message').toUtf8(),'utf-8'), unicode(_translate("MainWindow",'From ').toUtf8(),'utf-8') + unicode(fromLabel, 'utf-8'), self.SOUND_KNOWN, unicode(fromLabel, 'utf-8')) newItem.setData(Qt.UserRole, str(fromAddress)) newItem.setFont(font) self.ui.tableWidgetInbox.setItem(0, 1, newItem) From 3e134686952d261bf57b5a3a2a7532a95912c4bf Mon Sep 17 00:00:00 2001 From: fuzzgun Date: Mon, 15 Jul 2013 17:58:22 +0100 Subject: [PATCH 02/20] Use subprocess.call --- src/bitmessageqt/__init__.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/bitmessageqt/__init__.py b/src/bitmessageqt/__init__.py index 69ef2597..b2cb2640 100644 --- a/src/bitmessageqt/__init__.py +++ b/src/bitmessageqt/__init__.py @@ -29,6 +29,7 @@ import os from pyelliptic.openssl import OpenSSL import pickle import platform +import subprocess try: from PyQt4 import QtCore, QtGui @@ -936,9 +937,9 @@ class MyForm(QtGui.QMainWindow): if 'linux' in sys.platform: # Note: QSound was a nice idea but it didn't work if '.mp3' in soundFilename: - os.popen('gst123 ' + soundFilename) + subprocess.call(["gst123", soundFilename]) else: - os.popen('aplay ' + soundFilename) + subprocess.call(["aplay", soundFilename]) elif sys.platform[0:3] == 'win': # use winsound on Windows import winsound From a7a2de1d247bb09c2af23f4048a0af6688422ee3 Mon Sep 17 00:00:00 2001 From: fuzzgun Date: Mon, 15 Jul 2013 18:13:21 +0100 Subject: [PATCH 03/20] Fixed freeze on Ubuntu --- src/bitmessageqt/__init__.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/bitmessageqt/__init__.py b/src/bitmessageqt/__init__.py index b2cb2640..e61c351d 100644 --- a/src/bitmessageqt/__init__.py +++ b/src/bitmessageqt/__init__.py @@ -937,9 +937,13 @@ class MyForm(QtGui.QMainWindow): if 'linux' in sys.platform: # Note: QSound was a nice idea but it didn't work if '.mp3' in soundFilename: - subprocess.call(["gst123", soundFilename]) + subprocess.call(["gst123", soundFilename], + stdin=subprocess.PIPE, + stdout=subprocess.PIPE) else: - subprocess.call(["aplay", soundFilename]) + subprocess.call(["aplay", soundFilename], + stdin=subprocess.PIPE, + stdout=subprocess.PIPE) elif sys.platform[0:3] == 'win': # use winsound on Windows import winsound From cfc23718eddb322033e382fcbac83885a7ed87d6 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Sat, 20 Jul 2013 10:55:03 +0100 Subject: [PATCH 04/20] Added exception handling for sound playing dependencies --- src/bitmessageqt/__init__.py | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/bitmessageqt/__init__.py b/src/bitmessageqt/__init__.py index e61c351d..2c2c7276 100644 --- a/src/bitmessageqt/__init__.py +++ b/src/bitmessageqt/__init__.py @@ -937,13 +937,19 @@ class MyForm(QtGui.QMainWindow): if 'linux' in sys.platform: # Note: QSound was a nice idea but it didn't work if '.mp3' in soundFilename: - subprocess.call(["gst123", soundFilename], - stdin=subprocess.PIPE, - stdout=subprocess.PIPE) + try: + subprocess.call(["gst123", soundFilename], + stdin=subprocess.PIPE, + stdout=subprocess.PIPE) + except: + print "WARNING: gst123 must be installed in order to play mp3 sounds" else: - subprocess.call(["aplay", soundFilename], - stdin=subprocess.PIPE, - stdout=subprocess.PIPE) + try: + subprocess.call(["aplay", soundFilename], + stdin=subprocess.PIPE, + stdout=subprocess.PIPE) + except: + print "WARNING: aplay must be installed in order to play WAV sounds" elif sys.platform[0:3] == 'win': # use winsound on Windows import winsound From d036ca18edd278f55473fcd49b014ba9479f850e Mon Sep 17 00:00:00 2001 From: Jonathan Warren Date: Mon, 22 Jul 2013 01:10:22 -0400 Subject: [PATCH 05/20] Completed chan integration in the GUI --- src/bitmessageqt/__init__.py | 215 ++++++++++++++++++++---------- src/bitmessageqt/bitmessageui.py | 6 +- src/bitmessageqt/bitmessageui.ui | 26 ++-- src/bitmessageqt/newchandialog.py | 85 ++++++------ src/bitmessageqt/newchandialog.ui | 109 ++++++++------- src/class_addressGenerator.py | 31 ++--- src/class_outgoingSynSender.py | 1 - src/class_receiveDataThread.py | 33 +++-- src/class_singleWorker.py | 96 ++++++++----- src/message_data_reader.py | 4 +- src/shared.py | 4 +- 11 files changed, 374 insertions(+), 236 deletions(-) diff --git a/src/bitmessageqt/__init__.py b/src/bitmessageqt/__init__.py index 46bac1f3..dc12fcf8 100644 --- a/src/bitmessageqt/__init__.py +++ b/src/bitmessageqt/__init__.py @@ -17,6 +17,7 @@ from bitmessageui import * from newaddressdialog import * from newsubscriptiondialog import * from regenerateaddresses import * +from newchandialog import * from specialaddressbehavior import * from settings import * from about import * @@ -53,6 +54,7 @@ def _translate(context, text): class MyForm(QtGui.QMainWindow): str_broadcast_subscribers = '[Broadcast subscribers]' + str_chan = '[chan]' def __init__(self, parent=None): QtGui.QWidget.__init__(self, parent) @@ -105,6 +107,8 @@ class MyForm(QtGui.QMainWindow): "triggered()"), self.click_actionDeleteAllTrashedMessages) QtCore.QObject.connect(self.ui.actionRegenerateDeterministicAddresses, QtCore.SIGNAL( "triggered()"), self.click_actionRegenerateDeterministicAddresses) + QtCore.QObject.connect(self.ui.actionJoinChan, QtCore.SIGNAL( + "triggered()"), 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.comboBoxSendFrom, QtCore.SIGNAL( @@ -293,6 +297,8 @@ class MyForm(QtGui.QMainWindow): newItem = QtGui.QTableWidgetItem(addressInKeysFile) newItem.setFlags( QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) + if shared.safeConfigGetBoolean(addressInKeysFile, 'chan'): + newItem.setTextColor(QtGui.QColor(216, 119, 0)) # orange if not isEnabled: newItem.setTextColor(QtGui.QColor(128, 128, 128)) if shared.safeConfigGetBoolean(addressInKeysFile, 'mailinglist'): @@ -594,6 +600,9 @@ class MyForm(QtGui.QMainWindow): elif status == 'msgsent': statusText = _translate("MainWindow", "Message sent. Waiting on acknowledgement. Sent at %1").arg( unicode(strftime(shared.config.get('bitmessagesettings', 'timeformat'), localtime(lastactiontime)),'utf-8')) + elif status == 'msgsentnoackexpected': + statusText = _translate("MainWindow", "Message sent. Sent at %1").arg( + unicode(strftime(shared.config.get('bitmessagesettings', 'timeformat'), localtime(lastactiontime)),'utf-8')) elif status == 'doingmsgpow': statusText = _translate( "MainWindow", "Need to do work to send message. Work is queued.") @@ -709,6 +718,8 @@ class MyForm(QtGui.QMainWindow): newItem.setData(Qt.UserRole, str(toAddress)) if shared.safeConfigGetBoolean(toAddress, 'mailinglist'): newItem.setTextColor(QtGui.QColor(137, 04, 177)) + if shared.safeConfigGetBoolean(str(toAddress), 'chan'): + newItem.setTextColor(QtGui.QColor(216, 119, 0)) # orange self.ui.tableWidgetInbox.setItem(0, 0, newItem) if fromLabel == '': newItem = QtGui.QTableWidgetItem( @@ -1032,6 +1043,57 @@ class MyForm(QtGui.QMainWindow): ), self.regenerateAddressesDialogInstance.ui.lineEditPassphrase.text().toUtf8(), self.regenerateAddressesDialogInstance.ui.checkBoxEighteenByteRipe.isChecked())) self.ui.tabWidget.setCurrentIndex(3) + def click_actionJoinChan(self): + self.newChanDialogInstance = newChanDialog(self) + if self.newChanDialogInstance.exec_(): + if self.newChanDialogInstance.ui.radioButtonCreateChan.isChecked(): + if self.newChanDialogInstance.ui.lineEditChanNameCreate.text() == "": + QMessageBox.about(self, _translate("MainWindow", "Chan name needed"), _translate( + "MainWindow", "You didn't enter a chan name.")) + return + shared.apiAddressGeneratorReturnQueue.queue.clear() + shared.addressGeneratorQueue.put(('createChan', 3, 1, self.str_chan + ' ' + str(self.newChanDialogInstance.ui.lineEditChanNameCreate.text().toUtf8()), self.newChanDialogInstance.ui.lineEditChanNameCreate.text().toUtf8())) + addressGeneratorReturnValue = shared.apiAddressGeneratorReturnQueue.get() + print 'addressGeneratorReturnValue', addressGeneratorReturnValue + if len(addressGeneratorReturnValue) == 0: + QMessageBox.about(self, _translate("MainWindow", "Address already present"), _translate( + "MainWindow", "Could not add chan because it appears to already be one of your identities.")) + return + createdAddress = addressGeneratorReturnValue[0] + self.addEntryToAddressBook(createdAddress, self.str_chan + ' ' + str(self.newChanDialogInstance.ui.lineEditChanNameCreate.text().toUtf8())) + QMessageBox.about(self, _translate("MainWindow", "Success"), _translate( + "MainWindow", "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'.").arg(createdAddress)) + self.ui.tabWidget.setCurrentIndex(3) + elif self.newChanDialogInstance.ui.radioButtonJoinChan.isChecked(): + if self.newChanDialogInstance.ui.lineEditChanNameJoin.text() == "": + QMessageBox.about(self, _translate("MainWindow", "Chan name needed"), _translate( + "MainWindow", "You didn't enter a chan name.")) + return + if decodeAddress(self.newChanDialogInstance.ui.lineEditChanBitmessageAddress.text())[0] == 'versiontoohigh': + QMessageBox.about(self, _translate("MainWindow", "Address too new"), _translate( + "MainWindow", "Although that Bitmessage address might be valid, its version number is too new for us to handle. Perhaps you need to upgrade Bitmessage.")) + return + if decodeAddress(self.newChanDialogInstance.ui.lineEditChanBitmessageAddress.text())[0] != 'success': + QMessageBox.about(self, _translate("MainWindow", "Address invalid"), _translate( + "MainWindow", "That Bitmessage address is not valid.")) + return + shared.apiAddressGeneratorReturnQueue.queue.clear() + shared.addressGeneratorQueue.put(('joinChan', addBMIfNotPresent(self.newChanDialogInstance.ui.lineEditChanBitmessageAddress.text()), self.str_chan + ' ' + str(self.newChanDialogInstance.ui.lineEditChanNameJoin.text()), self.newChanDialogInstance.ui.lineEditChanNameJoin.text().toUtf8())) + addressGeneratorReturnValue = shared.apiAddressGeneratorReturnQueue.get() + print 'addressGeneratorReturnValue', addressGeneratorReturnValue + if addressGeneratorReturnValue == 'chan name does not match address': + QMessageBox.about(self, _translate("MainWindow", "Address does not match chan name"), _translate( + "MainWindow", "Although the Bitmessage address you entered was valid, it doesn\'t match the chan name.")) + return + if len(addressGeneratorReturnValue) == 0: + QMessageBox.about(self, _translate("MainWindow", "Address already present"), _translate( + "MainWindow", "Could not add chan because it appears to already be one of your identities.")) + return + self.addEntryToAddressBook(createdAddress, self.str_chan + ' ' + self.str_chan + ' ' + str(self.newChanDialogInstance.ui.lineEditChanNameJoin.text())) + QMessageBox.about(self, _translate("MainWindow", "Success"), _translate( + "MainWindow", "Successfully joined chan. ")) + self.ui.tabWidget.setCurrentIndex(3) + def openKeysFile(self): if 'linux' in sys.platform: subprocess.call(["xdg-open", shared.appdata + 'keys.dat']) @@ -1379,12 +1441,11 @@ class MyForm(QtGui.QMainWindow): toAddress = addBMIfNotPresent(toAddress) try: shared.config.get(toAddress, 'enabled') - # The toAddress is one owned by me. We cannot send - # messages to ourselves without significant changes - # to the codebase. - QMessageBox.about(self, _translate("MainWindow", "Sending to your address"), _translate( - "MainWindow", "Error: One of the addresses to which you are sending a message, %1, is yours. Unfortunately the Bitmessage client cannot process its own messages. Please try running a second client on a different computer or within a VM.").arg(toAddress)) - continue + # The toAddress is one owned by me. + if not shared.safeConfigGetBoolean(toAddress, 'chan'): + QMessageBox.about(self, _translate("MainWindow", "Sending to your address"), _translate( + "MainWindow", "Error: One of the addresses to which you are sending a message, %1, is yours. Unfortunately the Bitmessage client cannot process its own messages. Please try running a second client on a different computer or within a VM.").arg(toAddress)) + continue except: pass if addressVersionNumber > 3 or addressVersionNumber <= 1: @@ -1517,6 +1578,16 @@ class MyForm(QtGui.QMainWindow): def redrawLabelFrom(self, index): self.ui.labelFrom.setText( self.ui.comboBoxSendFrom.itemData(index).toPyObject()) + self.setBroadcastEnablementDependingOnWhetherThisIsAChanAddress(self.ui.comboBoxSendFrom.itemData(index).toPyObject()) + + def setBroadcastEnablementDependingOnWhetherThisIsAChanAddress(self, address): + # If this is a chan then don't let people broadcast because no one + # should subscribe to chan addresses. + if shared.safeConfigGetBoolean(str(address), 'chan'): + self.ui.radioButtonSpecific.click() + self.ui.radioButtonBroadcast.setEnabled(False) + else: + self.ui.radioButtonBroadcast.setEnabled(True) def rerenderComboBoxSendFrom(self): self.ui.comboBoxSendFrom.clear() @@ -1633,6 +1704,8 @@ class MyForm(QtGui.QMainWindow): newItem.setData(Qt.UserRole, str(toAddress)) if shared.safeConfigGetBoolean(str(toAddress), 'mailinglist'): newItem.setTextColor(QtGui.QColor(137, 04, 177)) + if shared.safeConfigGetBoolean(str(toAddress), 'chan'): + newItem.setTextColor(QtGui.QColor(216, 119, 0)) # orange self.ui.tableWidgetInbox.insertRow(0) self.ui.tableWidgetInbox.setItem(0, 0, newItem) @@ -1672,45 +1745,47 @@ class MyForm(QtGui.QMainWindow): # 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. - shared.sqlLock.acquire() - t = (addBMIfNotPresent(str( - self.NewSubscriptionDialogInstance.ui.lineEditSubscriptionAddress.text())),) - shared.sqlSubmitQueue.put( - '''select * from addressbook where address=?''') - shared.sqlSubmitQueue.put(t) - queryreturn = shared.sqlReturnQueue.get() - shared.sqlLock.release() - if queryreturn == []: - self.ui.tableWidgetAddressBook.setSortingEnabled(False) - self.ui.tableWidgetAddressBook.insertRow(0) - newItem = QtGui.QTableWidgetItem(unicode( - self.NewSubscriptionDialogInstance.ui.newsubscriptionlabel.text().toUtf8(), 'utf-8')) - self.ui.tableWidgetAddressBook.setItem(0, 0, newItem) - newItem = QtGui.QTableWidgetItem(addBMIfNotPresent( - self.NewSubscriptionDialogInstance.ui.lineEditSubscriptionAddress.text())) - newItem.setFlags( - QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) - self.ui.tableWidgetAddressBook.setItem(0, 1, newItem) - self.ui.tableWidgetAddressBook.setSortingEnabled(True) - t = (str(self.NewSubscriptionDialogInstance.ui.newsubscriptionlabel.text().toUtf8()), addBMIfNotPresent( - str(self.NewSubscriptionDialogInstance.ui.lineEditSubscriptionAddress.text()))) - shared.sqlLock.acquire() - shared.sqlSubmitQueue.put( - '''INSERT INTO addressbook VALUES (?,?)''') - shared.sqlSubmitQueue.put(t) - queryreturn = shared.sqlReturnQueue.get() - shared.sqlSubmitQueue.put('commit') - shared.sqlLock.release() - self.rerenderInboxFromLabels() - self.rerenderSentToLabels() - else: - self.statusBar().showMessage(_translate( - "MainWindow", "Error: You cannot add the same address to your address book twice. Try renaming the existing one if you want.")) + address = addBMIfNotPresent(str( + self.NewSubscriptionDialogInstance.ui.lineEditSubscriptionAddress.text())) + label = self.NewSubscriptionDialogInstance.ui.newsubscriptionlabel.text().toUtf8() + self.addEntryToAddressBook(address,label) else: self.statusBar().showMessage(_translate( "MainWindow", "The address you entered was invalid. Ignoring it.")) - def addSubscription(self, label, address): + def addEntryToAddressBook(self,address,label): + shared.sqlLock.acquire() + t = (address,) + shared.sqlSubmitQueue.put( + '''select * from addressbook where address=?''') + shared.sqlSubmitQueue.put(t) + queryreturn = shared.sqlReturnQueue.get() + shared.sqlLock.release() + if queryreturn == []: + self.ui.tableWidgetAddressBook.setSortingEnabled(False) + self.ui.tableWidgetAddressBook.insertRow(0) + newItem = QtGui.QTableWidgetItem(unicode(label, 'utf-8')) + self.ui.tableWidgetAddressBook.setItem(0, 0, newItem) + newItem = QtGui.QTableWidgetItem(address) + newItem.setFlags( + QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) + self.ui.tableWidgetAddressBook.setItem(0, 1, newItem) + self.ui.tableWidgetAddressBook.setSortingEnabled(True) + t = (str(label), address) + shared.sqlLock.acquire() + shared.sqlSubmitQueue.put( + '''INSERT INTO addressbook VALUES (?,?)''') + shared.sqlSubmitQueue.put(t) + queryreturn = shared.sqlReturnQueue.get() + shared.sqlSubmitQueue.put('commit') + shared.sqlLock.release() + self.rerenderInboxFromLabels() + self.rerenderSentToLabels() + else: + self.statusBar().showMessage(_translate( + "MainWindow", "Error: You cannot add the same address to your address book twice. Try renaming the existing one if you want.")) + + def addSubscription(self, address, label): address = addBMIfNotPresent(address) #This should be handled outside of this function, for error displaying and such, but it must also be checked here. if shared.isAddressInMySubscriptionsList(address): @@ -1747,7 +1822,7 @@ class MyForm(QtGui.QMainWindow): self.statusBar().showMessage(_translate("MainWindow", "Error: You cannot add the same address to your subsciptions twice. Perhaps rename the existing one if you want.")) return label = self.NewSubscriptionDialogInstance.ui.newsubscriptionlabel.text().toUtf8() - self.addSubscription(label, address) + self.addSubscription(address, label) def loadBlackWhiteList(self): # Initialize the Blacklist or Whitelist table @@ -1990,6 +2065,8 @@ class MyForm(QtGui.QMainWindow): currentRow = self.ui.tableWidgetYourIdentities.currentRow() addressAtCurrentRow = str( self.ui.tableWidgetYourIdentities.item(currentRow, 1).text()) + if shared.safeConfigGetBoolean(addressAtCurrentRow, 'chan'): + return if self.dialog.ui.radioButtonBehaveNormalAddress.isChecked(): shared.config.set(str( addressAtCurrentRow), 'mailinglist', 'false') @@ -2023,12 +2100,6 @@ class MyForm(QtGui.QMainWindow): # address.' streamNumberForAddress = addressStream( self.dialog.ui.comboBoxExisting.currentText()) - - # self.addressGenerator = addressGenerator() - # self.addressGenerator.setup(3,streamNumberForAddress,str(self.dialog.ui.newaddresslabel.text().toUtf8()),1,"",self.dialog.ui.checkBoxEighteenByteRipe.isChecked()) - # QtCore.QObject.connect(self.addressGenerator, SIGNAL("writeNewAddressToTable(PyQt_PyObject,PyQt_PyObject,PyQt_PyObject)"), self.writeNewAddressToTable) - # QtCore.QObject.connect(self.addressGenerator, QtCore.SIGNAL("updateStatusBar(PyQt_PyObject)"), self.updateStatusBar) - # self.addressGenerator.start() shared.addressGeneratorQueue.put(('createRandomAddress', 3, streamNumberForAddress, str( self.dialog.ui.newaddresslabel.text().toUtf8()), 1, "", self.dialog.ui.checkBoxEighteenByteRipe.isChecked())) else: @@ -2040,11 +2111,6 @@ class MyForm(QtGui.QMainWindow): "MainWindow", "Choose a passphrase"), _translate("MainWindow", "You really do need a passphrase.")) else: streamNumberForAddress = 1 # this will eventually have to be replaced by logic to determine the most available stream number. - # self.addressGenerator = addressGenerator() - # self.addressGenerator.setup(3,streamNumberForAddress,"unused address",self.dialog.ui.spinBoxNumberOfAddressesToMake.value(),self.dialog.ui.lineEditPassphrase.text().toUtf8(),self.dialog.ui.checkBoxEighteenByteRipe.isChecked()) - # QtCore.QObject.connect(self.addressGenerator, SIGNAL("writeNewAddressToTable(PyQt_PyObject,PyQt_PyObject,PyQt_PyObject)"), self.writeNewAddressToTable) - # QtCore.QObject.connect(self.addressGenerator, QtCore.SIGNAL("updateStatusBar(PyQt_PyObject)"), self.updateStatusBar) - # self.addressGenerator.start() shared.addressGeneratorQueue.put(('createDeterministicAddresses', 3, streamNumberForAddress, "unused deterministic address", self.dialog.ui.spinBoxNumberOfAddressesToMake.value( ), self.dialog.ui.lineEditPassphrase.text().toUtf8(), self.dialog.ui.checkBoxEighteenByteRipe.isChecked())) else: @@ -2121,6 +2187,7 @@ class MyForm(QtGui.QMainWindow): self.ui.labelFrom.setText('') else: self.ui.labelFrom.setText(toAddressAtCurrentInboxRow) + self.setBroadcastEnablementDependingOnWhetherThisIsAChanAddress(toAddressAtCurrentInboxRow) self.ui.lineEditTo.setText(str(fromAddressAtCurrentInboxRow)) self.ui.comboBoxSendFrom.setCurrentIndex(0) # self.ui.comboBoxSendFrom.setEditText(str(self.ui.tableWidgetInbox.item(currentInboxRow,0).text)) @@ -2344,7 +2411,7 @@ class MyForm(QtGui.QMainWindow): self.statusBar().showMessage(QtGui.QApplication.translate("MainWindow", "Error: You cannot add the same address to your subsciptions twice. Perhaps rename the existing one if you want.")) continue labelAtCurrentRow = self.ui.tableWidgetAddressBook.item(currentRow,0).text().toUtf8() - self.addSubscription(labelAtCurrentRow, addressAtCurrentRow) + self.addSubscription(addressAtCurrentRow, labelAtCurrentRow) self.ui.tabWidget.setCurrentIndex(4) def on_context_menuAddressBook(self, point): @@ -2527,6 +2594,8 @@ class MyForm(QtGui.QMainWindow): currentRow, 2).setTextColor(QtGui.QColor(0, 0, 0)) if shared.safeConfigGetBoolean(addressAtCurrentRow, 'mailinglist'): self.ui.tableWidgetYourIdentities.item(currentRow, 1).setTextColor(QtGui.QColor(137, 04, 177)) + if shared.safeConfigGetBoolean(addressAtCurrentRow, 'chan'): + self.ui.tableWidgetYourIdentities.item(currentRow, 1).setTextColor(QtGui.QColor(216, 119, 0)) # orange shared.reloadMyAddressHashes() def on_action_YourIdentitiesDisable(self): @@ -2695,11 +2764,14 @@ class MyForm(QtGui.QMainWindow): def writeNewAddressToTable(self, label, address, streamNumber): self.ui.tableWidgetYourIdentities.setSortingEnabled(False) self.ui.tableWidgetYourIdentities.insertRow(0) + newItem = QtGui.QTableWidgetItem(unicode(label, 'utf-8')) self.ui.tableWidgetYourIdentities.setItem( - 0, 0, QtGui.QTableWidgetItem(unicode(label, 'utf-8'))) + 0, 0, newItem) newItem = QtGui.QTableWidgetItem(address) newItem.setFlags( QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) + if shared.safeConfigGetBoolean(address, 'chan'): + newItem.setTextColor(QtGui.QColor(216, 119, 0)) # orange self.ui.tableWidgetYourIdentities.setItem(0, 1, newItem) newItem = QtGui.QTableWidgetItem(streamNumber) newItem.setFlags( @@ -2746,7 +2818,6 @@ class regenerateAddressesDialog(QtGui.QDialog): self.parent = parent QtGui.QWidget.resize(self, QtGui.QWidget.sizeHint(self)) - class settingsDialog(QtGui.QDialog): def __init__(self, parent): @@ -2869,17 +2940,23 @@ class SpecialAddressBehaviorDialog(QtGui.QDialog): currentRow = parent.ui.tableWidgetYourIdentities.currentRow() addressAtCurrentRow = str( parent.ui.tableWidgetYourIdentities.item(currentRow, 1).text()) - if shared.safeConfigGetBoolean(addressAtCurrentRow, 'mailinglist'): - self.ui.radioButtonBehaviorMailingList.click() - else: - self.ui.radioButtonBehaveNormalAddress.click() - try: - mailingListName = shared.config.get( - addressAtCurrentRow, 'mailinglistname') - except: - mailingListName = '' - self.ui.lineEditMailingListName.setText( - unicode(mailingListName, 'utf-8')) + if not shared.safeConfigGetBoolean(addressAtCurrentRow, 'chan'): + if shared.safeConfigGetBoolean(addressAtCurrentRow, 'mailinglist'): + self.ui.radioButtonBehaviorMailingList.click() + else: + self.ui.radioButtonBehaveNormalAddress.click() + try: + mailingListName = shared.config.get( + addressAtCurrentRow, 'mailinglistname') + except: + mailingListName = '' + self.ui.lineEditMailingListName.setText( + unicode(mailingListName, 'utf-8')) + else: # if addressAtCurrentRow is a chan address + self.ui.radioButtonBehaviorMailingList.setDisabled(True) + self.ui.lineEditMailingListName.setText(_translate( + "MainWindow", "This is a chan address. You cannot use it as a pseudo-mailing list.")) + QtGui.QWidget.resize(self, QtGui.QWidget.sizeHint(self)) @@ -2938,11 +3015,11 @@ class NewAddressDialog(QtGui.QDialog): self.ui.groupBoxDeterministic.setHidden(True) QtGui.QWidget.resize(self, QtGui.QWidget.sizeHint(self)) -class NewChanDialog(QtGui.QDialog): +class newChanDialog(QtGui.QDialog): def __init__(self, parent): QtGui.QWidget.__init__(self, parent) - self.ui = Ui_NewChanDialog() + self.ui = Ui_newChanDialog() self.ui.setupUi(self) self.parent = parent self.ui.groupBoxCreateChan.setHidden(True) diff --git a/src/bitmessageqt/bitmessageui.py b/src/bitmessageqt/bitmessageui.py index 1d04e5f1..4efecb97 100644 --- a/src/bitmessageqt/bitmessageui.py +++ b/src/bitmessageqt/bitmessageui.py @@ -2,7 +2,7 @@ # Form implementation generated from reading ui file 'bitmessageui.ui' # -# Created: Sat Jul 13 20:23:44 2013 +# Created: Sun Jul 21 17:50:02 2013 # by: PyQt4 UI code generator 4.10.2 # # WARNING! All changes made in this file will be lost! @@ -453,9 +453,12 @@ class Ui_MainWindow(object): self.actionRegenerateDeterministicAddresses.setObjectName(_fromUtf8("actionRegenerateDeterministicAddresses")) self.actionDeleteAllTrashedMessages = QtGui.QAction(MainWindow) self.actionDeleteAllTrashedMessages.setObjectName(_fromUtf8("actionDeleteAllTrashedMessages")) + self.actionJoinChan = QtGui.QAction(MainWindow) + self.actionJoinChan.setObjectName(_fromUtf8("actionJoinChan")) self.menuFile.addAction(self.actionManageKeys) self.menuFile.addAction(self.actionDeleteAllTrashedMessages) self.menuFile.addAction(self.actionRegenerateDeterministicAddresses) + self.menuFile.addAction(self.actionJoinChan) self.menuFile.addAction(self.actionExit) self.menuSettings.addAction(self.actionSettings) self.menuHelp.addAction(self.actionHelp) @@ -599,5 +602,6 @@ class Ui_MainWindow(object): self.actionSettings.setText(_translate("MainWindow", "Settings", None)) self.actionRegenerateDeterministicAddresses.setText(_translate("MainWindow", "Regenerate deterministic addresses", None)) self.actionDeleteAllTrashedMessages.setText(_translate("MainWindow", "Delete all trashed messages", None)) + self.actionJoinChan.setText(_translate("MainWindow", "Join / Create chan", None)) import bitmessage_icons_rc diff --git a/src/bitmessageqt/bitmessageui.ui b/src/bitmessageqt/bitmessageui.ui index 6c18cbe0..d4478fc8 100644 --- a/src/bitmessageqt/bitmessageui.ui +++ b/src/bitmessageqt/bitmessageui.ui @@ -14,7 +14,7 @@ Bitmessage - + :/newPrefix/images/can-icon-24px.png:/newPrefix/images/can-icon-24px.png @@ -61,7 +61,7 @@ - + :/newPrefix/images/inbox.png:/newPrefix/images/inbox.png @@ -188,7 +188,7 @@ - + :/newPrefix/images/send.png:/newPrefix/images/send.png @@ -346,7 +346,7 @@ p, li { white-space: pre-wrap; } - + :/newPrefix/images/sent.png:/newPrefix/images/sent.png @@ -466,7 +466,7 @@ p, li { white-space: pre-wrap; } - + :/newPrefix/images/identities.png:/newPrefix/images/identities.png @@ -566,7 +566,7 @@ p, li { white-space: pre-wrap; } - + :/newPrefix/images/subscriptions.png:/newPrefix/images/subscriptions.png @@ -651,7 +651,7 @@ p, li { white-space: pre-wrap; } - + :/newPrefix/images/addressbook.png:/newPrefix/images/addressbook.png @@ -733,7 +733,7 @@ p, li { white-space: pre-wrap; } - + :/newPrefix/images/blacklist.png:/newPrefix/images/blacklist.png @@ -825,7 +825,7 @@ p, li { white-space: pre-wrap; } - + :/newPrefix/images/networkstatus.png:/newPrefix/images/networkstatus.png @@ -844,7 +844,7 @@ p, li { white-space: pre-wrap; } - + :/newPrefix/images/redicon.png:/newPrefix/images/redicon.png @@ -1021,6 +1021,7 @@ p, li { white-space: pre-wrap; } + @@ -1094,6 +1095,11 @@ p, li { white-space: pre-wrap; } Delete all trashed messages + + + Join / Create chan + + tabWidget diff --git a/src/bitmessageqt/newchandialog.py b/src/bitmessageqt/newchandialog.py index 5c5e11f2..43235bfa 100644 --- a/src/bitmessageqt/newchandialog.py +++ b/src/bitmessageqt/newchandialog.py @@ -2,7 +2,7 @@ # Form implementation generated from reading ui file 'newchandialog.ui' # -# Created: Tue Jun 25 17:03:01 2013 +# Created: Mon Jul 22 01:05:35 2013 # by: PyQt4 UI code generator 4.10.2 # # WARNING! All changes made in this file will be lost! @@ -23,20 +23,36 @@ except AttributeError: def _translate(context, text, disambig): return QtGui.QApplication.translate(context, text, disambig) -class Ui_NewChanDialog(object): - def setupUi(self, NewChanDialog): - NewChanDialog.setObjectName(_fromUtf8("NewChanDialog")) - NewChanDialog.resize(447, 441) - self.formLayout = QtGui.QFormLayout(NewChanDialog) +class Ui_newChanDialog(object): + def setupUi(self, newChanDialog): + newChanDialog.setObjectName(_fromUtf8("newChanDialog")) + newChanDialog.resize(530, 422) + newChanDialog.setMinimumSize(QtCore.QSize(0, 0)) + self.formLayout = QtGui.QFormLayout(newChanDialog) self.formLayout.setObjectName(_fromUtf8("formLayout")) - self.radioButtonCreateChan = QtGui.QRadioButton(NewChanDialog) + self.radioButtonCreateChan = QtGui.QRadioButton(newChanDialog) self.radioButtonCreateChan.setObjectName(_fromUtf8("radioButtonCreateChan")) self.formLayout.setWidget(0, QtGui.QFormLayout.LabelRole, self.radioButtonCreateChan) - self.radioButtonJoinChan = QtGui.QRadioButton(NewChanDialog) + self.radioButtonJoinChan = QtGui.QRadioButton(newChanDialog) self.radioButtonJoinChan.setChecked(True) self.radioButtonJoinChan.setObjectName(_fromUtf8("radioButtonJoinChan")) self.formLayout.setWidget(1, QtGui.QFormLayout.LabelRole, self.radioButtonJoinChan) - self.groupBoxJoinChan = QtGui.QGroupBox(NewChanDialog) + self.groupBoxCreateChan = QtGui.QGroupBox(newChanDialog) + self.groupBoxCreateChan.setObjectName(_fromUtf8("groupBoxCreateChan")) + self.gridLayout = QtGui.QGridLayout(self.groupBoxCreateChan) + self.gridLayout.setObjectName(_fromUtf8("gridLayout")) + self.label_4 = QtGui.QLabel(self.groupBoxCreateChan) + self.label_4.setWordWrap(True) + self.label_4.setObjectName(_fromUtf8("label_4")) + self.gridLayout.addWidget(self.label_4, 0, 0, 1, 1) + self.label_5 = QtGui.QLabel(self.groupBoxCreateChan) + self.label_5.setObjectName(_fromUtf8("label_5")) + self.gridLayout.addWidget(self.label_5, 1, 0, 1, 1) + self.lineEditChanNameCreate = QtGui.QLineEdit(self.groupBoxCreateChan) + self.lineEditChanNameCreate.setObjectName(_fromUtf8("lineEditChanNameCreate")) + self.gridLayout.addWidget(self.lineEditChanNameCreate, 2, 0, 1, 1) + self.formLayout.setWidget(2, QtGui.QFormLayout.SpanningRole, self.groupBoxCreateChan) + self.groupBoxJoinChan = QtGui.QGroupBox(newChanDialog) self.groupBoxJoinChan.setObjectName(_fromUtf8("groupBoxJoinChan")) self.gridLayout_2 = QtGui.QGridLayout(self.groupBoxJoinChan) self.gridLayout_2.setObjectName(_fromUtf8("gridLayout_2")) @@ -57,43 +73,30 @@ class Ui_NewChanDialog(object): self.lineEditChanBitmessageAddress.setObjectName(_fromUtf8("lineEditChanBitmessageAddress")) self.gridLayout_2.addWidget(self.lineEditChanBitmessageAddress, 4, 0, 1, 1) self.formLayout.setWidget(3, QtGui.QFormLayout.SpanningRole, self.groupBoxJoinChan) - self.groupBoxCreateChan = QtGui.QGroupBox(NewChanDialog) - self.groupBoxCreateChan.setObjectName(_fromUtf8("groupBoxCreateChan")) - self.gridLayout = QtGui.QGridLayout(self.groupBoxCreateChan) - self.gridLayout.setObjectName(_fromUtf8("gridLayout")) - self.label_4 = QtGui.QLabel(self.groupBoxCreateChan) - self.label_4.setWordWrap(True) - self.label_4.setObjectName(_fromUtf8("label_4")) - self.gridLayout.addWidget(self.label_4, 0, 0, 1, 1) - self.label_5 = QtGui.QLabel(self.groupBoxCreateChan) - self.label_5.setObjectName(_fromUtf8("label_5")) - self.gridLayout.addWidget(self.label_5, 1, 0, 1, 1) - self.lineEditChanNameCreate = QtGui.QLineEdit(self.groupBoxCreateChan) - self.lineEditChanNameCreate.setObjectName(_fromUtf8("lineEditChanNameCreate")) - self.gridLayout.addWidget(self.lineEditChanNameCreate, 2, 0, 1, 1) - self.formLayout.setWidget(2, QtGui.QFormLayout.SpanningRole, self.groupBoxCreateChan) - self.buttonBox = QtGui.QDialogButtonBox(NewChanDialog) + spacerItem = QtGui.QSpacerItem(389, 2, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) + self.formLayout.setItem(4, QtGui.QFormLayout.FieldRole, spacerItem) + self.buttonBox = QtGui.QDialogButtonBox(newChanDialog) self.buttonBox.setOrientation(QtCore.Qt.Horizontal) self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Ok) self.buttonBox.setObjectName(_fromUtf8("buttonBox")) - self.formLayout.setWidget(4, QtGui.QFormLayout.FieldRole, self.buttonBox) + self.formLayout.setWidget(5, QtGui.QFormLayout.FieldRole, self.buttonBox) - self.retranslateUi(NewChanDialog) - QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("accepted()")), NewChanDialog.accept) - QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("rejected()")), NewChanDialog.reject) + self.retranslateUi(newChanDialog) + QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("accepted()")), newChanDialog.accept) + QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("rejected()")), newChanDialog.reject) QtCore.QObject.connect(self.radioButtonJoinChan, QtCore.SIGNAL(_fromUtf8("toggled(bool)")), self.groupBoxJoinChan.setShown) QtCore.QObject.connect(self.radioButtonCreateChan, QtCore.SIGNAL(_fromUtf8("toggled(bool)")), self.groupBoxCreateChan.setShown) - QtCore.QMetaObject.connectSlotsByName(NewChanDialog) + QtCore.QMetaObject.connectSlotsByName(newChanDialog) - def retranslateUi(self, NewChanDialog): - NewChanDialog.setWindowTitle(_translate("NewChanDialog", "Dialog", None)) - self.radioButtonCreateChan.setText(_translate("NewChanDialog", "Create a new chan", None)) - self.radioButtonJoinChan.setText(_translate("NewChanDialog", "Join a chan", None)) - self.groupBoxJoinChan.setTitle(_translate("NewChanDialog", "Join a chan", None)) - self.label.setText(_translate("NewChanDialog", "

A chan is a set of encryption keys that is shared by a group of people. The keys and bitmessage address used by a chan is generated from a human-friendly word or phrase (the chan name).

Chans are experimental and are unmoderatable.

", None)) - self.label_2.setText(_translate("NewChanDialog", "Chan name:", None)) - self.label_3.setText(_translate("NewChanDialog", "Chan bitmessage address:", None)) - self.groupBoxCreateChan.setTitle(_translate("NewChanDialog", "Create a chan", None)) - self.label_4.setText(_translate("NewChanDialog", "Enter a name for your chan. If you choose a sufficiently complex chan name (like a strong and unique passphrase) and none of your friends share it publicly then the chan will be secure and private.", None)) - self.label_5.setText(_translate("NewChanDialog", "Chan name:", None)) + def retranslateUi(self, newChanDialog): + newChanDialog.setWindowTitle(_translate("newChanDialog", "Dialog", None)) + self.radioButtonCreateChan.setText(_translate("newChanDialog", "Create a new chan", None)) + self.radioButtonJoinChan.setText(_translate("newChanDialog", "Join a chan", None)) + self.groupBoxCreateChan.setTitle(_translate("newChanDialog", "Create a chan", None)) + self.label_4.setText(_translate("newChanDialog", "Enter a name for your chan. If you choose a sufficiently complex chan name (like a strong and unique passphrase) and none of your friends share it publicly then the chan will be secure and private.", None)) + self.label_5.setText(_translate("newChanDialog", "Chan name:", None)) + self.groupBoxJoinChan.setTitle(_translate("newChanDialog", "Join a chan", None)) + self.label.setText(_translate("newChanDialog", "

A chan exists when a group of people share the same decryption keys. The keys and bitmessage address used by a chan are generated from a human-friendly word or phrase (the chan name). To send a message to everyone in the chan, send a normal person-to-person message to the chan address.

Chans are experimental and completely unmoderatable.

", None)) + self.label_2.setText(_translate("newChanDialog", "Chan name:", None)) + self.label_3.setText(_translate("newChanDialog", "Chan bitmessage address:", None)) diff --git a/src/bitmessageqt/newchandialog.ui b/src/bitmessageqt/newchandialog.ui index 2e6e4657..3713c6a3 100644 --- a/src/bitmessageqt/newchandialog.ui +++ b/src/bitmessageqt/newchandialog.ui @@ -1,15 +1,21 @@ - NewChanDialog - + newChanDialog + 0 0 - 447 - 441 + 530 + 422 + + + 0 + 0 + + Dialog @@ -31,45 +37,6 @@ - - - - Join a chan - - - - - - <html><head/><body><p>A chan is a set of encryption keys that is shared by a group of people. The keys and bitmessage address used by a chan is generated from a human-friendly word or phrase (the chan name).</p><p>Chans are experimental and are unmoderatable.</p></body></html> - - - true - - - - - - - Chan name: - - - - - - - - - - Chan bitmessage address: - - - - - - - - - @@ -99,7 +66,59 @@ + + + + Join a chan + + + + + + <html><head/><body><p>A chan exists when a group of people share the same decryption keys. The keys and bitmessage address used by a chan are generated from a human-friendly word or phrase (the chan name). To send a message to everyone in the chan, send a normal person-to-person message to the chan address.</p><p>Chans are experimental and completely unmoderatable.</p></body></html> + + + true + + + + + + + Chan name: + + + + + + + + + + Chan bitmessage address: + + + + + + + + + + + + Qt::Vertical + + + + 389 + 2 + + + + + Qt::Horizontal @@ -116,7 +135,7 @@ buttonBox accepted() - NewChanDialog + newChanDialog accept() @@ -132,7 +151,7 @@ buttonBox rejected() - NewChanDialog + newChanDialog reject() diff --git a/src/class_addressGenerator.py b/src/class_addressGenerator.py index 08c7773e..54582541 100644 --- a/src/class_addressGenerator.py +++ b/src/class_addressGenerator.py @@ -28,6 +28,8 @@ class addressGenerator(threading.Thread): elif queueValue[0] == 'joinChan': command, chanAddress, label, deterministicPassphrase = queueValue eighteenByteRipe = False + addressVersionNumber = decodeAddress(chanAddress)[1] + streamNumber = decodeAddress(chanAddress)[2] numberOfAddressesToMake = 1 elif len(queueValue) == 7: command, addressVersionNumber, streamNumber, label, numberOfAddressesToMake, deterministicPassphrase, eighteenByteRipe = queueValue @@ -35,7 +37,7 @@ class addressGenerator(threading.Thread): command, addressVersionNumber, streamNumber, label, numberOfAddressesToMake, deterministicPassphrase, eighteenByteRipe, nonceTrialsPerByte, payloadLengthExtraBytes = queueValue else: sys.stderr.write( - 'Programming error: A structure with the wrong number of values was passed into the addressGeneratorQueue. Here is the queueValue: %s\n' % queueValue) + 'Programming error: A structure with the wrong number of values was passed into the addressGeneratorQueue. Here is the queueValue: %s\n' % repr(queueValue)) if addressVersionNumber < 3 or addressVersionNumber > 3: sys.stderr.write( 'Program error: For some reason the address generator queue has been given a request to create at least one version %s address which it cannot do.\n' % addressVersionNumber) @@ -117,9 +119,8 @@ class addressGenerator(threading.Thread): with open(shared.appdata + 'keys.dat', 'wb') as configfile: shared.config.write(configfile) - # It may be the case that this address is being generated - # as a result of a call to the API. Let us put the result - # in the necessary queue. + # The API and the join and create Chan functionality + # both need information back from the address generator. shared.apiAddressGeneratorReturnQueue.put(address) shared.UISignalQueue.put(( @@ -128,7 +129,7 @@ class addressGenerator(threading.Thread): label, address, streamNumber))) shared.reloadMyAddressHashes() shared.workerQueue.put(( - 'doPOWForMyV3Pubkey', ripe.digest())) + 'sendOutOrStoreMyV3Pubkey', ripe.digest())) elif command == 'createDeterministicAddresses' or command == 'getDeterministicAddress' or command == 'createChan' or command == 'joinChan': if len(deterministicPassphrase) == 0: @@ -188,8 +189,7 @@ class addressGenerator(threading.Thread): # If we are joining an existing chan, let us check to make sure it matches the provided Bitmessage address if command == 'joinChan': if address != chanAddress: - #todo: show an error message in the UI - shared.apiAddressGeneratorReturnQueue.put('API Error 0018: Chan name does not match address.') + shared.apiAddressGeneratorReturnQueue.put('chan name does not match address') saveAddressToDisk = False if command == 'getDeterministicAddress': saveAddressToDisk = False @@ -210,8 +210,13 @@ class addressGenerator(threading.Thread): privEncryptionKeyWIF = arithmetic.changebase( privEncryptionKey + checksum, 256, 58) + addressAlreadyExists = False try: shared.config.add_section(address) + except: + print address, 'already exists. Not adding it again.' + addressAlreadyExists = True + if not addressAlreadyExists: print 'label:', label shared.config.set(address, 'label', label) shared.config.set(address, 'enabled', 'true') @@ -237,17 +242,13 @@ class addressGenerator(threading.Thread): potentialPrivEncryptionKey.encode('hex')) shared.myAddressesByHash[ ripe.digest()] = address - #todo: don't send out pubkey if dealing with a chan; save in pubkeys table instead. shared.workerQueue.put(( - 'doPOWForMyV3Pubkey', ripe.digest())) - except: - print address, 'already exists. Not adding it again.' + 'sendOutOrStoreMyV3Pubkey', ripe.digest())) # If this is a chan address, + # the worker thread won't send out the pubkey over the network. + # Done generating addresses. - if command == 'createDeterministicAddresses': - # It may be the case that this address is being - # generated as a result of a call to the API. Let us - # put the result in the necessary queue. + if command == 'createDeterministicAddresses' or command == 'joinChan' or command == 'createChan': shared.apiAddressGeneratorReturnQueue.put( listOfNewAddressesToSendOutThroughTheAPI) shared.UISignalQueue.put(( diff --git a/src/class_outgoingSynSender.py b/src/class_outgoingSynSender.py index 2c4766f4..5c21d72c 100644 --- a/src/class_outgoingSynSender.py +++ b/src/class_outgoingSynSender.py @@ -7,7 +7,6 @@ import socket import sys import tr -#import bitmessagemain from class_sendDataThread import * from class_receiveDataThread import * diff --git a/src/class_receiveDataThread.py b/src/class_receiveDataThread.py index e73f3d2b..2693b293 100644 --- a/src/class_receiveDataThread.py +++ b/src/class_receiveDataThread.py @@ -1412,34 +1412,39 @@ class receiveDataThread(threading.Thread): if len(requestedHash) != 20: print 'The length of the requested hash is not 20 bytes. Something is wrong. Ignoring.' return - print 'the hash requested in this getpubkey request is:', requestedHash.encode('hex') + with shared.printLock: + print 'the hash requested in this getpubkey request is:', requestedHash.encode('hex') if requestedHash in shared.myAddressesByHash: # if this address hash is one of mine if decodeAddress(shared.myAddressesByHash[requestedHash])[1] != requestedAddressVersionNumber: with shared.printLock: sys.stderr.write( - '(Within the recgetpubkey function) Someone requested one of my pubkeys but the requestedAddressVersionNumber doesn\'t match my actual address version number. That shouldn\'t have happened. Ignoring.\n') - + '(Within the recgetpubkey function) Someone requested one of my pubkeys but the requestedAddressVersionNumber doesn\'t match my actual address version number. They shouldn\'t have done that. Ignoring.\n') return + if shared.safeConfigGetBoolean(shared.myAddressesByHash[requestedHash], 'chan'): + with shared.printLock: + print 'Ignoring getpubkey request because it is for one of my chan addresses. The other party should already have the pubkey.' + return try: lastPubkeySendTime = int(shared.config.get( shared.myAddressesByHash[requestedHash], 'lastpubkeysendtime')) except: lastPubkeySendTime = 0 - if lastPubkeySendTime < time.time() - shared.lengthOfTimeToHoldOnToAllPubkeys: # If the last time we sent our pubkey was at least 28 days ago... - with shared.printLock: - print 'Found getpubkey-requested-hash in my list of EC hashes. Telling Worker thread to do the POW for a pubkey message and send it out.' - - if requestedAddressVersionNumber == 2: - shared.workerQueue.put(( - 'doPOWForMyV2Pubkey', requestedHash)) - elif requestedAddressVersionNumber == 3: - shared.workerQueue.put(( - 'doPOWForMyV3Pubkey', requestedHash)) - else: + if lastPubkeySendTime > time.time() - shared.lengthOfTimeToHoldOnToAllPubkeys: # If the last time we sent our pubkey was more recent than 28 days ago... with shared.printLock: print 'Found getpubkey-requested-hash in my list of EC hashes BUT we already sent it recently. Ignoring request. The lastPubkeySendTime is:', lastPubkeySendTime + return + with shared.printLock: + print 'Found getpubkey-requested-hash in my list of EC hashes. Telling Worker thread to do the POW for a pubkey message and send it out.' + if requestedAddressVersionNumber == 2: + shared.workerQueue.put(( + 'doPOWForMyV2Pubkey', requestedHash)) + elif requestedAddressVersionNumber == 3: + shared.workerQueue.put(( + 'sendOutOrStoreMyV3Pubkey', requestedHash)) + + else: with shared.printLock: print 'This getpubkey request is not for any of my keys.' diff --git a/src/class_singleWorker.py b/src/class_singleWorker.py index 56b7be6e..2ba34eeb 100644 --- a/src/class_singleWorker.py +++ b/src/class_singleWorker.py @@ -72,8 +72,8 @@ class singleWorker(threading.Thread): self.sendBroadcast() elif command == 'doPOWForMyV2Pubkey': self.doPOWForMyV2Pubkey(data) - elif command == 'doPOWForMyV3Pubkey': - self.doPOWForMyV3Pubkey(data) + elif command == 'sendOutOrStoreMyV3Pubkey': + self.sendOutOrStoreMyV3Pubkey(data) """elif command == 'newpubkey': toAddressVersion,toStreamNumber,toRipe = data if toRipe in shared.neededPubkeys: @@ -173,7 +173,11 @@ class singleWorker(threading.Thread): with open(shared.appdata + 'keys.dat', 'wb') as configfile: shared.config.write(configfile) - def doPOWForMyV3Pubkey(self, hash): # This function also broadcasts out the pubkey message once it is done with the POW + # 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". + def sendOutOrStoreMyV3Pubkey(self, hash): myAddress = shared.myAddressesByHash[hash] status, addressVersionNumber, streamNumber, hash = decodeAddress( myAddress) @@ -192,7 +196,7 @@ class singleWorker(threading.Thread): except Exception as err: with shared.printLock: sys.stderr.write( - 'Error within doPOWForMyV3Pubkey. Could not read the keys from the keys.dat file for a requested address. %s\n' % err) + 'Error within sendOutOrStoreMyV3Pubkey. Could not read the keys from the keys.dat file for a requested address. %s\n' % err) return @@ -216,34 +220,40 @@ class singleWorker(threading.Thread): payload += encodeVarint(len(signature)) payload += signature - # Do the POW for this pubkey message - target = 2 ** 64 / ((len(payload) + shared.networkDefaultPayloadLengthExtraBytes + - 8) * shared.networkDefaultProofOfWorkNonceTrialsPerByte) - print '(For pubkey message) Doing proof of work...' - initialHash = hashlib.sha512(payload).digest() - trialValue, nonce = proofofwork.run(target, initialHash) - print '(For pubkey message) Found proof of work', trialValue, 'Nonce:', nonce + if not shared.safeConfigGetBoolean(myAddress, 'chan'): + # Do the POW for this pubkey message + target = 2 ** 64 / ((len(payload) + shared.networkDefaultPayloadLengthExtraBytes + + 8) * shared.networkDefaultProofOfWorkNonceTrialsPerByte) + print '(For pubkey message) Doing proof of work...' + initialHash = hashlib.sha512(payload).digest() + trialValue, nonce = proofofwork.run(target, initialHash) + print '(For pubkey message) Found proof of work', trialValue, 'Nonce:', nonce - payload = pack('>Q', nonce) + payload - """t = (hash,payload,embeddedTime,'no') - shared.sqlLock.acquire() - shared.sqlSubmitQueue.put('''INSERT INTO pubkeys VALUES (?,?,?,?)''') - shared.sqlSubmitQueue.put(t) - queryreturn = shared.sqlReturnQueue.get() - shared.sqlSubmitQueue.put('commit') - shared.sqlLock.release()""" + payload = pack('>Q', nonce) + payload + inventoryHash = calculateInventoryHash(payload) + objectType = 'pubkey' + shared.inventory[inventoryHash] = ( + objectType, streamNumber, payload, embeddedTime) - inventoryHash = calculateInventoryHash(payload) - objectType = 'pubkey' - shared.inventory[inventoryHash] = ( - objectType, streamNumber, payload, embeddedTime) + with shared.printLock: + print 'broadcasting inv with hash:', inventoryHash.encode('hex') - with shared.printLock: - print 'broadcasting inv with hash:', inventoryHash.encode('hex') - - shared.broadcastToSendDataQueues(( - streamNumber, 'sendinv', inventoryHash)) - shared.UISignalQueue.put(('updateStatusBar', '')) + shared.broadcastToSendDataQueues(( + streamNumber, 'sendinv', inventoryHash)) + shared.UISignalQueue.put(('updateStatusBar', '')) + # If this is a chan address then we won't send out the pubkey over the + # network but rather will only store it in our pubkeys table so that + # we can send messages to "ourselves". + if shared.safeConfigGetBoolean(myAddress, 'chan'): + payload = '\x00' * 8 + payload # Attach a fake nonce on the front + # just so that it is in the correct format. + t = (hash,payload,embeddedTime,'yes') + shared.sqlLock.acquire() + shared.sqlSubmitQueue.put('''INSERT INTO pubkeys VALUES (?,?,?,?)''') + shared.sqlSubmitQueue.put(t) + shared.sqlReturnQueue.get() + shared.sqlSubmitQueue.put('commit') + shared.sqlLock.release() shared.config.set( myAddress, 'lastpubkeysendtime', str(int(time.time()))) with open(shared.appdata + 'keys.dat', 'wb') as configfile: @@ -722,8 +732,13 @@ class singleWorker(threading.Thread): subject + '\n' + 'Body:' + message payload += encodeVarint(len(messageToTransmit)) payload += messageToTransmit - fullAckPayload = self.generateFullAckMessage( - ackdata, toStreamNumber, embeddedTime) # 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. + if shared.safeConfigGetBoolean(toaddress, 'chan'): + with shared.printLock: + print 'Not bothering to generate ackdata because we are sending to a chan.' + fullAckPayload = '' + else: + fullAckPayload = self.generateFullAckMessage( + ackdata, toStreamNumber, embeddedTime) # 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. payload += encodeVarint(len(fullAckPayload)) payload += fullAckPayload signature = highlevelcrypto.sign(payload, privSigningKeyHex) @@ -765,17 +780,26 @@ class singleWorker(threading.Thread): objectType = 'msg' shared.inventory[inventoryHash] = ( objectType, toStreamNumber, encryptedPayload, int(time.time())) - shared.UISignalQueue.put(('updateSentItemStatusByAckdata', (ackdata, tr.translateText("MainWindow", "Message sent. Waiting on acknowledgement. Sent on %1").arg(unicode( - strftime(shared.config.get('bitmessagesettings', 'timeformat'), localtime(int(time.time()))), 'utf-8'))))) + if shared.safeConfigGetBoolean(toaddress, 'chan'): + shared.UISignalQueue.put(('updateSentItemStatusByAckdata', (ackdata, tr.translateText("MainWindow", "Message sent. Sent on %1").arg(unicode( + strftime(shared.config.get('bitmessagesettings', 'timeformat'), localtime(int(time.time()))), 'utf-8'))))) + else: + # not sending to a chan + shared.UISignalQueue.put(('updateSentItemStatusByAckdata', (ackdata, tr.translateText("MainWindow", "Message sent. Waiting on acknowledgement. Sent on %1").arg(unicode( + strftime(shared.config.get('bitmessagesettings', 'timeformat'), localtime(int(time.time()))), 'utf-8'))))) print 'Broadcasting inv for my msg(within sendmsg function):', inventoryHash.encode('hex') shared.broadcastToSendDataQueues(( streamNumber, 'sendinv', inventoryHash)) # Update the status of the message in the 'sent' table to have a - # 'msgsent' status + # 'msgsent' status or 'msgsentnoackexpected' status. + if shared.safeConfigGetBoolean(toaddress, 'chan'): + newStatus = 'msgsentnoackexpected' + else: + newStatus = 'msgsent' shared.sqlLock.acquire() - t = (inventoryHash,ackdata,) - shared.sqlSubmitQueue.put('''UPDATE sent SET msgid=?, status='msgsent' WHERE ackdata=?''') + t = (inventoryHash,newStatus,ackdata,) + shared.sqlSubmitQueue.put('''UPDATE sent SET msgid=?, status=? WHERE ackdata=?''') shared.sqlSubmitQueue.put(t) queryreturn = shared.sqlReturnQueue.get() shared.sqlSubmitQueue.put('commit') diff --git a/src/message_data_reader.py b/src/message_data_reader.py index 90f4bedc..c600935d 100644 --- a/src/message_data_reader.py +++ b/src/message_data_reader.py @@ -107,8 +107,8 @@ def vacuum(): #takeInboxMessagesOutOfTrash() #takeSentMessagesOutOfTrash() #markAllInboxMessagesAsUnread() -#readInbox() -readSent() +readInbox() +#readSent() #readPubkeys() #readSubscriptions() #readInventory() diff --git a/src/shared.py b/src/shared.py index 557b332d..aead1f8a 100644 --- a/src/shared.py +++ b/src/shared.py @@ -195,8 +195,8 @@ def isAddressInMyAddressBookSubscriptionsListOrWhitelist(address): def safeConfigGetBoolean(section,field): try: return config.getboolean(section,field) - except: - return False + except Exception, err: + return False def decodeWalletImportFormat(WIFstring): fullString = arithmetic.changebase(WIFstring,58,256) From a3dd730c2adc0c715299443b8649cd13bebdb59d Mon Sep 17 00:00:00 2001 From: Jonathan Warren Date: Mon, 22 Jul 2013 01:20:36 -0400 Subject: [PATCH 06/20] add one line to last commit --- src/bitmessageqt/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/bitmessageqt/__init__.py b/src/bitmessageqt/__init__.py index dc12fcf8..cbfc069b 100644 --- a/src/bitmessageqt/__init__.py +++ b/src/bitmessageqt/__init__.py @@ -1089,6 +1089,7 @@ class MyForm(QtGui.QMainWindow): QMessageBox.about(self, _translate("MainWindow", "Address already present"), _translate( "MainWindow", "Could not add chan because it appears to already be one of your identities.")) return + createdAddress = addressGeneratorReturnValue[0] self.addEntryToAddressBook(createdAddress, self.str_chan + ' ' + self.str_chan + ' ' + str(self.newChanDialogInstance.ui.lineEditChanNameJoin.text())) QMessageBox.about(self, _translate("MainWindow", "Success"), _translate( "MainWindow", "Successfully joined chan. ")) From 9c7e6600fa1af29a2073a3f2a5203a892abf6518 Mon Sep 17 00:00:00 2001 From: Jonathan Warren Date: Mon, 22 Jul 2013 01:41:50 -0400 Subject: [PATCH 07/20] Modified one line to support international characters --- 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 cbfc069b..d624a11b 100644 --- a/src/bitmessageqt/__init__.py +++ b/src/bitmessageqt/__init__.py @@ -1078,7 +1078,7 @@ class MyForm(QtGui.QMainWindow): "MainWindow", "That Bitmessage address is not valid.")) return shared.apiAddressGeneratorReturnQueue.queue.clear() - shared.addressGeneratorQueue.put(('joinChan', addBMIfNotPresent(self.newChanDialogInstance.ui.lineEditChanBitmessageAddress.text()), self.str_chan + ' ' + str(self.newChanDialogInstance.ui.lineEditChanNameJoin.text()), self.newChanDialogInstance.ui.lineEditChanNameJoin.text().toUtf8())) + shared.addressGeneratorQueue.put(('joinChan', addBMIfNotPresent(self.newChanDialogInstance.ui.lineEditChanBitmessageAddress.text()), self.str_chan + ' ' + str(self.newChanDialogInstance.ui.lineEditChanNameJoin.text().toUtf8()), self.newChanDialogInstance.ui.lineEditChanNameJoin.text().toUtf8())) addressGeneratorReturnValue = shared.apiAddressGeneratorReturnQueue.get() print 'addressGeneratorReturnValue', addressGeneratorReturnValue if addressGeneratorReturnValue == 'chan name does not match address': From b488bb5cda1b86bd6dcd612798b391c88ec1abd9 Mon Sep 17 00:00:00 2001 From: DivineOmega Date: Mon, 22 Jul 2013 10:40:19 +0100 Subject: [PATCH 08/20] Fixes double [chan] appearing when adding chan to address book --- 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 d624a11b..5caa58f5 100644 --- a/src/bitmessageqt/__init__.py +++ b/src/bitmessageqt/__init__.py @@ -1090,7 +1090,7 @@ class MyForm(QtGui.QMainWindow): "MainWindow", "Could not add chan because it appears to already be one of your identities.")) return createdAddress = addressGeneratorReturnValue[0] - self.addEntryToAddressBook(createdAddress, self.str_chan + ' ' + self.str_chan + ' ' + str(self.newChanDialogInstance.ui.lineEditChanNameJoin.text())) + self.addEntryToAddressBook(createdAddress, self.str_chan + ' ' + str(self.newChanDialogInstance.ui.lineEditChanNameJoin.text())) QMessageBox.about(self, _translate("MainWindow", "Success"), _translate( "MainWindow", "Successfully joined chan. ")) self.ui.tabWidget.setCurrentIndex(3) From 3638ed88563ff8d6edbed20e4bd09ca8263af0ea Mon Sep 17 00:00:00 2001 From: neko259 Date: Mon, 22 Jul 2013 21:28:51 +0300 Subject: [PATCH 09/20] Use system text color for enabled addresses instead of black --- src/bitmessageqt/__init__.py | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/bitmessageqt/__init__.py b/src/bitmessageqt/__init__.py index 5caa58f5..624b3842 100644 --- a/src/bitmessageqt/__init__.py +++ b/src/bitmessageqt/__init__.py @@ -1338,7 +1338,7 @@ class MyForm(QtGui.QMainWindow): self.ui.tableWidgetInbox.item(i, 0).setTextColor(QtGui.QColor(137, 04, 177)) else: self.ui.tableWidgetInbox.item( - i, 0).setTextColor(QtGui.QColor(0, 0, 0)) + i, 0).setTextColor(QApplication.palette().text().color()) def rerenderSentFromLabels(self): for i in range(self.ui.tableWidgetSent.rowCount()): @@ -2074,7 +2074,8 @@ class MyForm(QtGui.QMainWindow): # Set the color to either black or grey if shared.config.getboolean(addressAtCurrentRow, 'enabled'): self.ui.tableWidgetYourIdentities.item( - currentRow, 1).setTextColor(QtGui.QColor(0, 0, 0)) + currentRow, 1).setTextColor(QApplication.palette() + .text().color()) else: self.ui.tableWidgetYourIdentities.item( currentRow, 1).setTextColor(QtGui.QColor(128, 128, 128)) @@ -2464,9 +2465,9 @@ class MyForm(QtGui.QMainWindow): shared.sqlSubmitQueue.put('commit') shared.sqlLock.release() self.ui.tableWidgetSubscriptions.item( - currentRow, 0).setTextColor(QtGui.QColor(0, 0, 0)) + currentRow, 0).setTextColor(QApplication.palette().text().color()) self.ui.tableWidgetSubscriptions.item( - currentRow, 1).setTextColor(QtGui.QColor(0, 0, 0)) + currentRow, 1).setTextColor(QApplication.palette().text().color()) shared.reloadBroadcastSendersForWhichImWatching() def on_action_SubscriptionsDisable(self): @@ -2535,9 +2536,9 @@ class MyForm(QtGui.QMainWindow): addressAtCurrentRow = self.ui.tableWidgetBlacklist.item( currentRow, 1).text() self.ui.tableWidgetBlacklist.item( - currentRow, 0).setTextColor(QtGui.QColor(0, 0, 0)) + currentRow, 0).setTextColor(QApplication.palette().text().color()) self.ui.tableWidgetBlacklist.item( - currentRow, 1).setTextColor(QtGui.QColor(0, 0, 0)) + currentRow, 1).setTextColor(QApplication.palette().text().color()) t = (str(addressAtCurrentRow),) shared.sqlLock.acquire() if shared.config.get('bitmessagesettings', 'blackwhitelist') == 'black': @@ -2588,11 +2589,11 @@ class MyForm(QtGui.QMainWindow): with open(shared.appdata + 'keys.dat', 'wb') as configfile: shared.config.write(configfile) self.ui.tableWidgetYourIdentities.item( - currentRow, 0).setTextColor(QtGui.QColor(0, 0, 0)) + currentRow, 0).setTextColor(QApplication.palette().text().color()) self.ui.tableWidgetYourIdentities.item( - currentRow, 1).setTextColor(QtGui.QColor(0, 0, 0)) + currentRow, 1).setTextColor(QApplication.palette().text().color()) self.ui.tableWidgetYourIdentities.item( - currentRow, 2).setTextColor(QtGui.QColor(0, 0, 0)) + currentRow, 2).setTextColor(QApplication.palette().text().color()) if shared.safeConfigGetBoolean(addressAtCurrentRow, 'mailinglist'): self.ui.tableWidgetYourIdentities.item(currentRow, 1).setTextColor(QtGui.QColor(137, 04, 177)) if shared.safeConfigGetBoolean(addressAtCurrentRow, 'chan'): From 8649b72ae99b6e19ea74d5174b707f648f018e23 Mon Sep 17 00:00:00 2001 From: Postmodern Date: Mon, 22 Jul 2013 23:22:22 -0700 Subject: [PATCH 10/20] Add a missing `rm -f` to the uninstall task. --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index b9a85ff7..cd4a0ee4 100644 --- a/Makefile +++ b/Makefile @@ -36,7 +36,7 @@ uninstall: rm -f /usr/bin/${APP} rm -f /usr/share/applications/${APP}.desktop rm -f /usr/share/icons/hicolor/scalable/apps/${APP}.svg - /usr/share/pixmaps/${APP}.svg + rm -f /usr/share/pixmaps/${APP}.svg clean: rm -f ${APP} \#* \.#* gnuplot* *.png debian/*.substvars debian/*.log rm -fr deb.* debian/${APP} rpmpackage/${ARCH_TYPE} From 84f952d76c999ba2b25a23644e2ef29dcfcb68fc Mon Sep 17 00:00:00 2001 From: Postmodern Date: Mon, 22 Jul 2013 23:31:30 -0700 Subject: [PATCH 11/20] Install into /usr/local by default. --- Makefile | 57 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 29 insertions(+), 28 deletions(-) diff --git a/Makefile b/Makefile index cd4a0ee4..a83a6db1 100644 --- a/Makefile +++ b/Makefile @@ -2,41 +2,42 @@ APP=pybitmessage VERSION=0.3.4 RELEASE=1 ARCH_TYPE=`uname -m` +PREFIX?=/usr/local all: debug: source: tar -cvzf ../${APP}_${VERSION}.orig.tar.gz ../${APP}-${VERSION} --exclude-vcs install: - mkdir -p ${DESTDIR}/usr - mkdir -p ${DESTDIR}/usr/bin - mkdir -m 755 -p ${DESTDIR}/usr/share - mkdir -m 755 -p ${DESTDIR}/usr/share/man - mkdir -m 755 -p ${DESTDIR}/usr/share/man/man1 - install -m 644 man/${APP}.1.gz ${DESTDIR}/usr/share/man/man1 - mkdir -m 755 -p ${DESTDIR}/usr/share/${APP} - mkdir -m 755 -p ${DESTDIR}/usr/share/applications - mkdir -m 755 -p ${DESTDIR}/usr/share/pixmaps - mkdir -m 755 -p ${DESTDIR}/usr/share/icons - mkdir -m 755 -p ${DESTDIR}/usr/share/icons/hicolor - mkdir -m 755 -p ${DESTDIR}/usr/share/icons/hicolor/scalable - mkdir -m 755 -p ${DESTDIR}/usr/share/icons/hicolor/scalable/apps - mkdir -m 755 -p ${DESTDIR}/usr/share/icons/hicolor/24x24 - mkdir -m 755 -p ${DESTDIR}/usr/share/icons/hicolor/24x24/apps - install -m 644 desktop/${APP}.desktop ${DESTDIR}/usr/share/applications/${APP}.desktop - install -m 644 desktop/icon24.png ${DESTDIR}/usr/share/icons/hicolor/24x24/apps/${APP}.png - cp -rf src/* ${DESTDIR}/usr/share/${APP} - echo '#!/bin/sh' > ${DESTDIR}/usr/bin/${APP} - echo 'cd /usr/share/pybitmessage' >> ${DESTDIR}/usr/bin/${APP} - echo 'LD_LIBRARY_PATH="/opt/openssl-compat-bitcoin/lib/" exec python2 bitmessagemain.py' >> ${DESTDIR}/usr/bin/${APP} - chmod +x ${DESTDIR}/usr/bin/${APP} + mkdir -p ${DESTDIR}${PREFIX} + mkdir -p ${DESTDIR}${PREFIX}/bin + mkdir -m 755 -p ${DESTDIR}${PREFIX}/share + mkdir -m 755 -p ${DESTDIR}${PREFIX}/share/man + mkdir -m 755 -p ${DESTDIR}${PREFIX}/share/man/man1 + install -m 644 man/${APP}.1.gz ${DESTDIR}${PREFIX}/share/man/man1 + mkdir -m 755 -p ${DESTDIR}${PREFIX}/share/${APP} + mkdir -m 755 -p ${DESTDIR}${PREFIX}/share/applications + mkdir -m 755 -p ${DESTDIR}${PREFIX}/share/pixmaps + mkdir -m 755 -p ${DESTDIR}${PREFIX}/share/icons + mkdir -m 755 -p ${DESTDIR}${PREFIX}/share/icons/hicolor + mkdir -m 755 -p ${DESTDIR}${PREFIX}/share/icons/hicolor/scalable + mkdir -m 755 -p ${DESTDIR}${PREFIX}/share/icons/hicolor/scalable/apps + mkdir -m 755 -p ${DESTDIR}${PREFIX}/share/icons/hicolor/24x24 + mkdir -m 755 -p ${DESTDIR}${PREFIX}/share/icons/hicolor/24x24/apps + install -m 644 desktop/${APP}.desktop ${DESTDIR}${PREFIX}/share/applications/${APP}.desktop + install -m 644 desktop/icon24.png ${DESTDIR}${PREFIX}/share/icons/hicolor/24x24/apps/${APP}.png + cp -rf src/* ${DESTDIR}${PREFIX}/share/${APP} + echo '#!/bin/sh' > ${DESTDIR}${PREFIX}/bin/${APP} + echo 'cd ${PREFIX}/share/pybitmessage' >> ${DESTDIR}${PREFIX}/bin/${APP} + echo 'LD_LIBRARY_PATH="/opt/openssl-compat-bitcoin/lib/" exec python2 bitmessagemain.py' >> ${DESTDIR}${PREFIX}/bin/${APP} + chmod +x ${DESTDIR}${PREFIX}/bin/${APP} uninstall: - rm -f /usr/share/man/man1/${APP}.1.gz - rm -rf /usr/share/${APP} - rm -f /usr/bin/${APP} - rm -f /usr/share/applications/${APP}.desktop - rm -f /usr/share/icons/hicolor/scalable/apps/${APP}.svg - rm -f /usr/share/pixmaps/${APP}.svg + rm -f ${PREFIX}/share/man/man1/${APP}.1.gz + rm -rf ${PREFIX}/share/${APP} + rm -f ${PREFIX}/bin/${APP} + rm -f ${PREFIX}/share/applications/${APP}.desktop + rm -f ${PREFIX}/share/icons/hicolor/scalable/apps/${APP}.svg + rm -f ${PREFIX}/share/pixmaps/${APP}.svg clean: rm -f ${APP} \#* \.#* gnuplot* *.png debian/*.substvars debian/*.log rm -fr deb.* debian/${APP} rpmpackage/${ARCH_TYPE} From 2af86c8296e0c577f8ac48a56e9a3582ddd87473 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Tue, 23 Jul 2013 16:04:44 +0100 Subject: [PATCH 12/20] Improving the Ebuild --- Makefile | 56 ++++++++++++----------- archpackage/PKGBUILD | 2 +- debian/control | 2 +- debian/rules | 3 +- ebuildpackage/pybitmessage-0.3.4-1.ebuild | 20 ++++++-- generate.sh | 2 +- puppy.sh | 2 +- puppypackage/pybitmessage-0.3.4.pet.specs | 2 +- rpmpackage/pybitmessage.spec | 2 +- slack.sh | 2 +- 10 files changed, 53 insertions(+), 40 deletions(-) diff --git a/Makefile b/Makefile index b9a85ff7..adda5583 100644 --- a/Makefile +++ b/Makefile @@ -2,6 +2,7 @@ APP=pybitmessage VERSION=0.3.4 RELEASE=1 ARCH_TYPE=`uname -m` +PREFIX?=/usr/local all: debug: @@ -9,34 +10,35 @@ source: tar -cvzf ../${APP}_${VERSION}.orig.tar.gz ../${APP}-${VERSION} --exclude-vcs install: mkdir -p ${DESTDIR}/usr - mkdir -p ${DESTDIR}/usr/bin - mkdir -m 755 -p ${DESTDIR}/usr/share - mkdir -m 755 -p ${DESTDIR}/usr/share/man - mkdir -m 755 -p ${DESTDIR}/usr/share/man/man1 - install -m 644 man/${APP}.1.gz ${DESTDIR}/usr/share/man/man1 - mkdir -m 755 -p ${DESTDIR}/usr/share/${APP} - mkdir -m 755 -p ${DESTDIR}/usr/share/applications - mkdir -m 755 -p ${DESTDIR}/usr/share/pixmaps - mkdir -m 755 -p ${DESTDIR}/usr/share/icons - mkdir -m 755 -p ${DESTDIR}/usr/share/icons/hicolor - mkdir -m 755 -p ${DESTDIR}/usr/share/icons/hicolor/scalable - mkdir -m 755 -p ${DESTDIR}/usr/share/icons/hicolor/scalable/apps - mkdir -m 755 -p ${DESTDIR}/usr/share/icons/hicolor/24x24 - mkdir -m 755 -p ${DESTDIR}/usr/share/icons/hicolor/24x24/apps - install -m 644 desktop/${APP}.desktop ${DESTDIR}/usr/share/applications/${APP}.desktop - install -m 644 desktop/icon24.png ${DESTDIR}/usr/share/icons/hicolor/24x24/apps/${APP}.png - cp -rf src/* ${DESTDIR}/usr/share/${APP} - echo '#!/bin/sh' > ${DESTDIR}/usr/bin/${APP} - echo 'cd /usr/share/pybitmessage' >> ${DESTDIR}/usr/bin/${APP} - echo 'LD_LIBRARY_PATH="/opt/openssl-compat-bitcoin/lib/" exec python2 bitmessagemain.py' >> ${DESTDIR}/usr/bin/${APP} - chmod +x ${DESTDIR}/usr/bin/${APP} + mkdir -p ${DESTDIR}${PREFIX} + mkdir -p ${DESTDIR}${PREFIX}/bin + mkdir -m 755 -p ${DESTDIR}${PREFIX}/share + mkdir -m 755 -p ${DESTDIR}${PREFIX}/share/man + mkdir -m 755 -p ${DESTDIR}${PREFIX}/share/man/man1 + install -m 644 man/${APP}.1.gz ${DESTDIR}${PREFIX}/share/man/man1 + mkdir -m 755 -p ${DESTDIR}${PREFIX}/share/${APP} + mkdir -m 755 -p ${DESTDIR}${PREFIX}/share/applications + mkdir -m 755 -p ${DESTDIR}${PREFIX}/share/pixmaps + mkdir -m 755 -p ${DESTDIR}${PREFIX}/share/icons + mkdir -m 755 -p ${DESTDIR}${PREFIX}/share/icons/hicolor + mkdir -m 755 -p ${DESTDIR}${PREFIX}/share/icons/hicolor/scalable + mkdir -m 755 -p ${DESTDIR}${PREFIX}/share/icons/hicolor/scalable/apps + mkdir -m 755 -p ${DESTDIR}${PREFIX}/share/icons/hicolor/24x24 + mkdir -m 755 -p ${DESTDIR}${PREFIX}/share/icons/hicolor/24x24/apps + install -m 644 desktop/${APP}.desktop ${DESTDIR}${PREFIX}/share/applications/${APP}.desktop + install -m 644 desktop/icon24.png ${DESTDIR}${PREFIX}/share/icons/hicolor/24x24/apps/${APP}.png + cp -rf src/* ${DESTDIR}${PREFIX}/share/${APP} + echo '#!/bin/sh' > ${DESTDIR}${PREFIX}/bin/${APP} + echo 'cd ${PREFIX}/share/pybitmessage' >> ${DESTDIR}${PREFIX}/bin/${APP} + echo 'LD_LIBRARY_PATH="/opt/openssl-compat-bitcoin/lib/" exec python2 bitmessagemain.py' >> ${DESTDIR}${PREFIX}/bin/${APP} + chmod +x ${DESTDIR}${PREFIX}/bin/${APP} uninstall: - rm -f /usr/share/man/man1/${APP}.1.gz - rm -rf /usr/share/${APP} - rm -f /usr/bin/${APP} - rm -f /usr/share/applications/${APP}.desktop - rm -f /usr/share/icons/hicolor/scalable/apps/${APP}.svg - /usr/share/pixmaps/${APP}.svg + rm -f ${PREFIX}/share/man/man1/${APP}.1.gz + rm -rf ${PREFIX}/share/${APP} + rm -f ${PREFIX}/bin/${APP} + rm -f ${PREFIX}/share/applications/${APP}.desktop + rm -f ${PREFIX}/share/icons/hicolor/scalable/apps/${APP}.svg + ${PREFIX}/share/pixmaps/${APP}.svg clean: rm -f ${APP} \#* \.#* gnuplot* *.png debian/*.substvars debian/*.log rm -fr deb.* debian/${APP} rpmpackage/${ARCH_TYPE} diff --git a/archpackage/PKGBUILD b/archpackage/PKGBUILD index e9ab0f74..e36c1a11 100644 --- a/archpackage/PKGBUILD +++ b/archpackage/PKGBUILD @@ -27,5 +27,5 @@ build() { } package() { cd "$srcdir/$pkgname-$pkgver" - make DESTDIR="$pkgdir/" install + make DESTDIR="$pkgdir/" PREFIX="/usr" install } diff --git a/debian/control b/debian/control index d9ed8704..b2ec3268 100644 --- a/debian/control +++ b/debian/control @@ -4,7 +4,7 @@ Maintainer: Bob Mottram (4096 bits) Build-Depends: debhelper (>= 9.0.0) Standards-Version: 3.9.4 Homepage: https://github.com/Bitmessage/PyBitmessage -Vcs-Git: https://github.com/fuzzgun/fin.git +Vcs-Git: https://github.com/fuzzgun/packagemonkey.git Package: pybitmessage Section: mail diff --git a/debian/rules b/debian/rules index 233679ca..5b29d243 100755 --- a/debian/rules +++ b/debian/rules @@ -1,6 +1,7 @@ #!/usr/bin/make -f APP=pybitmessage +PREFIX=/usr build: build-stamp make build-arch: build-stamp @@ -20,7 +21,7 @@ install: build clean dh_testroot dh_prep dh_installdirs - ${MAKE} install -B DESTDIR=${CURDIR}/debian/${APP} + ${MAKE} install -B DESTDIR=${CURDIR}/debian/${APP} PREFIX=/usr binary-indep: build install dh_testdir dh_testroot diff --git a/ebuildpackage/pybitmessage-0.3.4-1.ebuild b/ebuildpackage/pybitmessage-0.3.4-1.ebuild index 20f056e4..fba11f74 100755 --- a/ebuildpackage/pybitmessage-0.3.4-1.ebuild +++ b/ebuildpackage/pybitmessage-0.3.4-1.ebuild @@ -1,22 +1,32 @@ # $Header: $ -EAPI=4 +EAPI=5 +inherit git-2 python-r1 + +PYTHON_COMPAT=( python2_7 ) +PYTHON_REQ_USE="sqlite" +REQUIRED_USE="${PYTHON_REQUIRED_USE}" DESCRIPTION="Bitmessage is a P2P communications protocol used to send encrypted messages to another person or to many subscribers. It is decentralized and trustless, meaning that you need-not inherently trust any entities like root certificate authorities. It uses strong authentication which means that the sender of a message cannot be spoofed, and it aims to hide "non-content" data, like the sender and receiver of messages, from passive eavesdroppers like those running warrantless wiretapping programs." HOMEPAGE="https://github.com/Bitmessage/PyBitmessage" -SRC_URI="${PN}/${P}.tar.gz" +EGIT_REPO_URI="https://github.com/fuzzgun/packagemonkey.git" LICENSE="MIT" SLOT="0" KEYWORDS="x86" -RDEPEND="dev-libs/popt" -DEPEND="${RDEPEND}" +DEPEND="dev-libs/popt + ${PYTHON_DEPS}" +RDEPEND="${DEPEND} + dev-libs/openssl + dev-python/PyQt4[]" src_configure() { econf --with-popt } +src_compile() { :; } + src_install() { - emake DESTDIR="${D}" install + emake DESTDIR="${D}" PREFIX="/usr" install # Install README and (Debian) changelog dodoc README.md debian/changelog } diff --git a/generate.sh b/generate.sh index 8489f024..7aa46e75 100755 --- a/generate.sh +++ b/generate.sh @@ -4,4 +4,4 @@ rm -f Makefile rpmpackage/*.spec -packagemonkey -n "PyBitmessage" --version "0.3.4" --dir "." -l "mit" -e "Bob Mottram (4096 bits) " --brief "Send encrypted messages" --desc "Bitmessage is a P2P communications protocol used to send encrypted messages to another person or to many subscribers. It is decentralized and trustless, meaning that you need-not inherently trust any entities like root certificate authorities. It uses strong authentication which means that the sender of a message cannot be spoofed, and it aims to hide \"non-content\" data, like the sender and receiver of messages, from passive eavesdroppers like those running warrantless wiretapping programs." --homepage "https://github.com/Bitmessage/PyBitmessage" --section "mail" --categories "Office/Email" --dependsdeb "python (>= 2.7.0), openssl, python-qt4, libqt4-dev (>= 4.8.0), python-qt4-dev, sqlite3, libsqlite3-dev, gst123" --dependsrpm "python, PyQt4, openssl-compat-bitcoin-libs, gst123" --mainscript "bitmessagemain.py" --librarypath "/opt/openssl-compat-bitcoin/lib/" --suggestsdeb "libmessaging-menu-dev" --dependspuppy "openssl, python-qt4, sqlite3, sqlite3-dev, python-openssl, python-sip, gst123" --dependsarch "python2, qt4, python2-pyqt4, sqlite, openssl, gst123" --suggestsarch "python2-gevent" --pythonversion 2 +packagemonkey -n "PyBitmessage" --version "0.3.4" --dir "." -l "mit" -e "Bob Mottram (4096 bits) " --brief "Send encrypted messages" --desc "Bitmessage is a P2P communications protocol used to send encrypted messages to another person or to many subscribers. It is decentralized and trustless, meaning that you need-not inherently trust any entities like root certificate authorities. It uses strong authentication which means that the sender of a message cannot be spoofed, and it aims to hide \"non-content\" data, like the sender and receiver of messages, from passive eavesdroppers like those running warrantless wiretapping programs." --homepage "https://github.com/Bitmessage/PyBitmessage" --section "mail" --categories "Office/Email" --dependsdeb "python (>= 2.7.0), openssl, python-qt4, libqt4-dev (>= 4.8.0), python-qt4-dev, sqlite3, libsqlite3-dev, gst123" --dependsrpm "python, PyQt4, openssl-compat-bitcoin-libs, gst123" --mainscript "bitmessagemain.py" --librarypath "/opt/openssl-compat-bitcoin/lib/" --suggestsdeb "libmessaging-menu-dev" --dependspuppy "openssl, python-qt4, sqlite3, sqlite3-dev, python-openssl, python-sip, gst123" --dependsarch "python2, qt4, python2-pyqt4, sqlite, openssl, gst123" --suggestsarch "python2-gevent" --pythonversion 2 --dependsebuild "dev-libs/openssl, dev-python/PyQt4[${PYTHON_USEDEP}]" --buildebuild "\${PYTHON_DEPS}" --pythonreq "sqlite" diff --git a/puppy.sh b/puppy.sh index dd54ecc9..efe1d7da 100755 --- a/puppy.sh +++ b/puppy.sh @@ -27,7 +27,7 @@ mkdir -p ${PROJECTDIR} # Build the project make clean make -make install -B DESTDIR=${PROJECTDIR} +make install -B DESTDIR=${PROJECTDIR} PREFIX=/usr # Alter the desktop file categories sed -i "s/Categories=Office;Email;/Categories=Internet;mailnews;/g" ${PROJECTDIR}/usr/share/applications/${APP}.desktop diff --git a/puppypackage/pybitmessage-0.3.4.pet.specs b/puppypackage/pybitmessage-0.3.4.pet.specs index 42d99ac3..4bcf119b 100644 --- a/puppypackage/pybitmessage-0.3.4.pet.specs +++ b/puppypackage/pybitmessage-0.3.4.pet.specs @@ -1 +1 @@ -pybitmessage-0.3.4-1|PyBitmessage|0.3.4|1|Internet;mailnews;|5.3M||pybitmessage-0.3.4-1.pet|+openssl,+python-qt4,+sqlite3,+sqlite3-dev,+python-openssl,+python-sip,+gst123|Send encrypted messages|ubuntu|precise|5| +pybitmessage-0.3.4-1|PyBitmessage|0.3.4|1|Internet;mailnews;|3.9M||pybitmessage-0.3.4-1.pet|+openssl,+python-qt4,+sqlite3,+sqlite3-dev,+python-openssl,+python-sip,+gst123|Send encrypted messages|ubuntu|precise|5| diff --git a/rpmpackage/pybitmessage.spec b/rpmpackage/pybitmessage.spec index c9254dec..9c12661a 100644 --- a/rpmpackage/pybitmessage.spec +++ b/rpmpackage/pybitmessage.spec @@ -48,7 +48,7 @@ mkdir -p %{buildroot}/usr/share/pixmaps mkdir -p %{buildroot}/usr/share/icons/hicolor/scalable mkdir -p %{buildroot}/usr/share/icons/hicolor/scalable/apps # Make install but to the RPM BUILDROOT directory -make install -B DESTDIR=%{buildroot} +make install -B DESTDIR=%{buildroot} PREFIX=/usr %files %doc README.md LICENSE diff --git a/slack.sh b/slack.sh index cc71e1f3..5d826e0b 100755 --- a/slack.sh +++ b/slack.sh @@ -28,7 +28,7 @@ mkdir -p ${PROJECTDIR} # Build the project make clean make -make install -B DESTDIR=${PROJECTDIR} +make install -B DESTDIR=${PROJECTDIR} PREFIX=/usr # Copy the slack-desc and doinst.sh files into the build install directory mkdir ${PROJECTDIR}/install From ba2958d076a2214feee3a7ad2136826a46c272c0 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Tue, 23 Jul 2013 21:20:58 +0100 Subject: [PATCH 13/20] Fixing /usr versus /usr/local dilemmas --- Makefile | 10 +++++++--- puppypackage/pybitmessage-0.3.4.pet.specs | 2 +- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index adda5583..72a86ba2 100644 --- a/Makefile +++ b/Makefile @@ -29,7 +29,11 @@ install: install -m 644 desktop/icon24.png ${DESTDIR}${PREFIX}/share/icons/hicolor/24x24/apps/${APP}.png cp -rf src/* ${DESTDIR}${PREFIX}/share/${APP} echo '#!/bin/sh' > ${DESTDIR}${PREFIX}/bin/${APP} - echo 'cd ${PREFIX}/share/pybitmessage' >> ${DESTDIR}${PREFIX}/bin/${APP} + echo 'if [ -d /usr/local/share/${APP} ]; then' >> ${DESTDIR}${PREFIX}/bin/${APP} + echo ' cd /usr/local/share/${APP}' >> ${DESTDIR}${PREFIX}/bin/${APP} + echo 'else' >> ${DESTDIR}${PREFIX}/bin/${APP} + echo ' cd /usr/share/pybitmessage' >> ${DESTDIR}${PREFIX}/bin/${APP} + echo 'fi' >> ${DESTDIR}${PREFIX}/bin/${APP} echo 'LD_LIBRARY_PATH="/opt/openssl-compat-bitcoin/lib/" exec python2 bitmessagemain.py' >> ${DESTDIR}${PREFIX}/bin/${APP} chmod +x ${DESTDIR}${PREFIX}/bin/${APP} uninstall: @@ -38,10 +42,10 @@ uninstall: rm -f ${PREFIX}/bin/${APP} rm -f ${PREFIX}/share/applications/${APP}.desktop rm -f ${PREFIX}/share/icons/hicolor/scalable/apps/${APP}.svg - ${PREFIX}/share/pixmaps/${APP}.svg + rm -f ${PREFIX}/share/pixmaps/${APP}.svg clean: rm -f ${APP} \#* \.#* gnuplot* *.png debian/*.substvars debian/*.log rm -fr deb.* debian/${APP} rpmpackage/${ARCH_TYPE} rm -f ../${APP}*.deb ../${APP}*.changes ../${APP}*.asc ../${APP}*.dsc rm -f rpmpackage/*.src.rpm archpackage/*.gz archpackage/*.xz - rm -f puppypackage/*.gz puppypackage/*.pet slackpackage/*.txz + rm -f puppypackage/*.gz puppypackage/*.pet slackpackage/*.txz diff --git a/puppypackage/pybitmessage-0.3.4.pet.specs b/puppypackage/pybitmessage-0.3.4.pet.specs index 4bcf119b..01e8ed0d 100644 --- a/puppypackage/pybitmessage-0.3.4.pet.specs +++ b/puppypackage/pybitmessage-0.3.4.pet.specs @@ -1 +1 @@ -pybitmessage-0.3.4-1|PyBitmessage|0.3.4|1|Internet;mailnews;|3.9M||pybitmessage-0.3.4-1.pet|+openssl,+python-qt4,+sqlite3,+sqlite3-dev,+python-openssl,+python-sip,+gst123|Send encrypted messages|ubuntu|precise|5| +pybitmessage-0.3.4-1|PyBitmessage|0.3.4|1|Internet;mailnews;|5.5M||pybitmessage-0.3.4-1.pet|+openssl,+python-qt4,+sqlite3,+sqlite3-dev,+python-openssl,+python-sip,+gst123|Send encrypted messages|ubuntu|precise|5| From 1e78685a987e4ec765deb3738f8c241f42356aa7 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Tue, 23 Jul 2013 21:31:55 +0100 Subject: [PATCH 14/20] Fixed missing repository --- debian/control | 2 +- ebuildpackage/pybitmessage-0.3.4-1.ebuild | 2 +- generate.sh | 2 +- puppypackage/pybitmessage-0.3.4.pet.specs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/debian/control b/debian/control index b2ec3268..5e016a1c 100644 --- a/debian/control +++ b/debian/control @@ -4,7 +4,7 @@ Maintainer: Bob Mottram (4096 bits) Build-Depends: debhelper (>= 9.0.0) Standards-Version: 3.9.4 Homepage: https://github.com/Bitmessage/PyBitmessage -Vcs-Git: https://github.com/fuzzgun/packagemonkey.git +Vcs-Git: https://github.com/Bitmessage/PyBitmessage.git Package: pybitmessage Section: mail diff --git a/ebuildpackage/pybitmessage-0.3.4-1.ebuild b/ebuildpackage/pybitmessage-0.3.4-1.ebuild index fba11f74..01eddc4f 100755 --- a/ebuildpackage/pybitmessage-0.3.4-1.ebuild +++ b/ebuildpackage/pybitmessage-0.3.4-1.ebuild @@ -9,7 +9,7 @@ PYTHON_REQ_USE="sqlite" REQUIRED_USE="${PYTHON_REQUIRED_USE}" DESCRIPTION="Bitmessage is a P2P communications protocol used to send encrypted messages to another person or to many subscribers. It is decentralized and trustless, meaning that you need-not inherently trust any entities like root certificate authorities. It uses strong authentication which means that the sender of a message cannot be spoofed, and it aims to hide "non-content" data, like the sender and receiver of messages, from passive eavesdroppers like those running warrantless wiretapping programs." HOMEPAGE="https://github.com/Bitmessage/PyBitmessage" -EGIT_REPO_URI="https://github.com/fuzzgun/packagemonkey.git" +EGIT_REPO_URI="https://github.com/Bitmessage/PyBitmessage.git" LICENSE="MIT" SLOT="0" KEYWORDS="x86" diff --git a/generate.sh b/generate.sh index 7aa46e75..173e3c79 100755 --- a/generate.sh +++ b/generate.sh @@ -4,4 +4,4 @@ rm -f Makefile rpmpackage/*.spec -packagemonkey -n "PyBitmessage" --version "0.3.4" --dir "." -l "mit" -e "Bob Mottram (4096 bits) " --brief "Send encrypted messages" --desc "Bitmessage is a P2P communications protocol used to send encrypted messages to another person or to many subscribers. It is decentralized and trustless, meaning that you need-not inherently trust any entities like root certificate authorities. It uses strong authentication which means that the sender of a message cannot be spoofed, and it aims to hide \"non-content\" data, like the sender and receiver of messages, from passive eavesdroppers like those running warrantless wiretapping programs." --homepage "https://github.com/Bitmessage/PyBitmessage" --section "mail" --categories "Office/Email" --dependsdeb "python (>= 2.7.0), openssl, python-qt4, libqt4-dev (>= 4.8.0), python-qt4-dev, sqlite3, libsqlite3-dev, gst123" --dependsrpm "python, PyQt4, openssl-compat-bitcoin-libs, gst123" --mainscript "bitmessagemain.py" --librarypath "/opt/openssl-compat-bitcoin/lib/" --suggestsdeb "libmessaging-menu-dev" --dependspuppy "openssl, python-qt4, sqlite3, sqlite3-dev, python-openssl, python-sip, gst123" --dependsarch "python2, qt4, python2-pyqt4, sqlite, openssl, gst123" --suggestsarch "python2-gevent" --pythonversion 2 --dependsebuild "dev-libs/openssl, dev-python/PyQt4[${PYTHON_USEDEP}]" --buildebuild "\${PYTHON_DEPS}" --pythonreq "sqlite" +packagemonkey -n "PyBitmessage" --version "0.3.4" --dir "." -l "mit" -e "Bob Mottram (4096 bits) " --brief "Send encrypted messages" --desc "Bitmessage is a P2P communications protocol used to send encrypted messages to another person or to many subscribers. It is decentralized and trustless, meaning that you need-not inherently trust any entities like root certificate authorities. It uses strong authentication which means that the sender of a message cannot be spoofed, and it aims to hide \"non-content\" data, like the sender and receiver of messages, from passive eavesdroppers like those running warrantless wiretapping programs." --homepage "https://github.com/Bitmessage/PyBitmessage" --section "mail" --categories "Office/Email" --dependsdeb "python (>= 2.7.0), openssl, python-qt4, libqt4-dev (>= 4.8.0), python-qt4-dev, sqlite3, libsqlite3-dev, gst123" --dependsrpm "python, PyQt4, openssl-compat-bitcoin-libs, gst123" --mainscript "bitmessagemain.py" --librarypath "/opt/openssl-compat-bitcoin/lib/" --suggestsdeb "libmessaging-menu-dev" --dependspuppy "openssl, python-qt4, sqlite3, sqlite3-dev, python-openssl, python-sip, gst123" --dependsarch "python2, qt4, python2-pyqt4, sqlite, openssl, gst123" --suggestsarch "python2-gevent" --pythonversion 2 --dependsebuild "dev-libs/openssl, dev-python/PyQt4[${PYTHON_USEDEP}]" --buildebuild "\${PYTHON_DEPS}" --pythonreq "sqlite" --repository "https://github.com/Bitmessage/PyBitmessage.git" diff --git a/puppypackage/pybitmessage-0.3.4.pet.specs b/puppypackage/pybitmessage-0.3.4.pet.specs index 01e8ed0d..aac180a9 100644 --- a/puppypackage/pybitmessage-0.3.4.pet.specs +++ b/puppypackage/pybitmessage-0.3.4.pet.specs @@ -1 +1 @@ -pybitmessage-0.3.4-1|PyBitmessage|0.3.4|1|Internet;mailnews;|5.5M||pybitmessage-0.3.4-1.pet|+openssl,+python-qt4,+sqlite3,+sqlite3-dev,+python-openssl,+python-sip,+gst123|Send encrypted messages|ubuntu|precise|5| +pybitmessage-0.3.4-1|PyBitmessage|0.3.4|1|Internet;mailnews;|5.8M||pybitmessage-0.3.4-1.pet|+openssl,+python-qt4,+sqlite3,+sqlite3-dev,+python-openssl,+python-sip,+gst123|Send encrypted messages|ubuntu|precise|5| From a76939114ecf167ccefd6c5f5da3e4000c0e5d9e Mon Sep 17 00:00:00 2001 From: Jonathan Warren Date: Tue, 23 Jul 2013 17:05:42 -0400 Subject: [PATCH 15/20] manual merge2 --- src/bitmessageqt/__init__.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/bitmessageqt/__init__.py b/src/bitmessageqt/__init__.py index 405ea1f8..3ee43370 100644 --- a/src/bitmessageqt/__init__.py +++ b/src/bitmessageqt/__init__.py @@ -30,12 +30,10 @@ import os from pyelliptic.openssl import OpenSSL import pickle import platform -<<<<<<< HEAD import debug from debug import logger -======= import subprocess ->>>>>>> 2af86c8296e0c577f8ac48a56e9a3582ddd87473 + try: from PyQt4 import QtCore, QtGui From f5e17eeeaa425f0a4a0c79e0305087b2b16ed44f Mon Sep 17 00:00:00 2001 From: Jonathan Warren Date: Wed, 24 Jul 2013 00:29:30 -0400 Subject: [PATCH 16/20] Moved code to add the sockslisten config option to a spot where it will actually work properly --- src/bitmessageqt/__init__.py | 2 +- src/class_sqlThread.py | 3 +++ src/helper_startup.py | 6 ------ 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/bitmessageqt/__init__.py b/src/bitmessageqt/__init__.py index d624a11b..b105881a 100644 --- a/src/bitmessageqt/__init__.py +++ b/src/bitmessageqt/__init__.py @@ -1885,7 +1885,7 @@ class MyForm(QtGui.QMainWindow): if shared.config.get('bitmessagesettings', 'socksproxytype') == 'none' and str(self.settingsDialogInstance.ui.comboBoxProxyType.currentText())[0:5] == 'SOCKS': if shared.statusIconColor != 'red': QMessageBox.about(self, _translate("MainWindow", "Restart"), _translate( - "MainWindow", "Bitmessage will use your proxy from now on but you may want to manually restart Bitmessage now to close existing connections.")) + "MainWindow", "Bitmessage will use your proxy from now on but you may want to manually restart Bitmessage now to close existing connections (if any).")) if shared.config.get('bitmessagesettings', 'socksproxytype')[0:5] == 'SOCKS' and str(self.settingsDialogInstance.ui.comboBoxProxyType.currentText()) == 'none': self.statusBar().showMessage('') shared.config.set('bitmessagesettings', 'socksproxytype', str( diff --git a/src/class_sqlThread.py b/src/class_sqlThread.py index f1a428d2..e07850e4 100644 --- a/src/class_sqlThread.py +++ b/src/class_sqlThread.py @@ -186,6 +186,9 @@ class sqlThread(threading.Thread): self.cur.execute( '''update sent set status='broadcastqueued' where status='broadcastpending' ''') self.conn.commit() + + if not shared.config.has_option('bitmessagesettings', 'sockslisten'): + shared.config.set('bitmessagesettings', 'sockslisten', 'false') try: testpayload = '\x00\x00' diff --git a/src/helper_startup.py b/src/helper_startup.py index 46150d4d..f3069658 100644 --- a/src/helper_startup.py +++ b/src/helper_startup.py @@ -80,9 +80,3 @@ def loadConfig(): os.umask(0o077) with open(shared.appdata + 'keys.dat', 'wb') as configfile: shared.config.write(configfile) - - # Initialize settings that may be missing due to upgrades and could - # cause errors if missing. - if not shared.config.has_option('bitmessagesettings', 'sockslisten'): - shared.config.set('bitmessagesettings', 'sockslisten', 'false') - From 79ecaf42854ecf2712a17abb555882b0e10d6396 Mon Sep 17 00:00:00 2001 From: gnumac Date: Wed, 24 Jul 2013 05:23:24 +0000 Subject: [PATCH 17/20] Added 'sqlite3' as to the includes when building for OS X --- src/build_osx.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/build_osx.py b/src/build_osx.py index aac551b9..ff33f6c1 100644 --- a/src/build_osx.py +++ b/src/build_osx.py @@ -21,7 +21,7 @@ if sys.platform == 'darwin': setup_requires=['py2app'], app=[mainscript], options=dict(py2app=dict(argv_emulation=True, - includes = ['PyQt4.QtCore','PyQt4.QtGui', 'sip'], + includes = ['PyQt4.QtCore','PyQt4.QtGui', 'sip', 'sqlite3'], packages = ['bitmessageqt'], frameworks = ['/usr/local/opt/openssl/lib/libcrypto.dylib'], iconfile='images/bitmessage.icns', From 350e8d66c755038d499a27325d26e038bdc22c85 Mon Sep 17 00:00:00 2001 From: Jonathan Warren Date: Wed, 24 Jul 2013 11:46:28 -0400 Subject: [PATCH 18/20] Prompt user to connect at first startup --- src/bitmessageqt/__init__.py | 28 ++++++++++++++++++++++++++-- src/class_outgoingSynSender.py | 3 ++- src/class_singleListener.py | 4 +++- src/helper_startup.py | 1 + 4 files changed, 32 insertions(+), 4 deletions(-) diff --git a/src/bitmessageqt/__init__.py b/src/bitmessageqt/__init__.py index 3ee43370..a7206c75 100644 --- a/src/bitmessageqt/__init__.py +++ b/src/bitmessageqt/__init__.py @@ -23,6 +23,7 @@ from settings import * from about import * from help import * from iconglossary import * +from connect import * import sys from time import strftime, localtime, gmtime import time @@ -424,6 +425,8 @@ class MyForm(QtGui.QMainWindow): self.rerenderComboBoxSendFrom() + + # Show or hide the application window after clicking an item within the # tray icon or, on Windows, the try icon itself. def appIndicatorShowOrHideWindow(self): @@ -1160,6 +1163,16 @@ class MyForm(QtGui.QMainWindow): "MainWindow", "Successfully joined chan. ")) self.ui.tabWidget.setCurrentIndex(3) + def showConnectDialog(self): + self.connectDialogInstance = connectDialog(self) + if self.connectDialogInstance.exec_(): + if self.connectDialogInstance.ui.radioButtonConnectNow.isChecked(): + shared.config.remove_option('bitmessagesettings', 'dontconnect') + with open(shared.appdata + 'keys.dat', 'wb') as configfile: + shared.config.write(configfile) + else: + self.click_actionSettings() + def openKeysFile(self): if 'linux' in sys.platform: subprocess.call(["xdg-open", shared.appdata + 'keys.dat']) @@ -1946,8 +1959,9 @@ class MyForm(QtGui.QMainWindow): shared.config.set('bitmessagesettings', 'startintray', str( self.settingsDialogInstance.ui.checkBoxStartInTray.isChecked())) if int(shared.config.get('bitmessagesettings', 'port')) != int(self.settingsDialogInstance.ui.lineEditTCPPort.text()): - QMessageBox.about(self, _translate("MainWindow", "Restart"), _translate( - "MainWindow", "You must restart Bitmessage for the port number change to take effect.")) + if not shared.safeConfigGetBoolean('bitmessagesettings', 'dontconnect'): + QMessageBox.about(self, _translate("MainWindow", "Restart"), _translate( + "MainWindow", "You must restart Bitmessage for the port number change to take effect.")) shared.config.set('bitmessagesettings', 'port', str( self.settingsDialogInstance.ui.lineEditTCPPort.text())) if shared.config.get('bitmessagesettings', 'socksproxytype') == 'none' and str(self.settingsDialogInstance.ui.comboBoxProxyType.currentText())[0:5] == 'SOCKS': @@ -2867,7 +2881,15 @@ class helpDialog(QtGui.QDialog): self.parent = parent self.ui.labelHelpURI.setOpenExternalLinks(True) QtGui.QWidget.resize(self, QtGui.QWidget.sizeHint(self)) + +class connectDialog(QtGui.QDialog): + def __init__(self, parent): + QtGui.QWidget.__init__(self, parent) + self.ui = Ui_connectDialog() + self.ui.setupUi(self) + self.parent = parent + QtGui.QWidget.resize(self, QtGui.QWidget.sizeHint(self)) class aboutDialog(QtGui.QDialog): @@ -3211,6 +3233,8 @@ def run(): myapp.appIndicatorInit(app) myapp.ubuntuMessagingMenuInit() myapp.notifierInit() + if shared.safeConfigGetBoolean('bitmessagesettings', 'dontconnect'): + myapp.showConnectDialog() # ask the user if we may connect if gevent is None: sys.exit(app.exec_()) else: diff --git a/src/class_outgoingSynSender.py b/src/class_outgoingSynSender.py index 5c21d72c..ac0b11ac 100644 --- a/src/class_outgoingSynSender.py +++ b/src/class_outgoingSynSender.py @@ -23,7 +23,8 @@ class outgoingSynSender(threading.Thread): self.selfInitiatedConnections = selfInitiatedConnections def run(self): - time.sleep(1) + while shared.safeConfigGetBoolean('bitmessagesettings', 'dontconnect'): + time.sleep(2) while True: while len(self.selfInitiatedConnections[self.streamNumber]) >= 8: # maximum number of outgoing connections = 8 time.sleep(10) diff --git a/src/class_singleListener.py b/src/class_singleListener.py index d6b46643..f339b2ba 100644 --- a/src/class_singleListener.py +++ b/src/class_singleListener.py @@ -26,7 +26,9 @@ class singleListener(threading.Thread): # proxy 'none' or configure SOCKS listening then this will start listening for # connections. while shared.config.get('bitmessagesettings', 'socksproxytype')[0:5] == 'SOCKS' and not shared.config.getboolean('bitmessagesettings', 'sockslisten'): - time.sleep(300) + time.sleep(10) + while shared.safeConfigGetBoolean('bitmessagesettings', 'dontconnect'): + time.sleep(1) with shared.printLock: print 'Listening for incoming connections.' diff --git a/src/helper_startup.py b/src/helper_startup.py index 46150d4d..3359a080 100644 --- a/src/helper_startup.py +++ b/src/helper_startup.py @@ -66,6 +66,7 @@ def loadConfig(): 'bitmessagesettings', 'maxacceptablenoncetrialsperbyte', '0') shared.config.set( 'bitmessagesettings', 'maxacceptablepayloadlengthextrabytes', '0') + shared.config.set('bitmessagesettings', 'dontconnect', 'true') if storeConfigFilesInSameDirectoryAsProgramByDefault: # Just use the same directory as the program and forget about From bfd2d35a573c0e314588ffbbf7dd4eaa0d5ab7e4 Mon Sep 17 00:00:00 2001 From: Jonathan Warren Date: Wed, 24 Jul 2013 11:49:48 -0400 Subject: [PATCH 19/20] add the connect.py file --- src/bitmessageqt/connect.py | 60 +++++++++++++++++++++ src/bitmessageqt/connect.ui | 101 ++++++++++++++++++++++++++++++++++++ 2 files changed, 161 insertions(+) create mode 100644 src/bitmessageqt/connect.py create mode 100644 src/bitmessageqt/connect.ui diff --git a/src/bitmessageqt/connect.py b/src/bitmessageqt/connect.py new file mode 100644 index 00000000..de950cdb --- /dev/null +++ b/src/bitmessageqt/connect.py @@ -0,0 +1,60 @@ +# -*- coding: utf-8 -*- + +# Form implementation generated from reading ui file 'connect.ui' +# +# Created: Wed Jul 24 10:41:58 2013 +# by: PyQt4 UI code generator 4.10 +# +# WARNING! All changes made in this file will be lost! + +from PyQt4 import QtCore, QtGui + +try: + _fromUtf8 = QtCore.QString.fromUtf8 +except AttributeError: + def _fromUtf8(s): + return s + +try: + _encoding = QtGui.QApplication.UnicodeUTF8 + def _translate(context, text, disambig): + return QtGui.QApplication.translate(context, text, disambig, _encoding) +except AttributeError: + def _translate(context, text, disambig): + return QtGui.QApplication.translate(context, text, disambig) + +class Ui_connectDialog(object): + def setupUi(self, connectDialog): + connectDialog.setObjectName(_fromUtf8("connectDialog")) + connectDialog.resize(400, 124) + self.gridLayout = QtGui.QGridLayout(connectDialog) + self.gridLayout.setObjectName(_fromUtf8("gridLayout")) + self.label = QtGui.QLabel(connectDialog) + self.label.setObjectName(_fromUtf8("label")) + self.gridLayout.addWidget(self.label, 0, 0, 1, 2) + self.radioButtonConnectNow = QtGui.QRadioButton(connectDialog) + self.radioButtonConnectNow.setChecked(True) + self.radioButtonConnectNow.setObjectName(_fromUtf8("radioButtonConnectNow")) + self.gridLayout.addWidget(self.radioButtonConnectNow, 1, 0, 1, 2) + self.radioButton = QtGui.QRadioButton(connectDialog) + self.radioButton.setObjectName(_fromUtf8("radioButton")) + self.gridLayout.addWidget(self.radioButton, 2, 0, 1, 2) + spacerItem = QtGui.QSpacerItem(185, 24, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) + self.gridLayout.addItem(spacerItem, 3, 0, 1, 1) + self.buttonBox = QtGui.QDialogButtonBox(connectDialog) + self.buttonBox.setOrientation(QtCore.Qt.Horizontal) + self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Ok) + self.buttonBox.setObjectName(_fromUtf8("buttonBox")) + self.gridLayout.addWidget(self.buttonBox, 3, 1, 1, 1) + + self.retranslateUi(connectDialog) + QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("accepted()")), connectDialog.accept) + QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("rejected()")), connectDialog.reject) + QtCore.QMetaObject.connectSlotsByName(connectDialog) + + def retranslateUi(self, connectDialog): + connectDialog.setWindowTitle(_translate("connectDialog", "Dialog", None)) + self.label.setText(_translate("connectDialog", "Bitmessage won\'t connect to anyone until you let it. ", None)) + self.radioButtonConnectNow.setText(_translate("connectDialog", "Connect now", None)) + self.radioButton.setText(_translate("connectDialog", "Let me configure special network settings first", None)) + diff --git a/src/bitmessageqt/connect.ui b/src/bitmessageqt/connect.ui new file mode 100644 index 00000000..a5e390dd --- /dev/null +++ b/src/bitmessageqt/connect.ui @@ -0,0 +1,101 @@ + + + connectDialog + + + + 0 + 0 + 400 + 124 + + + + Dialog + + + + + + Bitmessage won't connect to anyone until you let it. + + + + + + + Connect now + + + true + + + + + + + Let me configure special network settings first + + + + + + + Qt::Horizontal + + + + 185 + 24 + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + connectDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + connectDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + From c27494ace9decd24f47960b667c2a23272a0de6c Mon Sep 17 00:00:00 2001 From: Jonathan Warren Date: Wed, 24 Jul 2013 12:43:51 -0400 Subject: [PATCH 20/20] Further work to implement the Connect dialog on startup --- src/bitmessagemain.py | 35 +++++++++++++-------------------- src/bitmessageqt/connect.py | 12 ++++++------ src/bitmessageqt/connect.ui | 4 ++-- src/class_singleListener.py | 8 +++++--- src/helper_bootstrap.py | 39 +++++++++++++++++-------------------- 5 files changed, 44 insertions(+), 54 deletions(-) diff --git a/src/bitmessagemain.py b/src/bitmessagemain.py index 15acf545..9f87e80e 100644 --- a/src/bitmessagemain.py +++ b/src/bitmessagemain.py @@ -9,7 +9,7 @@ # The software version variable is now held in shared.py -#import ctypes +# import ctypes try: from gevent import monkey monkey.patch_all() @@ -36,7 +36,7 @@ import helper_bootstrap import sys if sys.platform == 'darwin': - if float( "{1}.{2}".format(*sys.version_info) ) < 7.5: + if float("{1}.{2}".format(*sys.version_info)) < 7.5: print "You should use python 2.7.5 or greater." print "Your version: {0}.{1}.{2}".format(*sys.version_info) sys.exit(0) @@ -56,8 +56,6 @@ def connectToStream(streamNumber): # This is one of several classes that constitute the API # This class was written by Vaibhav Bhatia. Modified by Jonathan Warren (Atheros). # http://code.activestate.com/recipes/501148-xmlrpc-serverclient-which-does-cookie-handling-and/ - - class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler): def do_POST(self): @@ -342,7 +340,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler): msgid, toAddress, fromAddress, subject, received, message, encodingtype = row subject = shared.fixPotentiallyInvalidUTF8Data(subject) message = shared.fixPotentiallyInvalidUTF8Data(message) - data += json.dumps({'msgid':msgid.encode('hex'),'toAddress':toAddress,'fromAddress':fromAddress,'subject':subject.encode('base64'),'message':message.encode('base64'),'encodingType':encodingtype,'receivedTime':received},indent=4, separators=(',', ': ')) + data += json.dumps({'msgid':msgid.encode('hex'), 'toAddress':toAddress, 'fromAddress':fromAddress, 'subject':subject.encode('base64'), 'message':message.encode('base64'), 'encodingType':encodingtype, 'receivedTime':received}, indent=4, separators=(',', ': ')) data += ']}' return data elif method == 'getAllSentMessages': @@ -358,7 +356,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler): message = shared.fixPotentiallyInvalidUTF8Data(message) if len(data) > 25: data += ',' - data += json.dumps({'msgid':msgid.encode('hex'),'toAddress':toAddress,'fromAddress':fromAddress,'subject':subject.encode('base64'),'message':message.encode('base64'),'encodingType':encodingtype,'lastActionTime':lastactiontime,'status':status,'ackData':ackdata.encode('hex')},indent=4, separators=(',', ': ')) + data += json.dumps({'msgid':msgid.encode('hex'), 'toAddress':toAddress, 'fromAddress':fromAddress, 'subject':subject.encode('base64'), 'message':message.encode('base64'), 'encodingType':encodingtype, 'lastActionTime':lastactiontime, 'status':status, 'ackData':ackdata.encode('hex')}, indent=4, separators=(',', ': ')) data += ']}' return data elif method == 'getInboxMessagesByAddress': @@ -373,12 +371,12 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler): shared.sqlLock.release() data = '{"inboxMessages":[' for row in queryreturn: - msgid, toAddress, fromAddress, subject, received, message, encodingtype= row + msgid, toAddress, fromAddress, subject, received, message, encodingtype = row subject = shared.fixPotentiallyInvalidUTF8Data(subject) message = shared.fixPotentiallyInvalidUTF8Data(message) if len(data) > 25: data += ',' - data += json.dumps({'msgid':msgid.encode('hex'),'toAddress':toAddress,'fromAddress':fromAddress,'subject':subject.encode('base64'),'message':message.encode('base64'),'encodingType':encodingtype,'receivedTime':received},indent=4, separators=(',', ': ')) + data += json.dumps({'msgid':msgid.encode('hex'), 'toAddress':toAddress, 'fromAddress':fromAddress, 'subject':subject.encode('base64'), 'message':message.encode('base64'), 'encodingType':encodingtype, 'receivedTime':received}, indent=4, separators=(',', ': ')) data += ']}' return data elif method == 'getSentMessageById': @@ -396,7 +394,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler): msgid, toAddress, fromAddress, subject, lastactiontime, message, encodingtype, status, ackdata = row subject = shared.fixPotentiallyInvalidUTF8Data(subject) message = shared.fixPotentiallyInvalidUTF8Data(message) - data += json.dumps({'msgid':msgid.encode('hex'),'toAddress':toAddress,'fromAddress':fromAddress,'subject':subject.encode('base64'),'message':message.encode('base64'),'encodingType':encodingtype,'lastActionTime':lastactiontime,'status':status,'ackData':ackdata.encode('hex')},indent=4, separators=(',', ': ')) + data += json.dumps({'msgid':msgid.encode('hex'), 'toAddress':toAddress, 'fromAddress':fromAddress, 'subject':subject.encode('base64'), 'message':message.encode('base64'), 'encodingType':encodingtype, 'lastActionTime':lastactiontime, 'status':status, 'ackData':ackdata.encode('hex')}, indent=4, separators=(',', ': ')) data += ']}' return data elif method == 'getSentMessagesByAddress': @@ -416,7 +414,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler): message = shared.fixPotentiallyInvalidUTF8Data(message) if len(data) > 25: data += ',' - data += json.dumps({'msgid':msgid.encode('hex'),'toAddress':toAddress,'fromAddress':fromAddress,'subject':subject.encode('base64'),'message':message.encode('base64'),'encodingType':encodingtype,'lastActionTime':lastactiontime,'status':status,'ackData':ackdata.encode('hex')},indent=4, separators=(',', ': ')) + data += json.dumps({'msgid':msgid.encode('hex'), 'toAddress':toAddress, 'fromAddress':fromAddress, 'subject':subject.encode('base64'), 'message':message.encode('base64'), 'encodingType':encodingtype, 'lastActionTime':lastactiontime, 'status':status, 'ackData':ackdata.encode('hex')}, indent=4, separators=(',', ': ')) data += ']}' return data elif method == 'getSentMessageByAckData': @@ -434,7 +432,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler): msgid, toAddress, fromAddress, subject, lastactiontime, message, encodingtype, status, ackdata = row subject = shared.fixPotentiallyInvalidUTF8Data(subject) message = shared.fixPotentiallyInvalidUTF8Data(message) - data += json.dumps({'msgid':msgid.encode('hex'),'toAddress':toAddress,'fromAddress':fromAddress,'subject':subject.encode('base64'),'message':message.encode('base64'),'encodingType':encodingtype,'lastActionTime':lastactiontime,'status':status,'ackData':ackdata.encode('hex')},indent=4, separators=(',', ': ')) + data += json.dumps({'msgid':msgid.encode('hex'), 'toAddress':toAddress, 'fromAddress':fromAddress, 'subject':subject.encode('base64'), 'message':message.encode('base64'), 'encodingType':encodingtype, 'lastActionTime':lastactiontime, 'status':status, 'ackData':ackdata.encode('hex')}, indent=4, separators=(',', ': ')) data += ']}' return data elif (method == 'trashMessage') or (method == 'trashInboxMessage'): @@ -454,7 +452,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler): shared.sqlReturnQueue.get() shared.sqlSubmitQueue.put('commit') shared.sqlLock.release() - #shared.UISignalQueue.put(('removeSentRowByMsgid',msgid)) This function doesn't exist yet. + # shared.UISignalQueue.put(('removeSentRowByMsgid',msgid)) This function doesn't exist yet. return 'Trashed sent message (assuming message existed).' elif method == 'sendMessage': if len(params) == 0: @@ -513,7 +511,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler): return 'API Error 0014: Your fromAddress is disabled. Cannot send.' ackdata = OpenSSL.rand(32) - + t = ('', toAddress, toRipe, fromAddress, subject, message, ackdata, int( time.time()), 'msgqueued', 1, 1, 'sent', 2) helper_sent.insert(t) @@ -577,7 +575,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler): toAddress = '[Broadcast subscribers]' ripe = '' - + t = ('', toAddress, ripe, fromAddress, subject, message, ackdata, int( time.time()), 'broadcastqueued', 1, 1, 'sent', 2) helper_sent.insert(t) @@ -719,7 +717,6 @@ if __name__ == "__main__": # signal.signal(signal.SIGINT, signal.SIG_DFL) helper_bootstrap.knownNodes() - helper_bootstrap.dns() # Start the address generation thread addressGeneratorThread = addressGenerator() addressGeneratorThread.daemon = True # close the main program even if there are threads left @@ -757,13 +754,6 @@ if __name__ == "__main__": singleAPIThread = singleAPI() singleAPIThread.daemon = True # close the main program even if there are threads left singleAPIThread.start() - # self.singleAPISignalHandlerThread = singleAPISignalHandler() - # self.singleAPISignalHandlerThread.start() - # QtCore.QObject.connect(self.singleAPISignalHandlerThread, QtCore.SIGNAL("updateStatusBar(PyQt_PyObject)"), self.updateStatusBar) - # QtCore.QObject.connect(self.singleAPISignalHandlerThread, QtCore.SIGNAL("passAddressGeneratorObjectThrough(PyQt_PyObject)"), self.connectObjectToAddressGeneratorSignals) - # QtCore.QObject.connect(self.singleAPISignalHandlerThread, - # QtCore.SIGNAL("displayNewSentMessage(PyQt_PyObject,PyQt_PyObject,PyQt_PyObject,PyQt_PyObject,PyQt_PyObject,PyQt_PyObject)"), - # self.displayNewSentMessage) connectToStream(1) @@ -783,6 +773,7 @@ if __name__ == "__main__": import bitmessageqt bitmessageqt.run() else: + shared.config.remove_option('bitmessagesettings', 'dontconnect') with shared.printLock: print 'Running as a daemon. You can use Ctrl+C to exit.' diff --git a/src/bitmessageqt/connect.py b/src/bitmessageqt/connect.py index de950cdb..1e224afb 100644 --- a/src/bitmessageqt/connect.py +++ b/src/bitmessageqt/connect.py @@ -2,7 +2,7 @@ # Form implementation generated from reading ui file 'connect.ui' # -# Created: Wed Jul 24 10:41:58 2013 +# Created: Wed Jul 24 12:42:01 2013 # by: PyQt4 UI code generator 4.10 # # WARNING! All changes made in this file will be lost! @@ -36,9 +36,9 @@ class Ui_connectDialog(object): self.radioButtonConnectNow.setChecked(True) self.radioButtonConnectNow.setObjectName(_fromUtf8("radioButtonConnectNow")) self.gridLayout.addWidget(self.radioButtonConnectNow, 1, 0, 1, 2) - self.radioButton = QtGui.QRadioButton(connectDialog) - self.radioButton.setObjectName(_fromUtf8("radioButton")) - self.gridLayout.addWidget(self.radioButton, 2, 0, 1, 2) + self.radioButtonConfigureNetwork = QtGui.QRadioButton(connectDialog) + self.radioButtonConfigureNetwork.setObjectName(_fromUtf8("radioButtonConfigureNetwork")) + self.gridLayout.addWidget(self.radioButtonConfigureNetwork, 2, 0, 1, 2) spacerItem = QtGui.QSpacerItem(185, 24, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) self.gridLayout.addItem(spacerItem, 3, 0, 1, 1) self.buttonBox = QtGui.QDialogButtonBox(connectDialog) @@ -53,8 +53,8 @@ class Ui_connectDialog(object): QtCore.QMetaObject.connectSlotsByName(connectDialog) def retranslateUi(self, connectDialog): - connectDialog.setWindowTitle(_translate("connectDialog", "Dialog", None)) + connectDialog.setWindowTitle(_translate("connectDialog", "Bitmessage", None)) self.label.setText(_translate("connectDialog", "Bitmessage won\'t connect to anyone until you let it. ", None)) self.radioButtonConnectNow.setText(_translate("connectDialog", "Connect now", None)) - self.radioButton.setText(_translate("connectDialog", "Let me configure special network settings first", None)) + self.radioButtonConfigureNetwork.setText(_translate("connectDialog", "Let me configure special network settings first", None)) diff --git a/src/bitmessageqt/connect.ui b/src/bitmessageqt/connect.ui index a5e390dd..74173860 100644 --- a/src/bitmessageqt/connect.ui +++ b/src/bitmessageqt/connect.ui @@ -11,7 +11,7 @@ - Dialog + Bitmessage @@ -32,7 +32,7 @@ - + Let me configure special network settings first diff --git a/src/class_singleListener.py b/src/class_singleListener.py index f339b2ba..3890447a 100644 --- a/src/class_singleListener.py +++ b/src/class_singleListener.py @@ -3,6 +3,7 @@ import shared import socket from class_sendDataThread import * from class_receiveDataThread import * +import helper_bootstrap # Only one singleListener thread will ever exist. It creates the # receiveDataThread and sendDataThread for each incoming connection. Note @@ -21,14 +22,15 @@ class singleListener(threading.Thread): self.selfInitiatedConnections = selfInitiatedConnections def run(self): + while shared.safeConfigGetBoolean('bitmessagesettings', 'dontconnect'): + time.sleep(1) + helper_bootstrap.dns() # We typically don't want to accept incoming connections if the user is using a # SOCKS proxy, unless they have configured otherwise. If they eventually select # proxy 'none' or configure SOCKS listening then this will start listening for # connections. while shared.config.get('bitmessagesettings', 'socksproxytype')[0:5] == 'SOCKS' and not shared.config.getboolean('bitmessagesettings', 'sockslisten'): - time.sleep(10) - while shared.safeConfigGetBoolean('bitmessagesettings', 'dontconnect'): - time.sleep(1) + time.sleep(5) with shared.printLock: print 'Listening for incoming connections.' diff --git a/src/helper_bootstrap.py b/src/helper_bootstrap.py index c3d5c1fd..e0056342 100644 --- a/src/helper_bootstrap.py +++ b/src/helper_bootstrap.py @@ -12,14 +12,10 @@ def knownNodes(): shared.knownNodes = pickle.load(pickleFile) pickleFile.close() except: - defaultKnownNodes.createDefaultKnownNodes(shared.appdata) - pickleFile = open(shared.appdata + 'knownnodes.dat', 'rb') - shared.knownNodes = pickle.load(pickleFile) - pickleFile.close() + shared.knownNodes = defaultKnownNodes.createDefaultKnownNodes(shared.appdata) if shared.config.getint('bitmessagesettings', 'settingsversion') > 6: print 'Bitmessage cannot read future versions of the keys file (keys.dat). Run the newer version of Bitmessage.' raise SystemExit - def dns(): # DNS bootstrap. This could be programmed to use the SOCKS proxy to do the @@ -27,19 +23,20 @@ def dns(): # defaultKnownNodes.py. Hopefully either they are up to date or the user # has run Bitmessage recently without SOCKS turned on and received good # bootstrap nodes using that method. - if shared.config.get('bitmessagesettings', 'socksproxytype') == 'none': - try: - for item in socket.getaddrinfo('bootstrap8080.bitmessage.org', 80): - print 'Adding', item[4][0], 'to knownNodes based on DNS boostrap method' - shared.knownNodes[1][item[4][0]] = (8080, int(time.time())) - except: - print 'bootstrap8080.bitmessage.org DNS bootstrapping failed.' - try: - for item in socket.getaddrinfo('bootstrap8444.bitmessage.org', 80): - print 'Adding', item[4][0], 'to knownNodes based on DNS boostrap method' - shared.knownNodes[1][item[4][0]] = (8444, int(time.time())) - except: - print 'bootstrap8444.bitmessage.org DNS bootstrapping failed.' - else: - print 'DNS bootstrap skipped because SOCKS is used.' - + with shared.printLock: + if shared.config.get('bitmessagesettings', 'socksproxytype') == 'none': + try: + for item in socket.getaddrinfo('bootstrap8080.bitmessage.org', 80): + print 'Adding', item[4][0], 'to knownNodes based on DNS boostrap method' + shared.knownNodes[1][item[4][0]] = (8080, int(time.time())) + except: + print 'bootstrap8080.bitmessage.org DNS bootstrapping failed.' + try: + for item in socket.getaddrinfo('bootstrap8444.bitmessage.org', 80): + print 'Adding', item[4][0], 'to knownNodes based on DNS boostrap method' + shared.knownNodes[1][item[4][0]] = (8444, int(time.time())) + except: + print 'bootstrap8444.bitmessage.org DNS bootstrapping failed.' + else: + print 'DNS bootstrap skipped because SOCKS is used.' +