summaryrefslogtreecommitdiffstats
path: root/mail2redmine.py
blob: 7a39e180f163f8e2e41e553da124c9e66925230c (plain)
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
# -*- encoding: utf-8 -*-

import os
import sys
import email
import tempfile
import uuid
import smtplib

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')


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(mail):
    try:
        mail = email.message_from_string(mail)
        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 été bien 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 Entrouvert
    """
        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'])
    except Exception, e:
        message = u"""Bonjour,

Malheureusement nous ne sommes pas en mesure de prendre en compte votre demande
pour une des raisons suivantes:

 - vous ne disposez pas de compte sur notre plateforme;
 - vous n'avez pas les droits d'accès au projet;

Veuillez vous assurer que vous remplissez les condition et re-essayez.

Cordialement,

L'équipe Entrouvert

%s"""
        send_mail(mail['From'], u'Rejet de votre demande', message % e)


if __name__ == '__main__':

    mail = 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(mail)
    create_ticket(mail)