Skip to content

Instantly share code, notes, and snippets.

@tcalmant
Created February 1, 2015 10:33
Show Gist options
  • Save tcalmant/02953bdd4c8f4ae8f91b to your computer and use it in GitHub Desktop.
Save tcalmant/02953bdd4c8f4ae8f91b to your computer and use it in GitHub Desktop.
A small script to send mails with attachements from command line.
#!/usr/bin/python3
# -- Content-Encoding: UTF-8 --
"""
Sends e-mails with attachments
:author: Thomas Calmant
:copyright: Copyright 2014, isandlaTech
:license: Apache License 2.0
:version: 0.0.1
:status: Alpha
..
Copyright 2014 isandlaTech
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
# Module version
__version_info__ = (0, 0, 1)
__version__ = ".".join(str(x) for x in __version_info__)
# Documentation strings format
__docformat__ = "restructuredtext en"
# ------------------------------------------------------------------------------
from configparser import ConfigParser
from email import encoders
from email.header import Header
from email.mime.base import MIMEBase
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.utils import COMMASPACE
import argparse
import mimetypes
import os
import smtplib
def send_mail(server, port, send_from, send_to, subject, text, files=None,
starttls=True, user=None, password=None):
"""
Sends an email
:param server: SMTP server
:param port: SMTP server port
:param send_from: Mail sender
:param send_to: Recipients
:param subject: Mail subject
:param text: Content of the mail
:param files: List of files to send
:param starttls: Use TLS
:param user: SMTP user name
:param password: SMTP user password
"""
assert isinstance(send_to, (tuple, list, set))
# Prepare the main message
outer = MIMEMultipart()
outer['Subject'] = Header(subject, 'utf-8')
outer['To'] = COMMASPACE.join(send_to)
outer['From'] = send_from
outer.attach(MIMEText(text, 'plain', 'utf-8'))
for filepath in files or []:
with open(filepath, "rb") as fp:
# Guess type of file
ctype, encoding = mimetypes.guess_type(filepath)
if ctype is None:
ctype = 'application/octet-stream'
maintype, subtype = ctype.split('/', 1)
# Prepare the attachment
attachement = MIMEBase(maintype, subtype)
attachement.set_payload(fp.read())
# Encore payload
encoders.encode_base64(attachement)
attachement.add_header("Content-Disposition", "attachment",
filename=os.path.basename(filepath))
# Attach it
outer.attach(attachement)
# Connect to the SMTP server
smtp = smtplib.SMTP(server, port)
smtp.ehlo()
# Use TLS
if starttls:
smtp.starttls()
smtp.ehlo()
# Login
if user:
smtp.login(user, password)
# Send mail
print("Sending mail to:", ", ".join(send_to))
smtp.sendmail(send_from, send_to, outer.as_string())
smtp.close()
def main(send_to, subject, text, files=None, config_file=None):
"""
Reads a configuration file and sends mails
"""
# Compute configuration file path
home = os.path.expanduser("~")
home_config_file = os.path.join(home, ".mail_sender")
# Parse it
parser = ConfigParser()
try:
for filepath in (home_config_file, config_file):
if filepath:
print("Reading configuration file:", filepath)
parser.read(filepath)
server = parser['server']
except OSError as ex:
print("Error reading file:", ex)
return
except KeyError:
print("File has no 'server' section")
return
# Add configured elements
try:
mail = parser['mail']
except KeyError:
# No mail section
pass
else:
if not subject:
subject = mail.get('subject', "")
if not send_to:
send_to = [recipient.strip() for recipient in
mail.get('recipients', "").split(";")]
# Send mail
send_mail(server['host'], int(server['port'] or 25),
server['from'], send_to, subject, text, files,
server.getboolean('starttls', fallback=True),
server.get('user'), server.get('password'))
def read_args(argv=None):
"""
Read script arguments
"""
if argv is None:
import sys
argv = sys.argv[1:]
# Parse arguments
parser = argparse.ArgumentParser(description="Mail sender script")
parser.add_argument("--to", dest="send_to", nargs="+",
help="Mail recipients")
parser.add_argument("--subject", dest="subject", help="Mail subject")
parser.add_argument("--text", dest="text", help="Mail content",
default="<no content>")
parser.add_argument("--files", dest="files", nargs="+",
help="Attached files")
parser.add_argument("-c", "--configuration", dest="config_file",
help="Configuration file")
return parser.parse_args(argv)
if __name__ == '__main__':
# Read arguments
args = read_args()
main(args.send_to, args.subject, args.text, args.files,
args.config_file)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment