Code:
#!/usr/bin/env python2 ''' 1. put your password in line 74 ; in keys.dat have lines : choose daemon = true or false daemon = false apienabled = true apiinterface = 127.0.0.1 apiusername = username apipassword = password ^--------------- must match with line 74 2. run ....../src/bitmessagemain.py as usual 3. then run in a bash shell / Konsole : ./bmcli.py show inbox 4. you will see the inbox of Bitmessages ! Name: bmcli (BitMessage Command Line Interface) License: MIT version 0.2 Description: a rudimentary command line interface client for PyBitmessage's RPC API in case you don't have or want a GUI or want to develop an own one or want to use pypy or don't have qt4 or for whatever reason a similar pgm is "pyBM..../src/bitmessagecli.py" but this one is less tedious and nice for bash Hint1: you have to activate the API and Daemon mode for this to work. Hint2: Daemon mode is not strictly necessary , simply keep daemon = false some bugs still in it and poor exception handling See https://bitmessage.org/wiki/API and https://bitmessage.org/wiki/Daemon for details ''' import xmlrpclib,base64,os,sys,json,time # have those installed with pip or whatever convert_time=lambda t:int(t[0:-1])*3600 if t[-1]=='h' else int(t[0:-1])*3600*24 if t[-1]=='d' else int(t[0:-1])*60 if t[-1]=='d' else int(t); tobytes=lambda x:x if type(x)==bytes else (unicode.encode(x,encoding="UTF-8") if type(x)==unicode else bytes(x)) tounicode=lambda x:x if type(x)==unicode else (unicode.decode(x,encoding="UTF-8") if type(x)==unicode else unicode(x)) u64decode=lambda x:tobytes(base64.b64decode(tobytes(x))); print_u=lambda x:sys.stdout.write(tobytes('\n'.join(x))+'\n') def print_help(): sys.stderr.write('Usage:\n\ <BITMESSAGE_SERVER>=http://user:pass@host:port/> bmcli <subcommand> [args]\n\ subcommand is either:\n\ show identities\n\ show inbox [new]\n\ show sent [pending]\n\ show subscriptions\n\ show contacts\n\ show message <id>\n\ show trash\n\ new message <sender_addr> <recipient_addr> <subject> [ttl]\n\ new broadcast <sender_addr> <subject> [ttl]\n\ new contact <name> <address>\n\ new subscription <name> <address>\n\ new chan <passphrase> [address]\n\ new identity name\n\ delete identity <address>\n\ delete subscription <address>\n\ delete contact <address>\n\ delete message <id>\n\ delete trash\n'); exit(1); try: api=xmlrpclib.ServerProxy(os.environ['BITMESSAGE_SERVER']); except: api=xmlrpclib.ServerProxy('http://username:password@127.0.0.1:8442/'); # put your password from keys.dat here def get_addresses(categories=[]): return (map(lambda x:{ 'address':tobytes(x['address']), 'label':tobytes(x[u'label']) },json.loads(api.listAddresses())['addresses']) if categories==[] else [])+map( lambda x:{ 'address':tobytes(x['address']), 'label':u64decode(x['label']) }, reduce( list.__add__, map( lambda z:z[z.keys()[0]], map( lambda y:json.loads(y), [api.listSubscriptions(),api.listAddressBookEntries()] if categories==[] else categories ) ) ) ); if __name__ == '__main__': if sys.argv[1] == 'show': if sys.argv[2] == 'inbox': addresses=get_addresses(); inbox=map( lambda y:{ 'msgid':base64.b64encode(base64.b16decode(y['msgid'].upper())), 'subject':u64decode(y['subject']), 'time':int(y['receivedTime']), 'length':int(len(base64.b64decode(tobytes(y['message'])))), 'to':( lambda x:filter( lambda z:z['address']==x, addresses+[{'address':x,'label':x}]) )( tobytes(y['toAddress']))[0]['label'], 'from':( lambda x:filter( lambda z:z['address']==x, addresses+[{'address':x,'label':x}]) )( tobytes(y['fromAddress']))[0]['label'], 'read':bool(y['read']) }, json.loads(api.getAllInboxMessages())['inboxMessages'] ); if len(sys.argv) >= 4: if sys.argv[3] == 'new': inbox=filter(lambda x:not x['read'],inbox); inbox.sort(cmp=(lambda x,y:int.__cmp__(x['time'],y['time']))); print_u ( map( lambda x:'\t'.join( [ x['from'], x['to'], time.ctime(x['time']), tobytes(x['length']), x['msgid'], x['subject'] ] ), inbox) ) elif sys.argv[2] == 'subscriptions': print_u ( map( lambda x:x['address']+'\t'+x['label'], get_addresses(categories=[api.listSubscriptions()]) ) ) elif sys.argv[2] == 'sent': addresses=get_addresses(); sent=map( lambda y:{ 'msgid':base64.b64encode(base64.b16decode(y['msgid'].upper())), 'subject':u64decode(y['subject']), 'time':int(y['lastActionTime']), 'length':int(len(base64.b64decode(tobytes(y['message'])))), 'to':( lambda x:filter( lambda z:z['address']==x, addresses+[{'address':x,'label':x}]) )( tobytes(y['toAddress']))[0]['label'], 'from':( lambda x:filter( lambda z:z['address']==x, addresses+[{'address':x,'label':x}]) )( tobytes(y['fromAddress']))[0]['label'], 'status':y['status'] }, json.loads(api.getAllSentMessages())['sentMessages'] ); if len(sys.argv) >= 4: if sys.argv[3] == 'pending': sent=filter(lambda x:not x['status'] in ['msgsentnoackexpected','ackreceived','broadcastsent'],sent); sent.sort(cmp=(lambda x,y:int.__cmp__(x['time'],y['time']))); print_u ( map( lambda x:'\t'.join(map(tobytes, [ x['from'], x['to'], time.ctime(x['time']), x['length'], x['msgid'], x['status'], x['subject'] ]) ), sent) ) elif sys.argv[2] == 'identities': print_u ( map( lambda x:x['address']+'\t'+x['label'], map(lambda x:{ 'address':tobytes(x[u'address']), 'label':tobytes(x[u'label']) },json.loads(api.listAddresses())['addresses']) ) ) elif sys.argv[2] == 'message': address=get_addresses(); print_u ( (lambda x:[ 'From: '+tobytes(x['fromAddress']), 'To: '+tobytes(x['toAddress']), 'Subject: '+base64.b64decode(x['subject']), '', base64.b64decode(x['message']) ])((json.loads( api.getInboxMessageByID(base64.b16encode(base64.b64decode(sys.argv[3])).lower(),True))['inboxMessage'][0] or json.loads(api.getSentMessageByID(base64.b16encode(base64.b64decode(sys.argv[3])).lower(),True))['sentMessage'][0]))); elif sys.argv[2] == 'contacts': print_u ( map( lambda x:x['address']+'\t'+x['label'], get_addresses(categories=[api.listAddressBookEntries()]) ) ) elif sys.argv[1] == 'new': if sys.argv[2] == 'identity': api.createRandomAddress(base64.b64(encode.argv[3])); elif sys.argv[2] == 'message': api.sendMessage( sys.argv[4], # to sys.argv[3], # from base64.b64encode(sys.argv[5]), # subject base64.b64encode(sys.stdin.read()), 2, # encoding convert_time(sys.argv[6]) if len(sys.argv)>6 else 4*24*3600 # ttl ); elif sys.argv[2] == 'contact': api.addAddressBookEntry(sys.argv[4],base64.b64encode(argv[3])) elif sys.argv[2] == 'subscription': api.addSubscription(sys.argv[4],base64.b64encode(sys.argv[3])) elif sys.argv[2] == 'broadcast': api.sendBroadcast( sys.argv[3], # from base64.b64encode(sys.argv[4]), # subject base64.b64encode(sys.stdin.read()), 2, #encoding convert_time(sys.argv[5]) if len(sys.argv)>5 else 4*24*3600 # ttl ); elif sys.argv[2] == 'chan': if len(sys.argv)<=2: print api.createChan(base64.b64encode(sys.argv[3])) else: print api.joinChan(base64.b64encode(sys.argv[3]),sys.argv[4]) elif sys.argv[1] == 'delete': if sys.argv[2] == 'identity': api.deleteAddress(sys.argv[3]) elif sys.argv[2] == 'message': api.trashMessage(base64.b16encode(base64.b64decode(sys.argv[3])).lower()) elif sys.argv[2] == 'contact': api.deleteAddressBookEntry(sys.argv[3]) elif sys.argv[2] == 'subscription': api.deleteSubscription(sys.argv[3]) else: print_help()