Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Various fixes and improvements #5

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
2 changes: 2 additions & 0 deletions .gitignore
@@ -0,0 +1,2 @@
postman.egg-info/
*.pyc
146 changes: 78 additions & 68 deletions postman/__main__.py
@@ -1,3 +1,5 @@
from __future__ import print_function

import argparse
import sys

Expand All @@ -6,119 +8,127 @@
from postman import __version__


def out(msg, args):
if args.verbose:
sys.stdout.write("%s\n" % msg)
sys.stdout.flush()


def cmd_send(args):
ses = boto.connect_ses()
out("Sending mail to: %s" % ", ".join(args.destinations), args)
msg = sys.stdin.read()
r = ses.send_raw_email(msg, args.f, args.destinations)
if r.get("SendRawEmailResponse", {}).get("SendRawEmailResult", {}).get("MessageId"):
out("OK", args)
# Verbosity lists all recipients instead of first
if args.verbose:
dests = ' '.join('post_to={0}'.format(d) for d in args.destinations)
else:
out("ERROR: %s" % r, args)
dests = 'post_to={0}'.format(args.destinations[0])
details = 'post_from={0} {1}'.format(args.f, dests)
try:
result = ses.send_raw_email(msg, args.f, args.destinations)
rbody = result.get("SendRawEmailResponse", {})
msgid = rbody.get("SendRawEmailResult", {}).get("MessageId")
reqid = rbody.get("ResponseMetadata", {}).get("RequestId")
print("post_status=OK msgid={0} reqid={1} {2}".format(
msgid, reqid, details))
except boto.exception.BotoServerError as err:
print('post_status=ERROR http_status={0} errmsg="{1}" errcode={2}'
' reqid={3} {4}'.format(err.status,
err.error_message,
err.error_code,
err.request_id,
details))
sys.exit(1)


def cmd_verify(args):
ses = boto.connect_ses()
for email in args.email:
ses.verify_email_address(email)
out("Verification for %s sent." % email, args)
print("Verification for {0} sent.".format(email))


def cmd_list_verified(args):
def cmd_list_verified(_args):
ses = boto.connect_ses()
args.verbose = True

addresses = ses.list_verified_email_addresses()
addresses = addresses["ListVerifiedEmailAddressesResponse"]
addresses = addresses["ListVerifiedEmailAddressesResult"]
addresses = addresses["VerifiedEmailAddresses"]

if not addresses:
out("No addresses are verified on this account.", args)
print("No addresses are verified on this account.")
return

for address in addresses:
out(address, args)
for address in sorted(addresses):
print(address)


def cmd_show_quota(args):
def cmd_show_quota(_args):
ses = boto.connect_ses()
args.verbose= True

data = ses.get_send_quota()["GetSendQuotaResponse"]["GetSendQuotaResult"]
out("Max 24 Hour Send: %s" % data["Max24HourSend"], args)
out("Sent Last 24 Hours: %s" % data["SentLast24Hours"], args)
out("Max Send Rate: %s" % data["MaxSendRate"], args)
fmt = "{0:<15} {1:<15} {2:<14}"
print(fmt.format("SentLast24Hours", "Max24HourSend", "MaxSendRate"))
fmt = "{0:<15.0f} {1:<15.0f} {2:<14.0f}"
print(fmt.format(float(data["SentLast24Hours"]),
float(data["Max24HourSend"]),
float(data["MaxSendRate"])))


def cmd_show_stats(args):
def cmd_show_stats(_args):
ses = boto.connect_ses()
args.verbose = True

data = ses.get_send_statistics()
data = data["GetSendStatisticsResponse"]["GetSendStatisticsResult"]
for datum in data["SendDataPoints"]:
out("Complaints: %s" % datum["Complaints"], args)
out("Timestamp: %s" % datum["Timestamp"], args)
out("DeliveryAttempts: %s" % datum["DeliveryAttempts"], args)
out("Bounces: %s" % datum["Bounces"], args)
out("Rejects: %s" % datum["Rejects"], args)
out("", args)
fmt = "{0:<20} {1:>10} {2:>8} {3:>7} {4:>7}"
print(fmt.format('Timestamp', 'DeliveryAttempts',
'Rejects', 'Bounces', 'Complaints'))
for datum in sorted(data["SendDataPoints"],
key=lambda x: x.get('Timestamp')):
print(fmt.format(
datum["Timestamp"],
datum["DeliveryAttempts"],
datum["Rejects"],
datum["Bounces"],
datum["Complaints"],
))


def cmd_delete_verified(args):
ses = boto.connect_ses()
for email in args.email:
ses.delete_verified_email_address(email_address=email)
out("Deleted %s" % email, args)
print("Deleted {0}".format(email))


def main():
parser = argparse.ArgumentParser(prog="postman", description="send an email via Amazon SES")
parser.add_argument("--version", action="version", version="%%(prog)s %s" % __version__)
parser.add_argument("--verbose", action="store_true")

command_parsers = parser.add_subparsers(dest="command")

# cmd: send
parser_send = command_parsers.add_parser("send")
parser = argparse.ArgumentParser(
prog="postman", description="Send an email via Amazon SES")
parser.add_argument("-V", "--version", action="version",
version="postman " + __version__)
parser.add_argument("-v", "--verbose", action="store_true",
help="Extra logging information.")

commands = parser.add_subparsers(dest="command")

parser_send = commands.add_parser("send")
parser_send.add_argument("-f",
help="the address to send the message from, must be validated")
parser_send.add_argument("destinations", metavar="TO", type=str, nargs="+",
parser_send.add_argument("destinations", metavar="TO", nargs="+",
help="a list of email addresses to deliver message to")

# cmd: verify
parser_send = command_parsers.add_parser("verify")
parser_send.add_argument("email", nargs="+",

parser_verify = commands.add_parser("verify")
parser_verify.add_argument("email", nargs="+",
help="an email address to verify for sending from")

# cmd: list_verified
command_parsers.add_parser("list_verified")

# cmd: show_quota
command_parsers.add_parser("show_quota")

# cmd: show_stats
command_parsers.add_parser("show_stats")

# cmd: delete_verified
parser_delete = command_parsers.add_parser("delete_verified")

commands.add_parser("list_verified")
commands.add_parser("show_quota")
commands.add_parser("show_stats")

parser_delete = commands.add_parser("delete_verified")
parser_delete.add_argument("email", nargs="+",
help="verified email addresses that will be deleted from verification list")

args = parser.parse_args()

{
help="verified email addresses to deleted from verification list")

cmdmap = {
"send": cmd_send,
"verify": cmd_verify,
"list_verified": cmd_list_verified,
"show_quota": cmd_show_quota,
"show_stats": cmd_show_stats,
"delete_verified": cmd_delete_verified
}[args.command](args)
}
args = parser.parse_args()
cmdmap[args.command](args)


if __name__ == "__main__":
main()
10 changes: 6 additions & 4 deletions setup.py
@@ -1,4 +1,5 @@
import os
import sys
from setuptools import setup, find_packages

from postman import __version__
Expand All @@ -7,6 +8,10 @@
def read(*path):
return open(os.path.join(os.path.abspath(os.path.dirname(__file__)), *path)).read()

pyversion = sys.version_info[:2]
install_requires = ["boto>=2.0"]
if pyversion < (2,7) or (3,0) <= pyversion <= (3,1):
install_requires.append('argparse')

setup(
name = "postman",
Expand All @@ -22,8 +27,5 @@ def read(*path):
"postman = postman.__main__:main",
],
},
install_requires = [
"argparse==1.2.1",
"boto==2.0"
]
install_requires = install_requires,
)