Launchpad automatic translations update.
[odoo/odoo.git] / bin / tools / import_email.py
1 # -*- coding: utf-8 -*-
2 ##############################################################################
3 #    
4 #    OpenERP, Open Source Management Solution
5 #    Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
6 #
7 #    This program is free software: you can redistribute it and/or modify
8 #    it under the terms of the GNU Affero General Public License as
9 #    published by the Free Software Foundation, either version 3 of the
10 #    License, or (at your option) any later version.
11 #
12 #    This program is distributed in the hope that it will be useful,
13 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
14 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 #    GNU Affero General Public License for more details.
16 #
17 #    You should have received a copy of the GNU Affero General Public License
18 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.     
19 #
20 ##############################################################################
21
22 import os, sys
23 import re
24 import smtplib
25 import email, mimetypes
26 from email.Header import decode_header
27 from email.MIMEText import MIMEText
28 import xmlrpclib
29
30 warn_msg = """
31 Bonjour,
32
33 Le message avec le sujet "%s" n'a pu être archivé dans l'ERP.
34
35 """.decode('utf-8')
36
37 class EmailParser(object):
38
39     def __init__(self, headers, dispatcher):
40         self.headers = headers
41         self.dispatcher = dispatcher
42     
43     def parse(self, msg):
44         dispatcher((self.headers, msg))
45
46 class CommandDispatcher(object):
47
48     def __init__(self, receiver):
49         self.receiver = receiver
50     
51     def __call__(self, request):
52         return self.receiver(request)
53
54 class RPCProxy(object):
55
56     def __init__(self, uid, passwd, host='localhost', port=8069, path='object'):
57         self.rpc = xmlrpclib.ServerProxy('http://%s:%s/%s' % (host, port, path))
58         self.user_id = uid
59         self.passwd = passwd
60     
61     def __call__(self, request):
62         return self.rpc.execute(self.user_id, self.passwd, *request)
63
64 class ReceiverEmail2Event(object):
65
66     email_re = re.compile(r"""
67         ([a-zA-Z][\w\.-]*[a-zA-Z0-9]     # username part
68         @                                # mandatory @ sign
69         [a-zA-Z0-9][\w\.-]*              # domain must start with a letter
70          \.
71          [a-z]{2,3}                      # TLD
72         )
73         """, re.VERBOSE)
74
75     project_re = re.compile(r"^ *\[?(\d{4}\.?\d{0,3})\]?", re.UNICODE)
76
77
78     def __init__(self, rpc):
79         self.rpc = rpc
80     
81     def get_addresses(self, headers, msg):
82         hcontent = ''
83         for header in [h for h in headers if msg.has_key(h)]:
84             hcontent += msg[header]
85         return self.email_re.findall(hcontent)
86
87     def get_partners(self, headers, msg):
88         alladdresses = self.get_addresses(headers, msg)
89         address_ids = self.rpc(('res.partner.address', 'search', [('email', 'in', alladdresses)]))
90         addresses = self.rpc(('res.partner.address', 'read', address_ids))
91         return [x['partner_id'][0] for x in addresses]
92
93     def __call__(self, request):
94         headers, msg = request
95         partners = self.get_partners(headers, msg)
96         subject = u''
97         for string, charset in decode_header(msg['Subject']):
98             if charset:
99                 subject += string.decode(charset)
100             else:
101                 subject += unicode(string)
102         if partners:
103             self.save_mail(msg, subject, partners)
104         else:
105             warning = MIMEText((warn_msg % (subject,)).encode('utf-8'), 'plain', 'utf-8')
106             warning['Subject'] = 'Message de OpenERP'
107             warning['From'] = 'erp@steel-sa.com'
108             warning['To'] = msg['From']
109             s = smtplib.SMTP()
110             s.connect()
111             s.sendmail('erp@steel-sa.com', self.email_re.findall(msg['From']), warning.as_string())
112             s.close()
113
114         if msg.is_multipart():
115             for message in [m for m in msg.get_payload() if m.get_content_type() == 'message/rfc822']:
116                 self((headers, message.get_payload()[0]))
117     
118     def save_mail(self, msg, subject, partners):
119         counter, description = 1, u''
120         if msg.is_multipart():
121             for part in msg.get_payload():
122                 stockdir = os.path.join('emails', msg['Message-Id'][1:-1])
123                 newdir = os.path.join('/tmp', stockdir)
124                 filename = part.get_filename()
125                 if not filename:
126                     ext = mimetypes.guess_extension(part.get_type())
127                     if not ext:
128                         ext = '.bin'
129                     filename = 'part-%03d%s' % (counter, ext)
130
131                 if part.get_content_maintype() == 'multipart':
132                     continue
133                 elif part.get_content_maintype() == 'text':
134                     if part.get_content_subtype() == 'plain':
135                         description += part.get_payload(decode=1).decode(part.get_charsets()[0])
136                         description += u'\n\nVous trouverez les éventuels fichiers dans le répertoire: %s' % stockdir
137                         continue
138                     else:
139                         description += u'\n\nCe message est en "%s", vous trouverez ce texte dans le répertoire: %s' % (part.get_content_type(), stockdir)
140                 elif part.get_content_type() == 'message/rfc822':
141                     continue
142                 if not os.path.isdir(newdir):
143                     os.mkdir(newdir)
144
145                 counter += 1
146                 fd = file(os.path.join(newdir, filename), 'w')
147                 fd.write(part.get_payload(decode=1))
148                 fd.close()
149         else:
150             description = msg.get_payload(decode=1).decode(msg.get_charsets()[0])
151
152         project = self.project_re.search(subject)
153         if project:
154             project = project.groups()[0]
155         else:
156             project = ''
157
158         for partner in partners:
159             self.rpc(('res.partner.event', 'create', {'name' : subject, 'partner_id' : partner, 'description' : description, 'project' : project}))
160
161
162 if __name__ == '__main__':
163     rpc_dispatcher = CommandDispatcher(RPCProxy(4, 'admin'))
164     dispatcher = CommandDispatcher(ReceiverEmail2Event(rpc_dispatcher))
165     parser = EmailParser(['To', 'Cc', 'From'], dispatcher)
166     parser.parse(email.message_from_file(sys.stdin))
167
168 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
169