|
|
|
@ -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.ljust(7) + '|'
|
|
|
|
|
|
|
|
|
|
print ' --------------------------------------------------------------------------\n'
|
|
|
|
|
|
|
|
|
|
def genAdd(lbl,deterministic, passphrase, numOfAdd, addVNum, streamNum, ripe): #Generate address
|
|
|
|
|
global usrPrompt
|
|
|
|
|
if deterministic == False: #Generates a new address with the user defined label. non-deterministic
|
|
|
|
|
addressLabel = lbl.encode('base64')
|
|
|
|
|
try:
|
|
|
|
|
generatedAddress = api.createRandomAddress(addressLabel)
|
|
|
|
|
except:
|
|
|
|
|
print '\n Connection Error\n'
|
|
|
|
|
usrPrompt = 0
|
|
|
|
|
main()
|
|
|
|
|
|
|
|
|
|
return generatedAddress
|
|
|
|
|
|
|
|
|
|
elif deterministic == True: #Generates a new deterministic address with the user inputs.
|
|
|
|
|
passphrase = passphrase.encode('base64')
|
|
|
|
|
try:
|
|
|
|
|
generatedAddress = api.createDeterministicAddresses(passphrase, numOfAdd, addVNum, streamNum, ripe)
|
|
|
|
|
except:
|
|
|
|
|
print '\n Connection Error\n'
|
|
|
|
|
usrPrompt = 0
|
|
|
|
|
main()
|
|
|
|
|
return generatedAddress
|
|
|
|
|
else:
|
|
|
|
|
return 'Entry Error'
|
|
|
|
|
|
|
|
|
|
def delMilAddr(): #Generate address
|
|
|
|
|
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' |