BBS-Universal
view release on metacpan or search on metacpan
lib/BBS/Universal/SysOp.pm view on Meta::CPAN
package BBS::Universal::SysOp;
BEGIN { our $VERSION = '0.020'; }
sub sysop_initialize {
my $self = shift;
$self->{'debug'}->DEBUG(['Start SysOp Initialize']);
# Screen size and derived sections for layout
my ($wsize, $hsize, $wpixels, $hpixels) = GetTerminalSize();
$self->{'wsize'} = $wsize;
$self->{'hsize'} = $hsize;
$self->{'debug'}->DEBUG(["Screen Size is $wsize x $hsize"]);
my $sections = _sections_for_width($wsize);
my $versions = $self->sysop_versions_format($sections, FALSE);
my $bbs_versions = $self->sysop_versions_format($sections, TRUE);
# Visual config
$self->{'sysop_menu_colors'} = [91, 93, 92, 95, 94, 96];
$self->{'sysop_menu_files'} = ['', '', '', '', ''];
# Default user capability flags
$self->{'flags_default'} = {
'prefer_nickname' => 'ON',
'view_files' => 'ON',
'upload_files' => 'OFF',
'download_files' => 'ON',
'remove_files' => 'OFF',
'read_message' => 'ON',
'post_message' => 'ON',
'remove_message' => 'OFF',
'sysop' => 'OFF',
'show_email' => 'OFF',
};
# Tokens (static + dynamic)
my $static = _build_static_tokens($self, $versions, $bbs_versions);
my $dynamic = _build_dynamic_tokens($self);
$self->{'sysop_tokens'} = { %{$static}, %{$dynamic} };
# Field orderings
$self->{'SYSOP ORDER DETAILED'} = [
qw(
id
fullname
username
given
family
nickname
email
birthday
location
access_level
date_format
baud_rate
text_mode
max_columns
max_rows
timeout
retro_systems
accomplishments
prefer_nickname
view_files
upload_files
download_files
remove_files
play_fortunes
read_message
post_message
remove_message
sysop
banned
login_time
logout_time
)
];
$self->{'SYSOP ORDER ABBREVIATED'} = [
qw(
id
fullname
username
given
family
nickname
text_mode
)
];
# Field type definitions
$self->{'SYSOP FIELD TYPES'} = {
'id' => { 'type' => NUMERIC, 'max' => 2, 'min' => 2 },
'username' => { 'type' => HOST, 'max' => 32, 'min' => 16 },
'fullname' => { 'type' => STRING, 'max' => 20, 'min' => 15 },
'given' => { 'type' => STRING, 'max' => 120, 'min' => 32 },
'family' => { 'type' => STRING, 'max' => 120, 'min' => 32 },
'nickname' => { 'type' => STRING, 'max' => 120, 'min' => 32 },
'email' => { 'type' => STRING, 'max' => 120, 'min' => 32 },
'birthday' => { 'type' => STRING, 'max' => 10, 'min' => 10 },
'location' => { 'type' => STRING, 'max' => 120, 'min' => 40 },
'date_format' => { 'type' => RADIO, 'max' => 14, 'min' => 14, 'choices' => ['MONTH/DAY/YEAR', 'DAY/MONTH/YEAR', 'YEAR/MONTH/DAY'], 'default' => 'DAY/MONTH/YEAR', },
'access_level' => { 'type' => RADIO, 'max' => 12, 'min' => 12, 'choices' => ['USER', 'VETERAN', 'JUNIOR SYSOP', 'SYSOP'], 'default' => 'USER', },
'baud_rate' => { 'type' => RADIO, 'max' => 5, 'min' => 5, 'choices' => ['FULL', '115200', '57600', '38400', '19200', '9600', '4800', '2400', '1200', '600', '300'], 'default' => 'FULL', },
'login_time' => { 'type' => STRING, 'max' => 10, 'min' => 10 },
'logout_time' => { 'type' => STRING, 'max' => 10, 'min' => 10 },
'text_mode' => { 'type' => RADIO, 'max' => 7, 'min' => 9, 'choices' => ['ANSI', 'ASCII', 'ATASCII', 'PETSCII'], 'default' => 'ASCII', },
'max_rows' => { 'type' => NUMERIC, 'max' => 3, 'min' => 3, 'default' => 25 },
'max_columns' => { 'type' => NUMERIC, 'max' => 3, 'min' => 3, 'default' => 80 },
'timeout' => { 'type' => NUMERIC, 'max' => 5, 'min' => 5, 'default' => 10 },
'retro_systems' => { 'type' => STRING, 'max' => 120, 'min' => 40 },
'accomplishments' => { 'type' => STRING, 'max' => 120, 'min' => 40 },
'prefer_nickname' => { 'type' => BOOLEAN, 'max' => 5, 'min' => 5, 'choices' => ['ON', 'OFF'], 'default' => 'OFF' },
'view_files' => { 'type' => BOOLEAN, 'max' => 5, 'min' => 5, 'choices' => ['ON', 'OFF'], 'default' => 'ON' },
'banned' => { 'type' => BOOLEAN, 'max' => 5, 'min' => 5, 'choices' => ['ON', 'OFF'], 'default' => 'OFF' },
'upload_files' => { 'type' => BOOLEAN, 'max' => 5, 'min' => 5, 'choices' => ['ON', 'OFF'], 'default' => 'OFF' },
'download_files' => { 'type' => BOOLEAN, 'max' => 5, 'min' => 5, 'choices' => ['ON', 'OFF'], 'default' => 'OFF' },
'remove_files' => { 'type' => BOOLEAN, 'max' => 5, 'min' => 5, 'choices' => ['ON', 'OFF'], 'default' => 'OFF' },
'read_message' => { 'type' => BOOLEAN, 'max' => 5, 'min' => 5, 'choices' => ['ON', 'OFF'], 'default' => 'ON' },
'post_message' => { 'type' => BOOLEAN, 'max' => 5, 'min' => 5, 'choices' => ['ON', 'OFF'], 'default' => 'OFF' },
'remove_message' => { 'type' => BOOLEAN, 'max' => 5, 'min' => 5, 'choices' => ['ON', 'OFF'], 'default' => 'OFF' },
'play_fortunes' => { 'type' => BOOLEAN, 'max' => 5, 'min' => 5, 'choices' => ['ON', 'OFF'], 'default' => 'ON' },
'sysop' => { 'type' => BOOLEAN, 'max' => 5, 'min' => 5, 'choices' => ['ON', 'OFF'], 'default' => 'OFF' },
'password' => { 'type' => STRING, 'max' => 64, 'min' => 32 },
};
$self->{'debug'}->DEBUG(['End SysOp Initialize']);
return $self;
} ## end sub sysop_initialize
# Helper: map terminal width to section count
sub _sections_for_width {
my ($wsize) = @_;
return 1 if $wsize <= 80;
return 2 if $wsize <= 120;
return 3 if $wsize <= 160;
return 4 if $wsize <= 200;
return 5 if $wsize <= 240;
return 6;
} ## end sub _sections_for_width
# Helper: build static token fields from $self
sub _build_static_tokens {
my ($self, $versions, $bbs_versions) = @_;
return {
'HOSTNAME' => $self->sysop_hostname,
'IP ADDRESS' => $self->sysop_ip_address(),
'CPU BITS' => $self->{'CPU'}->{'CPU BITS'},
'CPU CORES' => $self->{'CPU'}->{'CPU CORES'},
'CPU SPEED' => $self->{'CPU'}->{'CPU SPEED'},
'CPU IDENTITY' => $self->{'CPU'}->{'CPU IDENTITY'},
'CPU THREADS' => $self->{'CPU'}->{'CPU THREADS'},
'HARDWARE' => $self->{'CPU'}->{'HARDWARE'},
'VERSIONS' => $versions,
'BBS VERSIONS' => $bbs_versions,
'BBS NAME' => colored(['green'], $self->{'CONF'}->{'BBS NAME'}),
};
} ## end sub _build_static_tokens
# Helper: build dynamic token closures (uniform style)
sub _build_dynamic_tokens {
my ($self) = @_;
return {
'THREADS COUNT' => sub { my $self = shift; return $self->{'CACHE'}->get('THREADS_RUNNING'); },
'USERS COUNT' => sub { my $self = shift; return $self->db_count_users(); },
'UPTIME' => sub { my $self = shift; my $uptime = `uptime -p`; chomp($uptime); return $uptime; },
'DISK FREE SPACE' => sub { my $self = shift; return $self->sysop_disk_free(); },
'MEMORY' => sub { my $self = shift; return $self->sysop_memory(); },
'ONLINE' => sub { my $self = shift; return $self->sysop_online_count(); },
'CPU LOAD' => sub { my $self = shift; return $self->cpu_info->{'CPU LOAD'}; },
'ENVIRONMENT' => sub { my $self = shift; return $self->sysop_showenv(); },
'FILE CATEGORY' => sub {
my $self = shift;
my $sth = $self->{'dbh'}->prepare('SELECT description FROM file_categories WHERE id=?');
$sth->execute($self->{'USER'}->{'file_category'});
my ($result) = $sth->fetchrow_array();
lib/BBS/Universal/SysOp.pm view on Meta::CPAN
foreach my $name (@order) {
push(@hw, $self->{'SYSOP FIELD TYPES'}->{$name}->{'min'});
}
$table = Text::SimpleTable->new(@hw);
if ($list_mode =~ /ABBREVIATED/) {
$table->row(@order);
} else {
my @title = ();
foreach my $heading (@order) {
push(@title, $self->sysop_vertical_heading($heading));
}
$table->row(@title);
} ## end else [ if ($list_mode =~ /ABBREVIATED/)]
$table->hr();
while (my $row = $sth->fetchrow_hashref()) {
my @vals = ();
foreach my $name (@order) {
push(@vals, $row->{$name} . '');
$self->{'debug'}->DEBUGMAX([$name, $row->{$name}]);
}
$table->row(@vals);
} ## end while (my $row = $sth->fetchrow_hashref...)
$sth->finish();
my $string = $table->thick('CYAN')->draw();
$self->sysop_pager("$string\n");
} ## end else [ if ($list_mode =~ /VERTICAL/)]
print 'Press a key to continue ... ';
$self->{'debug'}->DEBUG(['End SysOp List Users']);
return ($self->sysop_keypress());
} ## end sub sysop_list_users
sub sysop_delete_files { # Placeholder
my $self = shift;
$self->{'debug'}->DEBUG(['Start SysOp Delete Files']);
$self->{'debug'}->DEBUG(['End SysOp Delete Files']);
return (TRUE);
} ## end sub sysop_delete_files
sub sysop_list_files {
my $self = shift;
$self->{'debug'}->DEBUG(['Start SysOp List Files']);
my ($wsize, $hsize, $wpixels, $hpixels) = GetTerminalSize();
my $sth = $self->{'dbh'}->prepare('SELECT * FROM files_view WHERE category_id=?');
$sth->execute($self->{'USER'}->{'file_category'});
my $sizes = {};
while (my $row = $sth->fetchrow_hashref()) {
foreach my $name (keys %{$row}) {
if ($name eq 'file_size') {
my $size = format_number($row->{$name});
$sizes->{$name} = max(length($size), $sizes->{$name});
} else {
$sizes->{$name} = max(length($row->{$name}), $sizes->{$name});
}
} ## end foreach my $name (keys %{$row...})
} ## end while (my $row = $sth->fetchrow_hashref...)
$sth->finish();
my $table;
if ($wsize > 150) {
$table = Text::SimpleTable->new(max(5, $sizes->{'title'}), max(8, $sizes->{'filename'}), max(4, $sizes->{'type'}), max(11, $sizes->{'description'}), max(8, $sizes->{'username'}), max(4, $sizes->{'file_size'}), max(8, $sizes->{'uploaded'}), ma...
$table->row('TITLE', 'FILENAME', 'TYPE', 'DESCRIPTION', 'UPLOADER', 'SIZE', 'UPLOADED', 'THUMBS UP', 'THUMBS DOWN');
} else {
$table = Text::SimpleTable->new(max(5, $sizes->{'filename'}), max(8, $sizes->{'title'}), max(4, $sizes->{'extension'}), max(11, $sizes->{'description'}), max(8, $sizes->{'username'}), max(4, $sizes->{'file_size'}), max(9, $sizes->{'thumbs_up'...
$table->row('TITLE', 'FILENAME', 'TYPE', 'DESCRIPTION', 'UPLOADER', 'SIZE', 'THUMBS UP', 'THUMBS DOWN');
}
$table->hr();
$sth = $self->{'dbh'}->prepare('SELECT * FROM files_view WHERE category_id=?');
$sth->execute($self->{'USER'}->{'file_category'});
my $category;
while (my $row = $sth->fetchrow_hashref()) {
if ($wsize > 150) {
$table->row($row->{'title'}, $row->{'filename'}, $row->{'type'}, $row->{'description'}, $row->{'username'}, format_number($row->{'file_size'}), $row->{'uploaded'}, sprintf('%-06u', $row->{'thumbs_up'}), sprintf('%-06u', $row->{'thumbs_dow...
} else {
$table->row($row->{'title'}, $row->{'filename'}, $row->{'extension'}, $row->{'description'}, $row->{'username'}, format_number($row->{'file_size'}), sprintf('%-06u', $row->{'thumbs_up'}), sprintf('%-06u', $row->{'thumbs_down'}));
}
$category = $row->{'category'};
} ## end while (my $row = $sth->fetchrow_hashref...)
$sth->finish();
$self->sysop_output("\n" . '[% B_ORANGE %][% BLACK %] Current Category [% RESET %] [% BRIGHT YELLOW %][% BLACK RIGHT-POINTING TRIANGLE %][% RESET %] [% BRIGHT WHITE %][% FILE CATEGORY %][% RESET %]');
my $tbl = $table->twin('YELLOW')->draw();
while ($tbl =~ / (TITLE|FILENAME|TYPE|DESCRIPTION|UPLOADER|SIZE|UPLOADED|THUMBS UP|THUMBS DOWN) /) {
my $ch = $1;
my $new = '[% BRIGHT GREEN %]' . $ch . '[% RESET %]';
$tbl =~ s/ $ch / $new /gs;
}
$self->sysop_output("\n$tbl\nPress a Key To Continue ...");
$self->sysop_keypress();
print " BACK\n";
$self->{'debug'}->DEBUG(['End SysOp List Files']);
return (TRUE);
} ## end sub sysop_list_files
sub sysop_color_border {
my ($self, $tbl, $color, $type) = @_;
$self->{'debug'}->DEBUG(['Start SysOp Color Border']);
$color = '[% ' . $color . ' %]';
my $new;
if ($tbl =~ /(â)/) {
my $ch = $1;
$new = $ch;
if ($type eq 'DOUBLE') {
$new =~ s/â/\[\% BOX DRAWINGS DOUBLE HORIZONTAL \%\]/gs;
} elsif ($type eq 'HEAVY') {
$new =~ s/â/\[\% BOX DRAWINGS HEAVY HORIZONTAL \%\]/gs;
}
$new = $color . $new . '[% RESET %]';
$tbl =~ s/$ch/$new/gs;
} ## end if ($tbl =~ /(â)/)
if ($tbl =~ /(â)/) {
my $ch = $1;
$new = $ch;
if ($type eq 'DOUBLE') {
$new =~ s/â/\[\% BOX DRAWINGS DOUBLE VERTICAL \%\]/gs;
} elsif ($type eq 'HEAVY') {
$new =~ s/â/\[\% BOX DRAWINGS HEAVY VERTICAL \%\]/gs;
}
$new = '[% RESET %]' . $color . $new . '[% RESET %]';
$tbl =~ s/$ch/$new/gs;
} ## end if ($tbl =~ /(â)/)
if ($tbl =~ /(â)/) {
my $ch = $1;
$new = $ch;
if ($type eq 'ROUNDED') {
$new =~ s/â/\[\% BOX DRAWINGS LIGHT ARC DOWN AND RIGHT \%\]/gs;
} elsif ($type eq 'DOUBLE') {
$new =~ s/â/\[\% BOX DRAWINGS DOUBLE DOWN AND RIGHT \%\]/gs;
} elsif ($type eq 'HEAVY') {
$new =~ s/â/\[\% BOX DRAWINGS HEAVY DOWN AND RIGHT \%\]/gs;
}
$new = $color . $new . '[% RESET %]';
$tbl =~ s/$ch/$new/gs;
lib/BBS/Universal/SysOp.pm view on Meta::CPAN
if (defined($user_row)) {
my ($wsize, $hsize, $wpixels, $hpixels) = GetTerminalSize();
do {
my $valsize = 1;
foreach my $fld (keys %{$user_row}) {
$valsize = max($valsize, length($user_row->{$fld}));
}
$valsize = min($valsize, $wsize - 29);
my $table = Text::SimpleTable->new(6, 16, $valsize);
$table->row('CHOICE', 'FIELD', 'VALUE');
$table->hr();
my $count = 0;
my %choice;
foreach my $field (@{ $self->{'SYSOP ORDER DETAILED'} }) {
if ($field =~ /_time|fullname|_category|id/) {
$table->row(' ', uc($field), $user_row->{$field} . '');
} else {
if ($user_row->{$field} =~ /^(0|1)$/) {
$table->row($choices[$count], uc($field), $self->sysop_true_false($user_row->{$field}, 'YN'));
} elsif ($field eq 'access_level') {
$table->row($choices[$count], uc($field), $user_row->{$field} . ' - USER, VETERAN, JUNIOR SYSOP, SYSOP');
} elsif ($field eq 'date_format') {
$table->row($choices[$count], uc($field), $user_row->{$field} . ' - YEAR/MONTH/DAY, MONTH/DAY/YEAR, DAY/MONTH/YEAR');
} elsif ($field eq 'baud_rate') {
$table->row($choices[$count], uc($field), $user_row->{$field} . ' - 300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200, FULL');
} elsif ($field eq 'text_mode') {
$table->row($choices[$count], uc($field), $user_row->{$field} . ' - ASCII, ANSI, ATASCII, PETSCII');
} elsif ($field eq 'timeout') {
$table->row($choices[$count], uc($field), $user_row->{$field} . ' - Minutes');
} else {
$table->row($choices[$count], uc($field), $user_row->{$field} . '');
}
$count++ if ($key_exit eq $choices[$count]);
$choice{ $choices[$count] } = $field;
$count++;
} ## end else [ if ($field =~ /_time|fullname|_category|id/)]
} ## end foreach my $field (@{ $self...})
my $tbl = $table->round('BRIGHT CYAN')->draw();
while ($tbl =~ / (CHOICE|FIELD|VALUE|No|Yes|USER. VETERAN. JUNIOR SYSOP. SYSOP|YEAR.MONTH.DAY, MONTH.DAY.YEAR, DAY.MONTH.YEAR|300. 600. 1200. 2400. 4800. 9600. 19200. FULL|ASCII. ANSI. ATASCII. PETSCII|Minutes) /) {
my $ch = $1;
my $new;
if ($ch =~ /Yes/) {
$new = '[% GREEN %]' . $ch . '[% RESET %]';
} elsif ($ch =~ /No/) {
$new = '[% RED %]' . $ch . '[% RESET %]';
} elsif ($ch =~ /CHOICE|FIELD|VALUE/) {
$new = '[% BRIGHT YELLOW %]' . $ch . '[% RESET %]';
} else {
$new = '[% RGB 50,50,150 %]' . $ch . '[% RESET %]';
}
$tbl =~ s/$ch/$new/g;
} ## end while ($tbl =~ / (CHOICE|FIELD|VALUE|No|Yes|USER. VETERAN. JUNIOR SYSOP. SYSOP|YEAR.MONTH.DAY, MONTH.DAY.YEAR, DAY.MONTH.YEAR|300. 600. 1200. 2400. 4800. 9600. 19200. FULL|ASCII. ANSI. ATASCII. PETSCII|Minutes) /)
$self->sysop_output('[% CLS %]' . $tbl . "\n");
$self->sysop_show_choices($mapping);
$self->sysop_prompt('Choose');
do {
$key = uc($self->sysop_keypress());
} until ('1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ' =~ /$key/i);
if ($key !~ /$key_exit/i) {
print 'Edit > (', $choice{$key}, ' = ', $user_row->{ $choice{$key} }, ') > ';
if ($choice{$key} =~ /^(play_fortunes|prefer_nickname|view_files|upload_files|download_files|remove_files|read_message|post_message|remove_message|sysop)$/) {
$user_row->{ $choice{$key} } = ($user_row->{ $choice{$key} } == 1) ? 0 : 1;
my $sth = $self->{'dbh'}->prepare('UPDATE permissions SET ' . $choice{$key} . '= !' . $choice{$key} . ' WHERE id=?');
$sth->execute($user_row->{'id'});
$sth->finish();
} elsif($choice{$key} =~ /text_mode/) {
my $new = $self->sysop_get_line($self->{'SYSOP FIELD TYPES'}->{ $choice{$key} }, $user_row->{ $choice{$key} });
$user_row->{ $choice{$key} } = $new;
my $sth = $self->{'dbh'}->prepare('UPDATE users SET ' . $choice{$key} . '=? WHERE id=?');
$sth->execute($new, $self->{'text_modes'}->{$user_row->{'id'}});
$sth->finish();
} else {
my $new = $self->sysop_get_line($self->{'SYSOP FIELD TYPES'}->{ $choice{$key} }, $user_row->{ $choice{$key} });
$user_row->{ $choice{$key} } = $new;
my $sth = $self->{'dbh'}->prepare('UPDATE users SET ' . $choice{$key} . '=? WHERE id=?');
$sth->execute($new, $user_row->{'id'});
$sth->finish();
} ## end else [ if ($choice{$key} =~ /^(prefer_nickname|view_files|upload_files|download_files|remove_files|read_message|post_message|remove_message|sysop)$/)]
} else {
print "BACK\n";
}
} until ($key =~ /$key_exit/i);
} elsif ($search ne '') {
print "User not found!\n\n";
}
$self->{'debug'}->DEBUG(['End SysOp User Edit']);
return (TRUE);
} ## end sub sysop_user_edit
sub sysop_new_user_edit {
my $self = shift;
my $row = shift;
my $file = shift;
$self->{'debug'}->DEBUG(['Start SysOp User Edit']);
my $mapping = $self->sysop_load_menu($row, $file);
print locate($row, 1), cldown, $mapping->{'TEXT'};
delete($mapping->{'TEXT'});
my ($key_exit) = (keys %{$mapping});
my @choices = qw( 0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P Q R S T U V W X Y );
my $key;
my @responses;
my $sth = $self->{'dbh'}->prepare('SELECT * FROM users_view WHERE access_level=?');
$sth->execute('USER');
my $user_row;
while ($user_row = $sth->fetchrow_hashref()) {
push(@responses, $user_row);
}
$sth->finish();
$self->{'debug'}->DEBUGMAX(\@responses);
my ($wsize, $hsize, $wpixels, $hpixels) = GetTerminalSize();
while ($user_row = pop(@responses)) {
do {
my $valsize = 1;
foreach my $fld (keys %{$user_row}) {
$valsize = max($valsize, length($user_row->{$fld}));
}
$valsize = min($valsize, $wsize - 29);
my $table = Text::SimpleTable->new(6, 16, $valsize);
$table->row('CHOICE', 'FIELD', 'VALUE');
$table->hr();
my $count = 0;
my %choice;
foreach my $field (@{ $self->{'SYSOP ORDER DETAILED'} }) {
if ($field =~ /_time|fullname|_category|id/) {
$table->row(' ', $field, $user_row->{$field} . '');
} else {
if ($user_row->{$field} =~ /^(0|1)$/) {
$table->row($choices[$count], $field, $self->sysop_true_false($user_row->{$field}, 'YN'));
} elsif ($field eq 'access_level') {
$table->row($choices[$count], $field, $user_row->{$field} . ' - USER, VETERAN, JUNIOR SYSOP, SYSOP');
} elsif ($field eq 'date_format') {
$table->row($choices[$count], $field, $user_row->{$field} . ' - YEAR/MONTH/DAY, MONTH/DAY/YEAR, DAY/MONTH/YEAR');
} elsif ($field eq 'baud_rate') {
$table->row($choices[$count], $field, $user_row->{$field} . ' - 300, 600, 1200, 2400, 4800, 9600, 19200, FULL');
} elsif ($field eq 'text_mode') {
$table->row($choices[$count], $field, $user_row->{$field} . ' - ASCII, ANSI, ATASCII, PETSCII');
} elsif ($field eq 'timeout') {
$table->row($choices[$count], $field, $user_row->{$field} . ' - Minutes');
} else {
$table->row($choices[$count], $field, $user_row->{$field} . '');
}
$count++ if ($key_exit eq $choices[$count]);
$choice{ $choices[$count] } = $field;
$count++;
} ## end else [ if ($field =~ /_time|fullname|_category|id/)]
} ## end foreach my $field (@{ $self...})
my $tbl = $table->round('BRIGHT CYAN')->draw();
while ($tbl =~ / (CHOICE|FIELD|VALUE|No|Yes|USER. VETERAN. JUNIOR SYSOP. SYSOP|YEAR.MONTH.DAY, MONTH.DAY.YEAR, DAY.MONTH.YEAR|300. 600. 1200. 2400. 4800. 9600. 19200. FULL|ASCII. ANSI. ATASCII. PETSCII|Minutes) /) {
my $ch = $1;
my $new;
if ($ch =~ /Yes/) {
$new = '[% GREEN %]' . $ch . '[% RESET %]';
} elsif ($ch =~ /No/) {
$new = '[% RED %]' . $ch . '[% RESET %]';
} elsif ($ch =~ /CHOICE|FIELD|VALUE/) {
$new = '[% BRIGHT YELLOW %]' . $ch . '[% RESET %]';
} else {
$new = '[% RGB 50,50,150 %]' . $ch . '[% RESET %]';
}
$tbl =~ s/$ch/$new/g;
} ## end while ($tbl =~ / (CHOICE|FIELD|VALUE|No|Yes|USER. VETERAN. JUNIOR SYSOP. SYSOP|YEAR.MONTH.DAY, MONTH.DAY.YEAR, DAY.MONTH.YEAR|300. 600. 1200. 2400. 4800. 9600. 19200. FULL|ASCII. ANSI. ATASCII. PETSCII|Minutes) /)
$self->sysop_output('[% CLS %]' . $tbl . "\n");
$self->sysop_show_choices($mapping);
$self->sysop_prompt('Choose');
do {
$key = uc($self->sysop_keypress());
} until ('1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ' =~ /$key/i);
if ($key !~ /$key_exit/i) {
print 'Edit > (', $choice{$key}, ' = ', $user_row->{ $choice{$key} }, ') > ';
my $new = $self->sysop_get_line(ECHO, 1 + $self->{'SYSOP FIELD TYPES'}->{ $choice{$key} }->{'max'}, $user_row->{ $choice{$key} });
unless ($new eq '') {
$new =~ s/^(Yes|On)$/1/i;
$new =~ s/^(No|Off)$/0/i;
}
$user_row->{ $choice{$key} } = $new;
if ($key =~ /prefer_nickname|view_files|upload_files|download_files|remove_files|read_message|post_message|remove_message|sysop/) {
my $sth = $self->{'dbh'}->prepare('UPDATE permissions SET ' . choice { $key } . '=? WHERE id=?');
$sth->execute($new, $user_row->{'id'});
$sth->finish();
} else {
my $sth = $self->{'dbh'}->prepare('UPDATE users SET ' . $choice{$key} . '=? WHERE id=?');
$sth->execute($new, $user_row->{'id'});
$sth->finish();
}
} else {
print "BACK\n";
}
} until ($key =~ /$key_exit/i);
} ## end while ($user_row = pop(@responses...))
$self->{'debug'}->DEBUG(['End SysOp User Edit']);
return (TRUE);
} ## end sub sysop_new_user_edit
sub sysop_user_add {
my $self = shift;
my $row = shift;
my $file = shift;
$self->{'debug'}->DEBUG(['Start SysOp User Add']);
my $flags_default = $self->{'flags_default'};
my $mapping = $self->sysop_load_menu($row, $file);
print locate($row, 1), cldown, $mapping->{'TEXT'};
my $table = Text::SimpleTable->new(15, 150);
my $user_template;
my @tmp = grep(!/id|banned|fullname|_time|max_|_category/, @{ $self->{'SYSOP ORDER DETAILED'} });
push(@tmp, 'password');
foreach my $name (@tmp) {
my $size = max(3, $self->{'SYSOP FIELD TYPES'}->{$name}->{'max'});
if ($name eq 'timeout') {
$table->row($name, '_' x $size . ' - Minutes');
} elsif ($name eq 'baud_rate') {
$table->row($name, '_' x $size . ' - 300 or 600 or 1200 or 2400 or 4800 or 9600 or 19200 or FULL');
} elsif ($name =~ /username|given|family|password/) {
if ($name eq 'given') {
$table->row("$name (first)", '_' x $size . ' - Cannot be empty');
} elsif ($name eq 'family') {
$table->row("$name (last)", '_' x $size . ' - Cannot be empty');
} else {
$table->row($name, '_' x $size . ' - Cannot be empty');
}
} elsif ($name eq 'date_format') {
$table->row($name, '_' x $size . ' - YEAR/MONTH/DAY or MONTH/DAY/YEAR or DAY/MONTH/YEAR');
} elsif ($name eq 'access_level') {
$table->row($name, '_' x $size . ' - USER or VETERAN or JUNIOR SYSOP or SYSOP');
} elsif ($name eq 'text_mode') {
$table->row($name, '_' x $size . ' - ANSI or ASCII or ATASCII or PETSCII');
} elsif ($name eq 'birthday') {
$table->row($name, '_' x $size . ' - YEAR-MM-DD');
} elsif ($name =~ /(prefer_nickname|_files|_message|sysop|fortunes)/) {
$table->row($name, '_' x $size . ' - Yes/No or True/False or On/Off or 1/0');
} elsif ($name =~ /location|retro_systems|accomplishments/) {
$table->row($name, '_' x ($self->{'SYSOP FIELD TYPES'}->{$name}->{'max'}));
} else {
$table->row($name, '_' x $size);
}
( run in 1.792 second using v1.01-cache-2.11-cpan-b16cb0d3907 )