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

feat: send also HTML formatted emails with alternative text only #5

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions mail.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[mail]
server = send.example.com
port = 587
send_from = [email protected]
password = verynicepassword
send_to = [email protected]
subject = Message from {caller}
title = Neue Sprachnachricht
title_html = Anrufbeantworter
epilog_html = Diese E-Mail wurde automatisch verfasst.
content = Der Anrufer: {name} ({caller}) hat für Sie auf dem Anrufbeantworter eine Nachricht hinterlassen. Sie finden die Sprachnachricht im Anhang dieser E-Mail.
label_from = Anruf von
label_for = für die Rufnummer
label_date = Datum
label_time = Uhrzeit
label_length = Aufnahmelänge
96 changes: 96 additions & 0 deletions mail.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
<!DOCTYPE html>
<html>
<head>
<title>{title}</title>
<meta http-equiv="content-type" content="text/html;charset=utf-8"/>
</head>
<body style="color: #000000; background-color: #f0eee6;">
<table width="100%" align="center" style="border:solid 2px #eeeeee; border-collapse: collapse;">
<tr>
<td>
<table style="border-collapse: collapse;">
<tr>
<td>
<table style="color: #ffffff; background-color: #006EC0;">
<tr>
<td width="1000" align="center" style="font-size: 18pt; font-family: Arial, Helvetica, sans-serif; padding: 10px;">
{title_html}
</td>
</tr>
</table>
</td>
</tr>
<tr>
<td style="padding: 10px 30px; background-color: #FFFFFF;">
<table style="border-collapse: collapse;">
<tr>
<td style="width: 940px; font-size: 13pt; font-family: Arial, Helvetica, sans-serif; text-align: left;">
{content}
</td>
</tr>
</table>
</td>
</tr>
<tr>
<td style="padding: 10px 30px; background-color: #FFFFFF;">
<table style="background-color: #ffffff; border-collapse: collapse;">
<tr>
<td style="width: 140px; font-size: 11pt; font-family: Arial, Helvetica, sans-serif; text-align: left; height: 20px;">
{label_from}:
</td>
<td style="width: 800px; font-size: 11pt; font-family: Arial, Helvetica, sans-serif; text-align: left; height: 20px; vertical-align: bottom;">
{name} ({caller})
</td>
</tr>
<tr>
<td style="font-size: 11pt; font-family: Arial, Helvetica, sans-serif; text-align: left;height: 20px;">
{label_for}:
</td>
<td style="font-size: 11pt; font-family: Arial, Helvetica, sans-serif; text-align: left; height: 20px; vertical-align: bottom;">
{number}
</td>
</tr>
<tr>
<td style="font-size: 11pt; font-family: Arial, Helvetica, sans-serif; text-align: left;height: 20px;">
{label_date}:
</td>
<td style="font-size: 11pt; font-family: Arial, Helvetica, sans-serif; text-align: left;height: 20px;">
{date}
</td>
</tr>
<tr>
<td style="font-size: 11pt; font-family: Arial, Helvetica, sans-serif; text-align: left;height: 20px;">
{label_time}:
</td>
<td style="font-size: 11pt; font-family: Arial, Helvetica, sans-serif; text-align: left;height: 20px;">
{time}
</td>
</tr>
<tr>
<td style="font-size: 11pt; font-family: Arial, Helvetica, sans-serif; text-align: left;height: 20px;">
{label_length}:
</td>
<td style="font-size: 11pt; font-family: Arial, Helvetica, sans-serif; text-align: left;height: 20px;">
{length}
</td>
</tr>
</table>
</td>
</tr>
<tr>
<td>
<table style="color: #FFFFFF; background-color: #006EC0;">
<tr>
<td style="width: 1000px; font-size: 10pt; text-align: center; padding: 10px;">
{epilog_html}
</td>
</tr>
</table>
</td>
</tr>
</table>
</td>
</tr>
</table>
</body>
</html>
147 changes: 105 additions & 42 deletions mail.py
Original file line number Diff line number Diff line change
@@ -1,59 +1,122 @@
#!/usr/bin/env python
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import sys
import re
import argparse
import configparser
import datetime
import html
import math
import smtplib
from os.path import basename
from email.mime.application import MIMEApplication
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.utils import COMMASPACE, formatdate
from email.utils import formatdate
from email import charset

from mutagen.mp3 import MP3

# config
server = "send.example.com"
port = 587
send_from = "[email protected]"
password = "verynicepassword"
send_to = "[email protected]"
subject = "Message from your answering machine"

def send_mail(args):
config = configparser.ConfigParser()
config.read(args.config)
config = config['mail']

def send_mail(text, f):
subject = config['subject']
send_from = config['send_from']
send_to = config['send_to']

msg = MIMEMultipart()
dt = datetime.datetime.now()
try:
audio = MP3(args.filename)
delta = datetime.timedelta(math.ceil(audio.info.length))
length = str(delta)
dt -= delta
except Exception as exc:
length = str(exc)

contents = {
'caller': args.caller,
'name': args.name,
'number': args.number,
'date': str(dt.date()),
'time': dt.time().strftime('%H:%S'),
'length': length,
'subject': subject,
'title': config['title'],
'title_html': config['title_html'],
'epilog_html': config['epilog_html'],
'label_from': config['label_from'],
'label_for': config['label_for'],
'label_date': config['label_date'],
'label_time': config['label_time'],
'label_length': config['label_length'],
}
contents['content'] = config['content'].format(**contents)

msg = MIMEMultipart(boundary="==Voice_Box==multipart/mixed==0==")
msg['From'] = send_from
msg['To'] = send_to
msg['Date'] = formatdate(localtime=True)
msg['Subject'] = subject
msg['Subject'] = subject.format(**contents)

cs = charset.Charset('utf-8')
cs.body_encoding = charset.QP

body = config.get('body', '''{title}:

msg.attach(MIMEText(text))
{content}

{label_from}: {name} ({caller})
{label_for}: {number}
{label_date}: {date}
{label_time}: {time}
{label_length}: {length}
''')
text = MIMEMultipart('alternative', boundary="==Voice_Box==multipart/alternative==1==")
text.attach(MIMEText(body.format(**contents), 'plain', cs))
try:
with open(f, "rb") as fil:
part = MIMEApplication(
fil.read(),
Name=basename(f)
)
part['Content-Disposition'] = 'attachment; filename="%s"' % basename(f)
msg.attach(part)
except IOError as e:
print "Can not read file \""+f+"\": I/O error({0}): {1}".format(e.errno, e.strerror)
except:
print "Can not read file", sys.exc_info()[0]
raise

s = smtplib.SMTP(server, port)
# s.debuglevel = 1
s.ehlo()
s.starttls()
# s.ehlo
s.login(send_from, password)
s.sendmail(send_from, send_to, msg.as_string())
s.quit()

# smtp.close()

if len(sys.argv) == 3:
send_mail(sys.argv[1],sys.argv[2])
else:
print"provide two arguments: \"text\" \"file\""
with open('mail.html') as fd:
body_html = re.sub(r'^\s*', '', fd.read())
text.attach(MIMEText(body_html.format(**{key: html.escape(value) for key, value in contents.items()}), 'html', cs))
except IOError:
pass
msg.attach(text)

with open(args.filename, "rb") as fd:
part = MIMEApplication(
fd.read(),
Name=basename(args.filename)
)
filename = basename(args.filename).replace('"', '').replace('\\', '')
part['Content-Disposition'] = 'attachment; filename="%s"' % (filename,)
msg.attach(part)

with smtplib.SMTP(config['server'], int(config['port'])) as s:
s.ehlo()
s.starttls()
s.login(send_from, config['password'])
s.sendmail(send_from, send_to, msg.as_string())
print('OK: email sent')

# FIXME: handle such errors. What to do then?
# Traceback (most recent call last):
# File "./mail.py", line 102, in <module>
# send_mail(args)
# File "./mail.py", line 91, in send_mail
# s.sendmail(send_from, send_to, msg.as_string())
# File "/usr/lib/python3.7/smtplib.py", line 888, in sendmail
# raise SMTPDataError(code, resp)
# smtplib.SMTPDataError: (554, b'5.7.0 Your message could not be sent. The limit on the number of allowed outgoing messages was exceeded. Try again later.')


if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('--config', default='mail.cfg')
parser.add_argument('--name', default='Name unknown')
parser.add_argument('number')
parser.add_argument('caller')
parser.add_argument('filename')
args = parser.parse_args()
send_mail(args)
10 changes: 5 additions & 5 deletions mail.sh
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
#!/bin/bash
#!/bin/sh
echo "compress-then-send script"
text=$1
filename=$2
number="$1"
callerid="$2"
filename="$3"
lame "$filename"

filename="${filename%.*}"

./mail.py "Call by $text recorded. Here is the file" "$filename.mp3"

./mail.py "$number" "$callerid" "$filename.mp3"
Loading