Merge branch 'master' of https://github.com/Bitmessage/PyBitmessage into namecoin-id

Conflicts:
	src/bitmessageqt/bitmessageui.py
	src/helper_startup.py
This commit is contained in:
Daniel Kraft 2013-07-27 08:24:52 +02:00
commit 665659f214
29 changed files with 751 additions and 350 deletions

View File

@ -2,6 +2,7 @@ APP=pybitmessage
VERSION=0.3.4 VERSION=0.3.4
RELEASE=1 RELEASE=1
ARCH_TYPE=`uname -m` ARCH_TYPE=`uname -m`
PREFIX?=/usr/local
all: all:
debug: debug:
@ -9,37 +10,42 @@ source:
tar -cvzf ../${APP}_${VERSION}.orig.tar.gz ../${APP}-${VERSION} --exclude-vcs tar -cvzf ../${APP}_${VERSION}.orig.tar.gz ../${APP}-${VERSION} --exclude-vcs
install: install:
mkdir -p ${DESTDIR}/usr mkdir -p ${DESTDIR}/usr
mkdir -p ${DESTDIR}/usr/bin mkdir -p ${DESTDIR}${PREFIX}
mkdir -m 755 -p ${DESTDIR}/usr/share mkdir -p ${DESTDIR}${PREFIX}/bin
mkdir -m 755 -p ${DESTDIR}/usr/share/man mkdir -m 755 -p ${DESTDIR}${PREFIX}/share
mkdir -m 755 -p ${DESTDIR}/usr/share/man/man1 mkdir -m 755 -p ${DESTDIR}${PREFIX}/share/man
install -m 644 man/${APP}.1.gz ${DESTDIR}/usr/share/man/man1 mkdir -m 755 -p ${DESTDIR}${PREFIX}/share/man/man1
mkdir -m 755 -p ${DESTDIR}/usr/share/${APP} install -m 644 man/${APP}.1.gz ${DESTDIR}${PREFIX}/share/man/man1
mkdir -m 755 -p ${DESTDIR}/usr/share/applications mkdir -m 755 -p ${DESTDIR}${PREFIX}/share/${APP}
mkdir -m 755 -p ${DESTDIR}/usr/share/pixmaps mkdir -m 755 -p ${DESTDIR}${PREFIX}/share/applications
mkdir -m 755 -p ${DESTDIR}/usr/share/icons mkdir -m 755 -p ${DESTDIR}${PREFIX}/share/pixmaps
mkdir -m 755 -p ${DESTDIR}/usr/share/icons/hicolor mkdir -m 755 -p ${DESTDIR}${PREFIX}/share/icons
mkdir -m 755 -p ${DESTDIR}/usr/share/icons/hicolor/scalable mkdir -m 755 -p ${DESTDIR}${PREFIX}/share/icons/hicolor
mkdir -m 755 -p ${DESTDIR}/usr/share/icons/hicolor/scalable/apps mkdir -m 755 -p ${DESTDIR}${PREFIX}/share/icons/hicolor/scalable
mkdir -m 755 -p ${DESTDIR}/usr/share/icons/hicolor/24x24 mkdir -m 755 -p ${DESTDIR}${PREFIX}/share/icons/hicolor/scalable/apps
mkdir -m 755 -p ${DESTDIR}/usr/share/icons/hicolor/24x24/apps mkdir -m 755 -p ${DESTDIR}${PREFIX}/share/icons/hicolor/24x24
install -m 644 desktop/${APP}.desktop ${DESTDIR}/usr/share/applications/${APP}.desktop mkdir -m 755 -p ${DESTDIR}${PREFIX}/share/icons/hicolor/24x24/apps
install -m 644 desktop/icon24.png ${DESTDIR}/usr/share/icons/hicolor/24x24/apps/${APP}.png install -m 644 desktop/${APP}.desktop ${DESTDIR}${PREFIX}/share/applications/${APP}.desktop
cp -rf src/* ${DESTDIR}/usr/share/${APP} install -m 644 desktop/icon24.png ${DESTDIR}${PREFIX}/share/icons/hicolor/24x24/apps/${APP}.png
echo '#!/bin/sh' > ${DESTDIR}/usr/bin/${APP} cp -rf src/* ${DESTDIR}${PREFIX}/share/${APP}
echo 'cd /usr/share/pybitmessage' >> ${DESTDIR}/usr/bin/${APP} echo '#!/bin/sh' > ${DESTDIR}${PREFIX}/bin/${APP}
echo 'LD_LIBRARY_PATH="/opt/openssl-compat-bitcoin/lib/" exec python2 bitmessagemain.py' >> ${DESTDIR}/usr/bin/${APP} echo 'if [ -d /usr/local/share/${APP} ]; then' >> ${DESTDIR}${PREFIX}/bin/${APP}
chmod +x ${DESTDIR}/usr/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: uninstall:
rm -f /usr/share/man/man1/${APP}.1.gz rm -f ${PREFIX}/share/man/man1/${APP}.1.gz
rm -rf /usr/share/${APP} rm -rf ${PREFIX}/share/${APP}
rm -f /usr/bin/${APP} rm -f ${PREFIX}/bin/${APP}
rm -f /usr/share/applications/${APP}.desktop rm -f ${PREFIX}/share/applications/${APP}.desktop
rm -f /usr/share/icons/hicolor/scalable/apps/${APP}.svg rm -f ${PREFIX}/share/icons/hicolor/scalable/apps/${APP}.svg
/usr/share/pixmaps/${APP}.svg rm -f ${PREFIX}/share/pixmaps/${APP}.svg
clean: clean:
rm -f ${APP} \#* \.#* gnuplot* *.png debian/*.substvars debian/*.log rm -f ${APP} \#* \.#* gnuplot* *.png debian/*.substvars debian/*.log
rm -fr deb.* debian/${APP} rpmpackage/${ARCH_TYPE} rm -fr deb.* debian/${APP} rpmpackage/${ARCH_TYPE}
rm -f ../${APP}*.deb ../${APP}*.changes ../${APP}*.asc ../${APP}*.dsc rm -f ../${APP}*.deb ../${APP}*.changes ../${APP}*.asc ../${APP}*.dsc
rm -f rpmpackage/*.src.rpm archpackage/*.gz archpackage/*.xz 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

View File

@ -7,7 +7,7 @@ arch=('i686' 'x86_64')
url="https://github.com/Bitmessage/PyBitmessage" url="https://github.com/Bitmessage/PyBitmessage"
license=('MIT') license=('MIT')
groups=() groups=()
depends=('python2' 'qt4' 'python2-pyqt4' 'sqlite' 'openssl') depends=('python2' 'qt4' 'python2-pyqt4' 'sqlite' 'openssl' 'gst123')
makedepends=() makedepends=()
optdepends=('python2-gevent') optdepends=('python2-gevent')
provides=() provides=()
@ -27,5 +27,5 @@ build() {
} }
package() { package() {
cd "$srcdir/$pkgname-$pkgver" cd "$srcdir/$pkgname-$pkgver"
make DESTDIR="$pkgdir/" install make DESTDIR="$pkgdir/" PREFIX="/usr" install
} }

4
debian/control vendored
View File

@ -4,12 +4,12 @@ Maintainer: Bob Mottram (4096 bits) <bob@robotics.uk.to>
Build-Depends: debhelper (>= 9.0.0) Build-Depends: debhelper (>= 9.0.0)
Standards-Version: 3.9.4 Standards-Version: 3.9.4
Homepage: https://github.com/Bitmessage/PyBitmessage Homepage: https://github.com/Bitmessage/PyBitmessage
Vcs-Git: https://github.com/fuzzgun/fin.git Vcs-Git: https://github.com/Bitmessage/PyBitmessage.git
Package: pybitmessage Package: pybitmessage
Section: mail Section: mail
Architecture: any 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 Suggests: libmessaging-menu-dev
Description: Send encrypted messages Description: Send encrypted messages
Bitmessage is a P2P communications protocol used to send encrypted Bitmessage is a P2P communications protocol used to send encrypted

3
debian/rules vendored
View File

@ -1,6 +1,7 @@
#!/usr/bin/make -f #!/usr/bin/make -f
APP=pybitmessage APP=pybitmessage
PREFIX=/usr
build: build-stamp build: build-stamp
make make
build-arch: build-stamp build-arch: build-stamp
@ -20,7 +21,7 @@ install: build clean
dh_testroot dh_testroot
dh_prep dh_prep
dh_installdirs dh_installdirs
${MAKE} install -B DESTDIR=${CURDIR}/debian/${APP} ${MAKE} install -B DESTDIR=${CURDIR}/debian/${APP} PREFIX=/usr
binary-indep: build install binary-indep: build install
dh_testdir dh_testdir
dh_testroot dh_testroot

View File

@ -1,22 +1,32 @@
# $Header: $ # $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." 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" HOMEPAGE="https://github.com/Bitmessage/PyBitmessage"
SRC_URI="${PN}/${P}.tar.gz" EGIT_REPO_URI="https://github.com/Bitmessage/PyBitmessage.git"
LICENSE="MIT" LICENSE="MIT"
SLOT="0" SLOT="0"
KEYWORDS="x86" KEYWORDS="x86"
RDEPEND="dev-libs/popt" DEPEND="dev-libs/popt
DEPEND="${RDEPEND}" ${PYTHON_DEPS}"
RDEPEND="${DEPEND}
dev-libs/openssl
dev-python/PyQt4[]"
src_configure() { src_configure() {
econf --with-popt econf --with-popt
} }
src_compile() { :; }
src_install() { src_install() {
emake DESTDIR="${D}" install emake DESTDIR="${D}" PREFIX="/usr" install
# Install README and (Debian) changelog # Install README and (Debian) changelog
dodoc README.md debian/changelog dodoc README.md debian/changelog
} }

View File

@ -4,4 +4,4 @@
rm -f Makefile rpmpackage/*.spec rm -f Makefile rpmpackage/*.spec
packagemonkey -n "PyBitmessage" --version "0.3.4" --dir "." -l "mit" -e "Bob Mottram (4096 bits) <bob@robotics.uk.to>" --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) <bob@robotics.uk.to>" --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"

View File

@ -27,7 +27,7 @@ mkdir -p ${PROJECTDIR}
# Build the project # Build the project
make clean make clean
make make
make install -B DESTDIR=${PROJECTDIR} make install -B DESTDIR=${PROJECTDIR} PREFIX=/usr
# Alter the desktop file categories # Alter the desktop file categories
sed -i "s/Categories=Office;Email;/Categories=Internet;mailnews;/g" ${PROJECTDIR}/usr/share/applications/${APP}.desktop sed -i "s/Categories=Office;Email;/Categories=Internet;mailnews;/g" ${PROJECTDIR}/usr/share/applications/${APP}.desktop

View File

@ -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.8M||pybitmessage-0.3.4-1.pet|+openssl,+python-qt4,+sqlite3,+sqlite3-dev,+python-openssl,+python-sip,+gst123|Send encrypted messages|ubuntu|precise|5|

View File

@ -8,7 +8,7 @@ Packager: Bob Mottram (4096 bits) <bob@robotics.uk.to>
Source0: http://yourdomainname.com/src/%{name}_%{version}.orig.tar.gz Source0: http://yourdomainname.com/src/%{name}_%{version}.orig.tar.gz
Group: Office/Email Group: Office/Email
Requires: python, PyQt4, openssl-compat-bitcoin-libs Requires: python, PyQt4, openssl-compat-bitcoin-libs, gst123
%description %description
@ -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
mkdir -p %{buildroot}/usr/share/icons/hicolor/scalable/apps mkdir -p %{buildroot}/usr/share/icons/hicolor/scalable/apps
# Make install but to the RPM BUILDROOT directory # Make install but to the RPM BUILDROOT directory
make install -B DESTDIR=%{buildroot} make install -B DESTDIR=%{buildroot} PREFIX=/usr
%files %files
%doc README.md LICENSE %doc README.md LICENSE

View File

@ -28,7 +28,7 @@ mkdir -p ${PROJECTDIR}
# Build the project # Build the project
make clean make clean
make 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 # Copy the slack-desc and doinst.sh files into the build install directory
mkdir ${PROJECTDIR}/install mkdir ${PROJECTDIR}/install

View File

@ -9,7 +9,7 @@
# The software version variable is now held in shared.py # The software version variable is now held in shared.py
#import ctypes # import ctypes
try: try:
from gevent import monkey from gevent import monkey
monkey.patch_all() monkey.patch_all()
@ -36,7 +36,7 @@ import helper_bootstrap
import sys import sys
if sys.platform == 'darwin': 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 "You should use python 2.7.5 or greater."
print "Your version: {0}.{1}.{2}".format(*sys.version_info) print "Your version: {0}.{1}.{2}".format(*sys.version_info)
sys.exit(0) sys.exit(0)
@ -56,8 +56,6 @@ def connectToStream(streamNumber):
# This is one of several classes that constitute the API # This is one of several classes that constitute the API
# This class was written by Vaibhav Bhatia. Modified by Jonathan Warren (Atheros). # 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/ # http://code.activestate.com/recipes/501148-xmlrpc-serverclient-which-does-cookie-handling-and/
class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler): class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
def do_POST(self): def do_POST(self):
@ -342,7 +340,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
msgid, toAddress, fromAddress, subject, received, message, encodingtype = row msgid, toAddress, fromAddress, subject, received, message, encodingtype = row
subject = shared.fixPotentiallyInvalidUTF8Data(subject) subject = shared.fixPotentiallyInvalidUTF8Data(subject)
message = shared.fixPotentiallyInvalidUTF8Data(message) 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 += ']}' data += ']}'
return data return data
elif method == 'getAllSentMessages': elif method == 'getAllSentMessages':
@ -358,7 +356,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
message = shared.fixPotentiallyInvalidUTF8Data(message) message = shared.fixPotentiallyInvalidUTF8Data(message)
if len(data) > 25: if len(data) > 25:
data += ',' 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 += ']}' data += ']}'
return data return data
elif method == 'getInboxMessagesByAddress': elif method == 'getInboxMessagesByAddress':
@ -373,12 +371,12 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
shared.sqlLock.release() shared.sqlLock.release()
data = '{"inboxMessages":[' data = '{"inboxMessages":['
for row in queryreturn: for row in queryreturn:
msgid, toAddress, fromAddress, subject, received, message, encodingtype= row msgid, toAddress, fromAddress, subject, received, message, encodingtype = row
subject = shared.fixPotentiallyInvalidUTF8Data(subject) subject = shared.fixPotentiallyInvalidUTF8Data(subject)
message = shared.fixPotentiallyInvalidUTF8Data(message) message = shared.fixPotentiallyInvalidUTF8Data(message)
if len(data) > 25: if len(data) > 25:
data += ',' 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 += ']}' data += ']}'
return data return data
elif method == 'getSentMessageById': elif method == 'getSentMessageById':
@ -396,7 +394,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
msgid, toAddress, fromAddress, subject, lastactiontime, message, encodingtype, status, ackdata = row msgid, toAddress, fromAddress, subject, lastactiontime, message, encodingtype, status, ackdata = row
subject = shared.fixPotentiallyInvalidUTF8Data(subject) subject = shared.fixPotentiallyInvalidUTF8Data(subject)
message = shared.fixPotentiallyInvalidUTF8Data(message) 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 += ']}' data += ']}'
return data return data
elif method == 'getSentMessagesByAddress': elif method == 'getSentMessagesByAddress':
@ -416,7 +414,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
message = shared.fixPotentiallyInvalidUTF8Data(message) message = shared.fixPotentiallyInvalidUTF8Data(message)
if len(data) > 25: if len(data) > 25:
data += ',' 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 += ']}' data += ']}'
return data return data
elif method == 'getSentMessageByAckData': elif method == 'getSentMessageByAckData':
@ -434,7 +432,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
msgid, toAddress, fromAddress, subject, lastactiontime, message, encodingtype, status, ackdata = row msgid, toAddress, fromAddress, subject, lastactiontime, message, encodingtype, status, ackdata = row
subject = shared.fixPotentiallyInvalidUTF8Data(subject) subject = shared.fixPotentiallyInvalidUTF8Data(subject)
message = shared.fixPotentiallyInvalidUTF8Data(message) 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 += ']}' data += ']}'
return data return data
elif (method == 'trashMessage') or (method == 'trashInboxMessage'): elif (method == 'trashMessage') or (method == 'trashInboxMessage'):
@ -454,7 +452,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
shared.sqlReturnQueue.get() shared.sqlReturnQueue.get()
shared.sqlSubmitQueue.put('commit') shared.sqlSubmitQueue.put('commit')
shared.sqlLock.release() 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).' return 'Trashed sent message (assuming message existed).'
elif method == 'sendMessage': elif method == 'sendMessage':
if len(params) == 0: if len(params) == 0:
@ -513,7 +511,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
return 'API Error 0014: Your fromAddress is disabled. Cannot send.' return 'API Error 0014: Your fromAddress is disabled. Cannot send.'
ackdata = OpenSSL.rand(32) ackdata = OpenSSL.rand(32)
t = ('', toAddress, toRipe, fromAddress, subject, message, ackdata, int( t = ('', toAddress, toRipe, fromAddress, subject, message, ackdata, int(
time.time()), 'msgqueued', 1, 1, 'sent', 2) time.time()), 'msgqueued', 1, 1, 'sent', 2)
helper_sent.insert(t) helper_sent.insert(t)
@ -577,7 +575,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
toAddress = '[Broadcast subscribers]' toAddress = '[Broadcast subscribers]'
ripe = '' ripe = ''
t = ('', toAddress, ripe, fromAddress, subject, message, ackdata, int( t = ('', toAddress, ripe, fromAddress, subject, message, ackdata, int(
time.time()), 'broadcastqueued', 1, 1, 'sent', 2) time.time()), 'broadcastqueued', 1, 1, 'sent', 2)
helper_sent.insert(t) helper_sent.insert(t)
@ -719,7 +717,6 @@ if __name__ == "__main__":
# signal.signal(signal.SIGINT, signal.SIG_DFL) # signal.signal(signal.SIGINT, signal.SIG_DFL)
helper_bootstrap.knownNodes() helper_bootstrap.knownNodes()
helper_bootstrap.dns()
# Start the address generation thread # Start the address generation thread
addressGeneratorThread = addressGenerator() addressGeneratorThread = addressGenerator()
addressGeneratorThread.daemon = True # close the main program even if there are threads left addressGeneratorThread.daemon = True # close the main program even if there are threads left
@ -757,13 +754,6 @@ if __name__ == "__main__":
singleAPIThread = singleAPI() singleAPIThread = singleAPI()
singleAPIThread.daemon = True # close the main program even if there are threads left singleAPIThread.daemon = True # close the main program even if there are threads left
singleAPIThread.start() 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) connectToStream(1)
@ -783,6 +773,7 @@ if __name__ == "__main__":
import bitmessageqt import bitmessageqt
bitmessageqt.run() bitmessageqt.run()
else: else:
shared.config.remove_option('bitmessagesettings', 'dontconnect')
with shared.printLock: with shared.printLock:
print 'Running as a daemon. You can use Ctrl+C to exit.' print 'Running as a daemon. You can use Ctrl+C to exit.'

View File

@ -18,11 +18,13 @@ from namecoin import namecoinConnection, ensureNamecoinOptions
from newaddressdialog import * from newaddressdialog import *
from newsubscriptiondialog import * from newsubscriptiondialog import *
from regenerateaddresses import * from regenerateaddresses import *
from newchandialog import *
from specialaddressbehavior import * from specialaddressbehavior import *
from settings import * from settings import *
from about import * from about import *
from help import * from help import *
from iconglossary import * from iconglossary import *
from connect import *
import sys import sys
from time import strftime, localtime, gmtime from time import strftime, localtime, gmtime
import time import time
@ -32,11 +34,14 @@ import pickle
import platform import platform
import debug import debug
from debug import logger from debug import logger
import subprocess
try: try:
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from PyQt4.QtCore import * from PyQt4.QtCore import *
from PyQt4.QtGui import * from PyQt4.QtGui import *
except Exception as err: 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 '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 print 'Error message:', err
@ -53,7 +58,16 @@ def _translate(context, text):
class MyForm(QtGui.QMainWindow): 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]' str_broadcast_subscribers = '[Broadcast subscribers]'
str_chan = '[chan]'
def __init__(self, parent=None): def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent) QtGui.QWidget.__init__(self, parent)
@ -106,6 +120,8 @@ class MyForm(QtGui.QMainWindow):
"triggered()"), self.click_actionDeleteAllTrashedMessages) "triggered()"), self.click_actionDeleteAllTrashedMessages)
QtCore.QObject.connect(self.ui.actionRegenerateDeterministicAddresses, QtCore.SIGNAL( QtCore.QObject.connect(self.ui.actionRegenerateDeterministicAddresses, QtCore.SIGNAL(
"triggered()"), self.click_actionRegenerateDeterministicAddresses) "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( QtCore.QObject.connect(self.ui.pushButtonNewAddress, QtCore.SIGNAL(
"clicked()"), self.click_NewAddressDialog) "clicked()"), self.click_NewAddressDialog)
QtCore.QObject.connect(self.ui.comboBoxSendFrom, QtCore.SIGNAL( QtCore.QObject.connect(self.ui.comboBoxSendFrom, QtCore.SIGNAL(
@ -296,6 +312,8 @@ class MyForm(QtGui.QMainWindow):
newItem = QtGui.QTableWidgetItem(addressInKeysFile) newItem = QtGui.QTableWidgetItem(addressInKeysFile)
newItem.setFlags( newItem.setFlags(
QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
if shared.safeConfigGetBoolean(addressInKeysFile, 'chan'):
newItem.setTextColor(QtGui.QColor(216, 119, 0)) # orange
if not isEnabled: if not isEnabled:
newItem.setTextColor(QtGui.QColor(128, 128, 128)) newItem.setTextColor(QtGui.QColor(128, 128, 128))
if shared.safeConfigGetBoolean(addressInKeysFile, 'mailinglist'): if shared.safeConfigGetBoolean(addressInKeysFile, 'mailinglist'):
@ -410,6 +428,8 @@ class MyForm(QtGui.QMainWindow):
self.rerenderComboBoxSendFrom() self.rerenderComboBoxSendFrom()
# Show or hide the application window after clicking an item within the # Show or hide the application window after clicking an item within the
# tray icon or, on Windows, the try icon itself. # tray icon or, on Windows, the try icon itself.
def appIndicatorShowOrHideWindow(self): def appIndicatorShowOrHideWindow(self):
@ -597,6 +617,9 @@ class MyForm(QtGui.QMainWindow):
elif status == 'msgsent': elif status == 'msgsent':
statusText = _translate("MainWindow", "Message sent. Waiting on acknowledgement. Sent at %1").arg( statusText = _translate("MainWindow", "Message sent. Waiting on acknowledgement. Sent at %1").arg(
unicode(strftime(shared.config.get('bitmessagesettings', 'timeformat'), localtime(lastactiontime)),'utf-8')) 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': elif status == 'doingmsgpow':
statusText = _translate( statusText = _translate(
"MainWindow", "Need to do work to send message. Work is queued.") "MainWindow", "Need to do work to send message. Work is queued.")
@ -712,6 +735,8 @@ class MyForm(QtGui.QMainWindow):
newItem.setData(Qt.UserRole, str(toAddress)) newItem.setData(Qt.UserRole, str(toAddress))
if shared.safeConfigGetBoolean(toAddress, 'mailinglist'): if shared.safeConfigGetBoolean(toAddress, 'mailinglist'):
newItem.setTextColor(QtGui.QColor(137, 04, 177)) 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) self.ui.tableWidgetInbox.setItem(0, 0, newItem)
if fromLabel == '': if fromLabel == '':
newItem = QtGui.QTableWidgetItem( newItem = QtGui.QTableWidgetItem(
@ -957,6 +982,57 @@ class MyForm(QtGui.QMainWindow):
# update the menu entries # update the menu entries
self.ubuntuMessagingMenuUnread(drawAttention) 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:
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:
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
winsound.PlaySound(soundFilename, winsound.SND_FILENAME)
# initialise the message notifier # initialise the message notifier
def notifierInit(self): def notifierInit(self):
global withMessagingMenu global withMessagingMenu
@ -964,8 +1040,11 @@ class MyForm(QtGui.QMainWindow):
Notify.init('pybitmessage') Notify.init('pybitmessage')
# shows a notification # shows a notification
def notifierShow(self, title, subtitle): def notifierShow(self, title, subtitle, fromCategory, label):
global withMessagingMenu global withMessagingMenu
self.playSound(fromCategory, label);
if withMessagingMenu: if withMessagingMenu:
n = Notify.Notification.new( n = Notify.Notification.new(
title, subtitle, 'notification-message-email') title, subtitle, 'notification-message-email')
@ -1035,6 +1114,68 @@ class MyForm(QtGui.QMainWindow):
), self.regenerateAddressesDialogInstance.ui.lineEditPassphrase.text().toUtf8(), self.regenerateAddressesDialogInstance.ui.checkBoxEighteenByteRipe.isChecked())) ), self.regenerateAddressesDialogInstance.ui.lineEditPassphrase.text().toUtf8(), self.regenerateAddressesDialogInstance.ui.checkBoxEighteenByteRipe.isChecked()))
self.ui.tabWidget.setCurrentIndex(3) 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().toUtf8()), 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
createdAddress = addressGeneratorReturnValue[0]
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)
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): def openKeysFile(self):
if 'linux' in sys.platform: if 'linux' in sys.platform:
subprocess.call(["xdg-open", shared.appdata + 'keys.dat']) subprocess.call(["xdg-open", shared.appdata + 'keys.dat'])
@ -1138,7 +1279,8 @@ class MyForm(QtGui.QMainWindow):
# if the connection is lost then show a notification # if the connection is lost then show a notification
if self.connected: if self.connected:
self.notifierShow('Bitmessage', unicode(_translate( self.notifierShow('Bitmessage', unicode(_translate(
"MainWindow", "Connection lost").toUtf8(),'utf-8')) "MainWindow", "Connection lost").toUtf8(),'utf-8'),
self.SOUND_DISCONNECTED, None)
self.connected = False self.connected = False
if self.actionStatus is not None: if self.actionStatus is not None:
@ -1155,7 +1297,8 @@ class MyForm(QtGui.QMainWindow):
# if a new connection has been established then show a notification # if a new connection has been established then show a notification
if not self.connected: if not self.connected:
self.notifierShow('Bitmessage', unicode(_translate( self.notifierShow('Bitmessage', unicode(_translate(
"MainWindow", "Connected").toUtf8(),'utf-8')) "MainWindow", "Connected").toUtf8(),'utf-8'),
self.SOUND_CONNECTED, None)
self.connected = True self.connected = True
if self.actionStatus is not None: if self.actionStatus is not None:
@ -1171,7 +1314,8 @@ class MyForm(QtGui.QMainWindow):
shared.statusIconColor = 'green' shared.statusIconColor = 'green'
if not self.connected: if not self.connected:
self.notifierShow('Bitmessage', unicode(_translate( self.notifierShow('Bitmessage', unicode(_translate(
"MainWindow", "Connected").toUtf8(),'utf-8')) "MainWindow", "Connected").toUtf8(),'utf-8'),
self.SOUND_CONNECTION_GREEN, None)
self.connected = True self.connected = True
if self.actionStatus is not None: if self.actionStatus is not None:
@ -1278,7 +1422,7 @@ class MyForm(QtGui.QMainWindow):
self.ui.tableWidgetInbox.item(i, 0).setTextColor(QtGui.QColor(137, 04, 177)) self.ui.tableWidgetInbox.item(i, 0).setTextColor(QtGui.QColor(137, 04, 177))
else: else:
self.ui.tableWidgetInbox.item( self.ui.tableWidgetInbox.item(
i, 0).setTextColor(QtGui.QColor(0, 0, 0)) i, 0).setTextColor(QApplication.palette().text().color())
def rerenderSentFromLabels(self): def rerenderSentFromLabels(self):
for i in range(self.ui.tableWidgetSent.rowCount()): for i in range(self.ui.tableWidgetSent.rowCount()):
@ -1382,12 +1526,11 @@ class MyForm(QtGui.QMainWindow):
toAddress = addBMIfNotPresent(toAddress) toAddress = addBMIfNotPresent(toAddress)
try: try:
shared.config.get(toAddress, 'enabled') shared.config.get(toAddress, 'enabled')
# The toAddress is one owned by me. We cannot send # The toAddress is one owned by me.
# messages to ourselves without significant changes if not shared.safeConfigGetBoolean(toAddress, 'chan'):
# to the codebase. QMessageBox.about(self, _translate("MainWindow", "Sending to your address"), _translate(
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))
"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
continue
except: except:
pass pass
if addressVersionNumber > 3 or addressVersionNumber <= 1: if addressVersionNumber > 3 or addressVersionNumber <= 1:
@ -1531,6 +1674,16 @@ class MyForm(QtGui.QMainWindow):
def redrawLabelFrom(self, index): def redrawLabelFrom(self, index):
self.ui.labelFrom.setText( self.ui.labelFrom.setText(
self.ui.comboBoxSendFrom.itemData(index).toPyObject()) 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): def rerenderComboBoxSendFrom(self):
self.ui.comboBoxSendFrom.clear() self.ui.comboBoxSendFrom.clear()
@ -1647,6 +1800,8 @@ class MyForm(QtGui.QMainWindow):
newItem.setData(Qt.UserRole, str(toAddress)) newItem.setData(Qt.UserRole, str(toAddress))
if shared.safeConfigGetBoolean(str(toAddress), 'mailinglist'): if shared.safeConfigGetBoolean(str(toAddress), 'mailinglist'):
newItem.setTextColor(QtGui.QColor(137, 04, 177)) 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.insertRow(0)
self.ui.tableWidgetInbox.setItem(0, 0, newItem) self.ui.tableWidgetInbox.setItem(0, 0, newItem)
@ -1654,12 +1809,12 @@ class MyForm(QtGui.QMainWindow):
newItem = QtGui.QTableWidgetItem(unicode(fromAddress, 'utf-8')) newItem = QtGui.QTableWidgetItem(unicode(fromAddress, 'utf-8'))
newItem.setToolTip(unicode(fromAddress, 'utf-8')) newItem.setToolTip(unicode(fromAddress, 'utf-8'))
if shared.config.getboolean('bitmessagesettings', 'showtraynotifications'): 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: else:
newItem = QtGui.QTableWidgetItem(unicode(fromLabel, 'utf-8')) newItem = QtGui.QTableWidgetItem(unicode(fromLabel, 'utf-8'))
newItem.setToolTip(unicode(unicode(fromLabel, 'utf-8'))) newItem.setToolTip(unicode(unicode(fromLabel, 'utf-8')))
if shared.config.getboolean('bitmessagesettings', 'showtraynotifications'): 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.setData(Qt.UserRole, str(fromAddress))
newItem.setFont(font) newItem.setFont(font)
self.ui.tableWidgetInbox.setItem(0, 1, newItem) self.ui.tableWidgetInbox.setItem(0, 1, newItem)
@ -1686,45 +1841,47 @@ class MyForm(QtGui.QMainWindow):
# First we must check to see if the address is already in the # 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 # address book. The user cannot add it again or else it will
# cause problems when updating and deleting the entry. # cause problems when updating and deleting the entry.
shared.sqlLock.acquire() address = addBMIfNotPresent(str(
t = (addBMIfNotPresent(str( self.NewSubscriptionDialogInstance.ui.lineEditSubscriptionAddress.text()))
self.NewSubscriptionDialogInstance.ui.lineEditSubscriptionAddress.text())),) label = self.NewSubscriptionDialogInstance.ui.newsubscriptionlabel.text().toUtf8()
shared.sqlSubmitQueue.put( self.addEntryToAddressBook(address,label)
'''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."))
else: else:
self.statusBar().showMessage(_translate( self.statusBar().showMessage(_translate(
"MainWindow", "The address you entered was invalid. Ignoring it.")) "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) address = addBMIfNotPresent(address)
#This should be handled outside of this function, for error displaying and such, but it must also be checked here. #This should be handled outside of this function, for error displaying and such, but it must also be checked here.
if shared.isAddressInMySubscriptionsList(address): if shared.isAddressInMySubscriptionsList(address):
@ -1761,7 +1918,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.")) 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 return
label = self.NewSubscriptionDialogInstance.ui.newsubscriptionlabel.text().toUtf8() label = self.NewSubscriptionDialogInstance.ui.newsubscriptionlabel.text().toUtf8()
self.addSubscription(label, address) self.addSubscription(address, label)
def loadBlackWhiteList(self): def loadBlackWhiteList(self):
# Initialize the Blacklist or Whitelist table # Initialize the Blacklist or Whitelist table
@ -1816,14 +1973,15 @@ class MyForm(QtGui.QMainWindow):
shared.config.set('bitmessagesettings', 'startintray', str( shared.config.set('bitmessagesettings', 'startintray', str(
self.settingsDialogInstance.ui.checkBoxStartInTray.isChecked())) self.settingsDialogInstance.ui.checkBoxStartInTray.isChecked()))
if int(shared.config.get('bitmessagesettings', 'port')) != int(self.settingsDialogInstance.ui.lineEditTCPPort.text()): if int(shared.config.get('bitmessagesettings', 'port')) != int(self.settingsDialogInstance.ui.lineEditTCPPort.text()):
QMessageBox.about(self, _translate("MainWindow", "Restart"), _translate( if not shared.safeConfigGetBoolean('bitmessagesettings', 'dontconnect'):
"MainWindow", "You must restart Bitmessage for the port number change to take effect.")) 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( shared.config.set('bitmessagesettings', 'port', str(
self.settingsDialogInstance.ui.lineEditTCPPort.text())) self.settingsDialogInstance.ui.lineEditTCPPort.text()))
if shared.config.get('bitmessagesettings', 'socksproxytype') == 'none' and str(self.settingsDialogInstance.ui.comboBoxProxyType.currentText())[0:5] == 'SOCKS': if shared.config.get('bitmessagesettings', 'socksproxytype') == 'none' and str(self.settingsDialogInstance.ui.comboBoxProxyType.currentText())[0:5] == 'SOCKS':
if shared.statusIconColor != 'red': if shared.statusIconColor != 'red':
QMessageBox.about(self, _translate("MainWindow", "Restart"), _translate( 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': if shared.config.get('bitmessagesettings', 'socksproxytype')[0:5] == 'SOCKS' and str(self.settingsDialogInstance.ui.comboBoxProxyType.currentText()) == 'none':
self.statusBar().showMessage('') self.statusBar().showMessage('')
shared.config.set('bitmessagesettings', 'socksproxytype', str( shared.config.set('bitmessagesettings', 'socksproxytype', str(
@ -2016,13 +2174,16 @@ class MyForm(QtGui.QMainWindow):
currentRow = self.ui.tableWidgetYourIdentities.currentRow() currentRow = self.ui.tableWidgetYourIdentities.currentRow()
addressAtCurrentRow = str( addressAtCurrentRow = str(
self.ui.tableWidgetYourIdentities.item(currentRow, 1).text()) self.ui.tableWidgetYourIdentities.item(currentRow, 1).text())
if shared.safeConfigGetBoolean(addressAtCurrentRow, 'chan'):
return
if self.dialog.ui.radioButtonBehaveNormalAddress.isChecked(): if self.dialog.ui.radioButtonBehaveNormalAddress.isChecked():
shared.config.set(str( shared.config.set(str(
addressAtCurrentRow), 'mailinglist', 'false') addressAtCurrentRow), 'mailinglist', 'false')
# Set the color to either black or grey # Set the color to either black or grey
if shared.config.getboolean(addressAtCurrentRow, 'enabled'): if shared.config.getboolean(addressAtCurrentRow, 'enabled'):
self.ui.tableWidgetYourIdentities.item( self.ui.tableWidgetYourIdentities.item(
currentRow, 1).setTextColor(QtGui.QColor(0, 0, 0)) currentRow, 1).setTextColor(QApplication.palette()
.text().color())
else: else:
self.ui.tableWidgetYourIdentities.item( self.ui.tableWidgetYourIdentities.item(
currentRow, 1).setTextColor(QtGui.QColor(128, 128, 128)) currentRow, 1).setTextColor(QtGui.QColor(128, 128, 128))
@ -2049,12 +2210,6 @@ class MyForm(QtGui.QMainWindow):
# address.' # address.'
streamNumberForAddress = addressStream( streamNumberForAddress = addressStream(
self.dialog.ui.comboBoxExisting.currentText()) 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( shared.addressGeneratorQueue.put(('createRandomAddress', 3, streamNumberForAddress, str(
self.dialog.ui.newaddresslabel.text().toUtf8()), 1, "", self.dialog.ui.checkBoxEighteenByteRipe.isChecked())) self.dialog.ui.newaddresslabel.text().toUtf8()), 1, "", self.dialog.ui.checkBoxEighteenByteRipe.isChecked()))
else: else:
@ -2066,11 +2221,6 @@ class MyForm(QtGui.QMainWindow):
"MainWindow", "Choose a passphrase"), _translate("MainWindow", "You really do need a passphrase.")) "MainWindow", "Choose a passphrase"), _translate("MainWindow", "You really do need a passphrase."))
else: else:
streamNumberForAddress = 1 # this will eventually have to be replaced by logic to determine the most available stream number. 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( 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())) ), self.dialog.ui.lineEditPassphrase.text().toUtf8(), self.dialog.ui.checkBoxEighteenByteRipe.isChecked()))
else: else:
@ -2147,6 +2297,7 @@ class MyForm(QtGui.QMainWindow):
self.ui.labelFrom.setText('') self.ui.labelFrom.setText('')
else: else:
self.ui.labelFrom.setText(toAddressAtCurrentInboxRow) self.ui.labelFrom.setText(toAddressAtCurrentInboxRow)
self.setBroadcastEnablementDependingOnWhetherThisIsAChanAddress(toAddressAtCurrentInboxRow)
self.ui.lineEditTo.setText(str(fromAddressAtCurrentInboxRow)) self.ui.lineEditTo.setText(str(fromAddressAtCurrentInboxRow))
self.ui.comboBoxSendFrom.setCurrentIndex(0) self.ui.comboBoxSendFrom.setCurrentIndex(0)
# self.ui.comboBoxSendFrom.setEditText(str(self.ui.tableWidgetInbox.item(currentInboxRow,0).text)) # self.ui.comboBoxSendFrom.setEditText(str(self.ui.tableWidgetInbox.item(currentInboxRow,0).text))
@ -2370,7 +2521,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.")) 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 continue
labelAtCurrentRow = self.ui.tableWidgetAddressBook.item(currentRow,0).text().toUtf8() labelAtCurrentRow = self.ui.tableWidgetAddressBook.item(currentRow,0).text().toUtf8()
self.addSubscription(labelAtCurrentRow, addressAtCurrentRow) self.addSubscription(addressAtCurrentRow, labelAtCurrentRow)
self.ui.tabWidget.setCurrentIndex(4) self.ui.tabWidget.setCurrentIndex(4)
def on_context_menuAddressBook(self, point): def on_context_menuAddressBook(self, point):
@ -2422,9 +2573,9 @@ class MyForm(QtGui.QMainWindow):
shared.sqlSubmitQueue.put('commit') shared.sqlSubmitQueue.put('commit')
shared.sqlLock.release() shared.sqlLock.release()
self.ui.tableWidgetSubscriptions.item( self.ui.tableWidgetSubscriptions.item(
currentRow, 0).setTextColor(QtGui.QColor(0, 0, 0)) currentRow, 0).setTextColor(QApplication.palette().text().color())
self.ui.tableWidgetSubscriptions.item( self.ui.tableWidgetSubscriptions.item(
currentRow, 1).setTextColor(QtGui.QColor(0, 0, 0)) currentRow, 1).setTextColor(QApplication.palette().text().color())
shared.reloadBroadcastSendersForWhichImWatching() shared.reloadBroadcastSendersForWhichImWatching()
def on_action_SubscriptionsDisable(self): def on_action_SubscriptionsDisable(self):
@ -2493,9 +2644,9 @@ class MyForm(QtGui.QMainWindow):
addressAtCurrentRow = self.ui.tableWidgetBlacklist.item( addressAtCurrentRow = self.ui.tableWidgetBlacklist.item(
currentRow, 1).text() currentRow, 1).text()
self.ui.tableWidgetBlacklist.item( self.ui.tableWidgetBlacklist.item(
currentRow, 0).setTextColor(QtGui.QColor(0, 0, 0)) currentRow, 0).setTextColor(QApplication.palette().text().color())
self.ui.tableWidgetBlacklist.item( self.ui.tableWidgetBlacklist.item(
currentRow, 1).setTextColor(QtGui.QColor(0, 0, 0)) currentRow, 1).setTextColor(QApplication.palette().text().color())
t = (str(addressAtCurrentRow),) t = (str(addressAtCurrentRow),)
shared.sqlLock.acquire() shared.sqlLock.acquire()
if shared.config.get('bitmessagesettings', 'blackwhitelist') == 'black': if shared.config.get('bitmessagesettings', 'blackwhitelist') == 'black':
@ -2546,13 +2697,15 @@ class MyForm(QtGui.QMainWindow):
with open(shared.appdata + 'keys.dat', 'wb') as configfile: with open(shared.appdata + 'keys.dat', 'wb') as configfile:
shared.config.write(configfile) shared.config.write(configfile)
self.ui.tableWidgetYourIdentities.item( self.ui.tableWidgetYourIdentities.item(
currentRow, 0).setTextColor(QtGui.QColor(0, 0, 0)) currentRow, 0).setTextColor(QApplication.palette().text().color())
self.ui.tableWidgetYourIdentities.item( self.ui.tableWidgetYourIdentities.item(
currentRow, 1).setTextColor(QtGui.QColor(0, 0, 0)) currentRow, 1).setTextColor(QApplication.palette().text().color())
self.ui.tableWidgetYourIdentities.item( self.ui.tableWidgetYourIdentities.item(
currentRow, 2).setTextColor(QtGui.QColor(0, 0, 0)) currentRow, 2).setTextColor(QApplication.palette().text().color())
if shared.safeConfigGetBoolean(addressAtCurrentRow, 'mailinglist'): if shared.safeConfigGetBoolean(addressAtCurrentRow, 'mailinglist'):
self.ui.tableWidgetYourIdentities.item(currentRow, 1).setTextColor(QtGui.QColor(137, 04, 177)) 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() shared.reloadMyAddressHashes()
def on_action_YourIdentitiesDisable(self): def on_action_YourIdentitiesDisable(self):
@ -2721,11 +2874,14 @@ class MyForm(QtGui.QMainWindow):
def writeNewAddressToTable(self, label, address, streamNumber): def writeNewAddressToTable(self, label, address, streamNumber):
self.ui.tableWidgetYourIdentities.setSortingEnabled(False) self.ui.tableWidgetYourIdentities.setSortingEnabled(False)
self.ui.tableWidgetYourIdentities.insertRow(0) self.ui.tableWidgetYourIdentities.insertRow(0)
newItem = QtGui.QTableWidgetItem(unicode(label, 'utf-8'))
self.ui.tableWidgetYourIdentities.setItem( self.ui.tableWidgetYourIdentities.setItem(
0, 0, QtGui.QTableWidgetItem(unicode(label, 'utf-8'))) 0, 0, newItem)
newItem = QtGui.QTableWidgetItem(address) newItem = QtGui.QTableWidgetItem(address)
newItem.setFlags( newItem.setFlags(
QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) 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) self.ui.tableWidgetYourIdentities.setItem(0, 1, newItem)
newItem = QtGui.QTableWidgetItem(streamNumber) newItem = QtGui.QTableWidgetItem(streamNumber)
newItem.setFlags( newItem.setFlags(
@ -2751,7 +2907,15 @@ class helpDialog(QtGui.QDialog):
self.parent = parent self.parent = parent
self.ui.labelHelpURI.setOpenExternalLinks(True) self.ui.labelHelpURI.setOpenExternalLinks(True)
QtGui.QWidget.resize(self, QtGui.QWidget.sizeHint(self)) 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): class aboutDialog(QtGui.QDialog):
@ -2772,7 +2936,6 @@ class regenerateAddressesDialog(QtGui.QDialog):
self.parent = parent self.parent = parent
QtGui.QWidget.resize(self, QtGui.QWidget.sizeHint(self)) QtGui.QWidget.resize(self, QtGui.QWidget.sizeHint(self))
class settingsDialog(QtGui.QDialog): class settingsDialog(QtGui.QDialog):
def __init__(self, parent): def __init__(self, parent):
@ -2963,17 +3126,23 @@ class SpecialAddressBehaviorDialog(QtGui.QDialog):
currentRow = parent.ui.tableWidgetYourIdentities.currentRow() currentRow = parent.ui.tableWidgetYourIdentities.currentRow()
addressAtCurrentRow = str( addressAtCurrentRow = str(
parent.ui.tableWidgetYourIdentities.item(currentRow, 1).text()) parent.ui.tableWidgetYourIdentities.item(currentRow, 1).text())
if shared.safeConfigGetBoolean(addressAtCurrentRow, 'mailinglist'): if not shared.safeConfigGetBoolean(addressAtCurrentRow, 'chan'):
self.ui.radioButtonBehaviorMailingList.click() if shared.safeConfigGetBoolean(addressAtCurrentRow, 'mailinglist'):
else: self.ui.radioButtonBehaviorMailingList.click()
self.ui.radioButtonBehaveNormalAddress.click() else:
try: self.ui.radioButtonBehaveNormalAddress.click()
mailingListName = shared.config.get( try:
addressAtCurrentRow, 'mailinglistname') mailingListName = shared.config.get(
except: addressAtCurrentRow, 'mailinglistname')
mailingListName = '' except:
self.ui.lineEditMailingListName.setText( mailingListName = ''
unicode(mailingListName, 'utf-8')) 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)) QtGui.QWidget.resize(self, QtGui.QWidget.sizeHint(self))
@ -3032,11 +3201,11 @@ class NewAddressDialog(QtGui.QDialog):
self.ui.groupBoxDeterministic.setHidden(True) self.ui.groupBoxDeterministic.setHidden(True)
QtGui.QWidget.resize(self, QtGui.QWidget.sizeHint(self)) QtGui.QWidget.resize(self, QtGui.QWidget.sizeHint(self))
class NewChanDialog(QtGui.QDialog): class newChanDialog(QtGui.QDialog):
def __init__(self, parent): def __init__(self, parent):
QtGui.QWidget.__init__(self, parent) QtGui.QWidget.__init__(self, parent)
self.ui = Ui_NewChanDialog() self.ui = Ui_newChanDialog()
self.ui.setupUi(self) self.ui.setupUi(self)
self.parent = parent self.parent = parent
self.ui.groupBoxCreateChan.setHidden(True) self.ui.groupBoxCreateChan.setHidden(True)
@ -3158,6 +3327,8 @@ def run():
myapp.appIndicatorInit(app) myapp.appIndicatorInit(app)
myapp.ubuntuMessagingMenuInit() myapp.ubuntuMessagingMenuInit()
myapp.notifierInit() myapp.notifierInit()
if shared.safeConfigGetBoolean('bitmessagesettings', 'dontconnect'):
myapp.showConnectDialog() # ask the user if we may connect
if gevent is None: if gevent is None:
sys.exit(app.exec_()) sys.exit(app.exec_())
else: else:

View File

@ -2,7 +2,7 @@
# Form implementation generated from reading ui file 'bitmessageui.ui' # Form implementation generated from reading ui file 'bitmessageui.ui'
# #
# Created: Wed Jul 17 18:15:14 2013 # Created: Sat Jul 27 08:23:55 2013
# by: PyQt4 UI code generator 4.9.3 # by: PyQt4 UI code generator 4.9.3
# #
# WARNING! All changes made in this file will be lost! # WARNING! All changes made in this file will be lost!
@ -450,9 +450,12 @@ class Ui_MainWindow(object):
self.actionRegenerateDeterministicAddresses.setObjectName(_fromUtf8("actionRegenerateDeterministicAddresses")) self.actionRegenerateDeterministicAddresses.setObjectName(_fromUtf8("actionRegenerateDeterministicAddresses"))
self.actionDeleteAllTrashedMessages = QtGui.QAction(MainWindow) self.actionDeleteAllTrashedMessages = QtGui.QAction(MainWindow)
self.actionDeleteAllTrashedMessages.setObjectName(_fromUtf8("actionDeleteAllTrashedMessages")) self.actionDeleteAllTrashedMessages.setObjectName(_fromUtf8("actionDeleteAllTrashedMessages"))
self.actionJoinChan = QtGui.QAction(MainWindow)
self.actionJoinChan.setObjectName(_fromUtf8("actionJoinChan"))
self.menuFile.addAction(self.actionManageKeys) self.menuFile.addAction(self.actionManageKeys)
self.menuFile.addAction(self.actionDeleteAllTrashedMessages) self.menuFile.addAction(self.actionDeleteAllTrashedMessages)
self.menuFile.addAction(self.actionRegenerateDeterministicAddresses) self.menuFile.addAction(self.actionRegenerateDeterministicAddresses)
self.menuFile.addAction(self.actionJoinChan)
self.menuFile.addAction(self.actionExit) self.menuFile.addAction(self.actionExit)
self.menuSettings.addAction(self.actionSettings) self.menuSettings.addAction(self.actionSettings)
self.menuHelp.addAction(self.actionHelp) self.menuHelp.addAction(self.actionHelp)
@ -597,5 +600,6 @@ class Ui_MainWindow(object):
self.actionSettings.setText(QtGui.QApplication.translate("MainWindow", "Settings", None, QtGui.QApplication.UnicodeUTF8)) self.actionSettings.setText(QtGui.QApplication.translate("MainWindow", "Settings", None, QtGui.QApplication.UnicodeUTF8))
self.actionRegenerateDeterministicAddresses.setText(QtGui.QApplication.translate("MainWindow", "Regenerate deterministic addresses", None, QtGui.QApplication.UnicodeUTF8)) self.actionRegenerateDeterministicAddresses.setText(QtGui.QApplication.translate("MainWindow", "Regenerate deterministic addresses", None, QtGui.QApplication.UnicodeUTF8))
self.actionDeleteAllTrashedMessages.setText(QtGui.QApplication.translate("MainWindow", "Delete all trashed messages", None, QtGui.QApplication.UnicodeUTF8)) self.actionDeleteAllTrashedMessages.setText(QtGui.QApplication.translate("MainWindow", "Delete all trashed messages", None, QtGui.QApplication.UnicodeUTF8))
self.actionJoinChan.setText(QtGui.QApplication.translate("MainWindow", "Join / Create chan", None, QtGui.QApplication.UnicodeUTF8))
import bitmessage_icons_rc import bitmessage_icons_rc

View File

@ -14,7 +14,7 @@
<string>Bitmessage</string> <string>Bitmessage</string>
</property> </property>
<property name="windowIcon"> <property name="windowIcon">
<iconset> <iconset resource="bitmessage_icons.qrc">
<normaloff>:/newPrefix/images/can-icon-24px.png</normaloff>:/newPrefix/images/can-icon-24px.png</iconset> <normaloff>:/newPrefix/images/can-icon-24px.png</normaloff>:/newPrefix/images/can-icon-24px.png</iconset>
</property> </property>
<property name="tabShape"> <property name="tabShape">
@ -61,7 +61,7 @@
</property> </property>
<widget class="QWidget" name="inbox"> <widget class="QWidget" name="inbox">
<attribute name="icon"> <attribute name="icon">
<iconset> <iconset resource="bitmessage_icons.qrc">
<normaloff>:/newPrefix/images/inbox.png</normaloff>:/newPrefix/images/inbox.png</iconset> <normaloff>:/newPrefix/images/inbox.png</normaloff>:/newPrefix/images/inbox.png</iconset>
</attribute> </attribute>
<attribute name="title"> <attribute name="title">
@ -188,7 +188,7 @@
</widget> </widget>
<widget class="QWidget" name="send"> <widget class="QWidget" name="send">
<attribute name="icon"> <attribute name="icon">
<iconset> <iconset resource="bitmessage_icons.qrc">
<normaloff>:/newPrefix/images/send.png</normaloff>:/newPrefix/images/send.png</iconset> <normaloff>:/newPrefix/images/send.png</normaloff>:/newPrefix/images/send.png</iconset>
</attribute> </attribute>
<attribute name="title"> <attribute name="title">
@ -358,7 +358,7 @@ p, li { white-space: pre-wrap; }
</widget> </widget>
<widget class="QWidget" name="sent"> <widget class="QWidget" name="sent">
<attribute name="icon"> <attribute name="icon">
<iconset> <iconset resource="bitmessage_icons.qrc">
<normaloff>:/newPrefix/images/sent.png</normaloff>:/newPrefix/images/sent.png</iconset> <normaloff>:/newPrefix/images/sent.png</normaloff>:/newPrefix/images/sent.png</iconset>
</attribute> </attribute>
<attribute name="title"> <attribute name="title">
@ -478,7 +478,7 @@ p, li { white-space: pre-wrap; }
</widget> </widget>
<widget class="QWidget" name="youridentities"> <widget class="QWidget" name="youridentities">
<attribute name="icon"> <attribute name="icon">
<iconset> <iconset resource="bitmessage_icons.qrc">
<normaloff>:/newPrefix/images/identities.png</normaloff>:/newPrefix/images/identities.png</iconset> <normaloff>:/newPrefix/images/identities.png</normaloff>:/newPrefix/images/identities.png</iconset>
</attribute> </attribute>
<attribute name="title"> <attribute name="title">
@ -578,7 +578,7 @@ p, li { white-space: pre-wrap; }
</widget> </widget>
<widget class="QWidget" name="subscriptions"> <widget class="QWidget" name="subscriptions">
<attribute name="icon"> <attribute name="icon">
<iconset> <iconset resource="bitmessage_icons.qrc">
<normaloff>:/newPrefix/images/subscriptions.png</normaloff>:/newPrefix/images/subscriptions.png</iconset> <normaloff>:/newPrefix/images/subscriptions.png</normaloff>:/newPrefix/images/subscriptions.png</iconset>
</attribute> </attribute>
<attribute name="title"> <attribute name="title">
@ -663,7 +663,7 @@ p, li { white-space: pre-wrap; }
</widget> </widget>
<widget class="QWidget" name="addressbook"> <widget class="QWidget" name="addressbook">
<attribute name="icon"> <attribute name="icon">
<iconset> <iconset resource="bitmessage_icons.qrc">
<normaloff>:/newPrefix/images/addressbook.png</normaloff>:/newPrefix/images/addressbook.png</iconset> <normaloff>:/newPrefix/images/addressbook.png</normaloff>:/newPrefix/images/addressbook.png</iconset>
</attribute> </attribute>
<attribute name="title"> <attribute name="title">
@ -745,7 +745,7 @@ p, li { white-space: pre-wrap; }
</widget> </widget>
<widget class="QWidget" name="blackwhitelist"> <widget class="QWidget" name="blackwhitelist">
<attribute name="icon"> <attribute name="icon">
<iconset> <iconset resource="bitmessage_icons.qrc">
<normaloff>:/newPrefix/images/blacklist.png</normaloff>:/newPrefix/images/blacklist.png</iconset> <normaloff>:/newPrefix/images/blacklist.png</normaloff>:/newPrefix/images/blacklist.png</iconset>
</attribute> </attribute>
<attribute name="title"> <attribute name="title">
@ -837,7 +837,7 @@ p, li { white-space: pre-wrap; }
</widget> </widget>
<widget class="QWidget" name="networkstatus"> <widget class="QWidget" name="networkstatus">
<attribute name="icon"> <attribute name="icon">
<iconset> <iconset resource="bitmessage_icons.qrc">
<normaloff>:/newPrefix/images/networkstatus.png</normaloff>:/newPrefix/images/networkstatus.png</iconset> <normaloff>:/newPrefix/images/networkstatus.png</normaloff>:/newPrefix/images/networkstatus.png</iconset>
</attribute> </attribute>
<attribute name="title"> <attribute name="title">
@ -856,7 +856,7 @@ p, li { white-space: pre-wrap; }
<string/> <string/>
</property> </property>
<property name="icon"> <property name="icon">
<iconset> <iconset resource="bitmessage_icons.qrc">
<normaloff>:/newPrefix/images/redicon.png</normaloff>:/newPrefix/images/redicon.png</iconset> <normaloff>:/newPrefix/images/redicon.png</normaloff>:/newPrefix/images/redicon.png</iconset>
</property> </property>
<property name="flat"> <property name="flat">
@ -1033,6 +1033,7 @@ p, li { white-space: pre-wrap; }
<addaction name="actionManageKeys"/> <addaction name="actionManageKeys"/>
<addaction name="actionDeleteAllTrashedMessages"/> <addaction name="actionDeleteAllTrashedMessages"/>
<addaction name="actionRegenerateDeterministicAddresses"/> <addaction name="actionRegenerateDeterministicAddresses"/>
<addaction name="actionJoinChan"/>
<addaction name="actionExit"/> <addaction name="actionExit"/>
</widget> </widget>
<widget class="QMenu" name="menuSettings"> <widget class="QMenu" name="menuSettings">
@ -1106,6 +1107,11 @@ p, li { white-space: pre-wrap; }
<string>Delete all trashed messages</string> <string>Delete all trashed messages</string>
</property> </property>
</action> </action>
<action name="actionJoinChan">
<property name="text">
<string>Join / Create chan</string>
</property>
</action>
</widget> </widget>
<tabstops> <tabstops>
<tabstop>tabWidget</tabstop> <tabstop>tabWidget</tabstop>

View File

@ -0,0 +1,60 @@
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'connect.ui'
#
# 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!
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.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)
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", "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.radioButtonConfigureNetwork.setText(_translate("connectDialog", "Let me configure special network settings first", None))

101
src/bitmessageqt/connect.ui Normal file
View File

@ -0,0 +1,101 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>connectDialog</class>
<widget class="QDialog" name="connectDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>124</height>
</rect>
</property>
<property name="windowTitle">
<string>Bitmessage</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0" colspan="2">
<widget class="QLabel" name="label">
<property name="text">
<string>Bitmessage won't connect to anyone until you let it. </string>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="QRadioButton" name="radioButtonConnectNow">
<property name="text">
<string>Connect now</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="0" colspan="2">
<widget class="QRadioButton" name="radioButtonConfigureNetwork">
<property name="text">
<string>Let me configure special network settings first</string>
</property>
</widget>
</item>
<item row="3" column="0">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>185</width>
<height>24</height>
</size>
</property>
</spacer>
</item>
<item row="3" column="1">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>connectDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>connectDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -2,7 +2,7 @@
# Form implementation generated from reading ui file 'newchandialog.ui' # 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 # by: PyQt4 UI code generator 4.10.2
# #
# WARNING! All changes made in this file will be lost! # WARNING! All changes made in this file will be lost!
@ -23,20 +23,36 @@ except AttributeError:
def _translate(context, text, disambig): def _translate(context, text, disambig):
return QtGui.QApplication.translate(context, text, disambig) return QtGui.QApplication.translate(context, text, disambig)
class Ui_NewChanDialog(object): class Ui_newChanDialog(object):
def setupUi(self, NewChanDialog): def setupUi(self, newChanDialog):
NewChanDialog.setObjectName(_fromUtf8("NewChanDialog")) newChanDialog.setObjectName(_fromUtf8("newChanDialog"))
NewChanDialog.resize(447, 441) newChanDialog.resize(530, 422)
self.formLayout = QtGui.QFormLayout(NewChanDialog) newChanDialog.setMinimumSize(QtCore.QSize(0, 0))
self.formLayout = QtGui.QFormLayout(newChanDialog)
self.formLayout.setObjectName(_fromUtf8("formLayout")) self.formLayout.setObjectName(_fromUtf8("formLayout"))
self.radioButtonCreateChan = QtGui.QRadioButton(NewChanDialog) self.radioButtonCreateChan = QtGui.QRadioButton(newChanDialog)
self.radioButtonCreateChan.setObjectName(_fromUtf8("radioButtonCreateChan")) self.radioButtonCreateChan.setObjectName(_fromUtf8("radioButtonCreateChan"))
self.formLayout.setWidget(0, QtGui.QFormLayout.LabelRole, self.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.setChecked(True)
self.radioButtonJoinChan.setObjectName(_fromUtf8("radioButtonJoinChan")) self.radioButtonJoinChan.setObjectName(_fromUtf8("radioButtonJoinChan"))
self.formLayout.setWidget(1, QtGui.QFormLayout.LabelRole, self.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.groupBoxJoinChan.setObjectName(_fromUtf8("groupBoxJoinChan"))
self.gridLayout_2 = QtGui.QGridLayout(self.groupBoxJoinChan) self.gridLayout_2 = QtGui.QGridLayout(self.groupBoxJoinChan)
self.gridLayout_2.setObjectName(_fromUtf8("gridLayout_2")) self.gridLayout_2.setObjectName(_fromUtf8("gridLayout_2"))
@ -57,43 +73,30 @@ class Ui_NewChanDialog(object):
self.lineEditChanBitmessageAddress.setObjectName(_fromUtf8("lineEditChanBitmessageAddress")) self.lineEditChanBitmessageAddress.setObjectName(_fromUtf8("lineEditChanBitmessageAddress"))
self.gridLayout_2.addWidget(self.lineEditChanBitmessageAddress, 4, 0, 1, 1) self.gridLayout_2.addWidget(self.lineEditChanBitmessageAddress, 4, 0, 1, 1)
self.formLayout.setWidget(3, QtGui.QFormLayout.SpanningRole, self.groupBoxJoinChan) self.formLayout.setWidget(3, QtGui.QFormLayout.SpanningRole, self.groupBoxJoinChan)
self.groupBoxCreateChan = QtGui.QGroupBox(NewChanDialog) spacerItem = QtGui.QSpacerItem(389, 2, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
self.groupBoxCreateChan.setObjectName(_fromUtf8("groupBoxCreateChan")) self.formLayout.setItem(4, QtGui.QFormLayout.FieldRole, spacerItem)
self.gridLayout = QtGui.QGridLayout(self.groupBoxCreateChan) self.buttonBox = QtGui.QDialogButtonBox(newChanDialog)
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)
self.buttonBox.setOrientation(QtCore.Qt.Horizontal) self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Ok) self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Ok)
self.buttonBox.setObjectName(_fromUtf8("buttonBox")) 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) self.retranslateUi(newChanDialog)
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("accepted()")), NewChanDialog.accept) 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.buttonBox, QtCore.SIGNAL(_fromUtf8("rejected()")), newChanDialog.reject)
QtCore.QObject.connect(self.radioButtonJoinChan, QtCore.SIGNAL(_fromUtf8("toggled(bool)")), self.groupBoxJoinChan.setShown) 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.QObject.connect(self.radioButtonCreateChan, QtCore.SIGNAL(_fromUtf8("toggled(bool)")), self.groupBoxCreateChan.setShown)
QtCore.QMetaObject.connectSlotsByName(NewChanDialog) QtCore.QMetaObject.connectSlotsByName(newChanDialog)
def retranslateUi(self, NewChanDialog): def retranslateUi(self, newChanDialog):
NewChanDialog.setWindowTitle(_translate("NewChanDialog", "Dialog", None)) newChanDialog.setWindowTitle(_translate("newChanDialog", "Dialog", None))
self.radioButtonCreateChan.setText(_translate("NewChanDialog", "Create a new chan", None)) self.radioButtonCreateChan.setText(_translate("newChanDialog", "Create a new chan", None))
self.radioButtonJoinChan.setText(_translate("NewChanDialog", "Join a chan", None)) self.radioButtonJoinChan.setText(_translate("newChanDialog", "Join a chan", None))
self.groupBoxJoinChan.setTitle(_translate("NewChanDialog", "Join a chan", None)) self.groupBoxCreateChan.setTitle(_translate("newChanDialog", "Create a chan", None))
self.label.setText(_translate("NewChanDialog", "<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>", 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_2.setText(_translate("NewChanDialog", "Chan name:", None)) self.label_5.setText(_translate("newChanDialog", "Chan name:", None))
self.label_3.setText(_translate("NewChanDialog", "Chan bitmessage address:", None)) self.groupBoxJoinChan.setTitle(_translate("newChanDialog", "Join a chan", None))
self.groupBoxCreateChan.setTitle(_translate("NewChanDialog", "Create a chan", None)) self.label.setText(_translate("newChanDialog", "<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>", 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_2.setText(_translate("newChanDialog", "Chan name:", None))
self.label_5.setText(_translate("NewChanDialog", "Chan name:", None)) self.label_3.setText(_translate("newChanDialog", "Chan bitmessage address:", None))

View File

@ -1,15 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0"> <ui version="4.0">
<class>NewChanDialog</class> <class>newChanDialog</class>
<widget class="QDialog" name="NewChanDialog"> <widget class="QDialog" name="newChanDialog">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>447</width> <width>530</width>
<height>441</height> <height>422</height>
</rect> </rect>
</property> </property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="windowTitle"> <property name="windowTitle">
<string>Dialog</string> <string>Dialog</string>
</property> </property>
@ -31,45 +37,6 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="0" colspan="2">
<widget class="QGroupBox" name="groupBoxJoinChan">
<property name="title">
<string>Join a chan</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;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).&lt;/p&gt;&lt;p&gt;Chans are experimental and are unmoderatable.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Chan name:</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLineEdit" name="lineEditChanNameJoin"/>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Chan bitmessage address:</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLineEdit" name="lineEditChanBitmessageAddress"/>
</item>
</layout>
</widget>
</item>
<item row="2" column="0" colspan="2"> <item row="2" column="0" colspan="2">
<widget class="QGroupBox" name="groupBoxCreateChan"> <widget class="QGroupBox" name="groupBoxCreateChan">
<property name="title"> <property name="title">
@ -99,7 +66,59 @@
</layout> </layout>
</widget> </widget>
</item> </item>
<item row="3" column="0" colspan="2">
<widget class="QGroupBox" name="groupBoxJoinChan">
<property name="title">
<string>Join a chan</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;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.&lt;/p&gt;&lt;p&gt;Chans are experimental and completely unmoderatable.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Chan name:</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLineEdit" name="lineEditChanNameJoin"/>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Chan bitmessage address:</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLineEdit" name="lineEditChanBitmessageAddress"/>
</item>
</layout>
</widget>
</item>
<item row="4" column="1"> <item row="4" column="1">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>389</width>
<height>2</height>
</size>
</property>
</spacer>
</item>
<item row="5" column="1">
<widget class="QDialogButtonBox" name="buttonBox"> <widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
@ -116,7 +135,7 @@
<connection> <connection>
<sender>buttonBox</sender> <sender>buttonBox</sender>
<signal>accepted()</signal> <signal>accepted()</signal>
<receiver>NewChanDialog</receiver> <receiver>newChanDialog</receiver>
<slot>accept()</slot> <slot>accept()</slot>
<hints> <hints>
<hint type="sourcelabel"> <hint type="sourcelabel">
@ -132,7 +151,7 @@
<connection> <connection>
<sender>buttonBox</sender> <sender>buttonBox</sender>
<signal>rejected()</signal> <signal>rejected()</signal>
<receiver>NewChanDialog</receiver> <receiver>newChanDialog</receiver>
<slot>reject()</slot> <slot>reject()</slot>
<hints> <hints>
<hint type="sourcelabel"> <hint type="sourcelabel">

View File

@ -21,7 +21,7 @@ if sys.platform == 'darwin':
setup_requires=['py2app'], setup_requires=['py2app'],
app=[mainscript], app=[mainscript],
options=dict(py2app=dict(argv_emulation=True, options=dict(py2app=dict(argv_emulation=True,
includes = ['PyQt4.QtCore','PyQt4.QtGui', 'sip'], includes = ['PyQt4.QtCore','PyQt4.QtGui', 'sip', 'sqlite3'],
packages = ['bitmessageqt'], packages = ['bitmessageqt'],
frameworks = ['/usr/local/opt/openssl/lib/libcrypto.dylib'], frameworks = ['/usr/local/opt/openssl/lib/libcrypto.dylib'],
iconfile='images/bitmessage.icns', iconfile='images/bitmessage.icns',

View File

@ -28,6 +28,8 @@ class addressGenerator(threading.Thread):
elif queueValue[0] == 'joinChan': elif queueValue[0] == 'joinChan':
command, chanAddress, label, deterministicPassphrase = queueValue command, chanAddress, label, deterministicPassphrase = queueValue
eighteenByteRipe = False eighteenByteRipe = False
addressVersionNumber = decodeAddress(chanAddress)[1]
streamNumber = decodeAddress(chanAddress)[2]
numberOfAddressesToMake = 1 numberOfAddressesToMake = 1
elif len(queueValue) == 7: elif len(queueValue) == 7:
command, addressVersionNumber, streamNumber, label, numberOfAddressesToMake, deterministicPassphrase, eighteenByteRipe = queueValue 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 command, addressVersionNumber, streamNumber, label, numberOfAddressesToMake, deterministicPassphrase, eighteenByteRipe, nonceTrialsPerByte, payloadLengthExtraBytes = queueValue
else: else:
sys.stderr.write( 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: if addressVersionNumber < 3 or addressVersionNumber > 3:
sys.stderr.write( 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) '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: with open(shared.appdata + 'keys.dat', 'wb') as configfile:
shared.config.write(configfile) shared.config.write(configfile)
# It may be the case that this address is being generated # The API and the join and create Chan functionality
# as a result of a call to the API. Let us put the result # both need information back from the address generator.
# in the necessary queue.
shared.apiAddressGeneratorReturnQueue.put(address) shared.apiAddressGeneratorReturnQueue.put(address)
shared.UISignalQueue.put(( shared.UISignalQueue.put((
@ -128,7 +129,7 @@ class addressGenerator(threading.Thread):
label, address, streamNumber))) label, address, streamNumber)))
shared.reloadMyAddressHashes() shared.reloadMyAddressHashes()
shared.workerQueue.put(( shared.workerQueue.put((
'doPOWForMyV3Pubkey', ripe.digest())) 'sendOutOrStoreMyV3Pubkey', ripe.digest()))
elif command == 'createDeterministicAddresses' or command == 'getDeterministicAddress' or command == 'createChan' or command == 'joinChan': elif command == 'createDeterministicAddresses' or command == 'getDeterministicAddress' or command == 'createChan' or command == 'joinChan':
if len(deterministicPassphrase) == 0: 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 we are joining an existing chan, let us check to make sure it matches the provided Bitmessage address
if command == 'joinChan': if command == 'joinChan':
if address != chanAddress: if address != chanAddress:
#todo: show an error message in the UI shared.apiAddressGeneratorReturnQueue.put('chan name does not match address')
shared.apiAddressGeneratorReturnQueue.put('API Error 0018: Chan name does not match address.')
saveAddressToDisk = False saveAddressToDisk = False
if command == 'getDeterministicAddress': if command == 'getDeterministicAddress':
saveAddressToDisk = False saveAddressToDisk = False
@ -210,8 +210,13 @@ class addressGenerator(threading.Thread):
privEncryptionKeyWIF = arithmetic.changebase( privEncryptionKeyWIF = arithmetic.changebase(
privEncryptionKey + checksum, 256, 58) privEncryptionKey + checksum, 256, 58)
addressAlreadyExists = False
try: try:
shared.config.add_section(address) shared.config.add_section(address)
except:
print address, 'already exists. Not adding it again.'
addressAlreadyExists = True
if not addressAlreadyExists:
print 'label:', label print 'label:', label
shared.config.set(address, 'label', label) shared.config.set(address, 'label', label)
shared.config.set(address, 'enabled', 'true') shared.config.set(address, 'enabled', 'true')
@ -237,17 +242,13 @@ class addressGenerator(threading.Thread):
potentialPrivEncryptionKey.encode('hex')) potentialPrivEncryptionKey.encode('hex'))
shared.myAddressesByHash[ shared.myAddressesByHash[
ripe.digest()] = address ripe.digest()] = address
#todo: don't send out pubkey if dealing with a chan; save in pubkeys table instead.
shared.workerQueue.put(( shared.workerQueue.put((
'doPOWForMyV3Pubkey', ripe.digest())) 'sendOutOrStoreMyV3Pubkey', ripe.digest())) # If this is a chan address,
except: # the worker thread won't send out the pubkey over the network.
print address, 'already exists. Not adding it again.'
# Done generating addresses. # Done generating addresses.
if command == 'createDeterministicAddresses': if command == 'createDeterministicAddresses' or command == 'joinChan' or command == 'createChan':
# 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.
shared.apiAddressGeneratorReturnQueue.put( shared.apiAddressGeneratorReturnQueue.put(
listOfNewAddressesToSendOutThroughTheAPI) listOfNewAddressesToSendOutThroughTheAPI)
shared.UISignalQueue.put(( shared.UISignalQueue.put((

View File

@ -7,7 +7,6 @@ import socket
import sys import sys
import tr import tr
#import bitmessagemain
from class_sendDataThread import * from class_sendDataThread import *
from class_receiveDataThread import * from class_receiveDataThread import *
@ -24,7 +23,8 @@ class outgoingSynSender(threading.Thread):
self.selfInitiatedConnections = selfInitiatedConnections self.selfInitiatedConnections = selfInitiatedConnections
def run(self): def run(self):
time.sleep(1) while shared.safeConfigGetBoolean('bitmessagesettings', 'dontconnect'):
time.sleep(2)
while True: while True:
while len(self.selfInitiatedConnections[self.streamNumber]) >= 8: # maximum number of outgoing connections = 8 while len(self.selfInitiatedConnections[self.streamNumber]) >= 8: # maximum number of outgoing connections = 8
time.sleep(10) time.sleep(10)

View File

@ -1412,34 +1412,39 @@ class receiveDataThread(threading.Thread):
if len(requestedHash) != 20: if len(requestedHash) != 20:
print 'The length of the requested hash is not 20 bytes. Something is wrong. Ignoring.' print 'The length of the requested hash is not 20 bytes. Something is wrong. Ignoring.'
return 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 requestedHash in shared.myAddressesByHash: # if this address hash is one of mine
if decodeAddress(shared.myAddressesByHash[requestedHash])[1] != requestedAddressVersionNumber: if decodeAddress(shared.myAddressesByHash[requestedHash])[1] != requestedAddressVersionNumber:
with shared.printLock: with shared.printLock:
sys.stderr.write( 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 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: try:
lastPubkeySendTime = int(shared.config.get( lastPubkeySendTime = int(shared.config.get(
shared.myAddressesByHash[requestedHash], 'lastpubkeysendtime')) shared.myAddressesByHash[requestedHash], 'lastpubkeysendtime'))
except: except:
lastPubkeySendTime = 0 lastPubkeySendTime = 0
if lastPubkeySendTime < time.time() - shared.lengthOfTimeToHoldOnToAllPubkeys: # If the last time we sent our pubkey was at least 28 days ago... 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. 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:
with shared.printLock: 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 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: else:
with shared.printLock: with shared.printLock:
print 'This getpubkey request is not for any of my keys.' print 'This getpubkey request is not for any of my keys.'

View File

@ -3,6 +3,7 @@ import shared
import socket import socket
from class_sendDataThread import * from class_sendDataThread import *
from class_receiveDataThread import * from class_receiveDataThread import *
import helper_bootstrap
# Only one singleListener thread will ever exist. It creates the # Only one singleListener thread will ever exist. It creates the
# receiveDataThread and sendDataThread for each incoming connection. Note # receiveDataThread and sendDataThread for each incoming connection. Note
@ -21,12 +22,15 @@ class singleListener(threading.Thread):
self.selfInitiatedConnections = selfInitiatedConnections self.selfInitiatedConnections = selfInitiatedConnections
def run(self): 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 # 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 # SOCKS proxy, unless they have configured otherwise. If they eventually select
# proxy 'none' or configure SOCKS listening then this will start listening for # proxy 'none' or configure SOCKS listening then this will start listening for
# connections. # connections.
while shared.config.get('bitmessagesettings', 'socksproxytype')[0:5] == 'SOCKS' and not shared.config.getboolean('bitmessagesettings', 'sockslisten'): while shared.config.get('bitmessagesettings', 'socksproxytype')[0:5] == 'SOCKS' and not shared.config.getboolean('bitmessagesettings', 'sockslisten'):
time.sleep(300) time.sleep(5)
with shared.printLock: with shared.printLock:
print 'Listening for incoming connections.' print 'Listening for incoming connections.'

View File

@ -72,8 +72,8 @@ class singleWorker(threading.Thread):
self.sendBroadcast() self.sendBroadcast()
elif command == 'doPOWForMyV2Pubkey': elif command == 'doPOWForMyV2Pubkey':
self.doPOWForMyV2Pubkey(data) self.doPOWForMyV2Pubkey(data)
elif command == 'doPOWForMyV3Pubkey': elif command == 'sendOutOrStoreMyV3Pubkey':
self.doPOWForMyV3Pubkey(data) self.sendOutOrStoreMyV3Pubkey(data)
"""elif command == 'newpubkey': """elif command == 'newpubkey':
toAddressVersion,toStreamNumber,toRipe = data toAddressVersion,toStreamNumber,toRipe = data
if toRipe in shared.neededPubkeys: if toRipe in shared.neededPubkeys:
@ -173,7 +173,11 @@ class singleWorker(threading.Thread):
with open(shared.appdata + 'keys.dat', 'wb') as configfile: with open(shared.appdata + 'keys.dat', 'wb') as configfile:
shared.config.write(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] myAddress = shared.myAddressesByHash[hash]
status, addressVersionNumber, streamNumber, hash = decodeAddress( status, addressVersionNumber, streamNumber, hash = decodeAddress(
myAddress) myAddress)
@ -192,7 +196,7 @@ class singleWorker(threading.Thread):
except Exception as err: except Exception as err:
with shared.printLock: with shared.printLock:
sys.stderr.write( 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 return
@ -216,34 +220,40 @@ class singleWorker(threading.Thread):
payload += encodeVarint(len(signature)) payload += encodeVarint(len(signature))
payload += signature payload += signature
# Do the POW for this pubkey message if not shared.safeConfigGetBoolean(myAddress, 'chan'):
target = 2 ** 64 / ((len(payload) + shared.networkDefaultPayloadLengthExtraBytes + # Do the POW for this pubkey message
8) * shared.networkDefaultProofOfWorkNonceTrialsPerByte) target = 2 ** 64 / ((len(payload) + shared.networkDefaultPayloadLengthExtraBytes +
print '(For pubkey message) Doing proof of work...' 8) * shared.networkDefaultProofOfWorkNonceTrialsPerByte)
initialHash = hashlib.sha512(payload).digest() print '(For pubkey message) Doing proof of work...'
trialValue, nonce = proofofwork.run(target, initialHash) initialHash = hashlib.sha512(payload).digest()
print '(For pubkey message) Found proof of work', trialValue, 'Nonce:', nonce trialValue, nonce = proofofwork.run(target, initialHash)
print '(For pubkey message) Found proof of work', trialValue, 'Nonce:', nonce
payload = pack('>Q', nonce) + payload payload = pack('>Q', nonce) + payload
"""t = (hash,payload,embeddedTime,'no') inventoryHash = calculateInventoryHash(payload)
shared.sqlLock.acquire() objectType = 'pubkey'
shared.sqlSubmitQueue.put('''INSERT INTO pubkeys VALUES (?,?,?,?)''') shared.inventory[inventoryHash] = (
shared.sqlSubmitQueue.put(t) objectType, streamNumber, payload, embeddedTime)
queryreturn = shared.sqlReturnQueue.get()
shared.sqlSubmitQueue.put('commit')
shared.sqlLock.release()"""
inventoryHash = calculateInventoryHash(payload) with shared.printLock:
objectType = 'pubkey' print 'broadcasting inv with hash:', inventoryHash.encode('hex')
shared.inventory[inventoryHash] = (
objectType, streamNumber, payload, embeddedTime)
with shared.printLock: shared.broadcastToSendDataQueues((
print 'broadcasting inv with hash:', inventoryHash.encode('hex') streamNumber, 'sendinv', inventoryHash))
shared.UISignalQueue.put(('updateStatusBar', ''))
shared.broadcastToSendDataQueues(( # If this is a chan address then we won't send out the pubkey over the
streamNumber, 'sendinv', inventoryHash)) # network but rather will only store it in our pubkeys table so that
shared.UISignalQueue.put(('updateStatusBar', '')) # 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( shared.config.set(
myAddress, 'lastpubkeysendtime', str(int(time.time()))) myAddress, 'lastpubkeysendtime', str(int(time.time())))
with open(shared.appdata + 'keys.dat', 'wb') as configfile: with open(shared.appdata + 'keys.dat', 'wb') as configfile:
@ -722,8 +732,13 @@ class singleWorker(threading.Thread):
subject + '\n' + 'Body:' + message subject + '\n' + 'Body:' + message
payload += encodeVarint(len(messageToTransmit)) payload += encodeVarint(len(messageToTransmit))
payload += messageToTransmit payload += messageToTransmit
fullAckPayload = self.generateFullAckMessage( if shared.safeConfigGetBoolean(toaddress, 'chan'):
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. 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 += encodeVarint(len(fullAckPayload))
payload += fullAckPayload payload += fullAckPayload
signature = highlevelcrypto.sign(payload, privSigningKeyHex) signature = highlevelcrypto.sign(payload, privSigningKeyHex)
@ -765,17 +780,26 @@ class singleWorker(threading.Thread):
objectType = 'msg' objectType = 'msg'
shared.inventory[inventoryHash] = ( shared.inventory[inventoryHash] = (
objectType, toStreamNumber, encryptedPayload, int(time.time())) objectType, toStreamNumber, encryptedPayload, int(time.time()))
shared.UISignalQueue.put(('updateSentItemStatusByAckdata', (ackdata, tr.translateText("MainWindow", "Message sent. Waiting on acknowledgement. Sent on %1").arg(unicode( if shared.safeConfigGetBoolean(toaddress, 'chan'):
strftime(shared.config.get('bitmessagesettings', 'timeformat'), localtime(int(time.time()))), 'utf-8'))))) 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') print 'Broadcasting inv for my msg(within sendmsg function):', inventoryHash.encode('hex')
shared.broadcastToSendDataQueues(( shared.broadcastToSendDataQueues((
streamNumber, 'sendinv', inventoryHash)) streamNumber, 'sendinv', inventoryHash))
# Update the status of the message in the 'sent' table to have a # 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() shared.sqlLock.acquire()
t = (inventoryHash,ackdata,) t = (inventoryHash,newStatus,ackdata,)
shared.sqlSubmitQueue.put('''UPDATE sent SET msgid=?, status='msgsent' WHERE ackdata=?''') shared.sqlSubmitQueue.put('''UPDATE sent SET msgid=?, status=? WHERE ackdata=?''')
shared.sqlSubmitQueue.put(t) shared.sqlSubmitQueue.put(t)
queryreturn = shared.sqlReturnQueue.get() queryreturn = shared.sqlReturnQueue.get()
shared.sqlSubmitQueue.put('commit') shared.sqlSubmitQueue.put('commit')

View File

@ -186,6 +186,9 @@ class sqlThread(threading.Thread):
self.cur.execute( self.cur.execute(
'''update sent set status='broadcastqueued' where status='broadcastpending' ''') '''update sent set status='broadcastqueued' where status='broadcastpending' ''')
self.conn.commit() self.conn.commit()
if not shared.config.has_option('bitmessagesettings', 'sockslisten'):
shared.config.set('bitmessagesettings', 'sockslisten', 'false')
try: try:
testpayload = '\x00\x00' testpayload = '\x00\x00'

View File

@ -12,14 +12,10 @@ def knownNodes():
shared.knownNodes = pickle.load(pickleFile) shared.knownNodes = pickle.load(pickleFile)
pickleFile.close() pickleFile.close()
except: except:
defaultKnownNodes.createDefaultKnownNodes(shared.appdata) shared.knownNodes = defaultKnownNodes.createDefaultKnownNodes(shared.appdata)
pickleFile = open(shared.appdata + 'knownnodes.dat', 'rb')
shared.knownNodes = pickle.load(pickleFile)
pickleFile.close()
if shared.config.getint('bitmessagesettings', 'settingsversion') > 6: 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.' print 'Bitmessage cannot read future versions of the keys file (keys.dat). Run the newer version of Bitmessage.'
raise SystemExit raise SystemExit
def dns(): def dns():
# DNS bootstrap. This could be programmed to use the SOCKS proxy to do the # 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 # defaultKnownNodes.py. Hopefully either they are up to date or the user
# has run Bitmessage recently without SOCKS turned on and received good # has run Bitmessage recently without SOCKS turned on and received good
# bootstrap nodes using that method. # bootstrap nodes using that method.
if shared.config.get('bitmessagesettings', 'socksproxytype') == 'none': with shared.printLock:
try: if shared.config.get('bitmessagesettings', 'socksproxytype') == 'none':
for item in socket.getaddrinfo('bootstrap8080.bitmessage.org', 80): try:
print 'Adding', item[4][0], 'to knownNodes based on DNS boostrap method' for item in socket.getaddrinfo('bootstrap8080.bitmessage.org', 80):
shared.knownNodes[1][item[4][0]] = (8080, int(time.time())) print 'Adding', item[4][0], 'to knownNodes based on DNS boostrap method'
except: shared.knownNodes[1][item[4][0]] = (8080, int(time.time()))
print 'bootstrap8080.bitmessage.org DNS bootstrapping failed.' except:
try: print 'bootstrap8080.bitmessage.org DNS bootstrapping failed.'
for item in socket.getaddrinfo('bootstrap8444.bitmessage.org', 80): try:
print 'Adding', item[4][0], 'to knownNodes based on DNS boostrap method' for item in socket.getaddrinfo('bootstrap8444.bitmessage.org', 80):
shared.knownNodes[1][item[4][0]] = (8444, int(time.time())) print 'Adding', item[4][0], 'to knownNodes based on DNS boostrap method'
except: shared.knownNodes[1][item[4][0]] = (8444, int(time.time()))
print 'bootstrap8444.bitmessage.org DNS bootstrapping failed.' except:
else: print 'bootstrap8444.bitmessage.org DNS bootstrapping failed.'
print 'DNS bootstrap skipped because SOCKS is used.' else:
print 'DNS bootstrap skipped because SOCKS is used.'

View File

@ -68,6 +68,7 @@ def loadConfig():
'bitmessagesettings', 'maxacceptablenoncetrialsperbyte', '0') 'bitmessagesettings', 'maxacceptablenoncetrialsperbyte', '0')
shared.config.set( shared.config.set(
'bitmessagesettings', 'maxacceptablepayloadlengthextrabytes', '0') 'bitmessagesettings', 'maxacceptablepayloadlengthextrabytes', '0')
shared.config.set('bitmessagesettings', 'dontconnect', 'true')
ensureNamecoinOptions() ensureNamecoinOptions()
if storeConfigFilesInSameDirectoryAsProgramByDefault: if storeConfigFilesInSameDirectoryAsProgramByDefault:
@ -83,9 +84,3 @@ def loadConfig():
os.umask(0o077) os.umask(0o077)
with open(shared.appdata + 'keys.dat', 'wb') as configfile: with open(shared.appdata + 'keys.dat', 'wb') as configfile:
shared.config.write(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')

View File

@ -107,8 +107,8 @@ def vacuum():
#takeInboxMessagesOutOfTrash() #takeInboxMessagesOutOfTrash()
#takeSentMessagesOutOfTrash() #takeSentMessagesOutOfTrash()
#markAllInboxMessagesAsUnread() #markAllInboxMessagesAsUnread()
#readInbox() readInbox()
readSent() #readSent()
#readPubkeys() #readPubkeys()
#readSubscriptions() #readSubscriptions()
#readInventory() #readInventory()

View File

@ -200,8 +200,8 @@ def isAddressInMyAddressBookSubscriptionsListOrWhitelist(address):
def safeConfigGetBoolean(section,field): def safeConfigGetBoolean(section,field):
try: try:
return config.getboolean(section,field) return config.getboolean(section,field)
except: except Exception, err:
return False return False
def decodeWalletImportFormat(WIFstring): def decodeWalletImportFormat(WIFstring):
fullString = arithmetic.changebase(WIFstring,58,256) fullString = arithmetic.changebase(WIFstring,58,256)