2017-12-26 14:17:37 +01:00
#!/usr/bin/python2.7
# -*- coding: utf-8 -*-
2015-01-19 18:53:07 +01:00
# 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.
2017-12-26 15:01:12 +01:00
# This is an example of a daemon client for PyBitmessage 0.6.2, by .dok (Version 0.3.1) , modified
2015-01-19 18:53:07 +01:00
import xmlrpclib
import datetime
2017-12-26 14:17:37 +01:00
#import hashlib
#import getopt
2015-01-19 18:53:07 +01:00
import imghdr
import ntpath
import json
2017-08-22 13:23:03 +02:00
import socket
2015-01-19 18:53:07 +01:00
import time
import sys
import os
2017-02-22 09:34:54 +01:00
from bmconfigparser import BMConfigParser
2016-12-06 10:47:39 +01:00
2015-01-19 18:53:07 +01:00
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 ( )
2017-12-26 14:17:37 +01:00
os . _exit ( ) # _
2015-01-19 18:53:07 +01:00
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 '
#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. '
2017-12-26 14:17:37 +01:00
os . _exit ( )
2015-01-19 18:53:07 +01:00
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 ( ) :
2017-01-11 14:27:19 +01:00
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.
BMConfigParser ( ) . set ( ' bitmessagesettings ' , ' apienabled ' , ' true ' ) #Sets apienabled to true in keys.dat
2015-01-19 18:53:07 +01:00
with open ( keysName , ' wb ' ) as configfile :
2017-01-11 14:27:19 +01:00
BMConfigParser ( ) . write ( configfile )
2015-01-19 18:53:07 +01:00
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 usrPrompt
2017-01-11 14:27:19 +01:00
BMConfigParser ( ) . read ( keysPath )
2015-01-19 18:53:07 +01:00
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 " : #
2017-01-11 14:27:19 +01:00
BMConfigParser ( ) . set ( ' bitmessagesettings ' , ' apienabled ' , ' true ' ) #Sets apienabled to true in keys.dat
2015-01-19 18:53:07 +01:00
with open ( keysPath , ' wb ' ) as configfile :
2017-01-11 14:27:19 +01:00
BMConfigParser ( ) . write ( configfile )
2015-01-19 18:53:07 +01:00
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 " )
2017-12-26 14:17:37 +01:00
#apiInterface = userInput("API Interface. (127.0.0.1)")
2015-01-19 18:53:07 +01:00
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 '
2017-01-11 14:27:19 +01:00
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.
BMConfigParser ( ) . set ( ' bitmessagesettings ' , ' apienabled ' , ' true ' )
BMConfigParser ( ) . set ( ' bitmessagesettings ' , ' apiport ' , apiPort )
BMConfigParser ( ) . set ( ' bitmessagesettings ' , ' apiinterface ' , ' 127.0.0.1 ' )
BMConfigParser ( ) . set ( ' bitmessagesettings ' , ' apiusername ' , apiUsr )
BMConfigParser ( ) . set ( ' bitmessagesettings ' , ' apipassword ' , apiPwd )
BMConfigParser ( ) . set ( ' bitmessagesettings ' , ' daemon ' , daemon )
2015-01-19 18:53:07 +01:00
with open ( keysPath , ' wb ' ) as configfile :
2017-01-11 14:27:19 +01:00
BMConfigParser ( ) . write ( configfile )
2015-01-19 18:53:07 +01:00
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 ' \n Invalid entry \n '
usrPrompt = 1
main ( )
def apiData ( ) :
global keysName
global keysPath
global usrPrompt
2017-01-11 14:27:19 +01:00
BMConfigParser ( ) . read ( keysPath ) #First try to load the config file (the keys.dat file) from the program directory
2015-01-19 18:53:07 +01:00
try :
2017-01-11 14:27:19 +01:00
BMConfigParser ( ) . get ( ' bitmessagesettings ' , ' port ' )
2015-01-19 18:53:07 +01:00
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
2017-01-11 14:27:19 +01:00
BMConfigParser ( ) . read ( keysPath )
2015-01-19 18:53:07 +01:00
try :
2017-01-11 14:27:19 +01:00
BMConfigParser ( ) . get ( ' bitmessagesettings ' , ' port ' )
2015-01-19 18:53:07 +01:00
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
2017-01-11 14:27:19 +01:00
BMConfigParser ( ) . get ( ' bitmessagesettings ' , ' apiport ' )
BMConfigParser ( ) . get ( ' bitmessagesettings ' , ' apiinterface ' )
BMConfigParser ( ) . get ( ' bitmessagesettings ' , ' apiusername ' )
BMConfigParser ( ) . get ( ' bitmessagesettings ' , ' apipassword ' )
2015-01-19 18:53:07 +01:00
except :
apiInit ( " " ) #Initalize the keys.dat file with API information
#keys.dat file was found or appropriately configured, allow information retrieval
2017-12-26 14:17:37 +01:00
#apiEnabled = apiInit(BMConfigParser().safeGetBoolean('bitmessagesettings','apienabled')) #if false it will prompt the user, if true it will return true
2015-01-19 18:53:07 +01:00
2017-01-11 14:27:19 +01:00
BMConfigParser ( ) . read ( keysPath ) #read again since changes have been made
apiPort = int ( BMConfigParser ( ) . get ( ' bitmessagesettings ' , ' apiport ' ) )
apiInterface = BMConfigParser ( ) . get ( ' bitmessagesettings ' , ' apiinterface ' )
apiUsername = BMConfigParser ( ) . get ( ' bitmessagesettings ' , ' apiusername ' )
apiPassword = BMConfigParser ( ) . get ( ' bitmessagesettings ' , ' apipassword ' )
2015-01-19 18:53:07 +01:00
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
keysPath = ' keys.dat '
2017-01-11 14:27:19 +01:00
BMConfigParser ( ) . read ( keysPath ) #Read the keys.dat
2015-01-19 18:53:07 +01:00
try :
2017-01-11 14:27:19 +01:00
port = BMConfigParser ( ) . get ( ' bitmessagesettings ' , ' port ' )
2015-01-19 18:53:07 +01:00
except :
print ' \n File not found. \n '
usrPrompt = 0
main ( )
2017-01-11 14:27:19 +01:00
startonlogon = BMConfigParser ( ) . safeGetBoolean ( ' bitmessagesettings ' , ' startonlogon ' )
minimizetotray = BMConfigParser ( ) . safeGetBoolean ( ' bitmessagesettings ' , ' minimizetotray ' )
showtraynotifications = BMConfigParser ( ) . safeGetBoolean ( ' bitmessagesettings ' , ' showtraynotifications ' )
startintray = BMConfigParser ( ) . safeGetBoolean ( ' bitmessagesettings ' , ' startintray ' )
defaultnoncetrialsperbyte = BMConfigParser ( ) . get ( ' bitmessagesettings ' , ' defaultnoncetrialsperbyte ' )
defaultpayloadlengthextrabytes = BMConfigParser ( ) . get ( ' bitmessagesettings ' , ' defaultpayloadlengthextrabytes ' )
daemon = BMConfigParser ( ) . safeGetBoolean ( ' bitmessagesettings ' , ' daemon ' )
socksproxytype = BMConfigParser ( ) . get ( ' bitmessagesettings ' , ' socksproxytype ' )
sockshostname = BMConfigParser ( ) . get ( ' bitmessagesettings ' , ' sockshostname ' )
socksport = BMConfigParser ( ) . get ( ' bitmessagesettings ' , ' socksport ' )
socksauthentication = BMConfigParser ( ) . safeGetBoolean ( ' bitmessagesettings ' , ' socksauthentication ' )
socksusername = BMConfigParser ( ) . get ( ' bitmessagesettings ' , ' socksusername ' )
sockspassword = BMConfigParser ( ) . get ( ' bitmessagesettings ' , ' sockspassword ' )
2015-01-19 18:53:07 +01:00
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. " )
2017-01-11 14:27:19 +01:00
BMConfigParser ( ) . set ( ' bitmessagesettings ' , ' port ' , str ( uInput ) )
2015-01-19 18:53:07 +01:00
elif uInput == " startonlogon " :
print ' Current status: ' + str ( startonlogon )
uInput = userInput ( " Enter the new status. " )
2017-01-11 14:27:19 +01:00
BMConfigParser ( ) . set ( ' bitmessagesettings ' , ' startonlogon ' , str ( uInput ) )
2015-01-19 18:53:07 +01:00
elif uInput == " minimizetotray " :
print ' Current status: ' + str ( minimizetotray )
uInput = userInput ( " Enter the new status. " )
2017-01-11 14:27:19 +01:00
BMConfigParser ( ) . set ( ' bitmessagesettings ' , ' minimizetotray ' , str ( uInput ) )
2015-01-19 18:53:07 +01:00
elif uInput == " showtraynotifications " :
print ' Current status: ' + str ( showtraynotifications )
uInput = userInput ( " Enter the new status. " )
2017-01-11 14:27:19 +01:00
BMConfigParser ( ) . set ( ' bitmessagesettings ' , ' showtraynotifications ' , str ( uInput ) )
2015-01-19 18:53:07 +01:00
elif uInput == " startintray " :
print ' Current status: ' + str ( startintray )
uInput = userInput ( " Enter the new status. " )
2017-01-11 14:27:19 +01:00
BMConfigParser ( ) . set ( ' bitmessagesettings ' , ' startintray ' , str ( uInput ) )
2015-01-19 18:53:07 +01:00
elif uInput == " defaultnoncetrialsperbyte " :
print ' Current default nonce trials per byte: ' + defaultnoncetrialsperbyte
uInput = userInput ( " Enter the new defaultnoncetrialsperbyte. " )
2017-01-11 14:27:19 +01:00
BMConfigParser ( ) . set ( ' bitmessagesettings ' , ' defaultnoncetrialsperbyte ' , str ( uInput ) )
2015-01-19 18:53:07 +01:00
elif uInput == " defaultpayloadlengthextrabytes " :
print ' Current default payload length extra bytes: ' + defaultpayloadlengthextrabytes
uInput = userInput ( " Enter the new defaultpayloadlengthextrabytes. " )
2017-01-11 14:27:19 +01:00
BMConfigParser ( ) . set ( ' bitmessagesettings ' , ' defaultpayloadlengthextrabytes ' , str ( uInput ) )
2015-01-19 18:53:07 +01:00
elif uInput == " daemon " :
print ' Current status: ' + str ( daemon )
uInput = userInput ( " Enter the new status. " ) . lower ( )
2017-01-11 14:27:19 +01:00
BMConfigParser ( ) . set ( ' bitmessagesettings ' , ' daemon ' , str ( uInput ) )
2015-01-19 18:53:07 +01:00
elif uInput == " socksproxytype " :
print ' Current socks proxy type: ' + socksproxytype
print " Possibilities: ' none ' , ' SOCKS4a ' , ' SOCKS5 ' . "
uInput = userInput ( " Enter the new socksproxytype. " )
2017-01-11 14:27:19 +01:00
BMConfigParser ( ) . set ( ' bitmessagesettings ' , ' socksproxytype ' , str ( uInput ) )
2015-01-19 18:53:07 +01:00
elif uInput == " sockshostname " :
print ' Current socks host name: ' + sockshostname
uInput = userInput ( " Enter the new sockshostname. " )
2017-01-11 14:27:19 +01:00
BMConfigParser ( ) . set ( ' bitmessagesettings ' , ' sockshostname ' , str ( uInput ) )
2015-01-19 18:53:07 +01:00
elif uInput == " socksport " :
print ' Current socks port number: ' + socksport
uInput = userInput ( " Enter the new socksport. " )
2017-01-11 14:27:19 +01:00
BMConfigParser ( ) . set ( ' bitmessagesettings ' , ' socksport ' , str ( uInput ) )
2015-01-19 18:53:07 +01:00
elif uInput == " socksauthentication " :
print ' Current status: ' + str ( socksauthentication )
uInput = userInput ( " Enter the new status. " )
2017-01-11 14:27:19 +01:00
BMConfigParser ( ) . set ( ' bitmessagesettings ' , ' socksauthentication ' , str ( uInput ) )
2015-01-19 18:53:07 +01:00
elif uInput == " socksusername " :
print ' Current socks username: ' + socksusername
uInput = userInput ( " Enter the new socksusername. " )
2017-01-11 14:27:19 +01:00
BMConfigParser ( ) . set ( ' bitmessagesettings ' , ' socksusername ' , str ( uInput ) )
2015-01-19 18:53:07 +01:00
elif uInput == " sockspassword " :
print ' Current socks password: ' + sockspassword
uInput = userInput ( " Enter the new password. " )
2017-01-11 14:27:19 +01:00
BMConfigParser ( ) . set ( ' bitmessagesettings ' , ' sockspassword ' , str ( uInput ) )
2015-01-19 18:53:07 +01:00
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 :
2017-01-11 14:27:19 +01:00
BMConfigParser ( ) . write ( configfile )
2015-01-19 18:53:07 +01:00
restartBmNotify ( )
break
elif uInput == " n " :
usrPrompt = 1
main ( )
else :
print " Invalid input. "
usrPrompt = 1
main ( )
def validAddress ( address ) :
2018-02-18 20:14:21 +01:00
address_information = json . loads ( api . decodeAddress ( address ) )
2015-01-19 18:53:07 +01:00
2018-02-18 20:14:21 +01:00
if ' success ' in str ( address_information [ ' status ' ] ) . lower ( ) :
2015-01-19 18:53:07 +01:00
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
2017-12-26 14:17:37 +01:00
userInput ( " Are you sure, (Y)es or (N)o? " ) . lower ( ) # #uInput =
2015-01-19 18:53:07 +01:00
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 ' \n Label, 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
2017-12-26 14:17:37 +01:00
label = ( jsonAddresses [ ' addresses ' ] [ addNum ] [ ' label ' ] ) . encode ( ' utf ' ) # may still misdiplay in some consoles
2015-01-19 18:53:07 +01:00
address = str ( jsonAddresses [ ' addresses ' ] [ addNum ] [ ' address ' ] )
2017-12-26 14:17:37 +01:00
stream = str ( jsonAddresses [ ' addresses ' ] [ addNum ] [ ' stream ' ] )
2015-01-19 18:53:07 +01:00
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 '
2015-06-20 09:54:15 +02:00
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 ' ) [ 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 :
2017-12-26 14:17:37 +01:00
api . createRandomAddress ( addressLabel ) # generatedAddress =
2015-06-20 09:54:15 +02:00
except :
print ' \n Connection Error \n '
usrPrompt = 0
main ( )
2015-01-19 18:53:07 +01:00
def saveFile ( fileName , fileData ) : #Allows attachments and messages/broadcats to be saved
#This section finds all invalid characters and replaces them with ~
fileName = fileName . replace ( " " , " " )
fileName = fileName . replace ( " / " , " ~ " )
#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 ( " > " , " ~ " )
fileName = fileName . replace ( " | " , " ~ " )
directory = ' attachments '
if not os . path . exists ( directory ) :
os . makedirs ( directory )
filePath = directory + ' / ' + fileName
''' try: #Checks if file already exists
with open ( filePath ) :
print ' File Already Exists '
return
except IOError : pass '''
f = open ( filePath , ' wb+ ' ) #Begin saving to file
f . write ( fileData . decode ( " base64 " ) )
f . close
print ' \n Successfully saved ' + filePath + ' \n '
def attachment ( ) : #Allows users to attach a file to their message or broadcast
theAttachmentS = ' '
while True :
isImage = False
theAttachment = ' '
while True : #loops until valid path is entered
filePath = userInput ( ' \n Please enter the path to the attachment or just the attachment name if in this folder. ' )
try :
with open ( filePath ) : break
except IOError :
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?)
invSize = os . path . getsize ( filePath )
invSize = ( invSize / 1024 ) #Converts to kilobytes
round ( invSize , 2 ) #Rounds to two decimal places
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 '
uInput = userInput ( ' Are you sure you still want to attach it, (Y)es or (N)o? ' ) . lower ( )
if uInput != " y " :
print ' \n Attachment discarded. \n '
return ' '
elif ( invSize > 184320.0 ) : #If larger than 180MB, discard.
print ' \n Attachment too big, maximum allowed size:180MB \n '
main ( )
pathLen = len ( str ( ntpath . basename ( filePath ) ) ) #Gets the length of the filepath excluding the filename
fileName = filePath [ ( len ( str ( filePath ) ) - pathLen ) : ] #reads the filename
filetype = imghdr . what ( filePath ) #Tests if it is an image file
if filetype is not None :
print ' \n --------------------------------------------------- '
print ' Attachment detected as an Image. '
print ' <img> tags will automatically be included, '
print ' allowing the recipient to view the image '
print ' using the " View HTML code... " option in Bitmessage. '
print ' --------------------------------------------------- \n '
isImage = True
time . sleep ( 2 )
print ' \n Encoding Attachment, Please Wait ... \n ' #Alert the user that the encoding process may take some time.
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 = data . encode ( " base64 " )
if ( isImage == True ) : #If it is an image, include image tags in the message
theAttachment = """
< ! - - 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 - - >
Filename : % s
Filesize : % sKB
Encoding : base64
< center >
< div id = " image " >
< img alt = " %s " src = ' data:image/ %s ;base64, %s ' / >
< / div >
< / center > """ % (fileName,invSize,fileName,filetype,data)
else : #Else it is not an image so do not include the embedded image code.
theAttachment = """
< ! - - Note : File attachment below . Please use a base64 decoder , or Daemon , to save it . - - >
< ! - - Sent using Bitmessage Daemon . https : / / github . com / Dokument / PyBitmessage - Daemon - - >
Filename : % s
Filesize : % sKB
Encoding : base64
< 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 ( )
if ( uInput == ' y ' or uInput == ' yes ' ) : #Allows multiple attachments to be added to one message
theAttachmentS = str ( theAttachmentS ) + str ( theAttachment ) + ' \n \n '
elif ( uInput == ' n ' or uInput == ' no ' ) :
break
theAttachmentS = theAttachmentS + theAttachment
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.
global usrPrompt
if ( validAddress ( toAddress ) == False ) :
while True :
toAddress = userInput ( " What is the To Address? " )
if ( toAddress == " c " ) :
usrPrompt = 1
print ' '
main ( )
elif ( validAddress ( toAddress ) == False ) :
print ' \n Invalid Address. " c " to cancel. Please try again. \n '
else :
break
if ( validAddress ( fromAddress ) == False ) :
try :
jsonAddresses = json . loads ( api . listAddresses ( ) )
numAddresses = len ( jsonAddresses [ ' addresses ' ] ) #Number of addresses
except :
print ' \n Connection Error \n '
usrPrompt = 0
main ( )
if ( numAddresses > 1 ) : #Ask what address to send from if multiple addresses
found = False
while True :
print ' '
fromAddress = userInput ( " Enter an Address or Address Label to send from. " )
if fromAddress == " exit " :
usrPrompt = 1
main ( )
for addNum in range ( 0 , numAddresses ) : #processes all of the addresses
label = jsonAddresses [ ' addresses ' ] [ addNum ] [ ' label ' ]
address = jsonAddresses [ ' addresses ' ] [ addNum ] [ ' address ' ]
#stream = jsonAddresses['addresses'][addNum]['stream']
#enabled = jsonAddresses['addresses'][addNum]['enabled']
if ( fromAddress == label ) : #address entered was a label and is found
fromAddress = address
found = True
break
if ( found == False ) :
if ( validAddress ( fromAddress ) == False ) :
print ' \n Invalid Address. Please try again. \n '
else :
for addNum in range ( 0 , numAddresses ) : #processes all of the addresses
#label = jsonAddresses['addresses'][addNum]['label']
address = jsonAddresses [ ' addresses ' ] [ addNum ] [ ' address ' ]
#stream = jsonAddresses['addresses'][addNum]['stream']
#enabled = jsonAddresses['addresses'][addNum]['enabled']
if ( fromAddress == address ) : #address entered was a found in our addressbook.
found = True
break
if ( found == False ) :
print ' \n The address entered is not one of yours. Please try again. \n '
if ( found == True ) :
break #Address was found
else : #Only one address in address book
print ' \n Using the only address in the addressbook to send from. \n '
fromAddress = jsonAddresses [ ' addresses ' ] [ 0 ] [ ' address ' ]
if ( subject == ' ' ) :
subject = userInput ( " Enter your Subject. " )
subject = subject . encode ( ' base64 ' )
if ( message == ' ' ) :
message = userInput ( " Enter your Message. " )
uInput = userInput ( ' Would you like to add an attachment, (Y)es or (N)o? ' ) . lower ( )
if uInput == " y " :
message = message + ' \n \n ' + attachment ( )
message = message . encode ( ' base64 ' )
try :
ackData = api . sendMessage ( toAddress , fromAddress , subject , message )
print ' \n Message Status: ' , api . getStatus ( ackData ) , ' \n '
except :
print ' \n Connection Error \n '
usrPrompt = 0
main ( )
def sendBrd ( fromAddress , subject , message ) : #sends a broadcast
global usrPrompt
if ( fromAddress == ' ' ) :
try :
jsonAddresses = json . loads ( api . listAddresses ( ) )
numAddresses = len ( jsonAddresses [ ' addresses ' ] ) #Number of addresses
except :
print ' \n Connection Error \n '
usrPrompt = 0
main ( )
if ( numAddresses > 1 ) : #Ask what address to send from if multiple addresses
found = False
while True :
fromAddress = userInput ( " \n Enter an Address or Address Label to send from. " )
if fromAddress == " exit " :
usrPrompt = 1
main ( )
for addNum in range ( 0 , numAddresses ) : #processes all of the addresses
label = jsonAddresses [ ' addresses ' ] [ addNum ] [ ' label ' ]
address = jsonAddresses [ ' addresses ' ] [ addNum ] [ ' address ' ]
#stream = jsonAddresses['addresses'][addNum]['stream']
#enabled = jsonAddresses['addresses'][addNum]['enabled']
if ( fromAddress == label ) : #address entered was a label and is found
fromAddress = address
found = True
break
if ( found == False ) :
if ( validAddress ( fromAddress ) == False ) :
print ' \n Invalid Address. Please try again. \n '
else :
for addNum in range ( 0 , numAddresses ) : #processes all of the addresses
#label = jsonAddresses['addresses'][addNum]['label']
address = jsonAddresses [ ' addresses ' ] [ addNum ] [ ' address ' ]
#stream = jsonAddresses['addresses'][addNum]['stream']
#enabled = jsonAddresses['addresses'][addNum]['enabled']
if ( fromAddress == address ) : #address entered was a found in our addressbook.
found = True
break
if ( found == False ) :
print ' \n The address entered is not one of yours. Please try again. \n '
if ( found == True ) :
break #Address was found
else : #Only one address in address book
print ' \n Using the only address in the addressbook to send from. \n '
fromAddress = jsonAddresses [ ' addresses ' ] [ 0 ] [ ' address ' ]
if ( subject == ' ' ) :
subject = userInput ( " Enter your Subject. " )
subject = subject . encode ( ' base64 ' )
if ( message == ' ' ) :
message = userInput ( " Enter your Message. " )
uInput = userInput ( ' Would you like to add an attachment, (Y)es or (N)o? ' ) . lower ( )
if uInput == " y " :
message = message + ' \n \n ' + attachment ( )
message = message . encode ( ' base64 ' )
try :
ackData = api . sendBroadcast ( fromAddress , subject , message )
print ' \n Message Status: ' , api . getStatus ( ackData ) , ' \n '
except :
print ' \n Connection Error \n '
usrPrompt = 0
main ( )
def inbox ( unreadOnly = False ) : #Lists the messages by: Message Number, To Address Label, From Address Label, Subject, Received Time)
global usrPrompt
try :
inboxMessages = json . loads ( api . getAllInboxMessages ( ) )
numMessages = len ( inboxMessages [ ' inboxMessages ' ] )
except :
print ' \n Connection Error \n '
usrPrompt = 0
main ( )
messagesPrinted = 0
messagesUnread = 0
for msgNum in range ( 0 , numMessages ) : #processes all of the messages in the inbox
message = inboxMessages [ ' inboxMessages ' ] [ msgNum ]
# if we are displaying all messages or if this message is unread then display it
if not unreadOnly or not message [ ' read ' ] :
print ' ----------------------------------- \n '
print ' Message Number: ' , msgNum #Message Number
print ' To: ' , getLabelForAddress ( message [ ' toAddress ' ] ) #Get the to address
print ' From: ' , getLabelForAddress ( message [ ' fromAddress ' ] ) #Get the from address
print ' Subject: ' , message [ ' subject ' ] . decode ( ' base64 ' ) #Get the subject
print ' Received: ' , datetime . datetime . fromtimestamp ( float ( message [ ' receivedTime ' ] ) ) . strftime ( ' % Y- % m- %d % H: % M: % S ' )
messagesPrinted + = 1
if not message [ ' read ' ] : messagesUnread + = 1
if ( messagesPrinted % 20 == 0 and messagesPrinted != 0 ) :
2017-12-26 14:17:37 +01:00
userInput ( ' (Press Enter to continue or type (Exit) to return to the main menu.) ' ) . lower ( ) # uInput =
2015-01-19 18:53:07 +01:00
print ' \n ----------------------------------- '
print ' There are %d unread messages of %d messages in the inbox. ' % ( messagesUnread , numMessages )
print ' ----------------------------------- \n '
def outbox ( ) :
global usrPrompt
try :
outboxMessages = json . loads ( api . getAllSentMessages ( ) )
numMessages = len ( outboxMessages [ ' sentMessages ' ] )
except :
print ' \n Connection Error \n '
usrPrompt = 0
main ( )
for msgNum in range ( 0 , numMessages ) : #processes all of the messages in the outbox
print ' \n ----------------------------------- \n '
print ' Message Number: ' , msgNum #Message Number
#print ' Message ID:', outboxMessages['sentMessages'][msgNum]['msgid']
print ' To: ' , getLabelForAddress ( outboxMessages [ ' sentMessages ' ] [ msgNum ] [ ' toAddress ' ] ) #Get the to address
print ' From: ' , getLabelForAddress ( outboxMessages [ ' sentMessages ' ] [ msgNum ] [ ' fromAddress ' ] ) #Get the from address
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 ' )
if ( msgNum % 20 == 0 and msgNum != 0 ) :
2017-12-26 14:17:37 +01:00
userInput ( ' (Press Enter to continue or type (Exit) to return to the main menu.) ' ) . lower ( ) # uInput =
2015-01-19 18:53:07 +01:00
print ' \n ----------------------------------- '
print ' There are ' , numMessages , ' messages in the outbox. '
print ' ----------------------------------- \n '
def readSentMsg ( msgNum ) : #Opens a sent message for reading
global usrPrompt
try :
outboxMessages = json . loads ( api . getAllSentMessages ( ) )
numMessages = len ( outboxMessages [ ' sentMessages ' ] )
except :
print ' \n Connection Error \n '
usrPrompt = 0
main ( )
print ' '
if ( msgNum > = numMessages ) :
print ' \n Invalid Message Number. \n '
main ( )
#Begin attachment detection
message = outboxMessages [ ' sentMessages ' ] [ msgNum ] [ ' message ' ] . decode ( ' base64 ' )
while True : #Allows multiple messages to be downloaded/saved
if ( ' ;base64, ' in message ) : #Found this text in the message, there is probably an attachment.
attPos = message . index ( " ;base64, " ) #Finds the attachment position
attEndPos = message . index ( " ' /> " ) #Finds the end of the attachment
#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
fileName = message [ fnPos + 7 : fnEndPos ]
else :
fnPos = attPos
fileName = ' Attachment '
uInput = userInput ( ' \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 ]
saveFile ( fileName , attachment )
message = message [ : fnPos ] + ' ~<Attachment data removed for easier viewing>~ ' + message [ ( attEndPos + 4 ) : ]
else :
break
#End attachment Detection
print ' \n To: ' , getLabelForAddress ( outboxMessages [ ' sentMessages ' ] [ msgNum ] [ ' toAddress ' ] ) #Get the to address
print ' From: ' , getLabelForAddress ( outboxMessages [ ' sentMessages ' ] [ msgNum ] [ ' fromAddress ' ] ) #Get the from address
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 ' Message: \n '
print message #inboxMessages['inboxMessages'][msgNum]['message'].decode('base64')
print ' '
def readMsg ( msgNum ) : #Opens a message for reading
global usrPrompt
try :
inboxMessages = json . loads ( api . getAllInboxMessages ( ) )
numMessages = len ( inboxMessages [ ' inboxMessages ' ] )
except :
print ' \n Connection Error \n '
usrPrompt = 0
main ( )
if ( msgNum > = numMessages ) :
print ' \n Invalid Message Number. \n '
main ( )
#Begin attachment detection
message = inboxMessages [ ' inboxMessages ' ] [ msgNum ] [ ' message ' ] . decode ( ' base64 ' )
while True : #Allows multiple messages to be downloaded/saved
if ( ' ;base64, ' in message ) : #Found this text in the message, there is probably an attachment.
attPos = message . index ( " ;base64, " ) #Finds the attachment position
attEndPos = message . index ( " ' /> " ) #Finds the end of the attachment
#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
fileName = message [ fnPos + 7 : fnEndPos ]
else :
fnPos = attPos
fileName = ' Attachment '
uInput = userInput ( ' \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 ]
saveFile ( fileName , attachment )
message = message [ : fnPos ] + ' ~<Attachment data removed for easier viewing>~ ' + message [ ( attEndPos + 4 ) : ]
else :
break
#End attachment Detection
print ' \n To: ' , getLabelForAddress ( inboxMessages [ ' inboxMessages ' ] [ msgNum ] [ ' toAddress ' ] ) #Get the to address
print ' From: ' , getLabelForAddress ( inboxMessages [ ' inboxMessages ' ] [ msgNum ] [ ' fromAddress ' ] ) #Get the from address
print ' Subject: ' , inboxMessages [ ' inboxMessages ' ] [ msgNum ] [ ' subject ' ] . decode ( ' base64 ' ) #Get the subject
print ' Received: ' , datetime . datetime . fromtimestamp ( float ( inboxMessages [ ' inboxMessages ' ] [ msgNum ] [ ' receivedTime ' ] ) ) . strftime ( ' % Y- % m- %d % H: % M: % S ' )
print ' Message: \n '
print message #inboxMessages['inboxMessages'][msgNum]['message'].decode('base64')
print ' '
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.
global usrPrompt
forwardORreply = forwardORreply . lower ( ) #makes it lowercase
try :
inboxMessages = json . loads ( api . getAllInboxMessages ( ) )
except :
print ' \n Connection Error \n '
usrPrompt = 0
main ( )
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.
subject = inboxMessages [ ' inboxMessages ' ] [ msgNum ] [ ' subject ' ]
subject = subject . decode ( ' base64 ' )
if ( forwardORreply == ' reply ' ) :
toAdd = inboxMessages [ ' inboxMessages ' ] [ msgNum ] [ ' fromAddress ' ] #Address it was From, now the To address
subject = " Re: " + subject
elif ( forwardORreply == ' forward ' ) :
subject = " Fwd: " + subject
while True :
toAdd = userInput ( " What is the To Address? " )
if ( toAdd == " c " ) :
usrPrompt = 1
print ' '
main ( )
elif ( validAddress ( toAdd ) == False ) :
print ' \n Invalid Address. " c " to cancel. Please try again. \n '
else :
break
else :
print ' \n Invalid Selection. Reply or Forward only '
usrPrompt = 0
main ( )
subject = subject . encode ( ' base64 ' )
newMessage = userInput ( " Enter your Message. " )
uInput = userInput ( ' Would you like to add an attachment, (Y)es or (N)o? ' ) . lower ( )
if uInput == " y " :
newMessage = newMessage + ' \n \n ' + attachment ( )
newMessage = newMessage + ' \n \n ------------------------------------------------------ \n '
newMessage = newMessage + message
newMessage = newMessage . encode ( ' base64 ' )
sendMsg ( toAdd , fromAdd , subject , newMessage )
main ( )
def delMsg ( msgNum ) : #Deletes a specified message from the inbox
global usrPrompt
try :
inboxMessages = json . loads ( api . getAllInboxMessages ( ) )
msgId = inboxMessages [ ' inboxMessages ' ] [ int ( msgNum ) ] [ ' msgid ' ] #gets the message ID via the message index number
msgAck = api . trashMessage ( msgId )
except :
print ' \n Connection Error \n '
usrPrompt = 0
main ( )
return msgAck
def delSentMsg ( msgNum ) : #Deletes a specified message from the outbox
global usrPrompt
try :
outboxMessages = json . loads ( api . getAllSentMessages ( ) )
msgId = outboxMessages [ ' sentMessages ' ] [ int ( msgNum ) ] [ ' msgid ' ] #gets the message ID via the message index number
msgAck = api . trashSentMessage ( msgId )
except :
print ' \n Connection Error \n '
usrPrompt = 0
main ( )
return msgAck
def getLabelForAddress ( address ) :
if address in knownAddresses :
return knownAddresses [ address ]
else :
buildKnownAddresses ( )
if address in knownAddresses :
return knownAddresses [ address ]
return address
def buildKnownAddresses ( ) :
# add from address book
try :
response = api . listAddressBookEntries ( )
# if api is too old then fail
if " API Error 0020 " in response : return
addressBook = json . loads ( response )
for entry in addressBook [ ' addresses ' ] :
if entry [ ' address ' ] not in knownAddresses :
knownAddresses [ entry [ ' address ' ] ] = " %s ( %s ) " % ( entry [ ' label ' ] . decode ( ' base64 ' ) , entry [ ' address ' ] )
except :
print ' \n Connection Error \n '
usrPrompt = 0
main ( )
# add from my addresses
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 [ ' address ' ] not in knownAddresses :
knownAddresses [ entry [ ' address ' ] ] = " %s ( %s ) " % ( entry [ ' label ' ] . decode ( ' base64 ' ) , entry [ ' address ' ] )
except :
print ' \n Connection Error \n '
usrPrompt = 0
main ( )
def listAddressBookEntries ( ) :
try :
response = api . listAddressBookEntries ( )
if " API Error " in response :
return getAPIErrorCode ( response )
addressBook = json . loads ( response )
print
print ' -------------------------------------------------------------- '
print ' | Label | Address | '
print ' |--------------------|---------------------------------------| '
for entry in addressBook [ ' addresses ' ] :
label = entry [ ' label ' ] . decode ( ' base64 ' )
address = entry [ ' address ' ]
if ( len ( label ) > 19 ) : label = label [ : 16 ] + ' ... '
print ' | ' + label . ljust ( 19 ) + ' | ' + address . ljust ( 37 ) + ' | '
print ' -------------------------------------------------------------- '
print
except :
print ' \n Connection Error \n '
usrPrompt = 0
main ( )
def addAddressToAddressBook ( address , label ) :
try :
response = api . addAddressBookEntry ( address , label . encode ( ' base64 ' ) )
if " API Error " in response :
return getAPIErrorCode ( response )
except :
print ' \n Connection Error \n '
usrPrompt = 0
main ( )
def deleteAddressFromAddressBook ( address ) :
try :
response = api . deleteAddressBookEntry ( address )
if " API Error " in response :
return getAPIErrorCode ( response )
except :
print ' \n Connection Error \n '
usrPrompt = 0
main ( )
def getAPIErrorCode ( response ) :
if " API Error " in response :
# if we got an API error return the number by getting the number
# after the second space and removing the trailing colon
return int ( response . split ( ) [ 2 ] [ : - 1 ] )
def markMessageRead ( messageID ) :
try :
response = api . getInboxMessageByID ( messageID , True )
if " API Error " in response :
return getAPIErrorCode ( response )
except :
print ' \n Connection Error \n '
usrPrompt = 0
main ( )
def markMessageUnread ( messageID ) :
try :
response = api . getInboxMessageByID ( messageID , False )
if " API Error " in response :
return getAPIErrorCode ( response )
except :
print ' \n Connection Error \n '
usrPrompt = 0
main ( )
def markAllMessagesRead ( ) :
try :
inboxMessages = json . loads ( api . getAllInboxMessages ( ) ) [ ' inboxMessages ' ]
except :
print ' \n Connection Error \n '
usrPrompt = 0
main ( )
for message in inboxMessages :
if not message [ ' read ' ] :
markMessageRead ( message [ ' msgid ' ] )
def markAllMessagesUnread ( ) :
try :
inboxMessages = json . loads ( api . getAllInboxMessages ( ) ) [ ' inboxMessages ' ]
except :
print ' \n Connection Error \n '
usrPrompt = 0
main ( )
for message in inboxMessages :
if message [ ' read ' ] :
markMessageUnread ( message [ ' msgid ' ] )
2015-06-20 09:54:15 +02:00
def clientStatus ( ) :
try :
clientStatus = json . loads ( api . clientStatus ( ) )
except :
print ' \n Connection Error \n '
usrPrompt = 0
main ( )
print " \n networkStatus: " + clientStatus [ ' networkStatus ' ] + " \n "
print " \n networkConnections: " + str ( clientStatus [ ' networkConnections ' ] ) + " \n "
print " \n numberOfPubkeysProcessed: " + str ( clientStatus [ ' numberOfPubkeysProcessed ' ] ) + " \n "
print " \n numberOfMessagesProcessed: " + str ( clientStatus [ ' numberOfMessagesProcessed ' ] ) + " \n "
print " \n numberOfBroadcastsProcessed: " + str ( clientStatus [ ' numberOfBroadcastsProcessed ' ] ) + " \n "
2017-08-22 13:23:03 +02:00
def shutdown ( ) :
try :
api . shutdown ( )
except socket . error :
pass
print " \n Shutdown command relayed \n "
2015-01-19 18:53:07 +01:00
def UI ( usrInput ) : #Main user menu
global usrPrompt
if usrInput == " help " or usrInput == " h " or usrInput == " ? " :
print ' '
print ' ------------------------------------------------------------------------- '
print ' | https://github.com/Dokument/PyBitmessage-Daemon | '
print ' |-----------------------------------------------------------------------| '
print ' | Command | Description | '
print ' |------------------------|----------------------------------------------| '
print ' | help | This help file. | '
print ' | apiTest | Tests the API | '
print ' | addInfo | Returns address information (If valid) | '
print ' | bmSettings | BitMessage settings | '
print ' | exit | Use anytime to return to main menu | '
print ' | quit | Quits the program | '
print ' |------------------------|----------------------------------------------| '
print ' | listAddresses | Lists all of the users addresses | '
print ' | generateAddress | Generates a new address | '
print ' | getAddress | Get determinist address from passphrase | '
print ' |------------------------|----------------------------------------------| '
print ' | listAddressBookEntries | Lists entries from the Address Book | '
print ' | addAddressBookEntry | Add address to the Address Book | '
print ' | deleteAddressBookEntry | Deletes address from the Address Book | '
print ' |------------------------|----------------------------------------------| '
print ' | subscribe | Subscribes to an address | '
print ' | unsubscribe | Unsubscribes from an address | '
2017-12-26 15:01:12 +01:00
#print' | listSubscriptions | Lists all of the subscriptions. |'
2015-01-19 18:53:07 +01:00
print ' |------------------------|----------------------------------------------| '
2017-12-26 14:17:37 +01:00
print ' | create | Creates a channel | '
2015-01-19 18:53:07 +01:00
print ' | join | Joins a channel | '
print ' | leave | Leaves a channel | '
2017-12-26 14:17:37 +01:00
print ' |------------------------|----------------------------------------------| '
2015-01-19 18:53:07 +01:00
print ' | inbox | Lists the message information for the inbox | '
print ' | outbox | Lists the message information for the outbox | '
print ' | send | Send a new message or broadcast | '
print ' | unread | Lists all unread inbox messages | '
print ' | read | Reads a message from the inbox or outbox | '
print ' | save | Saves message to text file | '
print ' | delete | Deletes a message or all messages | '
print ' ------------------------------------------------------------------------- '
print ' '
main ( )
elif usrInput == " apitest " : #tests the API Connection.
if ( apiTest ( ) == True ) :
print ' \n API connection test has: PASSED \n '
else :
print ' \n API connection test has: FAILED \n '
main ( )
elif usrInput == " addinfo " :
tmp_address = userInput ( ' \n Enter the Bitmessage Address. ' )
2018-02-18 20:14:21 +01:00
address_information = json . loads ( api . decodeAddress ( tmp_address ) )
2015-01-19 18:53:07 +01:00
print ' \n ------------------------------ '
2018-02-18 20:14:21 +01:00
if ' success ' in str ( address_information [ ' status ' ] ) . lower ( ) :
2015-01-19 18:53:07 +01:00
print ' Valid Address '
2018-02-18 20:14:21 +01:00
print ' Address Version: %s ' % str ( address_information [ ' addressVersion ' ] )
print ' Stream Number: %s ' % str ( address_information [ ' streamNumber ' ] )
2015-01-19 18:53:07 +01:00
else :
print ' Invalid Address ! '
print ' ------------------------------ \n '
main ( )
elif usrInput == " bmsettings " : #tests the API Connection.
bmSettings ( )
print ' '
main ( )
elif usrInput == " quit " : #Quits the application
print ' \n Bye \n '
sys . exit ( )
2017-12-26 14:17:37 +01:00
os . _exit ( )
2015-01-19 18:53:07 +01:00
elif usrInput == " listaddresses " : #Lists all of the identities in the addressbook
listAdd ( )
main ( )
elif usrInput == " generateaddress " : #Generates a new address
uInput = userInput ( ' \n Would you like to create a (D)eterministic or (R)andom address? ' ) . lower ( )
if uInput == " d " or uInput == " determinstic " : #Creates a deterministic address
deterministic = True
#lbl = raw_input('Label the new address:') #currently not possible via the api
lbl = ' '
passphrase = userInput ( ' Enter the Passphrase. ' ) #.encode('base64')
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
streamNum = 1
isRipe = userInput ( ' Shorten the address, (Y)es or (N)o? ' ) . lower ( )
if isRipe == " y " :
ripe = True
print genAdd ( lbl , deterministic , passphrase , numOfAdd , addVNum , streamNum , ripe )
main ( )
elif isRipe == " n " :
ripe = False
print genAdd ( lbl , deterministic , passphrase , numOfAdd , addVNum , streamNum , ripe )
main ( )
elif isRipe == " exit " :
usrPrompt = 1
main ( )
else :
print ' \n Invalid input \n '
main ( )
elif uInput == " r " or uInput == " random " : #Creates a random address with user-defined label
deterministic = False
null = ' '
lbl = userInput ( ' Enter the label for the new address. ' )
print genAdd ( lbl , deterministic , null , null , null , null , null )
main ( )
else :
print ' \n Invalid input \n '
main ( )
elif usrInput == " getaddress " : #Gets the address for/from a passphrase
phrase = userInput ( " Enter the address passphrase. " )
print ' \n Working... \n '
#vNumber = int(raw_input("Enter the address version number:"))
#sNumber = int(raw_input("Enter the address stream number:"))
address = getAddress ( phrase , 4 , 1 ) #,vNumber,sNumber)
print ( ' \n Address: ' + address + ' \n ' )
usrPrompt = 1
main ( )
elif usrInput == " subscribe " : #Subsribe to an address
subscribe ( )
usrPrompt = 1
main ( )
elif usrInput == " unsubscribe " : #Unsubscribe from an address
unsubscribe ( )
usrPrompt = 1
main ( )
elif usrInput == " listsubscriptions " : #Unsubscribe from an address
listSubscriptions ( )
usrPrompt = 1
main ( )
elif usrInput == " create " :
createChan ( )
2017-12-26 14:17:37 +01:00
usrPrompt = 1
2015-01-19 18:53:07 +01:00
main ( )
elif usrInput == " join " :
joinChan ( )
2017-12-26 14:17:37 +01:00
usrPrompt = 1
2015-01-19 18:53:07 +01:00
main ( )
elif usrInput == " leave " :
leaveChan ( )
2017-12-26 14:17:37 +01:00
usrPrompt = 1
2015-01-19 18:53:07 +01:00
main ( )
elif usrInput == " inbox " :
print ' \n Loading... \n '
inbox ( )
main ( )
elif usrInput == " unread " :
print ' \n Loading... \n '
inbox ( True )
main ( )
elif usrInput == " outbox " :
print ' \n Loading... \n '
outbox ( )
main ( )
elif usrInput == ' send ' : #Sends a message or broadcast
uInput = userInput ( ' Would you like to send a (M)essage or (B)roadcast? ' ) . lower ( )
if ( uInput == ' m ' or uInput == ' message ' ) :
null = ' '
sendMsg ( null , null , null , null )
main ( )
elif ( uInput == ' b ' or uInput == ' broadcast ' ) :
null = ' '
sendBrd ( null , null , null )
main ( )
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 ( )
if ( uInput != ' i ' and uInput != ' inbox ' and uInput != ' o ' and uInput != ' outbox ' ) :
print ' \n Invalid Input. \n '
usrPrompt = 1
main ( )
msgNum = int ( userInput ( " What is the number of the message you wish to open? " ) )
if ( uInput == ' i ' or uInput == ' inbox ' ) :
print ' \n Loading... \n '
messageID = readMsg ( msgNum )
uInput = userInput ( " \n Would you like to keep this message unread, (Y)es or (N)o? " ) . lower ( )
if not ( uInput == ' y ' or uInput == ' yes ' ) :
markMessageRead ( messageID )
usrPrompt = 1
uInput = userInput ( " \n Would you like to (D)elete, (F)orward, (R)eply to, or (Exit) this message? " ) . lower ( )
if ( uInput == ' r ' or uInput == ' reply ' ) :
print ' \n Loading... \n '
print ' '
replyMsg ( msgNum , ' reply ' )
usrPrompt = 1
elif ( uInput == ' f ' or uInput == ' forward ' ) :
print ' \n Loading... \n '
print ' '
replyMsg ( msgNum , ' forward ' )
usrPrompt = 1
elif ( uInput == " d " or uInput == ' delete ' ) :
uInput = userInput ( " Are you sure, (Y)es or (N)o? " ) . lower ( ) #Prevent accidental deletion
if uInput == " y " :
delMsg ( msgNum )
print ' \n Message Deleted. \n '
usrPrompt = 1
else :
usrPrompt = 1
else :
print ' \n Invalid entry \n '
usrPrompt = 1
elif ( uInput == ' o ' or uInput == ' outbox ' ) :
readSentMsg ( msgNum )
uInput = userInput ( " Would you like to (D)elete, or (Exit) this message? " ) . lower ( ) #Gives the user the option to delete the message
if ( uInput == " d " or uInput == ' delete ' ) :
uInput = userInput ( ' Are you sure, (Y)es or (N)o? ' ) . lower ( ) #Prevent accidental deletion
if uInput == " y " :
delSentMsg ( msgNum )
print ' \n Message Deleted. \n '
usrPrompt = 1
else :
usrPrompt = 1
else :
print ' \n Invalid Entry \n '
usrPrompt = 1
main ( )
elif usrInput == " save " :
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 ' ) :
print ' \n Invalid Input. \n '
usrPrompt = 1
main ( )
if ( uInput == ' i ' or uInput == ' inbox ' ) :
inboxMessages = json . loads ( api . getAllInboxMessages ( ) )
numMessages = len ( inboxMessages [ ' inboxMessages ' ] )
while True :
msgNum = int ( userInput ( " What is the number of the message you wish to save? " ) )
if ( msgNum > = numMessages ) :
print ' \n Invalid Message Number. \n '
else :
break
subject = inboxMessages [ ' inboxMessages ' ] [ msgNum ] [ ' subject ' ] . decode ( ' base64 ' )
message = inboxMessages [ ' inboxMessages ' ] [ msgNum ] [ ' message ' ] #Don't decode since it is done in the saveFile function
elif ( uInput == ' o ' or uInput == ' outbox ' ) :
outboxMessages = json . loads ( api . getAllSentMessages ( ) )
numMessages = len ( outboxMessages [ ' sentMessages ' ] )
while True :
msgNum = int ( userInput ( " What is the number of the message you wish to save? " ) )
if ( msgNum > = numMessages ) :
print ' \n Invalid Message Number. \n '
else :
break
subject = outboxMessages [ ' sentMessages ' ] [ msgNum ] [ ' subject ' ] . decode ( ' base64 ' )
message = outboxMessages [ ' sentMessages ' ] [ msgNum ] [ ' message ' ] #Don't decode since it is done in the saveFile function
subject = subject + ' .txt '
saveFile ( subject , message )
usrPrompt = 1
main ( )
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 ( )
if ( uInput == ' i ' or uInput == ' inbox ' ) :
inboxMessages = json . loads ( api . getAllInboxMessages ( ) )
numMessages = len ( inboxMessages [ ' inboxMessages ' ] )
while True :
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 ' ) :
break
elif ( int ( msgNum ) > = numMessages ) :
print ' \n Invalid Message Number. \n '
else :
break
uInput = userInput ( " Are you sure, (Y)es or (N)o? " ) . lower ( ) #Prevent accidental deletion
if uInput == " y " :
if ( msgNum == ' a ' or msgNum == ' all ' ) :
print ' '
for msgNum in range ( 0 , numMessages ) : #processes all of the messages in the inbox
print ' Deleting message ' , msgNum + 1 , ' of ' , numMessages
delMsg ( 0 )
print ' \n Inbox is empty. '
usrPrompt = 1
else :
delMsg ( int ( msgNum ) )
print ' \n Notice: Message numbers may have changed. \n '
main ( )
else :
usrPrompt = 1
elif ( uInput == ' o ' or uInput == ' outbox ' ) :
outboxMessages = json . loads ( api . getAllSentMessages ( ) )
numMessages = len ( outboxMessages [ ' sentMessages ' ] )
while True :
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 ' ) :
break
elif ( int ( msgNum ) > = numMessages ) :
print ' \n Invalid Message Number. \n '
else :
break
uInput = userInput ( " Are you sure, (Y)es or (N)o? " ) . lower ( ) #Prevent accidental deletion
if uInput == " y " :
if ( msgNum == ' a ' or msgNum == ' all ' ) :
print ' '
for msgNum in range ( 0 , numMessages ) : #processes all of the messages in the outbox
print ' Deleting message ' , msgNum + 1 , ' of ' , numMessages
delSentMsg ( 0 )
print ' \n Outbox is empty. '
usrPrompt = 1
else :
delSentMsg ( int ( msgNum ) )
print ' \n Notice: Message numbers may have changed. \n '
main ( )
else :
usrPrompt = 1
else :
print ' \n Invalid Entry. \n '
2017-12-26 14:17:37 +01:00
usrPrompt = 1
2015-01-19 18:53:07 +01:00
main ( )
elif usrInput == " exit " :
print ' \n You are already at the main menu. Use " quit " to quit. \n '
usrPrompt = 1
main ( )
elif usrInput == " listaddressbookentries " :
res = listAddressBookEntries ( )
if res == 20 : print ' \n Error: API function not supported. \n '
usrPrompt = 1
main ( )
elif usrInput == " addaddressbookentry " :
address = userInput ( ' Enter address ' )
label = userInput ( ' Enter label ' )
res = addAddressToAddressBook ( address , label )
if res == 16 : print ' \n Error: Address already exists in Address Book. \n '
if res == 20 : print ' \n Error: API function not supported. \n '
usrPrompt = 1
main ( )
elif usrInput == " deleteaddressbookentry " :
address = userInput ( ' Enter address ' )
res = deleteAddressFromAddressBook ( address )
if res == 20 : print ' \n Error: API function not supported. \n '
usrPrompt = 1
main ( )
elif usrInput == " markallmessagesread " :
markAllMessagesRead ( )
usrPrompt = 1
main ( )
elif usrInput == " markallmessagesunread " :
markAllMessagesUnread ( )
usrPrompt = 1
main ( )
2015-06-20 09:54:15 +02:00
elif usrInput == " status " :
clientStatus ( )
usrPrompt = 1
main ( )
2017-08-22 13:23:03 +02:00
elif usrInput == " shutdown " :
shutdown ( )
usrPrompt = 1
main ( )
2015-06-20 09:54:15 +02:00
elif usrInput == " million+ " :
genMilAddr ( )
usrPrompt = 1
main ( )
elif usrInput == " million- " :
delMilAddr ( )
usrPrompt = 1
main ( )
2015-01-19 18:53:07 +01:00
else :
print ' \n " ' , usrInput , ' " is not a command. \n '
usrPrompt = 1
main ( )
def main ( ) :
global api
global usrPrompt
if ( usrPrompt == 0 ) :
print ' \n ------------------------------ '
print ' | Bitmessage Daemon by .dok | '
2017-12-26 15:01:12 +01:00
print ' | Version 0.3.1 for BM 0.6.2 | '
2015-01-19 18:53:07 +01:00
print ' ------------------------------ '
api = xmlrpclib . ServerProxy ( apiData ( ) ) #Connect to BitMessage using these api credentials
if ( apiTest ( ) == False ) :
print ' \n **************************************************************** '
print ' WARNING: You are not connected to the Bitmessage client. '
print ' Either Bitmessage is not running or your settings are incorrect. '
print ' Use the command " apiTest " or " bmSettings " to resolve this issue. '
print ' **************************************************************** \n '
print ' Type (H)elp for a list of commands. ' #Startup message
usrPrompt = 2
#if (apiTest() == False):#Preform a connection test #taken out until I get the error handler working
# print '*************************************'
# print 'WARNING: No connection to Bitmessage.'
# print '*************************************'
# print ' '
elif ( usrPrompt == 1 ) :
print ' \n Type (H)elp for a list of commands. ' #Startup message
usrPrompt = 2
try :
UI ( ( raw_input ( ' > ' ) . lower ( ) ) . replace ( " " , " " ) )
except EOFError :
UI ( " quit " )
if __name__ == " __main__ " :
2017-12-26 15:01:12 +01:00
main ( )