mail2redmine/mail2redmine.py

116 lines
3.8 KiB
Python
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# -*- encoding: utf-8 -*-
import os
import sys
import email
import tempfile
import uuid
import smtplib
import subprocess
from redmine import Redmine
REDMINE_URL = os.environ.get('REDMINE_URL', 'https://dev.entrouvert.org')
REDMINE_KEY = os.environ.get('REDMINE_KEY')
TRACKER_ID = os.environ.get('REDMINE_TRACKER', '3')
PROJECT_ID = os.environ.get('PROJECT')
FALLBACK_EMAIL = os.environ.get('FALLBACK_EMAIL', 'support@entrouvert.com')
class UnknownUser(Exception):
pass
def parse_header(header_text):
default_charset = 'ascii'
try:
headers = email.Header.decode_header(header_text)
except email.Errors.HeaderParseError:
return header_text.encode(default_charset, 'replace').decode(default_charset)
else:
for i, (text, charset) in enumerate(headers):
headers[i] = unicode(text, charset or default_charset, errors='replace')
return u' '.join(headers)
def parse_attachment(data):
disposition = data.get('Content-Disposition')
if disposition:
dispositions = disposition.strip().split(";")
if dispositions[0] == "attachment":
file_data = data.get_payload(decode=True)
with tempfile.NamedTemporaryFile(delete=False) as attachment:
attachment.write(file_data)
attachment.flush()
temp = tempfile.NamedTemporaryFile(delete=False)
attachment = {'path': attachment.name,
'content_type': data.get_content_type(),
'filename': parse_header(data.get_filename())}
return attachment
return None
def send_mail(to, subject, message):
s = smtplib.SMTP('localhost')
from_mail = 'redmine@entrouvert.com'
msg = email.mime.text.MIMEText(message, 'plain', 'utf-8')
msg['From'] = from_mail
msg['To'] = to
msg['Subject'] = subject
s.sendmail(from_email, to, msg.as_string())
s.quit()
def create_ticket(email):
mail = email.message_from_string(email)
r = Redmine(REDMINE_URL, key=REDMINE_KEY)
from_name, from_email = email.utils.parseaddr(mail['From'])
users = r.user.filter(name=from_email)
if not users:
raise UnknownUser
r = Redmine(REDMINE_URL, key=REDMINE_KEY, impersonate=users[0].login)
attachments = []
for data in mail.walk():
attachment = parse_attachment(data)
if attachment:
attachments.append(attachment)
elif data.get_content_type() == "text/plain":
body = data.get_payload(decode=True)
body = unicode(body, data.get_content_charset('utf-8')).encode('utf-8')
issue = r.issue.create(project_id=PROJECT_ID,
subject=parse_header(mail['Subject']),
tracker_id=TRACKER_ID,
description=body,
uploads=attachments)
message = u"""Bonjour,
Votre demande a bien été prise en compte et enregistrée dans notre système sous
le numéro %s.
Vous pouvez suivre son évolution à l'adresse : %s .
Cordialement,
L'équipe Entr'ouvert"""
message = message % (issue.id, issue.url)
send_mail(mail['From'], u'Votre demande a été bien prise en compte', message)
# cleanup temporary attachment files
for attachment in attachments:
if os.path.exists(attachment['path']):
os.unlink(attachment['path'])
if __name__ == '__main__':
email = sys.stdin.read()
mail_dumps_dir = '/var/tmp'
if not os.path.exists(mail_dumps_dir):
os.mkdir(mail_dumps_dir)
filename = os.path.join(mail_dumps_dir, '%s.mail' % uuid.uuid4())
with open(filename, 'w') as mail_dump:
mail_dump.write(email)
try:
create_ticket(email)
except:
exim = subprocess.Popen(['/usr/sbin/exim', FALLBACK_EMAIL], stdin=file(filename))