from dataclasses import dataclass, replace from typing import ClassVar from fansifter_common.adapters.ows_account import OwsAccountClient from fansifter_common.adapters.ows_users import OwsUsersClient from fansifter_common.adapters.sendgrid import SendGridClient from fansifter_common.auth.requests import AuthRequest from fansifter_common.auth.services import AuthService from fansifter_common.auth.types import Permission from fansifter_common.legal_info.services import LegalInfoService from fansifter_common.translation.services import TranslationService from email_campaigns.adapters.db import Repository from email_campaigns.emails.exceptions import EmailNotFoundError from email_campaigns.emails.models import BaseEmail from email_campaigns.emails.substitutions import apply_preview_substitutions from email_campaigns.emails.types import EmailPreview from email_campaigns.fonts.services.google_fonts import GoogleFontsService @dataclass(kw_only=True) class GetEmailPreviewRequest(AuthRequest): email_id: str apply_substitutions: bool = False with_unapplied_changes: bool = False class GetEmailPreviewHandler[T: BaseEmail]: permission: ClassVar[Permission] def __init__( self, auth_service: AuthService, email_repository: Repository[T], sendgrid_client: SendGridClient, legal_info_service: LegalInfoService, translation_service: TranslationService, ows_account_client: OwsAccountClient, ows_users_client: OwsUsersClient, fonts_service: GoogleFontsService, ) -> None: self.auth_service = auth_service self.email_repository = email_repository self.sendgrid_client = sendgrid_client self.legal_info_service = legal_info_service self.translation_service = translation_service self.ows_account_client = ows_account_client self.ows_users_client = ows_users_client self.fonts_service = fonts_service def handle(self, request: GetEmailPreviewRequest) -> EmailPreview: email = self.email_repository.get(request.email_id) if email is None: raise EmailNotFoundError self.auth_service.authorize_account( request.identity_id, account=email.account, permission=self.permission, ) preview = replace( email.preview, favorite_fonts=self.fonts_service.get_favorite_fonts_for_email(email), ) return self.apply_substitutions(preview, email=email, request=request) def apply_substitutions( self, preview: EmailPreview, *, email: T, request: GetEmailPreviewRequest ) -> EmailPreview: if not request.apply_substitutions or preview.html is None: return preview identity = self.ows_users_client.get_identity(request.identity_id) return replace( preview, html=apply_preview_substitutions( preview.html, email=email, user_email=identity.email, sendgrid_client=self.sendgrid_client, legal_info_service=self.legal_info_service, translation_service=self.translation_service, ows_account_client=self.ows_account_client, ), )