<commit_before># -*- coding: utf-8 -*-
##
## 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 \
     CFG_SITE_SUPPORT_EMAIL, \
     CFG_SITE_URL, \
     CFG_SITE_LANG, \
     CFG_SITE_NAME_INTL, \
     CFG_SITE_NAME, \
     CFG_SITE_ADMIN_EMAIL, \
     CFG_MISCUTIL_SMTP_HOST, \
     CFG_MISCUTIL_SMTP_PORT, \
     CFG_VERSION

from invenio.messages import wash_language, gettext_set_language
from invenio.textutils import guess_minimum_encoding
from invenio.errorlib import get_msgs_for_code_list, register_errors, register_exception

def send_email(fromaddr,
               toaddr,
               subject="",
               content="",
               html_content='',
               html_images=None,
               header=None,
               footer=None,
               html_header=None,
               html_footer=None,
               copy_to_admin=0,
               attempt_times=1,
               attempt_sleeptime=10,
               debug_level=0,
               ln=CFG_SITE_LANG,
               charset=None
               ):
    """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 or list-of-strings] list of receivers (if string, then
                   receivers are 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_times: [int] number of tries
    @attempt_sleeptime: [int] seconds in between tries
    @debug_level: [int] debug level
    @ln: [string] invenio language
    @charset: [string] the content charset. By default is None which means
    to try to encode the email as ascii, then latin1 then utf-8.

    If sending fails, try to send it ATTEMPT_TIMES, and wait for
    ATTEMPT_SLEEPTIME seconds in between tries.

    e.g.:
    send_email('<EMAIL>', '<EMAIL>', 'Let\'s try!'', 'check 1234', '<strong>check</strong> <em>1234</em><img src="cid:image1">', {'image1': '/tmp/quantum.jpg'})

    @return [bool]: True if email was sent okay, False if it was not.
    """

    if html_images is None:
        html_images = {}

    if type(toaddr) is str:
        toaddr = toaddr.strip().split(',')
    usebcc = len(toaddr) > 1  # More than one address, let's use Bcc in place of To
    if copy_to_admin:
        toaddr.append(CFG_SITE_ADMIN_EMAIL)
    body = forge_email(fromaddr, toaddr, subject, content, html_content, html_images, usebcc, header, footer, html_header, html_footer, ln, charset)
    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=CFG_SITE_LANG):
    """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
<commit_msg>Fixed wrong recursive call to send_email.<commit_after># -*- coding: utf-8 -*-
##
## 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 \
     CFG_SITE_SUPPORT_EMAIL, \
     CFG_SITE_URL, \
     CFG_SITE_LANG, \
     CFG_SITE_NAME_INTL, \
     CFG_SITE_NAME, \
     CFG_SITE_ADMIN_EMAIL, \
     CFG_MISCUTIL_SMTP_HOST, \
     CFG_MISCUTIL_SMTP_PORT, \
     CFG_VERSION

from invenio.messages import wash_language, gettext_set_language
from invenio.textutils import guess_minimum_encoding
from invenio.errorlib import get_msgs_for_code_list, register_errors, register_exception

def send_email(fromaddr,
               toaddr,
               subject="",
               content="",
               html_content='',
               html_images=None,
               header=None,
               footer=None,
               html_header=None,
               html_footer=None,
               copy_to_admin=0,
               attempt_times=1,
               attempt_sleeptime=10,
               debug_level=0,
               ln=CFG_SITE_LANG,
               charset=None
               ):
    """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 or list-of-strings] list of receivers (if string, then
                   receivers are 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_times: [int] number of tries
    @attempt_sleeptime: [int] seconds in between tries
    @debug_level: [int] debug level
    @ln: [string] invenio language
    @charset: [string] the content charset. By default is None which means
    to try to encode the email as ascii, then latin1 then utf-8.

    If sending fails, try to send it ATTEMPT_TIMES, and wait for
    ATTEMPT_SLEEPTIME seconds in between tries.

    e.g.:
    send_email('<EMAIL>', '<EMAIL>', 'Let\'s try!'', 'check 1234', '<strong>check</strong> <em>1234</em><img src="cid:image1">', {'image1': '/tmp/quantum.jpg'})

    @return [bool]: True if email was sent okay, False if it was not.
    """

    if html_images is None:
        html_images = {}

    if type(toaddr) is str:
        toaddr = toaddr.strip().split(',')
    usebcc = len(toaddr) > 1  # More than one address, let's use Bcc in place of To
    if copy_to_admin:
        if CFG_SITE_ADMIN_EMAIL not in toaddr:
            toaddr.append(CFG_SITE_ADMIN_EMAIL)
    body = forge_email(fromaddr, toaddr, subject, content, html_content, html_images, usebcc, header, footer, html_header, html_footer, ln, charset)
    if attempt_times < 1 or not toaddr:
        log('ERR_MISCUTIL_NOT_ATTEMPTING_SEND_EMAIL', fromaddr, toaddr, body)
        return False
    sent = False
    while not sent and attempt_times > 0:
        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()
            sent = True
        except (smtplib.SMTPException, socket.error):
            register_exception(alert_admin=True)
            if (debug_level > 1):
                log('ERR_MISCUTIL_CONNECTION_SMTP', attempt_sleeptime, sys.exc_info()[0], fromaddr, toaddr, body)
            sleep(attempt_sleeptime)
        attempt_times -= 1
    if not sent:
        log('ERR_MISCUTIL_SENDING_EMAIL', fromaddr, toaddr, body)
    return sent

def email_header(ln=CFG_SITE_LANG):
    """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

{'fraction_non_alphanumeric': 0.08515381185911726, 'fraction_numerical': 0.012839946500222917, 'mean_word_length': 2.8689203173508107, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6014469', 'n_tokens_mistral': 3565, 'n_tokens_neox': 3369, 'n_words': 1161}