details: https://code.tryton.org/tryton/commit/6b38bc7a3ca0
branch: default
user: Cédric Krier <[email protected]>
date: Tue Apr 07 09:35:21 2026 +0200
description:
Use gettext and normalized email for chat messages
diffstat:
modules/inbound_email/ir.py | 9 +---
trytond/trytond/ir/chat.py | 65 ++++++++++++++++++-----------------------
trytond/trytond/ir/message.xml | 4 +-
3 files changed, 34 insertions(+), 44 deletions(-)
diffs (186 lines):
diff -r 794c36840038 -r 6b38bc7a3ca0 modules/inbound_email/ir.py
--- a/modules/inbound_email/ir.py Tue Apr 07 09:36:13 2026 +0200
+++ b/modules/inbound_email/ir.py Tue Apr 07 09:35:21 2026 +0200
@@ -8,7 +8,8 @@
from email.utils import getaddresses
import trytond.config as config
-from trytond.pool import Pool, PoolMeta
+from trytond.i18n import gettext
+from trytond.pool import PoolMeta
from trytond.transaction import Transaction
REPLY_LINE = '\N{EM DASH}' * 80
@@ -70,10 +71,6 @@
@classmethod
def _email_body(cls, message):
- pool = Pool()
- Message = pool.get('ir.message')
- ModelData = pool.get('ir.model.data')
-
with Transaction().set_context(language=message.channel.language):
- above_msg = Message(ModelData.get_id('ir', 'msg_reply_above'))
+ above_msg = gettext('ir.msg_reply_above')
return f'{REPLY_LINE}\n{above_msg.text}\n\n{message.content}'
diff -r 794c36840038 -r 6b38bc7a3ca0 trytond/trytond/ir/chat.py
--- a/trytond/trytond/ir/chat.py Tue Apr 07 09:36:13 2026 +0200
+++ b/trytond/trytond/ir/chat.py Tue Apr 07 09:35:21 2026 +0200
@@ -127,8 +127,6 @@
pool = Pool()
Follower = pool.get('ir.chat.follower')
User = pool.get('res.user')
- Message = pool.get('ir.message')
- ModelData = pool.get('ir.model.data')
if username is not None:
user, = User.search([
@@ -141,16 +139,14 @@
with Transaction().set_context(
language=channel.language, user=0, _notify=False):
- msg = Message(ModelData.get_id('ir', 'msg_chat_follower_joined'))
- cls.post(resource, msg.text % {'name': user.login})
+ msg = gettext('ir.msg_chat_follower_joined', name=user.login)
+ cls.post(resource, msg)
@classmethod
def unsubscribe(cls, resource, username=None):
pool = Pool()
Follower = pool.get('ir.chat.follower')
User = pool.get('res.user')
- Message = pool.get('ir.message')
- ModelData = pool.get('ir.model.data')
if username:
cls.check_access(resource)
@@ -166,8 +162,8 @@
with Transaction().set_context(
language=channel.language, user=0, _notify=False):
- msg = Message(ModelData.get_id('ir', 'msg_chat_follower_left'))
- cls.post(resource, msg.text % {'name': user.login})
+ msg = gettext('ir.msg_chat_follower_left', name=user.login)
+ cls.post(resource, msg)
@classmethod
def subscribe_email(cls, resource, email):
@@ -175,16 +171,15 @@
pool = Pool()
Follower = pool.get('ir.chat.follower')
- Message = pool.get('ir.message')
- ModelData = pool.get('ir.model.data')
channel = cls._get_channel(resource)
- Follower.add_email(channel, email)
+ email = Follower.add_email(channel, email)
- with Transaction().set_context(
- language=channel.language, user=0, _notify=False):
- msg = Message(ModelData.get_id('ir', 'msg_chat_follower_joined'))
- cls.post(resource, msg.text % {'name': email})
+ if email:
+ with Transaction().set_context(
+ language=channel.language, user=0, _notify=False):
+ msg = gettext('ir.msg_chat_follower_joined', name=email)
+ cls.post(resource, msg)
@classmethod
def unsubscribe_email(cls, resource, email):
@@ -192,16 +187,15 @@
pool = Pool()
Follower = pool.get('ir.chat.follower')
- Message = pool.get('ir.message')
- ModelData = pool.get('ir.model.data')
channel = cls._get_channel(resource)
- Follower.remove_email(channel, email)
+ email = Follower.remove_email(channel, email)
- with Transaction().set_context(
- language=channel.language, user=0, _notify=False):
- msg = Message(ModelData.get_id('ir', 'msg_chat_follower_left'))
- cls.post(resource, msg.text % {'name': email})
+ if email:
+ with Transaction().set_context(
+ language=channel.language, user=0, _notify=False):
+ msg = gettext('ir.msg_chat_follower_left', name=email)
+ cls.post(resource, msg)
@classmethod
def _get_followers(cls, resource):
@@ -333,10 +327,6 @@
@classmethod
def dispatch_message(cls, message, is_sender):
- pool = Pool()
- Message = pool.get('ir.message')
- ModelData = pool.get('ir.model.data')
-
Bus.publish(
f'chat:{str(message.channel.resource)}', {
'type': 'message',
@@ -357,8 +347,10 @@
if to_email:
with Transaction().set_context(language=message.channel.language):
- subject_msg = Message(ModelData.get_id('ir', 'msg_subject'))
- subject = subject_msg.text
+ subject = gettext(
+ 'ir.msg_chat_subject',
+ author=message.author,
+ channel=message.channel.rec_name)
from_ = cls._email_from(message)
domain = host()
@@ -373,10 +365,7 @@
f'channel-{message.channel.id}@{domain}'),
'utf-8')
msg['Message-ID'] = message.reference = make_msgid(domain=domain)
- msg['Subject'] = subject % {
- 'author': message.author,
- 'resource': message.channel.resource.rec_name,
- }
+ msg['Subject'] = subject
msg.set_content(cls._email_body(message))
send_message_transactional(msg)
@@ -510,14 +499,18 @@
('email', '=', email),
]):
cls(channel=channel, email=email).save()
+ return email
@classmethod
def remove_email(cls, channel, email):
email = normalize_email(email)
- cls.delete(cls.search([
- ('channel', '=', channel),
- ('email', '=', email),
- ]))
+ found = cls.search([
+ ('channel', '=', channel),
+ ('email', '=', email),
+ ])
+ if found:
+ cls.delete(found)
+ return email
def notify(self, message):
pool = Pool()
diff -r 794c36840038 -r 6b38bc7a3ca0 trytond/trytond/ir/message.xml
--- a/trytond/trytond/ir/message.xml Tue Apr 07 09:36:13 2026 +0200
+++ b/trytond/trytond/ir/message.xml Tue Apr 07 09:35:21 2026 +0200
@@ -487,8 +487,8 @@
<record model="ir.message" id="msg_chat_follower_left">
<field name="text">"%(name)s" left</field>
</record>
- <record model="ir.message" id="msg_subject">
- <field name="text">%(resource)s: %(author)s left a message</field>
+ <record model="ir.message" id="msg_chat_subject">
+ <field name="text">%(channel)s: %(author)s left a message</field>
</record>
<record model="ir.message" id="msg_chat_user_or_email">
<field name="text">Only user or email can be filled.</field>