/usr/bin/mandrill is in python-mandrill 1.0.51-1.
This file is owned by root:root, with mode 0o755.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 | #! /usr/bin/python
'''Mandrill
Usage:
mandrill setup
mandrill [-v] ping [--count=<cnt>]
mandrill [-v] send [--from=<addr>] [--to=<addr>] [--subject=<subj>] [--text-only]
mandrill [-v] search [--json] <query>
mandrill --help
Options:
-h --help Show this screen.
-v Turn on verbose mode - all traffic to the API will be logged to STDERR
-V --version Show version.
-c --count=<cnt> The number of times to ping Mandrill.
-f --from=<addr> The from address of the message to send.
-t --to=<addr> The recipient address of the message to send.
-s --subject=<subj> The subject line of the message to send.
--text-only The message will be sent as plain-text. If this option is not provided, HTML is presumed.
-j --json Print the result as a JSON string
'''
import mandrill, docopt, time, sys, os.path, socket, math, re, subprocess, tempfile
try:
import json as json
except:
import simplejson as json
email_re = re.compile(r'^[^\"\s@<>(),]+@[a-z0-9][a-z0-9\.\-_]*\.[a-z]+$', re.I)
def command_setup(args):
global m
apikey = raw_input('Your Mandrill API Key: ')
try:
m = mandrill.Mandrill(apikey)
m.users.ping()
except mandrill.Error, e:
print('Got an error trying to use that API key: %s' % e)
sys.exit(1)
try:
f = open('/etc/mandrill.key', 'w')
f.write(apikey)
f.close()
print('Saved Mandrill API Key to /etc/mandrill.key')
except:
f = open(os.path.expanduser('~/.mandrill.key'), 'w')
f.write(apikey)
f.close()
print('Saved Mandrill API Key to %s' % os.path.expanduser('~/.mandrill.key'))
def command_ping(args):
print('PING https://mandrillapp.com/api/1.0/users/ping2.json')
if args['--count'] is None:
args['--count'] = 4
else:
args['--count'] = int(args['--count'])
times = []
error_count = 0
for i in range(args['--count']):
start = time.time()
try:
m.users.ping2()
(remote_addr, remote_port) = m.last_request['remote_addr']
reverse_addr = socket.gethostbyaddr(remote_addr)[0]
times.append(m.last_request['time'] * 1000)
print('%d bytes from %s (%s): req=%s port=%s time=%.2fms' % (len(m.last_request['response_body']), reverse_addr, remote_addr, i + 1, remote_port, m.last_request['time'] * 1000))
except mandrill.Error, e:
error_count += 1
(remote_addr, remote_port) = m.last_request['remote_addr']
reverse_addr = socket.gethostbyaddr(remote_addr)[0]
times.append(m.last_request['time'] * 1000)
print('%d bytes from %s (%s): req=%s port=%s time=%.2fms ERROR: %s' % (len(m.last_request['response_body']), reverse_addr, remote_addr, i + 1, remote_port, m.last_request['time'] * 1000, e))
if i < args['--count'] - 1: time.sleep(1)
sq_sum = sum([t * t for t in times])
mean = sum(times) / len(times)
stdev = math.sqrt((sq_sum / len(times)) - (mean * mean))
print('\n--- Mandrill ping statistics ---')
print('%d calls transmitted, %d received, %d%% error rate, time %dms' % (args['--count'], args['--count'] - error_count, float(error_count) / args['--count'] * 100, sum(times)))
print('rtt min/avg/max/mdev = %.3f/%.3f/%.3f/%.3f ms' % (min(times), mean, max(times), stdev))
def command_send(args):
if args['--from'] is not None and not email_re.match(args['--from']):
args['--from'] = None
if args['--to'] is not None and not email_re.match(args['--to']):
args['--to'] = None
while args['--from'] is None:
from_email = raw_input('From: ').strip()
if email_re.match(from_email):
args['--from'] = from_email
else:
print('Invalid email address. Try again.')
while args['--to'] is None:
to_email = raw_input('To: ').strip()
if email_re.match(to_email):
args['--to'] = to_email
else:
print('Invalid email address. Try again.')
while args['--subject'] is None:
subject = raw_input('Subject: ').strip()
if subject != '':
args['--subject'] = subject
else:
print('Enter a subject line.')
if sys.stdin.isatty():
editor = os.environ.get('EDITOR', 'vim')
if args['--text-only']:
suffix = '.txt'
else:
suffix = '.html'
with tempfile.NamedTemporaryFile(suffix=suffix) as tmp:
if args['--text-only']:
tmp.write('REMOVE this and replace with your text content.')
else:
tmp.write('<p>REMOVE this and replace with your HTML content.</p>')
tmp.flush()
subprocess.check_call([editor, tmp.name])
tmp.seek(0)
content = tmp.read()
if 'REMOVE this and replace with your' in content:
print('Send canceled')
sys.exit(1)
else:
content = sys.stdin.read()
msg = {'from_email': args['--from'], 'to': [{'email': args['--to']}], 'subject': args['--subject']}
if args['--text-only']:
msg['text'] = content
else:
msg['html'] = content
m.messages.send(msg)
def command_search(args):
query = args['<query>']
results = m.messages.search(query)
if args['--json']:
json.dump(results, sys.stdout)
else:
print('Time\tStatus\tSender\tEmail\tSubject\tOpens\tClicks')
for result in results:
print('%s\t%s\t%s\t%s\t%s\t%s\t%s' % (time.strftime('%d/%b/%Y %H:%M:%S %Z', time.localtime(result['ts'])), result['state'], result['sender'], result['email'], result['subject'], result['opens'], result['clicks']))
if __name__ == '__main__':
arguments = docopt.docopt(__doc__, version='Mandrill 1.0')
if not arguments['setup']:
try:
m = mandrill.Mandrill(debug=arguments['-v'])
except mandrill.Error:
print('This looks like the first time you\'ve run Mandrill, so let\'s get you set up.')
command_setup(arguments)
commands = dict([(k[8:], getattr(sys.modules['__main__'], k)) for k in dir(sys.modules['__main__']) if k.startswith('command_')])
for command, func in commands.items():
if command in arguments and arguments[command]:
try:
func(arguments)
sys.exit(0)
except Exception, e:
print(e)
sys.exit(1)
|