def send_mail(self, data): """Send email.""" notification_type = data.get('notification_type') language = data['loan']['patron']['communication_language'] template = 'email/{type}/{lang}'.format( type=notification_type, lang=language ) recipient = data['loan']['patron']['email'] msg = TemplatedMessage( # template_html='{template}.html'.format(template=template), template_body='{template}.txt'.format(template=template), sender=config_value('EMAIL_SENDER'), recipients=[recipient], ctx=data['loan'] ) text = msg.body.split('\n') msg.subject = text[0] msg.body = '\n'.join(text[1:]) try: send_email.run(msg.__dict__) # TODO: investigate why delay does not work # send_email.delay(msg.__dict__) # current_app.extensions['mail'].send(msg) except Exception as e: raise(e)
def _create_email(data, patron, library, recipients): """.""" from flask_babelex import Locale from .api import get_template_to_use from ..loans.api import Loan language = patron['patron']['communication_language'] # set the current language for translations in template with current_app.test_request_context() as ctx: ctx.babel_locale = Locale.parse(language) loan = Loan.get_record_by_pid(data['loan']['pid']) tpl_path = get_template_to_use(loan, data).rstrip('/') template = f'{tpl_path}/{language}.txt' # get the sender email from # loan.pickup_location_pid.location.library.email sender = library['email'] msg = TemplatedMessage(template_body=template, sender=sender, recipients=recipients, ctx=data['loan']) text = msg.body.split('\n') # subject is the first line msg.subject = text[0] # body msg.body = '\n'.join(text[1:]) return msg
def send_mail(data): """Send the notification by email.""" notification_type = data.get('notification_type') language = data['loan']['patron']['communication_language'] template = 'email/{type}/{lang}.txt'.format( type=notification_type, lang=language ) # get the recipient email from loan.patron.email recipient = data['loan']['patron']['email'] # get the sender email from # loan.pickup_location_pid.location.library.email library = Location.get_record_by_pid( data['loan']['pickup_location_pid']).get_library() sender = library['email'] msg = TemplatedMessage( template_body=template, sender=sender, recipients=[recipient], ctx=data['loan'] ) text = msg.body.split('\n') msg.subject = text[0] msg.body = '\n'.join(text[1:]) task_send_email.run(msg.__dict__)
def create_and_send(template, ctx, subject, recipients, sender=None, type=None): if not current_app.config['CAP_SEND_MAIL']: return sender = sender or current_app.config.get('MAIL_DEFAULT_SENDER') try: assert recipients if type == "plain": msg = TemplatedMessage(template_body=template, ctx=ctx, **dict(sender=sender, bcc=recipients, subject=subject)) else: msg = TemplatedMessage(template_html=template, ctx=ctx, **dict(sender=sender, bcc=recipients, subject=subject)) current_app.extensions['mail'].send(msg) except AssertionError: current_app.logger.error( f'Mail Error from {sender} with subject: {subject}.\n' f'Empty recipient list.') raise AssertionError
def _create_user_for_api_registration(self, api_user_id): api_registration = ApiRegistrations.query.filter_by( id=api_user_id).one() password = os.urandom(5).encode('hex') kwargs = dict(email=api_registration.email, password=password, active='y') form = ConfirmRegisterForm(MultiDict(kwargs), csrf_enabled=False) u = None # Role with id 4 is an API user r = Role.query.filter_by(id=4).one() if form.validate(): kwargs['password'] = hash_password(kwargs['password']) kwargs['active'] = True u = _datastore.create_user(**kwargs) if _datastore.add_role_to_user(u, r): msg = TemplatedMessage( template_html='scoap3_api/email/confirmed.html', subject='SCOAP3 - Partner registration confirmation', sender=current_app.config.get('MAIL_DEFAULT_SENDER'), recipients=[api_registration.email], ctx={ 'email': api_registration.email, 'password': password, 'recipient': api_registration.name }) current_app.extensions['mail'].send(msg) else: flash('Error creating user. %s' % form.errors, 'error')
def send_result(result_data, content_type, recipients, tool_name): """ Sends the result via email to the user who requested it. :param result_data: generated data in a serialized form. :param content_type: MIME type of the attachment. :param recipients: recipients who will receive the email. :param tool_name: name of the tool, which will be used in the subject of the email. """ timestamp = datetime.now().strftime('%Y-%m-%dT%H:%M:%S') filename = 'scoap3_export_%s_%s.csv' % (tool_name, timestamp) # compress data if needed compress = current_app.config.get('TOOL_COMPRESS_ATTACHMENT', False) if compress: compressed_buffer = StringIO() gzip_file = GzipFile(fileobj=compressed_buffer, mode="wt") gzip_file.write(result_data) gzip_file.close() result_data = compressed_buffer.getvalue() content_type = 'application/gzip' filename += '.gz' attachment = Attachment(filename=filename, content_type=content_type, data=result_data) msg = TemplatedMessage( template_html='scoap3_tools/email/result.html', subject='SCOAP3 - Export %s result' % tool_name, sender=current_app.config.get('MAIL_DEFAULT_SENDER'), recipients=recipients, attachments=[attachment], ) current_app.extensions['mail'].send(msg)
def check_compliance(obj, *args): if 'control_number' not in obj.data: raise ValueError( "Object should have a 'control_number' key in 'data' dict to be consistent with article upload." ) recid = obj.data['control_number'] pid = PersistentIdentifier.get('recid', recid) record = Record.get_record(pid.object_uuid) checks = {} # Add temporary data to evaluation extra_data = {'extracted_text': __extract_article_text(record)} all_checks_accepted = True for name, func in COMPLIANCE_TASKS: check_accepted, details, debug = func(record, extra_data) all_checks_accepted = all_checks_accepted and check_accepted checks[name] = { 'check': check_accepted, 'details': details, 'debug': debug } c = Compliance.get_or_create(pid.object_uuid) results = { 'checks': checks, 'accepted': all_checks_accepted, 'data': { 'doi': get_first_doi(record), 'publisher': get_abbreviated_publisher(record), 'journal': get_abbreviated_journal(record), 'arxiv': get_first_arxiv(record) } } c.add_results(results) c.id_record = pid.object_uuid db.session.add(c) db.session.commit() # send notification about failed checks need_email = current_app.config.get('COMPLIANCE_SEND_FAILED_EMAILS', True) if need_email and not all_checks_accepted and c.has_final_result_changed(): msg = TemplatedMessage( template_html='scoap3_compliance/admin/failed_email.html', subject='SCOAP3 - Compliance check', sender=current_app.config.get('MAIL_DEFAULT_SENDER'), recipients=current_app.config.get('OPERATIONS_EMAILS'), ctx={ 'results': results, 'id': '%s,%s' % (c.id, record.id), }) current_app.extensions['mail'].send(msg)
def send_notification_to_location(loan, item, location): """Send a notification to the location defined email. :param loan: the loan to be parsed :param item: the requested item :param location: the location to inform """ if not location.get('send_notification', False) \ or not location.get('notification_email'): return template = 'email/others/location_notification.txt' recipient = location.get('notification_email') msg = TemplatedMessage(template_body=template, sender=config_value('EMAIL_SENDER'), recipients=[recipient], ctx=_build_notification_email_context( loan, item, location)) text = msg.body.split('\n') msg.subject = text[0] msg.body = '\n'.join(text[1:]) send_email.run(msg.__dict__)
def _create_email(recipients, reply_to, ctx_data, template): """Create email message from template. :param recipients: List of emails to send the message too. :param reply_to: Reply to email address. :param ctx_data: Dictionary with informations used in template. :param template: Template to use to create TemplatedMessage. :returns: Message created. """ msg = TemplatedMessage( template_body=template, sender=current_app.config.get('DEFAULT_SENDER_EMAIL', '*****@*****.**'), reply_to=','.join(reply_to), # the client is unable to manage list recipients=recipients, ctx=ctx_data) # subject is the first line, body is the rest text = msg.body.split('\n') msg.subject = text[0] msg.body = '\n'.join(text[1:]) return msg
def _send_article_check_report(missing_articles, statistics, from_date): """Sends detailed report regarding the missing articles.""" msg = TemplatedMessage( template_html='scoap3_records/email/article_check_report.html', subject='SCOAP3 - Article check report', sender=current_app.config.get('MAIL_DEFAULT_SENDER'), recipients=current_app.config.get('OPERATIONS_EMAILS'), ctx={ 'missing_articles': missing_articles, 'statistics': statistics, 'from_date': from_date }) current_app.extensions['mail'].send(msg)
def send_failed_email(recipients, tool_name, task_id=None): """ Notifies the user about a failed generation. :param recipients: recipients who will receive the email. :param tool_name: name of the tool, which will be used in the subject of the email. :param task_id: celery task id, if available. """ msg = TemplatedMessage( template_html='scoap3_tools/email/failed.html', subject='SCOAP3 - Export %s result error' % tool_name, sender=current_app.config.get('MAIL_DEFAULT_SENDER'), recipients=recipients, ctx={'task_id': task_id}) current_app.extensions['mail'].send(msg)
def send_email(recipients, subject, template, ctx=None, html=True, lang='en'): """Send email.""" email_type = 'html' if html else 'txt' template = '{template}/{lang}.{type}'.format(template=template, lang=lang, type=email_type) msg = TemplatedMessage( template_body=template if not html else None, template_html=template if html else None, sender=current_app.config.get('SECURITY_EMAIL_SENDER'), recipients=recipients, subject=subject, ctx=ctx) current_app.extensions['mail'].send(msg)
def __halt_and_notify(msg, eng): ctx = { 'reason': msg, # url with predefined filter for HALTED workflows 'url': url_for('workflow.index_view', flt1_21='2', _external=True), } template_msg = TemplatedMessage( template_html='scoap3_workflows/emails/halted_article_upload.html', subject='SCOAP3 - Artcile upload halted', sender=current_app.config.get('MAIL_DEFAULT_SENDER'), recipients=current_app.config.get('ADMIN_DEFAULT_EMAILS'), ctx=ctx) current_app.extensions['mail'].send(template_msg) eng.halt(msg)
def test_templated_message(email_api_app, email_params, email_ctx): """Test that all the fields given are inside the message.""" with email_api_app.app_context(): msg = TemplatedMessage(template_body='invenio_mail/base.txt', template_html='invenio_mail/base.html', ctx=email_ctx, **email_params) for key in email_params: assert email_params[key] == getattr(msg, key), key # let's check that the body and html are correctly formatted assert '<p>Dear {0},</p>'.format(email_ctx['user']) in msg.html assert 'Dear {0},'.format(email_ctx['user']) in msg.body assert '<p>{0}</p>'.format(email_ctx['content']) in msg.html assert '{0}'.format(email_ctx['content']) in msg.body assert email_ctx['sender'] in msg.html assert email_ctx['sender'] in msg.body
def send_result(result_data, content_type, recipients, tool_name): """ Sends the result via email to the user who requested it. :param result_data: generated data in a serialized form. :param content_type: MIME type of the attachment. :param recipients: recipients who will receive the email. :param tool_name: name of the tool, which will be used in the subject of the email. """ timestamp = datetime.now().strftime('%Y-%m-%dT%H:%M:%S') filename = 'scoap3_export_%s_%s.csv' % (tool_name, timestamp) # compress data if needed # try: # compress = current_app.config.get('TOOL_COMPRESS_ATTACHMENT', False) # if compress: # compressed_buffer = StringIO() # gzip_file = GzipFile(fileobj=compressed_buffer, mode="wt") # gzip_file.write(result_data) # gzip_file.close() # # result_data = compressed_buffer.getvalue() # content_type = 'application/gzip' # filename += '.gz' # except Exception as e: # logger.error('Error in csv compression: {}'.format(e.message)) # # attachment = Attachment(filename=filename, content_type=content_type, data=result_data) host = current_app.config.get('S3_HOSTNAME') bucket = current_app.config.get('S3_BUCKET') s3 = boto3.resource('s3', endpoint_url='http://s3.cern.ch/') s3.meta.client.upload_fileobj(io.BytesIO(result_data), bucket, filename, ExtraArgs={'ACL': 'public-read'}) file_url = "{}/{}/{}".format(host, bucket, filename) msg = TemplatedMessage( template_html='scoap3_tools/email/result.html', ctx={'attachment_url': file_url}, subject='SCOAP3 - Export %s result' % tool_name, sender=current_app.config.get('MAIL_DEFAULT_SENDER'), recipients=recipients, # attachments=[attachment], ) current_app.extensions['mail'].send(msg)
def handler_registration(): if request.method != 'POST': return False email = request.form.get('email') if not email: flash('Please provide a valid email address!', 'error') return False already_exists = User.query.filter(User.email == email).count() if already_exists: flash("User with email '%s' is already registered." % email, 'error') return False request_already_exists = ApiRegistrations.query.filter( ApiRegistrations.email == email).count() if request_already_exists: flash( "Registration failed! Request with email '%s' already exists." % email, 'error') return False new_reg = ApiRegistrations( partner=bool(int(request.form.get('partner', '0'))), name=request.form.get('name', ''), email=email, organization=request.form.get('organization', ''), role=request.form.get('role', ''), country=request.form.get('country', ''), description=request.form.get('description', '')) db.session.add(new_reg) db.session.commit() msg = TemplatedMessage( template_html='scoap3_api/email/new_registration.html', subject='SCOAP3 - New partner registration', sender=current_app.config.get('MAIL_DEFAULT_SENDER'), recipients=current_app.config.get('ADMIN_DEFAULT_EMAILS'), ctx={'url': url_for('apiregistrations.index_view', _external=True)}) current_app.extensions['mail'].send(msg) return True
def __halt_and_notify(msg, obj, eng): eng.halt(msg) ctx = { 'doi': __get_first_doi(obj), 'reason': msg, 'url': url_for('workflow.details_view', id=eng.current_object.workflow.uuid, _external=True) } msg = TemplatedMessage( template_html='scoap3_workflows/emails/halted_article_upload.html', subject='SCOAP3 - Artcile upload halted', sender=current_app.config.get('MAIL_DEFAULT_SENDER'), recipients=current_app.config.get('ADMIN_DEFAULT_EMAILS'), ctx=ctx) current_app.extensions['mail'].send(msg)
def send_mail(data): """Send the notification by email.""" patron = data['loan']['patron'] # get the recipient email from loan.patron.patron.email recipient = patron.get('email') # do nothing if the patron does not have an email if not recipient: current_app.logger.warning( 'Patron (pid: {pid}) does not have an email'.format( pid=patron['pid'])) return notification_type = data.get('notification_type') language = patron['patron']['communication_language'] template = 'email/{type}/{lang}.txt'.format( type=notification_type, lang=language ) # get the sender email from # loan.pickup_location_pid.location.library.email library = Location.get_record_by_pid( data['loan']['pickup_location_pid']).get_library() sender = library['email'] msg = TemplatedMessage( template_body=template, sender=sender, recipients=[recipient], ctx=data['loan'] ) # additional recipient add_recipient = patron['patron'].get('additional_communication_email') if add_recipient: msg.add_recipient(add_recipient) text = msg.body.split('\n') msg.subject = text[0] msg.body = '\n'.join(text[1:]) task_send_email.run(msg.__dict__)
def test_simple_templated_message(email_api_app): """Test that defaults are sane.""" with email_api_app.app_context(): msg = TemplatedMessage(template_body='invenio_mail/base.txt', template_html='invenio_mail/base.html') assert msg
def contact_us(): """Provide form for questions/comments.""" form = ContactForm() if form.validate_on_submit(): current_app.jinja_env.add_extension("jinja2_time.TimeExtension") # Send email to site operators subject = render_template_to_string( current_app.config['CONTACT_US_SUPPORT_EMAIL_SUBJECT_TEMPLATE'], original_subject=form.subject.data) msg = TemplatedMessage( subject=subject, template_body=( current_app.config[ 'CONTACT_US_SUPPORT_EMAIL_BODY_TEMPLATE_TXT'] # noqa ), template_html=( current_app.config[ 'CONTACT_US_SUPPORT_EMAIL_BODY_TEMPLATE_HTML'] # noqa ), sender=(form.name.data, form.email.data), recipients=[ ( current_app.config['CONTACT_US_RECIPIENT_NAME'], current_app.config['CONTACT_US_RECIPIENT_EMAIL'], ), ], reply_to=(form.name.data, form.email.data), ctx={'poster': form.data}) current_app.extensions['mail'].send(msg) # Send confirmation to the original poster subject = render_template_to_string(current_app.config[ 'CONTACT_US_CONFIRMATION_EMAIL_SUBJECT_TEMPLATE'] # noqa ) msg = TemplatedMessage( subject=subject, template_body=( current_app.config[ 'CONTACT_US_CONFIRMATION_EMAIL_BODY_TEMPLATE_TXT'] # noqa ), template_html=( current_app.config[ 'CONTACT_US_CONFIRMATION_EMAIL_BODY_TEMPLATE_HTML'] # noqa ), sender=(current_app.config['CONTACT_US_SENDER_NAME'], current_app.config['CONTACT_US_SENDER_EMAIL']), recipients=[(form.name.data, form.email.data)], ctx={} # Needed because of Invenio bug. # PR inveniosoftware/invenio-mail #44 sent. ) current_app.extensions['mail'].send(msg) # TODO?: Add mailing error resiliency # TODO?: Make mailing asynchronous flash("Thank you for contacting us. We will be in touch soon!", category='success') return redirect(url_for('cd2hrepo_frontpage.index')) else: return render_template( 'contact_us/contact_us.html', form=form, )