commit
af0dfdcf93
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -5,4 +5,5 @@ src/build
|
|||
src/dist
|
||||
src/.project
|
||||
src/.pydevproject
|
||||
src/.settings/
|
||||
src/.settings/
|
||||
*.dll
|
4
COPYING
4
COPYING
|
@ -1,5 +1,5 @@
|
|||
Copyright (c) 2012-2015 Jonathan Warren
|
||||
Copyright (c) 2013-2015 The Bitmessage Developers
|
||||
Copyright (c) 2012-2016 Jonathan Warren
|
||||
Copyright (c) 2013-2016 The Bitmessage Developers
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
4
LICENSE
4
LICENSE
|
@ -1,6 +1,6 @@
|
|||
The MIT License (MIT)
|
||||
Copyright (c) 2012-2014 Jonathan Warren
|
||||
Copyright (c) 2013-2014 The Bitmessage Developers
|
||||
Copyright (c) 2012-2016 Jonathan Warren
|
||||
Copyright (c) 2013-2016 The Bitmessage Developers
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
|
|
7
Makefile
7
Makefile
|
@ -1,5 +1,6 @@
|
|||
APP=pybitmessage
|
||||
VERSION=0.4.4
|
||||
APPDIR=`basename "\`pwd\`"`
|
||||
VERSION=0.6.0
|
||||
RELEASE=1
|
||||
ARCH_TYPE=`uname -m`
|
||||
PREFIX?=/usr/local
|
||||
|
@ -8,7 +9,7 @@ LIBDIR=lib
|
|||
all:
|
||||
debug:
|
||||
source:
|
||||
tar -cvf ../${APP}_${VERSION}.orig.tar ../${APP}-${VERSION} --exclude-vcs
|
||||
tar -cvf ../${APP}_${VERSION}.orig.tar ../${APPDIR} --exclude-vcs
|
||||
gzip -f9n ../${APP}_${VERSION}.orig.tar
|
||||
install:
|
||||
mkdir -p ${DESTDIR}/usr
|
||||
|
@ -57,5 +58,5 @@ clean:
|
|||
rm -f puppypackage/*.gz puppypackage/*.pet slackpackage/*.txz
|
||||
|
||||
sourcedeb:
|
||||
tar -cvf ../${APP}_${VERSION}.orig.tar ../${APP}-${VERSION} --exclude-vcs --exclude 'debian'
|
||||
tar -cvf ../${APP}_${VERSION}.orig.tar ../${APPDIR} --exclude-vcs --exclude 'debian'
|
||||
gzip -f9n ../${APP}_${VERSION}.orig.tar
|
||||
|
|
2
arch.sh
2
arch.sh
|
@ -2,7 +2,7 @@
|
|||
|
||||
APP=pybitmessage
|
||||
PREV_VERSION=0.4.4
|
||||
VERSION=0.4.4
|
||||
VERSION=0.6.0
|
||||
RELEASE=1
|
||||
ARCH_TYPE=any
|
||||
CURRDIR=`pwd`
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# Maintainer: Bob Mottram (4096 bits) <bob@robotics.uk.to>
|
||||
pkgname=pybitmessage
|
||||
pkgver=0.4.4
|
||||
pkgver=0.6.0
|
||||
pkgrel=1
|
||||
pkgdesc="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."
|
||||
arch=('any')
|
||||
|
|
20
compiletest.py
Normal file
20
compiletest.py
Normal file
|
@ -0,0 +1,20 @@
|
|||
#!/usr/bin/python2.7
|
||||
|
||||
import ctypes
|
||||
import fnmatch
|
||||
import os
|
||||
import sys
|
||||
import traceback
|
||||
|
||||
matches = []
|
||||
for root, dirnames, filenames in os.walk('src'):
|
||||
for filename in fnmatch.filter(filenames, '*.py'):
|
||||
matches.append(os.path.join(root, filename))
|
||||
|
||||
for filename in matches:
|
||||
source = open(filename, 'r').read() + '\n'
|
||||
try:
|
||||
compile(source, filename, 'exec')
|
||||
except Exception as e:
|
||||
ctypes.windll.user32.MessageBoxA(0, traceback.format_exc(), "Exception in " + filename, 1)
|
||||
sys.exit(1)
|
12
debian.sh
12
debian.sh
|
@ -1,11 +1,13 @@
|
|||
#!/bin/bash
|
||||
|
||||
APP=pybitmessage
|
||||
PREV_VERSION=0.4.2
|
||||
VERSION=0.4.4
|
||||
PREV_VERSION=0.4.4
|
||||
VERSION=0.6.0
|
||||
RELEASE=1
|
||||
ARCH_TYPE=all
|
||||
DIR=${APP}-${VERSION}
|
||||
CURDIR=`pwd`
|
||||
SHORTDIR=`basename ${CURDIR}`
|
||||
|
||||
if [ $ARCH_TYPE == "x86_64" ]; then
|
||||
ARCH_TYPE="amd64"
|
||||
|
@ -30,17 +32,17 @@ make clean
|
|||
make
|
||||
|
||||
# Change the parent directory name to Debian format
|
||||
mv ../${APP} ../${DIR}
|
||||
mv ../${SHORTDIR} ../${DIR}
|
||||
|
||||
# Create a source archive
|
||||
make sourcedeb
|
||||
|
||||
# Build the package
|
||||
dpkg-buildpackage -F
|
||||
dpkg-buildpackage -F -us -uc
|
||||
|
||||
# Sign files
|
||||
gpg -ba ../${APP}_${VERSION}-1_${ARCH_TYPE}.deb
|
||||
gpg -ba ../${APP}_${VERSION}.orig.tar.gz
|
||||
|
||||
# Restore the parent directory name
|
||||
mv ../${DIR} ../${APP}
|
||||
mv ../${DIR} ../${SHORTDIR}
|
||||
|
|
9
debian/changelog
vendored
9
debian/changelog
vendored
|
@ -1,3 +1,12 @@
|
|||
pybitmessage (0.6.0-1) trusty; urgency=low
|
||||
|
||||
* Bugfixes
|
||||
* UI improvements
|
||||
* performance and security improvements
|
||||
* integration with email gateway (mailchuck.com)
|
||||
|
||||
-- Peter Surda <dev@mailchuck.com> Mon, 2 May 2016 16:25:00 +0200
|
||||
|
||||
pybitmessage (0.4.4-1) utopic; urgency=low
|
||||
|
||||
* Added ability to limit network transfer rate
|
||||
|
|
4
debian/copyright
vendored
4
debian/copyright
vendored
|
@ -3,11 +3,11 @@ Upstream-Name:
|
|||
Source:
|
||||
|
||||
Files: *
|
||||
Copyright: Copyright 2014 Bob Mottram (4096 bits) <bob@robotics.uk.to>
|
||||
Copyright: Copyright 2016 Bob Mottram (4096 bits) <bob@robotics.uk.to>
|
||||
License: MIT
|
||||
|
||||
Files: debian/*
|
||||
Copyright: Copyright 2014 Bob Mottram (4096 bits) <bob@robotics.uk.to>
|
||||
Copyright: Copyright 2016 Bob Mottram (4096 bits) <bob@robotics.uk.to>
|
||||
License: MIT
|
||||
|
||||
License: MIT
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
APP=pybitmessage
|
||||
PREV_VERSION=0.4.4
|
||||
VERSION=0.4.4
|
||||
VERSION=0.6.0
|
||||
RELEASE=1
|
||||
SOURCEDIR=.
|
||||
ARCH_TYPE=`uname -m`
|
||||
|
|
|
@ -1,32 +0,0 @@
|
|||
# $Header: $
|
||||
|
||||
EAPI=5
|
||||
|
||||
inherit git-2 python-r1
|
||||
|
||||
PYTHON_COMPAT=( python2_7 )
|
||||
PYTHON_REQ_USE="sqlite"
|
||||
REQUIRED_USE="${PYTHON_REQUIRED_USE}"
|
||||
DESCRIPTION="Bitmessage is a P2P communications protocol used to send encrypted messages to another person or to many subscribers. It is decentralized and trustless, meaning that you need-not inherently trust any entities like root certificate authorities. It uses strong authentication which means that the sender of a message cannot be spoofed, and it aims to hide "non-content" data, like the sender and receiver of messages, from passive eavesdroppers like those running warrantless wiretapping programs."
|
||||
HOMEPAGE="https://github.com/Bitmessage/PyBitmessage"
|
||||
EGIT_REPO_URI="https://github.com/Bitmessage/PyBitmessage.git"
|
||||
LICENSE="MIT"
|
||||
SLOT="0"
|
||||
KEYWORDS="x86"
|
||||
DEPEND="dev-libs/popt
|
||||
${PYTHON_DEPS}"
|
||||
RDEPEND="${DEPEND}
|
||||
dev-libs/openssl
|
||||
dev-python/PyQt4[]"
|
||||
|
||||
src_configure() {
|
||||
econf --with-popt
|
||||
}
|
||||
|
||||
src_compile() { :; }
|
||||
|
||||
src_install() {
|
||||
emake DESTDIR="${D}" PREFIX="/usr" install
|
||||
# Install README and (Debian) changelog
|
||||
dodoc README.md debian/changelog
|
||||
}
|
2
osx.sh
2
osx.sh
|
@ -14,6 +14,8 @@ fi
|
|||
|
||||
echo "Creating OS X packages for Bitmessage."
|
||||
|
||||
export PYBITMESSAGEVERSION=$1
|
||||
|
||||
cd src && python2.7 build_osx.py py2app
|
||||
|
||||
if [[ $? = "0" ]]; then
|
||||
|
|
2
puppy.sh
2
puppy.sh
|
@ -2,7 +2,7 @@
|
|||
|
||||
APP=pybitmessage
|
||||
PREV_VERSION=0.4.4
|
||||
VERSION=0.4.4
|
||||
VERSION=0.6.0
|
||||
RELEASE=1
|
||||
BUILDDIR=~/petbuild
|
||||
CURRDIR=`pwd`
|
||||
|
|
58
pyinstaller/bitmessagemain.spec
Normal file
58
pyinstaller/bitmessagemain.spec
Normal file
|
@ -0,0 +1,58 @@
|
|||
srcPath = "C:\\src\\PyBitmessage\\src\\"
|
||||
qtPath = "C:\\Qt\\4.8.6\\"
|
||||
openSSLPath = "C:\\OpenSSL-1.0.2e\\"
|
||||
outPath = "C:\\src\\PyInstaller\\bitmessagemain"
|
||||
|
||||
# -*- mode: python -*-
|
||||
a = Analysis([srcPath + 'bitmessagemain.py'],
|
||||
pathex=[outPath],
|
||||
hiddenimports=[],
|
||||
hookspath=None,
|
||||
runtime_hooks=None)
|
||||
|
||||
# fix duplicates
|
||||
for d in a.datas:
|
||||
if 'pyconfig' in d[0]:
|
||||
a.datas.remove(d)
|
||||
break
|
||||
|
||||
def addTranslations():
|
||||
import os
|
||||
extraDatas = []
|
||||
for file in os.listdir(srcPath + 'translations'):
|
||||
if file[-3:] != ".qm":
|
||||
continue
|
||||
extraDatas.append(('translations\\'+file, srcPath + 'translations\\' + file, 'DATA'))
|
||||
for file in os.listdir(qtPath + 'translations'):
|
||||
if file[0:3] != "qt_" or file[5:8] != ".qm":
|
||||
continue
|
||||
extraDatas.append(('translations\\'+file, qtPath + 'translations\\' + file, 'DATA'))
|
||||
return extraDatas
|
||||
|
||||
def addUIs():
|
||||
import os
|
||||
extraDatas = []
|
||||
for file in os.listdir(srcPath + 'bitmessageqt'):
|
||||
if file[-3:] != ".ui":
|
||||
continue
|
||||
extraDatas.append(('ui\\'+file, srcPath + 'bitmessageqt\\' + file, 'DATA'))
|
||||
return extraDatas
|
||||
|
||||
# append the translations directory
|
||||
a.datas += addTranslations()
|
||||
a.datas += addUIs()
|
||||
|
||||
a.binaries.append(('msvcr120.dll', 'C:\\WINDOWS\\system32\\msvcr120.dll', 'BINARY'))
|
||||
|
||||
pyz = PYZ(a.pure)
|
||||
exe = EXE(pyz,
|
||||
a.scripts,
|
||||
a.binaries,
|
||||
a.zipfiles,
|
||||
a.datas,
|
||||
a.binaries + [('libeay32.dll', openSSLPath + 'libeay32.dll', 'BINARY'), ('bitmsghash\\bitmsghash32.dll', srcPath + 'bitmsghash\\bitmsghash32.dll', 'BINARY'), ('bitmsghash\\bitmsghash.cl', srcPath + 'bitmsghash\\bitmsghash.cl', 'BINARY'), ('sslkeys\\cert.pem', srcPath + 'sslkeys\\cert.pem', 'BINARY'), ('sslkeys\\key.pem', srcPath + 'sslkeys\\key.pem', 'BINARY')],
|
||||
name='Bitmessage.exe',
|
||||
debug=False,
|
||||
strip=None,
|
||||
upx=False,
|
||||
console=False, icon= srcPath + 'images\\can-icon.ico')
|
|
@ -1,5 +1,5 @@
|
|||
Name: pybitmessage
|
||||
Version: 0.4.4
|
||||
Version: 0.6.0
|
||||
Release: 1%{?dist}
|
||||
Summary: Send encrypted messages
|
||||
License: MIT
|
||||
|
|
2
slack.sh
2
slack.sh
|
@ -2,7 +2,7 @@
|
|||
|
||||
APP=pybitmessage
|
||||
PREV_VERSION=0.4.4
|
||||
VERSION=0.4.4
|
||||
VERSION=0.6.0
|
||||
RELEASE=1
|
||||
ARCH_TYPE=`uname -m`
|
||||
BUILDDIR=~/slackbuild
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import hashlib
|
||||
from struct import *
|
||||
from pyelliptic import arithmetic
|
||||
from binascii import hexlify, unhexlify
|
||||
|
||||
|
||||
|
||||
|
@ -10,9 +11,9 @@ def convertIntToString(n):
|
|||
if a[-1:] == 'L':
|
||||
a = a[:-1]
|
||||
if (len(a) % 2) == 0:
|
||||
return a[2:].decode('hex')
|
||||
return unhexlify(a[2:])
|
||||
else:
|
||||
return ('0'+a[2:]).decode('hex')
|
||||
return unhexlify('0'+a[2:])
|
||||
|
||||
ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
|
||||
|
||||
|
@ -55,7 +56,7 @@ def decodeBase58(string, alphabet=ALPHABET):
|
|||
|
||||
def encodeVarint(integer):
|
||||
if integer < 0:
|
||||
print 'varint cannot be < 0'
|
||||
logger.error('varint cannot be < 0')
|
||||
raise SystemExit
|
||||
if integer < 253:
|
||||
return pack('>B',integer)
|
||||
|
@ -66,7 +67,7 @@ def encodeVarint(integer):
|
|||
if integer >= 4294967296 and integer < 18446744073709551616:
|
||||
return pack('>B',255) + pack('>Q',integer)
|
||||
if integer >= 18446744073709551616:
|
||||
print 'varint cannot be >= 18446744073709551616'
|
||||
logger.error('varint cannot be >= 18446744073709551616')
|
||||
raise SystemExit
|
||||
|
||||
class varintDecodeError(Exception):
|
||||
|
@ -142,7 +143,7 @@ def encodeAddress(version,stream,ripe):
|
|||
sha.update(currentHash)
|
||||
checksum = sha.digest()[0:4]
|
||||
|
||||
asInt = int(storedBinaryData.encode('hex') + checksum.encode('hex'),16)
|
||||
asInt = int(hexlify(storedBinaryData) + hexlify(checksum),16)
|
||||
return 'BM-'+ encodeBase58(asInt)
|
||||
|
||||
def decodeAddress(address):
|
||||
|
@ -165,7 +166,7 @@ def decodeAddress(address):
|
|||
|
||||
#print 'hexdata', hexdata
|
||||
|
||||
data = hexdata.decode('hex')
|
||||
data = unhexlify(hexdata)
|
||||
checksum = data[-4:]
|
||||
|
||||
sha = hashlib.new('sha512')
|
||||
|
@ -185,25 +186,25 @@ def decodeAddress(address):
|
|||
try:
|
||||
addressVersionNumber, bytesUsedByVersionNumber = decodeVarint(data[:9])
|
||||
except varintDecodeError as e:
|
||||
print e
|
||||
logger.error(str(e))
|
||||
status = 'varintmalformed'
|
||||
return status,0,0,""
|
||||
#print 'addressVersionNumber', addressVersionNumber
|
||||
#print 'bytesUsedByVersionNumber', bytesUsedByVersionNumber
|
||||
|
||||
if addressVersionNumber > 4:
|
||||
print 'cannot decode address version numbers this high'
|
||||
logger.error('cannot decode address version numbers this high')
|
||||
status = 'versiontoohigh'
|
||||
return status,0,0,""
|
||||
elif addressVersionNumber == 0:
|
||||
print 'cannot decode address version numbers of zero.'
|
||||
logger.error('cannot decode address version numbers of zero.')
|
||||
status = 'versiontoohigh'
|
||||
return status,0,0,""
|
||||
|
||||
try:
|
||||
streamNumber, bytesUsedByStreamNumber = decodeVarint(data[bytesUsedByVersionNumber:])
|
||||
except varintDecodeError as e:
|
||||
print e
|
||||
logger.error(str(e))
|
||||
status = 'varintmalformed'
|
||||
return status,0,0,""
|
||||
#print streamNumber
|
||||
|
@ -268,7 +269,7 @@ if __name__ == "__main__":
|
|||
ripe.update(sha.digest())
|
||||
addressVersionNumber = 2
|
||||
streamNumber = 1
|
||||
print 'Ripe digest that we will encode in the address:', ripe.digest().encode('hex')
|
||||
print 'Ripe digest that we will encode in the address:', hexlify(ripe.digest())
|
||||
returnedAddress = encodeAddress(addressVersionNumber,streamNumber,ripe.digest())
|
||||
print 'Encoded address:', returnedAddress
|
||||
status,addressVersionNumber,streamNumber,data = decodeAddress(returnedAddress)
|
||||
|
@ -277,5 +278,5 @@ if __name__ == "__main__":
|
|||
print 'addressVersionNumber', addressVersionNumber
|
||||
print 'streamNumber', streamNumber
|
||||
print 'length of data(the ripe hash):', len(data)
|
||||
print 'ripe data:', data.encode('hex')
|
||||
print 'ripe data:', hexlify(data)
|
||||
|
||||
|
|
75
src/api.py
75
src/api.py
|
@ -1,5 +1,5 @@
|
|||
# Copyright (c) 2012-2014 Jonathan Warren
|
||||
# Copyright (c) 2012-2014 The Bitmessage developers
|
||||
# Copyright (c) 2012-2016 Jonathan Warren
|
||||
# Copyright (c) 2012-2016 The Bitmessage developers
|
||||
|
||||
comment= """
|
||||
This is not what you run to run the Bitmessage API. Instead, enable the API
|
||||
|
@ -12,8 +12,9 @@ if __name__ == "__main__":
|
|||
import sys
|
||||
sys.exit(0)
|
||||
|
||||
from SimpleXMLRPCServer import SimpleXMLRPCRequestHandler
|
||||
from SimpleXMLRPCServer import SimpleXMLRPCRequestHandler, SimpleXMLRPCServer
|
||||
import json
|
||||
from binascii import hexlify
|
||||
|
||||
import shared
|
||||
import time
|
||||
|
@ -26,7 +27,7 @@ from pyelliptic.openssl import OpenSSL
|
|||
from struct import pack
|
||||
|
||||
# Classes
|
||||
from helper_sql import sqlQuery,sqlExecute,SqlBulkExecute
|
||||
from helper_sql import sqlQuery,sqlExecute,SqlBulkExecute,sqlStoredProcedure
|
||||
from debug import logger
|
||||
|
||||
# Helper Functions
|
||||
|
@ -43,6 +44,13 @@ class APIError(Exception):
|
|||
def __str__(self):
|
||||
return "API Error %04i: %s" % (self.error_number, self.error_message)
|
||||
|
||||
|
||||
class StoppableXMLRPCServer(SimpleXMLRPCServer):
|
||||
def serve_forever(self):
|
||||
while shared.shutdown == 0:
|
||||
self.handle_request()
|
||||
|
||||
|
||||
# This is one of several classes that constitute the API
|
||||
# This class was written by Vaibhav Bhatia. Modified by Jonathan Warren (Atheros).
|
||||
# http://code.activestate.com/recipes/501148-xmlrpc-serverclient-which-does-cookie-handling-and/
|
||||
|
@ -174,7 +182,14 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
|
|||
return data
|
||||
|
||||
def HandleListAddressBookEntries(self, params):
|
||||
queryreturn = sqlQuery('''SELECT label, address from addressbook''')
|
||||
if len(params) == 1:
|
||||
label, = params
|
||||
label = self._decode(label, "base64")
|
||||
queryreturn = sqlQuery('''SELECT label, address from addressbook WHERE label = ?''', label)
|
||||
elif len(params) > 1:
|
||||
raise APIError(0, "Too many paremeters, max 1")
|
||||
else:
|
||||
queryreturn = sqlQuery('''SELECT label, address from addressbook''')
|
||||
data = '{"addresses":['
|
||||
for row in queryreturn:
|
||||
label, address = row
|
||||
|
@ -197,8 +212,8 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
|
|||
raise APIError(16, 'You already have this address in your address book.')
|
||||
|
||||
sqlExecute("INSERT INTO addressbook VALUES(?,?)", label, address)
|
||||
shared.UISignalQueue.put(('rerenderInboxFromLabels',''))
|
||||
shared.UISignalQueue.put(('rerenderSentToLabels',''))
|
||||
shared.UISignalQueue.put(('rerenderMessagelistFromLabels',''))
|
||||
shared.UISignalQueue.put(('rerenderMessagelistToLabels',''))
|
||||
shared.UISignalQueue.put(('rerenderAddressBook',''))
|
||||
return "Added address %s to address book" % address
|
||||
|
||||
|
@ -209,8 +224,8 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
|
|||
address = addBMIfNotPresent(address)
|
||||
self._verifyAddress(address)
|
||||
sqlExecute('DELETE FROM addressbook WHERE address=?', address)
|
||||
shared.UISignalQueue.put(('rerenderInboxFromLabels',''))
|
||||
shared.UISignalQueue.put(('rerenderSentToLabels',''))
|
||||
shared.UISignalQueue.put(('rerenderMessagelistFromLabels',''))
|
||||
shared.UISignalQueue.put(('rerenderMessagelistToLabels',''))
|
||||
shared.UISignalQueue.put(('rerenderAddressBook',''))
|
||||
return "Deleted address book entry for %s if it existed" % address
|
||||
|
||||
|
@ -448,8 +463,8 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
|
|||
shared.config.remove_section(address)
|
||||
with open(shared.appdata + 'keys.dat', 'wb') as configfile:
|
||||
shared.config.write(configfile)
|
||||
shared.UISignalQueue.put(('rerenderInboxFromLabels',''))
|
||||
shared.UISignalQueue.put(('rerenderSentToLabels',''))
|
||||
shared.UISignalQueue.put(('rerenderMessagelistFromLabels',''))
|
||||
shared.UISignalQueue.put(('rerenderMessagelistToLabels',''))
|
||||
shared.reloadMyAddressHashes()
|
||||
return 'success'
|
||||
|
||||
|
@ -463,7 +478,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
|
|||
message = shared.fixPotentiallyInvalidUTF8Data(message)
|
||||
if len(data) > 25:
|
||||
data += ','
|
||||
data += json.dumps({'msgid': msgid.encode('hex'), 'toAddress': toAddress, 'fromAddress': fromAddress, 'subject': subject.encode(
|
||||
data += json.dumps({'msgid': hexlify(msgid), 'toAddress': toAddress, 'fromAddress': fromAddress, 'subject': subject.encode(
|
||||
'base64'), 'message': message.encode('base64'), 'encodingType': encodingtype, 'receivedTime': received, 'read': read}, indent=4, separators=(',', ': '))
|
||||
data += ']}'
|
||||
return data
|
||||
|
@ -476,7 +491,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
|
|||
msgid = row[0]
|
||||
if len(data) > 25:
|
||||
data += ','
|
||||
data += json.dumps({'msgid': msgid.encode('hex')}, indent=4, separators=(',', ': '))
|
||||
data += json.dumps({'msgid': hexlify(msgid)}, indent=4, separators=(',', ': '))
|
||||
data += ']}'
|
||||
return data
|
||||
|
||||
|
@ -501,7 +516,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
|
|||
msgid, toAddress, fromAddress, subject, received, message, encodingtype, read = row
|
||||
subject = shared.fixPotentiallyInvalidUTF8Data(subject)
|
||||
message = shared.fixPotentiallyInvalidUTF8Data(message)
|
||||
data += json.dumps({'msgid':msgid.encode('hex'), 'toAddress':toAddress, 'fromAddress':fromAddress, 'subject':subject.encode('base64'), 'message':message.encode('base64'), 'encodingType':encodingtype, 'receivedTime':received, 'read': read}, indent=4, separators=(',', ': '))
|
||||
data += json.dumps({'msgid':hexlify(msgid), 'toAddress':toAddress, 'fromAddress':fromAddress, 'subject':subject.encode('base64'), 'message':message.encode('base64'), 'encodingType':encodingtype, 'receivedTime':received, 'read': read}, indent=4, separators=(',', ': '))
|
||||
data += ']}'
|
||||
return data
|
||||
|
||||
|
@ -514,7 +529,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
|
|||
message = shared.fixPotentiallyInvalidUTF8Data(message)
|
||||
if len(data) > 25:
|
||||
data += ','
|
||||
data += json.dumps({'msgid':msgid.encode('hex'), 'toAddress':toAddress, 'fromAddress':fromAddress, 'subject':subject.encode('base64'), 'message':message.encode('base64'), 'encodingType':encodingtype, 'lastActionTime':lastactiontime, 'status':status, 'ackData':ackdata.encode('hex')}, indent=4, separators=(',', ': '))
|
||||
data += json.dumps({'msgid':hexlify(msgid), 'toAddress':toAddress, 'fromAddress':fromAddress, 'subject':subject.encode('base64'), 'message':message.encode('base64'), 'encodingType':encodingtype, 'lastActionTime':lastactiontime, 'status':status, 'ackData':hexlify(ackdata)}, indent=4, separators=(',', ': '))
|
||||
data += ']}'
|
||||
return data
|
||||
|
||||
|
@ -525,7 +540,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
|
|||
msgid = row[0]
|
||||
if len(data) > 25:
|
||||
data += ','
|
||||
data += json.dumps({'msgid':msgid.encode('hex')}, indent=4, separators=(',', ': '))
|
||||
data += json.dumps({'msgid':hexlify(msgid)}, indent=4, separators=(',', ': '))
|
||||
data += ']}'
|
||||
return data
|
||||
|
||||
|
@ -541,7 +556,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
|
|||
message = shared.fixPotentiallyInvalidUTF8Data(message)
|
||||
if len(data) > 25:
|
||||
data += ','
|
||||
data += json.dumps({'msgid':msgid.encode('hex'), 'toAddress':toAddress, 'fromAddress':fromAddress, 'subject':subject.encode('base64'), 'message':message.encode('base64'), 'encodingType':encodingtype, 'receivedTime':received}, indent=4, separators=(',', ': '))
|
||||
data += json.dumps({'msgid':hexlify(msgid), 'toAddress':toAddress, 'fromAddress':fromAddress, 'subject':subject.encode('base64'), 'message':message.encode('base64'), 'encodingType':encodingtype, 'receivedTime':received}, indent=4, separators=(',', ': '))
|
||||
data += ']}'
|
||||
return data
|
||||
|
||||
|
@ -555,7 +570,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
|
|||
msgid, toAddress, fromAddress, subject, lastactiontime, message, encodingtype, status, ackdata = row
|
||||
subject = shared.fixPotentiallyInvalidUTF8Data(subject)
|
||||
message = shared.fixPotentiallyInvalidUTF8Data(message)
|
||||
data += json.dumps({'msgid':msgid.encode('hex'), 'toAddress':toAddress, 'fromAddress':fromAddress, 'subject':subject.encode('base64'), 'message':message.encode('base64'), 'encodingType':encodingtype, 'lastActionTime':lastactiontime, 'status':status, 'ackData':ackdata.encode('hex')}, indent=4, separators=(',', ': '))
|
||||
data += json.dumps({'msgid':hexlify(msgid), 'toAddress':toAddress, 'fromAddress':fromAddress, 'subject':subject.encode('base64'), 'message':message.encode('base64'), 'encodingType':encodingtype, 'lastActionTime':lastactiontime, 'status':status, 'ackData':hexlify(ackdata)}, indent=4, separators=(',', ': '))
|
||||
data += ']}'
|
||||
return data
|
||||
|
||||
|
@ -572,7 +587,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
|
|||
message = shared.fixPotentiallyInvalidUTF8Data(message)
|
||||
if len(data) > 25:
|
||||
data += ','
|
||||
data += json.dumps({'msgid':msgid.encode('hex'), 'toAddress':toAddress, 'fromAddress':fromAddress, 'subject':subject.encode('base64'), 'message':message.encode('base64'), 'encodingType':encodingtype, 'lastActionTime':lastactiontime, 'status':status, 'ackData':ackdata.encode('hex')}, indent=4, separators=(',', ': '))
|
||||
data += json.dumps({'msgid':hexlify(msgid), 'toAddress':toAddress, 'fromAddress':fromAddress, 'subject':subject.encode('base64'), 'message':message.encode('base64'), 'encodingType':encodingtype, 'lastActionTime':lastactiontime, 'status':status, 'ackData':hexlify(ackdata)}, indent=4, separators=(',', ': '))
|
||||
data += ']}'
|
||||
return data
|
||||
|
||||
|
@ -587,7 +602,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
|
|||
msgid, toAddress, fromAddress, subject, lastactiontime, message, encodingtype, status, ackdata = row
|
||||
subject = shared.fixPotentiallyInvalidUTF8Data(subject)
|
||||
message = shared.fixPotentiallyInvalidUTF8Data(message)
|
||||
data += json.dumps({'msgid':msgid.encode('hex'), 'toAddress':toAddress, 'fromAddress':fromAddress, 'subject':subject.encode('base64'), 'message':message.encode('base64'), 'encodingType':encodingtype, 'lastActionTime':lastactiontime, 'status':status, 'ackData':ackdata.encode('hex')}, indent=4, separators=(',', ': '))
|
||||
data += json.dumps({'msgid':hexlify(msgid), 'toAddress':toAddress, 'fromAddress':fromAddress, 'subject':subject.encode('base64'), 'message':message.encode('base64'), 'encodingType':encodingtype, 'lastActionTime':lastactiontime, 'status':status, 'ackData':hexlify(ackdata)}, indent=4, separators=(',', ': '))
|
||||
data += ']}'
|
||||
return data
|
||||
|
||||
|
@ -680,7 +695,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
|
|||
|
||||
shared.workerQueue.put(('sendmessage', toAddress))
|
||||
|
||||
return ackdata.encode('hex')
|
||||
return hexlify(ackdata)
|
||||
|
||||
def HandleSendBroadcast(self, params):
|
||||
if len(params) == 0:
|
||||
|
@ -737,7 +752,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
|
|||
toAddress, toLabel, fromAddress, subject, message, ackdata)))
|
||||
shared.workerQueue.put(('sendbroadcast', ''))
|
||||
|
||||
return ackdata.encode('hex')
|
||||
return hexlify(ackdata)
|
||||
|
||||
def HandleGetStatus(self, params):
|
||||
if len(params) != 1:
|
||||
|
@ -779,7 +794,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
|
|||
raise APIError(16, 'You are already subscribed to that address.')
|
||||
sqlExecute('''INSERT INTO subscriptions VALUES (?,?,?)''',label, address, True)
|
||||
shared.reloadBroadcastSendersForWhichImWatching()
|
||||
shared.UISignalQueue.put(('rerenderInboxFromLabels', ''))
|
||||
shared.UISignalQueue.put(('rerenderMessagelistFromLabels', ''))
|
||||
shared.UISignalQueue.put(('rerenderSubscriptions', ''))
|
||||
return 'Added subscription.'
|
||||
|
||||
|
@ -790,7 +805,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
|
|||
address = addBMIfNotPresent(address)
|
||||
sqlExecute('''DELETE FROM subscriptions WHERE address=?''', address)
|
||||
shared.reloadBroadcastSendersForWhichImWatching()
|
||||
shared.UISignalQueue.put(('rerenderInboxFromLabels', ''))
|
||||
shared.UISignalQueue.put(('rerenderMessagelistFromLabels', ''))
|
||||
shared.UISignalQueue.put(('rerenderSubscriptions', ''))
|
||||
return 'Deleted subscription if it existed.'
|
||||
|
||||
|
@ -836,9 +851,8 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
|
|||
TTL = 2.5 * 24 * 60 * 60
|
||||
shared.inventory[inventoryHash] = (
|
||||
objectType, toStreamNumber, encryptedPayload, int(time.time()) + TTL,'')
|
||||
shared.inventorySets[toStreamNumber].add(inventoryHash)
|
||||
with shared.printLock:
|
||||
print 'Broadcasting inv for msg(API disseminatePreEncryptedMsg command):', inventoryHash.encode('hex')
|
||||
print 'Broadcasting inv for msg(API disseminatePreEncryptedMsg command):', hexlify(inventoryHash)
|
||||
shared.broadcastToSendDataQueues((
|
||||
toStreamNumber, 'advertiseobject', inventoryHash))
|
||||
|
||||
|
@ -884,9 +898,8 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
|
|||
TTL = 28 * 24 * 60 * 60
|
||||
shared.inventory[inventoryHash] = (
|
||||
objectType, pubkeyStreamNumber, payload, int(time.time()) + TTL,'')
|
||||
shared.inventorySets[pubkeyStreamNumber].add(inventoryHash)
|
||||
with shared.printLock:
|
||||
print 'broadcasting inv within API command disseminatePubkey with hash:', inventoryHash.encode('hex')
|
||||
print 'broadcasting inv within API command disseminatePubkey with hash:', hexlify(inventoryHash)
|
||||
shared.broadcastToSendDataQueues((
|
||||
streamNumber, 'advertiseobject', inventoryHash))
|
||||
|
||||
|
@ -921,7 +934,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
|
|||
payload, = row
|
||||
if len(data) > 25:
|
||||
data += ','
|
||||
data += json.dumps({'data':payload.encode('hex')}, indent=4, separators=(',', ': '))
|
||||
data += json.dumps({'data':hexlify(payload)}, indent=4, separators=(',', ': '))
|
||||
data += ']}'
|
||||
return data
|
||||
|
||||
|
@ -956,6 +969,9 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
|
|||
message, = params
|
||||
shared.UISignalQueue.put(('updateStatusBar', message))
|
||||
|
||||
def HandleDeleteAndVacuum(self, params):
|
||||
sqlStoredProcedure('deleteandvacuume')
|
||||
return 'done'
|
||||
|
||||
handlers = {}
|
||||
handlers['helloWorld'] = HandleHelloWorld
|
||||
|
@ -1006,6 +1022,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
|
|||
handlers['getMessageDataByDestinationTag'] = HandleGetMessageDataByDestinationHash
|
||||
handlers['clientStatus'] = HandleClientStatus
|
||||
handlers['decodeAddress'] = HandleDecodeAddress
|
||||
handlers['deleteAndVacuum'] = HandleDeleteAndVacuum
|
||||
|
||||
def _handle_request(self, method, params):
|
||||
if (self.handlers.has_key(method)):
|
||||
|
|
1778
src/bitmessagecli.py
Normal file
1778
src/bitmessagecli.py
Normal file
|
@ -0,0 +1,1778 @@
|
|||
#!/usr/bin/env python2.7.x
|
||||
# Created by Adam Melton (.dok) referenceing https://bitmessage.org/wiki/API_Reference for API documentation
|
||||
# Distributed under the MIT/X11 software license. See http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
# This is an example of a daemon client for PyBitmessage 0.4.2, by .dok (Version 0.3.0)
|
||||
|
||||
|
||||
import ConfigParser
|
||||
import xmlrpclib
|
||||
import datetime
|
||||
import hashlib
|
||||
import getopt
|
||||
import imghdr
|
||||
import ntpath
|
||||
import json
|
||||
import time
|
||||
import sys
|
||||
import os
|
||||
|
||||
api = ''
|
||||
keysName = 'keys.dat'
|
||||
keysPath = 'keys.dat'
|
||||
usrPrompt = 0 #0 = First Start, 1 = prompt, 2 = no prompt if the program is starting up
|
||||
knownAddresses = dict()
|
||||
|
||||
def userInput(message): #Checks input for exit or quit. Also formats for input, etc
|
||||
global usrPrompt
|
||||
print '\n' + message
|
||||
uInput = raw_input('> ')
|
||||
|
||||
if (uInput.lower() == 'exit'): #Returns the user to the main menu
|
||||
usrPrompt = 1
|
||||
main()
|
||||
|
||||
elif (uInput.lower() == 'quit'): #Quits the program
|
||||
print '\n Bye\n'
|
||||
sys.exit()
|
||||
os.exit()
|
||||
else:
|
||||
return uInput
|
||||
|
||||
def restartBmNotify(): #Prompts the user to restart Bitmessage.
|
||||
print '\n *******************************************************************'
|
||||
print ' WARNING: If Bitmessage is running locally, you must restart it now.'
|
||||
print ' *******************************************************************\n'
|
||||
|
||||
def safeConfigGetBoolean(section,field):
|
||||
global keysPath
|
||||
config = ConfigParser.SafeConfigParser()
|
||||
config.read(keysPath)
|
||||
|
||||
try:
|
||||
return config.getboolean(section,field)
|
||||
except:
|
||||
return False
|
||||
|
||||
#Begin keys.dat interactions
|
||||
def lookupAppdataFolder(): #gets the appropriate folders for the .dat files depending on the OS. Taken from bitmessagemain.py
|
||||
APPNAME = "PyBitmessage"
|
||||
from os import path, environ
|
||||
if sys.platform == 'darwin':
|
||||
if "HOME" in environ:
|
||||
dataFolder = path.join(os.environ["HOME"], "Library/Application support/", APPNAME) + '/'
|
||||
else:
|
||||
print ' Could not find home folder, please report this message and your OS X version to the Daemon Github.'
|
||||
os.exit()
|
||||
|
||||
elif 'win32' in sys.platform or 'win64' in sys.platform:
|
||||
dataFolder = path.join(environ['APPDATA'], APPNAME) + '\\'
|
||||
else:
|
||||
dataFolder = path.expanduser(path.join("~", ".config/" + APPNAME + "/"))
|
||||
return dataFolder
|
||||
|
||||
def configInit():
|
||||
global keysName
|
||||
config = ConfigParser.SafeConfigParser()
|
||||
|
||||
config.add_section('bitmessagesettings')
|
||||
config.set('bitmessagesettings', 'port', '8444') #Sets the bitmessage port to stop the warning about the api not properly being setup. This is in the event that the keys.dat is in a different directory or is created locally to connect to a machine remotely.
|
||||
config.set('bitmessagesettings','apienabled','true') #Sets apienabled to true in keys.dat
|
||||
|
||||
with open(keysName, 'wb') as configfile:
|
||||
config.write(configfile)
|
||||
|
||||
print '\n ' + str(keysName) + ' Initalized in the same directory as daemon.py'
|
||||
print ' You will now need to configure the ' + str(keysName) + ' file.\n'
|
||||
|
||||
def apiInit(apiEnabled):
|
||||
global keysPath
|
||||
global usrPrompt
|
||||
config = ConfigParser.SafeConfigParser()
|
||||
config.read(keysPath)
|
||||
|
||||
|
||||
|
||||
if (apiEnabled == False): #API information there but the api is disabled.
|
||||
uInput = userInput("The API is not enabled. Would you like to do that now, (Y)es or (N)o?").lower()
|
||||
|
||||
if uInput == "y": #
|
||||
config.set('bitmessagesettings','apienabled','true') #Sets apienabled to true in keys.dat
|
||||
with open(keysPath, 'wb') as configfile:
|
||||
config.write(configfile)
|
||||
|
||||
print 'Done'
|
||||
restartBmNotify()
|
||||
return True
|
||||
|
||||
elif uInput == "n":
|
||||
print ' \n************************************************************'
|
||||
print ' Daemon will not work when the API is disabled. '
|
||||
print ' Please refer to the Bitmessage Wiki on how to setup the API.'
|
||||
print ' ************************************************************\n'
|
||||
usrPrompt = 1
|
||||
main()
|
||||
|
||||
else:
|
||||
print '\n Invalid Entry\n'
|
||||
usrPrompt = 1
|
||||
main()
|
||||
elif (apiEnabled == True): #API correctly setup
|
||||
#Everything is as it should be
|
||||
return True
|
||||
|
||||
else: #API information was not present.
|
||||
print '\n ' + str(keysPath) + ' not properly configured!\n'
|
||||
uInput = userInput("Would you like to do this now, (Y)es or (N)o?").lower()
|
||||
|
||||
if uInput == "y": #User said yes, initalize the api by writing these values to the keys.dat file
|
||||
print ' '
|
||||
|
||||
apiUsr = userInput("API Username")
|
||||
apiPwd = userInput("API Password")
|
||||
apiInterface = userInput("API Interface. (127.0.0.1)")
|
||||
apiPort = userInput("API Port")
|
||||
apiEnabled = userInput("API Enabled? (True) or (False)").lower()
|
||||
daemon = userInput("Daemon mode Enabled? (True) or (False)").lower()
|
||||
|
||||
if (daemon != 'true' and daemon != 'false'):
|
||||
print '\n Invalid Entry for Daemon.\n'
|
||||
uInput = 1
|
||||
main()
|
||||
|
||||
print ' -----------------------------------\n'
|
||||
|
||||
config.set('bitmessagesettings', 'port', '8444') #sets the bitmessage port to stop the warning about the api not properly being setup. This is in the event that the keys.dat is in a different directory or is created locally to connect to a machine remotely.
|
||||
config.set('bitmessagesettings','apienabled','true')
|
||||
config.set('bitmessagesettings', 'apiport', apiPort)
|
||||
config.set('bitmessagesettings', 'apiinterface', '127.0.0.1')
|
||||
config.set('bitmessagesettings', 'apiusername', apiUsr)
|
||||
config.set('bitmessagesettings', 'apipassword', apiPwd)
|
||||
config.set('bitmessagesettings', 'daemon', daemon)
|
||||
with open(keysPath, 'wb') as configfile:
|
||||
config.write(configfile)
|
||||
|
||||
print '\n Finished configuring the keys.dat file with API information.\n'
|
||||
restartBmNotify()
|
||||
return True
|
||||
|
||||
elif uInput == "n":
|
||||
print '\n ***********************************************************'
|
||||
print ' Please refer to the Bitmessage Wiki on how to setup the API.'
|
||||
print ' ***********************************************************\n'
|
||||
usrPrompt = 1
|
||||
main()
|
||||
else:
|
||||
print ' \nInvalid entry\n'
|
||||
usrPrompt = 1
|
||||
main()
|
||||
|
||||
|
||||
def apiData():
|
||||
global keysName
|
||||
global keysPath
|
||||
global usrPrompt
|
||||
|
||||
config = ConfigParser.SafeConfigParser()
|
||||
config.read(keysPath) #First try to load the config file (the keys.dat file) from the program directory
|
||||
|
||||
try:
|
||||
config.get('bitmessagesettings','port')
|
||||
appDataFolder = ''
|
||||
except:
|
||||
#Could not load the keys.dat file in the program directory. Perhaps it is in the appdata directory.
|
||||
appDataFolder = lookupAppdataFolder()
|
||||
keysPath = appDataFolder + keysPath
|
||||
config = ConfigParser.SafeConfigParser()
|
||||
config.read(keysPath)
|
||||
|
||||
try:
|
||||
config.get('bitmessagesettings','port')
|
||||
except:
|
||||
#keys.dat was not there either, something is wrong.
|
||||
print '\n ******************************************************************'
|
||||
print ' There was a problem trying to access the Bitmessage keys.dat file'
|
||||
print ' or keys.dat is not set up correctly'
|
||||
print ' Make sure that daemon is in the same directory as Bitmessage. '
|
||||
print ' ******************************************************************\n'
|
||||
|
||||
uInput = userInput("Would you like to create a keys.dat in the local directory, (Y)es or (N)o?").lower()
|
||||
|
||||
if (uInput == "y" or uInput == "yes"):
|
||||
configInit()
|
||||
keysPath = keysName
|
||||
usrPrompt = 0
|
||||
main()
|
||||
elif (uInput == "n" or uInput == "no"):
|
||||
print '\n Trying Again.\n'
|
||||
usrPrompt = 0
|
||||
main()
|
||||
else:
|
||||
print '\n Invalid Input.\n'
|
||||
|
||||
usrPrompt = 1
|
||||
main()
|
||||
|
||||
try: #checks to make sure that everyting is configured correctly. Excluding apiEnabled, it is checked after
|
||||
config.get('bitmessagesettings', 'apiport')
|
||||
config.get('bitmessagesettings', 'apiinterface')
|
||||
config.get('bitmessagesettings', 'apiusername')
|
||||
config.get('bitmessagesettings', 'apipassword')
|
||||
except:
|
||||
apiInit("") #Initalize the keys.dat file with API information
|
||||
|
||||
#keys.dat file was found or appropriately configured, allow information retrieval
|
||||
apiEnabled = apiInit(safeConfigGetBoolean('bitmessagesettings','apienabled')) #if false it will prompt the user, if true it will return true
|
||||
|
||||
config.read(keysPath)#read again since changes have been made
|
||||
apiPort = int(config.get('bitmessagesettings', 'apiport'))
|
||||
apiInterface = config.get('bitmessagesettings', 'apiinterface')
|
||||
apiUsername = config.get('bitmessagesettings', 'apiusername')
|
||||
apiPassword = config.get('bitmessagesettings', 'apipassword')
|
||||
|
||||
print '\n API data successfully imported.\n'
|
||||
|
||||
return "http://" + apiUsername + ":" + apiPassword + "@" + apiInterface+ ":" + str(apiPort) + "/" #Build the api credentials
|
||||
|
||||
#End keys.dat interactions
|
||||
|
||||
|
||||
def apiTest(): #Tests the API connection to bitmessage. Returns true if it is connected.
|
||||
|
||||
try:
|
||||
result = api.add(2,3)
|
||||
except:
|
||||
return False
|
||||
|
||||
if (result == 5):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def bmSettings(): #Allows the viewing and modification of keys.dat settings.
|
||||
global keysPath
|
||||
global usrPrompt
|
||||
config = ConfigParser.SafeConfigParser()
|
||||
keysPath = 'keys.dat'
|
||||
|
||||
config.read(keysPath)#Read the keys.dat
|
||||
try:
|
||||
port = config.get('bitmessagesettings', 'port')
|
||||
except:
|
||||
print '\n File not found.\n'
|
||||
usrPrompt = 0
|
||||
main()
|
||||
|
||||
startonlogon = safeConfigGetBoolean('bitmessagesettings', 'startonlogon')
|
||||
minimizetotray = safeConfigGetBoolean('bitmessagesettings', 'minimizetotray')
|
||||
showtraynotifications = safeConfigGetBoolean('bitmessagesettings', 'showtraynotifications')
|
||||
startintray = safeConfigGetBoolean('bitmessagesettings', 'startintray')
|
||||
defaultnoncetrialsperbyte = config.get('bitmessagesettings', 'defaultnoncetrialsperbyte')
|
||||
defaultpayloadlengthextrabytes = config.get('bitmessagesettings', 'defaultpayloadlengthextrabytes')
|
||||
daemon = safeConfigGetBoolean('bitmessagesettings', 'daemon')
|
||||
|
||||
socksproxytype = config.get('bitmessagesettings', 'socksproxytype')
|
||||
sockshostname = config.get('bitmessagesettings', 'sockshostname')
|
||||
socksport = config.get('bitmessagesettings', 'socksport')
|
||||
socksauthentication = safeConfigGetBoolean('bitmessagesettings', 'socksauthentication')
|
||||
socksusername = config.get('bitmessagesettings', 'socksusername')
|
||||
sockspassword = config.get('bitmessagesettings', 'sockspassword')
|
||||
|
||||
|
||||
print '\n -----------------------------------'
|
||||
print ' | Current Bitmessage Settings |'
|
||||
print ' -----------------------------------'
|
||||
print ' port = ' + port
|
||||
print ' startonlogon = ' + str(startonlogon)
|
||||
print ' minimizetotray = ' + str(minimizetotray)
|
||||
print ' showtraynotifications = ' + str(showtraynotifications)
|
||||
print ' startintray = ' + str(startintray)
|
||||
print ' defaultnoncetrialsperbyte = ' + defaultnoncetrialsperbyte
|
||||
print ' defaultpayloadlengthextrabytes = ' + defaultpayloadlengthextrabytes
|
||||
print ' daemon = ' + str(daemon)
|
||||
print '\n ------------------------------------'
|
||||
print ' | Current Connection Settings |'
|
||||
print ' -----------------------------------'
|
||||
print ' socksproxytype = ' + socksproxytype
|
||||
print ' sockshostname = ' + sockshostname
|
||||
print ' socksport = ' + socksport
|
||||
print ' socksauthentication = ' + str(socksauthentication)
|
||||
print ' socksusername = ' + socksusername
|
||||
print ' sockspassword = ' + sockspassword
|
||||
print ' '
|
||||
|
||||
uInput = userInput("Would you like to modify any of these settings, (Y)es or (N)o?").lower()
|
||||
|
||||
if uInput == "y":
|
||||
while True: #loops if they mistype the setting name, they can exit the loop with 'exit'
|
||||
invalidInput = False
|
||||
uInput = userInput("What setting would you like to modify?").lower()
|
||||
print ' '
|
||||
|
||||
if uInput == "port":
|
||||
print ' Current port number: ' + port
|
||||
uInput = userInput("Enter the new port number.")
|
||||
config.set('bitmessagesettings', 'port', str(uInput))
|
||||
elif uInput == "startonlogon":
|
||||
print ' Current status: ' + str(startonlogon)
|
||||
uInput = userInput("Enter the new status.")
|
||||
config.set('bitmessagesettings', 'startonlogon', str(uInput))
|
||||
elif uInput == "minimizetotray":
|
||||
print ' Current status: ' + str(minimizetotray)
|
||||
uInput = userInput("Enter the new status.")
|
||||
config.set('bitmessagesettings', 'minimizetotray', str(uInput))
|
||||
elif uInput == "showtraynotifications":
|
||||
print ' Current status: ' + str(showtraynotifications)
|
||||
uInput = userInput("Enter the new status.")
|
||||
config.set('bitmessagesettings', 'showtraynotifications', str(uInput))
|
||||
elif uInput == "startintray":
|
||||
print ' Current status: ' + str(startintray)
|
||||
uInput = userInput("Enter the new status.")
|
||||
config.set('bitmessagesettings', 'startintray', str(uInput))
|
||||
elif uInput == "defaultnoncetrialsperbyte":
|
||||
print ' Current default nonce trials per byte: ' + defaultnoncetrialsperbyte
|
||||
uInput = userInput("Enter the new defaultnoncetrialsperbyte.")
|
||||
config.set('bitmessagesettings', 'defaultnoncetrialsperbyte', str(uInput))
|
||||
elif uInput == "defaultpayloadlengthextrabytes":
|
||||
print ' Current default payload length extra bytes: ' + defaultpayloadlengthextrabytes
|
||||
uInput = userInput("Enter the new defaultpayloadlengthextrabytes.")
|
||||
config.set('bitmessagesettings', 'defaultpayloadlengthextrabytes', str(uInput))
|
||||
elif uInput == "daemon":
|
||||
print ' Current status: ' + str(daemon)
|
||||
uInput = userInput("Enter the new status.").lower()
|
||||
config.set('bitmessagesettings', 'daemon', str(uInput))
|
||||
elif uInput == "socksproxytype":
|
||||
print ' Current socks proxy type: ' + socksproxytype
|
||||
print "Possibilities: 'none', 'SOCKS4a', 'SOCKS5'."
|
||||
uInput = userInput("Enter the new socksproxytype.")
|
||||
config.set('bitmessagesettings', 'socksproxytype', str(uInput))
|
||||
elif uInput == "sockshostname":
|
||||
print ' Current socks host name: ' + sockshostname
|
||||
uInput = userInput("Enter the new sockshostname.")
|
||||
config.set('bitmessagesettings', 'sockshostname', str(uInput))
|
||||
elif uInput == "socksport":
|
||||
print ' Current socks port number: ' + socksport
|
||||
uInput = userInput("Enter the new socksport.")
|
||||
config.set('bitmessagesettings', 'socksport', str(uInput))
|
||||
elif uInput == "socksauthentication":
|
||||
print ' Current status: ' + str(socksauthentication)
|
||||
uInput = userInput("Enter the new status.")
|
||||
config.set('bitmessagesettings', 'socksauthentication', str(uInput))
|
||||
elif uInput == "socksusername":
|
||||
print ' Current socks username: ' + socksusername
|
||||
uInput = userInput("Enter the new socksusername.")
|
||||
config.set('bitmessagesettings', 'socksusername', str(uInput))
|
||||
elif uInput == "sockspassword":
|
||||
print ' Current socks password: ' + sockspassword
|
||||
uInput = userInput("Enter the new password.")
|
||||
config.set('bitmessagesettings', 'sockspassword', str(uInput))
|
||||
else:
|
||||
print "\n Invalid input. Please try again.\n"
|
||||
invalidInput = True
|
||||
|
||||
if invalidInput != True: #don't prompt if they made a mistake.
|
||||
uInput = userInput("Would you like to change another setting, (Y)es or (N)o?").lower()
|
||||
|
||||
if uInput != "y":
|
||||
print '\n Changes Made.\n'
|
||||
with open(keysPath, 'wb') as configfile:
|
||||
config.write(configfile)
|
||||
restartBmNotify()
|
||||
break
|
||||
|
||||
|
||||
elif uInput == "n":
|
||||
usrPrompt = 1
|
||||
main()
|
||||
else:
|
||||
print "Invalid input."
|
||||
usrPrompt = 1
|
||||
main()
|
||||
|
||||
def validAddress(address):
|
||||
address_information = api.decodeAddress(address)
|
||||
address_information = eval(address_information)
|
||||
|
||||
if 'success' in str(address_information.get('status')).lower():
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def getAddress(passphrase,vNumber,sNumber):
|
||||
passphrase = passphrase.encode('base64')#passphrase must be encoded
|
||||
|
||||
return api.getDeterministicAddress(passphrase,vNumber,sNumber)
|
||||
|
||||
def subscribe():
|
||||
global usrPrompt
|
||||
|
||||
while True:
|
||||
address = userInput("What address would you like to subscribe to?")
|
||||
|
||||
if (address == "c"):
|
||||
usrPrompt = 1
|
||||
print ' '
|
||||
main()
|
||||
elif (validAddress(address)== False):
|
||||
print '\n Invalid. "c" to cancel. Please try again.\n'
|
||||
else:
|
||||
break
|
||||
|
||||
label = userInput("Enter a label for this address.")
|
||||
label = label.encode('base64')
|
||||
|
||||
api.addSubscription(address,label)
|
||||
print ('\n You are now subscribed to: ' + address + '\n')
|
||||
|
||||
def unsubscribe():
|
||||
global usrPrompt
|
||||
|
||||
while True:
|
||||
address = userInput("What address would you like to unsubscribe from?")
|
||||
|
||||
if (address == "c"):
|
||||
usrPrompt = 1
|
||||
print ' '
|
||||
main()
|
||||
elif (validAddress(address)== False):
|
||||
print '\n Invalid. "c" to cancel. Please try again.\n'
|
||||
else:
|
||||
break
|
||||
|
||||
|
||||
uInput = userInput("Are you sure, (Y)es or (N)o?").lower()
|
||||
|
||||
api.deleteSubscription(address)
|
||||
print ('\n You are now unsubscribed from: ' + address + '\n')
|
||||
|
||||
def listSubscriptions():
|
||||
global usrPrompt
|
||||
#jsonAddresses = json.loads(api.listSubscriptions())
|
||||
#numAddresses = len(jsonAddresses['addresses']) #Number of addresses
|
||||
print '\nLabel, Address, Enabled\n'
|
||||
try:
|
||||
print api.listSubscriptions()
|
||||
except:
|
||||
print '\n Connection Error\n'
|
||||
usrPrompt = 0
|
||||
main()
|
||||
|
||||
'''for addNum in range (0, numAddresses): #processes all of the addresses and lists them out
|
||||
label = jsonAddresses['addresses'][addNum]['label']
|
||||
address = jsonAddresses['addresses'][addNum]['address']
|
||||
enabled = jsonAddresses['addresses'][addNum]['enabled']
|
||||
|
||||
print label, address, enabled
|
||||
'''
|
||||
print ' '
|
||||
|
||||
def createChan():
|
||||
global usrPrompt
|
||||
password = userInput("Enter channel name")
|
||||
password = password.encode('base64')
|
||||
try:
|
||||
print api.createChan(password)
|
||||
except:
|
||||
print '\n Connection Error\n'
|
||||
usrPrompt = 0
|
||||
main()
|
||||
|
||||
|
||||
def joinChan():
|
||||
global usrPrompt
|
||||
while True:
|
||||
address = userInput("Enter channel address")
|
||||
|
||||
if (address == "c"):
|
||||
usrPrompt = 1
|
||||
print ' '
|
||||
main()
|
||||
elif (validAddress(address)== False):
|
||||
print '\n Invalid. "c" to cancel. Please try again.\n'
|
||||
else:
|
||||
break
|
||||
|
||||
password = userInput("Enter channel name")
|
||||
password = password.encode('base64')
|
||||
try:
|
||||
print api.joinChan(password,address)
|
||||
except:
|
||||
print '\n Connection Error\n'
|
||||
usrPrompt = 0
|
||||
main()
|
||||
|
||||
def leaveChan():
|
||||
global usrPrompt
|
||||
while True:
|
||||
address = userInput("Enter channel address")
|
||||
|
||||
if (address == "c"):
|
||||
usrPrompt = 1
|
||||
print ' '
|
||||
main()
|
||||
elif (validAddress(address)== False):
|
||||
print '\n Invalid. "c" to cancel. Please try again.\n'
|
||||
else:
|
||||
break
|
||||
|
||||
try:
|
||||
print api.leaveChan(address)
|
||||
except:
|
||||
print '\n Connection Error\n'
|
||||
usrPrompt = 0
|
||||
main()
|
||||
|
||||
|
||||
def listAdd(): #Lists all of the addresses and their info
|
||||
global usrPrompt
|
||||
try:
|
||||
jsonAddresses = json.loads(api.listAddresses())
|
||||
numAddresses = len(jsonAddresses['addresses']) #Number of addresses
|
||||
except:
|
||||
print '\n Connection Error\n'
|
||||
usrPrompt = 0
|
||||
main()
|
||||
|
||||
#print '\nAddress Number,Label,Address,Stream,Enabled\n'
|
||||
print '\n --------------------------------------------------------------------------'
|
||||
print ' | # | Label | Address |S#|Enabled|'
|
||||
print ' |---|-------------------|-------------------------------------|--|-------|'
|
||||
for addNum in range (0, numAddresses): #processes all of the addresses and lists them out
|
||||
label = str(jsonAddresses['addresses'][addNum]['label'])
|
||||
address = str(jsonAddresses['addresses'][addNum]['address'])
|
||||
stream = str(jsonAddresses['addresses'][addNum]['stream'])
|
||||
enabled = str(jsonAddresses['addresses'][addNum]['enabled'])
|
||||
|
||||
if (len(label) > 19):
|
||||
label = label[:16] + '...'
|
||||
|
||||
print ' |' + str(addNum).ljust(3) + '|' + label.ljust(19) + '|' + address.ljust(37) + '|' + stream.ljust(1), '|' + enabled |