Compare commits
35 Commits
11_0_0-4_e
...
11_0_0-25_
Author | SHA1 | Date | |
---|---|---|---|
fe62bd3e39 | |||
df6d21dbc9 | |||
9c9592f861 | |||
4d2097d2da | |||
44a9ecc0e1 | |||
785ebcfaaf | |||
127ea74a8b | |||
b9f6392c1d | |||
659f060eb6 | |||
1087a8a5a2 | |||
6a5a756438 | |||
91ca26de27 | |||
8b93232bbe | |||
ed1c3e13b1 | |||
095a0a1499 | |||
d16ea6a847 | |||
e70cc67430 | |||
b097acafab | |||
5d7655a709 | |||
a58df95aa9 | |||
251b454470 | |||
174d511899 | |||
4be8a1411f | |||
ba431a8a7d | |||
77a7849898 | |||
fb5b0942d6 | |||
5edc830f9b | |||
473cb57a47 | |||
55b85496d4 | |||
2fd6f8b630 | |||
a428e91c92 | |||
03955eecea | |||
891fc73ce3 | |||
e7d7b6afb8 | |||
1837bc9a18 |
59
README.md
59
README.md
@@ -17,6 +17,59 @@ Show list of outstanding bugs: [here](https://bugs.koozali.org/buglist.cgi?compo
|
||||
|
||||
## Description
|
||||
|
||||
<br />*This description has been generated by an LLM AI system and cannot be relied on to be fully correct.*
|
||||
*Once it has been checked, then this comment will be deleted*
|
||||
<br />
|
||||
The *smeserver-manager* is a web-based management interface for the SME Server (formerly known as e-smith server and gateway). SME Server is a Linux-based distribution designed for small to medium-sized enterprises, providing a wide range of network services and simplified server management.
|
||||
|
||||
It is based on the perl Mojolicious package. Mojolicious is a real-time web framework for Perl, which provides a range of functionalities that make it a powerful and flexible tool for web development.
|
||||
|
||||
### Features
|
||||
|
||||
#### Web-Based Management Interface:
|
||||
smeserver-manager provides an intuitive and user-friendly web interface that allows administrators to manage various aspects of the server without needing deep technical knowledge or command-line skills.
|
||||
|
||||
#### User and Group Management:
|
||||
It allows you to easily add, remove, and manage user accounts and groups. The interface simplifies creating email accounts, setting passwords, and configuring user permissions.
|
||||
|
||||
#### Network Configuration:
|
||||
You can configures network settings such as IP addresses, DNS, DHCP, and gateway settings. The interface also provides options for setting up VPNs, remote access, and firewall rules.
|
||||
|
||||
#### File Sharing and Storage:
|
||||
Enables and manages file sharing services like Samba (for Windows file sharing) and NFS (for Unix/Linux file sharing). Administrators can easily create shared folders and manage permissions.
|
||||
|
||||
#### Email Services:
|
||||
Configure and manage email services, including setting up mail domains, user mailboxes, and SMTP/IMAP/POP3 settings. It also provides options for spam and virus filtering.
|
||||
|
||||
#### Web Services:
|
||||
Host and manage websites using the integrated web server (usually Apache). It supports virtual hosting, where multiple websites can be hosted on the same server.
|
||||
|
||||
#### Backup and Restore:
|
||||
Perform backups of essential data and server configurations. The interface provides options for scheduled backups and restoring from backup files.
|
||||
|
||||
#### Software Updates and Installation:
|
||||
Keep the server up-to-date with the latest security patches and software updates. The interface helps in installing and updating software packages and extensions.
|
||||
|
||||
#### Monitoring and Reporting:
|
||||
Monitor server performance and health. The interface provides logs, status reports, and alerts for various server components, including disk usage, network traffic, and system load.
|
||||
|
||||
|
||||
### Installation and Access
|
||||
|
||||
Typically, smeserver-manager is installed by default on SME Server. To access the interface:
|
||||
|
||||
Open a web browser on a device connected to the same network as the SME Server. Enter the server's IP address or hostname followed by /server-manager in the address bar (e.g., https://192.168.1.1/server-manager).
|
||||
You will be prompted to log in. Use the administrator credentials set during the SME Server installation.
|
||||
|
||||
### Benefits
|
||||
|
||||
Simplicity: Makes it easy for non-technical users to manage a server.
|
||||
Centralized Management: Provides a single point of control for various server functionalities.
|
||||
Efficiency: Saves time and reduces complexity in server management tasks.
|
||||
Security: Regular updates and built-in security features ensure the server remains secure.
|
||||
|
||||
### Considerations
|
||||
|
||||
Learning Curve: While designed to be user-friendly, some features may still require a basic understanding of server and network management concepts.
|
||||
Dependencies: Relies on specific packages and configurations of SME Server, and may not be directly applicable to other Linux distributions.
|
||||
|
||||
### Summary
|
||||
|
||||
SMEserver-manager is a powerful tool that brings simplicity and efficiency to server management for small to medium-sized enterprises. By providing a centralized, web-based interface, it allows administrators to manage users, network settings, file sharing, email services, web hosting, and more, all from a single location.
|
@@ -47,6 +47,9 @@ for my $event ( qw( smeserver-manager-update smanager-refresh bootstrap-console-
|
||||
|
||||
event_link('systemd-default', "smeserver-manager-update", '88');
|
||||
event_link('systemd-reload', "smeserver-manager-update", '89');
|
||||
templates2events("/etc/rsyslog.conf", "smeserver-manager-update");
|
||||
safe_symlink("restart",
|
||||
"root/etc/e-smith/events/smeserver-manager-update/services2adjust/rsyslog");
|
||||
|
||||
use esmith::Build::Backup qw(:all);
|
||||
backup_includes("smeserver-manager", qw(
|
||||
|
@@ -33,6 +33,8 @@ use esmith::I18N;
|
||||
|
||||
use Data::Dumper; # activate if DEBUG
|
||||
|
||||
binmode(STDOUT, ":encoding(UTF-8)");
|
||||
|
||||
my $navigation_ignore =
|
||||
"(\.\.?|Swttheme\.pm|Login\.pm|Request\.pm|Modules\.pm(-.*)?)";
|
||||
|
||||
@@ -46,131 +48,193 @@ my @files = grep (!/^${navigation_ignore}$/, readdir (FUNCTIONS));
|
||||
closedir FUNCTIONS;
|
||||
|
||||
my @langs = $i18n->availableLanguages();
|
||||
#my @langs = ('en', 'fr');
|
||||
#print Dumper(\@langs);
|
||||
#my @langs = ('tr'); #Temp override
|
||||
|
||||
|
||||
foreach my $lang (@langs)
|
||||
{
|
||||
my $long_lex = SMNGR_LIB.'/'.I18NMODULES."/General/general_$lang.lex";
|
||||
next unless ( -e $long_lex );
|
||||
my $long_lex = SMNGR_LIB.'/'.I18NMODULES."/General/general_$lang.lex";
|
||||
next unless ( -e $long_lex );
|
||||
|
||||
open(LEX, '<:encoding(UTF-8)', $long_lex)
|
||||
or die "Couldn't open ", $long_lex, " for reading.\n";
|
||||
my @gen_lex = <LEX>;
|
||||
close LEX;
|
||||
open(LEX, '<:encoding(UTF-8)', $long_lex)
|
||||
or die "Couldn't open ", $long_lex, " for reading.\n";
|
||||
my @gen_lex = <LEX>;
|
||||
close LEX;
|
||||
|
||||
foreach my $file (@files)
|
||||
{
|
||||
next if (-d SMNGR_LIB.'/'.WEBFUNCTIONS . "/$file");
|
||||
# next unless ( $file =~ m/D.*\.pm$/ );
|
||||
next unless ( $file =~ m/[A-Z].*\.pm$/ );
|
||||
|
||||
my $file2 = lc($file);
|
||||
$file2 =~ s/\.pm$//;
|
||||
|
||||
#--------------------------------------------------
|
||||
# extract heading, description and weight information
|
||||
# from Mojo controller
|
||||
#--------------------------------------------------
|
||||
open(SCRIPT, SMNGR_LIB.'/'.WEBFUNCTIONS . "/$file");
|
||||
my $heading = undef;
|
||||
my $description = undef;
|
||||
my $heading_weight = undef;
|
||||
my $description_weight = undef;
|
||||
my $menucat = undef;
|
||||
my $routes = undef;
|
||||
|
||||
while ( <SCRIPT> )
|
||||
#my @files = ('Portforwarding.pm'); #Temp override
|
||||
foreach my $file (@files)
|
||||
{
|
||||
$heading = $1 if (/^\s*#\s*heading\s*:\s*(.+?)\s*$/);
|
||||
$description = $1
|
||||
if (/^\s*#\s*description\s*:\s*(.+?)\s*$/);
|
||||
($heading_weight, $description_weight) = ($1, $2)
|
||||
if (/^\s*#\s*navigation\s*:\s*(\d+?)\s+(\d+?)\s*$/);
|
||||
$menucat = $1
|
||||
if (/^\s*#\s*menu\s*:\s*(.+?)\s*$/);
|
||||
next if (-d SMNGR_LIB.'/'.WEBFUNCTIONS . "/$file");
|
||||
# next unless ( $file =~ m/D.*\.pm$/ );
|
||||
next unless ( $file =~ m/[A-Z].*\.pm$/ );
|
||||
|
||||
last if (defined $heading and
|
||||
defined $description and
|
||||
defined $heading_weight and
|
||||
defined $description_weight and
|
||||
defined $menucat);
|
||||
my $file2 = lc($file);
|
||||
$file2 =~ s/\.pm$//;
|
||||
#--------------------------------------------------
|
||||
# extract heading, description and weight information
|
||||
# from Mojo controller
|
||||
#--------------------------------------------------
|
||||
open(SCRIPT, SMNGR_LIB.'/'.WEBFUNCTIONS . "/$file");
|
||||
my $heading = undef;
|
||||
my $description = undef;
|
||||
my $heading_weight = undef;
|
||||
my $description_weight = undef;
|
||||
my $menucat = undef;
|
||||
my $routes = undef;
|
||||
|
||||
# routes : end (stop before eof if 'menu' is not here before 'routes'!!!
|
||||
$routes = $1 if (/^\s*#\s*routes\s*:\s*(.+?)\s*$/);
|
||||
last if (defined $routes and $routes eq 'end');
|
||||
while ( <SCRIPT> )
|
||||
{
|
||||
$heading = $1 if (/^\s*#\s*heading\s*:\s*(.+?)\s*$/);
|
||||
$description = $1
|
||||
if (/^\s*#\s*description\s*:\s*(.+?)\s*$/);
|
||||
($heading_weight, $description_weight) = ($1, $2)
|
||||
if (/^\s*#\s*navigation\s*:\s*(\d+?)\s+(\d+?)\s*$/);
|
||||
$menucat = $1
|
||||
if (/^\s*#\s*menu\s*:\s*(.+?)\s*$/);
|
||||
|
||||
last if (defined $heading and
|
||||
defined $description and
|
||||
defined $heading_weight and
|
||||
defined $description_weight and
|
||||
defined $menucat);
|
||||
|
||||
# routes : end (stop before eof if 'menu' is not here before 'routes'!!!
|
||||
$routes = $1 if (/^\s*#\s*routes\s*:\s*(.+?)\s*$/);
|
||||
last if (defined $routes and $routes eq 'end');
|
||||
}
|
||||
close SCRIPT;
|
||||
|
||||
print "updating script $file for lang $lang\n"if DEBUG;
|
||||
my $navdb = $navdbs{$lang};
|
||||
my $navinfo = NAVDIR.'/'.NAVIGATIONDIR . "/navigation.$lang";
|
||||
$navdb ||= esmith::NavigationDB->open($navinfo);
|
||||
$navdb ||= esmith::NavigationDB->create($navinfo) or
|
||||
die "Couldn't create $navinfo\n";
|
||||
$navdbs{$lang} ||= $navdb;
|
||||
my $rec = $navdb->get($file2) ||
|
||||
$navdb->new_record($file2, { type => 'panel' } );
|
||||
|
||||
my @panel_lex = ();
|
||||
$long_lex = SMNGR_LIB.'/'.I18NMODULES.'/'.ucfirst($file2)."/${file2}_$lang.lex";
|
||||
if ( -e $long_lex ) {
|
||||
open(LEX, '<:encoding(UTF-8)', $long_lex)
|
||||
or die "Couldn't open ", $long_lex, " for reading.\n";
|
||||
@panel_lex = <LEX>;
|
||||
close LEX;
|
||||
}
|
||||
#Extract the prefix for this module
|
||||
my @keys = values @panel_lex; # Get all values from the array
|
||||
|
||||
my $i = 0; # Initialize the index
|
||||
my $found = 0; # Flag to check if the prefix was found
|
||||
my $prefix = "xx_"; # Probably never match!!
|
||||
|
||||
while ($i < @keys) { # Loop until we run out of entries
|
||||
my $extracted_value = $keys[$i] || ""; # The current entry
|
||||
#print("Extracted val: ".$extracted_value."\n");
|
||||
|
||||
# Extract prefix from the second value (up to and including the first underscore)
|
||||
#my ($prefix) = $second_value =~ /^'(.*?_)/; # Match everything up to and including the first underscore
|
||||
($prefix) = $extracted_value =~ /^'(.*?_)/; # Match everything up to and including the first underscore
|
||||
|
||||
if (defined $prefix) {
|
||||
$found = 1; # Set found flag to true
|
||||
last; # Exit the loop if prefix is found
|
||||
} else {
|
||||
#print("Extracted Val: " . $extracted_value . "\n");
|
||||
}
|
||||
|
||||
$i++; # Increment the index to check the next entry
|
||||
}
|
||||
|
||||
if (!$found) {
|
||||
print(STDERR "No valid prefix found in any entries: ".$file2." (".$lang.")\n"); # if DEBUG;
|
||||
$prefix = "xx_"; # Probably never match!!
|
||||
|
||||
}
|
||||
#print("Prefix: ".$prefix." ".$file2." (".$lang.")\n");
|
||||
|
||||
my %Lexicon = ();
|
||||
push(@panel_lex, @gen_lex);
|
||||
my $top_error = 0;
|
||||
|
||||
chomp @panel_lex;
|
||||
for (@panel_lex) {
|
||||
next unless $_; # first one empty
|
||||
my ($k, $v) = split / => /, $_;
|
||||
# errors on split to $v (use DEBUG to see)
|
||||
if ( $k and $v ) {
|
||||
$k =~ s/\'//g;
|
||||
$v =~ s/\'//g;
|
||||
$v =~ s/,$//g;
|
||||
$Lexicon{ lc($k) } = $v;
|
||||
} else {
|
||||
$k = "?" unless ($k);
|
||||
print STDERR "Error for $lang $file2 on $k \n" if DEBUG;
|
||||
$top_error++;
|
||||
}
|
||||
}
|
||||
if ( $top_error > 0) {
|
||||
if ( DEBUG ) {
|
||||
print STDERR "$top_error errors for $lang $file2\n";
|
||||
# print Dumper(\@panel_lex);
|
||||
# print Dumper(\%Lexicon);
|
||||
# exit 1;
|
||||
}
|
||||
}
|
||||
$heading = "" unless defined $heading;
|
||||
$description = "" unless defined $description;
|
||||
# Get the base language code from $lang
|
||||
my $base_lang = (split('-', $lang))[0];
|
||||
my $loc_heading = process_localization( \%Lexicon, $heading, $lang, $prefix );
|
||||
my $loc_description = process_localization( \%Lexicon, $description, $lang, $prefix );
|
||||
$loc_heading =~ s/^\s*(\w.*?)\s*$/$1/;
|
||||
$loc_description =~ s/^\s*(\w.*?)\s*$/$1/;
|
||||
|
||||
$rec->merge_props(
|
||||
Heading => $loc_heading,
|
||||
Description => $loc_description,
|
||||
HeadingWeight => localise( \%Lexicon, $heading_weight ),
|
||||
DescriptionWeight => localise( \%Lexicon, $description_weight ),
|
||||
MenuCat => (defined $menucat ? $menucat : 'A'));
|
||||
}
|
||||
close SCRIPT;
|
||||
|
||||
print "updating script $file for lang $lang\n" if DEBUG;
|
||||
#warn "trying to close for lang $lang\n";
|
||||
my $navdb = $navdbs{$lang};
|
||||
my $navinfo = NAVDIR.'/'.NAVIGATIONDIR . "/navigation.$lang";
|
||||
$navdb ||= esmith::NavigationDB->open($navinfo);
|
||||
$navdb ||= esmith::NavigationDB->create($navinfo) or
|
||||
die "Couldn't create $navinfo\n";
|
||||
$navdbs{$lang} ||= $navdb;
|
||||
my $rec = $navdb->get($file2) ||
|
||||
$navdb->new_record($file2, { type => 'panel' } );
|
||||
|
||||
my @panel_lex = ();
|
||||
$long_lex = SMNGR_LIB.'/'.I18NMODULES.'/'.ucfirst($file2)."/${file2}_$lang.lex";
|
||||
if ( -e $long_lex ) {
|
||||
open(LEX, '<:encoding(UTF-8)', $long_lex)
|
||||
or die "Couldn't open ", $long_lex, " for reading.\n";
|
||||
@panel_lex = <LEX>;
|
||||
close LEX;
|
||||
}
|
||||
|
||||
my %Lexicon = ();
|
||||
push(@panel_lex, @gen_lex);
|
||||
my $top_error = 0;
|
||||
|
||||
chomp @panel_lex;
|
||||
for (@panel_lex) {
|
||||
next unless $_; # first one empty
|
||||
my ($k, $v) = split / => /, $_;
|
||||
# errors on split to $v (use DEBUG to see)
|
||||
if ( $k and $v ) {
|
||||
$k =~ s/\'//g;
|
||||
$v =~ s/\'//g;
|
||||
$v =~ s/,$//g;
|
||||
$Lexicon{ $k } = $v;
|
||||
} else {
|
||||
$k = "?" unless ($k);
|
||||
print STDERR "Error for $lang $file2 on $k \n" if DEBUG;
|
||||
$top_error++;
|
||||
}
|
||||
}
|
||||
if ( $top_error > 0) {
|
||||
if ( DEBUG ) {
|
||||
print STDERR "$top_error errors for $lang $file2\n";
|
||||
# print Dumper(\@panel_lex);
|
||||
# print Dumper(\%Lexicon);
|
||||
# exit 1;
|
||||
}
|
||||
}
|
||||
|
||||
my $loc_heading = localise( \%Lexicon, $heading );
|
||||
my $loc_description = localise( \%Lexicon, $description );
|
||||
$loc_heading =~ s/^\s*(\w.*?)\s*$/$1/;
|
||||
$loc_description =~ s/^\s*(\w.*?)\s*$/$1/;
|
||||
|
||||
$rec->merge_props(
|
||||
Heading => $loc_heading,
|
||||
Description => $loc_description,
|
||||
HeadingWeight => localise( \%Lexicon, $heading_weight ),
|
||||
DescriptionWeight => localise( \%Lexicon, $description_weight ),
|
||||
MenuCat => (defined $menucat ? $menucat : 'A'));
|
||||
}
|
||||
#warn "trying to close for lang $lang\n";
|
||||
my $navdb = $navdbs{$lang};
|
||||
$navdb->close();
|
||||
$navdb->close();
|
||||
}
|
||||
|
||||
|
||||
sub localise {
|
||||
my ($lexicon, $string) = @_;
|
||||
#print("Looking up:".$string."\n");
|
||||
$string = "" unless defined $string;
|
||||
return $lexicon->{$string} || $string;
|
||||
my $lc_string = lc($string);
|
||||
my $res = $lexicon->{$lc_string} || $string;
|
||||
#print("Returning:".$res."\n");
|
||||
return $res;
|
||||
}
|
||||
|
||||
# Subroutine to process localization
|
||||
sub process_localization {
|
||||
my ($lexicon_ref, $heading, $lang, $prefix) = @_;
|
||||
|
||||
# Localized heading based on original heading
|
||||
my $loc_heading = localise($lexicon_ref, $heading);
|
||||
|
||||
# Get the base language code from $lang
|
||||
my $base_lang = (split('-', $lang))[0];
|
||||
|
||||
# Check the condition
|
||||
if ($loc_heading eq $heading && $base_lang ne 'en') {
|
||||
# Construct the new key by combining the prefix and the original heading
|
||||
my $key = $prefix . $heading;
|
||||
# Localize using the constructed key
|
||||
$loc_heading = localise($lexicon_ref, $key);
|
||||
# See if it got a hit
|
||||
if ($loc_heading eq $key){
|
||||
$loc_heading = $heading;
|
||||
}
|
||||
}
|
||||
|
||||
return $loc_heading; # Optionally return the localized heading
|
||||
}
|
||||
|
@@ -40,5 +40,10 @@
|
||||
$OUT .= " Require ip $localAccess $externalSSLAccess\n";
|
||||
}
|
||||
$OUT .= " </Location>\n";
|
||||
# prevent caching of manager files in browser
|
||||
$OUT .= " <LocationMatch \"/$place/.+\.(html|cgi)\$\">\n";
|
||||
$OUT .= " Header set Cache-Control no-store\n";
|
||||
$OUT .= " </LocationMatch>\n";
|
||||
|
||||
}
|
||||
}
|
||||
|
4
root/etc/e-smith/templates/etc/rsyslog.conf/32smanager
Normal file
4
root/etc/e-smith/templates/etc/rsyslog.conf/32smanager
Normal file
@@ -0,0 +1,4 @@
|
||||
#smanager
|
||||
:programname, isequal, "smanager" /var/log/smanager/smanager.log
|
||||
& stop
|
||||
|
@@ -67,5 +67,21 @@ hr.sme-copyrightbar {
|
||||
color: #8ebe43;
|
||||
background-color: #8ebe43;
|
||||
}
|
||||
|
||||
/* flag container no flag */
|
||||
#flag-container span {
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
.fallback-box {
|
||||
display: inline-block; /* Make it inline-block to fit around the content */
|
||||
border: 2px solid gray; /* Change the border color as desired */
|
||||
padding: 10px; /* Add some padding */
|
||||
border-radius: 10px; /* Round the corners of the box */
|
||||
font-size: 60px; /* Adjust size if needed */
|
||||
margin-top: 10px; /* Add some margin */
|
||||
text-align: center; /* Center text inside the box */
|
||||
}
|
||||
|
||||
HERE
|
||||
}
|
||||
|
@@ -234,7 +234,7 @@ a.menu-title {
|
||||
width: 100%;
|
||||
}
|
||||
#h2e11 {
|
||||
width: 70%;
|
||||
width: 50%;
|
||||
float: left;
|
||||
}
|
||||
#h2e12 {
|
||||
@@ -257,9 +257,9 @@ a.menu-title {
|
||||
width: 70%;
|
||||
}
|
||||
|
||||
#h2e22,#h2e23 {
|
||||
#h2e22,#h2e23,#h2e12 {
|
||||
float: left;
|
||||
width: 10%;
|
||||
width: 14em;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
@@ -273,6 +273,7 @@ a.menu-title {
|
||||
left: 2px;
|
||||
}
|
||||
|
||||
|
||||
/*end*/
|
||||
EOF
|
||||
}
|
||||
|
@@ -0,0 +1,27 @@
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const flagContainer = document.getElementById('flag-container');
|
||||
|
||||
// Function to get the browser's locale
|
||||
function getBrowserLocale() {
|
||||
return navigator.language || navigator.userLanguage;
|
||||
}
|
||||
|
||||
// Function to map locale to country code
|
||||
function getCountryCodeFromLocale(locale) {
|
||||
const localeParts = locale.split('-');
|
||||
return localeParts.length > 1 ? localeParts[1] : localeParts[0];
|
||||
}
|
||||
|
||||
// Function to create and display the flag icon
|
||||
function displayFlagIcon(countryCode) {
|
||||
const flagIcon = document.createElement('span');
|
||||
flagIcon.className = `flag-icon flag-icon-${countryCode.toLowerCase()}`;
|
||||
flagIcon.id = 'flag-icon';
|
||||
flagContainer.appendChild(flagIcon);
|
||||
}
|
||||
|
||||
// Main logic
|
||||
const locale = getBrowserLocale();
|
||||
const countryCode = getCountryCodeFromLocale(locale);
|
||||
displayFlagIcon(countryCode);
|
||||
});
|
@@ -1,4 +1,6 @@
|
||||
/usr/share/smanager/log/production.log {
|
||||
/var/log/smanager/smanager.log {
|
||||
su root root
|
||||
create 600 root root
|
||||
weekly
|
||||
copytruncate
|
||||
rotate 12
|
||||
|
@@ -7,7 +7,7 @@ After=network.target
|
||||
Type=simple
|
||||
SyslogIdentifier=smanager
|
||||
WorkingDirectory=/usr/share/smanager/script
|
||||
PIDFile=/var/run/smanager.pid
|
||||
PIDFile=/run/smanager.pid
|
||||
ExecStartPre=/sbin/e-smith/service-status smanager
|
||||
ExecStart=/usr/bin/hypnotoad srvmngr -f
|
||||
ExecStop=/usr/bin/hypnotoad -s srvmngr
|
||||
|
@@ -25,8 +25,16 @@ use SrvMngr::Plugin::I18N;
|
||||
use SrvMngr::I18N;
|
||||
use SrvMngr::Model::Main;
|
||||
|
||||
use SrvMngr::Plugin::WithoutCache;
|
||||
|
||||
our $VERSION = '1.420';
|
||||
#this is overwrittrn with the "release" by the spec file - release can be "99.el8.sme"
|
||||
our $VERSION = '';
|
||||
#Extract the release value
|
||||
if ($VERSION =~ /^(\d+)/) {
|
||||
$VERSION = $1; # $1 contains the matched numeric digits
|
||||
} else {
|
||||
$VERSION = '999' #No leading numeric digits found
|
||||
}
|
||||
$VERSION = eval $VERSION;
|
||||
|
||||
use Exporter 'import';
|
||||
@@ -210,6 +218,8 @@ sub setup_plugins {
|
||||
$self->plugin('TagHelpers');
|
||||
|
||||
$self->plugin('RenderFile');
|
||||
|
||||
$self->plugin('SrvMngr::Plugin::WithoutCache');
|
||||
|
||||
# CSRF protection if production mode
|
||||
# $self->plugin('Mojolicious::Plugin::CSRFDefender' => {
|
||||
@@ -624,7 +634,7 @@ sub getNavigation {
|
||||
{
|
||||
$heading = $rec->prop('Heading');
|
||||
$description = $rec->prop('Description');
|
||||
$headingWeight = $rec->prop('HeadingWeight');
|
||||
$headingWeight = $rec->prop('HeadingWeight') || 99999; #Stop noise in logs if file in dir does not have nav header.
|
||||
$descriptionWeight = $rec->prop('DescriptionWeight');
|
||||
$urlpath = $rec->prop('UrlPath') || '';
|
||||
$menucat = $rec->prop('MenuCat') || 'A'; # admin menu (default)
|
||||
|
@@ -37,6 +37,8 @@ use esmith::BackupHistoryDB;
|
||||
use esmith::util;
|
||||
use esmith::lockfile;
|
||||
|
||||
use esmith::BlockDevices;
|
||||
|
||||
use constant DEBUG => $ENV{MOJO_SMANAGER_DEBUG} || 0;
|
||||
|
||||
our $cdb = esmith::ConfigDB->open || die "Couldn't open config db";
|
||||
@@ -1576,19 +1578,33 @@ sub get_BackupwkDest_options {
|
||||
my @usbdisks = ();
|
||||
|
||||
if ( $VFSType eq 'usb' ) {
|
||||
foreach my $udi (qx(hal-find-by-property --key volume.fsusage --string filesystem)) {
|
||||
$udi =~ m/^(\S+)/;
|
||||
my $devices = esmith::BlockDevices->new ('allowmount' => 'disabled');
|
||||
my ($valid, $invalid) = $devices->checkBackupDrives(0);
|
||||
|
||||
my $is_mounted = qx(hal-get-property --udi $1 --key volume.is_mounted);
|
||||
|
||||
if ($is_mounted eq "false\n") {
|
||||
my $vollbl = qx(hal-get-property --udi $1 --key volume.label);
|
||||
$vollbl =~ m/^(\S+)/;
|
||||
if ($vollbl =~ /^\s/) {$vollbl = 'nolabel';}
|
||||
chomp $vollbl;
|
||||
push @usbdisks, $vollbl;
|
||||
if ( ${$valid}[0] ) {
|
||||
foreach ( @{$valid} ) {
|
||||
push @usbdisks, $devices->label($_);
|
||||
}
|
||||
}
|
||||
|
||||
if (!$usbdisks[0]){
|
||||
push (@usbdisks,$c->l('bac_No suitable local devices found'));
|
||||
}
|
||||
$devices->destroy;
|
||||
|
||||
#foreach my $udi (qx(hal-find-by-property --key volume.fsusage --string filesystem)) {
|
||||
#$udi =~ m/^(\S+)/;
|
||||
|
||||
#my $is_mounted = qx(hal-get-property --udi $1 --key volume.is_mounted);
|
||||
|
||||
#if ($is_mounted eq "false\n") {
|
||||
#my $vollbl = qx(hal-get-property --udi $1 --key volume.label);
|
||||
#$vollbl =~ m/^(\S+)/;
|
||||
#if ($vollbl =~ /^\s/) {$vollbl = 'nolabel';}
|
||||
#chomp $vollbl;
|
||||
#push @usbdisks, $vollbl;
|
||||
#}
|
||||
#}
|
||||
# return undef unless ($usbdisks[0]);
|
||||
}
|
||||
|
||||
@@ -1985,31 +2001,50 @@ sub dmount {
|
||||
return ( qx(/bin/mount -t nfs -o nolock "$host:/$share" $mountdir 2>&1) );
|
||||
}
|
||||
elsif ($VFSType eq 'usb') {
|
||||
my $device = "";
|
||||
my $blkdev = "";
|
||||
my $device = "";
|
||||
my $vollbl = "";
|
||||
foreach my $udi (qx(hal-find-by-property --key volume.fsusage --string filesystem)) {
|
||||
$udi =~ m/^(\S+)/;
|
||||
my $is_mounted = qx(hal-get-property --udi $1 --key volume.is_mounted);
|
||||
|
||||
if ($is_mounted eq "false\n") {
|
||||
$blkdev = qx(hal-get-property --udi $1 --key block.device);
|
||||
if ($blkdev =~ m/^(\S+)/) {$blkdev = $1;}
|
||||
}
|
||||
if ($is_mounted eq "false\n") {
|
||||
$vollbl = qx(hal-get-property --udi $1 --key volume.label);
|
||||
$vollbl =~ m/^(\S+)/;
|
||||
if ($vollbl =~ /^\s/) {$vollbl = 'nolabel';}
|
||||
}
|
||||
my $devices = esmith::BlockDevices->new ('allowmount' => 'disabled');
|
||||
my ($valid, $invalid) = $devices->checkBackupDrives(0);
|
||||
|
||||
chomp $vollbl;
|
||||
chomp $blkdev;
|
||||
$vollbl = "media/$vollbl";
|
||||
if ($vollbl eq $share) {
|
||||
$device = $blkdev;
|
||||
}
|
||||
if ( ${$valid}[0] ) {
|
||||
foreach ( @{$valid} ) {
|
||||
$vollbl = $devices->label($_);
|
||||
if ( $share eq "media/$vollbl" ) {
|
||||
$device = "/dev/$_";
|
||||
}
|
||||
}
|
||||
}
|
||||
return ( qx(/bin/mount $device "/$share" 2>&1) );
|
||||
$devices->destroy;
|
||||
return ( qx (mount $device /$share 2>&1) );
|
||||
|
||||
#-------------------------------------------------------------------------------------------------------
|
||||
#my $device = "";
|
||||
#my $blkdev = "";
|
||||
#my $vollbl = "";
|
||||
#foreach my $udi (qx(hal-find-by-property --key volume.fsusage --string filesystem)) {
|
||||
#$udi =~ m/^(\S+)/;
|
||||
#my $is_mounted = qx(hal-get-property --udi $1 --key volume.is_mounted);
|
||||
|
||||
#if ($is_mounted eq "false\n") {
|
||||
#$blkdev = qx(hal-get-property --udi $1 --key block.device);
|
||||
#if ($blkdev =~ m/^(\S+)/) {$blkdev = $1;}
|
||||
#}
|
||||
#if ($is_mounted eq "false\n") {
|
||||
#$vollbl = qx(hal-get-property --udi $1 --key volume.label);
|
||||
#$vollbl =~ m/^(\S+)/;
|
||||
#if ($vollbl =~ /^\s/) {$vollbl = 'nolabel';}
|
||||
#}
|
||||
|
||||
#chomp $vollbl;
|
||||
#chomp $blkdev;
|
||||
#$vollbl = "media/$vollbl";
|
||||
#if ($vollbl eq $share) {
|
||||
#$device = $blkdev;
|
||||
#}
|
||||
#}
|
||||
#return ( qx(/bin/mount $device "/$share" 2>&1) );
|
||||
#-------------------------------------------------------------------------------------------------------
|
||||
} else {
|
||||
return ("Error while mounting $host/$share : $VFSType not supported.\n");
|
||||
}
|
||||
|
@@ -57,12 +57,14 @@ sub do_display {
|
||||
|
||||
$mai_datas{'trt'} = $trt;
|
||||
|
||||
if ( $trt eq 'ACC' ) {
|
||||
$dest = 'emailaccess';
|
||||
$mai_datas{fetchmailmethod} = $cdb->get_prop('fetchmail', 'Method');
|
||||
}
|
||||
if ( $trt eq 'ACC' )
|
||||
{
|
||||
$dest = 'emailaccess';
|
||||
$mai_datas{fetchmailmethod} = $cdb->get_prop('fetchmail', 'Method');
|
||||
}
|
||||
|
||||
if ( $trt eq 'FIL' ) {
|
||||
if ( $trt eq 'FIL' )
|
||||
{
|
||||
$dest = 'emailfilter';
|
||||
$mai_datas{'virusstatus'} = $c->get_virus_status();
|
||||
$mai_datas{'spamstatus'} = $cdb->get_prop('spamassassin', 'status');
|
||||
@@ -72,9 +74,10 @@ sub do_display {
|
||||
$mai_datas{spamsortspam} = $cdb->get_prop('spamassassin', 'SortSpam');
|
||||
$mai_datas{spamsubjecttag} = $cdb->get_prop('spamassassin', 'SubjectTag');
|
||||
$mai_datas{spamsubject} = $cdb->get_prop('spamassassin', 'Subject');
|
||||
}
|
||||
}
|
||||
|
||||
if ( $trt eq 'REC' ) {
|
||||
if ( $trt eq 'REC' )
|
||||
{
|
||||
$dest = 'emailreceive';
|
||||
$mai_datas{fetchmailmethod} = $cdb->get_prop('fetchmail', 'Method');
|
||||
$mai_datas{freqoffice} = $cdb->get_prop('fetchmail', 'FreqOffice');
|
||||
@@ -86,9 +89,10 @@ sub do_display {
|
||||
$mai_datas{specifyheader} = get_secondary_mail_use_envelope();
|
||||
$mai_datas{secondarymailenvelope} = $cdb->get_prop('fetchmail', 'SecondaryMailEnvelope');
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if ( $trt eq 'DEL' ) {
|
||||
if ( $trt eq 'DEL' )
|
||||
{
|
||||
$dest = 'emaildeliver';
|
||||
$mai_datas{emailunknownuser} = $cdb->get_value('EmailUnknownUser') || '"returntosender';
|
||||
$mai_datas{delegatemailserver} = $cdb->get_value('DelegateMailServer');
|
||||
@@ -96,7 +100,7 @@ sub do_display {
|
||||
$mai_datas{smtpauthproxystatus} = $cdb->get_prop('smtp-auth-proxy', 'status') || 'disabled';
|
||||
$mai_datas{smtpauthproxyuserid} = $cdb->get_prop('smtp-auth-proxy', 'Userid') || '';
|
||||
$mai_datas{smtpauthproxypassword} = $cdb->get_prop('smtp-auth-proxy', 'Passwd') || '';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$c->stash( title => $title, notif => $notif, mai_datas => \%mai_datas );
|
||||
@@ -120,98 +124,107 @@ sub do_update {
|
||||
|
||||
my ($dest, $res, $result) = '';
|
||||
|
||||
if ( $trt eq 'ACC' ) {
|
||||
if ( $trt eq 'ACC' )
|
||||
{
|
||||
$dest = 'emailaccess';
|
||||
# $mai_datas{xxx} = $c->param('XXX');
|
||||
|
||||
# controls
|
||||
# $res = xxxxxxx( $c );
|
||||
# $result .= $res unless $res eq 'OK';
|
||||
|
||||
$dest = 'emailaccess';
|
||||
# $mai_datas{xxx} = $c->param('XXX');
|
||||
if ( ! $result )
|
||||
{
|
||||
$res = $c->change_settings_access();
|
||||
$result .= $res unless $res eq 'OK';
|
||||
if ( ! $result )
|
||||
{
|
||||
$result = $c->l('mai_SUCCESS');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# controls
|
||||
# $res = xxxxxxx( $c );
|
||||
# $result .= $res unless $res eq 'OK';
|
||||
if ( $trt eq 'FIL' )
|
||||
{
|
||||
$dest = 'emailfilter';
|
||||
# $mai_datas{xxx} = $c->param('XXX');
|
||||
|
||||
# controls
|
||||
# $res = zzzzzz( $c );
|
||||
# $result .= $res unless $res eq 'OK';
|
||||
|
||||
if ( ! $result ) {
|
||||
$res = $c->change_settings_access();
|
||||
$result .= $res unless $res eq 'OK';
|
||||
if ( ! $result ) {
|
||||
$result = $c->l('mai_SUCCESS');
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( ! $result )
|
||||
{
|
||||
$res = $c->change_settings_filtering();
|
||||
$result .= $res unless $res eq 'OK';
|
||||
if ( ! $result )
|
||||
{
|
||||
$result = $c->l('mai_SUCCESS');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( $trt eq 'FIL' ) {
|
||||
if ( $trt eq 'REC' )
|
||||
{
|
||||
$dest = 'emailreceive';
|
||||
# $mai_datas{xxx} = $c->param('XXX');
|
||||
|
||||
# controls
|
||||
# $res = yyyyyyyyy( $c );
|
||||
# $result .= $res unless $res eq 'OK';
|
||||
|
||||
$dest = 'emailfilter';
|
||||
# $mai_datas{xxx} = $c->param('XXX');
|
||||
if ( ! $result )
|
||||
{
|
||||
$res = $c->change_settings_reception();
|
||||
$result .= $res unless $res eq 'OK';
|
||||
if ( ! $result )
|
||||
{
|
||||
$result = $c->l('mai_SUCCESS');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# controls
|
||||
# $res = zzzzzz( $c );
|
||||
# $result .= $res unless $res eq 'OK';
|
||||
if ( $trt eq 'DEL' )
|
||||
{
|
||||
$dest = 'emaildeliver';
|
||||
# $mai_datas{xxx} = $c->param('XXX');
|
||||
|
||||
# controls
|
||||
$res = $c->ip_number_or_blank( $c->param('DelegateMailServer') );
|
||||
$result .= $res . ' DMS <br>' unless $res eq 'OK';
|
||||
|
||||
if ( ! $result ) {
|
||||
$res = $c->change_settings_filtering();
|
||||
$result .= $res unless $res eq 'OK';
|
||||
if ( ! $result ) {
|
||||
$result = $c->l('mai_SUCCESS');
|
||||
}
|
||||
}
|
||||
}
|
||||
$res = $c->validate_smarthost( $c->param('SMTPSmartHost') );
|
||||
$result .= $res . ' SH <br>' unless $res eq 'OK';
|
||||
|
||||
if ( $trt eq 'REC' ) {
|
||||
$res = $c->nonblank_if_smtpauth( $c->param('SMTPSmartHost') );
|
||||
$result .= $res . ' SH <br>' unless $res eq 'OK';
|
||||
|
||||
$dest = 'emailreceive';
|
||||
# $mai_datas{xxx} = $c->param('XXX');
|
||||
$res = $c->nonblank_if_smtpauth( $c->param('SMTPAUTHPROXY_Userid') );
|
||||
$result .= $res . ' USR <br>' unless $res eq 'OK';
|
||||
|
||||
# controls
|
||||
# $res = yyyyyyyyy( $c );
|
||||
# $result .= $res unless $res eq 'OK';
|
||||
$res = $c->nonblank_if_smtpauth( $c->param('SMTPAUTHPROXY_Passwd') );
|
||||
$result .= $res . ' PWD <br>' unless $res eq 'OK';
|
||||
|
||||
if ( ! $result ) {
|
||||
$res = $c->change_settings_reception();
|
||||
$result .= $res unless $res eq 'OK';
|
||||
if ( ! $result ) {
|
||||
$result = $c->l('mai_SUCCESS');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( $trt eq 'DEL' ) {
|
||||
|
||||
$dest = 'emaildeliver';
|
||||
# $mai_datas{xxx} = $c->param('XXX');
|
||||
|
||||
# controls
|
||||
$res = $c->ip_number_or_blank( $c->param('DelegateMailServer') );
|
||||
$result .= $res . ' DMS <br>' unless $res eq 'OK';
|
||||
|
||||
$res = $c->validate_smarthost( $c->param('SMTPSmartHost') );
|
||||
$result .= $res . ' SH <br>' unless $res eq 'OK';
|
||||
|
||||
$res = $c->nonblank_if_smtpauth( $c->param('SMTPSmartHost') );
|
||||
$result .= $res . ' SH <br>' unless $res eq 'OK';
|
||||
|
||||
$res = $c->nonblank_if_smtpauth( $c->param('SMTPAUTHPROXY_Userid') );
|
||||
$result .= $res . ' USR <br>' unless $res eq 'OK';
|
||||
|
||||
$res = $c->nonblank_if_smtpauth( $c->param('SMTPAUTHPROXY_Passwd') );
|
||||
$result .= $res . ' PWD <br>' unless $res eq 'OK';
|
||||
|
||||
if ( ! $result ) {
|
||||
$res = $c->change_settings_delivery();
|
||||
$result .= $res unless $res eq 'OK';
|
||||
if ( ! $result ) {
|
||||
$result = $c->l('mai_SUCCESS');
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( ! $result )
|
||||
{
|
||||
$res = $c->change_settings_delivery();
|
||||
$result .= $res unless $res eq 'OK';
|
||||
if ( ! $result )
|
||||
{
|
||||
$result = $c->l('mai_SUCCESS');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# common part
|
||||
|
||||
if ($res ne 'OK') {
|
||||
$c->stash( error => $result );
|
||||
$c->stash( title => $title, mai_datas => \%mai_datas );
|
||||
return $c->render( $dest );
|
||||
}
|
||||
if ($res ne 'OK')
|
||||
{
|
||||
$c->stash( error => $result );
|
||||
$c->stash( title => $title, mai_datas => \%mai_datas );
|
||||
return $c->render( $dest );
|
||||
}
|
||||
|
||||
my $message = "emailsettings updates $trt DONE";
|
||||
$c->app->log->info($message);
|
||||
@@ -395,19 +408,16 @@ sub get_current_webmail_status {
|
||||
# determine status of webmail
|
||||
my $WebmailStatus = "disabled";
|
||||
|
||||
my $IMPStatus = $cdb->get_prop('imp', 'status') || 'disabled';
|
||||
|
||||
my $HordeStatus = $cdb->get_prop('horde', 'status') || 'disabled';
|
||||
my $RoundcubeStatus = $cdb->get_prop('roundcube', 'status') || 'disabled';
|
||||
|
||||
my $MysqlStatus = $cdb->get_prop('mariadb', 'status') || 'disabled';
|
||||
|
||||
my $PHPStatus = $cdb->get_prop('php', 'status') || 'disabled';
|
||||
my $PHPStatus = $cdb->get_prop('php81-php-fpm', 'status') || 'disabled';
|
||||
|
||||
my $Networkaccess = $cdb->get_prop('horde','access') || 'disabled';
|
||||
my $Networkaccess = $cdb->get_prop('roundcube','access') || 'disabled';
|
||||
|
||||
# all four components must be on for webmail to be working
|
||||
if ( ( $IMPStatus eq "enabled" )
|
||||
&& ( $HordeStatus eq "enabled" )
|
||||
# all 3 components must be on for webmail to be working
|
||||
if ( ( $RoundcubeStatus eq "enabled" )
|
||||
&& ( $MysqlStatus eq "enabled" )
|
||||
&& ( $PHPStatus eq "enabled" )
|
||||
&& ( $Networkaccess eq "public"))
|
||||
@@ -415,8 +425,7 @@ sub get_current_webmail_status {
|
||||
$WebmailStatus = "enabledSSL";
|
||||
}
|
||||
|
||||
elsif ( ( $IMPStatus eq "enabled" )
|
||||
&& ( $HordeStatus eq "enabled" )
|
||||
elsif ( ( $RoundcubeStatus eq "enabled" )
|
||||
&& ( $MysqlStatus eq "enabled" )
|
||||
&& ( $PHPStatus eq "enabled" )
|
||||
&& ( $Networkaccess eq "private" ))
|
||||
@@ -507,8 +516,7 @@ sub get_webmail_opt {
|
||||
|
||||
return [[ $c->l('DISABLED') => 'disabled' ],
|
||||
[ $c->l('mai_ENABLED_SECURE_ONLY') => 'enabledSSL' ],
|
||||
[ $c->l('mai_ONLY_LOCAL_NETWORK_SSL') => 'localnetworkSSL' ],
|
||||
[ $c->l('mai_ENABLED_BOTH') => 'public' ]];
|
||||
[ $c->l('mai_ONLY_LOCAL_NETWORK_SSL') => 'localnetworkSSL' ]];
|
||||
|
||||
}
|
||||
|
||||
@@ -519,10 +527,10 @@ sub get_webmail_options {
|
||||
|
||||
my %options = (
|
||||
disabled => 'DISABLED',
|
||||
enabledSSL => 'mai_ENABLED_SECURE_ONLY',
|
||||
localnetworkSSL => 'mai_ONLY_LOCAL_NETWORK_SSL' );
|
||||
enabledSSL => 'mai_ENABLED_SECURE_ONLY',
|
||||
localnetworkSSL => 'mai_ONLY_LOCAL_NETWORK_SSL');
|
||||
|
||||
\%options;
|
||||
return \%options;
|
||||
}
|
||||
|
||||
|
||||
@@ -658,6 +666,7 @@ sub display_multidrop {
|
||||
sub change_settings_reception {
|
||||
|
||||
my $c = shift;
|
||||
$cdb = esmith::ConfigDB->open || die "Couldn't open config db";
|
||||
|
||||
my $FetchmailMethod = ( $c->param('FetchmailMethod') || 'standard' );
|
||||
|
||||
@@ -724,6 +733,7 @@ sub change_settings_reception {
|
||||
sub change_settings_delivery {
|
||||
|
||||
my ($c) = shift;
|
||||
$cdb = esmith::ConfigDB->open || die "Couldn't open config db";
|
||||
|
||||
my $EmailUnknownUser = ($c->param('EmailUnknownUser') || 'returntosender');
|
||||
|
||||
@@ -752,7 +762,8 @@ sub change_settings_delivery {
|
||||
sub change_settings_access {
|
||||
|
||||
my $c = shift;
|
||||
|
||||
$cdb = esmith::ConfigDB->open || die "Couldn't open config db";
|
||||
|
||||
my $pop3Access = ($c->param('POPAccess') || 'private');
|
||||
if ($pop3Access eq 'disabled') {
|
||||
$cdb->set_prop('pop3', "status", "disabled" );
|
||||
@@ -802,38 +813,22 @@ sub change_settings_access {
|
||||
#------------------------------------------------------------
|
||||
|
||||
my $webmail = ($c->param('WebMail') || 'disabled');
|
||||
if ( $webmail eq "enabled" ) {
|
||||
$cdb->set_prop('php', "status", $webmail );
|
||||
$cdb->set_prop('mariadb',"status", $webmail );
|
||||
$cdb->set_prop('imp',"status", $webmail );
|
||||
$cdb->set_prop('horde', "status", $webmail );
|
||||
$cdb->set_prop('imp',"access", "full" );
|
||||
$cdb->set_prop('horde',"access", "public" );
|
||||
$cdb->set_prop('horde',"HttpsOnly", "no" );
|
||||
}
|
||||
elsif ( $webmail eq "enabledSSL" ) {
|
||||
$cdb->set_prop('php',"status", "enabled" );
|
||||
if ( $webmail eq "enabledSSL" ) {
|
||||
$cdb->set_prop('php81-php-fpm',"status", "enabled" );
|
||||
$cdb->set_prop('mariadb',"status", "enabled" );
|
||||
$cdb->set_prop('imp',"status", 'enabled' );
|
||||
$cdb->set_prop('horde',"status", 'enabled' );
|
||||
$cdb->set_prop('imp',"access", "SSL" );
|
||||
$cdb->set_prop('horde',"access", "public" );
|
||||
$cdb->set_prop('horde',"HttpsOnly", "yes" );
|
||||
$cdb->set_prop('roundcube',"status", 'enabled' );
|
||||
$cdb->set_prop('roundcube',"access", "public" );
|
||||
}
|
||||
|
||||
elsif ( $webmail eq "localnetworkSSL" ) {
|
||||
$cdb->set_prop('php',"status", "enabled" );
|
||||
$cdb->set_prop('php81-php-fpm',"status", "enabled" );
|
||||
$cdb->set_prop('mariadb',"status", "enabled" );
|
||||
$cdb->set_prop('imp',"status", 'enabled' );
|
||||
$cdb->set_prop('horde',"status", 'enabled' );
|
||||
$cdb->set_prop('imp',"access", "SSL" );
|
||||
$cdb->set_prop('horde',"access", "private" );
|
||||
$cdb->set_prop('horde',"HttpsOnly", "yes" );
|
||||
$cdb->set_prop('roundcube',"status", 'enabled' );
|
||||
$cdb->set_prop('roundcube',"access", "private" );
|
||||
}
|
||||
|
||||
else {
|
||||
$cdb->set_prop('imp',"status", 'disabled' );
|
||||
$cdb->set_prop('horde',"status", 'disabled' );
|
||||
$cdb->set_prop('roundcube',"status", 'disabled' );
|
||||
}
|
||||
|
||||
unless ( system( "/sbin/e-smith/signal-event", "email-update" ) == 0 ) {
|
||||
@@ -847,6 +842,8 @@ sub change_settings_access {
|
||||
sub change_settings_filtering {
|
||||
|
||||
my $c = shift;
|
||||
$cdb = esmith::ConfigDB->open || die "Couldn't open config db";
|
||||
|
||||
|
||||
my $virus_status = ( $c->param('VirusStatus') || 'disabled' );
|
||||
$cdb->set_prop("qpsmtpd", 'VirusScan', $virus_status);
|
||||
@@ -860,7 +857,7 @@ sub change_settings_filtering {
|
||||
Subject
|
||||
SubjectTag) )
|
||||
{
|
||||
$cdb->set_prop('spamassassin', $param, $c->param("Spam$param"));
|
||||
$cdb->set_prop('spamassassin', $param, $c->param("Spam$param"));
|
||||
}
|
||||
|
||||
my $patterns_status = $c->adjust_patterns() ? 'enabled' : 'disabled';
|
||||
@@ -868,7 +865,7 @@ sub change_settings_filtering {
|
||||
|
||||
unless ( system( "/sbin/e-smith/signal-event", "email-update" ) == 0 )
|
||||
{
|
||||
return $c->l('mai_ERROR_UPDATING_CONFIGURATION');
|
||||
return $c->l('mai_ERROR_UPDATING_CONFIGURATION');
|
||||
}
|
||||
|
||||
return 'OK';
|
||||
|
@@ -171,9 +171,11 @@ sub add_portforward {
|
||||
#work out which protocol
|
||||
my $fdb;
|
||||
if ($proto eq 'TCP') {
|
||||
$tcp_db = esmith::ConfigDB->open('portforward_tcp') || die "Can't open portforward_tcp database: $!\n";
|
||||
$fdb = $tcp_db;
|
||||
}
|
||||
else {
|
||||
$udp_db = esmith::ConfigDB->open('portforward_udp') || die "Can't open portforward_udp database: $!\n";
|
||||
$fdb = $udp_db;
|
||||
}
|
||||
#Get the other values
|
||||
|
@@ -23,14 +23,16 @@ use File::Basename;
|
||||
|
||||
our $cdb = esmith::ConfigDB->open || die "Couldn't open config db";
|
||||
|
||||
my $dnf_status_file = '/var/cache/dnf/dnf.status';
|
||||
|
||||
#use File::stat;
|
||||
|
||||
our %dbs;
|
||||
|
||||
for ( qw(available installed updates) )
|
||||
{
|
||||
$dbs{$_} = esmith::ConfigDB->open_ro("yum_$_") or
|
||||
die "Couldn't open yum_$_ DB\n";
|
||||
$dbs{$_} = esmith::ConfigDB->open_ro("dnf_$_") or
|
||||
die "Couldn't open dnf_$_ DB\n";
|
||||
}
|
||||
|
||||
for ( qw(repositories) )
|
||||
@@ -52,10 +54,11 @@ sub main {
|
||||
|
||||
$yum_datas{'trt'} = 'STAT';
|
||||
|
||||
if ( -e "/var/run/yum.pid" ) {
|
||||
|
||||
if ( $c->is_dnf_running()) {
|
||||
$yum_datas{'trt'} = 'LOGF';
|
||||
$dest = 'yumlogfile';
|
||||
} elsif ($cdb->get_prop('yum', 'LogFile')) {
|
||||
} elsif ($cdb->get_prop('dnf', 'LogFile')) {
|
||||
$yum_datas{'trt'} = 'PSTU';
|
||||
$yum_datas{'reconf'} = $cdb->get_value('UnsavedChanges', 'yes');
|
||||
$dest = 'yumpostupg';
|
||||
@@ -83,9 +86,9 @@ sub do_display {
|
||||
$yum_datas{'trt'} = $trt;
|
||||
|
||||
# force $trt if current logfile
|
||||
if ( -e "/var/run/yum.pid" ) {
|
||||
if ( $c->is_dnf_running() ) {
|
||||
$trt = 'LOGF';
|
||||
} elsif ($cdb->get_prop('yum', 'LogFile')) {
|
||||
} elsif ($cdb->get_prop('dnf', 'LogFile')) {
|
||||
$trt = 'PSTU';
|
||||
}
|
||||
|
||||
@@ -106,13 +109,13 @@ sub do_display {
|
||||
}
|
||||
|
||||
if ( $trt eq 'LOGF' ) {
|
||||
if (-e "/var/run/yum.pid") {
|
||||
if ($c->is_dnf_running()) {
|
||||
$dest = 'yumlogfile';
|
||||
}
|
||||
}
|
||||
|
||||
if ( $trt eq 'PSTU') {
|
||||
if ($cdb->get_prop('yum', 'LogFile')) {
|
||||
if ($cdb->get_prop('dnf', 'LogFile')) {
|
||||
$dest = 'yumpostupg';
|
||||
$yum_datas{'reconf'} = $cdb->get_value('UnsavedChanges', 'yes');
|
||||
}
|
||||
@@ -221,7 +224,7 @@ sub do_update {
|
||||
if ( $trt eq 'LOGF' ) {
|
||||
|
||||
$dest = 'yumlogfile';
|
||||
if ( ! -e "/var/run/yum.pid") {
|
||||
if ( ! $c->is_dnf_running()) {
|
||||
$yum_datas{trt} = 'SUC';
|
||||
$result = $c->l('yum_SUCCESS');
|
||||
}
|
||||
@@ -247,6 +250,24 @@ sub do_update {
|
||||
|
||||
};
|
||||
|
||||
sub get_dnf_status {
|
||||
#interrogate status file created and maintained by smeserver.py plugin for dnf.
|
||||
my ($c) = @_;
|
||||
my $file_name = $dnf_status_file;
|
||||
my $content = "resolved";
|
||||
if ( -e "$file_name") {
|
||||
open my $fh, '<', $file_name or die "Can't open file: $!";
|
||||
$content = <$fh>;
|
||||
close $fh;
|
||||
}
|
||||
return $content;
|
||||
}
|
||||
|
||||
sub is_dnf_running {
|
||||
my ($c) = @_;
|
||||
my $dnf_status = $c->get_dnf_status();
|
||||
return $dnf_status ne "resolved" && $dnf_status ne "config" && $dnf_status ne "sack";
|
||||
}
|
||||
|
||||
sub is_empty {
|
||||
|
||||
@@ -289,7 +310,7 @@ sub package_functions_enabled {
|
||||
|
||||
my ($c) = @_;
|
||||
|
||||
return ($cdb->get_prop("yum", "PackageFunctions") eq "enabled");
|
||||
return ($cdb->get_prop("dnf", "PackageFunctions") eq "enabled");
|
||||
|
||||
}
|
||||
|
||||
@@ -298,7 +319,7 @@ sub get_status {
|
||||
|
||||
my ($c, $prop, $localise) = @_;
|
||||
|
||||
my $status = $cdb->get_prop("yum", $prop) || 'disabled';
|
||||
my $status = $cdb->get_prop("dnf", $prop) || 'disabled';
|
||||
|
||||
return $status unless $localise;
|
||||
|
||||
@@ -433,7 +454,7 @@ sub change_settings {
|
||||
PackageFunctions
|
||||
) )
|
||||
{
|
||||
$cdb->set_prop('yum', $param, $c->param("yum_$param"));
|
||||
$cdb->set_prop("dnf", $param, $c->param("yum_$param"));
|
||||
}
|
||||
|
||||
my $check4updates = $c->param("yum_check4updates");
|
||||
@@ -441,21 +462,21 @@ sub change_settings {
|
||||
|
||||
if ($check4updates ne 'disabled') { $status = 'enabled'; }
|
||||
|
||||
$cdb->set_prop('yum', 'check4updates', $check4updates);
|
||||
$cdb->set_prop("dnf", 'check4updates', $check4updates);
|
||||
|
||||
my $deltarpm = $c->param("yum_DeltaRpmProcess");
|
||||
$cdb->set_prop('yum', 'DeltaRpmProcess', $deltarpm);
|
||||
$cdb->set_prop("dnf", 'DeltaRpmProcess', $deltarpm);
|
||||
|
||||
my $downloadonly = $c->param("yum_DownloadOnly");
|
||||
if ($downloadonly ne 'disabled') { $status = 'enabled'; }
|
||||
|
||||
$cdb->set_prop('yum', 'DownloadOnly', $downloadonly);
|
||||
$cdb->set_prop("dnf", 'DownloadOnly', $downloadonly);
|
||||
|
||||
my $AutoInstallUpdates = $c->param("yum_AutoInstallUpdates");
|
||||
if ($AutoInstallUpdates ne 'disabled') { $status = 'enabled'; }
|
||||
|
||||
$cdb->set_prop('yum', 'AutoInstallUpdates', $AutoInstallUpdates);
|
||||
$cdb->set_prop('yum', 'status', $status);
|
||||
$cdb->set_prop("dnf", 'AutoInstallUpdates', $AutoInstallUpdates);
|
||||
$cdb->set_prop("dnf", 'status', $status);
|
||||
|
||||
my %selected = map {$_ => 1} @{$c->every_param('SelectedRepositories')};
|
||||
|
||||
@@ -469,7 +490,7 @@ sub change_settings {
|
||||
|
||||
$dbs{repositories}->reload;
|
||||
|
||||
unless ( system( "/sbin/e-smith/signal-event", "yum-modify" ) == 0 )
|
||||
unless ( system( "/sbin/e-smith/signal-event", "dnf-modify" ) == 0 )
|
||||
{
|
||||
return $c->l('yum_ERROR_UPDATING_CONFIGURATION');
|
||||
}
|
||||
@@ -484,11 +505,11 @@ sub do_yum {
|
||||
|
||||
for ( qw(SelectedGroups SelectedPackages) )
|
||||
{
|
||||
$cdb->set_prop("yum", $_, join(',', (@{$c->every_param($_)} )));
|
||||
$cdb->set_prop("dnf", $_, join(',', (@{$c->every_param($_)} )));
|
||||
}
|
||||
|
||||
esmith::util::backgroundCommand(0,
|
||||
"/sbin/e-smith/signal-event", "yum-$function");
|
||||
"/sbin/e-smith/signal-event", "dnf-$function");
|
||||
|
||||
for ( qw(available installed updates) ) {
|
||||
$dbs{$_}->reload;
|
||||
@@ -517,7 +538,7 @@ sub format_yum_log {
|
||||
|
||||
$cdb->reload;
|
||||
|
||||
my $filepage = $cdb->get_prop('yum', 'LogFile');
|
||||
my $filepage = $cdb->get_prop('dnf', 'LogFile');
|
||||
return '' unless $filepage and ( -e "$filepage" );
|
||||
|
||||
my $out = sprintf "<PRE>";
|
||||
@@ -537,7 +558,7 @@ sub post_upgrade_reboot {
|
||||
|
||||
my $c = shift;
|
||||
|
||||
$cdb->get_prop_and_delete('yum', 'LogFile');
|
||||
$cdb->get_prop_and_delete('dnf', 'LogFile');
|
||||
$cdb->reload;
|
||||
|
||||
if (fork == 0) {
|
||||
@@ -552,7 +573,7 @@ sub post_upgrade_reboot {
|
||||
sub show_yum_log {
|
||||
my $c = shift;
|
||||
my $out = $c->format_yum_log();
|
||||
my $yum_log = $cdb->get_prop_and_delete('yum', 'LogFile');
|
||||
my $yum_log = $cdb->get_prop_and_delete('dnf', 'LogFile');
|
||||
return $out;
|
||||
}
|
||||
|
||||
|
@@ -1,3 +1,4 @@
|
||||
'bac_No suitable local devices found' => 'No suitable local devices found',
|
||||
'bac_BACKUP_TITLE' => 'Backup or restore server data',
|
||||
'bac_BACKUP_DESC' => '<P>The server provides two ways to back up and restore
|
||||
your server: using your local desktop or a tape drive.</P>
|
||||
|
73
root/usr/share/smanager/lib/SrvMngr/Plugin/Cache.pm
Normal file
73
root/usr/share/smanager/lib/SrvMngr/Plugin/Cache.pm
Normal file
@@ -0,0 +1,73 @@
|
||||
package SrvMngr::Plugin::Cache;
|
||||
use Mojo::Base -base;
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Mojolicious::Plugin::Renderer::WithoutCache::Cache - Mojo::Cache that doesn't cache
|
||||
|
||||
=head1 VERSION
|
||||
|
||||
Version 0.04
|
||||
|
||||
=cut
|
||||
|
||||
our $VERSION = '0.04';
|
||||
$VERSION = eval $VERSION;
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
You probably don't want to use this directly.
|
||||
|
||||
my $cache = Mojolicious::Plugin::Renderer::WithoutCache::Cache->new;
|
||||
# this cache does nothing
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
A cache object that's compatible to Mojo::Cache but does nothing. It does
|
||||
not save or return any values. It's always empty.
|
||||
|
||||
=head1 METHODS
|
||||
|
||||
=head2 get
|
||||
|
||||
Does nothing. Returns C<undef>.
|
||||
|
||||
=cut
|
||||
|
||||
sub get {}
|
||||
|
||||
=head2 set
|
||||
|
||||
Does nothing. Returns C<$self> so chaining is possible.
|
||||
|
||||
=cut
|
||||
|
||||
sub set { shift; }
|
||||
|
||||
=head2 max_keys
|
||||
|
||||
Always returns zero. Can't be set. We don't want any keys.
|
||||
|
||||
=cut
|
||||
|
||||
sub max_keys { 0 }
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
simbabque, C<< <simbabque at cpan.org> >>
|
||||
|
||||
=head1 BUGS
|
||||
|
||||
Please report any bugs or feature requests through an issue
|
||||
on github at L<https://github.com/simbabque/Mojolicious-Plugin-Renderer-WithoutCache/issues>.
|
||||
|
||||
=head1 LICENSE
|
||||
|
||||
Copyright (C) simbabque.
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the same terms as Perl itself.
|
||||
|
||||
=cut
|
||||
|
||||
1;
|
94
root/usr/share/smanager/lib/SrvMngr/Plugin/WithoutCache.pm
Normal file
94
root/usr/share/smanager/lib/SrvMngr/Plugin/WithoutCache.pm
Normal file
@@ -0,0 +1,94 @@
|
||||
package SrvMngr::Plugin::WithoutCache;
|
||||
use Mojo::Base 'Mojolicious::Plugin';
|
||||
use SrvMngr::Plugin::Cache;
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Mojolicious::Plugin::Renderer::WithoutCache - Disable the template cache in your Mojo app
|
||||
|
||||
=begin html
|
||||
|
||||
<p>
|
||||
<a href="https://travis-ci.org/simbabque/Mojolicious-Plugin-Renderer-WithoutCache"><img src="https://travis-ci.org/simbabque/Mojolicious-Plugin-Renderer-WithoutCache.svg?branch=master"></a>
|
||||
<a href='https://coveralls.io/github/simbabque/Mojolicious-Plugin-Renderer-WithoutCache?branch=master'><img src='https://coveralls.io/repos/github/simbabque/Mojolicious-Plugin-Renderer-WithoutCache/badge.svg?branch=master' alt='Coverage Status' /></a>
|
||||
</p>
|
||||
|
||||
=end html
|
||||
|
||||
=head1 VERSION
|
||||
|
||||
Version 0.04
|
||||
|
||||
=cut
|
||||
|
||||
our $VERSION = '0.04';
|
||||
$VERSION = eval $VERSION;
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
This plugin turns off the renderer's cache in L<Mojolicious> and L<Mojo::Lite> applications.
|
||||
|
||||
use Mojolicious::Lite;
|
||||
plugin 'Renderer::WithoutCache';
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This does what it says on the box. It turns off caching for the L<Mojolicious::Renderer>
|
||||
or any other renderer that's inside C<$app-E<gt>renderer> by injecting a cache object that
|
||||
does not do anything. This is superior to setting the C<max_keys> of L<Mojo::Cache>
|
||||
to C<0> if you plan to do a lot of uncached requests, because L<Mojolicious::Renderer>
|
||||
will still try to cache, and every time L<Mojo::Cache> sets a value in the cache it
|
||||
looks at the C<max_keys>, and then stops.
|
||||
|
||||
Doing nothing at all is cheaper. But not a lot really.
|
||||
|
||||
=head1 METHODS
|
||||
|
||||
=head2 register
|
||||
|
||||
Register the plugin in a L<Mojolicious> application.
|
||||
|
||||
$plugin->register(Mojolicious->new);
|
||||
|
||||
=cut
|
||||
|
||||
sub register {
|
||||
my ( $self, $app ) = @_;
|
||||
$app->renderer->cache( SrvMngr::Plugin::Cache->new );
|
||||
}
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
simbabque, C<< <simbabque at cpan.org> >>
|
||||
|
||||
=head1 BUGS
|
||||
|
||||
Please report any bugs or feature requests through an issue
|
||||
on github at L<https://github.com/simbabque/Mojolicious-Plugin-Renderer-WithoutCache/issues>.
|
||||
|
||||
=head1 SUPPORT
|
||||
|
||||
You can find documentation for this module with the perldoc command.
|
||||
|
||||
perldoc Mojolicious::Plugin::Renderer::WithoutCache
|
||||
|
||||
=head2 Why would I want to turn off the cache?
|
||||
|
||||
I don't know.
|
||||
|
||||
=head1 ACKNOWLEDGEMENTS
|
||||
|
||||
This plugin was inspired by Tom Hunt asking about turning the cache off
|
||||
on L<Stack Overflow|http://stackoverflow.com/q/41750243/1331451>.
|
||||
|
||||
=head1 LICENSE
|
||||
|
||||
Copyright (C) simbabque.
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the same terms as Perl itself.
|
||||
|
||||
=cut
|
||||
|
||||
1;
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 10 KiB |
@@ -0,0 +1,278 @@
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const flagContainer = document.getElementById('flag-container');
|
||||
|
||||
async function getCountryName(countryCode) {
|
||||
try {
|
||||
const response = await fetch(`https://restcountries.com/v3.1/alpha/${countryCode}`);
|
||||
if (!response.ok) throw new Error('Country not found');
|
||||
const data = await response.json();
|
||||
// Return the name in the native language
|
||||
return data[0].name.common;
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
return 'Unknown Country';
|
||||
}
|
||||
}
|
||||
|
||||
function getFlagEmoji(locale) {
|
||||
// Split the locale to get the language and country code
|
||||
const parts = locale.split('-');
|
||||
let countryCode;
|
||||
|
||||
// Handle single subtag (language only) or double subtag (language-country)
|
||||
if (parts.length === 1) {
|
||||
countryCode = getCountryCodeFromLanguage(parts[0]);
|
||||
} else if (parts.length === 2) {
|
||||
countryCode = parts[1].toLowerCase(); // Use the country code
|
||||
}
|
||||
|
||||
// If country code is not found, set a fallback output
|
||||
if (!countryCode) {
|
||||
const fallback = `? ${locale.toUpperCase()}`; // Just a question mark and the full locale
|
||||
return { flag: fallback, isUnknown: true, countryName: 'Unknown Country' };
|
||||
}
|
||||
|
||||
// Convert the country code to a flag emoji
|
||||
return {
|
||||
flag: String.fromCodePoint(...[...countryCode.toUpperCase()].map(char => 0x1F1E6 + char.charCodeAt(0) - 'A'.charCodeAt(0))),
|
||||
isUnknown: false,
|
||||
countryCode: countryCode
|
||||
};
|
||||
}
|
||||
|
||||
function getCountryCodeFromLanguage(language) {
|
||||
// Map languages to countries (this is an example, extend as needed)
|
||||
const languageToCountryMap = {
|
||||
// Add more mappings as needed
|
||||
"af": "NA",
|
||||
"agq": "CM",
|
||||
"ak": "GH",
|
||||
"am": "ET",
|
||||
"ar": "01",
|
||||
"as": "IN",
|
||||
"asa": "TZ",
|
||||
"ast": "ES",
|
||||
"az": "rl",
|
||||
"bas": "CM",
|
||||
"be": "BY",
|
||||
"bem": "ZM",
|
||||
"bez": "TZ",
|
||||
"bg": "BG",
|
||||
"bm": "ML",
|
||||
"bn": "BD",
|
||||
"bo": "CN",
|
||||
"br": "FR",
|
||||
"brx": "IN",
|
||||
"bs": "rl",
|
||||
"ca": "AD",
|
||||
"ccp": "BD",
|
||||
"ce": "RU",
|
||||
"cgg": "UG",
|
||||
"chr": "US",
|
||||
"ckb": "IQ",
|
||||
"cs": "CZ",
|
||||
"cy": "GB",
|
||||
"da": "DK",
|
||||
"dav": "KE",
|
||||
"de": "DE",
|
||||
"dje": "NE",
|
||||
"dsb": "DE",
|
||||
"dua": "CM",
|
||||
"dyo": "SN",
|
||||
"dz": "BT",
|
||||
"ebu": "KE",
|
||||
"ee": "GH",
|
||||
"el": "CY",
|
||||
"en": "01",
|
||||
"es": "ES",
|
||||
"et": "EE",
|
||||
"eu": "ES",
|
||||
"ewo": "CM",
|
||||
"fa": "AF",
|
||||
"ff": "CM",
|
||||
"fi": "FI",
|
||||
"fil": "PH",
|
||||
"fo": "FO",
|
||||
"fr": "FR",
|
||||
"fur": "IT",
|
||||
"fy": "NL",
|
||||
"ga": "IE",
|
||||
"gd": "GB",
|
||||
"gl": "ES",
|
||||
"gsw": "CH",
|
||||
"gu": "IN",
|
||||
"guz": "KE",
|
||||
"gv": "IM",
|
||||
"ha": "GH",
|
||||
"haw": "US",
|
||||
"he": "IL",
|
||||
"hi": "IN",
|
||||
"hr": "HR",
|
||||
"hsb": "DE",
|
||||
"hu": "HU",
|
||||
"hy": "AM",
|
||||
"id": "ID",
|
||||
"ig": "NG",
|
||||
"ii": "CN",
|
||||
"is": "IS",
|
||||
"it": "IT",
|
||||
"ja": "JP",
|
||||
"jgo": "CM",
|
||||
"jmc": "TZ",
|
||||
"ka": "GE",
|
||||
"kab": "DZ",
|
||||
"kam": "KE",
|
||||
"kde": "TZ",
|
||||
"kea": "CV",
|
||||
"khq": "ML",
|
||||
"ki": "KE",
|
||||
"kk": "KZ",
|
||||
"kkj": "CM",
|
||||
"kl": "GL",
|
||||
"kln": "KE",
|
||||
"km": "KH",
|
||||
"kn": "IN",
|
||||
"ko": "KP",
|
||||
"kok": "IN",
|
||||
"ks": "IN",
|
||||
"ksb": "TZ",
|
||||
"ksf": "CM",
|
||||
"ksh": "DE",
|
||||
"kw": "GB",
|
||||
"ky": "KG",
|
||||
"lag": "TZ",
|
||||
"lb": "LU",
|
||||
"lg": "UG",
|
||||
"lkt": "US",
|
||||
"ln": "AO",
|
||||
"lo": "LA",
|
||||
"lrc": "IQ",
|
||||
"lt": "LT",
|
||||
"lu": "CD",
|
||||
"luo": "KE",
|
||||
"Luo": "KE",
|
||||
"luy": "KE",
|
||||
"lv": "LV",
|
||||
"mas": "KE",
|
||||
"mer": "KE",
|
||||
"mfe": "MU",
|
||||
"mg": "MG",
|
||||
"mgh": "MZ",
|
||||
"mgo": "CM",
|
||||
"mk": "MK",
|
||||
"ml": "IN",
|
||||
"mn": "MN",
|
||||
"mr": "IN",
|
||||
"ms": "BN",
|
||||
"mt": "MT",
|
||||
"mua": "CM",
|
||||
"my": "MM",
|
||||
"mzn": "IR",
|
||||
"naq": "NA",
|
||||
"nb": "NO",
|
||||
"nd": "ZW",
|
||||
"nds": "DE",
|
||||
"ne": "IN",
|
||||
"nl": "NL",
|
||||
"nmg": "CM",
|
||||
"nn": "NO",
|
||||
"nnh": "CM",
|
||||
"nus": "SS",
|
||||
"nyn": "UG",
|
||||
"om": "ET",
|
||||
"or": "IN",
|
||||
"os": "GE",
|
||||
"pa": "ab",
|
||||
"pl": "PL",
|
||||
"ps": "AF",
|
||||
"pt": "PT",
|
||||
"qu": "BO",
|
||||
"rm": "CH",
|
||||
"rn": "BI",
|
||||
"ro": "RO",
|
||||
"rof": "TZ",
|
||||
"ru": "RU",
|
||||
"rw": "RW",
|
||||
"rwk": "TZ",
|
||||
"sah": "RU",
|
||||
"saq": "KE",
|
||||
"sbp": "TZ",
|
||||
"se": "SE",
|
||||
"seh": "MZ",
|
||||
"ses": "ML",
|
||||
"sg": "CF",
|
||||
"shi": "tn",
|
||||
"si": "LK",
|
||||
"sk": "SK",
|
||||
"sl": "SI",
|
||||
"smn": "FI",
|
||||
"sn": "ZW",
|
||||
"so": "SO",
|
||||
"sq": "AL",
|
||||
"sr": "rl",
|
||||
"sv": "AX",
|
||||
"sw": "CD",
|
||||
"ta": "IN",
|
||||
"te": "IN",
|
||||
"teo": "KE",
|
||||
"tg": "TJ",
|
||||
"th": "TH",
|
||||
"ti": "ER",
|
||||
"to": "TO",
|
||||
"tr": "TR",
|
||||
"tt": "RU",
|
||||
"twq": "NE",
|
||||
"tzm": "MA",
|
||||
"ug": "CN",
|
||||
"uk": "UA",
|
||||
"ur": "IN",
|
||||
"uz": "ab",
|
||||
"vai": "tn",
|
||||
"Vai": "tn",
|
||||
"vi": "VN",
|
||||
"vun": "TZ",
|
||||
"wae": "CH",
|
||||
"wo": "SN",
|
||||
"xog": "UG",
|
||||
"yav": "CM",
|
||||
"yi": "01",
|
||||
"yo": "BJ",
|
||||
"yue": "ns",
|
||||
"zgh": "MA",
|
||||
"zh": "ns",
|
||||
"zu": "ZA"
|
||||
|
||||
|
||||
};
|
||||
|
||||
return languageToCountryMap[language] || null;
|
||||
}
|
||||
|
||||
async function displayLocaleAndFlag() {
|
||||
// Get the browser locale
|
||||
const userLocale = navigator.language || navigator.userLanguage;
|
||||
const { flag, isUnknown, countryCode } = getFlagEmoji(userLocale);
|
||||
|
||||
// Display the locale and the corresponding flag (or fallback)
|
||||
//document.getElementById('locale').textContent = `Your Locale: ${userLocale}`;
|
||||
|
||||
if (isUnknown) {
|
||||
const fallbackDiv = document.createElement('div');
|
||||
fallbackDiv.className = 'fallback-box';
|
||||
fallbackDiv.textContent = `? ${userLocale.toUpperCase()}`; // Only show ? and locale code inside the box
|
||||
//document.getElementById('flag-container').textContent = "Flag: ";
|
||||
document.getElementById('flag-container').appendChild(fallbackDiv);
|
||||
// Tooltip for fallback
|
||||
fallbackDiv.title = "Unknown Country"; // Tooltip for fallback
|
||||
} else {
|
||||
const countryName = await getCountryName(countryCode);
|
||||
const flagSpan = document.createElement('span');
|
||||
flagSpan.textContent = flag; // Use flag emoji
|
||||
flagSpan.title = countryName; // Tooltip for the flag in country language
|
||||
//document.getElementById('flag-container').textContent = "Flag: ";
|
||||
document.getElementById('flag-container').appendChild(flagSpan);
|
||||
}
|
||||
}
|
||||
|
||||
displayLocaleAndFlag();
|
||||
});
|
@@ -19,18 +19,35 @@
|
||||
%= content_for 'refresh'
|
||||
|
||||
%= stylesheet '/js/datatables.min.css'
|
||||
%= javascript '/js/datatables.min.js'
|
||||
%= stylesheet '/js/jquery-ui.min.css'
|
||||
%= javascript '/js/jquery-ui.min.js'
|
||||
|
||||
%= stylesheet '/js/dataTables.buttons.min.js'
|
||||
%= stylesheet '/js/jszip.min.js'
|
||||
%= stylesheet '/js/pdfmake.min.js'
|
||||
%= stylesheet '/js/vfs_fonts.js'
|
||||
%= stylesheet '/js/buttons.html5.min.js'
|
||||
%= stylesheet '/js/buttons.print.min.js'
|
||||
|
||||
%= javascript '/js/datatables.min.js'
|
||||
|
||||
%= stylesheet '/js/jquery-ui.min.css'
|
||||
|
||||
%= javascript '/js/jquery-ui.min.js'
|
||||
%= javascript '/js/dataTables.buttons.min.js'
|
||||
%= javascript '/js/jszip.min.js'
|
||||
%= javascript '/js/pdfmake.min.js'
|
||||
%= javascript '/js/vfs_fonts.js'
|
||||
%= javascript '/js/buttons.html5.min.js'
|
||||
%= javascript '/js/buttons.print.min.js'
|
||||
%= javascript '/js/flag-by-locale.js'
|
||||
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.5.0/css/flag-icon.min.css">
|
||||
%= stylesheet '/css/sme-jquery-overrides.css'
|
||||
|
||||
<style>
|
||||
#busy-indicator {
|
||||
display: none;
|
||||
margin-top: 10px;
|
||||
font-weight: bold;
|
||||
color: red;
|
||||
}
|
||||
.busy {
|
||||
cursor: wait; /* Change the cursor to a 'wait' cursor */
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
</head>
|
||||
|
||||
@@ -91,46 +108,21 @@
|
||||
|
||||
%= javascript '/js/sme-dataTable-setup.js'
|
||||
|
||||
%= javascript begin
|
||||
//Set menu to initial condition based on localStorage
|
||||
$(document).ready(function() {
|
||||
let menunavflag = window.localStorage.getItem('menunav');
|
||||
if (menunavflag != "false"){
|
||||
$('#menunav').toggle(true);
|
||||
} else {
|
||||
$('#menunav').toggle(false);
|
||||
}
|
||||
|
||||
let menuadmflag = window.localStorage.getItem('menuadm');
|
||||
if (menuadmflag != "false"){
|
||||
$('#menuadm').toggle(true);
|
||||
} else {
|
||||
$('#menuadm').toggle(false);
|
||||
}
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
// Handle form submission for any form
|
||||
$('form').on('submit', function(event) {
|
||||
// Disable the submit button
|
||||
$(this).find('button[type="submit"], input[type="submit"]').prop('disabled', true);
|
||||
// Show the busy indicator
|
||||
// $('#busy-indicator').show();
|
||||
|
||||
// Change the cursor to "wait"
|
||||
$('body').addClass('busy');
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
let menuuserflag = window.localStorage.getItem('menuuser');
|
||||
if (menuuserflag != "false"){
|
||||
$('#menuuser').toggle(true);
|
||||
} else {
|
||||
$('#menuuser').toggle(false);
|
||||
}
|
||||
|
||||
var sections = document.getElementsByClassName("section-title");
|
||||
for (var i = 0, len = sections.length; i < len; i++) {
|
||||
var jqObj = $(sections[i]);
|
||||
var $section = jqObj.parent().next('div');
|
||||
if(!$section.length){
|
||||
return false;
|
||||
}
|
||||
let localStorageTag = "admSection-"+sections[i].innerHTML;
|
||||
if (window.localStorage.getItem(localStorageTag) != "false"){
|
||||
$section.toggle(true);
|
||||
} else {
|
||||
$section.toggle(false);
|
||||
}
|
||||
}
|
||||
})
|
||||
%end
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
@@ -1,8 +1,9 @@
|
||||
<div id="footer">
|
||||
<div id="footer" width=100%>
|
||||
<HR class="sme-copyrightbar">
|
||||
<a href="https://mojolicious.org" target="_blank"><img src="images/sme-mojo-logo-white.png" style="position:relative;"></a>
|
||||
<font class="sme-copyright">
|
||||
% if ( $c->is_logged_in ) {
|
||||
SME Server <%= session 'releaseVersion' %> - Manager <%= $c->app->VERSION %>
|
||||
SME Server <%= session 'releaseVersion' %>-<%= $c->app->VERSION %> Manager II
|
||||
% }
|
||||
<br>Copyright 1999-2006 Mitel Corporation<br>
|
||||
%= session 'copyRight'
|
||||
|
@@ -1,27 +1,128 @@
|
||||
<style>
|
||||
#h2l1 {
|
||||
display: flex; /* Use flexbox layout */
|
||||
justify-content: space-between; /* Space between child elements */
|
||||
align-items: center; /* Center items vertically */
|
||||
}
|
||||
|
||||
#h2e11 {
|
||||
flex: 1; /* Allow the first div to take available space on the left */
|
||||
}
|
||||
|
||||
#h2e12 {
|
||||
display: flex; /* Make this div a flex container */
|
||||
align-items: center; /* Vertically center content in this div */
|
||||
margin-left: 20px; /* Add margin to the left of this div */
|
||||
}
|
||||
|
||||
#flag-container {
|
||||
display: flex; /* Make this div a flex container */
|
||||
align-items: center; /* Vertically center content in this div */
|
||||
margin-left: 20px; /* Add margin to the left of the flag container */
|
||||
padding-right: 20px; /* Add padding to the right side of the flag container */
|
||||
}
|
||||
|
||||
.flag-icon {
|
||||
width: 43px;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
#legacy-button button {
|
||||
background-color: #98d36e; /* Button background color */
|
||||
font-weight: lighter; /* Lighter text for the button */
|
||||
color: #063; /* Button text color */
|
||||
padding: 5px 10px; /* Padding for the button */
|
||||
border: none; /* Remove default button border */
|
||||
border-radius: 4px; /* Rounded corners for button */
|
||||
cursor: pointer; /* Change cursor on hover */
|
||||
}
|
||||
|
||||
#legacy-button button:hover {
|
||||
background-color: #82c961; /* Change color on hover */
|
||||
}
|
||||
|
||||
.infobar {
|
||||
display: flex; /* Use flexbox for alignment */
|
||||
justify-content: space-between; /* Space between child elements */
|
||||
align-items: center; /* Center items vertically */
|
||||
padding: 10px; /* Adjust padding as desired */
|
||||
}
|
||||
|
||||
#h2e21 {
|
||||
flex: 1; /* Allow the first div to take available space on the left */
|
||||
}
|
||||
|
||||
#h2e22 {
|
||||
display: flex; /* Make this div a flex container */
|
||||
justify-content: center; /* Center the help button */
|
||||
align-items: center; /* Center vertically */
|
||||
flex: none; /* Prevent this div from growing */
|
||||
position: relative; /* Relative position for centering */
|
||||
width: 100px; /* Set a width for the help button container */
|
||||
}
|
||||
|
||||
#h2e23 {
|
||||
margin-left: auto; /* Push the third div to the right */
|
||||
}
|
||||
|
||||
.login-button {
|
||||
background-color: #98d36e; /* Button background color */
|
||||
font-weight: bold; /* Bold text */
|
||||
xxcolor: #ffffff; /* Button text color */
|
||||
padding: 8px 12px; /* Adjust padding for button height */
|
||||
border: none; /* Remove default border */
|
||||
border-radius: 4px; /* Rounded corners */
|
||||
cursor: pointer; /* Change cursor on hover */
|
||||
}
|
||||
|
||||
.login-button:hover {
|
||||
background-color: #82c961; /* Change color on hover */
|
||||
}
|
||||
|
||||
#help-button {
|
||||
text-decoration: none; /* Remove underline from link */
|
||||
font-size: 20px; /* Adjust font size as needed */
|
||||
padding: 8px 12px; /* Add padding to the help link */
|
||||
background-color: #98d36e; /* Background for visibility */
|
||||
border-radius: 4px; /* Rounded corners */
|
||||
color: #000; /* Button text color */
|
||||
}
|
||||
|
||||
#help-button:hover {
|
||||
background-color: #82c961; /* Change background on hover */
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="header2" class="hd2">
|
||||
<div id="h2l1">
|
||||
<div id="h2e11">
|
||||
<a target='_blank' href="http://www.koozali.org"><img src="images/smeserver_logo.jpg" height="40" alt="SME Server"></a>
|
||||
</div>
|
||||
<!-- <div id="h2e12"><h5><a href="initial">Server Manager</a>
|
||||
<a href="/server-manager" target='_blank'>    (Prev SM)</a></h5> -->
|
||||
<div id="h2e12" style="float:right;"><br><a href="/server-manager" target='_blank'><button style="background-color:#98d36e;font-weight:bold;color:#063;">Legacy SM</button></a></div>
|
||||
</div>
|
||||
<div id="h2e11">
|
||||
<a target='_blank' href="http://www.koozali.org"><img src="images/smeserver_logo.jpg" height="40" alt="SME Server"></a>
|
||||
</div>
|
||||
|
||||
<div id="h2l2" class="infobar">
|
||||
<div id="h2e21">
|
||||
<b>
|
||||
<%= session 'SystemName' %>@<%= session 'DomainName' %></b>
|
||||
</div>
|
||||
<div id="h2e22">
|
||||
<a target="_parent" href="manual"> <b> ? </b> </a>
|
||||
</div>
|
||||
<div id="h2e23">
|
||||
% if ( not defined $c->session->{username} ) {
|
||||
<a target="_parent" href="login"><b>Login</b></a>
|
||||
% } else {
|
||||
<a target="_parent" href="logout"><b><%= $c->session->{username} %> Logout</b></a>
|
||||
% }
|
||||
</div>
|
||||
<div id="h2e22">
|
||||
<a id="help-button" target="_parent" href="manual"><button> ? </button></a>
|
||||
</div>
|
||||
|
||||
<div id="h2e12">
|
||||
<a id="legacy-button" href="/server-manager" target='_blank'><button>Legacy SM</button></a>
|
||||
</div>
|
||||
<div id="h2e23">
|
||||
% if ( not defined $c->session->{username} ) {
|
||||
<a target="_parent" href="login"><button class="login-button">Login</button></a>
|
||||
% } else {
|
||||
<a target="_parent" href="logout"><button class="login-button"><%= $c->session->{username} %> Logout</button></a>
|
||||
% }
|
||||
</div>
|
||||
<div id="flag-container">
|
||||
<!-- The flag icon will be inserted here -->
|
||||
</div>
|
||||
</div>
|
||||
<div id="h2l2" class="infobar">
|
||||
<div id="h2e21">
|
||||
<b>
|
||||
<%= session 'SystemName' %>@<%= session 'DomainName' %></b>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -9,6 +9,7 @@
|
||||
<br>
|
||||
%= submit_button "$btn", class => 'action'
|
||||
</p>
|
||||
%= hidden_field 'trt' => 'ADD';
|
||||
|
||||
% end
|
||||
|
||||
@@ -71,9 +72,7 @@
|
||||
% }
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<%} %>
|
||||
|
||||
%= hidden_field 'trt' => $iba_datas->{trt}
|
||||
|
||||
</div>
|
||||
|
@@ -60,9 +60,10 @@
|
||||
<span class=data>
|
||||
%=text_field 'networkRouter'
|
||||
</span><br><br>
|
||||
<div class='center'>
|
||||
%= submit_button "$btn", class => 'action'
|
||||
</div>
|
||||
<p>
|
||||
<br>
|
||||
%= submit_button "$btn", class => 'action'
|
||||
</p>
|
||||
%end
|
||||
|
||||
</div>
|
||||
|
@@ -49,9 +49,11 @@
|
||||
</span><br><br>
|
||||
%}
|
||||
%= hidden_field localnetwork=>$localnetwork
|
||||
<div class='center'>
|
||||
%= submit_button "$btn", class => 'action'
|
||||
</div>
|
||||
<p>
|
||||
<br>
|
||||
%= submit_button "$btn", class => 'action'
|
||||
</p>
|
||||
|
||||
%end
|
||||
|
||||
</div>
|
||||
|
@@ -37,10 +37,12 @@
|
||||
%= $c->render_to_string(inline => l($ret{ret},$var1,$var2,$var3,$var4,$var5,$var6,$var7));
|
||||
</div>
|
||||
%}
|
||||
<br><br>
|
||||
<div class='center'>
|
||||
|
||||
<p>
|
||||
<br>
|
||||
%= submit_button "$btn", class => 'action'
|
||||
</div>
|
||||
</p>
|
||||
|
||||
% end
|
||||
|
||||
<br>
|
||||
|
@@ -77,9 +77,11 @@
|
||||
<span class=data>
|
||||
%=text_field 'cmmnt'
|
||||
</span><br><br>
|
||||
<div class='center'>
|
||||
%= submit_button "$btn", class => 'action'
|
||||
</div>
|
||||
<p>
|
||||
<br>
|
||||
%= submit_button "$btn", class => 'action'
|
||||
</p>
|
||||
|
||||
%end
|
||||
|
||||
</div>
|
||||
|
@@ -57,9 +57,10 @@
|
||||
%#}
|
||||
%= hidden_field sport=>$sport
|
||||
%= hidden_field proto=>$proto
|
||||
<div class='center'>
|
||||
%= submit_button "$btn", class => 'action'
|
||||
</div>
|
||||
<br>
|
||||
%= submit_button "$btn", class => 'action'
|
||||
</p>
|
||||
|
||||
%end
|
||||
|
||||
</div>
|
||||
|
@@ -18,8 +18,6 @@
|
||||
% my $var5 = @vars[4];
|
||||
% my $var6 = @vars[5];
|
||||
|
||||
|
||||
|
||||
%if ($ret{ret} eq "") {
|
||||
%= $c->render_to_string(inline => l('pf_FIRST_PAGE_DESCRIPTION'));
|
||||
%} elsif (index($ret{ret},"SUCCESS") != -1) {
|
||||
@@ -33,21 +31,22 @@
|
||||
%= $c->l($ret{ret},$var1,$var2,$var3,$var4,$var5,$var6);
|
||||
</div>
|
||||
%}
|
||||
<br><br>
|
||||
<div class='center'>
|
||||
|
||||
<p>
|
||||
<br>
|
||||
%= submit_button "$btn", class => 'action'
|
||||
</div>
|
||||
</p>
|
||||
|
||||
|
||||
% end
|
||||
|
||||
<br>
|
||||
|
||||
% if ($empty){
|
||||
<br>
|
||||
%=l 'pf_NO_FORWARDS'
|
||||
% } else {
|
||||
<br>
|
||||
%=l 'pf_SHOW_FORWARDS'
|
||||
<br>
|
||||
<br><br />
|
||||
<table class="sme-border TableSort"><thead>
|
||||
<tr>
|
||||
<th class='sme-border'>
|
||||
|
@@ -213,10 +213,10 @@
|
||||
</p>
|
||||
%}
|
||||
|
||||
|
||||
<div class='center'>
|
||||
<p>
|
||||
<br>
|
||||
%= submit_button "$btn", class => 'action'
|
||||
</div>
|
||||
</p>
|
||||
|
||||
% end
|
||||
|
||||
|
@@ -66,9 +66,10 @@
|
||||
</span>
|
||||
<br><br></p>
|
||||
|
||||
<div class='center'>
|
||||
%= submit_button "$btn", class => 'action'
|
||||
</div>
|
||||
<p>
|
||||
<br>
|
||||
%= submit_button "$btn", class => 'action'
|
||||
</p>
|
||||
|
||||
% end
|
||||
|
||||
|
@@ -79,9 +79,9 @@
|
||||
|
||||
%= hidden_field 'trt' => 'CONF'
|
||||
<br>
|
||||
<div class='center'>
|
||||
<!--<div class='center'>-->
|
||||
%= submit_button $c->l('SAVE'), class => 'action'
|
||||
</div>
|
||||
<!--</div>-->
|
||||
|
||||
% end
|
||||
|
||||
|
@@ -47,9 +47,9 @@
|
||||
|
||||
%= hidden_field 'trt' => 'INST'
|
||||
<br><br>
|
||||
<div class='center'>
|
||||
<!-- <div class='center'>-->
|
||||
%= submit_button $c->l('yum_INSTALL_SOFTWARE'), class => 'action'
|
||||
</div>
|
||||
<!--</div>-->
|
||||
|
||||
% end
|
||||
|
||||
|
@@ -34,9 +34,9 @@
|
||||
%= hidden_field 'trt' => 'PSTU'
|
||||
%= hidden_field 'reconf' => $yum_datas->{reconf}
|
||||
<br>
|
||||
<div class='center'>
|
||||
<!-- <div class='center'>-->
|
||||
%= submit_button "$btn", class => 'action'
|
||||
</div>
|
||||
<!--</div>-->
|
||||
|
||||
% end
|
||||
|
||||
|
@@ -46,9 +46,9 @@
|
||||
|
||||
%= hidden_field 'trt' => 'REMO'
|
||||
<br>
|
||||
<div class='center'>
|
||||
<!--<div class='center'>-->
|
||||
%= submit_button $c->l('REMOVE'), class => 'action'
|
||||
</div>
|
||||
<!--</div>-->
|
||||
|
||||
% end
|
||||
|
||||
|
@@ -33,9 +33,9 @@
|
||||
|
||||
%= hidden_field 'trt' => 'UPDT'
|
||||
<br>
|
||||
<div class='center'>
|
||||
<!--<div class='center'>-->
|
||||
%= submit_button $c->l('yum_INSTALL_UPDATES'), class => 'action'
|
||||
</div>
|
||||
<!--</div>-->
|
||||
|
||||
% end
|
||||
|
||||
|
0
root/var/log/smanager/.gitignore
vendored
Normal file
0
root/var/log/smanager/.gitignore
vendored
Normal file
@@ -2,7 +2,7 @@ Summary: Sme server navigation module : manager 2
|
||||
%define name smeserver-manager
|
||||
Name: %{name}
|
||||
%define version 11.0.0
|
||||
%define release 4
|
||||
%define release 25
|
||||
Version: %{version}
|
||||
Release: %{release}%{?dist}
|
||||
License: GPL
|
||||
@@ -49,6 +49,11 @@ This RPM contributes the navigation bars for the smeserver-manager. New Mojolici
|
||||
%setup
|
||||
|
||||
%build
|
||||
|
||||
#extract the release number and drop it in to the version for SM2 footer.
|
||||
sed -i "s/our \$VERSION = '[^']*'/our \$VERSION = '%{release}'/g" root/usr/share/smanager/lib/SrvMngr.pm
|
||||
|
||||
|
||||
perl createlinks
|
||||
|
||||
# Force creation of potentially empty directories
|
||||
@@ -108,6 +113,75 @@ true
|
||||
%defattr(-,root,root)
|
||||
|
||||
%changelog
|
||||
* Wed Oct 02 2024 Brian Read <brianr@koozali.org> 11.0.0-25.sme
|
||||
- Add in cursor change when save/submit pressed to indicate processing [SME: 12748]
|
||||
|
||||
* Wed Oct 02 2024 Brian Read <brianr@koozali.org> 11.0.0-24.sme
|
||||
- Messed up build - finger trouble [SME: 12753]
|
||||
|
||||
* Wed Oct 02 2024 Brian Read <brianr@koozali.org> 11.0.0-23.sme
|
||||
- Add release number to footer [SME: 12753]
|
||||
|
||||
* Tue Sep 24 2024 Jean-Philippe Pialasse <jpp@koozali.org> 11.0.0-22.sme
|
||||
- fix typos, and tidy tabs [SME: 12744]
|
||||
|
||||
* Mon Sep 23 2024 Brian Read <brianr@koozali.org> 11.0.0-21.sme
|
||||
- Remove both option for webmail [SME: 12744]
|
||||
- Add in re-open DB for portforwarding and email settings.
|
||||
|
||||
* Mon Sep 23 2024 Jean-Philippe Pialasse <jpp@koozali.org> 11.0.0-20.sme
|
||||
- webmail switch panel to use roundcube [SME: 12742]
|
||||
- prevent browser from caching [SME: 12695]
|
||||
|
||||
* Thu Sep 05 2024 Brian Read <brianr@koozali.org> 11.0.0-19.sme
|
||||
- Add in mojo plugin WithoutCache [SME: 12695]
|
||||
|
||||
* Sun Aug 25 2024 Brian Read <brianr@koozali.org> 11.0.0-18.sme
|
||||
- Move flag to emojii from downloaded jpg. Fix singleton locale issue[SME: 12706]
|
||||
|
||||
* Thu Aug 22 2024 Brian Read <brianr@koozali.org> 11.0.0-17.sme
|
||||
- Left Align Software Install panels Submit button [SME: 12727]
|
||||
|
||||
* Wed Aug 21 2024 Brian Read <brianr@koozali.org> 11.0.0-16.sme
|
||||
- Typo uc DNF changed to lc dnf in Yum.pm [SME: 127245]
|
||||
- Monitor dnf running using dnf status file
|
||||
|
||||
* Wed Aug 21 2024 Brian Read <brianr@koozali.org> 11.0.0-15.sme
|
||||
- Migrate SM2 Software installer panel from use of yum to dnf [SME: 12718]
|
||||
|
||||
* Sun Jul 28 2024 Brian Read <brianr@koozali.org> 11.0.0-14.sme
|
||||
- Version skipped due to operator error! [SME: <none> ]
|
||||
|
||||
* Sun Jul 28 2024 Brian Read <brianr@koozali.org> 11.0.0-13.sme
|
||||
- Fix sysles.css template - overwrote it by mistake [SME: 12706]
|
||||
- Also re-organised login and Legacy SM menus and help on top
|
||||
|
||||
* Sun Jul 28 2024 Brian Read <brianr@koozali.org> 11.0.0-12.sme
|
||||
- correct positio of flag-icon [SME: 12706]
|
||||
|
||||
* Sat Jul 27 2024 Brian Read <brianr@koozali.org> 11.0.0-11.sme
|
||||
- Add in flag icon indication of locale [SME: 12706]
|
||||
|
||||
* Fri Jul 26 2024 Brian Read <brianr@koozali.org> 11.0.0-10.sme
|
||||
- fix navigation2.conf to more correctly translate menus [SME: 12714]
|
||||
|
||||
* Thu May 09 2024 Brian Read <brianr@koozali.org> 11.0.0-9.sme
|
||||
- Add mojo logo to footer [SME: 12679]
|
||||
- Fix default for HeaderWeight to avoid noise in logs if no Nav header in file
|
||||
- Align buttons consistently [SME: 12680]
|
||||
|
||||
* Tue Apr 30 2024 Jean-Philippe Pialasse <jpp@koozali.org> 11.0.0-8.sme
|
||||
- create dedicated log files and logrotate [SME: 12664]
|
||||
|
||||
* Tue Apr 30 2024 Brian Read <brianr@koozali.org> 11.0.0-7.sme
|
||||
- Remove use of hel command and replace by call to BlockDevices lib [SME: 12644]
|
||||
|
||||
* Mon Apr 29 2024 Brian Read <brianr@koozali.org> 11.0.0-6.sme
|
||||
- Update layout for table extras [SME: 12656]
|
||||
|
||||
* Sun Apr 28 2024 Brian Read <brianr@koozali.org> 11.0.0-5.sme
|
||||
- Ibay create not getting into panel [SME: 12652]
|
||||
|
||||
* Tue Apr 23 2024 Brian Read <brianr@koozali.org> 11.0.0-4.sme
|
||||
- add in Nav numbers for Legacypanels.pm and ignore it when generating nav menu [SME:12643]
|
||||
|
||||
|
Reference in New Issue
Block a user