Source code for schedula.utils.form.server.contact

# coding=utf-8
# -*- coding: UTF-8 -*-
#
# Copyright 2015-2025, Vincenzo Arcidiacono;
# Licensed under the EUPL (the 'Licence');
# You may not use this work except in compliance with the Licence.
# You may obtain a copy of the Licence at: http://ec.europa.eu/idabc/eupl

"""
It provides functions to build the contact service.
"""
import os
import rst2txt
import logging
import datetime
import schedula as sh
from flask import render_template
from docutils.core import publish_string
from flask_security import current_user as cu
from flask_mail import Message, Mail as _Mail
from werkzeug.datastructures import MultiDict
from flask_wtf.recaptcha import RecaptchaField
from flask_babel import get_locale
from flask import flash, Blueprint, redirect, request, current_app as ca
from flask_security.utils import (
    base_render_json, suppress_form_csrf, get_post_action_redirect
)
from flask_security.forms import (
    RequiredLocalize, get_form_field_label, StringField, Form, EmailField,
    email_required, EmailValidation
)
from .locale import lazy_gettext

log = logging.getLogger(__name__)
bp = Blueprint('contact', __name__)


[docs] def prepare_message(boby, subject, recipients, reply_to=None, **kwargs): body = publish_string(boby, writer=rst2txt.Writer()).decode() html = publish_string(boby, writer_name='html').decode() return Message( body=body, html=html, subject=subject, recipients=recipients, reply_to=reply_to, **kwargs )
[docs] def _render_template(*paths, **data): from jinja2.exceptions import TemplateNotFound for path in paths: try: return render_template(path, **data) except TemplateNotFound: continue raise TemplateNotFound
[docs] class Mail(_Mail):
[docs] def send_rst( self, to, data, rst=None, reply_to=None, body=None, subject=None, language=None, **kwargs): from tabulate import tabulate if language is None: locale = get_locale() language = f"{locale.language}_{locale.territory}" body = body or _render_template( f'schedula/email/{rst}/body/{language}.rst', f'schedula/email/{rst}/body.rst', tabulate=tabulate, **data ) subject = subject or _render_template( f'schedula/email/{rst}/subject/{language}.rst', f'schedula/email/{rst}/subject.rst', tabulate=tabulate, **data ) recipients = list(sh.stlp(os.environ.get('LOCAL', to))) message = prepare_message( body, subject, recipients, reply_to=reply_to, **kwargs ) return self.send(message)
[docs] class ContactForm(Form): name = StringField( get_form_field_label('name'), validators=[RequiredLocalize()] ) email = EmailField( get_form_field_label("email"), render_kw={"autocomplete": "email"}, validators=[email_required, EmailValidation(verify=True)], ) subject = StringField( get_form_field_label('subject'), validators=[RequiredLocalize()] ) message = StringField( get_form_field_label('message'), validators=[RequiredLocalize()] ) recaptcha = RecaptchaField('g-recaptcha-response')
[docs] def get_post_contact_redirect(): return get_post_action_redirect("SCHEDULA_POST_CONTACT_VIEW", request.form)
[docs] @bp.route('/contact', methods=['POST']) def contact(): data = MultiDict( request.get_json() ) if request.is_json else request.form if cu.is_authenticated: if 'email' not in data: data['email'] = cu.email if 'name' not in data: data['name'] = f'{cu.firstname} {cu.lastname}' form = ContactForm(data, meta=suppress_form_csrf()) if form.validate_on_submit(): try: ca.extensions['schedula_mail'].send_rst( to=[form.data['email'], ca.config.get('MAIL_DEFAULT_SENDER')], rst='contact', reply_to=form.data['email'], data={ 'user': cu, 'data': data, 'created': datetime.datetime.now().strftime( "%d/%m/%Y-%H:%M:%S") } ) flash(str(lazy_gettext( 'Your message has been successfully sent!', domain='contact' )), 'success') except Exception as ex: flash(str(lazy_gettext( "A system error has occurred. Please try again later. " "If the problem persists, contact technical support.", domain='contact' )), 'error') return redirect(request.referrer or '/') if ca.extensions["security"]._want_json(request): return base_render_json(form) return redirect(get_post_contact_redirect())
[docs] class Contact(Mail):
[docs] def __init__(self, app): super().__init__(app)
[docs] def init_app(self, app): super().init_app(app) app.config['SCHEDULA_POST_CONTACT_VIEW'] = app.config.get( 'SCHEDULA_POST_CONTACT_VIEW', os.environ.get( 'SCHEDULA_POST_CONTACT_VIEW', app.config.get( "APPLICATION_ROOT", "/" ) ) ) app.register_blueprint(bp, url_prefix='/mail') app.extensions['schedula_mail'] = self