def send_mail(recipients, subject, msg_html): """Envoi d'un email à l'aide de Flask_mail. .. :quickref: Fonction générique d'envoi d'email. Parameters ---------- recipients : str or [str] Chaine contenant des emails séparés par des virgules ou liste contenant des emails. Un email encadré par des chevrons peut être précédé d'un libellé qui sera utilisé lors de l'envoi. subject : str Sujet de l'email. msg_html : str Contenu de l'eamil au format HTML. Returns ------- void L'email est envoyé. Aucun retour. """ if not MAIL: raise Exception("No configuration for email") with MAIL.connect() as conn: mail_sender = current_app.config.get('MAIL_DEFAULT_SENDER') if not mail_sender: mail_sender = current_app.config["MAIL_USERNAME"] msg = Message(subject, sender=mail_sender, recipients=clean_recipients(recipients)) msg.html = msg_html conn.send(msg)
def create_app(with_external_mods=True): app = Flask(__name__.split('.')[0], static_folder="../static") app.config.update(config) api_uri = urlsplit(app.config['API_ENDPOINT']) app.config['APPLICATION_ROOT'] = api_uri.path app.config['PREFERRED_URL_SCHEME'] = api_uri.scheme if 'SCRIPT_NAME' not in os.environ: os.environ['SCRIPT_NAME'] = app.config['APPLICATION_ROOT'].rstrip('/') app.config['TEMPLATES_AUTO_RELOAD'] = True # disable cache for downloaded files (PDF file stat for ex) app.config['SEND_FILE_MAX_AGE_DEFAULT'] = 0 if len(app.config['SECRET_KEY']) < 20: raise Exception("The SECRET_KEY config option must have a length " "greater or equals to 20 characters.") # set from headers HTTP_HOST, SERVER_NAME, and SERVER_PORT app.wsgi_app = ProxyFix(app.wsgi_app, x_host=1) app.json_encoder = MyJSONEncoder # set logging config config_loggers(app.config) db.init_app(app) migrate.init_app(app, DB, directory=BACKEND_DIR / 'geonature' / 'migrations') MA.init_app(app) CORS(app, supports_credentials=True) # Emails configuration if app.config["MAIL_CONFIG"]: conf = app.config.copy() conf.update(app.config["MAIL_CONFIG"]) app.config = conf MAIL.init_app(app) # Pass parameters to the usershub authenfication sub-module, DONT CHANGE THIS app.config["DB"] = DB # Pass parameters to the submodules app.config["MA"] = MA # For deleting files on "delete" media @before_models_committed.connect_via(app) def on_before_models_committed(sender, changes): for obj, change in changes: if change == "delete" and hasattr(obj, "__before_commit_delete__"): obj.__before_commit_delete__() # setting g.current_user on each request @app.before_request def load_current_user(): try: g.current_user = user_from_token(request.cookies['token']).role except (KeyError, UnreadableAccessRightsError, AccessRightsExpiredError): g.current_user = None admin.init_app(app) # Pass the ID_APP to the submodule to avoid token conflict between app on the same server with app.app_context(): try: gn_app = Application.query.filter_by( code_application=config['CODE_APPLICATION']).one() except (ProgrammingError, NoResultFound): logging.warning( "Warning: unable to find GeoNature application, database not yet initialized?" ) else: app.config["ID_APP"] = app.config[ "ID_APPLICATION_GEONATURE"] = gn_app.id_application for blueprint_path, url_prefix in [ ('pypnusershub.routes:routes', '/auth'), ('pypn_habref_api.routes:routes', '/habref'), ('pypnusershub.routes_register:bp', '/pypn/register'), ('pypnnomenclature.routes:routes', '/nomenclatures'), ('geonature.core.gn_commons.routes:routes', '/gn_commons'), ('geonature.core.gn_permissions.routes:routes', '/permissions'), ('geonature.core.gn_permissions.backoffice.views:routes', '/permissions_backoffice'), ('geonature.core.routes:routes', '/'), ('geonature.core.users.routes:routes', '/users'), ('geonature.core.gn_synthese.routes:routes', '/synthese'), ('geonature.core.gn_meta.routes:routes', '/meta'), ('geonature.core.ref_geo.routes:routes', '/geo'), ('geonature.core.auth.routes:routes', '/gn_auth'), ('geonature.core.gn_monitoring.routes:routes', '/gn_monitoring'), ('geonature.core.gn_profiles.routes:routes', '/gn_profiles'), ]: module_name, blueprint_name = blueprint_path.split(':') blueprint = getattr(import_module(module_name), blueprint_name) app.register_blueprint(blueprint, url_prefix=url_prefix) with app.app_context(): # register errors handlers import geonature.core.errors # Loading third-party modules if with_external_mods: try: for module_object, module_config, module_blueprint in import_backend_enabled_modules( ): app.config[module_config['MODULE_CODE']] = module_config app.register_blueprint( module_blueprint, url_prefix=module_config['MODULE_URL']) except ProgrammingError as sqla_error: if isinstance(sqla_error.orig, UndefinedTable): logging.warning( "Warning: database not yet initialized, skipping loading of external modules" ) else: raise return app
def create_app(with_external_mods=True, with_flask_admin=True): app = Flask(__name__) app.config.update(config) # Bind app to DB DB.init_app(app) MAIL.init_app(app) # For deleting files on "delete" media @before_models_committed.connect_via(app) def on_before_models_committed(sender, changes): for obj, change in changes: if change == "delete" and hasattr(obj, "__before_commit_delete__"): obj.__before_commit_delete__() # Bind app to MA MA.init_app(app) # Pass parameters to the usershub authenfication sub-module, DONT CHANGE THIS app.config["DB"] = DB # Pass parameters to the submodules app.config["MA"] = MA # Pass the ID_APP to the submodule to avoid token conflict between app on the same server app.config["ID_APP"] = app.config["ID_APPLICATION_GEONATURE"] if with_flask_admin: from geonature.core.admin.admin import admin admin.init_app(app) with app.app_context(): if app.config["MAIL_ON_ERROR"] and app.config["MAIL_CONFIG"]: from geonature.utils.logs import mail_handler logging.getLogger().addHandler(mail_handler) from pypnusershub.routes import routes app.register_blueprint(routes, url_prefix="/auth") from pypn_habref_api.routes import routes app.register_blueprint(routes, url_prefix="/habref") from pypnusershub import routes_register app.register_blueprint(routes_register.bp, url_prefix="/pypn/register") from pypnnomenclature.routes import routes app.register_blueprint(routes, url_prefix="/nomenclatures") from geonature.core.gn_permissions.routes import routes app.register_blueprint(routes, url_prefix="/permissions") from geonature.core.gn_permissions.backoffice.views import routes app.register_blueprint(routes, url_prefix="/permissions_backoffice") from geonature.core.routes import routes app.register_blueprint(routes, url_prefix="") from geonature.core.users.routes import routes app.register_blueprint(routes, url_prefix="/users") from geonature.core.gn_synthese.routes import routes app.register_blueprint(routes, url_prefix="/synthese") from geonature.core.gn_meta.routes import routes app.register_blueprint(routes, url_prefix="/meta") from geonature.core.ref_geo.routes import routes app.register_blueprint(routes, url_prefix="/geo") from geonature.core.gn_exports.routes import routes app.register_blueprint(routes, url_prefix="/exports") from geonature.core.auth.routes import routes app.register_blueprint(routes, url_prefix="/gn_auth") from geonature.core.gn_monitoring.routes import routes app.register_blueprint(routes, url_prefix="/gn_monitoring") from geonature.core.gn_commons.routes import routes app.register_blueprint(routes, url_prefix="/gn_commons") # Errors from geonature.core.errors import routes CORS(app, supports_credentials=True) # Emails configuration if app.config["MAIL_CONFIG"]: conf = app.config.copy() conf.update(app.config["MAIL_CONFIG"]) app.config = conf MAIL.init_app(app) app.config['TEMPLATES_AUTO_RELOAD'] = True # disable cache for downloaded files (PDF file stat for ex) app.config['SEND_FILE_MAX_AGE_DEFAULT'] = 0 # Loading third-party modules if with_external_mods: for module, blueprint in import_backend_enabled_modules(): app.config[blueprint.config['MODULE_CODE']] = blueprint.config app.register_blueprint( blueprint, url_prefix=blueprint.config['MODULE_URL']) _app = app return app