def store_public_object(bucket: str, object_id: str, blob: bytes, content_type: str, symlink_path=None) -> None: for backend_path in _get_backends(): backend = import_string(backend_path) backend().store_public_object(bucket, object_id, blob, content_type, symlink_path)
def send(*, recipients: Iterable[str], data: dict) -> bool: """Try to send an e-mail and return whether it was successful.""" if isinstance(recipients, str): if settings.IS_RUNNING_TESTS: raise ValueError("Recipients should be a sequence, not a single string.") recipients = [recipients] backend = import_string(settings.EMAIL_BACKEND) result = backend().send_mail(recipients=recipients, data=data) _save_email(result) return result.successful
def delete_assets_tied_to_mediationsqlentities( backend_name: str = "local", dry_run: bool = True, container_name: Optional[str] = None, folder_name: str = "thumbs", marker: str = "thumbs/mediations", end_marker: str = "thumbs/mf", full_listing: bool = True, ) -> None: backend_path = BACKENDS_MAPPING[backend_name] if backend_name in ("OVH", "local"): backend = import_string(backend_path) else: raise ImportError("backend must be 'OVH' or 'local'") if dry_run: logger.info("This a dry run; if you are sure about the changes, call this function with dry_run=False") db.session.commit() old_mediationsqlentities_asset_names = set() # get_container() returns a tuple of (dict of headers, list(dict of asset properties)) mediation_assets = backend().get_container( container_name=container_name, marker=marker, end_marker=end_marker, full_listing=full_listing, )[1] for mediation_asset in mediation_assets: asset_name = mediation_asset["name"] if backend_name == "local" and asset_name.endswith(".type"): continue if asset_name.startswith(f"{folder_name}/mediationsqlentities/"): old_mediationsqlentities_asset_names.add(asset_name.replace(f"{folder_name}/", "")) # MediationSQLEntities assets logger.info( "%d assets that are related to a former MediationSQLEntity are about to be deleted", len(old_mediationsqlentities_asset_names), ) if dry_run: pass else: for asset_name in old_mediationsqlentities_asset_names: logger.info("deleting asset: %s", asset_name) try: backend().delete_public_object(bucket=folder_name, object_id=asset_name) except Exception as exc: # pylint: disable=broad-except logger.exception("An unexpected error was encountered during deletion: %s", exc)
def send(*, recipients: Iterable[str], data: Union[dict, SendinblueTransactionalEmailData], send_with_sendinblue=False) -> bool: """Try to send an e-mail and return whether it was successful.""" if isinstance(recipients, str): if settings.IS_RUNNING_TESTS: raise ValueError( "Recipients should be a sequence, not a single string.") recipients = [recipients] backend = import_string(get_email_backend(send_with_sendinblue)) result = backend().send_mail(recipients=recipients, data=data) _save_email(result) return result.successful
def send_transactional_sms(recipient: str, content: str) -> bool: backend = import_string(settings.SMS_NOTIFICATION_BACKEND) return backend().send_transactional_sms(recipient, content)
def _get_backend(self, path_str): return import_string(path_str)
def update_user_attributes(user_id: int, attribute_values: dict) -> None: backend = import_string(settings.PUSH_NOTIFICATION_BACKEND) backend().update_user_attributes(user_id, attribute_values)
def create_contact(email: str) -> Response: backend = import_string(settings.EMAIL_BACKEND) return backend().create_contact(email)
def add_contact_to_list(email: str, list_id: str) -> Response: backend = import_string(get_email_backend(False)) return backend().add_contact_to_list(email, list_id)
def update_user_attributes_with_legacy_internal_task(user_id: int, attribute_values: dict) -> None: backend = import_string(settings.PUSH_NOTIFICATION_BACKEND) if backend == BatchBackend: backend().update_user_attributes_with_legacy_internal_task(user_id, attribute_values) else: update_user_attributes(user_id, attribute_values)
def delete_mediations_without_uploaded_assets( backend_name: str = "local", dry_run: bool = True, container_name: Optional[str] = None, folder_name: str = "thumbs", marker: str = "thumbs/mediations", end_marker: str = "thumbs/mf", full_listing: bool = True, ) -> None: backend_path = BACKENDS_MAPPING[backend_name] if backend_name in ("OVH", "local"): backend = import_string(backend_path) else: raise ImportError("backend must be 'OVH' or 'local'") if dry_run: logger.info("This a dry run; if you are sure about the changes, call this function with dry_run=False") db.session.commit() current_mediation_asset_ids = set() # get_container() returns a tuple of (dict of headers, list(dict of asset properties)) mediation_assets = backend().get_container( container_name=container_name, marker=marker, end_marker=end_marker, full_listing=full_listing, )[1] for mediation_asset in mediation_assets: asset_name = mediation_asset["name"] if backend_name == "local" and asset_name.endswith(".type"): continue if asset_name.startswith(f"{folder_name}/mediations/"): asset_name = asset_name.replace(f"{folder_name}/mediations/", "") if "_" in asset_name: continue try: mediation_id = dehumanize(asset_name) except Exception as exc: # pylint: disable=broad-except logger.warning(exc) current_mediation_asset_ids.add(mediation_id) # create a set of Mediation IDs out of the list of tuples returned by the query current_mediation_ids = set((mediation_id for mediation_id, in Mediation.query.with_entities(Mediation.id).all())) # Mediations without assets orphan_mediation_ids = current_mediation_ids - current_mediation_asset_ids logger.info("There are %d Mediations without assets", len(orphan_mediation_ids)) favorites_to_update = set(Favorite.query.filter(Favorite.mediationId.in_(orphan_mediation_ids)).all()) _update_favorites_mediations(favorites_to_update) deleted_mediations_without_assets = Mediation.query.filter(Mediation.id.in_(orphan_mediation_ids)).delete( synchronize_session="fetch" ) logger.info( "%d Mediations without assets are about to be deleted", deleted_mediations_without_assets, ) if dry_run: db.session.rollback() else: db.session.commit()
def delete_assets_without_mediation( backend_name: str = "local", dry_run: bool = True, container_name: Optional[str] = None, folder_name: str = "thumbs", marker: str = "thumbs/mediations", end_marker: str = "thumbs/mf", full_listing: bool = True, ) -> None: backend_path = BACKENDS_MAPPING[backend_name] if backend_name in ("OVH", "local"): backend = import_string(backend_path) else: raise ImportError("backend must be 'OVH' or 'local'") if dry_run: logger.info("This a dry run; if you are sure about the changes, call this function with dry_run=False") db.session.commit() current_mediation_asset_ids = set() # get_container() returns a tuple of (dict of headers, list(dict of asset properties)) mediation_assets = backend().get_container( container_name=container_name, marker=marker, end_marker=end_marker, full_listing=full_listing, )[1] for mediation_asset in mediation_assets: asset_name = mediation_asset["name"] if backend_name == "local" and asset_name.endswith(".type"): continue if asset_name.startswith(f"{folder_name}/mediations/"): asset_name = asset_name.replace(f"{folder_name}/mediations/", "") if "_" in asset_name: continue mediation_id = dehumanize(asset_name) current_mediation_asset_ids.add(mediation_id) # create a set of Mediation IDs out of the list of tuples returned by the query current_mediation_ids = set((mediation_id for mediation_id, in Mediation.query.with_entities(Mediation.id).all())) # Assets without mediations orphan_asset_mediation_ids = current_mediation_asset_ids - current_mediation_ids orphan_assets_names = set() for numerical_id in orphan_asset_mediation_ids: human_id = humanize(numerical_id) orphan_assets_names.add(f"mediations/{human_id}") logger.info( "%d assets that are not related to a Mediation are about to be deleted", len(orphan_asset_mediation_ids), ) if dry_run: pass else: for orphan_assets_name in orphan_assets_names: logger.info("deleting asset: %s", orphan_assets_name) try: backend().delete_public_object(bucket=folder_name, object_id=orphan_assets_name) except Exception as exc: # pylint: disable=broad-except logger.exception("An unexpected error was encountered during deletion: %s", exc)
def get_application_by_id(application_id: int) -> BeneficiaryPreSubscription: backend = import_string(settings.JOUVE_APPLICATION_BACKEND) return backend().get_application_by(application_id)
def add_contact_to_list(email: str, list_id: str) -> Response: backend = import_string(settings.EMAIL_BACKEND) return backend().add_contact_to_list(email, list_id)
def update_contact(email: str, *, birth_date: date, department: str) -> Response: backend = import_string(settings.EMAIL_BACKEND) return backend().update_contact(email, birth_date=birth_date, department=department)
def create_contact(email: str) -> Response: backend = import_string(get_email_backend(False)) return backend().create_contact(email)
def update_contact(email: str, *, birth_date: date, department: str) -> Response: backend = import_string(get_email_backend(False)) return backend().update_contact(email, birth_date=birth_date, department=department)
def update_users_attributes(users_data: list[UserUpdateData]) -> None: backend = import_string(settings.PUSH_NOTIFICATION_BACKEND) backend().update_users_attributes(users_data)
def _check_backends_module_paths() -> None: """When the app starts, this checks if the module paths are correct""" for path in BACKENDS_MAPPING.values(): import_string(path)
def send_transactional_notification(notification_data: TransactionalNotificationData) -> None: backend = import_string(settings.PUSH_NOTIFICATION_BACKEND) backend().send_transactional_notification(notification_data)
def delete_public_object(bucket: str, object_id: str) -> None: for backend_path in _get_backends(): backend = import_string(backend_path) backend().delete_public_object(bucket, object_id)
def delete_user_attributes(user_id: int) -> None: backend = import_string(settings.PUSH_NOTIFICATION_BACKEND) backend().delete_user_attributes(user_id)