## $Id: utils.py 7407 2011-12-20 11:05:07Z henrik $
##
## Copyright (C) 2011 Uli Fouquet & Henrik Bettermann
## This program 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.
##
## This program 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 this program; if not, write to the Free Software
## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
##
"""General helper utilities for SIRP.
"""
import grok
import smtplib
import string
from random import SystemRandom as r
from email.mime.text import MIMEText
from waeup.sirp.interfaces import ISIRPUtils

from email.Header import Header
from email.Utils import parseaddr, formataddr

def send_mail(from_name,from_addr,rcpt_name,rcpt_addr,subject,body,config):
    """
    XXX: While this method is unicode-proof (i.e. it can handle
         non-plain-ASCII chars in names and messages) other
         methods inhere are not and will fail silently. Some
         reorganization of SMPT-related code is needed here.
    """

    header_charset = 'ISO-8859-1'
    from_name = str(Header(unicode(from_name), header_charset))
    rcpt_name = str(Header(unicode(rcpt_name), header_charset))
    from_addr = from_addr.encode('ascii')
    rpct_addr = rcpt_addr.encode('ascii')
    for body_charset in ['US-ASCII', 'ISO-8859-1', 'UTF-8']:
        try:
            body.encode(body_charset)
        except UnicodeError:
            #print "FAILED: ", body_charset, body
            pass
        else:
            break
    msg = MIMEText(body.encode(body_charset), 'plain', body_charset)
    msg['From'] = formataddr((from_name, from_addr))
    msg['To'] = formataddr((rcpt_name, rcpt_addr))
    msg['Subject'] = Header(unicode(subject), header_charset)
    server = smtplib.SMTP(config.smtp_server)
    if config.smtp_requires_login:
        server.login(config.smtp_username,config.smtp_password)
    try:
        server.sendmail(from_addr,rcpt_addr,msg.as_string())
    except Exception, e:
        # XXX: log error message
        return False
    server.quit()
    return True


class SIRPUtils(grok.GlobalUtility):
    """A collection of methods subject to customization.
    """
    grok.implements(ISIRPUtils)

    def sendContactForm(self,from_name,from_addr,rcpt_name,rcpt_addr,
                from_username,usertype,portal,body,subject):
        """Send an email with data provided by forms.
        """
        config = grok.getSite()['configuration']
        text = """Fullname: %s
User Id: %s
User Type: %s
Portal: %s

%s
"""
        body = text % (from_name,from_username,usertype,portal,body)
        return send_mail(
            from_name,from_addr,rcpt_name,rcpt_addr,subject,body,config)

    def fullname(self,firstname,lastname,middlename=None):
        # We do not necessarily have the middlename attribute
        if middlename:
            return string.capwords(
                '%s %s %s' % (firstname, middlename, lastname))
        else:
            return string.capwords(
                '%s %s' % (firstname, lastname))

    def genPassword(self, length=8, chars=string.letters + string.digits):
        return ''.join([r().choice(chars) for i in range(length)])


    def sendCredentials(self, user, password=None, login_url=None, msg=None):
        """Send credentials as email.

        Input is the applicant for which credentials are sent and the
        password.

        Returns True or False to indicate successful operation.
        """
        subject = 'Your SIRP credentials'
        text = """Dear %s,

%s
Student Registration and Information Portal of
%s.

Your user name: %s
Your password: %s
Login page: %s

Please remember your user name and keep
your password secret!

Please also note that passwords are case-sensitive.

Regards
"""
        config = grok.getSite()['configuration']
        from_name = config.name_admin
        from_addr = config.email_admin
        rcpt_name = user.title
        rcpt_addr = user.email
        body = text % (
                rcpt_name, msg,config.name,user.name,password,login_url)
        return send_mail(
            from_name,from_addr,rcpt_name,rcpt_addr,subject,body,config)
