Skip to content

Commit 175f9e3

Browse files
committed
update for python3
1 parent db63723 commit 175f9e3

83 files changed

Lines changed: 355 additions & 355 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Mailman/Cgi/admin.py

Lines changed: 75 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -450,7 +450,7 @@ def option_help(mlist, varhelp):
450450
item = None
451451
reflist = varhelp.split('/')
452452
if len(reflist) >= 2:
453-
category = subcat = None
453+
category, subcat = None, None
454454
if len(reflist) == 2:
455455
category, varname = reflist
456456
elif len(reflist) == 3:
@@ -514,18 +514,59 @@ def option_help(mlist, varhelp):
514514
doc.AddItem(mlist.GetMailmanFooter())
515515
print(doc.Format())
516516

517+
def add_standard_headers(doc, mlist, title, category=None, subcat=None):
518+
"""Add standard headers to admin pages.
519+
520+
Args:
521+
doc: The Document object
522+
mlist: The MailList object
523+
title: The page title
524+
category: Optional category name
525+
subcat: Optional subcategory name
526+
"""
527+
# Set the page title
528+
doc.SetTitle(title)
529+
530+
# Add the main header
531+
doc.AddItem(Header(2, title))
532+
533+
# Add navigation breadcrumbs if category/subcat provided
534+
if category:
535+
adminurl = mlist.GetScriptURL('admin')
536+
categories = mlist.GetConfigCategories()
537+
category_label = _(categories[category][0])
538+
if isinstance(category_label, bytes):
539+
category_label = category_label.decode(Utils.GetCharSet(mlist.preferred_language), 'replace')
540+
541+
breadcrumbs = []
542+
breadcrumbs.append(Link(adminurl, _('Admin')))
543+
breadcrumbs.append(Link(f'{adminurl}/{category}', category_label))
544+
545+
if subcat:
546+
subcat_label = _(categories[category][1].get(subcat, [subcat])[0])
547+
if isinstance(subcat_label, bytes):
548+
subcat_label = subcat_label.decode(Utils.GetCharSet(mlist.preferred_language), 'replace')
549+
breadcrumbs.append(Link(f'{adminurl}/{category}/{subcat}', subcat_label))
550+
551+
doc.AddItem(Center(' > '.join(breadcrumbs)))
552+
553+
# Add horizontal rule
554+
doc.AddItem('<hr>')
555+
517556
def show_results(mlist, doc, category, subcat, cgidata):
518557
# Produce the results page
519558
adminurl = mlist.GetScriptURL('admin')
520559
categories = mlist.GetConfigCategories()
521560
label = _(categories[category][0])
522561
if isinstance(label, bytes):
523-
label = label.decode('latin1', 'replace')
562+
label = label.decode(Utils.GetCharSet(mlist.preferred_language), 'replace')
524563

525-
doc.SetTitle(_('%(realname)s Administration (%(label)s)') % {
564+
# Add standard headers
565+
title = _('%(realname)s Administration (%(label)s)') % {
526566
'realname': mlist.real_name,
527567
'label': label
528-
})
568+
}
569+
add_standard_headers(doc, mlist, title, category, subcat)
529570

530571
# Use ParseTags for the main content
531572
replacements = {
@@ -539,6 +580,11 @@ def show_results(mlist, doc, category, subcat, cgidata):
539580
'rmlisturl': mlist.GetScriptURL('rmlist') if mm_cfg.OWNERS_CAN_DELETE_THEIR_OWN_LISTS and mlist.internal_name() != mm_cfg.MAILMAN_SITE_LIST else None
540581
}
541582

583+
# Ensure all replacements are properly encoded for the list's language
584+
for key, value in replacements.items():
585+
if isinstance(value, bytes):
586+
replacements[key] = value.decode(Utils.GetCharSet(mlist.preferred_language), 'replace')
587+
542588
output = mlist.ParseTags('admin_results.html', replacements, mlist.preferred_language)
543589
doc.AddItem(output)
544590

@@ -586,7 +632,7 @@ def show_variables(mlist, category, subcat, cgidata, doc):
586632
mailman_log('debug', 'Got config categories: %s', str(categories))
587633
label = _(categories[category][0])
588634
if isinstance(label, bytes):
589-
label = label.decode('latin1', 'replace')
635+
label = label.decode(Utils.GetCharSet(mlist.preferred_language), 'replace')
590636
mailman_log('debug', 'Category label: %s', label)
591637

592638
table.AddRow([Center(Header(2, label))])
@@ -597,7 +643,7 @@ def show_variables(mlist, category, subcat, cgidata, doc):
597643
# description if it is a string
598644
description = options[0]
599645
if isinstance(description, bytes):
600-
description = description.decode('latin1', 'replace')
646+
description = description.decode(Utils.GetCharSet(mlist.preferred_language), 'replace')
601647
mailman_log('debug', 'Description: %s', description)
602648
if type(description) is str:
603649
table.AddRow([description])
@@ -623,7 +669,7 @@ def show_variables(mlist, category, subcat, cgidata, doc):
623669
# treated as a general description, while any others are
624670
# treated as section headers - centered and italicized...
625671
if isinstance(item, bytes):
626-
item = item.decode('latin1', 'replace')
672+
item = item.decode(Utils.GetCharSet(mlist.preferred_language), 'replace')
627673
formatted_text = '[%s]' % item
628674
item = Bold(formatted_text).Format()
629675
table.AddRow([Center(Italic(item))])
@@ -707,16 +753,7 @@ def get_item_gui_value(mlist, category, kind, varname, params, extra):
707753
kind == mm_cfg.Host or kind == mm_cfg.Number):
708754
# Ensure value is a string, decoding bytes if necessary
709755
if isinstance(value, bytes):
710-
try:
711-
# Try UTF-8 first
712-
value = value.decode('utf-8', 'replace')
713-
except UnicodeDecodeError:
714-
try:
715-
# Try EUC-JP for Japanese text
716-
value = value.decode('euc-jp', 'replace')
717-
except UnicodeDecodeError:
718-
# Fall back to latin1
719-
value = value.decode('latin1', 'replace')
756+
value = value.decode(Utils.GetCharSet(mlist.preferred_language), 'replace')
720757
return TextBox(varname, value, params)
721758
elif kind == mm_cfg.Text:
722759
if params:
@@ -725,16 +762,7 @@ def get_item_gui_value(mlist, category, kind, varname, params, extra):
725762
r, c = None, None
726763
# Ensure value is a string, decoding bytes if necessary
727764
if isinstance(value, bytes):
728-
try:
729-
# Try UTF-8 first
730-
value = value.decode('utf-8', 'replace')
731-
except UnicodeDecodeError:
732-
try:
733-
# Try EUC-JP for Japanese text
734-
value = value.decode('euc-jp', 'replace')
735-
except UnicodeDecodeError:
736-
# Fall back to latin1
737-
value = value.decode('latin1', 'replace')
765+
value = value.decode(Utils.GetCharSet(mlist.preferred_language), 'replace')
738766
return TextArea(varname, value or '', r, c)
739767
elif kind in (mm_cfg.EmailList, mm_cfg.EmailListEx):
740768
if params:
@@ -743,16 +771,7 @@ def get_item_gui_value(mlist, category, kind, varname, params, extra):
743771
r, c = None, None
744772
# Ensure value is a string, decoding bytes if necessary
745773
if isinstance(value, bytes):
746-
try:
747-
# Try UTF-8 first
748-
value = value.decode('utf-8', 'replace')
749-
except UnicodeDecodeError:
750-
try:
751-
# Try EUC-JP for Japanese text
752-
value = value.decode('euc-jp', 'replace')
753-
except UnicodeDecodeError:
754-
# Fall back to latin1
755-
value = value.decode('latin1', 'replace')
774+
value = value.decode(Utils.GetCharSet(mlist.preferred_language), 'replace')
756775
res = NL.join(value)
757776
return TextArea(varname, res, r, c, wrap='off')
758777
elif kind == mm_cfg.FileUpload:
@@ -819,11 +838,11 @@ def makebox(i, name, pattern, desc, empty=False, table=table):
819838
data = getattr(mlist, varname)
820839
for name, pattern, desc, empty in data:
821840
if isinstance(name, bytes):
822-
name = name.decode('latin1', 'replace')
841+
name = name.decode(Utils.GetCharSet(mlist.preferred_language), 'replace')
823842
if isinstance(pattern, bytes):
824-
pattern = pattern.decode('latin1', 'replace')
843+
pattern = pattern.decode(Utils.GetCharSet(mlist.preferred_language), 'replace')
825844
if isinstance(desc, bytes):
826-
desc = desc.decode('latin1', 'replace')
845+
desc = desc.decode(Utils.GetCharSet(mlist.preferred_language), 'replace')
827846
makebox(i, name, pattern, desc, empty)
828847
i += 1
829848
# Add one more non-deleteable widget as the first blank entry, but
@@ -889,7 +908,7 @@ def makebox(i, pattern, action, empty=False, table=table):
889908
data = getattr(mlist, varname)
890909
for pattern, action, empty in data:
891910
if isinstance(pattern, bytes):
892-
pattern = pattern.decode('latin1', 'replace')
911+
pattern = pattern.decode(Utils.GetCharSet(mlist.preferred_language), 'replace')
893912
makebox(i, pattern, action, empty)
894913
i += 1
895914
# Add one more non-deleteable widget as the first blank entry, but
@@ -942,43 +961,24 @@ def membership_options(mlist, subcat, cgidata, doc, form):
942961
adminurl = mlist.GetScriptURL('admin', absolute=1)
943962
container = Container()
944963
header = Table(width="100%")
945-
# If we're in the list subcategory, show the membership list
964+
965+
# Add standard headers based on subcat
946966
if subcat == 'add':
947-
header.AddRow([Center(Header(2, _('Mass Subscriptions')))])
948-
header.AddCellInfo(header.GetCurrentRowIndex(), 0, colspan=2,
949-
bgcolor=mm_cfg.WEB_HEADER_COLOR)
950-
container.AddItem(header)
951-
mass_subscribe(mlist, container)
952-
return container
953-
if subcat == 'remove':
954-
header.AddRow([Center(Header(2, _('Mass Removals')))])
955-
header.AddCellInfo(header.GetCurrentRowIndex(), 0, colspan=2,
956-
bgcolor=mm_cfg.WEB_HEADER_COLOR)
957-
container.AddItem(header)
958-
mass_remove(mlist, container)
959-
return container
960-
if subcat == 'change':
961-
header.AddRow([Center(Header(2, _('Address Change')))])
962-
header.AddCellInfo(header.GetCurrentRowIndex(), 0, colspan=2,
963-
bgcolor=mm_cfg.WEB_HEADER_COLOR)
964-
container.AddItem(header)
965-
address_change(mlist, container)
966-
return container
967-
if subcat == 'sync':
968-
header.AddRow([Center(Header(2, _('Sync Membership List')))])
969-
header.AddCellInfo(header.GetCurrentRowIndex(), 0, colspan=2,
970-
bgcolor=mm_cfg.WEB_HEADER_COLOR)
971-
container.AddItem(header)
972-
mass_sync(mlist, container)
973-
return container
974-
# Otherwise...
975-
header.AddRow([Center(Header(2, _('Membership List')))])
976-
header.AddCellInfo(header.GetCurrentRowIndex(), 0, colspan=2,
977-
bgcolor=mm_cfg.WEB_HEADER_COLOR)
978-
container.AddItem(header)
967+
title = _('Mass Subscriptions')
968+
elif subcat == 'remove':
969+
title = _('Mass Removals')
970+
elif subcat == 'change':
971+
title = _('Address Change')
972+
elif subcat == 'sync':
973+
title = _('Sync Membership List')
974+
else:
975+
title = _('Membership List')
976+
977+
add_standard_headers(doc, mlist, title, 'members', subcat)
978+
979979
# Add a "search for member" button
980980
table = Table(width='100%')
981-
link = Link('https://docs.python.org/2/library/re.html'
981+
link = Link('https://docs.python.org/3/library/re.html'
982982
'#regular-expression-syntax',
983983
_('(help)')).Format()
984984
table.AddRow([Label(_('Find member %(link)s:') % {'link': link}),

Mailman/Defaults.py.in

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ KNOWN_SPAMMERS = []
261261
# normalized unicodes against normalized unicode headers. This setting
262262
# determines the normalization form. It is one of 'NFC', 'NFD', 'NFKC' or
263263
# 'NFKD'. See
264-
# https://docs.python.org/2/library/unicodedata.html#unicodedata.normalize
264+
# https://docs.python.org/3/library/unicodedata.html#unicodedata.normalize
265265
NORMALIZE_FORM = 'NFKC'
266266

267267

Mailman/Gui/Privacy.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ def GetConfigInfo(self, mlist, category, subcat=None):
196196
197197
<p>In the text boxes below, add one address per line; start the
198198
line with a ^ character to designate a <a href=
199-
"https://docs.python.org/2/library/re.html"
199+
"https://docs.python.org/3/library/re.html"
200200
>Python regular expression</a>. When entering backslashes, do so
201201
as if you were using Python raw strings (i.e. you generally just
202202
use a single backslash).

Mailman/Gui/Topics.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ def GetConfigInfo(self, mlist, category, subcat=None):
4444

4545
_("""The topic filter categorizes each incoming email message
4646
according to <a
47-
href="https://docs.python.org/2/library/re.html">regular
47+
href="https://docs.python.org/3/library/re.html">regular
4848
expression filters</a> you specify below. If the message's
4949
<code>Subject:</code> or <code>Keywords:</code> header contains a
5050
match against a topic filter, the message is logically placed

bin/find_member

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ specifically excluded.
4949
Regular expression syntax is Perl5-like, using the Python re module. Complete
5050
specifications are at:
5151

52-
https://docs.python.org/2/library/re.html
52+
https://docs.python.org/3/library/re.html
5353

5454
Address matches are case-insensitive, but case-preserved addresses are
5555
displayed.

messages/ar/LC_MESSAGES/mailman.po

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6586,7 +6586,7 @@ msgid ""
65866586
"\n"
65876587
" <p>In the text boxes below, add one address per line; start the\n"
65886588
" line with a ^ character to designate a <a href=\n"
6589-
" \"https://docs.python.org/2/library/re.html\"\n"
6589+
" \"https://docs.python.org/3/library/re.html\"\n"
65906590
" >Python regular expression</a>. When entering backslashes, do "
65916591
"so\n"
65926592
" as if you were using Python raw strings (i.e. you generally "
@@ -6617,7 +6617,7 @@ msgstr ""
66176617
"\n"
66186618
" <p>في مربعات النص تحت، أضف عناناً واحداً في السطر، ابدأ السطر "
66196619
"بمحرف ^ لصنع <a href=\n"
6620-
" \"https://docs.python.org/2/library/re.html\"\n"
6620+
" \"https://docs.python.org/3/library/re.html\"\n"
66216621
" >صيغة بايثون نظامية</a>. عند إدخال محرف التقسيم الخلفي أدخله "
66226622
"وكأنك تدخل أحرف بايثون خام (مثلاً أنت عادة تستخدم محرف تقسيم خلفي واحد).\n"
66236623
" <p>لاحظ أن المقابلات مع الإدخالات غير الصيغ النظامية دائماً تحصل "
@@ -7358,7 +7358,7 @@ msgstr "هل يجب أن يكون مصفي الموضوع ممكناً أم مع
73587358
msgid ""
73597359
"The topic filter categorizes each incoming email message\n"
73607360
" according to <a\n"
7361-
" href=\"https://docs.python.org/2/library/re.html\">regular\n"
7361+
" href=\"https://docs.python.org/3/library/re.html\">regular\n"
73627362
" expression filters</a> you specify below. If the message's\n"
73637363
" <code>Subject:</code> or <code>Keywords:</code> header contains "
73647364
"a\n"
@@ -7381,7 +7381,7 @@ msgid ""
73817381
" configuration variable."
73827382
msgstr ""
73837383
"يصنف مصفي الموضوع كل رسالة بريد قائمة حسب <a\n"
7384-
" href=\"https://docs.python.org/2/library/re.html\">مصفيات صيغ "
7384+
" href=\"https://docs.python.org/3/library/re.html\">مصفيات صيغ "
73857385
"نظامية</a> تحددها أنت في الأسفل. إذا كانت ترويسة \n"
73867386
" <code>Subject :</code> أو <code>Keywords:</code> الخاصة "
73877387
"بالرسالة تحتوي على تطابق مع مصفي موضوع فسوف توضع الرسالة في <em>جيب</em> "
@@ -9652,7 +9652,7 @@ msgid ""
96529652
"Complete\n"
96539653
"specifications are at:\n"
96549654
"\n"
9655-
"https://docs.python.org/2/library/re.html\n"
9655+
"https://docs.python.org/3/library/re.html\n"
96569656
"\n"
96579657
"Address matches are case-insensitive, but case-preserved addresses are\n"
96589658
"displayed.\n"
@@ -12408,7 +12408,7 @@ msgstr ""
1240812408

1240912409
#~ msgid ""
1241012410
#~ "This text can include \n"
12411-
#~ "<a href=\"https://docs.python.org/2/library/stdtypes.html#string-"
12411+
#~ "<a href=\"https://docs.python.org/3/library/stdtypes.html#string-"
1241212412
#~ "formatting-operations\">Python\n"
1241312413
#~ "format strings</a> which are resolved against list attributes. The\n"
1241412414
#~ "list of substitutions allowed are:\n"
@@ -12437,7 +12437,7 @@ msgstr ""
1243712437
#~ " <li><b>cgiext</b> - The extension added to CGI scripts.\n"
1243812438
#~ "</ul>"
1243912439
#~ msgstr ""
12440-
#~ "يمكن لهذا النص أن يتضمن<a href=\"https://docs.python.org/2/library/"
12440+
#~ "يمكن لهذا النص أن يتضمن<a href=\"https://docs.python.org/3/library/"
1244112441
#~ "stdtypes.html#string-formatting-operations\">محارف تنسيق بايثون</a> \n"
1244212442
#~ "والتي سيتم حلها مع مواصفات القائمة. قائمة الاستبدالات المسموحة هي:\n"
1244312443
#~ "\n"

0 commit comments

Comments
 (0)