Merge lp:~futatuki/mailman/i18n-add-whence-to-adminack-templates into lp:mailman/2.1

Proposed by Yasuhito FUTATSUKI at POEM
Status: Merged
Merged at revision: 1776
Proposed branch: lp:~futatuki/mailman/i18n-add-whence-to-adminack-templates
Merge into: lp:mailman/2.1
Diff against target: 200 lines (+25/-14)
7 files modified
Mailman/Bouncer.py (+2/-1)
Mailman/Cgi/admin.py (+5/-3)
Mailman/Cgi/options.py (+2/-1)
Mailman/ListAdmin.py (+3/-1)
Mailman/MailList.py (+8/-6)
Mailman/i18n.py (+4/-1)
messages/Makefile.in (+1/-1)
To merge this branch: bzr merge lp:~futatuki/mailman/i18n-add-whence-to-adminack-templates
Reviewer Review Type Date Requested Status
Mark Sapiro Approve
Review via email: mp+348127@code.launchpad.net

Commit message

i18nize whence candidate message strings

Description of the change

This is a solution of problem left in mp+347992.

To mark whence messages for pygettext, I introduced dummy function i18n.D_(s) returns s it self, and then added "-k D_" option to pygettext commandline in messages/Makefile.in.
This costs extra function call on execute, for its maintenancebility.

I've picked up whence candidate message strings except from bin/add_member, bin/delete_member, and cron/disabled, and tested with ja translation (temporary for test, not included in this proposal).

Note:
* whence messages for user conformation of subscribe and unsubscribe are inconsistent. For subscribe they are 'via email confirmation' and 'via web confirmation', but for unsubscribe they are 'email confirmation' and 'web confirmation'.
* admin approval for unsubscription dosen't report whence because ListAdmin.__handleunsubscription() calls ApproveDeleteMember() without whence option.

To post a comment you must log in.
Revision history for this message
Mark Sapiro (msapiro) wrote :

I'm going to merge this although somewhat differently. I like what you have done and it is conceptually similar to what we do in Mailman 3. There, we have augmented i18n._ with a context manager to not do the translation and then we can do things like:

    with _.defer_translation():
        # This will be translated at the point of use.
        msgdata.setdefault('moderation_reasons', []).append(
            _('Message contains administrivia'))

to mark messages without translating them. However, there are already many places in Mailman 2.1 where we accomplish a similar thing by doing things like:

    def _(s):
        return s

    _('string to translate later')

    _ = i18n._

In fact, for example, in Mailman/Bouncer.py we already have

def _(s): return s

REASONS = {MemberAdaptor.BYBOUNCE: _('due to excessive bounces'),
           MemberAdaptor.BYUSER: _('by yourself'),
           MemberAdaptor.BYADMIN: _('by the list administrator'),
           MemberAdaptor.UNKNOWN: _('for unknown reasons'),
           }

_ = i18n._

To to be more consistent with what is done elsewhere in the code, rather than defining D_() in i18n, I'll define it in the places it's needed and then just do things like

    _ = D_

    _('string to translate later')

    _ = i18n._

Your way is actually better, but in this case, I think it's more important to maintain consistency

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'Mailman/Bouncer.py'
--- Mailman/Bouncer.py 2017-06-02 22:25:12 +0000
+++ Mailman/Bouncer.py 2018-06-17 13:04:43 +0000
@@ -49,6 +49,7 @@
49 }49 }
5050
51_ = i18n._51_ = i18n._
52D_ = i18n.D_
5253
5354
5455
5556
@@ -265,7 +266,7 @@
265 if info.noticesleft <= 0:266 if info.noticesleft <= 0:
266 # BAW: Remove them now, with a notification message267 # BAW: Remove them now, with a notification message
267 self.ApprovedDeleteMember(268 self.ApprovedDeleteMember(
268 member, 'disabled address',269 member, D_('disabled address'),
269 admin_notif=self.bounce_notify_owner_on_removal,270 admin_notif=self.bounce_notify_owner_on_removal,
270 userack=1)271 userack=1)
271 # Expunge the pending cookie for the user. We throw away the272 # Expunge the pending cookie for the user. We throw away the
272273
=== modified file 'Mailman/Cgi/admin.py'
--- Mailman/Cgi/admin.py 2018-06-11 16:59:26 +0000
+++ Mailman/Cgi/admin.py 2018-06-17 13:04:43 +0000
@@ -47,6 +47,7 @@
47# Set up i18n47# Set up i18n
48_ = i18n._48_ = i18n._
49i18n.set_language(mm_cfg.DEFAULT_SERVER_LANGUAGE)49i18n.set_language(mm_cfg.DEFAULT_SERVER_LANGUAGE)
50D_ = i18n.D_
5051
51NL = '\n'52NL = '\n'
52OPTCOLUMNS = 1153OPTCOLUMNS = 11
@@ -1484,7 +1485,7 @@
1484 else:1485 else:
1485 mlist.ApprovedAddMember(userdesc, send_welcome_msg,1486 mlist.ApprovedAddMember(userdesc, send_welcome_msg,
1486 send_admin_notif, invitation,1487 send_admin_notif, invitation,
1487 whence='admin mass sub')1488 whence=D_('admin mass sub'))
1488 except Errors.MMAlreadyAMember:1489 except Errors.MMAlreadyAMember:
1489 subscribe_errors.append((safeentry, _('Already a member')))1490 subscribe_errors.append((safeentry, _('Already a member')))
1490 except Errors.MMBadEmailError:1491 except Errors.MMBadEmailError:
@@ -1538,7 +1539,7 @@
1538 for addr in names:1539 for addr in names:
1539 try:1540 try:
1540 mlist.ApprovedDeleteMember(1541 mlist.ApprovedDeleteMember(
1541 addr, whence='admin mass unsub',1542 addr, whence=D_('admin mass unsub'),
1542 admin_notif=send_unsub_notifications,1543 admin_notif=send_unsub_notifications,
1543 userack=userack)1544 userack=userack)
1544 unsubscribe_success.append(Utils.websafe(addr))1545 unsubscribe_success.append(Utils.websafe(addr))
@@ -1645,7 +1646,8 @@
1645 quser = urllib.quote(user)1646 quser = urllib.quote(user)
1646 if cgidata.has_key('%s_unsub' % quser):1647 if cgidata.has_key('%s_unsub' % quser):
1647 try:1648 try:
1648 mlist.ApprovedDeleteMember(user, whence='member mgt page')1649 mlist.ApprovedDeleteMember(user,
1650 whence=D_('member mgt page'))
1649 removes.append(user)1651 removes.append(user)
1650 except Errors.NotAMemberError:1652 except Errors.NotAMemberError:
1651 errors.append((user, _('Not subscribed')))1653 errors.append((user, _('Not subscribed')))
16521654
=== modified file 'Mailman/Cgi/options.py'
--- Mailman/Cgi/options.py 2018-06-11 16:59:26 +0000
+++ Mailman/Cgi/options.py 2018-06-17 13:04:43 +0000
@@ -45,6 +45,7 @@
45# Set up i18n45# Set up i18n
46_ = i18n._46_ = i18n._
47i18n.set_language(mm_cfg.DEFAULT_SERVER_LANGUAGE)47i18n.set_language(mm_cfg.DEFAULT_SERVER_LANGUAGE)
48D_ = i18n.D_
4849
49try:50try:
50 True, False51 True, False
@@ -583,7 +584,7 @@
583 try:584 try:
584 try:585 try:
585 mlist.DeleteMember(586 mlist.DeleteMember(
586 user, 'via the member options page', userack=1)587 user, D_('via the member options page'), userack=1)
587 except Errors.MMNeedApproval:588 except Errors.MMNeedApproval:
588 needapproval = True589 needapproval = True
589 except Errors.NotAMemberError:590 except Errors.NotAMemberError:
590591
=== modified file 'Mailman/ListAdmin.py'
--- Mailman/ListAdmin.py 2017-06-02 22:25:12 +0000
+++ Mailman/ListAdmin.py 2018-06-17 13:04:43 +0000
@@ -45,6 +45,7 @@
45from Mailman import i18n45from Mailman import i18n
4646
47_ = i18n._47_ = i18n._
48D_ = i18n.D_
4849
49# Request types requiring admin approval50# Request types requiring admin approval
50IGN = 051IGN = 0
@@ -436,7 +437,8 @@
436 assert value == mm_cfg.SUBSCRIBE437 assert value == mm_cfg.SUBSCRIBE
437 try:438 try:
438 userdesc = UserDesc(addr, fullname, password, digest, lang)439 userdesc = UserDesc(addr, fullname, password, digest, lang)
439 self.ApprovedAddMember(userdesc, whence='via admin approval')440 self.ApprovedAddMember(userdesc,
441 whence=D_('via admin approval'))
440 except Errors.MMAlreadyAMember:442 except Errors.MMAlreadyAMember:
441 # User has already been subscribed, after sending the request443 # User has already been subscribed, after sending the request
442 pass444 pass
443445
=== modified file 'Mailman/MailList.py'
--- Mailman/MailList.py 2018-06-16 16:39:45 +0000
+++ Mailman/MailList.py 2018-06-17 13:04:43 +0000
@@ -72,6 +72,7 @@
72from Mailman.Logging.Syslog import syslog72from Mailman.Logging.Syslog import syslog
7373
74_ = i18n._74_ = i18n._
75D_ = i18n.D_
7576
76EMPTYSTRING = ''77EMPTYSTRING = ''
77OR = '|'78OR = '|'
@@ -1071,6 +1072,7 @@
1071 otrans = i18n.get_translation()1072 otrans = i18n.get_translation()
1072 i18n.set_language(lang)1073 i18n.set_language(lang)
1073 try:1074 try:
1075 whence = "" if whence is None else "(" + _(whence) + ")"
1074 realname = self.real_name1076 realname = self.real_name
1075 subject = _('%(realname)s subscription notification')1077 subject = _('%(realname)s subscription notification')
1076 finally:1078 finally:
@@ -1081,7 +1083,7 @@
1081 "adminsubscribeack.txt",1083 "adminsubscribeack.txt",
1082 {"listname" : realname,1084 {"listname" : realname,
1083 "member" : formataddr((name, email)),1085 "member" : formataddr((name, email)),
1084 "whence" : "" if whence is None else "(" + whence + ")"1086 "whence" : whence
1085 }, mlist=self)1087 }, mlist=self)
1086 msg = Message.OwnerNotification(self, subject, text)1088 msg = Message.OwnerNotification(self, subject, text)
1087 msg.send(self)1089 msg.send(self)
@@ -1118,7 +1120,7 @@
1118 'adminunsubscribeack.txt',1120 'adminunsubscribeack.txt',
1119 {'member' : name,1121 {'member' : name,
1120 'listname': self.real_name,1122 'listname': self.real_name,
1121 "whence" : "" if whence is None else "(" + whence + ")"1123 "whence" : "" if whence is None else "(" + _(whence) + ")"
1122 }, mlist=self)1124 }, mlist=self)
1123 msg = Message.OwnerNotification(self, subject, text)1125 msg = Message.OwnerNotification(self, subject, text)
1124 msg.send(self)1126 msg.send(self)
@@ -1307,7 +1309,7 @@
1307 except ValueError:1309 except ValueError:
1308 raise Errors.MMBadConfirmation, 'op-less data %s' % (rec,)1310 raise Errors.MMBadConfirmation, 'op-less data %s' % (rec,)
1309 if op == Pending.SUBSCRIPTION:1311 if op == Pending.SUBSCRIPTION:
1310 whence = 'via email confirmation'1312 whence = D_('via email confirmation')
1311 try:1313 try:
1312 userdesc = data[0]1314 userdesc = data[0]
1313 # If confirmation comes from the web, context should be a1315 # If confirmation comes from the web, context should be a
@@ -1316,7 +1318,7 @@
1316 # context is a Message and isn't relevant, so ignore it.1318 # context is a Message and isn't relevant, so ignore it.
1317 if isinstance(context, UserDesc):1319 if isinstance(context, UserDesc):
1318 userdesc += context1320 userdesc += context
1319 whence = 'via web confirmation'1321 whence = D_('via web confirmation')
1320 addr = userdesc.address1322 addr = userdesc.address
1321 fullname = userdesc.fullname1323 fullname = userdesc.fullname
1322 password = userdesc.password1324 password = userdesc.password
@@ -1348,9 +1350,9 @@
1348 addr = data[0]1350 addr = data[0]
1349 # Log file messages don't need to be i18n'd1351 # Log file messages don't need to be i18n'd
1350 if isinstance(context, Message.Message):1352 if isinstance(context, Message.Message):
1351 whence = 'email confirmation'1353 whence = D_('email confirmation')
1352 else:1354 else:
1353 whence = 'web confirmation'1355 whence = D_('web confirmation')
1354 # Can raise NotAMemberError if they unsub'd via other means1356 # Can raise NotAMemberError if they unsub'd via other means
1355 self.ApprovedDeleteMember(addr, whence=whence)1357 self.ApprovedDeleteMember(addr, whence=whence)
1356 return op, addr1358 return op, addr
13571359
=== modified file 'Mailman/i18n.py'
--- Mailman/i18n.py 2017-01-18 06:49:29 +0000
+++ Mailman/i18n.py 2018-06-17 13:04:43 +0000
@@ -123,7 +123,10 @@
123 def C_(s):123 def C_(s):
124 return tolocale(_(s, 2))124 return tolocale(_(s, 2))
125125
126 126# marking for pygettext
127def D_(s):
128 return s
129
127130
128131
129def ctime(date):132def ctime(date):
130 # Don't make these module globals since we have to do runtime translation133 # Don't make these module globals since we have to do runtime translation
131134
=== modified file 'messages/Makefile.in'
--- messages/Makefile.in 2018-06-04 01:12:09 +0000
+++ messages/Makefile.in 2018-06-17 13:04:43 +0000
@@ -139,7 +139,7 @@
139139
140potfile: marked.files docstring.files140potfile: marked.files docstring.files
141 @echo "Running pygettext on $@; this make take a while."141 @echo "Running pygettext on $@; this make take a while."
142 (cd ..; $(PROG) -k C_ -p messages -d mailman -D -X messages/marked.files `cat messages/marked.files messages/docstring.files`)142 (cd ..; $(PROG) -k C_ -k D_ -p messages -d mailman -D -X messages/marked.files `cat messages/marked.files messages/docstring.files`)
143143
144# Update the individual mailman.po files with the new changes to the144# Update the individual mailman.po files with the new changes to the
145# .pot file145# .pot file