Merge PR 1249 into v0.6

This commit is contained in:
Peter Šurda 2018-05-21 08:56:36 +02:00
commit 7313a4687e
Signed by: PeterSurda
GPG Key ID: 0C5F50C0B5F37D87

View File

@ -1,15 +1,20 @@
#!/usr/bin/python2.7 #!/usr/bin/python2.7
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Created by Adam Melton (.dok) referenceing https://bitmessage.org/wiki/API_Reference for API documentation # pylint: disable=too-many-lines,global-statement,too-many-branches,too-many-statements,inconsistent-return-statements
# Distributed under the MIT/X11 software license. See http://www.opensource.org/licenses/mit-license.php. # pylint: disable=too-many-nested-blocks,too-many-locals,protected-access,too-many-arguments,too-many-function-args
# pylint: disable=no-member
"""
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.6.2, by .dok (Version 0.3.1) , modified This is an example of a daemon client for PyBitmessage 0.6.2, by .dok (Version 0.3.1) , modified
TODO: fix the following (currently ignored) violations:
"""
import xmlrpclib import xmlrpclib
import datetime import datetime
#import hashlib
#import getopt
import imghdr import imghdr
import ntpath import ntpath
import json import json
@ -20,54 +25,73 @@ import os
from bmconfigparser import BMConfigParser from bmconfigparser import BMConfigParser
api = '' api = ''
keysName = 'keys.dat' keysName = 'keys.dat'
keysPath = 'keys.dat' keysPath = 'keys.dat'
usrPrompt = 0 #0 = First Start, 1 = prompt, 2 = no prompt if the program is starting up usrPrompt = 0 # 0 = First Start, 1 = prompt, 2 = no prompt if the program is starting up
knownAddresses = dict() knownAddresses = dict()
def userInput(message): #Checks input for exit or quit. Also formats for input, etc
def userInput(message):
"""Checks input for exit or quit. Also formats for input, etc"""
global usrPrompt global usrPrompt
print '\n' + message print '\n' + message
uInput = raw_input('> ') uInput = raw_input('> ')
if (uInput.lower() == 'exit'): #Returns the user to the main menu if uInput.lower() == 'exit': # Returns the user to the main menu
usrPrompt = 1 usrPrompt = 1
main() main()
elif (uInput.lower() == 'quit'): #Quits the program elif uInput.lower() == 'quit': # Quits the program
print '\n Bye\n' print '\n Bye\n'
sys.exit() sys.exit(0)
os._exit() # _
else: else:
return uInput return uInput
def restartBmNotify(): #Prompts the user to restart Bitmessage.
def restartBmNotify():
"""Prompt the user to restart Bitmessage"""
print '\n *******************************************************************' print '\n *******************************************************************'
print ' WARNING: If Bitmessage is running locally, you must restart it now.' print ' WARNING: If Bitmessage is running locally, you must restart it now.'
print ' *******************************************************************\n' print ' *******************************************************************\n'
#Begin keys.dat interactions
def lookupAppdataFolder(): #gets the appropriate folders for the .dat files depending on the OS. Taken from bitmessagemain.py # Begin keys.dat interactions
def lookupAppdataFolder():
"""gets the appropriate folders for the .dat files depending on the OS. Taken from bitmessagemain.py"""
APPNAME = "PyBitmessage" APPNAME = "PyBitmessage"
from os import path, environ
if sys.platform == 'darwin': if sys.platform == 'darwin':
if "HOME" in environ: if "HOME" in os.environ:
dataFolder = path.join(os.environ["HOME"], "Library/Application support/", APPNAME) + '/' dataFolder = os.path.join(os.environ["HOME"], "Library/Application support/", APPNAME) + '/'
else: else:
print ' Could not find home folder, please report this message and your OS X version to the Daemon Github.' print(
os._exit() ' Could not find home folder, please report '
'this message and your OS X version to the Daemon Github.')
sys.exit(1)
elif 'win32' in sys.platform or 'win64' in sys.platform: elif 'win32' in sys.platform or 'win64' in sys.platform:
dataFolder = path.join(environ['APPDATA'], APPNAME) + '\\' dataFolder = os.path.join(os.environ['APPDATA'], APPNAME) + '\\'
else: else:
dataFolder = path.expanduser(path.join("~", ".config/" + APPNAME + "/")) dataFolder = os.path.expanduser(os.path.join("~", ".config/" + APPNAME + "/"))
return dataFolder return dataFolder
def configInit(): def configInit():
"""Initialised the configuration"""
BMConfigParser().add_section('bitmessagesettings') BMConfigParser().add_section('bitmessagesettings')
BMConfigParser().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. # Sets the bitmessage port to stop the warning about the api not properly
BMConfigParser().set('bitmessagesettings','apienabled','true') #Sets apienabled to true in keys.dat # 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.
BMConfigParser().set('bitmessagesettings', 'port', '8444')
BMConfigParser().set('bitmessagesettings', 'apienabled', 'true') # Sets apienabled to true in keys.dat
with open(keysName, 'wb') as configfile: with open(keysName, 'wb') as configfile:
BMConfigParser().write(configfile) BMConfigParser().write(configfile)
@ -75,17 +99,18 @@ def configInit():
print '\n ' + str(keysName) + ' Initalized in the same directory as daemon.py' print '\n ' + str(keysName) + ' Initalized in the same directory as daemon.py'
print ' You will now need to configure the ' + str(keysName) + ' file.\n' print ' You will now need to configure the ' + str(keysName) + ' file.\n'
def apiInit(apiEnabled): def apiInit(apiEnabled):
"""Initialise the API"""
global usrPrompt global usrPrompt
BMConfigParser().read(keysPath) BMConfigParser().read(keysPath)
if apiEnabled is False: # API information there but the api is disabled.
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() uInput = userInput("The API is not enabled. Would you like to do that now, (Y)es or (N)o?").lower()
if uInput == "y": # if uInput == "y":
BMConfigParser().set('bitmessagesettings','apienabled','true') #Sets apienabled to true in keys.dat BMConfigParser().set('bitmessagesettings', 'apienabled', 'true') # Sets apienabled to true in keys.dat
with open(keysPath, 'wb') as configfile: with open(keysPath, 'wb') as configfile:
BMConfigParser().write(configfile) BMConfigParser().write(configfile)
@ -105,20 +130,20 @@ def apiInit(apiEnabled):
print '\n Invalid Entry\n' print '\n Invalid Entry\n'
usrPrompt = 1 usrPrompt = 1
main() main()
elif (apiEnabled == True): #API correctly setup
#Everything is as it should be elif apiEnabled: # API correctly setup
# Everything is as it should be
return True return True
else: #API information was not present. else: # API information was not present.
print '\n ' + str(keysPath) + ' not properly configured!\n' print '\n ' + str(keysPath) + ' not properly configured!\n'
uInput = userInput("Would you like to do this now, (Y)es or (N)o?").lower() 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 if uInput == "y": # User said yes, initalize the api by writing these values to the keys.dat file
print ' ' print ' '
apiUsr = userInput("API Username") apiUsr = userInput("API Username")
apiPwd = userInput("API Password") apiPwd = userInput("API Password")
#apiInterface = userInput("API Interface. (127.0.0.1)")
apiPort = userInput("API Port") apiPort = userInput("API Port")
apiEnabled = userInput("API Enabled? (True) or (False)").lower() apiEnabled = userInput("API Enabled? (True) or (False)").lower()
daemon = userInput("Daemon mode Enabled? (True) or (False)").lower() daemon = userInput("Daemon mode Enabled? (True) or (False)").lower()
@ -130,8 +155,11 @@ def apiInit(apiEnabled):
print ' -----------------------------------\n' print ' -----------------------------------\n'
BMConfigParser().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. # sets the bitmessage port to stop the warning about the api not properly
BMConfigParser().set('bitmessagesettings','apienabled','true') # 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.
BMConfigParser().set('bitmessagesettings', 'port', '8444')
BMConfigParser().set('bitmessagesettings', 'apienabled', 'true')
BMConfigParser().set('bitmessagesettings', 'apiport', apiPort) BMConfigParser().set('bitmessagesettings', 'apiport', apiPort)
BMConfigParser().set('bitmessagesettings', 'apiinterface', '127.0.0.1') BMConfigParser().set('bitmessagesettings', 'apiinterface', '127.0.0.1')
BMConfigParser().set('bitmessagesettings', 'apiusername', apiUsr) BMConfigParser().set('bitmessagesettings', 'apiusername', apiUsr)
@ -157,25 +185,27 @@ def apiInit(apiEnabled):
def apiData(): def apiData():
"""TBC"""
global keysName global keysName
global keysPath global keysPath
global usrPrompt global usrPrompt
BMConfigParser().read(keysPath) #First try to load the config file (the keys.dat file) from the program directory BMConfigParser().read(keysPath) # First try to load the config file (the keys.dat file) from the program directory
try: try:
BMConfigParser().get('bitmessagesettings','port') BMConfigParser().get('bitmessagesettings', 'port')
appDataFolder = '' appDataFolder = ''
except: except:
#Could not load the keys.dat file in the program directory. Perhaps it is in the appdata directory. # Could not load the keys.dat file in the program directory. Perhaps it is in the appdata directory.
appDataFolder = lookupAppdataFolder() appDataFolder = lookupAppdataFolder()
keysPath = appDataFolder + keysPath keysPath = appDataFolder + keysPath
BMConfigParser().read(keysPath) BMConfigParser().read(keysPath)
try: try:
BMConfigParser().get('bitmessagesettings','port') BMConfigParser().get('bitmessagesettings', 'port')
except: except:
#keys.dat was not there either, something is wrong. # keys.dat was not there either, something is wrong.
print '\n ******************************************************************' print '\n ******************************************************************'
print ' There was a problem trying to access the Bitmessage keys.dat file' print ' There was a problem trying to access the Bitmessage keys.dat file'
print ' or keys.dat is not set up correctly' print ' or keys.dat is not set up correctly'
@ -199,18 +229,21 @@ def apiData():
usrPrompt = 1 usrPrompt = 1
main() main()
try: #checks to make sure that everyting is configured correctly. Excluding apiEnabled, it is checked after try: # checks to make sure that everyting is configured correctly. Excluding apiEnabled, it is checked after
BMConfigParser().get('bitmessagesettings', 'apiport') BMConfigParser().get('bitmessagesettings', 'apiport')
BMConfigParser().get('bitmessagesettings', 'apiinterface') BMConfigParser().get('bitmessagesettings', 'apiinterface')
BMConfigParser().get('bitmessagesettings', 'apiusername') BMConfigParser().get('bitmessagesettings', 'apiusername')
BMConfigParser().get('bitmessagesettings', 'apipassword') BMConfigParser().get('bitmessagesettings', 'apipassword')
except: except:
apiInit("") #Initalize the keys.dat file with API information apiInit("") # Initalize the keys.dat file with API information
#keys.dat file was found or appropriately configured, allow information retrieval # keys.dat file was found or appropriately configured, allow information retrieval
#apiEnabled = apiInit(BMConfigParser().safeGetBoolean('bitmessagesettings','apienabled')) #if false it will prompt the user, if true it will return true # apiEnabled =
# apiInit(BMConfigParser().safeGetBoolean('bitmessagesettings','apienabled'))
# #if false it will prompt the user, if true it will return true
BMConfigParser().read(keysPath)#read again since changes have been made BMConfigParser().read(keysPath) # read again since changes have been made
apiPort = int(BMConfigParser().get('bitmessagesettings', 'apiport')) apiPort = int(BMConfigParser().get('bitmessagesettings', 'apiport'))
apiInterface = BMConfigParser().get('bitmessagesettings', 'apiinterface') apiInterface = BMConfigParser().get('bitmessagesettings', 'apiinterface')
apiUsername = BMConfigParser().get('bitmessagesettings', 'apiusername') apiUsername = BMConfigParser().get('bitmessagesettings', 'apiusername')
@ -218,29 +251,33 @@ def apiData():
print '\n API data successfully imported.\n' print '\n API data successfully imported.\n'
return "http://" + apiUsername + ":" + apiPassword + "@" + apiInterface+ ":" + str(apiPort) + "/" #Build the api credentials # Build the api credentials
return "http://" + apiUsername + ":" + apiPassword + "@" + apiInterface + ":" + str(apiPort) + "/"
#End keys.dat interactions
def apiTest(): #Tests the API connection to bitmessage. Returns true if it is connected. # End keys.dat interactions
def apiTest():
"""Tests the API connection to bitmessage. Returns true if it is connected."""
try: try:
result = api.add(2,3) result = api.add(2, 3)
except: except:
return False return False
if (result == 5): return result == 5
return True
else:
return False def bmSettings():
"""Allows the viewing and modification of keys.dat settings."""
def bmSettings(): #Allows the viewing and modification of keys.dat settings.
global keysPath global keysPath
global usrPrompt global usrPrompt
keysPath = 'keys.dat' keysPath = 'keys.dat'
BMConfigParser().read(keysPath)#Read the keys.dat BMConfigParser().read(keysPath) # Read the keys.dat
try: try:
port = BMConfigParser().get('bitmessagesettings', 'port') port = BMConfigParser().get('bitmessagesettings', 'port')
except: except:
@ -263,7 +300,6 @@ def bmSettings(): #Allows the viewing and modification of keys.dat settings.
socksusername = BMConfigParser().get('bitmessagesettings', 'socksusername') socksusername = BMConfigParser().get('bitmessagesettings', 'socksusername')
sockspassword = BMConfigParser().get('bitmessagesettings', 'sockspassword') sockspassword = BMConfigParser().get('bitmessagesettings', 'sockspassword')
print '\n -----------------------------------' print '\n -----------------------------------'
print ' | Current Bitmessage Settings |' print ' | Current Bitmessage Settings |'
print ' -----------------------------------' print ' -----------------------------------'
@ -289,7 +325,7 @@ def bmSettings(): #Allows the viewing and modification of keys.dat settings.
uInput = userInput("Would you like to modify any of these settings, (Y)es or (N)o?").lower() uInput = userInput("Would you like to modify any of these settings, (Y)es or (N)o?").lower()
if uInput == "y": if uInput == "y":
while True: #loops if they mistype the setting name, they can exit the loop with 'exit' while True: # loops if they mistype the setting name, they can exit the loop with 'exit'
invalidInput = False invalidInput = False
uInput = userInput("What setting would you like to modify?").lower() uInput = userInput("What setting would you like to modify?").lower()
print ' ' print ' '
@ -355,7 +391,7 @@ def bmSettings(): #Allows the viewing and modification of keys.dat settings.
print "\n Invalid input. Please try again.\n" print "\n Invalid input. Please try again.\n"
invalidInput = True invalidInput = True
if invalidInput != True: #don't prompt if they made a mistake. if invalidInput is not True: # don't prompt if they made a mistake.
uInput = userInput("Would you like to change another setting, (Y)es or (N)o?").lower() uInput = userInput("Would you like to change another setting, (Y)es or (N)o?").lower()
if uInput != "y": if uInput != "y":
@ -365,7 +401,6 @@ def bmSettings(): #Allows the viewing and modification of keys.dat settings.
restartBmNotify() restartBmNotify()
break break
elif uInput == "n": elif uInput == "n":
usrPrompt = 1 usrPrompt = 1
main() main()
@ -374,30 +409,33 @@ def bmSettings(): #Allows the viewing and modification of keys.dat settings.
usrPrompt = 1 usrPrompt = 1
main() main()
def validAddress(address): def validAddress(address):
"""Predicate to test address validity"""
address_information = json.loads(api.decodeAddress(address)) address_information = json.loads(api.decodeAddress(address))
if 'success' in str(address_information['status']).lower(): return 'success' in str(address_information['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 getAddress(passphrase, vNumber, sNumber):
"""Get a deterministic address"""
passphrase = passphrase.encode('base64') # passphrase must be encoded
return api.getDeterministicAddress(passphrase, vNumber, sNumber)
def subscribe(): def subscribe():
"""Subscribe to an address"""
global usrPrompt global usrPrompt
while True: while True:
address = userInput("What address would you like to subscribe to?") address = userInput("What address would you like to subscribe to?")
if (address == "c"): if address == "c":
usrPrompt = 1 usrPrompt = 1
print ' ' print ' '
main() main()
elif (validAddress(address)== False): elif validAddress(address) is False:
print '\n Invalid. "c" to cancel. Please try again.\n' print '\n Invalid. "c" to cancel. Please try again.\n'
else: else:
break break
@ -405,34 +443,36 @@ def subscribe():
label = userInput("Enter a label for this address.") label = userInput("Enter a label for this address.")
label = label.encode('base64') label = label.encode('base64')
api.addSubscription(address,label) api.addSubscription(address, label)
print ('\n You are now subscribed to: ' + address + '\n') print '\n You are now subscribed to: ' + address + '\n'
def unsubscribe(): def unsubscribe():
"""Unsusbcribe from an address"""
global usrPrompt global usrPrompt
while True: while True:
address = userInput("What address would you like to unsubscribe from?") address = userInput("What address would you like to unsubscribe from?")
if (address == "c"): if address == "c":
usrPrompt = 1 usrPrompt = 1
print ' ' print ' '
main() main()
elif (validAddress(address)== False): elif validAddress(address) is False:
print '\n Invalid. "c" to cancel. Please try again.\n' print '\n Invalid. "c" to cancel. Please try again.\n'
else: else:
break break
userInput("Are you sure, (Y)es or (N)o?").lower() # uInput =
userInput("Are you sure, (Y)es or (N)o?").lower() # #uInput =
api.deleteSubscription(address) api.deleteSubscription(address)
print ('\n You are now unsubscribed from: ' + address + '\n') print '\n You are now unsubscribed from: ' + address + '\n'
def listSubscriptions(): def listSubscriptions():
"""List subscriptions"""
global usrPrompt global usrPrompt
#jsonAddresses = json.loads(api.listSubscriptions())
#numAddresses = len(jsonAddresses['addresses']) #Number of addresses
print '\nLabel, Address, Enabled\n' print '\nLabel, Address, Enabled\n'
try: try:
print api.listSubscriptions() print api.listSubscriptions()
@ -440,17 +480,12 @@ def listSubscriptions():
print '\n Connection Error\n' print '\n Connection Error\n'
usrPrompt = 0 usrPrompt = 0
main() 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 ' ' print ' '
def createChan(): def createChan():
"""Create a channel"""
global usrPrompt global usrPrompt
password = userInput("Enter channel name") password = userInput("Enter channel name")
password = password.encode('base64') password = password.encode('base64')
@ -463,15 +498,17 @@ def createChan():
def joinChan(): def joinChan():
"""Join a channel"""
global usrPrompt global usrPrompt
while True: while True:
address = userInput("Enter channel address") address = userInput("Enter channel address")
if (address == "c"): if address == "c":
usrPrompt = 1 usrPrompt = 1
print ' ' print ' '
main() main()
elif (validAddress(address)== False): elif validAddress(address) is False:
print '\n Invalid. "c" to cancel. Please try again.\n' print '\n Invalid. "c" to cancel. Please try again.\n'
else: else:
break break
@ -479,22 +516,25 @@ def joinChan():
password = userInput("Enter channel name") password = userInput("Enter channel name")
password = password.encode('base64') password = password.encode('base64')
try: try:
print api.joinChan(password,address) print api.joinChan(password, address)
except: except:
print '\n Connection Error\n' print '\n Connection Error\n'
usrPrompt = 0 usrPrompt = 0
main() main()
def leaveChan(): def leaveChan():
"""Leave a channel"""
global usrPrompt global usrPrompt
while True: while True:
address = userInput("Enter channel address") address = userInput("Enter channel address")
if (address == "c"): if address == "c":
usrPrompt = 1 usrPrompt = 1
print ' ' print ' '
main() main()
elif (validAddress(address)== False): elif validAddress(address) is False:
print '\n Invalid. "c" to cancel. Please try again.\n' print '\n Invalid. "c" to cancel. Please try again.\n'
else: else:
break break
@ -507,36 +547,58 @@ def leaveChan():
main() main()
def listAdd(): #Lists all of the addresses and their info def listAdd():
"""List all of the addresses and their info"""
global usrPrompt global usrPrompt
try: try:
jsonAddresses = json.loads(api.listAddresses()) jsonAddresses = json.loads(api.listAddresses())
numAddresses = len(jsonAddresses['addresses']) #Number of addresses numAddresses = len(jsonAddresses['addresses']) # Number of addresses
except: except:
print '\n Connection Error\n' print '\n Connection Error\n'
usrPrompt = 0 usrPrompt = 0
main() main()
#print '\nAddress Number,Label,Address,Stream,Enabled\n' # print '\nAddress Number,Label,Address,Stream,Enabled\n'
print '\n --------------------------------------------------------------------------' print '\n --------------------------------------------------------------------------'
print ' | # | Label | Address |S#|Enabled|' print ' | # | Label | Address |S#|Enabled|'
print ' |---|-------------------|-------------------------------------|--|-------|' print ' |---|-------------------|-------------------------------------|--|-------|'
for addNum in range (0, numAddresses): #processes all of the addresses and lists them out for addNum in range(0, numAddresses): # processes all of the addresses and lists them out
label = (jsonAddresses['addresses'][addNum]['label' ]).encode('utf') # may still misdiplay in some consoles label = (jsonAddresses['addresses'][addNum]['label']).encode(
'utf') # may still misdiplay in some consoles
address = str(jsonAddresses['addresses'][addNum]['address']) address = str(jsonAddresses['addresses'][addNum]['address'])
stream = str(jsonAddresses['addresses'][addNum]['stream']) stream = str(jsonAddresses['addresses'][addNum]['stream'])
enabled = str(jsonAddresses['addresses'][addNum]['enabled']) enabled = str(jsonAddresses['addresses'][addNum]['enabled'])
if (len(label) > 19): if len(label) > 19:
label = label[:16] + '...' label = label[:16] + '...'
print ' |' + str(addNum).ljust(3) + '|' + label.ljust(19) + '|' + address.ljust(37) + '|' + stream.ljust(1), '|' + enabled.ljust(7) + '|' print ''.join(
' |',
str(addNum).ljust(3),
'|',
label.ljust(19),
'|',
address.ljust(37),
'|',
stream.ljust(1),
'|',
enabled.ljust(7),
'|',
)
print ' --------------------------------------------------------------------------\n' print ''.join(
' ',
74 * '-',
'\n',
)
def genAdd(lbl, deterministic, passphrase, numOfAdd, addVNum, streamNum, ripe):
"""Generate address"""
def genAdd(lbl,deterministic, passphrase, numOfAdd, addVNum, streamNum, ripe): #Generate address
global usrPrompt global usrPrompt
if deterministic == False: #Generates a new address with the user defined label. non-deterministic
if deterministic is False: # Generates a new address with the user defined label. non-deterministic
addressLabel = lbl.encode('base64') addressLabel = lbl.encode('base64')
try: try:
generatedAddress = api.createRandomAddress(addressLabel) generatedAddress = api.createRandomAddress(addressLabel)
@ -547,7 +609,7 @@ def genAdd(lbl,deterministic, passphrase, numOfAdd, addVNum, streamNum, ripe): #
return generatedAddress return generatedAddress
elif deterministic == True: #Generates a new deterministic address with the user inputs. elif deterministic: # Generates a new deterministic address with the user inputs.
passphrase = passphrase.encode('base64') passphrase = passphrase.encode('base64')
try: try:
generatedAddress = api.createDeterministicAddresses(passphrase, numOfAdd, addVNum, streamNum, ripe) generatedAddress = api.createDeterministicAddresses(passphrase, numOfAdd, addVNum, streamNum, ripe)
@ -556,55 +618,17 @@ def genAdd(lbl,deterministic, passphrase, numOfAdd, addVNum, streamNum, ripe): #
usrPrompt = 0 usrPrompt = 0
main() main()
return generatedAddress return generatedAddress
else:
return 'Entry Error'
def delMilAddr(): #Delete address return 'Entry Error'
global usrPrompt
try:
response = api.listAddresses2()
# if api is too old just return then fail
if "API Error 0020" in response: return
addresses = json.loads(response)
for entry in addresses['addresses']:
if entry['label'].decode('base64')[:6] == "random":
api.deleteAddress(entry['address'])
except:
print '\n Connection Error\n'
usrPrompt = 0
main()
def genMilAddr(): #Generate address
global usrPrompt
maxn = 0
try:
response = api.listAddresses2()
if "API Error 0020" in response: return
addresses = json.loads(response)
for entry in addresses['addresses']:
if entry['label'].decode('base64')[:6] == "random":
newn = int(entry['label'].decode('base64')[6:])
if maxn < newn:
maxn = newn
except:
print "\n Some error\n"
print "\n Starting at " + str(maxn) + "\n"
for i in range(maxn, 10000):
lbl = "random" + str(i)
addressLabel = lbl.encode('base64')
try:
api.createRandomAddress(addressLabel) # generatedAddress =
except:
print '\n Connection Error\n'
usrPrompt = 0
main()
def saveFile(fileName, fileData): #Allows attachments and messages/broadcats to be saved def saveFile(fileName, fileData):
"""Allows attachments and messages/broadcats to be saved"""
#This section finds all invalid characters and replaces them with ~ # This section finds all invalid characters and replaces them with ~
fileName = fileName.replace(" ", "") fileName = fileName.replace(" ", "")
fileName = fileName.replace("/", "~") fileName = fileName.replace("/", "~")
#fileName = fileName.replace("\\", "~") How do I get this to work...? # fileName = fileName.replace("\\", "~") How do I get this to work...?
fileName = fileName.replace(":", "~") fileName = fileName.replace(":", "~")
fileName = fileName.replace("*", "~") fileName = fileName.replace("*", "~")
fileName = fileName.replace("?", "~") fileName = fileName.replace("?", "~")
@ -613,27 +637,21 @@ def saveFile(fileName, fileData): #Allows attachments and messages/broadcats to
fileName = fileName.replace(">", "~") fileName = fileName.replace(">", "~")
fileName = fileName.replace("|", "~") fileName = fileName.replace("|", "~")
directory = 'attachments' directory = os.path.abspath('attachments')
if not os.path.exists(directory): if not os.path.exists(directory):
os.makedirs(directory) os.makedirs(directory)
filePath = directory +'/'+ fileName filePath = os.path.join(directory, fileName)
'''try: #Checks if file already exists with open(filePath, 'wb+') as path_to_file:
with open(filePath): path_to_file.write(fileData.decode("base64"))
print 'File Already Exists' print '\n Successfully saved ' + filePath + '\n'
return
except IOError: pass'''
f = open(filePath, 'wb+') #Begin saving to file def attachment():
f.write(fileData.decode("base64")) """Allows users to attach a file to their message or broadcast"""
f.close
print '\n Successfully saved '+ filePath + '\n'
def attachment(): #Allows users to attach a file to their message or broadcast
theAttachmentS = '' theAttachmentS = ''
while True: while True:
@ -641,35 +659,40 @@ def attachment(): #Allows users to attach a file to their message or broadcast
isImage = False isImage = False
theAttachment = '' theAttachment = ''
while True:#loops until valid path is entered while True: # loops until valid path is entered
filePath = userInput('\nPlease enter the path to the attachment or just the attachment name if in this folder.') filePath = userInput(
'\nPlease enter the path to the attachment or just the attachment name if in this folder.')
try: try:
with open(filePath): break with open(filePath):
break
except IOError: except IOError:
print '\n %s was not found on your filesystem or can not be opened.\n' % filePath print '\n %s was not found on your filesystem or can not be opened.\n' % filePath
pass
#print filesize, and encoding estimate with confirmation if file is over X size (1mb?) # print filesize, and encoding estimate with confirmation if file is over X size (1mb?)
invSize = os.path.getsize(filePath) invSize = os.path.getsize(filePath)
invSize = (invSize / 1024) #Converts to kilobytes invSize = (invSize / 1024) # Converts to kilobytes
round(invSize,2) #Rounds to two decimal places round(invSize, 2) # Rounds to two decimal places
if (invSize > 500.0):#If over 500KB if invSize > 500.0: # If over 500KB
print '\n WARNING:The file that you are trying to attach is ', invSize, 'KB and will take considerable time to send.\n' print ''.join(
'\n WARNING:The file that you are trying to attach is ',
invSize,
'KB and will take considerable time to send.\n'
)
uInput = userInput('Are you sure you still want to attach it, (Y)es or (N)o?').lower() uInput = userInput('Are you sure you still want to attach it, (Y)es or (N)o?').lower()
if uInput != "y": if uInput != "y":
print '\n Attachment discarded.\n' print '\n Attachment discarded.\n'
return '' return ''
elif (invSize > 184320.0): #If larger than 180MB, discard. elif invSize > 184320.0: # If larger than 180MB, discard.
print '\n Attachment too big, maximum allowed size:180MB\n' print '\n Attachment too big, maximum allowed size:180MB\n'
main() main()
pathLen = len(str(ntpath.basename(filePath))) #Gets the length of the filepath excluding the filename pathLen = len(str(ntpath.basename(filePath))) # Gets the length of the filepath excluding the filename
fileName = filePath[(len(str(filePath)) - pathLen):] #reads the filename fileName = filePath[(len(str(filePath)) - pathLen):] # reads the filename
filetype = imghdr.what(filePath) #Tests if it is an image file filetype = imghdr.what(filePath) # Tests if it is an image file
if filetype is not None: if filetype is not None:
print '\n ---------------------------------------------------' print '\n ---------------------------------------------------'
print ' Attachment detected as an Image.' print ' Attachment detected as an Image.'
@ -680,13 +703,14 @@ def attachment(): #Allows users to attach a file to their message or broadcast
isImage = True isImage = True
time.sleep(2) time.sleep(2)
print '\n Encoding Attachment, Please Wait ...\n' #Alert the user that the encoding process may take some time. # Alert the user that the encoding process may take some time.
print '\n Encoding Attachment, Please Wait ...\n'
with open(filePath, 'rb') as f: #Begin the actual encoding with open(filePath, 'rb') as f: # Begin the actual encoding
data = f.read(188743680) #Reads files up to 180MB, the maximum size for Bitmessage. data = f.read(188743680) # Reads files up to 180MB, the maximum size for Bitmessage.
data = data.encode("base64") data = data.encode("base64")
if (isImage == True): #If it is an image, include image tags in the message if isImage: # If it is an image, include image tags in the message
theAttachment = """ theAttachment = """
<!-- Note: Image attachment below. Please use the right click "View HTML code ..." option to view it. --> <!-- Note: Image attachment below. Please use the right click "View HTML code ..." option to view it. -->
<!-- Sent using Bitmessage Daemon. https://github.com/Dokument/PyBitmessage-Daemon --> <!-- Sent using Bitmessage Daemon. https://github.com/Dokument/PyBitmessage-Daemon -->
@ -699,8 +723,8 @@ Encoding:base64
<div id="image"> <div id="image">
<img alt = "%s" src='data:image/%s;base64, %s' /> <img alt = "%s" src='data:image/%s;base64, %s' />
</div> </div>
</center>""" % (fileName,invSize,fileName,filetype,data) </center>""" % (fileName, invSize, fileName, filetype, data)
else: #Else it is not an image so do not include the embedded image code. else: # Else it is not an image so do not include the embedded image code.
theAttachment = """ theAttachment = """
<!-- Note: File attachment below. Please use a base64 decoder, or Daemon, to save it. --> <!-- Note: File attachment below. Please use a base64 decoder, or Daemon, to save it. -->
<!-- Sent using Bitmessage Daemon. https://github.com/Dokument/PyBitmessage-Daemon --> <!-- Sent using Bitmessage Daemon. https://github.com/Dokument/PyBitmessage-Daemon -->
@ -709,44 +733,49 @@ Filename:%s
Filesize:%sKB Filesize:%sKB
Encoding:base64 Encoding:base64
<attachment alt = "%s" src='data:file/%s;base64, %s' />""" % (fileName,invSize,fileName,fileName,data) <attachment alt = "%s" src='data:file/%s;base64, %s' />""" % (fileName, invSize, fileName, fileName, data)
uInput = userInput('Would you like to add another attachment, (Y)es or (N)o?').lower() uInput = userInput('Would you like to add another attachment, (Y)es or (N)o?').lower()
if (uInput == 'y' or uInput == 'yes'):#Allows multiple attachments to be added to one message if uInput == 'y' or uInput == 'yes': # Allows multiple attachments to be added to one message
theAttachmentS = str(theAttachmentS) + str(theAttachment)+ '\n\n' theAttachmentS = str(theAttachmentS) + str(theAttachment) + '\n\n'
elif (uInput == 'n' or uInput == 'no'): elif uInput == 'n' or uInput == 'no':
break break
theAttachmentS = theAttachmentS + theAttachment theAttachmentS = theAttachmentS + theAttachment
return theAttachmentS return theAttachmentS
def sendMsg(toAddress, fromAddress, subject, message): #With no arguments sent, sendMsg fills in the blanks. subject and message must be encoded before they are passed.
def sendMsg(toAddress, fromAddress, subject, message):
"""
With no arguments sent, sendMsg fills in the blanks.
subject and message must be encoded before they are passed.
"""
global usrPrompt global usrPrompt
if (validAddress(toAddress)== False): if validAddress(toAddress) is False:
while True: while True:
toAddress = userInput("What is the To Address?") toAddress = userInput("What is the To Address?")
if (toAddress == "c"): if toAddress == "c":
usrPrompt = 1 usrPrompt = 1
print ' ' print ' '
main() main()
elif (validAddress(toAddress)== False): elif validAddress(toAddress) is False:
print '\n Invalid Address. "c" to cancel. Please try again.\n' print '\n Invalid Address. "c" to cancel. Please try again.\n'
else: else:
break break
if validAddress(fromAddress) is False:
if (validAddress(fromAddress)== False):
try: try:
jsonAddresses = json.loads(api.listAddresses()) jsonAddresses = json.loads(api.listAddresses())
numAddresses = len(jsonAddresses['addresses']) #Number of addresses numAddresses = len(jsonAddresses['addresses']) # Number of addresses
except: except:
print '\n Connection Error\n' print '\n Connection Error\n'
usrPrompt = 0 usrPrompt = 0
main() main()
if (numAddresses > 1): #Ask what address to send from if multiple addresses if numAddresses > 1: # Ask what address to send from if multiple addresses
found = False found = False
while True: while True:
print ' ' print ' '
@ -756,44 +785,39 @@ def sendMsg(toAddress, fromAddress, subject, message): #With no arguments sent,
usrPrompt = 1 usrPrompt = 1
main() main()
for addNum in range (0, numAddresses): #processes all of the addresses for addNum in range(0, numAddresses): # processes all of the addresses
label = jsonAddresses['addresses'][addNum]['label'] label = jsonAddresses['addresses'][addNum]['label']
address = jsonAddresses['addresses'][addNum]['address'] address = jsonAddresses['addresses'][addNum]['address']
#stream = jsonAddresses['addresses'][addNum]['stream'] if fromAddress == label: # address entered was a label and is found
#enabled = jsonAddresses['addresses'][addNum]['enabled']
if (fromAddress == label): #address entered was a label and is found
fromAddress = address fromAddress = address
found = True found = True
break break
if (found == False): if found is False:
if(validAddress(fromAddress)== False): if validAddress(fromAddress) is False:
print '\n Invalid Address. Please try again.\n' print '\n Invalid Address. Please try again.\n'
else: else:
for addNum in range (0, numAddresses): #processes all of the addresses for addNum in range(0, numAddresses): # processes all of the addresses
#label = jsonAddresses['addresses'][addNum]['label']
address = jsonAddresses['addresses'][addNum]['address'] address = jsonAddresses['addresses'][addNum]['address']
#stream = jsonAddresses['addresses'][addNum]['stream'] if fromAddress == address: # address entered was a found in our addressbook.
#enabled = jsonAddresses['addresses'][addNum]['enabled']
if (fromAddress == address): #address entered was a found in our addressbook.
found = True found = True
break break
if (found == False): if found is False:
print '\n The address entered is not one of yours. Please try again.\n' print '\n The address entered is not one of yours. Please try again.\n'
if (found == True): if found:
break #Address was found break # Address was found
else: #Only one address in address book else: # Only one address in address book
print '\n Using the only address in the addressbook to send from.\n' print '\n Using the only address in the addressbook to send from.\n'
fromAddress = jsonAddresses['addresses'][0]['address'] fromAddress = jsonAddresses['addresses'][0]['address']
if (subject == ''): if subject == '':
subject = userInput("Enter your Subject.") subject = userInput("Enter your Subject.")
subject = subject.encode('base64') subject = subject.encode('base64')
if (message == ''): if message == '':
message = userInput("Enter your Message.") message = userInput("Enter your Message.")
uInput = userInput('Would you like to add an attachment, (Y)es or (N)o?').lower() uInput = userInput('Would you like to add an attachment, (Y)es or (N)o?').lower()
@ -811,19 +835,21 @@ def sendMsg(toAddress, fromAddress, subject, message): #With no arguments sent,
main() main()
def sendBrd(fromAddress, subject, message): #sends a broadcast def sendBrd(fromAddress, subject, message):
"""Send a broadcast"""
global usrPrompt global usrPrompt
if (fromAddress == ''): if fromAddress == '':
try: try:
jsonAddresses = json.loads(api.listAddresses()) jsonAddresses = json.loads(api.listAddresses())
numAddresses = len(jsonAddresses['addresses']) #Number of addresses numAddresses = len(jsonAddresses['addresses']) # Number of addresses
except: except:
print '\n Connection Error\n' print '\n Connection Error\n'
usrPrompt = 0 usrPrompt = 0
main() main()
if (numAddresses > 1): #Ask what address to send from if multiple addresses if numAddresses > 1: # Ask what address to send from if multiple addresses
found = False found = False
while True: while True:
fromAddress = userInput("\nEnter an Address or Address Label to send from.") fromAddress = userInput("\nEnter an Address or Address Label to send from.")
@ -832,51 +858,46 @@ def sendBrd(fromAddress, subject, message): #sends a broadcast
usrPrompt = 1 usrPrompt = 1
main() main()
for addNum in range (0, numAddresses): #processes all of the addresses for addNum in range(0, numAddresses): # processes all of the addresses
label = jsonAddresses['addresses'][addNum]['label'] label = jsonAddresses['addresses'][addNum]['label']
address = jsonAddresses['addresses'][addNum]['address'] address = jsonAddresses['addresses'][addNum]['address']
#stream = jsonAddresses['addresses'][addNum]['stream'] if fromAddress == label: # address entered was a label and is found
#enabled = jsonAddresses['addresses'][addNum]['enabled']
if (fromAddress == label): #address entered was a label and is found
fromAddress = address fromAddress = address
found = True found = True
break break
if (found == False): if found is False:
if(validAddress(fromAddress)== False): if validAddress(fromAddress) is False:
print '\n Invalid Address. Please try again.\n' print '\n Invalid Address. Please try again.\n'
else: else:
for addNum in range (0, numAddresses): #processes all of the addresses for addNum in range(0, numAddresses): # processes all of the addresses
#label = jsonAddresses['addresses'][addNum]['label']
address = jsonAddresses['addresses'][addNum]['address'] address = jsonAddresses['addresses'][addNum]['address']
#stream = jsonAddresses['addresses'][addNum]['stream'] if fromAddress == address: # address entered was a found in our addressbook.
#enabled = jsonAddresses['addresses'][addNum]['enabled']
if (fromAddress == address): #address entered was a found in our addressbook.
found = True found = True
break break
if (found == False): if found is False:
print '\n The address entered is not one of yours. Please try again.\n' print '\n The address entered is not one of yours. Please try again.\n'
if (found == True): if found:
break #Address was found break # Address was found
else: #Only one address in address book else: # Only one address in address book
print '\n Using the only address in the addressbook to send from.\n' print '\n Using the only address in the addressbook to send from.\n'
fromAddress = jsonAddresses['addresses'][0]['address'] fromAddress = jsonAddresses['addresses'][0]['address']
if (subject == ''): if subject == '':
subject = userInput("Enter your Subject.") subject = userInput("Enter your Subject.")
subject = subject.encode('base64') subject = subject.encode('base64')
if (message == ''): if message == '':
message = userInput("Enter your Message.") message = userInput("Enter your Message.")
uInput = userInput('Would you like to add an attachment, (Y)es or (N)o?').lower() uInput = userInput('Would you like to add an attachment, (Y)es or (N)o?').lower()
if uInput == "y": if uInput == "y":
message = message + '\n\n' + attachment() message = message + '\n\n' + attachment()
message = message.encode('base64') message = message.encode('base64')
try: try:
ackData = api.sendBroadcast(fromAddress, subject, message) ackData = api.sendBroadcast(fromAddress, subject, message)
@ -886,7 +907,10 @@ def sendBrd(fromAddress, subject, message): #sends a broadcast
usrPrompt = 0 usrPrompt = 0
main() main()
def inbox(unreadOnly = False): #Lists the messages by: Message Number, To Address Label, From Address Label, Subject, Received Time)
def inbox(unreadOnly=False):
"""Lists the messages by: Message Number, To Address Label, From Address Label, Subject, Received Time)"""
global usrPrompt global usrPrompt
try: try:
inboxMessages = json.loads(api.getAllInboxMessages()) inboxMessages = json.loads(api.getAllInboxMessages())
@ -898,27 +922,35 @@ def inbox(unreadOnly = False): #Lists the messages by: Message Number, To Addres
messagesPrinted = 0 messagesPrinted = 0
messagesUnread = 0 messagesUnread = 0
for msgNum in range (0, numMessages): #processes all of the messages in the inbox for msgNum in range(0, numMessages): # processes all of the messages in the inbox
message = inboxMessages['inboxMessages'][msgNum] message = inboxMessages['inboxMessages'][msgNum]
# if we are displaying all messages or if this message is unread then display it # if we are displaying all messages or if this message is unread then display it
if not unreadOnly or not message['read']: if not unreadOnly or not message['read']:
print ' -----------------------------------\n' print ' -----------------------------------\n'
print ' Message Number:',msgNum #Message Number print ' Message Number:', msgNum # Message Number
print ' To:', getLabelForAddress(message['toAddress']) #Get the to address print ' To:', getLabelForAddress(message['toAddress']) # Get the to address
print ' From:', getLabelForAddress(message['fromAddress']) #Get the from address print ' From:', getLabelForAddress(message['fromAddress']) # Get the from address
print ' Subject:', message['subject'].decode('base64') #Get the subject print ' Subject:', message['subject'].decode('base64') # Get the subject
print ' Received:', datetime.datetime.fromtimestamp(float(message['receivedTime'])).strftime('%Y-%m-%d %H:%M:%S') print ''.join(
' Received:',
datetime.datetime.fromtimestamp(
float(message['receivedTime'])).strftime('%Y-%m-%d %H:%M:%S'),
)
messagesPrinted += 1 messagesPrinted += 1
if not message['read']: messagesUnread += 1 if not message['read']:
messagesUnread += 1
if (messagesPrinted%20 == 0 and messagesPrinted != 0): if messagesPrinted % 20 == 0 and messagesPrinted != 0:
userInput('(Press Enter to continue or type (Exit) to return to the main menu.)').lower() # uInput = userInput('(Press Enter to continue or type (Exit) to return to the main menu.)').lower() # uInput =
print '\n -----------------------------------' print '\n -----------------------------------'
print ' There are %d unread messages of %d messages in the inbox.' % (messagesUnread, numMessages) print ' There are %d unread messages of %d messages in the inbox.' % (messagesUnread, numMessages)
print ' -----------------------------------\n' print ' -----------------------------------\n'
def outbox(): def outbox():
"""TBC"""
global usrPrompt global usrPrompt
try: try:
outboxMessages = json.loads(api.getAllSentMessages()) outboxMessages = json.loads(api.getAllSentMessages())
@ -928,25 +960,33 @@ def outbox():
usrPrompt = 0 usrPrompt = 0
main() main()
for msgNum in range (0, numMessages): #processes all of the messages in the outbox for msgNum in range(0, numMessages): # processes all of the messages in the outbox
print '\n -----------------------------------\n' print '\n -----------------------------------\n'
print ' Message Number:',msgNum #Message Number print ' Message Number:', msgNum # Message Number
#print ' Message ID:', outboxMessages['sentMessages'][msgNum]['msgid'] # print ' Message ID:', outboxMessages['sentMessages'][msgNum]['msgid']
print ' To:', getLabelForAddress(outboxMessages['sentMessages'][msgNum]['toAddress']) #Get the to address print ' To:', getLabelForAddress(outboxMessages['sentMessages'][msgNum]['toAddress']) # Get the to address
print ' From:', getLabelForAddress(outboxMessages['sentMessages'][msgNum]['fromAddress']) #Get the from address # Get the from address
print ' Subject:', outboxMessages['sentMessages'][msgNum]['subject'].decode('base64') #Get the subject print ' From:', getLabelForAddress(outboxMessages['sentMessages'][msgNum]['fromAddress'])
print ' Status:', outboxMessages['sentMessages'][msgNum]['status'] #Get the subject print ' Subject:', outboxMessages['sentMessages'][msgNum]['subject'].decode('base64') # Get the subject
print ' Status:', outboxMessages['sentMessages'][msgNum]['status'] # Get the subject
print ' Last Action Time:', datetime.datetime.fromtimestamp(float(outboxMessages['sentMessages'][msgNum]['lastActionTime'])).strftime('%Y-%m-%d %H:%M:%S') print ''.join(
' Last Action Time:',
datetime.datetime.fromtimestamp(
float(outboxMessages['sentMessages'][msgNum]['lastActionTime'])).strftime('%Y-%m-%d %H:%M:%S'),
)
if (msgNum%20 == 0 and msgNum != 0): if msgNum % 20 == 0 and msgNum != 0:
userInput('(Press Enter to continue or type (Exit) to return to the main menu.)').lower() # uInput = userInput('(Press Enter to continue or type (Exit) to return to the main menu.)').lower() # uInput =
print '\n -----------------------------------' print '\n -----------------------------------'
print ' There are ',numMessages,' messages in the outbox.' print ' There are ', numMessages, ' messages in the outbox.'
print ' -----------------------------------\n' print ' -----------------------------------\n'
def readSentMsg(msgNum): #Opens a sent message for reading
def readSentMsg(msgNum):
"""Opens a sent message for reading"""
global usrPrompt global usrPrompt
try: try:
outboxMessages = json.loads(api.getAllSentMessages()) outboxMessages = json.loads(api.getAllSentMessages())
@ -958,53 +998,60 @@ def readSentMsg(msgNum): #Opens a sent message for reading
print ' ' print ' '
if (msgNum >= numMessages): if msgNum >= numMessages:
print '\n Invalid Message Number.\n' print '\n Invalid Message Number.\n'
main() main()
#Begin attachment detection # Begin attachment detection
message = outboxMessages['sentMessages'][msgNum]['message'].decode('base64') message = outboxMessages['sentMessages'][msgNum]['message'].decode('base64')
while True: #Allows multiple messages to be downloaded/saved while True: # Allows multiple messages to be downloaded/saved
if (';base64,' in message): #Found this text in the message, there is probably an attachment. if ';base64,' in message: # Found this text in the message, there is probably an attachment.
attPos= message.index(";base64,") #Finds the attachment position attPos = message.index(";base64,") # Finds the attachment position
attEndPos = message.index("' />") #Finds the end of the attachment attEndPos = message.index("' />") # Finds the end of the attachment
#attLen = attEndPos - attPos #Finds the length of the message # attLen = attEndPos - attPos #Finds the length of the message
if 'alt = "' in message: # We can get the filename too
fnPos = message.index('alt = "') # Finds position of the filename
fnEndPos = message.index('" src=') # Finds the end position
# fnLen = fnEndPos - fnPos #Finds the length of the filename
if ('alt = "' in message): #We can get the filename too fileName = message[fnPos + 7:fnEndPos]
fnPos = message.index('alt = "') #Finds position of the filename
fnEndPos = message.index('" src=') #Finds the end position
#fnLen = fnEndPos - fnPos #Finds the length of the filename
fileName = message[fnPos+7:fnEndPos]
else: else:
fnPos = attPos fnPos = attPos
fileName = 'Attachment' fileName = 'Attachment'
uInput = userInput('\n Attachment Detected. Would you like to save the attachment, (Y)es or (N)o?').lower() uInput = userInput(
if (uInput == "y" or uInput == 'yes'): '\n Attachment Detected. Would you like to save the attachment, (Y)es or (N)o?').lower()
if uInput == "y" or uInput == 'yes':
attachment = message[attPos+9:attEndPos] this_attachment = message[attPos + 9:attEndPos]
saveFile(fileName,attachment) saveFile(fileName, this_attachment)
message = message[:fnPos] + '~<Attachment data removed for easier viewing>~' + message[(attEndPos+4):] message = message[:fnPos] + '~<Attachment data removed for easier viewing>~' + message[(attEndPos + 4):]
else: else:
break break
#End attachment Detection # End attachment Detection
print '\n To:', getLabelForAddress(outboxMessages['sentMessages'][msgNum]['toAddress']) #Get the to address print '\n To:', getLabelForAddress(outboxMessages['sentMessages'][msgNum]['toAddress']) # Get the to address
print ' From:', getLabelForAddress(outboxMessages['sentMessages'][msgNum]['fromAddress']) #Get the from address # Get the from address
print ' Subject:', outboxMessages['sentMessages'][msgNum]['subject'].decode('base64') #Get the subject print ' From:', getLabelForAddress(outboxMessages['sentMessages'][msgNum]['fromAddress'])
print ' Status:', outboxMessages['sentMessages'][msgNum]['status'] #Get the subject print ' Subject:', outboxMessages['sentMessages'][msgNum]['subject'].decode('base64') # Get the subject
print ' Last Action Time:', datetime.datetime.fromtimestamp(float(outboxMessages['sentMessages'][msgNum]['lastActionTime'])).strftime('%Y-%m-%d %H:%M:%S') print ' Status:', outboxMessages['sentMessages'][msgNum]['status'] # Get the subject
print ''.join(
' Last Action Time:',
datetime.datetime.fromtimestamp(
float(outboxMessages['sentMessages'][msgNum]['lastActionTime'])).strftime('%Y-%m-%d %H:%M:%S'),
)
print ' Message:\n' print ' Message:\n'
print message #inboxMessages['inboxMessages'][msgNum]['message'].decode('base64') print message # inboxMessages['inboxMessages'][msgNum]['message'].decode('base64')
print ' ' print ' '
def readMsg(msgNum): #Opens a message for reading
def readMsg(msgNum):
"""Open a message for reading"""
global usrPrompt global usrPrompt
try: try:
inboxMessages = json.loads(api.getAllInboxMessages()) inboxMessages = json.loads(api.getAllInboxMessages())
@ -1014,54 +1061,61 @@ def readMsg(msgNum): #Opens a message for reading
usrPrompt = 0 usrPrompt = 0
main() main()
if (msgNum >= numMessages): if msgNum >= numMessages:
print '\n Invalid Message Number.\n' print '\n Invalid Message Number.\n'
main() main()
#Begin attachment detection # Begin attachment detection
message = inboxMessages['inboxMessages'][msgNum]['message'].decode('base64') message = inboxMessages['inboxMessages'][msgNum]['message'].decode('base64')
while True: #Allows multiple messages to be downloaded/saved while True: # Allows multiple messages to be downloaded/saved
if (';base64,' in message): #Found this text in the message, there is probably an attachment. if ';base64,' in message: # Found this text in the message, there is probably an attachment.
attPos= message.index(";base64,") #Finds the attachment position attPos = message.index(";base64,") # Finds the attachment position
attEndPos = message.index("' />") #Finds the end of the attachment attEndPos = message.index("' />") # Finds the end of the attachment
#attLen = attEndPos - attPos #Finds the length of the message # attLen = attEndPos - attPos #Finds the length of the message
if 'alt = "' in message: # We can get the filename too
fnPos = message.index('alt = "') # Finds position of the filename
fnEndPos = message.index('" src=') # Finds the end position
# fnLen = fnEndPos - fnPos #Finds the length of the filename
if ('alt = "' in message): #We can get the filename too fileName = message[fnPos + 7:fnEndPos]
fnPos = message.index('alt = "') #Finds position of the filename
fnEndPos = message.index('" src=') #Finds the end position
#fnLen = fnEndPos - fnPos #Finds the length of the filename
fileName = message[fnPos+7:fnEndPos]
else: else:
fnPos = attPos fnPos = attPos
fileName = 'Attachment' fileName = 'Attachment'
uInput = userInput('\n Attachment Detected. Would you like to save the attachment, (Y)es or (N)o?').lower() uInput = userInput(
if (uInput == "y" or uInput == 'yes'): '\n Attachment Detected. Would you like to save the attachment, (Y)es or (N)o?').lower()
if uInput == "y" or uInput == 'yes':
attachment = message[attPos+9:attEndPos] this_attachment = message[attPos + 9:attEndPos]
saveFile(fileName,attachment) saveFile(fileName, this_attachment)
message = message[:fnPos] + '~<Attachment data removed for easier viewing>~' + message[(attEndPos+4):] message = message[:fnPos] + '~<Attachment data removed for easier viewing>~' + message[attEndPos + 4:]
else: else:
break break
#End attachment Detection # End attachment Detection
print '\n To:', getLabelForAddress(inboxMessages['inboxMessages'][msgNum]['toAddress']) #Get the to address print '\n To:', getLabelForAddress(inboxMessages['inboxMessages'][msgNum]['toAddress']) # Get the to address
print ' From:', getLabelForAddress(inboxMessages['inboxMessages'][msgNum]['fromAddress']) #Get the from address # Get the from address
print ' Subject:', inboxMessages['inboxMessages'][msgNum]['subject'].decode('base64') #Get the subject print ' From:', getLabelForAddress(inboxMessages['inboxMessages'][msgNum]['fromAddress'])
print ' Received:',datetime.datetime.fromtimestamp(float(inboxMessages['inboxMessages'][msgNum]['receivedTime'])).strftime('%Y-%m-%d %H:%M:%S') print ' Subject:', inboxMessages['inboxMessages'][msgNum]['subject'].decode('base64') # Get the subject
print ''.join(
' Received:', datetime.datetime.fromtimestamp(
float(inboxMessages['inboxMessages'][msgNum]['receivedTime'])).strftime('%Y-%m-%d %H:%M:%S'),
)
print ' Message:\n' print ' Message:\n'
print message #inboxMessages['inboxMessages'][msgNum]['message'].decode('base64') print message # inboxMessages['inboxMessages'][msgNum]['message'].decode('base64')
print ' ' print ' '
return inboxMessages['inboxMessages'][msgNum]['msgid'] return inboxMessages['inboxMessages'][msgNum]['msgid']
def replyMsg(msgNum,forwardORreply): #Allows you to reply to the message you are currently on. Saves typing in the addresses and subject.
def replyMsg(msgNum, forwardORreply):
"""Allows you to reply to the message you are currently on. Saves typing in the addresses and subject."""
global usrPrompt global usrPrompt
forwardORreply = forwardORreply.lower() #makes it lowercase forwardORreply = forwardORreply.lower() # makes it lowercase
try: try:
inboxMessages = json.loads(api.getAllInboxMessages()) inboxMessages = json.loads(api.getAllInboxMessages())
except: except:
@ -1069,27 +1123,27 @@ def replyMsg(msgNum,forwardORreply): #Allows you to reply to the message you are
usrPrompt = 0 usrPrompt = 0
main() main()
fromAdd = inboxMessages['inboxMessages'][msgNum]['toAddress']#Address it was sent To, now the From address fromAdd = inboxMessages['inboxMessages'][msgNum]['toAddress'] # Address it was sent To, now the From address
message = inboxMessages['inboxMessages'][msgNum]['message'].decode('base64') #Message that you are replying too. message = inboxMessages['inboxMessages'][msgNum]['message'].decode('base64') # Message that you are replying too.
subject = inboxMessages['inboxMessages'][msgNum]['subject'] subject = inboxMessages['inboxMessages'][msgNum]['subject']
subject = subject.decode('base64') subject = subject.decode('base64')
if (forwardORreply == 'reply'): if forwardORreply == 'reply':
toAdd = inboxMessages['inboxMessages'][msgNum]['fromAddress'] #Address it was From, now the To address toAdd = inboxMessages['inboxMessages'][msgNum]['fromAddress'] # Address it was From, now the To address
subject = "Re: " + subject subject = "Re: " + subject
elif (forwardORreply == 'forward'): elif forwardORreply == 'forward':
subject = "Fwd: " + subject subject = "Fwd: " + subject
while True: while True:
toAdd = userInput("What is the To Address?") toAdd = userInput("What is the To Address?")
if (toAdd == "c"): if toAdd == "c":
usrPrompt = 1 usrPrompt = 1
print ' ' print ' '
main() main()
elif (validAddress(toAdd)== False): elif validAddress(toAdd) is False:
print '\n Invalid Address. "c" to cancel. Please try again.\n' print '\n Invalid Address. "c" to cancel. Please try again.\n'
else: else:
break break
@ -1114,11 +1168,15 @@ def replyMsg(msgNum,forwardORreply): #Allows you to reply to the message you are
main() main()
def delMsg(msgNum): #Deletes a specified message from the inbox
def delMsg(msgNum):
"""Deletes a specified message from the inbox"""
global usrPrompt global usrPrompt
try: try:
inboxMessages = json.loads(api.getAllInboxMessages()) inboxMessages = json.loads(api.getAllInboxMessages())
msgId = inboxMessages['inboxMessages'][int(msgNum)]['msgid'] #gets the message ID via the message index number # gets the message ID via the message index number
msgId = inboxMessages['inboxMessages'][int(msgNum)]['msgid']
msgAck = api.trashMessage(msgId) msgAck = api.trashMessage(msgId)
except: except:
@ -1128,11 +1186,15 @@ def delMsg(msgNum): #Deletes a specified message from the inbox
return msgAck return msgAck
def delSentMsg(msgNum): #Deletes a specified message from the outbox
def delSentMsg(msgNum):
"""Deletes a specified message from the outbox"""
global usrPrompt global usrPrompt
try: try:
outboxMessages = json.loads(api.getAllSentMessages()) outboxMessages = json.loads(api.getAllSentMessages())
msgId = outboxMessages['sentMessages'][int(msgNum)]['msgid'] #gets the message ID via the message index number # gets the message ID via the message index number
msgId = outboxMessages['sentMessages'][int(msgNum)]['msgid']
msgAck = api.trashSentMessage(msgId) msgAck = api.trashSentMessage(msgId)
except: except:
print '\n Connection Error\n' print '\n Connection Error\n'
@ -1141,7 +1203,10 @@ def delSentMsg(msgNum): #Deletes a specified message from the outbox
return msgAck return msgAck
def getLabelForAddress(address): def getLabelForAddress(address):
"""Get label for an address"""
if address in knownAddresses: if address in knownAddresses:
return knownAddresses[address] return knownAddresses[address]
else: else:
@ -1151,12 +1216,18 @@ def getLabelForAddress(address):
return address return address
def buildKnownAddresses(): def buildKnownAddresses():
"""Build known addresses"""
global usrPrompt
# add from address book # add from address book
try: try:
response = api.listAddressBookEntries() response = api.listAddressBookEntries()
# if api is too old then fail # if api is too old then fail
if "API Error 0020" in response: return if "API Error 0020" in response:
return
addressBook = json.loads(response) addressBook = json.loads(response)
for entry in addressBook['addresses']: for entry in addressBook['addresses']:
if entry['address'] not in knownAddresses: if entry['address'] not in knownAddresses:
@ -1170,7 +1241,8 @@ def buildKnownAddresses():
try: try:
response = api.listAddresses2() response = api.listAddresses2()
# if api is too old just return then fail # if api is too old just return then fail
if "API Error 0020" in response: return if "API Error 0020" in response:
return
addresses = json.loads(response) addresses = json.loads(response)
for entry in addresses['addresses']: for entry in addresses['addresses']:
if entry['address'] not in knownAddresses: if entry['address'] not in knownAddresses:
@ -1180,7 +1252,12 @@ def buildKnownAddresses():
usrPrompt = 0 usrPrompt = 0
main() main()
def listAddressBookEntries(): def listAddressBookEntries():
"""List addressbook entries"""
global usrPrompt
try: try:
response = api.listAddressBookEntries() response = api.listAddressBookEntries()
if "API Error" in response: if "API Error" in response:
@ -1193,7 +1270,8 @@ def listAddressBookEntries():
for entry in addressBook['addresses']: for entry in addressBook['addresses']:
label = entry['label'].decode('base64') label = entry['label'].decode('base64')
address = entry['address'] address = entry['address']
if (len(label) > 19): label = label[:16] + '...' if len(label) > 19:
label = label[:16] + '...'
print ' | ' + label.ljust(19) + '| ' + address.ljust(37) + ' |' print ' | ' + label.ljust(19) + '| ' + address.ljust(37) + ' |'
print ' --------------------------------------------------------------' print ' --------------------------------------------------------------'
print print
@ -1203,7 +1281,12 @@ def listAddressBookEntries():
usrPrompt = 0 usrPrompt = 0
main() main()
def addAddressToAddressBook(address, label): def addAddressToAddressBook(address, label):
"""Add an address to an addressbook"""
global usrPrompt
try: try:
response = api.addAddressBookEntry(address, label.encode('base64')) response = api.addAddressBookEntry(address, label.encode('base64'))
if "API Error" in response: if "API Error" in response:
@ -1213,7 +1296,12 @@ def addAddressToAddressBook(address, label):
usrPrompt = 0 usrPrompt = 0
main() main()
def deleteAddressFromAddressBook(address): def deleteAddressFromAddressBook(address):
"""Delete an address from an addressbook"""
global usrPrompt
try: try:
response = api.deleteAddressBookEntry(address) response = api.deleteAddressBookEntry(address)
if "API Error" in response: if "API Error" in response:
@ -1223,13 +1311,21 @@ def deleteAddressFromAddressBook(address):
usrPrompt = 0 usrPrompt = 0
main() main()
def getAPIErrorCode(response): def getAPIErrorCode(response):
"""Get API error code"""
if "API Error" in response: if "API Error" in response:
# if we got an API error return the number by getting the number # if we got an API error return the number by getting the number
# after the second space and removing the trailing colon # after the second space and removing the trailing colon
return int(response.split()[2][:-1]) return int(response.split()[2][:-1])
def markMessageRead(messageID): def markMessageRead(messageID):
"""Mark a message as read"""
global usrPrompt
try: try:
response = api.getInboxMessageByID(messageID, True) response = api.getInboxMessageByID(messageID, True)
if "API Error" in response: if "API Error" in response:
@ -1239,7 +1335,12 @@ def markMessageRead(messageID):
usrPrompt = 0 usrPrompt = 0
main() main()
def markMessageUnread(messageID): def markMessageUnread(messageID):
"""Mark a mesasge as unread"""
global usrPrompt
try: try:
response = api.getInboxMessageByID(messageID, False) response = api.getInboxMessageByID(messageID, False)
if "API Error" in response: if "API Error" in response:
@ -1249,7 +1350,12 @@ def markMessageUnread(messageID):
usrPrompt = 0 usrPrompt = 0
main() main()
def markAllMessagesRead(): def markAllMessagesRead():
"""Mark all messages as read"""
global usrPrompt
try: try:
inboxMessages = json.loads(api.getAllInboxMessages())['inboxMessages'] inboxMessages = json.loads(api.getAllInboxMessages())['inboxMessages']
except: except:
@ -1260,7 +1366,12 @@ def markAllMessagesRead():
if not message['read']: if not message['read']:
markMessageRead(message['msgid']) markMessageRead(message['msgid'])
def markAllMessagesUnread(): def markAllMessagesUnread():
"""Mark all messages as unread"""
global usrPrompt
try: try:
inboxMessages = json.loads(api.getAllInboxMessages())['inboxMessages'] inboxMessages = json.loads(api.getAllInboxMessages())['inboxMessages']
except: except:
@ -1271,20 +1382,29 @@ def markAllMessagesUnread():
if message['read']: if message['read']:
markMessageUnread(message['msgid']) markMessageUnread(message['msgid'])
def clientStatus(): def clientStatus():
"""Print the client status"""
global usrPrompt
try: try:
clientStatus = json.loads(api.clientStatus()) client_status = json.loads(api.clientStatus())
except: except:
print '\n Connection Error\n' print '\n Connection Error\n'
usrPrompt = 0 usrPrompt = 0
main() main()
print "\nnetworkStatus: " + clientStatus['networkStatus'] + "\n"
print "\nnetworkConnections: " + str(clientStatus['networkConnections']) + "\n" print "\nnetworkStatus: " + client_status['networkStatus'] + "\n"
print "\nnumberOfPubkeysProcessed: " + str(clientStatus['numberOfPubkeysProcessed']) + "\n" print "\nnetworkConnections: " + str(client_status['networkConnections']) + "\n"
print "\nnumberOfMessagesProcessed: " + str(clientStatus['numberOfMessagesProcessed']) + "\n" print "\nnumberOfPubkeysProcessed: " + str(client_status['numberOfPubkeysProcessed']) + "\n"
print "\nnumberOfBroadcastsProcessed: " + str(clientStatus['numberOfBroadcastsProcessed']) + "\n" print "\nnumberOfMessagesProcessed: " + str(client_status['numberOfMessagesProcessed']) + "\n"
print "\nnumberOfBroadcastsProcessed: " + str(client_status['numberOfBroadcastsProcessed']) + "\n"
def shutdown(): def shutdown():
"""Shutdown the API"""
try: try:
api.shutdown() api.shutdown()
except socket.error: except socket.error:
@ -1292,7 +1412,9 @@ def shutdown():
print "\nShutdown command relayed\n" print "\nShutdown command relayed\n"
def UI(usrInput): #Main user menu def UI(usrInput):
"""Main user menu"""
global usrPrompt global usrPrompt
if usrInput == "help" or usrInput == "h" or usrInput == "?": if usrInput == "help" or usrInput == "h" or usrInput == "?":
@ -1319,7 +1441,6 @@ def UI(usrInput): #Main user menu
print ' |------------------------|----------------------------------------------|' print ' |------------------------|----------------------------------------------|'
print ' | subscribe | Subscribes to an address |' print ' | subscribe | Subscribes to an address |'
print ' | unsubscribe | Unsubscribes from an address |' print ' | unsubscribe | Unsubscribes from an address |'
#print' | listSubscriptions | Lists all of the subscriptions. |'
print ' |------------------------|----------------------------------------------|' print ' |------------------------|----------------------------------------------|'
print ' | create | Creates a channel |' print ' | create | Creates a channel |'
print ' | join | Joins a channel |' print ' | join | Joins a channel |'
@ -1336,8 +1457,8 @@ def UI(usrInput): #Main user menu
print ' ' print ' '
main() main()
elif usrInput == "apitest": #tests the API Connection. elif usrInput == "apitest": # tests the API Connection.
if (apiTest() == True): if apiTest():
print '\n API connection test has: PASSED\n' print '\n API connection test has: PASSED\n'
else: else:
print '\n API connection test has: FAILED\n' print '\n API connection test has: FAILED\n'
@ -1359,39 +1480,35 @@ def UI(usrInput): #Main user menu
print '------------------------------\n' print '------------------------------\n'
main() main()
elif usrInput == "bmsettings": #tests the API Connection. elif usrInput == "bmsettings": # tests the API Connection.
bmSettings() bmSettings()
print ' ' print ' '
main() main()
elif usrInput == "quit": #Quits the application elif usrInput == "quit": # Quits the application
print '\n Bye\n' print '\n Bye\n'
sys.exit() sys.exit(0)
os._exit()
elif usrInput == "listaddresses": #Lists all of the identities in the addressbook elif usrInput == "listaddresses": # Lists all of the identities in the addressbook
listAdd() listAdd()
main() main()
elif usrInput == "generateaddress": #Generates a new address elif usrInput == "generateaddress": # Generates a new address
uInput = userInput('\nWould you like to create a (D)eterministic or (R)andom address?').lower() uInput = userInput('\nWould you like to create a (D)eterministic or (R)andom address?').lower()
if uInput in ["d", "deterministic"]: #Creates a deterministic address if uInput in ["d", "deterministic"]: # Creates a deterministic address
deterministic = True deterministic = True
#lbl = raw_input('Label the new address:') #currently not possible via the api
lbl = '' lbl = ''
passphrase = userInput('Enter the Passphrase.')#.encode('base64') passphrase = userInput('Enter the Passphrase.') # .encode('base64')
numOfAdd = int(userInput('How many addresses would you like to generate?')) numOfAdd = int(userInput('How many addresses would you like to generate?'))
#addVNum = int(raw_input('Address version number (default "0"):'))
#streamNum = int(raw_input('Stream number (default "0"):'))
addVNum = 3 addVNum = 3
streamNum = 1 streamNum = 1
isRipe = userInput('Shorten the address, (Y)es or (N)o?').lower() isRipe = userInput('Shorten the address, (Y)es or (N)o?').lower()
if isRipe == "y": if isRipe == "y":
ripe = True ripe = True
print genAdd(lbl,deterministic, passphrase, numOfAdd, addVNum, streamNum, ripe) print genAdd(lbl, deterministic, passphrase, numOfAdd, addVNum, streamNum, ripe)
main() main()
elif isRipe == "n": elif isRipe == "n":
ripe = False ripe = False
@ -1404,40 +1521,37 @@ def UI(usrInput): #Main user menu
print '\n Invalid input\n' print '\n Invalid input\n'
main() main()
elif uInput == "r" or uInput == "random": # Creates a random address with user-defined label
elif uInput == "r" or uInput == "random": #Creates a random address with user-defined label
deterministic = False deterministic = False
null = '' null = ''
lbl = userInput('Enter the label for the new address.') lbl = userInput('Enter the label for the new address.')
print genAdd(lbl,deterministic, null,null, null, null, null) print genAdd(lbl, deterministic, null, null, null, null, null)
main() main()
else: else:
print '\n Invalid input\n' print '\n Invalid input\n'
main() main()
elif usrInput == "getaddress": #Gets the address for/from a passphrase elif usrInput == "getaddress": # Gets the address for/from a passphrase
phrase = userInput("Enter the address passphrase.") phrase = userInput("Enter the address passphrase.")
print '\n Working...\n' print '\n Working...\n'
#vNumber = int(raw_input("Enter the address version number:")) address = getAddress(phrase, 4, 1) # ,vNumber,sNumber)
#sNumber = int(raw_input("Enter the address stream number:")) print '\n Address: ' + address + '\n'
address = getAddress(phrase,4,1)#,vNumber,sNumber)
print ('\n Address: ' + address + '\n')
usrPrompt = 1 usrPrompt = 1
main() main()
elif usrInput == "subscribe": #Subsribe to an address elif usrInput == "subscribe": # Subsribe to an address
subscribe() subscribe()
usrPrompt = 1 usrPrompt = 1
main() main()
elif usrInput == "unsubscribe": #Unsubscribe from an address
elif usrInput == "unsubscribe": # Unsubscribe from an address
unsubscribe() unsubscribe()
usrPrompt = 1 usrPrompt = 1
main() main()
elif usrInput == "listsubscriptions": #Unsubscribe from an address
elif usrInput == "listsubscriptions": # Unsubscribe from an address
listSubscriptions() listSubscriptions()
usrPrompt = 1 usrPrompt = 1
main() main()
@ -1472,20 +1586,19 @@ def UI(usrInput): #Main user menu
outbox() outbox()
main() main()
elif usrInput == 'send': #Sends a message or broadcast elif usrInput == 'send': # Sends a message or broadcast
uInput = userInput('Would you like to send a (M)essage or (B)roadcast?').lower() uInput = userInput('Would you like to send a (M)essage or (B)roadcast?').lower()
if (uInput == 'm' or uInput == 'message'): if (uInput == 'm' or uInput == 'message'):
null = '' null = ''
sendMsg(null,null,null,null) sendMsg(null, null, null, null)
main() main()
elif (uInput =='b' or uInput == 'broadcast'): elif (uInput == 'b' or uInput == 'broadcast'):
null = '' null = ''
sendBrd(null,null,null) sendBrd(null, null, null)
main() main()
elif usrInput == "read": # Opens a message from the inbox for viewing.
elif usrInput == "read": #Opens a message from the inbox for viewing.
uInput = userInput("Would you like to read a message from the (I)nbox or (O)utbox?").lower() uInput = userInput("Would you like to read a message from the (I)nbox or (O)utbox?").lower()
@ -1508,20 +1621,20 @@ def UI(usrInput): #Main user menu
uInput = userInput("\nWould you like to (D)elete, (F)orward, (R)eply to, or (Exit) this message?").lower() uInput = userInput("\nWould you like to (D)elete, (F)orward, (R)eply to, or (Exit) this message?").lower()
if (uInput == 'r' or uInput == 'reply'): if uInput in ['r', 'reply']:
print '\n Loading...\n' print '\n Loading...\n'
print ' ' print ' '
replyMsg(msgNum,'reply') replyMsg(msgNum, 'reply')
usrPrompt = 1 usrPrompt = 1
elif (uInput == 'f' or uInput == 'forward'): elif uInput == 'f' or uInput == 'forward':
print '\n Loading...\n' print '\n Loading...\n'
print ' ' print ' '
replyMsg(msgNum,'forward') replyMsg(msgNum, 'forward')
usrPrompt = 1 usrPrompt = 1
elif (uInput == "d" or uInput == 'delete'): elif uInput in ["d", 'delete']:
uInput = userInput("Are you sure, (Y)es or (N)o?").lower()#Prevent accidental deletion uInput = userInput("Are you sure, (Y)es or (N)o?").lower() # Prevent accidental deletion
if uInput == "y": if uInput == "y":
delMsg(msgNum) delMsg(msgNum)
@ -1536,10 +1649,11 @@ def UI(usrInput): #Main user menu
elif (uInput == 'o' or uInput == 'outbox'): elif (uInput == 'o' or uInput == 'outbox'):
readSentMsg(msgNum) readSentMsg(msgNum)
uInput = userInput("Would you like to (D)elete, or (Exit) this message?").lower() #Gives the user the option to delete the message # Gives the user the option to delete the message
uInput = userInput("Would you like to (D)elete, or (Exit) this message?").lower()
if (uInput == "d" or uInput == 'delete'): if (uInput == "d" or uInput == 'delete'):
uInput = userInput('Are you sure, (Y)es or (N)o?').lower() #Prevent accidental deletion uInput = userInput('Are you sure, (Y)es or (N)o?').lower() # Prevent accidental deletion
if uInput == "y": if uInput == "y":
delSentMsg(msgNum) delSentMsg(msgNum)
@ -1557,72 +1671,75 @@ def UI(usrInput): #Main user menu
uInput = userInput("Would you like to save a message from the (I)nbox or (O)utbox?").lower() uInput = userInput("Would you like to save a message from the (I)nbox or (O)utbox?").lower()
if (uInput != 'i' and uInput == 'inbox' and uInput != 'o' and uInput == 'outbox'): if uInput not in ['i', 'inbox', 'o', 'outbox']:
print '\n Invalid Input.\n' print '\n Invalid Input.\n'
usrPrompt = 1 usrPrompt = 1
main() main()
if (uInput == 'i' or uInput == 'inbox'): if uInput in ['i', 'inbox']:
inboxMessages = json.loads(api.getAllInboxMessages()) inboxMessages = json.loads(api.getAllInboxMessages())
numMessages = len(inboxMessages['inboxMessages']) numMessages = len(inboxMessages['inboxMessages'])
while True: while True:
msgNum = int(userInput("What is the number of the message you wish to save?")) msgNum = int(userInput("What is the number of the message you wish to save?"))
if (msgNum >= numMessages): if msgNum >= numMessages:
print '\n Invalid Message Number.\n' print '\n Invalid Message Number.\n'
else: else:
break break
subject = inboxMessages['inboxMessages'][msgNum]['subject'].decode('base64') subject = inboxMessages['inboxMessages'][msgNum]['subject'].decode('base64')
message = inboxMessages['inboxMessages'][msgNum]['message']#Don't decode since it is done in the saveFile function # Don't decode since it is done in the saveFile function
message = inboxMessages['inboxMessages'][msgNum]['message']
elif (uInput == 'o' or uInput == 'outbox'): elif uInput == 'o' or uInput == 'outbox':
outboxMessages = json.loads(api.getAllSentMessages()) outboxMessages = json.loads(api.getAllSentMessages())
numMessages = len(outboxMessages['sentMessages']) numMessages = len(outboxMessages['sentMessages'])
while True: while True:
msgNum = int(userInput("What is the number of the message you wish to save?")) msgNum = int(userInput("What is the number of the message you wish to save?"))
if (msgNum >= numMessages): if msgNum >= numMessages:
print '\n Invalid Message Number.\n' print '\n Invalid Message Number.\n'
else: else:
break break
subject = outboxMessages['sentMessages'][msgNum]['subject'].decode('base64') subject = outboxMessages['sentMessages'][msgNum]['subject'].decode('base64')
message = outboxMessages['sentMessages'][msgNum]['message']#Don't decode since it is done in the saveFile function # Don't decode since it is done in the saveFile function
message = outboxMessages['sentMessages'][msgNum]['message']
subject = subject +'.txt' subject = subject + '.txt'
saveFile(subject,message) saveFile(subject, message)
usrPrompt = 1 usrPrompt = 1
main() main()
elif usrInput == "delete": #will delete a message from the system, not reflected on the UI. elif usrInput == "delete": # will delete a message from the system, not reflected on the UI.
uInput = userInput("Would you like to delete a message from the (I)nbox or (O)utbox?").lower() uInput = userInput("Would you like to delete a message from the (I)nbox or (O)utbox?").lower()
if (uInput == 'i' or uInput == 'inbox'): if uInput in ['i', 'inbox']:
inboxMessages = json.loads(api.getAllInboxMessages()) inboxMessages = json.loads(api.getAllInboxMessages())
numMessages = len(inboxMessages['inboxMessages']) numMessages = len(inboxMessages['inboxMessages'])
while True: while True:
msgNum = userInput('Enter the number of the message you wish to delete or (A)ll to empty the inbox.').lower() msgNum = userInput(
'Enter the number of the message you wish to delete or (A)ll to empty the inbox.').lower()
if (msgNum == 'a' or msgNum == 'all'): if msgNum == 'a' or msgNum == 'all':
break break
elif (int(msgNum) >= numMessages): elif int(msgNum) >= numMessages:
print '\n Invalid Message Number.\n' print '\n Invalid Message Number.\n'
else: else:
break break
uInput = userInput("Are you sure, (Y)es or (N)o?").lower()#Prevent accidental deletion uInput = userInput("Are you sure, (Y)es or (N)o?").lower() # Prevent accidental deletion
if uInput == "y": if uInput == "y":
if (msgNum == 'a' or msgNum == 'all'): if msgNum in ['a', 'all']:
print ' ' print ' '
for msgNum in range (0, numMessages): #processes all of the messages in the inbox for msgNum in range(0, numMessages): # processes all of the messages in the inbox
print ' Deleting message ', msgNum+1, ' of ', numMessages print ' Deleting message ', msgNum + 1, ' of ', numMessages
delMsg(0) delMsg(0)
print '\n Inbox is empty.' print '\n Inbox is empty.'
@ -1634,27 +1751,29 @@ def UI(usrInput): #Main user menu
main() main()
else: else:
usrPrompt = 1 usrPrompt = 1
elif (uInput == 'o' or uInput == 'outbox'):
elif uInput in ['o', 'outbox']:
outboxMessages = json.loads(api.getAllSentMessages()) outboxMessages = json.loads(api.getAllSentMessages())
numMessages = len(outboxMessages['sentMessages']) numMessages = len(outboxMessages['sentMessages'])
while True: while True:
msgNum = userInput('Enter the number of the message you wish to delete or (A)ll to empty the inbox.').lower() msgNum = userInput(
'Enter the number of the message you wish to delete or (A)ll to empty the inbox.').lower()
if (msgNum == 'a' or msgNum == 'all'): if msgNum in ['a', 'all']:
break break
elif (int(msgNum) >= numMessages): elif int(msgNum) >= numMessages:
print '\n Invalid Message Number.\n' print '\n Invalid Message Number.\n'
else: else:
break break
uInput = userInput("Are you sure, (Y)es or (N)o?").lower()#Prevent accidental deletion uInput = userInput("Are you sure, (Y)es or (N)o?").lower() # Prevent accidental deletion
if uInput == "y": if uInput == "y":
if (msgNum == 'a' or msgNum == 'all'): if msgNum in ['a', 'all']:
print ' ' print ' '
for msgNum in range (0, numMessages): #processes all of the messages in the outbox for msgNum in range(0, numMessages): # processes all of the messages in the outbox
print ' Deleting message ', msgNum+1, ' of ', numMessages print ' Deleting message ', msgNum + 1, ' of ', numMessages
delSentMsg(0) delSentMsg(0)
print '\n Outbox is empty.' print '\n Outbox is empty.'
@ -1677,7 +1796,8 @@ def UI(usrInput): #Main user menu
elif usrInput == "listaddressbookentries": elif usrInput == "listaddressbookentries":
res = listAddressBookEntries() res = listAddressBookEntries()
if res == 20: print '\n Error: API function not supported.\n' if res == 20:
print '\n Error: API function not supported.\n'
usrPrompt = 1 usrPrompt = 1
main() main()
@ -1685,15 +1805,18 @@ def UI(usrInput): #Main user menu
address = userInput('Enter address') address = userInput('Enter address')
label = userInput('Enter label') label = userInput('Enter label')
res = addAddressToAddressBook(address, label) res = addAddressToAddressBook(address, label)
if res == 16: print '\n Error: Address already exists in Address Book.\n' if res == 16:
if res == 20: print '\n Error: API function not supported.\n' print '\n Error: Address already exists in Address Book.\n'
if res == 20:
print '\n Error: API function not supported.\n'
usrPrompt = 1 usrPrompt = 1
main() main()
elif usrInput == "deleteaddressbookentry": elif usrInput == "deleteaddressbookentry":
address = userInput('Enter address') address = userInput('Enter address')
res = deleteAddressFromAddressBook(address) res = deleteAddressFromAddressBook(address)
if res == 20: print '\n Error: API function not supported.\n' if res == 20:
print '\n Error: API function not supported.\n'
usrPrompt = 1 usrPrompt = 1
main() main()
@ -1717,49 +1840,37 @@ def UI(usrInput): #Main user menu
usrPrompt = 1 usrPrompt = 1
main() main()
elif usrInput == "million+":
genMilAddr()
usrPrompt = 1
main()
elif usrInput == "million-":
delMilAddr()
usrPrompt = 1
main()
else: else:
print '\n "',usrInput,'" is not a command.\n' print '\n "', usrInput, '" is not a command.\n'
usrPrompt = 1 usrPrompt = 1
main() main()
def main(): def main():
"""Entrypoint for the CLI app"""
global api global api
global usrPrompt global usrPrompt
if (usrPrompt == 0): if usrPrompt == 0:
print '\n ------------------------------' print '\n ------------------------------'
print ' | Bitmessage Daemon by .dok |' print ' | Bitmessage Daemon by .dok |'
print ' | Version 0.3.1 for BM 0.6.2 |' print ' | Version 0.3.1 for BM 0.6.2 |'
print ' ------------------------------' print ' ------------------------------'
api = xmlrpclib.ServerProxy(apiData()) #Connect to BitMessage using these api credentials api = xmlrpclib.ServerProxy(apiData()) # Connect to BitMessage using these api credentials
if (apiTest() == False): if apiTest() is False:
print '\n ****************************************************************' print '\n ****************************************************************'
print ' WARNING: You are not connected to the Bitmessage client.' print ' WARNING: You are not connected to the Bitmessage client.'
print ' Either Bitmessage is not running or your settings are incorrect.' print ' Either Bitmessage is not running or your settings are incorrect.'
print ' Use the command "apiTest" or "bmSettings" to resolve this issue.' print ' Use the command "apiTest" or "bmSettings" to resolve this issue.'
print ' ****************************************************************\n' print ' ****************************************************************\n'
print 'Type (H)elp for a list of commands.' #Startup message print 'Type (H)elp for a list of commands.' # Startup message
usrPrompt = 2 usrPrompt = 2
#if (apiTest() == False):#Preform a connection test #taken out until I get the error handler working elif usrPrompt == 1:
# print '*************************************' print '\nType (H)elp for a list of commands.' # Startup message
# print 'WARNING: No connection to Bitmessage.'
# print '*************************************'
# print ' '
elif (usrPrompt == 1):
print '\nType (H)elp for a list of commands.' #Startup message
usrPrompt = 2 usrPrompt = 2
try: try:
@ -1767,5 +1878,6 @@ def main():
except EOFError: except EOFError:
UI("quit") UI("quit")
if __name__ == "__main__": if __name__ == "__main__":
main() main()