#!/usr/bin/env python
# -*- coding: utf-8 -*-
###############################################################################
# Copyright 2014 Kitware Inc.
#
# Licensed under the Apache License, Version 2.0 ( the "License" );
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
###############################################################################
import cherrypy
import os
import smtplib
from email.mime.text import MIMEText
from mako.lookup import TemplateLookup
from girder import events
from girder import logger
from girder.constants import SettingKey, ROOT_DIR
from .model_importer import ModelImporter
[docs]def getEmailUrlPrefix():
"""
Return the URL prefix for links back to the server. This is the link to the
server root, so Girder-level path information and any query parameters or
fragment value should be appended to this value.
"""
host = ModelImporter.model('setting').get(SettingKey.EMAIL_HOST, '')
if not host:
host = '://'.join((cherrypy.request.scheme,
cherrypy.request.local.name))
if cherrypy.request.local.port != 80:
host += ':{}'.format(cherrypy.request.local.port)
return host
[docs]def renderTemplate(name, params=None):
"""
Renders one of the HTML mail templates located in girder/mail_templates.
:param name: The name of the file inside girder/mail_templates to render.
:param params: The parameters to pass when rendering the template.
:type params: dict
:returns: The rendered template as a string of HTML.
"""
if not params:
params = {}
if 'host' not in params:
params['host'] = getEmailUrlPrefix()
template = _templateLookup.get_template(name)
return template.render(**params)
[docs]def sendEmail(to=None, subject=None, text=None, toAdmins=False):
"""
Send an email. This builds the appropriate email object and then triggers
an asynchronous event to send the email (handled in _sendmail).
:param to: The recipient's email address, or a list of addresses.
:type to: str, list/tuple, or None
:param subject: The subject line of the email.
:type subject: str
:param text: The body of the email.
:type text: str
:param toAdmins: To send an email to all site administrators, set this
to True, which will override any "to" argument that was passed.
:type toAdmins: bool
"""
if toAdmins:
to = [u['email'] for u in ModelImporter.model('user').getAdmins()]
elif isinstance(to, basestring):
to = (to,)
if not isinstance(to, (list, tuple)):
raise Exception('You must specify a "to" address or list of addresses '
'or set toAdmins=True when calling sendEmail.')
msg = MIMEText(text, 'html')
msg['Subject'] = subject or '[no subject]'
msg['To'] = ', '.join(to)
msg['From'] = ModelImporter.model('setting').get(
SettingKey.EMAIL_FROM_ADDRESS, 'no-reply@girder.org')
events.daemon.trigger('_sendmail', info={
'message': msg,
'recipients': to
})
[docs]def addTemplateDirectory(dir):
"""
Adds a directory to the search path for mail templates. This is useful
for plugins that have their own set of mail templates.
:param dir: The directory to add to the template lookup path.
:type dir: str
"""
_templateLookup.directories.append(dir)
def _sendmail(event):
msg = event.info['message']
smtpHost = ModelImporter.model('setting').get(SettingKey.SMTP_HOST,
'localhost')
logger.info('Sending email to %s through %s', msg['To'], smtpHost)
s = smtplib.SMTP(smtpHost)
s.sendmail(msg['From'], event.info['recipients'], msg.as_string())
s.quit()
logger.info('Sent email to %s', msg['To'])
_templateDir = os.path.join(ROOT_DIR, 'girder', 'mail_templates')
_templateLookup = TemplateLookup(directories=[_templateDir], collection_size=50)
events.bind('_sendmail', 'core.email', _sendmail)