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
1=== modified file 'Mailman/Bouncer.py'
2--- Mailman/Bouncer.py 2017-06-02 22:25:12 +0000
3+++ Mailman/Bouncer.py 2018-06-17 13:04:43 +0000
4@@ -49,6 +49,7 @@
5 }
6
7 _ = i18n._
8+D_ = i18n.D_
9
10
11
12
13@@ -265,7 +266,7 @@
14 if info.noticesleft <= 0:
15 # BAW: Remove them now, with a notification message
16 self.ApprovedDeleteMember(
17- member, 'disabled address',
18+ member, D_('disabled address'),
19 admin_notif=self.bounce_notify_owner_on_removal,
20 userack=1)
21 # Expunge the pending cookie for the user. We throw away the
22
23=== modified file 'Mailman/Cgi/admin.py'
24--- Mailman/Cgi/admin.py 2018-06-11 16:59:26 +0000
25+++ Mailman/Cgi/admin.py 2018-06-17 13:04:43 +0000
26@@ -47,6 +47,7 @@
27 # Set up i18n
28 _ = i18n._
29 i18n.set_language(mm_cfg.DEFAULT_SERVER_LANGUAGE)
30+D_ = i18n.D_
31
32 NL = '\n'
33 OPTCOLUMNS = 11
34@@ -1484,7 +1485,7 @@
35 else:
36 mlist.ApprovedAddMember(userdesc, send_welcome_msg,
37 send_admin_notif, invitation,
38- whence='admin mass sub')
39+ whence=D_('admin mass sub'))
40 except Errors.MMAlreadyAMember:
41 subscribe_errors.append((safeentry, _('Already a member')))
42 except Errors.MMBadEmailError:
43@@ -1538,7 +1539,7 @@
44 for addr in names:
45 try:
46 mlist.ApprovedDeleteMember(
47- addr, whence='admin mass unsub',
48+ addr, whence=D_('admin mass unsub'),
49 admin_notif=send_unsub_notifications,
50 userack=userack)
51 unsubscribe_success.append(Utils.websafe(addr))
52@@ -1645,7 +1646,8 @@
53 quser = urllib.quote(user)
54 if cgidata.has_key('%s_unsub' % quser):
55 try:
56- mlist.ApprovedDeleteMember(user, whence='member mgt page')
57+ mlist.ApprovedDeleteMember(user,
58+ whence=D_('member mgt page'))
59 removes.append(user)
60 except Errors.NotAMemberError:
61 errors.append((user, _('Not subscribed')))
62
63=== modified file 'Mailman/Cgi/options.py'
64--- Mailman/Cgi/options.py 2018-06-11 16:59:26 +0000
65+++ Mailman/Cgi/options.py 2018-06-17 13:04:43 +0000
66@@ -45,6 +45,7 @@
67 # Set up i18n
68 _ = i18n._
69 i18n.set_language(mm_cfg.DEFAULT_SERVER_LANGUAGE)
70+D_ = i18n.D_
71
72 try:
73 True, False
74@@ -583,7 +584,7 @@
75 try:
76 try:
77 mlist.DeleteMember(
78- user, 'via the member options page', userack=1)
79+ user, D_('via the member options page'), userack=1)
80 except Errors.MMNeedApproval:
81 needapproval = True
82 except Errors.NotAMemberError:
83
84=== modified file 'Mailman/ListAdmin.py'
85--- Mailman/ListAdmin.py 2017-06-02 22:25:12 +0000
86+++ Mailman/ListAdmin.py 2018-06-17 13:04:43 +0000
87@@ -45,6 +45,7 @@
88 from Mailman import i18n
89
90 _ = i18n._
91+D_ = i18n.D_
92
93 # Request types requiring admin approval
94 IGN = 0
95@@ -436,7 +437,8 @@
96 assert value == mm_cfg.SUBSCRIBE
97 try:
98 userdesc = UserDesc(addr, fullname, password, digest, lang)
99- self.ApprovedAddMember(userdesc, whence='via admin approval')
100+ self.ApprovedAddMember(userdesc,
101+ whence=D_('via admin approval'))
102 except Errors.MMAlreadyAMember:
103 # User has already been subscribed, after sending the request
104 pass
105
106=== modified file 'Mailman/MailList.py'
107--- Mailman/MailList.py 2018-06-16 16:39:45 +0000
108+++ Mailman/MailList.py 2018-06-17 13:04:43 +0000
109@@ -72,6 +72,7 @@
110 from Mailman.Logging.Syslog import syslog
111
112 _ = i18n._
113+D_ = i18n.D_
114
115 EMPTYSTRING = ''
116 OR = '|'
117@@ -1071,6 +1072,7 @@
118 otrans = i18n.get_translation()
119 i18n.set_language(lang)
120 try:
121+ whence = "" if whence is None else "(" + _(whence) + ")"
122 realname = self.real_name
123 subject = _('%(realname)s subscription notification')
124 finally:
125@@ -1081,7 +1083,7 @@
126 "adminsubscribeack.txt",
127 {"listname" : realname,
128 "member" : formataddr((name, email)),
129- "whence" : "" if whence is None else "(" + whence + ")"
130+ "whence" : whence
131 }, mlist=self)
132 msg = Message.OwnerNotification(self, subject, text)
133 msg.send(self)
134@@ -1118,7 +1120,7 @@
135 'adminunsubscribeack.txt',
136 {'member' : name,
137 'listname': self.real_name,
138- "whence" : "" if whence is None else "(" + whence + ")"
139+ "whence" : "" if whence is None else "(" + _(whence) + ")"
140 }, mlist=self)
141 msg = Message.OwnerNotification(self, subject, text)
142 msg.send(self)
143@@ -1307,7 +1309,7 @@
144 except ValueError:
145 raise Errors.MMBadConfirmation, 'op-less data %s' % (rec,)
146 if op == Pending.SUBSCRIPTION:
147- whence = 'via email confirmation'
148+ whence = D_('via email confirmation')
149 try:
150 userdesc = data[0]
151 # If confirmation comes from the web, context should be a
152@@ -1316,7 +1318,7 @@
153 # context is a Message and isn't relevant, so ignore it.
154 if isinstance(context, UserDesc):
155 userdesc += context
156- whence = 'via web confirmation'
157+ whence = D_('via web confirmation')
158 addr = userdesc.address
159 fullname = userdesc.fullname
160 password = userdesc.password
161@@ -1348,9 +1350,9 @@
162 addr = data[0]
163 # Log file messages don't need to be i18n'd
164 if isinstance(context, Message.Message):
165- whence = 'email confirmation'
166+ whence = D_('email confirmation')
167 else:
168- whence = 'web confirmation'
169+ whence = D_('web confirmation')
170 # Can raise NotAMemberError if they unsub'd via other means
171 self.ApprovedDeleteMember(addr, whence=whence)
172 return op, addr
173
174=== modified file 'Mailman/i18n.py'
175--- Mailman/i18n.py 2017-01-18 06:49:29 +0000
176+++ Mailman/i18n.py 2018-06-17 13:04:43 +0000
177@@ -123,7 +123,10 @@
178 def C_(s):
179 return tolocale(_(s, 2))
180
181-
182+# marking for pygettext
183+def D_(s):
184+ return s
185+
186
187
188 def ctime(date):
189 # Don't make these module globals since we have to do runtime translation
190
191=== modified file 'messages/Makefile.in'
192--- messages/Makefile.in 2018-06-04 01:12:09 +0000
193+++ messages/Makefile.in 2018-06-17 13:04:43 +0000
194@@ -139,7 +139,7 @@
195
196 potfile: marked.files docstring.files
197 @echo "Running pygettext on $@; this make take a while."
198- (cd ..; $(PROG) -k C_ -p messages -d mailman -D -X messages/marked.files `cat messages/marked.files messages/docstring.files`)
199+ (cd ..; $(PROG) -k C_ -k D_ -p messages -d mailman -D -X messages/marked.files `cat messages/marked.files messages/docstring.files`)
200
201 # Update the individual mailman.po files with the new changes to the
202 # .pot file