* Mon May 05 2025 Brian Read <brianr@koozali.org> 11.0.0-2.sme

- Add first go at SM2 panels [SME: 13000]
This commit is contained in:
Brian Read 2025-05-07 13:13:58 +01:00
parent c3a2201fae
commit 54a0eb3665
6 changed files with 352 additions and 133 deletions

View File

@ -111,27 +111,27 @@ my $pdb;
return %ret;
}
sub get_data_for_panel_RULES {
# Return a hash with the fields required which will be loaded into the shared data
my $c = shift;
my %ret = (
'Data1'=>'Data for RULES', #Example
# fields from Inputs in RULES $fields['RULES']
'basis'=>'basis contents',
'criterion'=>'criterion contents',
'basis2'=>'basis2 contents',
'criterion2'=>'criterion2 contents',
'action'=>'action contents',
'deliver'=>'deliver contents',
'folder'=>'folder contents',
'copy'=>'copy contents',
'action2'=>'action2 contents',
'deliver2'=>'deliver2 contents',
'key'=>'key contents',
);
return %ret;
}
sub get_data_for_panel_RULES {
# Return a hash with the fields required which will be loaded into the shared data
my $c = shift;
my $pdb = esmith::ConfigDB->open('processmail') or die "Could not open processmail DB\n";
my $PanelUser = $c->get_panel_user();
my $key = $c->param('Selected');
# Get the rule object from the DB
my $rule = $pdb->get($key);
return () unless $rule;
# Use the new routine to get rule data
my $rule_info = get_rule_from_db($c, $rule);
# Add/override any fields specific to the panel as needed
my %ret = (
%$rule_info,
);
return %ret;
}
sub get_data_for_panel_REMOVE {
# Return a hash with the fields required which will be loaded into the shared data
@ -167,72 +167,36 @@ my $pdb;
);
sub actual_getAllRules {
my $c = shift;
my @ret = ();
# Actual code for extracting getAllRules
$cdb = esmith::ConfigDB->open();
$adb = esmith::AccountsDB->open();
$pdb = esmith::ConfigDB->open('processmail') or die "Could not open processmail DB\n";
my $PanelUser = $c->get_panel_user();
my $c = shift;
my @data;
# Open the required databases
my $cdb = esmith::ConfigDB->open();
my $adb = esmith::AccountsDB->open();
my $pdb = esmith::ConfigDB->open('processmail') or die "Could not open processmail DB\n";
my $PanelUser = $c->get_panel_user();
my @rules = $pdb->get_all_by_prop(type => "$PanelUser");
return $c->l("NO_RULES") if (@rules == 0);
foreach my $rule (@rules)
{
my $key = $rule->key;
my $basis = $rule->prop("basis") || '';
my $basis2 = $rule->prop("basis2") || '';
my $deliver = $rule->prop("deliver") || '';
my $deliver2 = $rule->prop("deliver2") || '';
my $action = $rule->prop("action") || '';
my $action2 = $rule->prop("action2") || '';
my $folder = ("$action" eq "sort" )? $deliver : '';
$folder = "INBOX" if "$folder" eq "" && "$action" eq "sort";
my $copy = $rule->prop("copy") || '';
my $oldpmRule = '';
for ($basis, $basis2)
{
if ($_ eq '<')
{ $_ = 'sizelt'; }
elsif ($_ eq '>')
{ $_ = 'sizegt'; }
}
foreach my $rule (@rules) {
# Get the rule info as a hashref using the new routine
my $rule_info = get_rule_from_db($c, $rule);
# except restore the folder into deliver
if ($rule_info->{action} eq 'sort'){
$rule_info->{deliver} = $rule_info->{folder};
}
# Add any extra fields needed for the UI
$rule_info->{Modify} = "<a href=mailsortingd?trt=RULES&account=$PanelUser&Selected=$rule_info->{key}>".$c->l('MODIFY')."</a>";
$rule_info->{Remove} = "<a href=mailsortingd?trt=REMOVE&account=$PanelUser&Selected=$rule_info->{key}>".$c->l('REMOVE')."</a>";
# If you want to keep these for compatibility (though they seem odd)
$rule_info->{a} = $a if defined $a;
$rule_info->{b} = $b if defined $b;
$rule_info->{c} = $c;
my $b1 = $c->l($basis);
my $b2 = $c->l($basis2);
my $copyto = $rule->prop("deliver2") || '';# useless
if (($copy eq 'yes') && ($action2 eq 'inbox'))
{ $deliver2 = ""; $copyto = 'inbox'; } # copyto is useless
$deliver = GetDisplayName($deliver);
$deliver2 = GetDisplayName($deliver2);
$key = $rule->key;
push @data,
{
key => $key,
basis => $basis,
basis2 => $basis2,
criterion => $rule->prop("criterion") || '',
criterion2 => $rule->prop("criterion2") || '',
deliver => $deliver,
deliver2 => $deliver2,
folder => $folder,
action => $action,
action2 => $action2,
copy => $copy,
Modify => "<a href=mailsortingd?trt=RULES&account=$PanelUser&Selected=$key>".$c->l('MODIFY')."</a>",
Remove => "<a href=mailsortingd?trt=REMOVE&account=$PanelUser&Selected=$key>".$c->l('REMOVE')."</a>",
b1 => $b1,
b2 => $b2,
a => $a,
b => $b,
c => $c,
}
push @data, $rule_info;
}
return @data;
return @data;
}
sub get_getAllRules {
@ -310,34 +274,35 @@ sub get_getAllRules {
sub perform_RULES {
my $c = shift;
my $ms_data = shift; #Data hash as parameter
my $ret = "";
my $db = $cdb; #maybe one of the others
my $dbkey = 'ChangeThis';
# To make it write to DB as comment, delete this (regex) string in each if statement "TRUE\) \#copy or perform with value: .* e.g."
if (! TRUE) #copy or perform with value: basis e.g. $db->set_prop($dbkey,'basis',$c->param('basis'),type=>'service'))
{$ret .= 'Perform/save failed for basis';}
if (! TRUE) #copy or perform with value: criterion e.g. $db->set_prop($dbkey,'criterion',$c->param('criterion'),type=>'service'))
{$ret .= 'Perform/save failed for criterion';}
if (! TRUE) #copy or perform with value: basis2 e.g. $db->set_prop($dbkey,'basis2',$c->param('basis2'),type=>'service'))
{$ret .= 'Perform/save failed for basis2';}
if (! TRUE) #copy or perform with value: criterion2 e.g. $db->set_prop($dbkey,'criterion2',$c->param('criterion2'),type=>'service'))
{$ret .= 'Perform/save failed for criterion2';}
if (! TRUE) #copy or perform with value: action e.g. $db->set_prop($dbkey,'action',$c->param('action'),type=>'service'))
{$ret .= 'Perform/save failed for action';}
if (! TRUE) #copy or perform with value: deliver e.g. $db->set_prop($dbkey,'deliver',$c->param('deliver'),type=>'service'))
{$ret .= 'Perform/save failed for deliver';}
if (! TRUE) #copy or perform with value: folder e.g. $db->set_prop($dbkey,'folder',$c->param('folder'),type=>'service'))
{$ret .= 'Perform/save failed for folder';}
if (! TRUE) #copy or perform with value: copy e.g. $db->set_prop($dbkey,'copy',$c->param('copy'),type=>'service'))
{$ret .= 'Perform/save failed for copy';}
if (! TRUE) #copy or perform with value: action2 e.g. $db->set_prop($dbkey,'action2',$c->param('action2'),type=>'service'))
{$ret .= 'Perform/save failed for action2';}
if (! TRUE) #copy or perform with value: deliver2 e.g. $db->set_prop($dbkey,'deliver2',$c->param('deliver2'),type=>'service'))
{$ret .= 'Perform/save failed for deliver2';}
if (! TRUE) #copy or perform with value: key e.g. $db->set_prop($dbkey,'key',$c->param('key'),type=>'service'))
{$ret .= 'Perform/save failed for key';}
if ($ret eq "") {$ret = 'ok';}
my $ret = $c->save_rule();
#my $db = $cdb; #maybe one of the others
#my $dbkey = 'ChangeThis';
## To make it write to DB as comment, delete this (regex) string in each if statement "TRUE\) \#copy or perform with value: .* e.g."
#if (! TRUE) #copy or perform with value: basis e.g. $db->set_prop($dbkey,'basis',$c->param('basis'),type=>'service'))
#{$ret .= 'Perform/save failed for basis';}
#if (! TRUE) #copy or perform with value: criterion e.g. $db->set_prop($dbkey,'criterion',$c->param('criterion'),type=>'service'))
#{$ret .= 'Perform/save failed for criterion';}
#if (! TRUE) #copy or perform with value: basis2 e.g. $db->set_prop($dbkey,'basis2',$c->param('basis2'),type=>'service'))
#{$ret .= 'Perform/save failed for basis2';}
#if (! TRUE) #copy or perform with value: criterion2 e.g. $db->set_prop($dbkey,'criterion2',$c->param('criterion2'),type=>'service'))
#{$ret .= 'Perform/save failed for criterion2';}
#if (! TRUE) #copy or perform with value: action e.g. $db->set_prop($dbkey,'action',$c->param('action'),type=>'service'))
#{$ret .= 'Perform/save failed for action';}
#if (! TRUE) #copy or perform with value: deliver e.g. $db->set_prop($dbkey,'deliver',$c->param('deliver'),type=>'service'))
#{$ret .= 'Perform/save failed for deliver';}
#if (! TRUE) #copy or perform with value: folder e.g. $db->set_prop($dbkey,'folder',$c->param('folder'),type=>'service'))
#{$ret .= 'Perform/save failed for folder';}
#if (! TRUE) #copy or perform with value: copy e.g. $db->set_prop($dbkey,'copy',$c->param('copy'),type=>'service'))
#{$ret .= 'Perform/save failed for copy';}
#if (! TRUE) #copy or perform with value: action2 e.g. $db->set_prop($dbkey,'action2',$c->param('action2'),type=>'service'))
#{$ret .= 'Perform/save failed for action2';}
#if (! TRUE) #copy or perform with value: deliver2 e.g. $db->set_prop($dbkey,'deliver2',$c->param('deliver2'),type=>'service'))
#{$ret .= 'Perform/save failed for deliver2';}
#if (! TRUE) #copy or perform with value: key e.g. $db->set_prop($dbkey,'key',$c->param('key'),type=>'service'))
#{$ret .= 'Perform/save failed for key';}
#if ($ret eq "") {$ret = 'ok';}
return $ret;
}
@ -416,5 +381,223 @@ sub listfolders
return \%out_dir;
}
sub get_rule_from_db{
$c = shift;
$rule = shift;
my $key = $rule->key;
my $basis = $rule->prop("basis") || '';
my $basis2 = $rule->prop("basis2") || '';
my $deliver = $rule->prop("deliver") || '';
my $deliver2 = $rule->prop("deliver2") || '';
my $action = $rule->prop("action") || '';
my $action2 = $rule->prop("action2") || '';
my $folder = ("$action" eq "sort" )? $deliver : '';
$folder = "INBOX" if "$folder" eq "" && "$action" eq "sort";
my $copy = $rule->prop("copy") || '';
my $oldpmRule = '';
my $criterion = $rule->prop("criterion") || '';
my $criterion2 = $rule->prop("criterion2") || '';
my $deliver = '' if "$action" eq "sort";
for ($basis, $basis2)
{
if ($_ eq '<')
{ $_ = 'sizelt'; }
elsif ($_ eq '>')
{ $_ = 'sizegt'; }
}
my $b1 = $c->l($basis);
my $b2 = $c->l($basis2);
my $copyto = $rule->prop("deliver2") || '';# useless
if (($copy eq 'yes') && ($action2 eq 'inbox'))
{ $deliver2 = ""; $copyto = 'inbox'; } # copyto is useless
$deliver = GetDisplayName($deliver);
$deliver2 = GetDisplayName($deliver2);
my $result = {
key => $key,
basis => $basis,
basis2 => $basis2,
deliver => $deliver,
deliver2 => $deliver2,
action => $action,
action2 => $action2,
folder => $folder,
copy => $copy,
b1 => $b1,
b2 => $b2,
copyto => $copyto,
criterion => $criterion,
criterion2 => $criterion2,
oldkey => $key
};
}
sub save_rule
{
my $c = shift;
my $pdb = esmith::ConfigDB->open('processmail') or die "Could not open processmail DB\n";
my $PanelUser = $c->get_panel_user();
my $rule = $c->param ('key') || '';
#my $q =
if (($rule eq '') || ($rule eq 'new'))
{
my $random = int(rand(999999));
$rule = $PanelUser.$random;
$pdb->new_record($rule, { type => "$PanelUser" });
}
my %filtered;
$filtered{criterion} .= $c->param ('criterion') || '';
$filtered{criterion2} .= $c->param ('criterion2') || '';
$filtered{basis} .= $c->param ('basis') || '';
$filtered{basis2} .= $c->param ('basis2') || '';
$filtered{action} .= $c->param ('action') || '';
$filtered{action2} .= $c->param ('action2') || '';
$filtered{deliver} .= $c->param ('deliver') || '';
$filtered{deliver2} .= $c->param ('deliver2') || '';
$filtered{folder} .= $c->param ('folder') || '';
$filtered{copy} .= $c->param ('copy') || '';
$filtered{oldkey} .= $c->param ('oldkey') || '';
if ($filtered{basis} eq 'sizelt') { $filtered{basis} = '<'; }
if ($filtered{basis} eq 'sizegt') { $filtered{basis} = '>'; }
if ($filtered{basis2} eq 'sizelt') { $filtered{basis2} = '<'; }
if ($filtered{basis2} eq 'sizegt') { $filtered{basis2} = '>'; }
# we use the folder drop box selection if asked to sort
$filtered{folder} = "" if $filtered{folder} eq "INBOX";
$filtered{deliver} = $filtered{folder} if $filtered{action} eq "sort";
if ($filtered{copy} eq 'no') { $filtered{deliver2} = ''; $filtered{action2} = ''; }
if ($filtered{copy} eq 'yes' && $filtered{action2} eq 'inbox') { $filtered{deliver2} = ''; }
# keys are different but rule at least has part of users name so is likely changed
if (($filtered{oldkey} ne $rule) && ($filtered{oldkey} =~ /$PanelUser/))
{
$pdb->new_record($rule, { type => "$PanelUser" });
my $rec = $pdb->get($filtered{oldkey});
$rec->delete;
}
foreach ("criterion","criterion2","action","action2","copy","basis","basis2","deliver","deliver2" )
{ $pdb->set_prop($rule, "$_", $filtered{$_}); }
unless ( system ("/sbin/e-smith/signal-event mailsorting-conf $PanelUser") == 0 )
{ return 'ERROR_UPDATING'; }
return "ok";
}
#
# This are for the future enhanced version.
#
sub describe_procmail_rule {
my ($rule) = @_;
my @lines = grep { /\S/ } map { s/^\s+|\s+$//gr } split /\n/, $rule;
my ($header, @conditions, $action);
$header = shift @lines if $lines[0] =~ /^:0/;
while (@lines && $lines[0] =~ /^\*/) {
push @conditions, shift @lines;
}
$action = join(' ', @lines);
my $desc = "";
if ($header) {
my $flags = $header; $flags =~ s/^:0//; $flags =~ s/:$//; $flags =~ s/\s+//g;
$desc .= "Recipe flags: " . ($flags ? $flags : "none") . ". ";
}
if (@conditions) {
$desc .= "Matches if ";
my @cond_descs;
foreach my $cond (@conditions) {
$cond =~ s/^\*\s*//;
if ($cond =~ /^\^(.*?):\s*(.*)/) {
push @cond_descs, "the header '$1' contains '$2'";
} elsif ($cond =~ /^\//) {
push @cond_descs, "the body matches regex '$cond'";
} else {
push @cond_descs, "the message matches '$cond'";
}
}
$desc .= join(" AND ", @cond_descs) . ". ";
} else {
$desc .= "Matches all messages. ";
}
if ($action) {
if ($action =~ m{^/}) {
$desc .= "Delivers to file or mailbox '$action'.";
} elsif ($action =~ /^[A-Za-z0-9_\-]+$/) {
$desc .= "Delivers to folder '$action'.";
} elsif ($action =~ /^\!/) {
$desc .= "Forwards to address '" . (split ' ', $action, 2)[1] . "'.";
} elsif ($action =~ /^\|/) {
$desc .= "Pipes message to command '" . (substr $action, 1) . "'.";
} else {
$desc .= "Performs action: '$action'.";
}
} else {
$desc .= "No action specified.";
}
return $desc;
}
sub construct_procmail_rule {
my ($entry) = @_;
# Start the recipe header
my $flags = '';
$flags .= 'c' if ($entry->{copy} && $entry->{copy} eq 'yes');
my $header = ":0$flags:";
# Build conditions
my @conditions;
if ($entry->{basis} && $entry->{criterion}) {
my $cond = ($entry->{basis} eq 'Subject')
? "^Subject:.*$entry->{criterion}"
: ($entry->{basis} eq 'headers')
? $entry->{criterion}
: "^$entry->{basis}:.*$entry->{criterion}";
push @conditions, "* $cond";
}
if ($entry->{basis2} && $entry->{criterion2}) {
my $cond2 = ($entry->{basis2} eq 'Subject')
? "^Subject:.*$entry->{criterion2}"
: ($entry->{basis2} eq 'headers')
? $entry->{criterion2}
: "^$entry->{basis2}:.*$entry->{criterion2}";
push @conditions, "* $cond2";
}
# Build action
my $action = '';
if ($entry->{action} && $entry->{action} eq 'delete') {
$action = "/dev/null";
} elsif ($entry->{deliver}) {
$action = $entry->{deliver};
} else {
$action = "INBOX"; # Default action
}
# Assemble the recipe
my $rule = $header . "\n";
$rule .= join("\n", @conditions) . "\n" if @conditions;
$rule .= "$action\n";
return $rule;
}
sub get_esmith_db_property {
# as a hashref
my ($db, $key, $prop) = @_;
my $record = $db->get($key) or return undef;
my $value = $record->prop($prop);
return $value;
}
1;

View File

@ -12,7 +12,7 @@ package SrvMngr::Controller::Mailsorting;
# name : mailsorting, method : get, url : /mailsorting, ctlact : Mailsorting#main
# name : mailsortingu, method : post, url : /mailsortingu, ctlact : Mailsorting#do_update
# name : mailsortingd, method : get, url : /mailsortingd, ctlact : Mailsorting#do_display
# name : mailsortinge, method : post, url : /mailsortinge, ctlact : Mailsorting#do_update
#
# routes : end
#

View File

@ -1,6 +1,39 @@
/*
Generated by: SM2Gen version:0.9(20Jan2025) Chameleon version:4.5.4 On Python:3.12.3 at 2025-05-04 12:59:05
*/
.inline-buttons {
display: flex; /* Use flexbox to arrange items horizontally */
gap: 10px; /* Optional: Add space between buttons */
}
.inline-buttons .link {
/* Additional styling can be added here if needed */
}
.inline-buttons .link {
display: inline-block; /* Keep links as inline-block for button shape */
padding: 7px 14px; /* Adjusted padding to approximate 70% of the original */
margin: 0; /* Remove margin */
background-color: #efefef; /* Light gray background color */
color: black; /* Text color */
text-decoration: none; /* Remove underline */
border: 2px solid #bbb; /* Thin, light gray border */
border-radius: 3px; /* Slightly rounded corners */
font-size: 11.2px; /* Adjusted font size to approximate 70% of the original */
text-align: center; /* Center the text */
cursor: pointer; /* Pointer cursor on hover */ }
/* Hover and active effects for better interaction */
.inline-buttons .link:hover {
background-color: #d9d9d9; /* Darker shade on hover */
}
.inline-buttons .link:active {
background-color: #c0c0c0; /* Even darker shade on click */
}
.Mailsorting-panel {}
.name {}
.rout {}
@ -36,4 +69,4 @@ tbody .tabl1 {}
.head {}
.subh {}
.text94 {}
.subm95 {}
.subm95 {}

View File

@ -16,6 +16,7 @@
%= form_for "mailsortingu" => (method => 'POST') => begin
% param 'trt' => $ms_data->{trt} unless param 'trt';
%= hidden_field 'trt' => $ms_data->{trt}
%= hidden_field 'oldkey' => $ms_data->{oldkey}
%# Inputs etc in here.
<h1 class='head'><%=l('ms_Mail_sorting_rules')%></h1>
@ -31,52 +32,52 @@
</p>
<p><span class=label>
%=l('ms_basis')
%=l('ms_Match_against')
</span><span class=data>
% my @basis_options = [['Subject' => 'Subject'], ['To' => 'TO_'], ['From' => 'From'], ['Email Headers' => 'headers'], ['Size greater than' => 'sizegt'], ['Size less than' => 'sizelt']];
% my @basis_options = [['Subject' => 'Subject'], ['To' => 'To'], ['From' => 'From'], ['Email Headers' => 'headers'], ['Size greater than' => 'sizegt'], ['Size less than' => 'sizelt']];
% param 'basis' => $ms_data->{basis} unless param 'basis';
%= select_field 'basis' => @basis_options, class => 'input', id => 'basis_select'
<br></span> </p>
<p><span class=label>
%=l('ms_criterion')
%=l('ms_the_rule')
</span><span class=data>
% param 'criterion' => $ms_data->{criterion} unless param 'criterion';
%= text_field 'criterion', size => '50', class => 'textinput criterion' , pattern=>'.*' , placeholder=>'criterion', title =>'Pattern regex mismatch', id => 'criterion_text'
<br></span></p>
<p><span class=label>
%=l('ms_basis2')
%=l('ms_2nd_Match')
</span><span class=data>
% my @basis2_options = [['' => ''], ['Subject' => 'Subject'], ['To' => 'TO_'], ['From' => 'From'], ['Email Headers' => 'headers']];
% my @basis2_options = [['' => ''], ['Subject' => 'Subject'], ['To' => 'To'], ['From' => 'From'], ['Email Headers' => 'headers']];
% param 'basis2' => $ms_data->{basis2} unless param 'basis2';
%= select_field 'basis2' => @basis2_options, class => 'input', id => 'basis2_select'
<br></span> </p>
<p><span class=label>
%=l('ms_criterion2')
%=l('ms_2nd_rule')
</span><span class=data>
% param 'criterion2' => $ms_data->{criterion2} unless param 'criterion2';
%= text_field 'criterion2', size => '50', class => 'textinput criterion2' , pattern=>'.*' , placeholder=>'criterion2', title =>'Pattern regex mismatch', id => 'criterion2_text'
<br></span></p>
<p><span class=label>
%=l('ms_action')
%=l('ms_Action')
</span><span class=data>
% my @action_options = [['Delete email' => 'delete'], ['Forward email' => 'forward'], ['Sort to mail folder' => 'sort']];
% param 'action' => $ms_data->{action} unless param 'action';
% my @action_options = selected_field([['Delete email' => 'delete'], ['Forward email' => 'forward'], ['Sort to mail folder' => 'sort']],$ms_data->{action});
%# param 'action' => $ms_data->{action} unless param 'action';
%= select_field 'action' => @action_options, class => 'input', id => 'action_select'
<br></span> </p>
<p><span class=label>
%=l('ms_deliver')
%=l('ms_deliver_email')
</span><span class=data>
% param 'deliver' => $ms_data->{deliver} unless param 'deliver';
%= text_field 'deliver', size => '50', class => 'textinput deliver' , pattern=>'.*' , placeholder=>'deliver', title =>'Pattern regex mismatch', id => 'deliver_text'
<br></span></p>
<p><span class=label>
%=l('ms_folder')
%=l('ms_folder_if_sorting')
</span><span class=data>
% my @folder_options = $c->get_Folders();
% param 'folder' => $ms_data->{folder} unless param 'folder';
@ -92,15 +93,15 @@
<br></span> </p>
<p><span class=label>
%=l('ms_action2')
%=l('ms_2nd_action')
</span><span class=data>
% my @action2_options = [['' => ''], ['Delete email' => 'delete'], ['Forward email' => 'forward'], ['Send to my inbox' => 'inbox']];
% param 'action2' => $ms_data->{action2} unless param 'action2';
% my @action2_options = selected_field([['' => ''], ['Delete email' => 'delete'], ['Forward email' => 'forward'], ['Send to my inbox' => 'inbox']],$ms_data->{action2});
%# param 'action2' => $ms_data->{action2} unless param 'action2';
%= select_field 'action2' => @action2_options, class => 'input', id => 'action2_select'
<br></span> </p>
<p><span class=label>
%=l('ms_deliver2')
%=l('ms_deliver2_email')
</span><span class=data>
% param 'deliver2' => $ms_data->{deliver2} unless param 'deliver2';
%= text_field 'deliver2', size => '50', class => 'textinput deliver2' , pattern=>'.*' , placeholder=>'deliver2', title =>'Pattern regex mismatch', id => 'deliver2_text'

View File

@ -38,10 +38,12 @@
%= text_field 'username', size => '50', class => 'textinput username' , pattern=>'.*' , placeholder=>'username', title =>'Pattern regex mismatch', id => 'username_text'
<br></span></p>
<a href='mailsortingdd?trt=RULES' class='link link1'>
%= l('ms_Add_new_rule')
</a>
%#= link_to l('ms_Add_new_rule'), 'mailsortingdd?trt=RULES' , class=>'link link1'
<div class = 'inline-buttons'>
<a href='mailsortingd?trt=RULES' class='link link1'>
%= l('ms_Add_new_rule')
</a>
</div>
%#= link_to l('ms_Add_new_rule'), 'mailsortinge?trt=RULES' , class=>'link link1'
<h2 class='subh'><%=l('ms_Current_rules')%></h2>

View File

@ -15,7 +15,7 @@ Group: SMEserver/addon
Source: %{name}-%{version}.tar.xz
BuildArchitectures: noarch
BuildRoot: /var/tmp/%{name}-%{version}
BuildRoot: /var/tmp/%{name}-%{version}
Requires: smeserver-release >= 9.0
#Requires: perl-Unicode-IMAPUtf7
Requires: smeserver-formmagick >= 1.4.0-12
@ -33,7 +33,7 @@ Optionally provides user panels where users can create mail rules for themselves
%changelog
* Mon May 05 2025 Brian Read <brianr@koozali.org> 11.0.0-2.sme
- Add first go at SM2 panels - still wip
- Add first go at SM2 panels [SME: 13000]
* Fri May 02 2025 Brian Read <brianr@koozali.org> 11.0.0-1.sme
- Initial build for SME11 [SME: ]