]> git.openstreetmap.org Git - osqa.git/blob - forum/utils/mail.py
8c80f537490e91a36bf7bafaa8e8d3f55a1111a5
[osqa.git] / forum / utils / mail.py
1 import email\r
2 import socket\r
3 import os\r
4 \r
5 from email.mime.multipart import MIMEMultipart\r
6 from email.mime.text import MIMEText\r
7 from email.mime.image import MIMEImage\r
8 \r
9 from django.core.mail import DNS_NAME\r
10 from smtplib import SMTP\r
11 import email.Charset\r
12 from forum import settings\r
13 from django.template import loader, Context, Template\r
14 from forum.utils.html import sanitize_html\r
15 from forum.context import application_settings\r
16 from forum.utils.html2text import HTML2Text\r
17 from threading import Thread\r
18 \r
19 def send_msg_list(msgs, sender=None):\r
20     if len(msgs):\r
21         connection = SMTP(str(settings.EMAIL_HOST), str(settings.EMAIL_PORT),\r
22                 local_hostname=DNS_NAME.get_fqdn())\r
23 \r
24         try:\r
25             if (bool(settings.EMAIL_USE_TLS)):\r
26                 connection.ehlo()\r
27                 connection.starttls()\r
28                 connection.ehlo()\r
29 \r
30             if settings.EMAIL_HOST_USER and settings.EMAIL_HOST_PASSWORD:\r
31                 connection.login(str(settings.EMAIL_HOST_USER), str(settings.EMAIL_HOST_PASSWORD))\r
32 \r
33             if sender is None:\r
34                 sender = str(settings.DEFAULT_FROM_EMAIL)\r
35 \r
36             for email, msg in msgs:\r
37                 try:\r
38                     connection.sendmail(sender, [email], msg)\r
39                 except Exception, e:\r
40                     pass\r
41             try:\r
42                 connection.quit()\r
43             except socket.sslerror:\r
44                 connection.close()\r
45         except Exception, e:\r
46             pass\r
47 \r
48 def html2text(s, ignore_tags=(), indent_width=4, page_width=80):\r
49     ignore_tags = [t.lower() for t in ignore_tags]\r
50     parser = HTML2Text(ignore_tags, indent_width, page_width)\r
51     parser.feed(s)\r
52     parser.close()\r
53     parser.generate()\r
54     return parser.result\r
55 \r
56 def named(data):\r
57     if isinstance(data, (tuple, list)) and len(data) == 2:\r
58         return '%s <%s>' % data\r
59 \r
60     return str(data)\r
61 \r
62 def create_msg(subject, sender, recipient, html, text, images):\r
63     msgRoot = MIMEMultipart('related')\r
64     msgRoot['Subject'] = subject\r
65     msgRoot['From'] = named(sender)\r
66     msgRoot['To'] =  named(recipient)\r
67     msgRoot.preamble = 'This is a multi-part message from %s.' % unicode(settings.APP_SHORT_NAME).encode('utf8')\r
68 \r
69     msgAlternative = MIMEMultipart('alternative')\r
70     msgRoot.attach(msgAlternative)\r
71 \r
72     msgAlternative.attach(MIMEText(text, _charset='utf-8'))\r
73     msgAlternative.attach(MIMEText(html, 'html', _charset='utf-8'))\r
74 \r
75     for img in images:\r
76         try:\r
77             fp = open(img[0], 'rb')\r
78             msgImage = MIMEImage(fp.read())\r
79             fp.close()\r
80             msgImage.add_header('Content-ID', '<'+img[1]+'>')\r
81             msgRoot.attach(msgImage)\r
82         except:\r
83             pass\r
84 \r
85     return msgRoot.as_string()\r
86 \r
87 def send_email(subject, recipients, template, context={}, sender=None, images=[], threaded=True):\r
88     if sender is None:\r
89         sender = (unicode(settings.APP_SHORT_NAME), unicode(settings.DEFAULT_FROM_EMAIL))\r
90 \r
91     if not len(images):\r
92         images = [(os.path.join(str(settings.UPFILES_FOLDER), os.path.basename(str(settings.APP_LOGO))), 'logo')]\r
93 \r
94     context.update(application_settings(None))\r
95     html_body = loader.get_template(template).render(Context(context))\r
96     txt_body = html2text(html_body)\r
97 \r
98     if isinstance(recipients, str):\r
99         recipients = [recipients]\r
100 \r
101     msgs = []\r
102 \r
103     for recipient in recipients:\r
104         if isinstance(recipient, str):\r
105             recipient_data = ('recipient', recipient)\r
106             recipient_context = None\r
107         elif isinstance(recipient, (list, tuple)) and len(recipient) == 2:\r
108             name, email = recipient\r
109             recipient_data = (name, email)\r
110             recipient_context = None\r
111         elif isinstance(recipient, (list, tuple)) and len(recipient) == 3:\r
112             name, email, recipient_context = recipient\r
113             recipient_data = (name, email)\r
114         else:\r
115             raise Exception('bad argument for recipients')\r
116 \r
117         if recipient_context is not None:\r
118             recipient_context = Context(recipient_context)\r
119             msg_html = Template(html_body).render(recipient_context)\r
120             msg_txt = Template(txt_body).render(recipient_context)\r
121         else:\r
122             msg_html = html_body\r
123             msg_txt = txt_body\r
124 \r
125         msg = create_msg(subject, sender, recipient_data, msg_html, msg_txt, images)\r
126         msgs.append((email, msg))\r
127 \r
128     if threaded:\r
129         thread = Thread(target=send_msg_list,  args=[msgs])\r
130         thread.setDaemon(True)\r
131         thread.start()\r
132     else:\r
133         send_msg_list(msgs)\r
134 \r
135 \r
136 def send_template_email(recipients, template, context):\r
137     t = loader.get_template(template)\r
138     context.update(dict(recipients=recipients, settings=settings))\r
139     t.render(Context(context))\r
140 \r
141 def create_and_send_mail_messages(messages):\r
142     sender = '%s <%s>' % (unicode(settings.APP_SHORT_NAME), unicode(settings.DEFAULT_FROM_EMAIL))\r
143 \r
144     connection = SMTP(str(settings.EMAIL_HOST), str(settings.EMAIL_PORT),\r
145                 local_hostname=DNS_NAME.get_fqdn())\r
146 \r
147     try:\r
148         if (bool(settings.EMAIL_USE_TLS)):\r
149             connection.ehlo()\r
150             connection.starttls()\r
151             connection.ehlo()\r
152 \r
153         if settings.EMAIL_HOST_USER and settings.EMAIL_HOST_PASSWORD:\r
154             connection.login(str(settings.EMAIL_HOST_USER), str(settings.EMAIL_HOST_PASSWORD))\r
155 \r
156         if sender is None:\r
157             sender = str(settings.DEFAULT_FROM_EMAIL)\r
158 \r
159         for recipient, subject, html, text, media in messages:\r
160             msgRoot = MIMEMultipart('related')\r
161             msgRoot['Subject'] = subject\r
162             msgRoot['From'] = sender\r
163             msgRoot['To'] =  '%s <%s>' % (recipient.username, recipient.email)\r
164             msgRoot.preamble = 'This is a multi-part message from %s.' % unicode(settings.APP_SHORT_NAME).encode('utf8')\r
165 \r
166             msgAlternative = MIMEMultipart('alternative')\r
167             msgRoot.attach(msgAlternative)\r
168 \r
169             msgAlternative.attach(MIMEText(text, _charset='utf-8'))\r
170             msgAlternative.attach(MIMEText(html, 'html', _charset='utf-8'))\r
171 \r
172             for alias, location in media.items():\r
173                 fp = open(location, 'rb')\r
174                 msgImage = MIMEImage(fp.read())\r
175                 fp.close()\r
176                 msgImage.add_header('Content-ID', '<'+alias+'>')\r
177                 msgRoot.attach(msgImage)\r
178 \r
179             try:\r
180                 connection.sendmail(sender, [recipient.email], msgRoot.as_string())\r
181             except Exception, e:\r
182                 pass\r
183 \r
184         try:\r
185             connection.quit()\r
186         except socket.sslerror:\r
187             connection.close()\r
188     except Exception, e:\r
189         print e\r