clearsilver branch merged and removed

This commit is contained in:
lars 2005-06-20 22:51:06 +00:00
parent 118bf84d45
commit 64c3e10df0
16 changed files with 879 additions and 364 deletions

3
TODO Normal file
View file

@ -0,0 +1,3 @@
start.cs -> select_list.cs
check permission for uploading before doing!

View file

@ -40,11 +40,11 @@
# Modules to include
use strict;
use Getopt::Std;
use ClearSilver;
use Mail::Ezmlm;
use Mail::Address;
use DB_File;
use CGI;
use CGI::Carp qw(fatalsToBrowser set_message);
# These two are actually included later and are put here so we remember them.
#use File::Find if ($UNSAFE_RM == 1);
@ -69,7 +69,14 @@ use vars qw[$DEFAULT_OPTIONS %EZMLM_LABELS $UNSAFE_RM $ALIAS_USER $LIST_DIR];
use vars qw[$QMAIL_BASE $EZMLM_CGI_RC $EZMLM_CGI_URL $HTML_BGCOLOR $PRETTY_NAMES];
use vars qw[%HELPER $HELP_ICON_URL $HTML_HEADER $HTML_FOOTER $HTML_TEXT $HTML_LINK];
use vars qw[%BUTTON %LANGUAGE $HTML_VLINK $HTML_TITLE $FILE_UPLOAD $WEBUSERS_FILE];
use vars qw[$HTML_CSS_FILE];
use vars qw[$HTML_CSS_FILE $TEMPLATE_DIR $LANGUAGE_DIR];
#TODO: interim
$TEMPLATE_DIR = "/root/clearsilver/template";
# pagedata contains the hdf tree for clearsilver
# pagename refers to the template file that should be used
use vars qw[$pagedata $pagename];
# Get user configuration stuff
if(defined($opt_C)) {
@ -109,64 +116,61 @@ if(defined($Q::action) && $Q::action eq '[Web Archive]') {
exit;
}
# Print header on every page ...
print $q->header(-pragma=>'no-cache', '-cache-control'=>'no-cache', -expires=>'-1d', '-Content-Type'=>'text/html; charset=utf-8');
print $q->start_html(-style=>{'src'=>"$HTML_CSS_FILE"},-title=>$HTML_TITLE, -author=>'guy-ezmlm@rucus.ru.ac.za', -expires=>'-1d');
print $HTML_HEADER;
my $pagedata = load_hdf();
# check permissions
&check_permission_for_action == 0 || die 'Error: you are not allowed to do this!';
&check_permission_for_action == 0 || &error_die('Error: you are not allowed to do this!');
# This is where we decide what to do, depending on the form state and the
# users chosen course of action ...
unless (defined($q->param('state'))) {
# Default action. Present a list of available lists to the user ...
&select_list;
&select_list();
} elsif ($Q::state eq 'select') {
# User selects an action to perform on a list ...
if ($Q::action eq "[$BUTTON{'create'}]") { # Create a new list ...
if ($Q::action eq $pagedata->getValue("Lang.Buttons.Create","unknown button")) { # Create a new list ...
&allow_create_list;
} elsif (defined($Q::list)) {
if ($Q::action eq "[$BUTTON{'edit'}]") { # Edit an existing list ...
if ($Q::action eq $pagedata->getValue("Lang.Buttons.Edit","unknown button")) { # Edit an existing list ...
&display_list;
} elsif ($Q::action eq "[$BUTTON{'delete'}]") { # Delete a list ...
} elsif ($Q::action eq $pagedata->getValue("Lang.Buttons.Delete","unknown button")) { # Delete a list ...
&confirm_delete;
}
} else {
&select_list; # NOP - Blank input ...
&select_list(); # NOP - Blank input ...
}
} elsif ($Q::state eq 'edit') {
# User chooses to edit a list
my($list); $list = $LIST_DIR . '/' . $q->param('list');
if ($Q::action eq "[$BUTTON{'deleteaddress'}]") { # Delete a subscriber ...
if ($Q::action eq $pagedata->getValue("Lang.Buttons.DeleteAddress","unknown button")) { # Delete a subscriber ...
&delete_address($list);
&display_list;
} elsif ($Q::action eq "[$BUTTON{'addaddress'}]") { # Add a subscriber ...
} elsif ($Q::action eq $pagedata->getValue("Lang.Buttons.AddAddress","unknown button")) { # Add a subscriber ...
&add_address($list);
&display_list;
} elsif ($Q::action eq "[$BUTTON{'moderators'}]") { # Edit the moderators ...
} elsif ($Q::action eq $pagedata->getValue("Lang.Buttons.Moderators","unknown button")) { # Edit the moderators ...
&part_subscribers('mod');
} elsif ($Q::action eq "[$BUTTON{'denylist'}]") { # Edit the deny list ...
} elsif ($Q::action eq $pagedata->getValue("Lang.Buttons.DenyList","unknown button")) { # Edit the deny list ...
&part_subscribers('deny');
} elsif ($Q::action eq "[$BUTTON{'allowlist'}]") { # edit the allow list ...
} elsif ($Q::action eq $pagedata->getValue("Lang.Buttons.AllowList","unknown button")) { # edit the allow list ...
&part_subscribers('allow');
} elsif ($Q::action eq "[$BUTTON{'digestsubscribers'}]") { # Edit the digest subscribers ...
} elsif ($Q::action eq $pagedata->getValue("Lang.Buttons.DigestSubscribers","unknown button")) { # Edit the digest subscribers ...
&part_subscribers('digest');
} elsif ($Q::action eq "[$BUTTON{'configuration'}]") { # Edit the config ...
} elsif ($Q::action eq $pagedata->getValue("Lang.Buttons.Configuration","unknown button")) { # Edit the config ...
&list_config;
} else { # Cancel - Return a screen ...
&select_list;
&select_list();
}
} elsif ($Q::state eq 'allow' || $Q::state eq 'mod' || $Q::state eq 'deny' || $q->param('state') eq 'digest') {
@ -184,11 +188,11 @@ unless (defined($q->param('state'))) {
$part = 'digest';
}
if ($Q::action eq "[$BUTTON{'deleteaddress'}]") { # Delete a subscriber ...
if ($Q::action eq $pagedata->getValue("Lang.Buttons.DeleteAddress","unknown button")) { # Delete a subscriber ...
&delete_address("$LIST_DIR/$Q::list", $part);
&part_subscribers($part);
} elsif ($Q::action eq "[$BUTTON{'addaddress'}]") { # Add a subscriber ...
} elsif ($Q::action eq $pagedata->getValue("Lang.Buttons.AddAddress","unknown button")) { # Add a subscriber ...
&add_address("$LIST_DIR/$Q::list", $part);
&part_subscribers($part);
@ -199,32 +203,32 @@ unless (defined($q->param('state'))) {
} elsif ($Q::state eq 'confirm_delete') {
# User wants to delete a list ...
&delete_list if($q->param('confirm') eq "[$BUTTON{'yes'}]"); # Do it ...
&delete_list if($q->param('confirm') eq $pagedata->getValue("Lang.Buttons.Yes","unknown button")); # Do it ...
$q->delete_all;
&select_list;
&select_list();
} elsif ($Q::state eq 'create') {
# User wants to create a list ...
if ($Q::action eq "[$BUTTON{'createlist'}]") {
if ($Q::action eq $pagedata->getValue("Lang.Buttons.CreateList","unknown button")) {
if (&create_list) { # Return if list creation is unsuccessful ...
&allow_create_list;
} else {
&select_list; # Else choose a list ...
&select_list(); # Else choose a list ...
}
} else { # Cancel ...
&select_list;
&select_list();
}
} elsif ($Q::state eq 'configuration') {
# User updates configuration ...
if ($Q::action eq "[$BUTTON{'updateconfiguration'}]") { # Save current settings ...
if ($Q::action eq $pagedata->getValue("Lang.Buttons.UpdateConfiguration","unknown button")) { # Save current settings ...
&update_config;
&display_list;
} elsif ($Q::action eq "[$BUTTON{'edittexts'}]") { # Edit DIR/text ...
} elsif ($Q::action eq $pagedata->getValue("Lang.Buttons.EditTexts","unknown button")) { # Edit DIR/text ...
&list_text;
} else { # Cancel - Return to list editing screen ...
@ -234,7 +238,7 @@ unless (defined($q->param('state'))) {
} elsif ($Q::state eq 'list_text') {
# User wants to edit texts associated with the list ...
if ($Q::action eq "[$BUTTON{'editfile'}]") {
if ($Q::action eq $pagedata->getValue("Lang.Buttons.EditFile","unknown button")) {
&edit_text;
} else {
&list_config; # Cancel ...
@ -243,19 +247,59 @@ unless (defined($q->param('state'))) {
} elsif ($Q::state eq 'edit_text') {
# User wants to save a new version of something in DIR/text ...
&save_text if ($Q::action eq "[$BUTTON{'savefile'}]");
&save_text if ($Q::action eq $pagedata->getValue("Lang.Buttons.SaveFile","unknown button"));
&list_text;
} else {
print "<h1>$Q::action</h1><h2>$LANGUAGE{'nop'}</h2><hr>";
$pagedata->setValue("Data.Action", $q->param('action'));
$pagedata->setValue("Data.Status", "unknown action");
$pagename = 'select_list';
}
# Print HTML footer and exit :) ...
print $HTML_FOOTER, $q->end_html;
# Print page and exit :) ...
&output_page;
exit;
# =========================================================================
sub load_hdf {
# initialize the data for clearsilver
my $hdf = ClearSilver::HDF->new();
# TODO: respect LANGUAGE_DIR and LANGUAGE
$hdf->readFile($LANGUAGE_DIR . "/en.hdf");
# TODO: check for existence
$hdf->setValue("TemplateDir", "$TEMPLATE_DIR/");
$hdf->setValue("LanguageDir", "$LANGUAGE_DIR/");
$hdf->setValue("ScriptName", $ENV{'SCRIPT_NAME'});
$hdf->setValue("Stylesheet", "$HTML_CSS_FILE");
$hdf->setValue("HelpIconURL", "$HELP_ICON_URL");
return $hdf;
}
sub output_page {
# Print the page
my $pagefile = $TEMPLATE_DIR . "/" . $pagename . ".cs";
die "template ($pagefile) not found!" unless (-e "$pagefile");
# print http header
print "Content-Type: text/html\n\n";
my $cs = ClearSilver::CS->new($pagedata);
$cs->parseFile($TEMPLATE_DIR . '/macros.cs');
$cs->parseFile($TEMPLATE_DIR . '/header.cs');
$cs->parseFile($TEMPLATE_DIR . '/' . $pagename . '.cs');
$cs->parseFile($TEMPLATE_DIR . '/footer.cs');
print $cs->render();
}
sub select_list {
# List all mailing lists (sub directories) in the list directory.
# Allow the user to choose a course of action; either editing an existing
@ -263,43 +307,26 @@ sub select_list {
my (@lists, @files, $i, $scrollsize);
$pagename = 'select_list';
# Read the list directory for mailing lists.
opendir DIR, $LIST_DIR || die "Unable to read $LIST_DIR: $!";
opendir DIR, $LIST_DIR || &error_die("Unable to read $LIST_DIR: $!");
@files = grep !/^\./, readdir DIR;
closedir DIR;
# Check that they actually are lists ...
my $num = 0;
foreach $i (0 .. $#files) {
if (-e "$LIST_DIR/$files[$i]/lock") {
$lists[$#lists + 1] = $files[$i] if (&webauth($files[$i]) == 0);
if ((-e "$LIST_DIR/$files[$i]/lock") && (&webauth($files[$i]) == 0)) {
$num++;
$pagedata->setValue("Data.Lists." . $num, "$files[$i]");
}
}
$pagedata->setValue("Data.ListsCount", "$num");
# Keep selection box a resonable size - suggested by Sebastian Andersson
$scrollsize = 25 if(($scrollsize = $#lists + 1) > 25);
# Begin of content
print '<div id="main" class="container">';
# Print a form
$q->delete_all;
print $q->startform;
print $q->hidden(-name=>'state', -default=>'select');
print '<div class="list">';
print $q->scrolling_list(-name=>'list', -size=>$scrollsize, -values=>\@lists) if defined(@lists);
print '</div>'; # end of main_mainlinglists_list
# TODO: ACL an einer Stelle zentral bestimmen lassen
$pagedata->setValue("Data.Permissions.Create", (&webauth_create_allowed == 0)? 1 : 0 );
print '<div class="info">', $LANGUAGE{'chooselistinfo'}, '</div>'; # explanation of options
print '<div class="add_remove">';
print '<span class="button">', $q->submit(-name=>'action', -value=>"[$BUTTON{'create'}]"), '</span>' if (&webauth_create_allowed == 0);
print '<span class="button">', $q->submit(-name=>'action', -value=>"[$BUTTON{'edit'}]"), '</span>' if(defined(@lists));
print '<span class="button">', $q->submit(-name=>'action', -value=>"[$BUTTON{'delete'}]"), '</span>' if(defined(@lists));
print '</div>'; # end of main_buttons
print $q->endform;
print '</div>'; # end of content
}
# ------------------------------------------------------------------------
@ -307,25 +334,8 @@ sub select_list {
sub confirm_delete {
# Make sure that the user really does want to delete the list!
# Begin of content
print '<div id="delete" class="container">';
# Print a form ...
$q->delete('state');
print $q->startform;
print $q->hidden(-name=>'state', -default=>'confirm_delete');
print $q->hidden(-name=>'list', -default=>$q->param('list'));
print '<div class="title">';
print '<h2>', $LANGUAGE{'confirmdelete'}, ' ', $q->param('list'), '</h2>';
print '</div>'; # end of delete->title
print '<div class="question">';
print '<span class="button">', $q->submit(-name=>'confirm', -value=>"[$BUTTON{'no'}]"), '</span>';
print '<span class="button">', $q->submit(-name=>'confirm', -value=>"[$BUTTON{'yes'}]"), '</span>';
print '</div>'; # end of delete->question
print '</div>'; # enf of delete
$pagedata->setValue("Data.ListName", $q->param('list'));
$pagename = 'confirm_delete';
}
# ------------------------------------------------------------------------
@ -333,63 +343,31 @@ sub confirm_delete {
sub display_list {
# Show a list of subscribers to the user ...
my ($i, $list, $listaddress, $moderated, @subscribers, $scrollsize);
my ($list);
# Work out the address of this list ...
$list = new Mail::Ezmlm("$LIST_DIR/$Q::list");
$listaddress = &this_listaddress;
# Get a list of subscribers from ezmlm ...
@subscribers = $list->subscribers;
# Keep selection box a resonable size - suggested by Sebastian Andersson
$scrollsize = 25 if(($scrollsize = $#subscribers + 1) > 25);
$pagename = 'display_list';
# Print out a form of options ...
$q->delete('state');
$pagedata->setValue("Data.ListName", $q->param('list'));
$pagedata->setValue("Data.ListAddress", &this_listaddress);
# Begin of content
print '<div id="edit" class="container">';
my $i = 0;
my $one_subs;
# TODO: use "pretty" output style for visible mail address
foreach $one_subs ($list->subscribers) {
$pagedata->setValue("Data.Subscribers." . $i, "$one_subs");
$i++;
}
$pagedata->setValue("Data.SubscribersCount", "$i");
print '<div class="title">';
print "<h2>$LANGUAGE{'subscribersto'} $Q::list</h2>";
print "<h3>($listaddress)</h3>";
print '<hr>';
print '</div>'; # end of edit->title
print $q->start_multipart_form;
print $q->hidden(-name=>'state', -default=>'edit');
print $q->hidden(-name=>'list', -default=>$Q::list);
print '<div class="list">';
print $q->scrolling_list(-name=>'delsubscriber', -size=>$scrollsize, -values=>\@subscribers, -labels=>&pretty_names, -multiple=>'true') if defined(@subscribers);
print '</div>'; # end of edit->list
print '<div class="add_remove">';
print '<p>', ($#subscribers + 1), ' ', $LANGUAGE{'subscribers'}, '</p>' if defined(@subscribers);
print '<span class="button">', $q->submit(-name=>'action', -value=>"[$BUTTON{'deleteaddress'}]"), '</span>' if defined(@subscribers);
print '<span class="formfield">', $q->textfield(-name=>'addsubscriber', -size=>'40'), ' <img src="', $HELP_ICON_URL, '" title="', $HELPER{'addaddress'}, '"></span>';
print '<span class="formfield">', $q->filefield(-name=>'addfile', -size=>20, -maxlength=>100), ' <img src="', $HELP_ICON_URL, '" title="', $HELPER{'addaddressfile'}, '"></span>' if ($FILE_UPLOAD);
print '<span class="button">', $q->submit(-name=>'action', -value=>"[$BUTTON{'addaddress'}]"), '</span>';
print '</div>'; # end of edit->add_remove
print '<div class="options">';
print '<h3>', $LANGUAGE{'additionalparts'}, ':</h3>' if($list->ismodpost || $list->ismodsub || $list->isremote || $list->isdeny || $list->isallow || $list->isdigest);
print '<p>';
print '<span class="button">', $q->submit(-name=>'action', -value=>"[$BUTTON{'moderators'}]"), '<img src="', $HELP_ICON_URL, '" title="', $HELPER{'moderator'}, '"> </span>' if ($list->ismodpost || $list->ismodsub || $list->isremote);
print '<span class="button">', $q->submit(-name=>'action', -value=>"[$BUTTON{'denylist'}]"), '<img src="', $HELP_ICON_URL, '" title="', $HELPER{'deny'}, '"> </span>' if ($list->isdeny);
print '<span class="button">', $q->submit(-name=>'action', -value=>"[$BUTTON{'allowlist'}]"), '<img src="', $HELP_ICON_URL, '" title="', $HELPER{'allow'}, '"> </span>' if ($list->isallow);
print '<span class="button">', $q->submit(-name=>'action', -value=>"[$BUTTON{'digestsubscribers'}]"), '<img src="', $HELP_ICON_URL, '" title="', $HELPER{'digest'}, '"> </span>' if ($list->isdigest);
print '</p><p>';
print '<span class="button">', $q->submit(-name=>'action', -value=>"[$BUTTON{'webarchive'}]"), '<img src="', $HELP_ICON_URL, '" title="', $HELPER{'webarch'}, '"> </span>' if(&ezmlmcgirc);
print '<span class="button">', $q->submit(-name=>'action', -value=>"[$BUTTON{'configuration'}]"), '<img src="', $HELP_ICON_URL, '" title="', $HELPER{'config'}, '"> </span>';
print '<span class="button">', $q->submit(-name=>'action', -value=>"[$BUTTON{'selectlist'}]"), '</span>';
print '</p>';
print '</div>'; # end of edit->options
print $q->endform;
print '</div>'; # end of edit
$pagedata->setValue("Data.ConfigAvail.Extras", 1) if($list->ismodpost || $list->ismodsub || $list->isremote || $list->isdeny || $list->isallow || $list->isdigest);
$pagedata->setValue("Data.ConfigAvail.Moderation", 1) if ($list->ismodpost || $list->ismodsub || $list->isremote);
$pagedata->setValue("Data.ConfigAvail.DenyList", 1) if ($list->isdeny);
$pagedata->setValue("Data.ConfigAvail.AllowList", 1) if ($list->isallow);
$pagedata->setValue("Data.ConfigAvail.Digest", 1) if ($list->isdigest);
$pagedata->setValue("Data.ConfigAvail.WebArch", 1) if(&ezmlmcgirc);
}
@ -426,7 +404,7 @@ sub delete_list {
closedir DIR;
foreach (@files) {
unless (move($_, "$HOME_DIR/deleted.qmail/")) {
die "Unable to move .qmail files: $!";
error_die("Unable to move .qmail files: $!");
}
}
warn "List '$oldfile' moved (deleted)";
@ -434,13 +412,13 @@ sub delete_list {
# This, however, does DELETE the list. I don't like the idea, but I was
# asked to include support for it so ...
if (!rmtree("$LIST_DIR/$Q::list")) {
die "Unable to delete list: $!";
error_die("Unable to delete list: $!");
}
opendir(DIR, "$HOME_DIR") or die "Unable to get directory listing: $!";
my @files = map { "$HOME_DIR/$1" if m{^(\.qmail.+)$} } grep { /^\.qmail-$listaddress/ } readdir DIR;
closedir DIR;
if (unlink(@files) <= 0) {
die "Unable to delete .qmail files: $!";
&error_die("Unable to delete .qmail files: $!");
}
warn "List '$list->thislist()' deleted";
}
@ -489,7 +467,6 @@ sub check_permission_for_action {
$ret = 0;
}
return $ret;
}
# ------------------------------------------------------------------------
@ -503,7 +480,7 @@ sub add_address {
if (($q->param('addfile')) && ($FILE_UPLOAD)) {
# Sanity check
die "File upload must be of type text/*" unless($q->uploadInfo($q->param('addfile'))->{'Content-Type'} =~ m{^text/});
&error_die("File upload must be of type text/*") unless($q->uploadInfo($q->param('addfile'))->{'Content-Type'} =~ m{^text/});
# Handle file uploads of addresses
my($fh) = $q->param('addfile');
@ -543,7 +520,7 @@ sub add_address {
}
if ($list->sub($add->address(), $part) != 1) {
die "Unable to subscribe to list: $!";
&error_die("Unable to subscribe to list: $!");
}
$count++;
}
@ -563,7 +540,7 @@ sub delete_address {
@address = $q->param('delsubscriber');
if ($list->unsub(@address, $part) != 1) {
die "Unable to unsubscribe from list $list: $!";
&error_die("Unable to unsubscribe from list $list: $!");
}
if($PRETTY_NAMES) {
@ -586,12 +563,16 @@ sub part_subscribers {
my ($i, $list, $listaddress, @subscribers, $moderated, $scrollsize, $type);
$pagename = "config_list";
# Work out the address of this list ...
$list = new Mail::Ezmlm("$LIST_DIR/$Q::list");
$listaddress = &this_listaddress;
$listaddress = &this_listaddress();
if($part eq 'mod') {
# Lets know what is moderated :)
$pagedata->setValue("Data.isModerated",1);
# do we store things in different directories?
my $config = $list->getconfig;
@ -599,65 +580,34 @@ sub part_subscribers {
my($subpath) = $config =~ m{8\s*'([^']+)'};
my($remotepath) = $config =~ m{9\s*'([^']+)'};
my($divclass);
$pagedata->setValue("Data.isPostMod", ($list->ismodpost)? 1 : 0);
$pagedata->setValue("Data.PostModPath", "$postpath");
$divclass = ($postpath)? 'warning' : 'ok';
$moderated .= "<p class=\"$divclass\">[$LANGUAGE{'posting'}]" if ($list->ismodpost);
$moderated .= '<img src="' . $HELP_ICON_URL . '" title="Posting Moderators are stored in a non-standard location (' . $postpath . '). You will have to edit them manually.">' if ($postpath);
$moderated .= '</p>' if ($list->ismodpost);
$pagedata->setValue("Data.isSubMod", ($list->ismodsub)? 1 : 0);
$pagedata->setValue("Data.SubModPath", "$subpath");
$divclass = ($subpath)? 'warning' : 'ok';
$moderated .= "<p class=\"$divclass\">[$LANGUAGE{'subscription'}]" if($list->ismodsub);
$moderated .= '<img src="' . $HELP_ICON_URL . '" title="Subscriber Moderators are stored in a non-standard location (' . $subpath . '). You will have to edit them manually">' if ($subpath);
$moderated .= '</p>' if ($list->ismodsub);
$divclass = ($remotepath)? 'warning' : 'ok';
$moderated .= "<p class=\"$divclass\">[$LANGUAGE{'remoteadmin'}]" if($list->isremote);
$moderated .= '<img src="' . $HELP_ICON_URL . '" title="Remote Administrators are stored in a non-standard location (' . $remotepath . '). You will have to edit them manually">' if ($remotepath);
$moderated .= '</p> if ($list->isremote)';
$pagedata->setValue("Data.isRemote", ($list->isremote)? 1 : 0);
$pagedata->setValue("Data.RemotePath", "$remotepath");
}
# What type of sublist is this?
($type) = $Q::action =~ m/^\[(.+)\]$/;
# Get a list of moderators from ezmlm ...
@subscribers = $list->subscribers($part);
my $i = 0;
my $one_subs;
# TODO: use "pretty" output style for visible mail address
foreach $one_subs ($list->subscribers($part)) {
$pagedata->setValue("Data.List." . $i, "$one_subs");
$i++;
}
$pagedata->setValue("Data.ListCount", "$i");
# Keep selection box a resonable size - suggested by Sebastian Andersson
$scrollsize = 25 if(($scrollsize = $#subscribers + 1) > 25);
$pagedata->setValue("Data.ListName", $q->param('list'));
$pagedata->setValue("Data.ListAddress", "$listaddress");
# Begin of content
print '<div id="parts" class="container">';
# Print out a form of options ...
$q->delete('state');
print '<div class="title">';
print "<h2>$type $LANGUAGE{'for'} $listaddress</h2>";
print '<hr>';
print '</div>'; # end of parts_title
print '<div class="info">', "$moderated", '</div>' if(defined($moderated));
print $q->start_multipart_form;
print $q->hidden(-name=>'state', -default=>$part);
print $q->hidden(-name=>'list', -default=>$Q::list), "\n";
print '<div class="list">', $q->scrolling_list(-name=>'delsubscriber', -size=>$scrollsize, -values=>\@subscribers, -multiple=>'true', -labels=>&pretty_names), '</div>' if defined(@subscribers);
print '<div class="add_remove">';
print '<span class="button">', $q->submit(-name=>'action', -value=>"[$BUTTON{'deleteaddress'}]"), '</span>' if defined(@subscribers);
print '<span class="formfield">', $q->textfield(-name=>'addsubscriber', -size=>'40'), ' <img src="', $HELP_ICON_URL, '" title="', $HELPER{'addaddress'}, '"></span>';
print '<span class="formfield">', $q->filefield(-name=>'addfile', -size=>20, -maxlength=>100), ' <img src="', $HELP_ICON_URL, '" title="', $HELPER{'addaddressfile'}, '"></span>' if ($FILE_UPLOAD);
print '<span class="button">', $q->submit(-name=>'action', -value=>"[$BUTTON{'addaddress'}]"), '</span>';
print '<span class="button">', $q->submit(-name=>'action', -value=>"[$BUTTON{'subscribers'}]"), '</span>';
print '</div>'; # end of parts_subscribers_actions
print $q->endform;
print '</div>'; # end of parts
$pagedata->setValue("Data.Form.State", $q->param('part'));
$pagedata->setValue("Data.FileUploadAllowed", ($FILE_UPLOAD)? 1 : 0);
}
# ------------------------------------------------------------------------
@ -666,6 +616,9 @@ sub allow_create_list {
# Let the user select options for list creation ...
my($username, $hostname, %labels, $j);
# TODO: klaeren wofuer %labels da ist
$pagename = 'create_list';
# Work out if this user has a virtual host and set input accordingly ...
if(-e "$QMAIL_BASE/virtualdomains") {
@ -681,56 +634,22 @@ sub allow_create_list {
$hostname = $DEFAULT_HOST;
}
print '<div id="create" class="container">';
$pagedata->setValue("Data.UserName", "$username");
$pagedata->setValue("Data.HostName", "$hostname");
# Print a form of options ...
$q->delete_all;
print '<div class="title">';
print '<h2>', $LANGUAGE{'createnew'}, '</h2>';
print '<hr>';
print '</div>'; # end of create->title
print $q->startform;
print $q->hidden(-name=>'state', -value=>'create');
print '<div class="input">';
print '<span class="formfield">', $LANGUAGE{'listname'}, ': ', $q->textfield(-name=>'list', -size=>'20'), ' <img src="', $HELP_ICON_URL, '" title="', $HELPER{'listname'}, '"></span>';
print '<span class="formfield">', $LANGUAGE{'listaddress'}, ': ', $q->textfield(-name=>'inlocal', -default=>$username, -size=>'10');
print ' @ ', $q->textfield(-name=>'inhost', -default=>$hostname, -size=>'30'), ' <img src="', $HELP_ICON_URL, '" title="', $HELPER{'listadd'}, '"></span>';
print '<span class="formfield">', $LANGUAGE{'listoptions'}, ':</span>';
# TODO: migrate to cs
&display_options($DEFAULT_OPTIONS);
# Allow creation of mysql table if the module allows it
if($Mail::Ezmlm::MYSQL_BASE) {
print '<span class="formfield">', $q->checkbox(-name=>'sql', -label=>$LANGUAGE{'mysqlcreate'}, -on=>1);
print ' <img src="', $HELP_ICON_URL, '" title="', $HELPER{'mysqlcreate'}, '"></span>';
}
if(-e "$WEBUSERS_FILE") {
print '<span class="formfield">', $LANGUAGE{'allowedtoedit'}, ': ';
print $q->textfield(-name=>'webusers', -value=>$ENV{'REMOTE_USER'}||'ALL', -size=>'30');
print ' <img src="', $HELP_ICON_URL, '" title="', $HELPER{'webusers'}, '"></span>';
print '<span class="help">', $HELPER{'allowedit'}, '</span>';
}
print '</div>'; # end of create->input
print '<div class="question">';
print '<span class="button">', $q->submit(-name=>'action', -value=>"[$BUTTON{'createlist'}]"), '</span>';
print '<span class="button">', $q->reset(-value=>"[$BUTTON{'resetform'}]"), '</span>';
print '<span class="button">', $q->submit(-name=>'action', -value=>"[$BUTTON{'cancel'}]"), '</span>';
print '</div>'; # end of create->question
print $q->endform;
print '</div>'; # end of create
$pagedata->setValue("Data.mysqlModule", ($Mail::Ezmlm::MYSQL_BASE)? 1 : 0);
$pagedata->setValue("Data.WebUser.show", (-e "$WEBUSERS_FILE")? 1 : 0);
$pagedata->setValue("Data.WebUser.UserName", $ENV{'REMOTE_USER'}||'ALL');
}
# ------------------------------------------------------------------------
sub create_list {
# Create a list acording to user selections ...
# Create a list according to user selections ...
# Check the list directory exists and create if necessary ...
if(!-e $LIST_DIR) {
@ -746,7 +665,8 @@ sub create_list {
# Sanity Checks ...
return 1 if ($listname eq '' || $qmail eq '');
if(-e ("$LIST_DIR/$listname/lock") || -e ("$HOME_DIR/.qmail-$qmail")) {
print '<h1 class="warning">', "List '$listname' already exists :(</h1>";
&error_die("Can't create list '$listname', as it already exists");
# TODO: create a language string for this message
return 1;
}
@ -774,13 +694,13 @@ sub create_list {
-switches=>$options,
-user=>$USER)
) {
die 'List creation failed', $list->errmsg();
&error_die('List creation failed' , $list->errmsg());
}
# handle MySQL stuff
if($q->param('sql') && $options =~ m/-6\s+/) {
unless($list->createsql()) {
die 'SQL table creation failed: ', $list->errmsg();
error_die('SQL table creation failed: ' , $list->errmsg());
}
}
@ -794,51 +714,32 @@ sub create_list {
sub list_config {
# Allow user to alter the list configuration ...
my ($list, $listaddress, $listname, $options);
my ($headeradd, $headerremove, $mimeremove, $prefix, $j);
my ($list, $listname);
$pagename = "list_config";
# Store some variables before we delete them ...
$list = new Mail::Ezmlm("$LIST_DIR/$Q::list");
$listname = $q->param('list');
$listaddress = &this_listaddress;
# Begin of content
print '<div id="config" class="container">';
# Print a form of options ...
$q->delete_all;
print '<div class="title">';
print '<h2>', $LANGUAGE{'editconfiguration'}, '</h2>';
print '<hr>';
print '</div>'; # end of config->title
print $q->startform;
print $q->hidden(-name=>'state', -value=>'configuration');
print $q->hidden(-name=>'list', -value=>$listname);
print '<div class="info">';
print '<p>', $LANGUAGE{'listname'}, ": <em>$listname</em></p>";
print '<p>', "$LANGUAGE{'listaddress'}: <em>$listaddress</em></p>";
print '</div>'; # end of config->info
print '<div class="input">';
print '<h2>', $LANGUAGE{'listoptions'}, ':</h2>';
$pagedata->setValue("Data.ListName", "$listname");
$pagedata->setValue("Data.ListAddress", &this_listaddress);
# TODO: migrate
# Print a list of options, selecting the ones that apply to this list ...
&display_options($list->getconfig);
# Get the contents of the headeradd, headerremove, mimeremove and prefix files
$headeradd = $list->getpart('headeradd');
$headerremove = $list->getpart('headerremove');
$mimeremove = $list->getpart('mimeremove');
$prefix = $list->getpart('prefix');
$pagedata->setValue("Data.List.Prefix", $list->getpart('prefix'));
# TODO: die folgenden Zeilen enden in einem Hash anstelle des Inhalts
my $temp = $list->getpart('headeradd');
$pagedata->setValue("Data.List.HeaderAdd", "$temp");
$temp = $list->getpart('headerremove');
$pagedata->setValue("Data.List.HeaderRemove", "$temp");
$temp = $list->getpart('mimeremove');
$pagedata->setValue("Data.List.MimeRemove", "$temp");
print '<span class="formfield">', $LANGUAGE{'prefix'}, ': ', $q->textfield(-name=>'prefix', -default=>$prefix, -size=>12), ' <img src="', $HELP_ICON_URL, '" title="', $HELPER{'prefix'}, '"></span>' if defined($prefix);
print '<p class="formfield">', $LANGUAGE{'headerremove'}, ': <img src="', $HELP_ICON_URL, '" title="', $HELPER{'headerremove'}, '"><br>', $q->textarea(-name=>'headerremove', -default=>$headerremove, -rows=>5, -columns=>70), '</span>';
print '<span class="formfield">', $LANGUAGE{'headeradd'}, ': <img src="', $HELP_ICON_URL, '" title="', $HELPER{'headeradd'}, '"><br>', $q->textarea(-name=>'headeradd', -default=>$headeradd, -rows=>5, -columns=>70), '</div>';
print '<span class="formfield">', $LANGUAGE{'mimeremove'}, ': <img src="', $HELP_ICON_URL, '" title="', $HELPER{'mimeremove'}, '"><br>', $q->textarea(-name=>'mimeremove', -default=>$mimeremove, -rows=>5, -columns=>70), '</span>' if defined($mimeremove);
# TODO: this is definitely ugly - create a new sub!
if(open(WEBUSER, "<$WEBUSERS_FILE")) {
my($webusers);
while(<WEBUSER>) {
@ -847,24 +748,8 @@ sub list_config {
close WEBUSER;
$webusers ||= $ENV{'REMOTE_USER'} || 'ALL';
print '<span class="formfield">', $LANGUAGE{'allowedtoedit'}, ': ';
print $q->textfield(-name=>'webusers', -value=>$webusers, -size=>'30');
print ' <img src="', $HELP_ICON_URL, '" title="', $HELPER{'webusers'}, '"></span>',
print '<span class="help">', $HELPER{'allowedit'}, '</span>';
$pagedata->setValue("Data.List.WebUsers", "$webusers");
}
print '</div>'; # end of config->input
print '<div class="question">';
print '<span class="button">', $q->submit(-name=>'action', -value=>"[$BUTTON{'updateconfiguration'}]"), '</span>';
print '<span class="button">', $q->reset(-value=>"[$BUTTON{'resetform'}]"), '</span>';
print '<span class="button">', $q->submit(-name=>'action', -value=>"[$BUTTON{'cancel'}]"), '</span>';
print '<span class="button">', $q->submit(-name=>'action', -value=>"[$BUTTON{'edittexts'}]"), '</span>';
print '</div>'; # end of config->question
print $q->endform;
print '</div>'; # end of config
}
# ------------------------------------------------------------------------
@ -945,41 +830,27 @@ sub this_listaddress {
sub list_text {
# Show a listing of what is in DIR/text ...
$pagename = 'list_textfiles';
my(@files, $list);
$list = $LIST_DIR . '/' . $q->param('list');
# Read the list directory for text ...
opendir DIR, "$list/text" || die "Unable to read DIR/text: $!";
opendir DIR, "$list/text" || &error_die("Unable to read DIR/text: $!");
@files = grep !/^\./, readdir DIR;
closedir DIR;
# Begin of content
print '<div id="textfiles" class="container">';
$pagedata->setValue("Data.ListName", $q->param('list'));
# Print a form ...
$q->delete('state');
print $q->startform;
print $q->hidden(-name=>'state', -default=>'list_text');
print $q->hidden(-name=>'list', -default=>$q->param('list'));
print '<div class="list">';
print $q->scrolling_list(-name=>'file', -values=>\@files);
print '</div>'; # end of textfiles->list
print '<div class="info">';
print $LANGUAGE{'edittextinfo'};
print '</div>'; # end of textfiles->info
print '<div class="question">';
print '<span class="button">', $q->submit(-name=>'action', -value=>"[$BUTTON{'editfile'}]"), '</span>';
print '<span class="button">', $q->submit(-name=>'action', -value=>"[$BUTTON{'cancel'}]"), '</span>';
print '</div>'; # end of textfiles->question
print $q->endform;
print '</div>';
# TODO: find a better way to set a list ...
my $i = 0;
my $one_file;
foreach $one_file (@files) {
$pagedata->setValue("Data.Files." . $i, "$one_file");
$i++;
}
$pagedata->setValue("Data.FilesCount", "$i");
}
# ------------------------------------------------------------------------
@ -987,42 +858,16 @@ sub list_text {
sub edit_text {
# Allow user to edit the contents of DIR/text ...
$pagename = 'edit_text';
my ($content);
my($list) = new Mail::Ezmlm("$LIST_DIR/$Q::list");
$content = $list->getpart("text/$Q::file");
# Begin of content
print '<div id="edittext" class="container">';
# Print a form ...
$q->delete('state');
print '<div class="title">';
print '<h2>', $LANGUAGE{'editingfile'}, ': ', $Q::file, '</h2>';
print '</div>'; # end of edittext->title
print $q->startform;
print $q->hidden(-name=>'state', -default=>'edit_text');
print $q->hidden(-name=>'list', -default=>$q->param('list'));
print $q->hidden(-name=>'file', -default=>$q->param('file'));
print '<div class="input">';
print '<span class="formfield">', $q->textarea(-name=>'content', -default=>$content, -rows=>'25', -columns=>'72'), '</span>';
print '</div>'; # end of edittext->input
print '<id class="info">';
print $LANGUAGE{'editfileinfo'};
print '</div>'; # end of edittext->info
print '<div class="question">';
print '<span class="button">', $q->submit(-name=>'action', -value=>"[$BUTTON{'savefile'}]"), '</span>';
print '<span class="button">', $q->reset(-value=>"[$BUTTON{'resetform'}]"), '</span>';
print '<span class="button">', $q->submit(-name=>'action', -value=>"[$BUTTON{'cancel'}]"), '</span>';
print '</div>'; # end of edittext->question
print $q->endform;
print '</div>'; # end of edittext
$pagedata->setValue("Data.ListName", $q->param('list'));
# TODO: file wird nurals hash interpretiert
$pagedata->setValue("Data.File.Name", $q->param('file'));
$pagedata->setValue("Data.File.Content", "$content");
}
# ------------------------------------------------------------------------
@ -1087,33 +932,29 @@ sub display_options {
my($opts) = shift;
my($i, $j);
print "<!-- $opts -->";
print '<p>';
# TODO: remove when migration to cs is done
$j = 0;
# convert EZMLM_LABELS to hdf-language values
foreach $i (grep {/\D/} keys %EZMLM_LABELS) {
if ($opts =~ /^\w*$i\w*\s*/) {
print '<span class="checkbox">', $q->checkbox(-name=>$i, -value=>$i, -label=>$EZMLM_LABELS{$i}[0], -on=>'1');
} else {
print '<span class="checkbox">', $q->checkbox(-name=>$i, -value=>$i, -label=>$EZMLM_LABELS{$i}[0]);
}
print '<img src="', $HELP_ICON_URL, '" border="0" title="', $EZMLM_LABELS{$i}[1] , '"></span>';
print '</td>'; $j++;
if ($j >= 3) {
$j = 0; print '</p><p>';
}
$pagedata->setValue("Data.ListOptions." . $i . ".name", "$i");
$pagedata->setValue("Data.ListOptions." . $i . ".short", "$EZMLM_LABELS{$i}[0]");
$pagedata->setValue("Data.ListOptions." . $i . ".long", "$EZMLM_LABELS{$i}[1]");
$pagedata->setValue("Data.ListOptions." . $i . ".state", ($opts =~ /^\w*$i\w*\s*/)? 1 : 0);
$j++;
}
print '</p>';
$pagedata->setValue("Data.ListOptionsCount", "$j");
$j = 0;
# convert EZMLM_LABELS to hdf-language values
foreach $i (grep {/\d/} keys %EZMLM_LABELS) {
print '<p>';
if ($opts =~ /$i (?:'(.+?)')/) {
print '<span class="checkbox">', $q->checkbox(-name=>$i, -value=>$i, -label=>$EZMLM_LABELS{$i}[0], -on=>'1');
} else {
print '<span class="checkbox">', $q->checkbox(-name=>$i, -value=>$i, -label=>$EZMLM_LABELS{$i}[0]);
}
print '<img src="', $HELP_ICON_URL, '" border="0" title="', $EZMLM_LABELS{$i}[1] , '"></span>';
print '<span class="formfield">', $q->textfield(-name=>"$i-value", -value=>$1||$EZMLM_LABELS{$i}[2], -size=>30), '</span>';
print '</p>';
$pagedata->setValue("Data.ListSettings." . $i . ".name", "$i");
$pagedata->setValue("Data.ListSettings." . $i . ".short", "$EZMLM_LABELS{$i}[0]");
$pagedata->setValue("Data.ListSettings." . $i . ".long", "$EZMLM_LABELS{$i}[1]");
$pagedata->setValue("Data.ListSettings." . $i . ".state", ($opts =~ /$i (?:'(.+?)')/)? 1 : 0);
$pagedata->setValue("Data.ListSettings." . $i . ".value", $1||$EZMLM_LABELS{$i}[2]);
$j++;
}
$pagedata->setValue("Data.ListSettingsCount", "$j");
}
@ -1179,9 +1020,17 @@ BEGIN {
quoting the error message above.</p>
</</div>
EOM
}
set_message(\&handle_errors);
sub error_die {
my $msg = @_;
$pagedata->setValue("Data.ErrorMessage", "$msg");
# TODO: besser waere eine Warnung in header.cs
$pagename = 'error';
&output_page;
die;
}
}
# ------------------------------------------------------------------------
@ -1235,6 +1084,7 @@ F<./ezmlmwebrc>
=head1 AUTHOR
Guy Antony Halse <guy-ezmlm@rucus.ru.ac.za>
Lars Kruse <ezmlm-web@sumpfralle.de>
=head1 BUGS

168
lang/en.hdf Normal file
View file

@ -0,0 +1,168 @@
Language = en
PageTitle = ezmlm-web - a mailinglists' administration interface
Lang {
Buttons {
Create = [Create List]
Edit = [Edit]
Delete = [Delete]
Yes = [Yes]
No = [No]
Cancel = [Cancel]
DeleteAddress = [Delete Address]
AddAddress = [Add Address]
Moderators = [Moderators]
DenyList = [Deny List]
AllowList = [Allow List]
DigestSubscribers = [Digest Subscribers]
Configuration = [Configuration]
UpdateConfiguration = [Update Configuration]
EditTexts = [Edit Texts]
EditFile = [Edit File]
SaveFile = [Save File]
WebArchive = [Web Archive]
SelectList = [Select List]
Subscribers = [Subscribers]
ResetForm = [Reset Form]
}
Options {
a.short = Archived
a.long = Ezmlm will archive new messages
b.short = Block archive
b.long = Only moderators are allowed to access the archive
# c => config. This is implicity called, so is not defined here
d.short = Digest
d.long = Set up a digest list to disseminate digest of the list messages
# e => edit. Also implicity called, so not defined here
f.short = Prefix
f.long = Outgoing subject will be prefixed with the list name
g.short = Guard Archive
g.long = Archive access requests from unrecognized SENDERs will be rejected
h.short = Help subscription
h.long = Subscriptions do not require confirmation
i.short = Indexed
i.long = Indexed for WWW archive access
j.short = Jump off
j.long = Unsubscribe does not require confirmation
k.short = Kill
k.long = Posts from addresses in dir/deny/ are rejected
l.short = Subscriber List
l.long = Remote administrators can request a subscriber list
m.short = Message Moderation
m.long = All incoming messages are moderated
n.short = Text Editing
n.long = Allow remote administrators to edit files in dir/text/
o.short = Others rejected
o.long = Posts from addresses other than moderators are rejected
p.short = Public
p.long = List will respond to administrative requests and archive retrieval
q.short = Service Request Address
q.long = Process commands sent in the subject to local-request@host
r.short = Remote Admin
r.long = Enable remote adminstration of the list
s.short = Subscription Moderation
s.long = Subscriptions to the main list and digest will be moderated
t.short = Trailer
t.long = Add a trailer to outgoing messages
u.short = User Posts Only
u.long = Posts from unrecognized SENDER addresses will be rejected
# v => version. I doubt you will really need this ;-)
w.short = Remove Warn
w.long = Remove the ezmlm-warn(1) invocations from the list setup. It is assumed that ezmlm-warn(1) is run by other means
x.short = Extra
x.long = Strip certain mimetypes, etc
# y => not used
# z => not used
}
Settings {
0.short = Sublist
0.long = Make the list a sublist of list mainlist@host
0.default = mainlist@host
# 1 => not used
# 2 => not used
3.short = From Address
3.long = Replace the &quot;From:&quot; header of the message with &quot;From: fromarg&quot;
3.default = fromarg
4.short = Digest Options
4.long = Switches for ezmlm-tstdig(1)
4.default = -t24 -m30 -k64
5.short = List Owner
5.default = The email address of the list owner
6.short = SQL Database
6.long = SQL database connect information. Requires SQL support
6.default = host:port:user:password:datab:table
7.short = Message Moderation Path
7.long = Make /path the path to the database for message moderators, if the list is set up for message moderation
7.default = /some/full/path
8.short = Subscription Moderation Path
8.long = Make /path the path to the database for message moderators, if the list is set up for message moderation
8.default = /some/full/path
9.short = Remote Admin Path
9.long = Make /path the path to the database for message moderators, if the list is set up for message moderation
9.default = /some/full/path
}
Helper {
AddAddress = You may enter any RFC822 compliant email address here, including the comment part. For example; 'J Random User <jru@on.web.za>'
AddAddressFile = or you may enter the filename of a plain text file containing multiple RFC822 email addresses, one per line
Moderator = Moderators: people who control who may subscribe or post to a list
Deny = Deny: A list of addresses that are _never_ allowed to mail the list
Allow = Allow: A list of address that are allowed to mail the list even if the configuration otherwise restricts it
Digest = Digest: People who will recieve a digest of all messages on the list
WebArch = View the web based archive of this list
Config = This lets you alter the way the list is set up
ListName = This is the name of the list as displayed on the Select Lists screen. It is also the name of the subdirectory that contains the list
ListAdd = This is the email address of the list. Note that the defaults come from your qmail config. You should just update the local part (before the @)
WebUsers = NB! At this stage, any users specified here must exist. User creation may be added in future versions
Prefix = Text to add to the subject line of all outgoing messages
HeaderRemove = This is a list of headers to remove from all outgoing mail
HeaderAdd = This is a list of headers to add to all outging mail
MimeRemove = All messages whose Content-Type matches these mime types will be bounced back to sender
AllowEdit = Comma separated list of usernames, or 'ALL' (all valid users)
MysqlCreate = This will create the necessary MySQL tables if the list configuration above requires it
SelectList = Go back to list selection
}
Misc {
ListSelectDescription {
1 = choose a mailing list from the selection box or click on [Create List]
2 = click on the [Edit] button if you want to edit the selected list
3 = click on the [Delete] button if you want to delete the selected list
}
UnknownAction = Action not yet implemented
ConfirmDelete = Confirm deletion of
SubscribersTo = Subscribers to
Subscribers = subscribers
AdditionalParts = Additional list parts
Posting = Posting
Subscription = Subscription
RemoteAdmin = Remote Admin
For = for
# as in; "moderators for ..."
CreateNew = Create a New List
ListName = List Name
ListAddress = List Address
ListOptions = List Options
AllowedToEdit = Users allowed to edit this list
EditConfiguration = Edit the List Configuration
Prefix = Subject prefex for outgoing messages
HeaderRemove = Headers to strip from all outgoing mail
HeaderAdd = Headers to add to all outgoing mail
MimeRemove = Mime types to strip from all outgoing mail
EditTextInfo = The box on the left contains a list of files available in the DIR/text directory. These files are sent out in response to specfic user request, or as part of all outgoing messages<br/>To edit a file, select its name from the box. Then click on the [Edit File] button. Press [cancel] when you have finished editing.
EditingFile = Editing File
EditFileInfo = <big><strong>ezmlm-manage</strong></big><br><tt><strong>&lt;#l#&gt;</strong></tt> The list name<br><tt><strong>&lt;#A#&gt;</strong></tt>The subscription address<br><tt><strong>&lt;#R#&gt;</strong></tt> The address a subscriber must reply to<p/><big><strong>ezmlm-store</strong></big><br><tt><strong>&lt;#l#&gt;</strong></tt> The list name<br/><tt><strong>&lt;#A#&gt;</strong></tt>The acceptance address<br/><tt><strong>&lt;#R#&gt;</strong></tt> The rejection address</ul>
mysqlCreate = Create the MySQL database tables if necessary
SuggestEdit = You will have to edit them manually.
PostModPathWarn = Posting Moderators are stored in a non-standard location
SubModPathWarn = Subscriber Moderators are stored in a non-standard location
RemotePathWarn = Remote Administrators are stored in a non-standard location
}
}

58
template/config_list.cs Normal file
View file

@ -0,0 +1,58 @@
<div id="parts" class="container">
<div class="title">
<!-- TODO: einheitliche Formatierung fuer listaddress - span und css -->
<h2><?cs var:Lang.Misc.For <i><?cs var:Data.ListName ?></i></h2>
<h3><?cs var:Data.ListAddress ?></h3>
<hr>
</div>
<!-- Moderation -->
<?cs if:Data.isModerated ?>
<?cs include:TemplateDir + "modpath_info.cs" ?>
<?cs /if ?>
<!-- form -->
<form method="post" action="<?cs var:ScriptName ?>" enctype="application/x-www-form-urlencoded">
<input type="hidden" name="state" value="<?cs var:Data.Form.State ?>">
<input type="hidden" name="list" value="<?cs var:Data.ListName ?>">
<div class="list">
# TODO: the same as of "display_list.cs"
# list of moderators/administrators
<?cs if:Data.ListCount >0 ?>
<!-- Keep selection box a resonable size - suggested by Sebastian Andersson -->
<?cs if:(Data.ListCount > 25) ?>
<?cs set:Data.ScrollSize = 25 ?>
<?cs else ?>
<?cs set:Data.ScrollSize = Data.ListCount ?>
<?cs /if ?>
<select name="delsubscriber" tabindex="1" multiple="true" size="<?cs var:Data.ScrollSize ?>">
<?cs each:item = Data.List ?>
<!-- TODO: pretty names sind notwendig -->
<option><?cs var:item ?></option>
<?cs /each ?>
</select>
<?cs /if ?>
<div class="add_remove">
<?cs if:Data.ListCount > 0) ?>
<span class="button"><input type="submit"
value="<?cs var:Lang.Buttons.DeleteAddress ?>" name="action"/></span>
<?cs /if ?>
<span class="formfield">
<input type="text" name="addsubscriber" size="40"/> <?cs call:help_icon("AddAddress") ?></span>
<?cs if:FileUploadAllowed ?><span class="formfield">
<input type="filefield" name="addfile" size="20" maxlength="100"/> <?cs call:help_icon("AddAddressFile") ?></span><?cs /if ?>
<span class="button">
<input type="submit" name="action" value="<?cs var:Lang.Buttons.AddAddress ?>"/></span>
<span class="button">
<input type="submit" name="action" value="<?cs var:Lang.Buttons.Subscribers ?>"/></span>
</div>
</form>
</div>

View file

@ -0,0 +1,17 @@
<div id="delete" class="container">
<form method="post" action="<?cs var:ScriptName ?>" enctype="application/x-www-form-urlencoded">
<input type="hidden" name="state" value="confirm_delete">
<input type="hidden" name="list" value="<?cs var:Data.ListName ?>">
<div class="title">
<h2><?cs var:Lang.Misc.ConfirmDelete ?> <i><?cs var:Data.ListName ?></i></h2>
<div class="question">
<span class="button"><input type="submit" name="confirm"
value="<?cs var:Lang.Buttons.Yes ?>" tabindex="1"></span>
<span class="button"><input type="submit" name="confirm"
value="<?cs var:Lang.Buttons.No ?>" tabindex="2"></span>
</div>
</div>
</form>
</div>

43
template/create_list.cs Normal file
View file

@ -0,0 +1,43 @@
<div id="create" class="container">
<div class="title">
<h2><?cs var:Lang.Misc.CreateNew ?></h2>
<hr>
</div>
<form method="post" action="<?cs var:ScriptName ?>" enctype="application/x-www-form-urlencoded">
<input type="hidden" name="state" value="create">
<div class="input">
<span class="formfield"><?cs var:Lang.Misc.ListName ?>: <input type="text" name="list" size="20"><?cs call:help_icon("ListName") ?></span>
<span class="formfield"><?cs var:Lang.Misc.ListAddress ?>: <input type="text" name="inlocal" size="10" value="<?cs var:Data.UserName ?>">
<?cs call:help_icon("ListName") ?> @ <input type="text" name="inhost" value="<?cs var:Data.HostName ?>" size="30"><?cs call:help_icon("ListAdd") ?></span>
<span class="formfield"><?cs var:Lang.Misc.ListOptions ?>:</span>
<?cs include:TemplateDir + "display_options.cs" ?>
<?cs if:Data.mysqlModule ?>
<!-- Allow creation of mysql table if the module allows it -->
<span class="formfield"><input type="checkbox" name="sql"label="<?cs var:Lang.Misc.mysqlCreate ?>" on="1"><?cs call:help_icon("mysqlCreate") ?></span>
<?cs /if ?>
<?cs if:Data.WebUser.show ?>
<span class="formfield"><?cs var:Lang.Misc.AllowedToEdit ?>: <input type="text"
name="webusers" size="30" value="<?cs var:Data.WebUser.UserName ?>">
<?cs call:help_icon("WebUsers") ?></span>
# TODO: the following span is quite unusual
<span class="help"><?cs var:Lang.Helper.AllowEdit ?></span>
<?cs /if ?>
</div>
<div class="question">
<span class="button"><input type="submit" name="action"
value="<?cs var:Lang.Buttons.Create ?>"></span>
<span class="button"><input type="reset" name="action"
value="<?cs var:Lang.Buttons.ResetForm ?>"></span>
<span class="button"><input type="submit" name="action"
value="<?cs var:Lang.Buttons.Cancel ?>"></span>
</div>
</form>
</div>

100
template/display_list.cs Normal file
View file

@ -0,0 +1,100 @@
<div id="edit" class="container">
<div class="title">
<h2><?cs var:Lang.Misc.SubscribersTo ?> <i><?cs var:Data.ListName ?></i></h2>
<h3><?cs var:Data.ListAddress ?></h3>
<hr>
</div>
<div class="list">
<form method="post" action="<?cs var:ScriptName ?>" enctype="application/x-www-form-urlencoded">
<input type="hidden" name="state" value="edit">
<input type="hidden" name="list" value="<?cs var:Data.ListName ?>">
<!-- scrollbox for list's subscribers -->
<!-- Keep selection box a reasonable size - suggested by Sebastian Andersson -->
<?cs if:(Data.SubscribersCount > 25) ?>
<?cs set:Data.ScrollSize = 25 ?>
<?cs else ?>
<?cs set:Data.ScrollSize = Data.SubscribersCount ?>
<?cs /if ?>
<select name="delsubscriber" tabindex="1" size="<?cs var:Data.ScrollSize ?>" multiple="yes">
<?cs each:item = Data.Subscribers ?>
<option><?cs var:item ?></option>
<?cs /each ?>
</select>
<div class="add_remove">
<?cs if:(Data.SubscribersCount > 0) ?>
<p><?cs var:Data.SubscribersCount ?> <?cs var:Lang.Misc.Subscribers ?></p>
<span class="button"><input type="submit" name="action" tabindex="2"
value="<?cs var:Lang.Buttons.DeleteAddress ?>"></span>
<?cs /if ?>
<span class="formfield"><input type="text" name="addsubscriber"
tabindex="3" size="40"/><?cs call:help_icon("AddAddress") ?></span>
<!-- TODO: eventuell ein BR einfuegen -->
<span class="formfield"><input type="file" name="addfile" size="20"
maxlength="100" tabindex="4"/><?cs call:help_icon("AddAddressFile") ?></span>
<span class="button"><input type="submit" tabindex="5" name="action"
value="<?cs var:Lang.Buttons.AddAddress ?>"/></span>
</div>
<div class="options">
<?cs if:Data.ConfigAvail.Extras ?>
<!-- at least one extra config option is available -->
<h3><?cs var:Lang.Misc.AdditionalParts ?>:</h3>
<?cs /if ?>
<p>
<?cs if:Data.ConfigAvail.Moderation ?>
<!-- moderation -->
<span class="button"><input type="submit" tabindex="6" name="action"
value="<?cs var:Lang.Buttons.Moderators ?>"/>
<?cs call:help_icon("Moderator") ?></span>
<?cs /if ?>
<?cs if:Data.ConfigAvail.DenyList ?>
<!-- deny lists -->
<span class="button"><input type="submit" tabindex="7" name="action"
value="<?cs var:Lang.Buttons.DenyList ?>"/>
<?cs call:help_icon("Deny") ?></span>
<?cs /if ?>
<?cs if:Data.ConfigAvail.AllowList ?>
<!-- allow lists -->
<span class="button"><input type="submit" tabindex="8" name="action"
value="<?cs var:Lang.Buttons.AllowList ?>"/>
<?cs call:help_icon("Allow") ?></span>
<?cs /if ?>
<?cs if:Data.ConfigAvail.Digest ?>
<!-- digest subscribers -->
<span class="button"><input type="submit" tabindex="9" name="action"
value="<?cs var:Lang.Buttons.DigestSubscribers ?>"/>
<?cs call:help_icon("Digest") ?></span>
<?cs /if ?>
</p>
<p>
<!-- web archive -->
<?cs if:Data.ConfigAvail.WebArch ?>
<span class="button"><input type="submit" tabindex="10" name="action"
value="<?cs var:Lang.Buttons.WebArchive ?>"/>
<?cs call:help_icon("WebArch") ?></span>
<?cs /if ?>
<!-- extra config options -->
<span class="button"><input type="submit" tabindex="11" name="action"
value="<?cs var:Lang.Buttons.Configuration ?>"/>
<?cs call:help_icon("Config") ?></span>
<span class="button"><input type="submit" tabindex="12" name="action"
value="<?cs var:Lang.Buttons.SelectList ?>"/>
<?cs call:help_icon("SelectList") ?></span>
</p>
</div>
</form>
</div>
</div>

View file

@ -0,0 +1,23 @@
<!-- $opts -->
<p>
<!-- TODO: das sollte so etwas, wie eine Tabelle werden -->
<?cs each:item = Data.ListOptions ?>
<div class="checkbox"><input type="checkbox"
name="<?cs var:item.name ?>" value="<?cs var:item.name ?>"
<?cs if:item.state ?> checked="checked"<?cs /if ?>>
<?cs var:item.short ?><?cs call:generic_icon(item.long) ?></div>
<?cs /each ?>
</p>
<p>
<?cs each:item = Data.ListSettings ?>
<div class="checkbox"><input type="checkbox" name="<?cs var:item.name ?>"
value="<?cs var:item.name ?>"<?cs if:item.state ?> checked="checked"<?cs /if ?>>
<?cs var:item.short ?>
<span class="formfield"><input type="text" name="<?cs var:item.name ?>-value"
value="<?cs var:item.value ?>" size="30">
<?cs call:generic_icon(item.long) ?></div>
<!-- TODO: die indirekte Namensangabe des textfield is unsauber - sollte nicht
mit dem Code vermischt sein -->
<?cs /each ?>
</p>

32
template/edit_text.cs Normal file
View file

@ -0,0 +1,32 @@
<div id="edittext" class="container">
<div class="title">
<h2><?cs var:Lang.Misc.EditingFile ?> <?cs var:Data.File.Name ?></h2>
</div>
<form method="post" action="<?cs var:ScriptName ?>" enctype="application/x-www-form-urlencoded">
<input type="hidden" name="state" value="edit_text">
<input type="hidden" name="list" value="<?cs var:Data.ListName ?>">
<input type="hidden" name="file" value="<?cs var:Data.File.Name ?>">
<div class="input">
<span class="formfield"><textarea name="content"
rows="20" cols="72"><?cs var:Data.File.Content ?></textarea></span>
</div>
<div class="info">
<?cs var:Lang.Misc.EditFileInfo ?>
</div>
<div class="question">
<span class="button"><input type="submit" name="action"
value="<?cs var:Lang.Buttons.SaveFile ?>"></span>
<span class="button"><input type="reset" name="action"
value="<?cs var:Lang.Buttons.ResetForm ?>"></span>
<span class="button"><input type="submit" name="action"
value="<?cs var:Lang.Buttons.Cancel ?>"></span>
</div>
</form>
</div>

9
template/footer.cs Normal file
View file

@ -0,0 +1,9 @@
</td></tr></table>
<table border="0" cellpadding="5" cellspacing="5" align="center" width="99%">
<tr><td bgcolor="#e0e0ff"><font size="-1">
<a href="https://systemausfall.org/toolforge/ezmlm-web" target="_blank">ezmlm-web</a> (v2.3) A web interface to <a href="http://www.ezmlm.org/" target="_blank">ezmlm</a></font>
</td></tr></table>
</body>
</html>

25
template/header.cs Normal file
View file

@ -0,0 +1,25 @@
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title><?cs var:PageTitle ?></title>
<meta http-equiv="pragma" content="no-cache" /> <!-- for browsers -->
<meta http-equiv="cache-control" content="no-cache" /> <!-- for proxys -->
<meta http-equiv="content-language" content="<?cs var:Language ?>" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="Author" content="guy-ezmlm[at]rucus.ru.ac.za" />
<meta http-equiv="expire" content="-1d" />
<link rel="stylesheet" type="text/css" href="<?cs var:Stylesheet ?>" />
</head>
<body>
<p>
<center><table border="3" align="center" cellpadding="5"><tr><td bgcolor="#e0e0ff"><font size=+3 color=#000080><strong>E Z Mailing List Manager</strong></font></td></tr></table></center>
</p>
<table border="0" cellpadding="5" cellspacing="5" align="center" width="99%"><tr><td bgcolor="#e0e0ff">

57
template/list_config.cs Normal file
View file

@ -0,0 +1,57 @@
<div id="config" class="container">
<div class="title">
<h2><?cs var:Lang.Misc.EditConfiguration ?></h2>
<hr>
</div>
<form method="post" action="<?cs var:ScriptName ?>" enctype="application/x-www-form-urlencoded">
<input type="hidden" name="state" value="configuration">
<input type="hidden" name="list" value="<?cs var:Data.ListName ?>">
<div class="info">
<p><?cs var:Lang.Misc.ListName ?>: <em><?cs var:Data.ListName ?></em></p>
<p><?cs var:Lang.Misc.ListAddress ?>: <em><?cs var:Data.ListAddress ?></em></p>
</div>
<div class="input">
<h2><?cs var:Lang.Misc.ListOptions ?> :</h2>
<?cs include:TemplateDir + "display_options.cs" ?>
<?cs if:Data.List.Prefix ?>
<div class="formfield"><?cs var:Lang.Misc.Prefix ?>: <input type="text" name="prefix"
value="<?cs var:Data.List.Prefix ?>" size="12"><?cs call:help_icon("Prefix") ?></div>
<?cs /if ?>
<div class="formfield"><?cs var:Lang.Misc.HeaderRemove ?>:<?cs call:help_icon("HeaderRemove") ?>
<br/><textarea name="headerremove" rows="5" cols="70"><?cs var:Data.List.HeaderRemove ?></textarea></div>
<div class="formfield"><?cs var:Lang.Misc.HeaderAdd ?>:<?cs call:help_icon("HeaderAdd") ?>
<br/><textarea name="headeradd" rows="5" cols="70"><?cs var:Data.List.HeaderAdd ?></textarea></div>
<?cs if:Data.List.MimeRemove ?>
<div class="formfield"><?cs var:Lang.Misc.MimeRemove ?>:<?cs call:help_icon("MimeRemove") ?>
<br/><textarea name="mimeremove" rows="5" cols="70"><?cs var:Data.List.MimeRemove ?></textarea></div>
<?cs /if ?>
<?cs if:Data.List.WebUsers ?>
<div>
<span class="formfield"><?cs var:Lang.Misc.AllowedToEdit ?>: <input type="text"
name="webusers" value="<?cs var:Data.List.WebUsers ?>" size="30">
<cs call:help_icon("WebUsers") ?></span>
<span class="help"><?cs var:Lang.Helper.AllowEdit ?></span>
</div>
<?cs /if ?>
</div>
<div class="question">
<span class="button"><input type="submit" name="action"
value="<?cs var:Lang.Buttons.UpdateConfiguration ?>"></span>
<span class="button"><input type="reset" name="action"
value="<?cs var:Lang.Buttons.ResetForm ?>"></span>
<span class="button"><input type="submit" name="action"
value="<?cs var:Lang.Buttons.Cancel ?>"></span>
<span class="button"><input type="submit" name="action"
value="<?cs var:Lang.Buttons.EditTexts ?>"></span>
</div>
</form>
</div>

View file

@ -0,0 +1,28 @@
<div id="textfiles" class="container">
<form method="post" action="<?cs var:ScriptName ?>" enctype="application/x-www-form-urlencoded">
<input type="hidden" name="state" value="list_text">
<input type="hidden" name="list" value="<?cs var:Data.ListName ?>">
<div class="list">
<select name="file" tabindex="1" size="25">
<?cs each:item = Data.Files ?>
<option><?cs var:item ?></option>
<?cs /each ?>
</select>
</div>
<div class="info">
<?cs var:Lang.Misc.EditTextInfo ?>
</div>
<div class="question">
<span class="button"><input type="submit" name="action"
value="<?cs var:Lang.Buttons.EditFile ?>"></span>
<span class="button"><input type="submit" name="action"
value="<?cs var:Lang.Buttons.Cancel ?>"></span>
</div>
</form>
</div>

11
template/macros.cs Normal file
View file

@ -0,0 +1,11 @@
<?cs def:help_icon(helpname) ?>
<?cs each:item = Lang.Helper ?>
<?cs if:(name(item) == helpname) ?>
&nbsp<img src="<?cs var:HelpIconURL ?>" title="<?cs var:item ?>"/>
<?cs /if ?>
<?cs /each ?>
<?cs /def ?>
<?cs def:generic_icon(helptext) ?>
&nbsp<img src="<?cs var:HelpIconURL ?>" title="<?cs var:helptext ?>"/>
<?cs /def ?>

30
template/modpath_info.cs Normal file
View file

@ -0,0 +1,30 @@
<div class="info">
<!-- posting moderation -->
<?cs if:Data.isPostMod ?>
<p class="<?cs if:Data.PostModPath ?>warning<?cs else ?>ok<?cs /if ?>"><?cs var:Lang.Misc.Posting ?>
<?cs if:Data.PostModPath ?>
<?cs var:Lang.Misc.PostModPathWarn ?>(<?cs var:Data.PostModPath ?>). <?cs var:SuggestEdit ?>
<?cs /if ?>
</p>
<?cs /if ?>
<!-- subscription moderation -->
<?cs if:Data.isSubMod ?>
<p class="<?cs if:Data.SubModPath ?>warning<?cs else ?>ok<?cs /if ?>"><?cs var:Lang.Misc.Subscription ?>
<?cs if:Data.SubModPath ?>
<?cs var:Lang.Misc.SubModPathWarn ?>(<?cs var:Data.SubModPath ?>). <?cs var:SuggestEdit ?>
<?cs /if ?>
</p>
<?cs /if ?>
<!-- remote administration -->
<?cs if:Data.isRemote ?>
<p class="<?cs if:Data.RemotePath ?>warning<?cs else ?>ok<?cs /if ?>"><?cs var:Lang.Misc.RemoteAdmin ?>
<?cs if:Data.RemotePath ?>
<?cs var:Lang.Misc.RemotePathWarn ?>(<?cs var:Data.RemotePath ?>). <?cs var:SuggestEdit ?>
<?cs /if ?>
</p>
<?cs /if ?>
</div>

61
template/select_list.cs Normal file
View file

@ -0,0 +1,61 @@
<?cs if:(Status == "unknown action") ?>
<!-- the chosen action is not specified -->
<div class="error">
<h1><?cs var:Data.Action ?></h1>
<h2><?cs var:Lang.Misc.UnknownAction ?></h2>
</div>
<?cs else ?>
<!-- print available lists and administrative buttons -->
<div id="main" class="container">
<!-- TODO: die URL des cgi ersetzen - DRINGEND! -->
<form method="post" action="<?cs var:ScriptName ?>" enctype="application/x-www-form-urlencoded">
<input type="hidden" name="state" value="select">
<?cs if:(Data.ListsCount > 0) ?>
<!-- scrollbox for available lists -->
<div class="list">
<!-- Keep selection box a resonable size - suggested by Sebastian Andersson -->
<?cs if:(Data.ListsCount > 25) ?>
<?cs set:Data.ScrollSize = 25 ?>
<?cs else ?>
<?cs set:Data.ScrollSize = Data.ListsCount ?>
<?cs /if ?>
<select name="list" tabindex="1" size="<?cs var:Data.ScrollSize ?>">
<?cs each:item = Data.Lists ?>
<option><?cs var:item ?></option>
<?cs /each ?>
</select>
</div>
<?cs /if ?>
<!-- short description -->
<div class="info">
<ul>
<?cs each:item = Lang.Misc.ListSelectDescription ?>
<li><?cs var:item ?></li>
<?cs /each ?>
</ul>
</div>
<!-- the buttons -->
<div class="add_remove">
<?cs if:(Data.Permissions.Create == 1) ?>
<!-- button "create" -->
<span class="button"><input type="submit" tabindex="2" name="action"
value="<?cs var:Lang.Buttons.Create ?>" /></span>
<?cs /if ?>
<?cs if:(Data.ListsCount > 0) ?>
<!-- buttons: "edit" and "delete" -->
<span class="button"><input type="submit" tabindex="3" name="action"
value="<?cs var:Lang.Buttons.Edit ?>" /></span>
<span class="button"><input type="submit" tabindex="4" name="action"
value="<?cs var:Lang.Buttons.Delete ?>" /></span>
<?cs /if ?>
</div>
</form>
</div>
<?cs /if ?>