# Copyright (C) 1998-2006 by the Free Software Foundation, Inc.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
# USA.
"""Script which implements admin editing of the list's html templates."""
import os
import cgi
import errno
import re
from Mailman import Utils
from Mailman import MailList
from Mailman.htmlformat import *
from Mailman.HTMLFormatter import HTMLFormatter
from Mailman import Errors
from Mailman.Cgi import Auth
from Mailman.Logging.Syslog import syslog
from Mailman import i18n
_ = i18n._
def main():
# Trick out pygettext since we want to mark template_data as translatable,
# but we don't want to actually translate it here.
def _(s):
return s
template_data = (
('listinfo.html', _('General list information page')),
('subscribe.html', _('Subscribe results page')),
('options.html', _('User specific options page')),
('subscribeack.txt', _('Welcome email text file')),
)
_ = i18n._
doc = Document()
# Set up the system default language
i18n.set_language(mm_cfg.DEFAULT_SERVER_LANGUAGE)
doc.set_language(mm_cfg.DEFAULT_SERVER_LANGUAGE)
parts = Utils.GetPathPieces()
if not parts:
title = _('List name is required')
doc.SetTitle(title)
doc.AddItem(Div(Paragraph(
_('%(title)s'))
).Format(css='class="message error strong"'))
doc.AddItem(MailmanLogo())
print doc.Format()
return
listname = parts[0].lower()
try:
mlist = MailList.MailList(listname, lock=0)
except Errors.MMListError, e:
# Avoid cross-site scripting attacks
safelistname = Utils.websafe(listname)
title = _('No such list')
doc.SetTitle(title)
doc.AddItem(Div(Header(3, title),
Paragraph(
_('The <tt>%(safelistname)s</tt> mailing list does not exist.'))
).Format(css='class="message error"'))
doc.AddItem(MailmanLogo())
print doc.Format()
syslog('error', 'No such list "%s": %s', listname, e)
return
# Now that we have a valid list, set the language to its default
i18n.set_language(mlist.preferred_language)
doc.set_language(mlist.preferred_language)
# Must be authenticated to get any farther
cgidata = cgi.FieldStorage()
# Editing the html for a list is limited to the list admin and site admin.
if not mlist.WebAuthenticate((mm_cfg.AuthListAdmin,
mm_cfg.AuthSiteAdmin),
cgidata.getvalue('adminpw', '')):
if cgidata.has_key('admlogin'):
# This is a re-authorization attempt
msg = Div(Paragraph(_('Authorization failed.'))).Format(css='class="message error strong"')
else:
msg = ''
Auth.loginpage(mlist, 'admin', msg=msg)
return
realname = mlist.real_name
if len(parts) > 1:
template_name = parts[1]
for (template, info) in template_data:
if template == template_name:
template_info = _(info)
doc.SetTitle(_('Public Templates'))
break
else:
# Avoid cross-site scripting attacks
safetemplatename = Utils.websafe(template_name)
doc.SetTitle(_('Invalid Template'))
doc.AddItem(Div(Header(3, _('Invalid Template')),
Paragraph(_('%(safetemplatename)s is not a valid template.'))
).Format(css='class="message error"'))
doc.AddItem(mlist.GetMailmanFooter())
print doc.Format()
return
else:
title = _('Public Templates')
doc.SetTitle(title)
doc.AddItem(Header(1, title))
doc.AddItem(Paragraph(_('Select template to edit:')))
template_list = UnorderedList()
for (template, info) in template_data:
l = Link(mlist.GetScriptURL('edithtml') + '/' + template, _(info))
template_list.AddItem(l)
doc.AddItem(template_list)
doc.AddItem(mlist.GetMailmanFooter())
print doc.Format()
return
try:
if cgidata.keys():
ChangeHTML(mlist, cgidata, template_name, doc)
FormatHTML(mlist, doc, template_name, template_info)
finally:
doc.AddItem(mlist.GetMailmanFooter())
print doc.Format()
def FormatHTML(mlist, doc, template_name, template_info):
realname = mlist.real_name
title = _(template_info)
doc.AddItem(Header(1, title))
form = Form(mlist.GetScriptURL('edithtml') + '/' + template_name)
text = Utils.maketext(template_name, raw=1, mlist=mlist)
# MAS: Don't websafe twice. TextArea does it.
form.AddItem(Paragraph(TextArea('html_code', text, rows=40, cols=75)))
form.AddItem(Paragraph(
_('When you are done making changes...'),
SubmitButton('submit', _('Submit Changes')).Format()))
doc.AddItem(form)
def ChangeHTML(mlist, cgi_info, template_name, doc):
if not cgi_info.has_key('html_code'):
doc.AddItem(Div(Header(3, _('Template Unchanged.')),
Paragraph(_("Can't have empty template."))).Format(css='class="message error"'))
return
code = cgi_info['html_code'].value
code = re.sub(r'<([/]?script.*?)>', r'<\1>', code)
langdir = os.path.join(mlist.fullpath(), mlist.preferred_language)
# Make sure the directory exists
omask = os.umask(0)
try:
try:
os.mkdir(langdir, 02775)
except OSError, e:
if e.errno <> errno.EEXIST: raise
finally:
os.umask(omask)
fp = open(os.path.join(langdir, template_name), 'w')
try:
fp.write(code)
finally:
fp.close()
doc.AddItem(Div(Paragraph(_('Template successfully updated.'))).Format(css='class="message success strong"'))