Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F68472607
mailutils.py
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Thu, Jun 27, 13:38
Size
10 KB
Mime Type
text/x-python
Expires
Sat, Jun 29, 13:38 (2 d)
Engine
blob
Format
Raw Data
Handle
18483327
Attached To
R3600 invenio-infoscience
mailutils.py
View Options
# -*- coding: utf-8 -*-
##
## $Id$
##
## This file is part of CDS Invenio.
## Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 CERN.
##
## CDS Invenio is free software; you can redistribute it and/or
## modify it under the terms of the GNU General Public License as
## published by the Free Software Foundation; either version 2 of the
## License, or (at your option) any later version.
##
## CDS Invenio is distributed in the hope that it will be useful, but
## WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
## General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with CDS Invenio; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""
Invenio mail sending utilities. send_email() is the main API function
people should be using; just check out its docstring.
"""
__revision__
=
"$Id$"
import
sys
from
time
import
sleep
import
smtplib
import
socket
import
re
import
os
from
email.Header
import
Header
from
email.MIMEText
import
MIMEText
from
email.MIMEMultipart
import
MIMEMultipart
from
email.MIMEImage
import
MIMEImage
from
cStringIO
import
StringIO
from
formatter
import
DumbWriter
,
AbstractFormatter
from
invenio.config
import
\
supportemail
,
\
weburl
,
\
cdslang
,
\
cdsnameintl
,
\
cdsname
,
\
adminemail
,
\
CFG_MISCUTIL_SMTP_HOST
,
\
CFG_MISCUTIL_SMTP_PORT
,
\
version
from
invenio.messages
import
wash_language
,
gettext_set_language
from
invenio.errorlib
import
get_msgs_for_code_list
,
register_errors
,
register_exception
def
send_email
(
fromaddr
,
toaddr
,
subject
=
""
,
content
=
""
,
html_content
=
''
,
html_images
=
{},
header
=
None
,
footer
=
None
,
html_header
=
None
,
html_footer
=
None
,
copy_to_admin
=
0
,
attempt_times
=
1
,
attempt_sleeptime
=
10
,
debug_level
=
0
,
ln
=
cdslang
,
charset
=
'utf-8'
):
"""Send an forged email to TOADDR from FROMADDR with message created from subjet, content and possibly
header and footer.
@param fromaddr: [string] sender
@param toaddr: [string] receivers separated by ,
@param subject: [string] subject of the email
@param content: [string] content of the email
@param html_content: [string] html version of the email
@param html_images: [dict] dictionary of image id, image path
@param header: [string] header to add, None for the Default
@param footer: [string] footer to add, None for the Default
@param html_header: [string] header to add to the html part, None for the Default
@param html_footer: [string] footer to add to the html part, None for the Default
@param copy_to_admin: [int] if 1 add emailamin in receivers
@attempt_time: [int] number of tries
@attempt_sleeptime: [int] seconds in between tries
@debug_level: [int] debug level
@ln: [string] invenio language
@param charset: which charset to use in message ('utf-8' by default)
If sending fails, try to send it ATTEMPT_TIMES, and wait for
ATTEMPT_SLEEPTIME seconds in between tries.
e.g.:
send_email('foo.bar@cern.ch', 'bar.foo@cern.ch', 'Let\'s try!'', 'check 1234', '<strong>check</strong> <em>1234</em><img src="cid:image1">', {'image1': '/tmp/quantum.jpg'})
@return [int]: 0 if email was sent okay, 1 if it was not.
"""
toaddr
=
toaddr
.
strip
()
usebcc
=
','
in
toaddr
# More than one address, let's use Bcc in place of To
if
copy_to_admin
:
if
len
(
toaddr
)
>
0
:
toaddr
+=
",
%s
"
%
(
adminemail
,)
else
:
toaddr
=
adminemail
body
=
forge_email
(
fromaddr
,
toaddr
,
subject
,
content
,
html_content
,
html_images
,
usebcc
,
header
,
footer
,
html_header
,
html_footer
,
ln
,
charset
)
toaddr
=
toaddr
.
split
(
","
)
if
attempt_times
<
1
or
len
(
toaddr
[
0
])
==
0
:
log
(
'ERR_MISCUTIL_NOT_ATTEMPTING_SEND_EMAIL'
,
fromaddr
,
toaddr
,
body
)
return
False
try
:
server
=
smtplib
.
SMTP
(
CFG_MISCUTIL_SMTP_HOST
,
CFG_MISCUTIL_SMTP_PORT
)
if
debug_level
>
2
:
server
.
set_debuglevel
(
1
)
else
:
server
.
set_debuglevel
(
0
)
server
.
sendmail
(
fromaddr
,
toaddr
,
body
)
server
.
quit
()
except
(
smtplib
.
SMTPException
,
socket
.
error
):
if
attempt_times
>
1
:
if
(
debug_level
>
1
):
log
(
'ERR_MISCUTIL_CONNECTION_SMTP'
,
attempt_sleeptime
,
sys
.
exc_info
()[
0
],
fromaddr
,
toaddr
,
body
)
sleep
(
attempt_sleeptime
)
return
send_email
(
fromaddr
,
toaddr
,
body
,
attempt_times
-
1
,
attempt_sleeptime
)
else
:
log
(
'ERR_MISCUTIL_SENDING_EMAIL'
,
fromaddr
,
toaddr
,
body
)
return
False
except
Exception
:
register_exception
()
return
False
return
True
def
email_header
(
ln
=
cdslang
):
"""The header of the email
@param ln: language
@return header as a string"""
ln
=
wash_language
(
ln
)
_
=
gettext_set_language
(
ln
)
#standard header
out
=
"""%(hello)s
"""
%
{
'hello'
:
_
(
"Hello:"
)
}
return
out
def
email_html_header
(
ln
=
cdslang
):
"""The header of the email
@param ln: language
@return header as a string"""
ln
=
wash_language
(
ln
)
_
=
gettext_set_language
(
ln
)
#standard header
out
=
"""%(hello)s<br />
"""
%
{
'hello'
:
_
(
"Hello:"
)
}
return
out
def
email_footer
(
ln
=
cdslang
):
"""The footer of the email
@param ln: language
@return footer as a string"""
ln
=
wash_language
(
ln
)
_
=
gettext_set_language
(
ln
)
#standard footer
out
=
"""\n\n%(best_regards)s
--
%(cdsnameintl)s <%(weburl)s>
%(need_intervention_please_contact)s <%(supportemail)s>
"""
%
{
'cdsnameintl'
:
cdsnameintl
[
ln
],
'best_regards'
:
_
(
"Best regards"
),
'weburl'
:
weburl
,
'need_intervention_please_contact'
:
_
(
"Need human intervention? Contact"
),
'supportemail'
:
supportemail
}
return
out
def
email_html_footer
(
ln
=
cdslang
):
"""The html footer of the email
@param ln: language
@return footer as a string"""
ln
=
wash_language
(
ln
)
_
=
gettext_set_language
(
ln
)
#standard footer
out
=
"""<br /><br /><em>%(best_regards)s</em>
<hr />
<a href="%(weburl)s"><strong>%(cdsnameintl)s</strong></a><br />
%(need_intervention_please_contact)s <a href="mailto:%(supportemail)s">%(supportemail)s</a>
"""
%
{
'cdsnameintl'
:
cdsnameintl
.
get
(
ln
,
cdsname
),
'best_regards'
:
_
(
"Best regards"
),
'weburl'
:
weburl
,
'need_intervention_please_contact'
:
_
(
"Need human intervention? Contact"
),
'supportemail'
:
supportemail
}
return
out
def
forge_email
(
fromaddr
,
toaddr
,
subject
,
content
,
html_content
=
''
,
html_images
=
{},
usebcc
=
False
,
header
=
None
,
footer
=
None
,
html_header
=
None
,
html_footer
=
None
,
ln
=
cdslang
,
charset
=
'utf-8'
):
"""Prepare email. Add header and footer if needed.
@param fromaddr: [string] sender
@param toaddr: [string] receivers separated by ,
@param usebcc: [bool] True for using Bcc in place of To
@param subject: [string] subject of the email
@param content: [string] content of the email
@param html_content: [string] html version of the email
@param html_images: [dict] dictionary of image id, image path
@param header: [string] None for the default header
@param footer: [string] None for the default footer
@param ln: language
@param charset: which charset to use in message ('utf-8' by default)
@return forged email as a string"""
if
header
is
None
:
content
=
email_header
(
ln
)
+
content
else
:
content
=
header
+
content
if
footer
is
None
:
content
+=
email_footer
(
ln
)
else
:
content
+=
footer
if
html_content
:
if
html_header
is
None
:
html_content
=
email_html_header
(
ln
)
+
html_content
else
:
html_content
=
html_header
+
content
if
html_footer
is
None
:
html_content
+=
email_html_footer
(
ln
)
else
:
html_content
+=
html_footer
msg_root
=
MIMEMultipart
(
'related'
)
msg_root
[
'Subject'
]
=
Header
(
subject
,
charset
)
msg_root
[
'From'
]
=
fromaddr
if
usebcc
:
msg_root
[
'Bcc'
]
=
toaddr
else
:
msg_root
[
'To'
]
=
toaddr
msg_root
.
preamble
=
'This is a multi-part message in MIME format.'
msg_alternative
=
MIMEMultipart
(
'alternative'
)
msg_root
.
attach
(
msg_alternative
)
msg_text
=
MIMEText
(
content
,
_charset
=
charset
)
msg_alternative
.
attach
(
msg_text
)
msg_text
=
MIMEText
(
html_content
,
'html'
,
_charset
=
charset
)
msg_alternative
.
attach
(
msg_text
)
for
image_id
,
image_path
in
html_images
.
iteritems
():
msg_image
=
MIMEImage
(
open
(
image_path
,
'rb'
)
.
read
())
msg_image
.
add_header
(
'Content-ID'
,
'<
%s
>'
%
image_id
)
msg_image
.
add_header
(
'Content-Disposition'
,
'attachment'
,
filename
=
os
.
path
.
split
(
image_path
)[
1
])
msg_root
.
attach
(
msg_image
)
else
:
msg_root
=
MIMEText
(
content
,
_charset
=
charset
)
msg_root
[
'From'
]
=
fromaddr
if
usebcc
:
msg_root
[
'Bcc'
]
=
toaddr
else
:
msg_root
[
'To'
]
=
toaddr
msg_root
[
'Subject'
]
=
Header
(
subject
,
charset
)
msg_root
.
add_header
(
'User-Agent'
,
'CDS Invenio
%s
'
%
version
)
return
msg_root
.
as_string
()
RE_NEWLINES
=
re
.
compile
(
r'<br\s*/?>|</p>'
,
re
.
I
)
RE_SPACES
=
re
.
compile
(
r'\s+'
)
RE_HTML_TAGS
=
re
.
compile
(
r'<.+?>'
)
def
email_strip_html
(
html_content
):
"""Strip html tags from html_content, trying to respect formatting."""
html_content
=
RE_SPACES
.
sub
(
' '
,
html_content
)
html_content
=
RE_NEWLINES
.
sub
(
'
\n
'
,
html_content
)
html_content
=
RE_HTML_TAGS
.
sub
(
''
,
html_content
)
html_content
=
html_content
.
split
(
'
\n
'
)
out
=
StringIO
()
out_format
=
AbstractFormatter
(
DumbWriter
(
out
))
for
row
in
html_content
:
out_format
.
add_flowing_data
(
row
)
out_format
.
end_paragraph
(
1
)
return
out
.
getvalue
()
def
log
(
*
error
):
"""Register error
@param error: tuple of the form(ERR_, arg1, arg2...)
"""
_
=
gettext_set_language
(
cdslang
)
errors
=
get_msgs_for_code_list
([
error
],
'error'
,
cdslang
)
register_errors
(
errors
,
'error'
)
Event Timeline
Log In to Comment