diff --git a/packages/dsw-database/dsw/database/database.py b/packages/dsw-database/dsw/database/database.py index 01f44633..39a3a3e9 100644 --- a/packages/dsw-database/dsw/database/database.py +++ b/packages/dsw-database/dsw/database/database.py @@ -88,7 +88,7 @@ class Database: ' enabled is TRUE AND ' ' tenant_uuid = %(tenant_uuid)s;') SELECT_LOCALE = ('SELECT * FROM locale ' - 'WHERE id = %(locale_id)s AND tenant_uuid = %(tenant_uuid)s;') + 'WHERE uuid = %(locale_uuid)s AND tenant_uuid = %(tenant_uuid)s;') def __init__(self, cfg: DatabaseConfig, connect: bool = True, with_queue: bool = True): @@ -481,14 +481,14 @@ def get_default_locale(self, tenant_uuid: str) -> DBLocale | None: before=tenacity.before_log(LOG, logging.DEBUG), after=tenacity.after_log(LOG, logging.DEBUG), ) - def get_locale(self, locale_id: str, tenant_uuid: str) -> DBLocale | None: + def get_locale(self, locale_uuid: str, tenant_uuid: str) -> DBLocale | None: if not self._check_table_exists(table_name='locale'): return None with self.conn_query.new_cursor(use_dict=True) as cursor: try: cursor.execute( query=self.SELECT_LOCALE, - params={'locale_id': locale_id, 'tenant_uuid': tenant_uuid}, + params={'locale_uuid': locale_uuid, 'tenant_uuid': tenant_uuid}, ) result = cursor.fetchone() if result is None: @@ -496,7 +496,7 @@ def get_locale(self, locale_id: str, tenant_uuid: str) -> DBLocale | None: return DBLocale.from_dict_row(data=result) except Exception as e: LOG.warning('Could not retrieve locale "%s" for tenant "%s": %s', - locale_id, tenant_uuid, str(e)) + locale_uuid, tenant_uuid, str(e)) return None @tenacity.retry( diff --git a/packages/dsw-database/dsw/database/model.py b/packages/dsw-database/dsw/database/model.py index 736d941c..36355224 100644 --- a/packages/dsw-database/dsw/database/model.py +++ b/packages/dsw-database/dsw/database/model.py @@ -408,7 +408,10 @@ def from_dict_row(data: dict): class DBLocale: TABLE_NAME = 'locale' - id: str + uuid: str + organization_id: str + locale_id: str + version: str name: str code: str default_locale: bool @@ -417,13 +420,20 @@ class DBLocale: @staticmethod def from_dict_row(data: dict): return DBLocale( - id=str(data['id']), + uuid=str(data['uuid']), + organization_id=data['organization_id'], + locale_id=data['locale_id'], + version=data['version'], name=data['name'], code=data['code'], default_locale=data['default_locale'], enabled=data['enabled'], ) + @property + def id(self) -> str: + return f'{self.organization_id}:{self.locale_id}:{self.version}' + @dataclasses.dataclass class DBInstanceConfigMail: diff --git a/packages/dsw-mailer/dsw/mailer/mailer.py b/packages/dsw-mailer/dsw/mailer/mailer.py index 28a780c6..b36f11a6 100644 --- a/packages/dsw-mailer/dsw/mailer/mailer.py +++ b/packages/dsw-mailer/dsw/mailer/mailer.py @@ -94,7 +94,7 @@ def run_once(self): queue = self._run_preparation() queue.run_once() - def _get_locale_id(self, recipient_uuid: str, tenant_uuid: str) -> str | None: + def _get_locale_uuid(self, recipient_uuid: str, tenant_uuid: str) -> str | None: app_ctx = Context.get().app user = app_ctx.db.get_user( user_uuid=recipient_uuid, @@ -116,13 +116,13 @@ def _get_msg_request(self, command: PersistentCommand) -> MessageRequest: if len(mc.recipients) == 0: raise RuntimeError('No recipients specified') first_recipient = mc.recipients[0] - locale_id = None + locale_uuid = None if first_recipient.uuid is not None: - locale_id = self._get_locale_id(first_recipient.uuid, command.tenant_uuid) + locale_uuid = self._get_locale_uuid(first_recipient.uuid, command.tenant_uuid) return mc.to_request( msg_id=command.uuid, trigger='PersistentComment', - locale_id=locale_id, + locale_uuid=locale_uuid, ) def _get_mail_config(self, command: PersistentCommand) -> MailConfig: @@ -180,7 +180,7 @@ def send(self, rq: MessageRequest, cfg: MailConfig): raise RuntimeError(f'Template not found: {rq.template_name}') # render LOG.info('Rendering message: %s', rq.template_name) - LOG.warning('Should send with locale: %s', rq.locale_id) + LOG.warning('Should send with locale: %s', rq.locale_uuid) msg = self.ctx.templates.render(rq, cfg, Context.get().app) # send LOG.info('Sending message: %s', rq.template_name) @@ -225,12 +225,12 @@ def __init__(self, *, recipients: list[MessageRecipient], mode: str, self.cmd_uuid = cmd_uuid self._enrich_context() - def to_request(self, msg_id: str, locale_id: str | None, trigger: str) -> MessageRequest: + def to_request(self, msg_id: str, locale_uuid: str | None, trigger: str) -> MessageRequest: rq = MessageRequest( message_id=msg_id, template_name=f'{self.mode}:{self.template}', tenant_uuid=self.tenant_uuid, - locale_id=locale_id, + locale_uuid=locale_uuid, trigger=trigger, ctx=self.ctx, recipients=self.recipients, diff --git a/packages/dsw-mailer/dsw/mailer/model.py b/packages/dsw-mailer/dsw/mailer/model.py index 7838efca..b5470b6b 100644 --- a/packages/dsw-mailer/dsw/mailer/model.py +++ b/packages/dsw-mailer/dsw/mailer/model.py @@ -203,13 +203,13 @@ def from_dict(cls, data: dict): class MessageRequest: - def __init__(self, *, message_id: str, locale_id: str | None, template_name: str, + def __init__(self, *, message_id: str, locale_uuid: str | None, template_name: str, trigger: str, ctx: dict, recipients: list[MessageRecipient], tenant_uuid: str, style: StyleConfig | None = None): self.id = message_id self.template_name = template_name self.tenant_uuid = tenant_uuid - self.locale_id = locale_id + self.locale_uuid = locale_uuid self.trigger = trigger self.ctx = ctx self.recipients = recipients @@ -228,7 +228,7 @@ def load_from_file(data: dict) -> 'MessageRequest': message_id=data['id'], template_name=data['type'], tenant_uuid=data['tenantUuid'], - locale_id=data['localeId'], + locale_uuid=data['localeUuid'], trigger=data.get('trigger', 'input_file'), ctx=data.get('ctx', {}), recipients=data.get('recipients', []), diff --git a/packages/dsw-mailer/dsw/mailer/templates.py b/packages/dsw-mailer/dsw/mailer/templates.py index 646899d0..501d944a 100644 --- a/packages/dsw-mailer/dsw/mailer/templates.py +++ b/packages/dsw-mailer/dsw/mailer/templates.py @@ -201,25 +201,26 @@ def _install_translations(self, translations: gettext.GNUTranslations): # pylint: disable-next=no-member self.j2_env.install_gettext_translations(translations) - def _load_locale(self, tenant_uuid: str, locale_id: str | None, app_ctx, + def _load_locale(self, tenant_uuid: str, locale_uuid: str | None, app_ctx, locale_root_dir: pathlib.Path): - LOG.info('Loading locale: %s (for tenant %s)', locale_id, tenant_uuid) + LOG.info('Loading locale: %s (for tenant %s)', locale_uuid, tenant_uuid) self._uninstall_translations() - if locale_id is None: + if locale_uuid is None: LOG.info('No locale specified - using null translations') self._install_null_translations() - elif locale_id == self.DEFAULT_LOCALE: - LOG.info('Default locale - using null translations') - self._install_null_translations() else: # fetch locale from DB locale = app_ctx.db.get_locale( tenant_uuid=tenant_uuid, - locale_id=locale_id, + locale_uuid=locale_uuid, ) + if locale.id == self.DEFAULT_LOCALE: + LOG.info('Locale is default locale - using null translations') + self._install_null_translations() + return if locale is None: LOG.error('Could not find locale for tenant %s', tenant_uuid) - raise RuntimeError(f'Locale not found in DB: {locale_id}') + raise RuntimeError(f'Locale not found in DB: {locale_uuid}') # fetch locale from S3 locale_dir = locale_root_dir / locale.code / 'LC_MESSAGES' locale_dir.mkdir(parents=True, exist_ok=True) @@ -227,14 +228,14 @@ def _load_locale(self, tenant_uuid: str, locale_id: str | None, app_ctx, locale_mo_path = locale_dir / 'default.mo' downloaded = app_ctx.s3.download_locale( tenant_uuid=tenant_uuid, - locale_id=locale_id, + locale_uuid=locale_uuid, file_name='mail.po', target_path=locale_po_path, ) if not downloaded: LOG.error('Cannot download locale file (mail.po) from %s to %s', - locale_id, locale_po_path) - raise RuntimeError(f'Failed to download locale file (mail.po) from {locale_id}') + locale_uuid, locale_po_path) + raise RuntimeError(f'Failed to download locale file (mail.po) from {locale_uuid}') LOG.debug('Saved PO file to %s', locale_po_path) # convert po to mo po = polib.pofile(locale_po_path.absolute().as_posix()) @@ -256,7 +257,7 @@ def render(self, rq: MessageRequest, cfg: MailConfig, app_ctx) -> MailMessage: with tempfile.TemporaryDirectory() as tmpdir: try: locale_root_dir = pathlib.Path(tmpdir) / 'locale' - self._load_locale(rq.tenant_uuid, rq.locale_id, app_ctx, locale_root_dir) + self._load_locale(rq.tenant_uuid, rq.locale_uuid, app_ctx, locale_root_dir) except Exception as e: LOG.warning('Cannot load locale for tenant %s: %s', rq.tenant_uuid, str(e)) LOG.warning('Rendering without locale') diff --git a/packages/dsw-storage/dsw/storage/s3storage.py b/packages/dsw-storage/dsw/storage/s3storage.py index 5c518322..4fe3924e 100644 --- a/packages/dsw-storage/dsw/storage/s3storage.py +++ b/packages/dsw-storage/dsw/storage/s3storage.py @@ -121,11 +121,11 @@ def download_template_asset(self, *, tenant_uuid: str, template_id: str, before=tenacity.before_log(LOG, logging.DEBUG), after=tenacity.after_log(LOG, logging.DEBUG), ) - def download_locale(self, *, tenant_uuid: str, locale_id: str, + def download_locale(self, *, tenant_uuid: str, locale_uuid: str, file_name: str, target_path: pathlib.Path) -> bool: return self._download_file( tenant_uuid=tenant_uuid, - file_name=f'locales/{locale_id}/{file_name}', + file_name=f'locales/{locale_uuid}/{file_name}', target_path=target_path, )