Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env python3
- # Distributed under the MIT software license. See
- # http://delicatebits.mit-license.org
- # (c) by delicatebits, the_austria
- # Bugs, Feedback etc. BM-GuRN32ZC5TBmamUMAA9R7Lja1NJWDkRb
- # version 1.0.1
- import sys
- from argparse import ArgumentParser
- import configparser
- import ntpath
- import datetime
- import xmlrpc.client as xmlrpclib
- import json
- import imghdr
- from base64 import b64encode
- # Q: What do I put here?
- # A: The values for the API https://bitmessage.org/wiki/API_Reference or your Bitmessage path to lookup these values in key.dat
- bitmsgpath = ''
- api_user = 'felix'
- api_pass = 'felix'
- api_host = 'localhost'
- api_port = '8442'
- # Set the default address where messages will send to, otherwise the argument -t has to be specified
- # e.g. BM-BbbuVnYuaSY6yjyhfQm5KVrJLqjiyetB (ImageBoard)
- defaultRecipient = ''
- def getDateTimeString():
- return '%s UTC' % (datetime.datetime.utcnow().strftime('%A, %B %d, %H:%M %Y'))
- def encode(imgpath):
- with open(imgpath, "rb") as f:
- data = f.read()
- return b64encode(data).decode()
- class BitmessageApiClient():
- def __init__(self):
- if api_user=='' or api_pass=='' or api_host=='' or not api_port:
- if not self.getCredentialsFromKeysFile():
- print ('Walrus is unable to send messages without access to PyBitmessage\'s API. Exiting.')
- print ('For help read README.md or https://github.com/delicatebits/walrus/blob/master/README.md')
- sys.exit(0)
- self.api_addr = 'http://%s:%s@%s:%s/' % (api_user,api_pass,api_host,api_port)
- self.ready = False
- self.api = xmlrpclib.ServerProxy(self.api_addr)
- self.identity = False
- self.addresses = None
- jsn = self.api.listAddresses()
- try:
- self.addresses = json.loads(jsn)
- except:
- print ('An error occurred when connecting!',jsn)
- return
- if len(self.addresses['addresses']) == 0:
- print ('You must have at least one valid Identity in PyBitmessage')
- #userinput = input('Would you like to create a Random Identity now? [y/N]: ').lower()
- #if 'yes' not in userinput and 'y' not in userinput:
- # return
- #self.createRandomIdentity();
- else:
- self.addresses = self.addresses['addresses']
- self.ready = True
- def createRandomIdentity(self):
- """not yet ready"""
- print ('Warning: Make sure you aren\'t currently creating an Identity in the GUI')
- ripe18 = False
- userinput = input('Spend extra time for a shorter address? [y/N]: ').lower()
- if 'y' in userinput: ripe18 = True
- label = 'Generated by Walrus'
- userinput = input('Enter a label. Default=%s: '%label)
- if len(userinput) > 0: label = userinput
- self.identity = self.api.createRandomAddress(b64encode(label),ripe18)
- print (self.identity)
- def isReady(self):
- return self.ready
- def lookupBitmessageDataFolder(self):
- from os import path, environ
- if sys.platform == 'darwin':
- if "HOME" in environ:
- bitmessagedata = path.join(os.environ["HOME"], "Library/Application support/PyBitmessage") + '/'
- else:
- print ('Could not find home folder, please report this message and your OS X version to the BitMessage Github.')
- sys.exit()
- elif 'win32' in sys.platform or 'win64' in sys.platform:
- bitmessagedata = path.join(environ['APPDATA'], "PyBitmessage") + '\\'
- else:
- bitmessagedata = path.expanduser(path.join("~", ".PyBitmessage/"))
- return bitmessagedata
- def getCredentialsFromKeysFile(self):
- if bitmsgpath != '':
- bitmessagedata = bitmsgpath
- else:
- bitmessagedata = self.lookupBitmessageDataFolder()
- config = configparser.SafeConfigParser()
- config.read(bitmessagedata + 'keys.dat')
- try:
- global api_user,api_pass,api_host,api_port
- api_user = config.get('bitmessagesettings', 'apiusername')
- api_pass = config.get('bitmessagesettings', 'apipassword')
- api_host = config.get('bitmessagesettings', 'apiinterface')
- api_port = config.get('bitmessagesettings', 'apiport')
- except:
- print ('Walrus was unable to read %s' % (bitmessagedata + 'keys.dat') )
- return False
- return True
- def getIdentityAddress(self):
- return self.identity['address']
- def identityIsSet(self):
- if self.identity != False:
- return True
- return False
- def getIdentity(self):
- if not self.ready: return False
- idcnt = 0;
- for x in self.addresses:
- if x['enabled'] != True:
- idcnt += 1
- continue;
- print ("[ID: %s]\tAddress: %s\tLabel: %s" % (idcnt,x['address'],x['label']))
- idcnt += 1
- userinput = input('Choose an ID: ')
- try:
- i = int(userinput)
- except ValueError:
- print ('%s is an invalid choice.' % userinput)
- return False
- if len(self.addresses)-1 < i:
- print ('%s is an invalid choice.' % i)
- return False
- self.identity = self.addresses[int(userinput)]
- print ('Message will be sent as %s, %s' % (self.identity['label'],self.identity['address']))
- return True
- def checkFromIdentity(self,userinput):
- if not self.ready: return False
- for x in self.addresses:
- if x['address'] == userinput or x['label'] == userinput:
- if x['enabled'] != True:
- print ('(%s) %s is Disabled!' % (x['label'],x['address']))
- else:
- self.identity = x
- print ('Message will be sent as %s, %s' % (self.identity['label'],self.identity['address']))
- return True
- return False
- def sendMessage(self,toAddress,subject,message):
- if not self.ready or not self.identity:
- print ('Unable to send message.')
- return False
- self.api.sendMessage(toAddress, self.identity['address'], subject, message)
- print ('Message sent to %s!' % toAddress)
- def sendBroadcast(self,subject,message):
- if not self.ready or not self.identity:
- print ('Unable to send message.')
- return False
- self.api.sendBroadcast(self.identity['address'], subject, message)
- print ('Message broadcasted!')
- def main():
- global defaultRecipient
- parser = ArgumentParser(usage="usage: %(prog)s filename [options]",
- version="%(prog)s 0.1")
- parser.add_argument("filename")
- parser.add_argument("-s", "--send", action="store_true", dest="flag_send",
- default=False, help="Send output to Address")
- parser.add_argument("-b", "--broadcast", action="store_true", dest="flag_broadcast", default=False, help="Broadcast output")
- parser.add_argument("-f", "--from", action="store", dest="flag_from", metavar='FROM',
- default=False, help="Address/Label to send from")
- parser.add_argument("-t", "--to", action="store", dest="flag_to", metavar='TO',
- default=defaultRecipient, help="Address/Label to send to. Default is %%default")
- parser.add_argument("-u", "--subject", action="store", dest="flag_subject", metavar='SUBJECT',
- default=False, help="Subject of the message. Default is image name.")
- args = vars(parser.parse_args())
- if args['filename']:
- file_path = args['filename']
- file_name = ntpath.basename(file_path)
- else:
- print ('Error: Path to image must be provided')
- return
- try:
- with open(file_path): pass
- except IOError:
- print ('%s was not found on your filesystem!' % file_path)
- return
- filetype = imghdr.what(file_path)
- if filetype is None:
- print ('%s Does not appear to be an image.' % file_path)
- return;
- else:
- print ('%s is of type: %s' % (file_name, filetype))
- encoded = encode(file_path)
- api = None
- if not args['flag_send'] and not args['flag_broadcast']:
- print ('Base64 Encoded Image:\n%s' % encoded)
- return
- apiClient = BitmessageApiClient()
- if not apiClient.isReady():
- print ('There was an error with the API. Please check your credentials, and make sure you have at least 1 Identity')
- return
- if args['flag_from'] != False:
- if not apiClient.checkFromIdentity(args['flag_from']):
- print ('Invalid From Address/Label provided.')
- if not apiClient.identityIsSet():
- if not apiClient.getIdentity():
- return
- if args['flag_to'] != defaultRecipient:
- print ('To Addresses/Labels are not validated, yet')
- userinput = input('Are you sure you want to send a message to %s [y/N]: ' % args['flag_to']).lower()
- if 'yes' not in userinput and 'y' not in userinput:
- print ('Exiting')
- exit(0)
- else:
- defaultRecipient = args['flag_to']
- print ('Attempting to generate and send message')
- if not apiClient.isReady() or not apiClient.identityIsSet():
- print ('Something went wrong with the API, exiting.')
- return
- message = """<html>
- <!-- To view the image, right click on the message to view as HTML -->
- <!-- This message was sent via a script using the API. -->
- <!-- https://github.com/Bitmessage/PyBitmessage/ -->
- <!-- This script can be found at: http://pastebin.com/58txrbsK (python 2) or http://pastebin.com/VS7EPJ7m (python 3)-->
- <style type="text/css">
- #header { font-size: 12px; color: #555; }
- #image { max-width: 999px; max-height: 300px; }
- </style>
- <center>
- <div id="header">
- <p>Sent on %s</p>
- </div>
- <div id="image">
- <img src='data:image/%s;base64, %s' />
- </div>
- </center>
- </html>""" % (getDateTimeString(), filetype, encoded)
- if args['flag_subject'] != False:
- subject = args['flag_subject']
- else:
- subject = file_name
- if args['flag_send']:
- apiClient.sendMessage(defaultRecipient,
- b64encode(subject.encode()).decode(),
- b64encode(message.encode()).decode() )
- if args['flag_broadcast']:
- apiClient.sendBroadcast(
- b64encode(subject.encode()).decode(),
- b64encode(message.encode()).decode() )
- print ('Operations Complete! exiting.')
- if __name__ == '__main__':
- main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement