Compare commits
	
		
			20 Commits
		
	
	
		
			11_0_0-6_e
			...
			11_0_0-14_
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| ed1c3e13b1 | |||
| 095a0a1499 | |||
| d16ea6a847 | |||
| e70cc67430 | |||
| b097acafab | |||
| 5d7655a709 | |||
| a58df95aa9 | |||
| 251b454470 | |||
| 174d511899 | |||
| 4be8a1411f | |||
| ba431a8a7d | |||
| 77a7849898 | |||
| fb5b0942d6 | |||
| 5edc830f9b | |||
| 473cb57a47 | |||
| 55b85496d4 | |||
| 2fd6f8b630 | |||
| a428e91c92 | |||
| 03955eecea | |||
| 891fc73ce3 | 
							
								
								
									
										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:
 | 
			
		||||
Easily add, remove, and manage user accounts and groups. The interface simplifies creating email accounts, setting passwords, and configuring user permissions.
 | 
			
		||||
 | 
			
		||||
#### Network Configuration:
 | 
			
		||||
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.
 | 
			
		||||
							
								
								
									
										2
									
								
								clog
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								clog
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,2 @@
 | 
			
		||||
* Sun Jul 28 2024 Brian Read <brianr@koozali.org> 11.0.0-14.sme
 | 
			
		||||
- fix [SME: ]
 | 
			
		||||
@@ -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
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										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
 | 
			
		||||
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -624,7 +624,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");
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -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>
 | 
			
		||||
 
 | 
			
		||||
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 10 KiB  | 
@@ -0,0 +1,63 @@
 | 
			
		||||
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 fetch country names from a CDN
 | 
			
		||||
  async function fetchCountryNames() {
 | 
			
		||||
    const response = await fetch('https://restcountries.com/v3.1/all');
 | 
			
		||||
    const countries = await response.json();
 | 
			
		||||
    const countryNames = {};
 | 
			
		||||
    for (const country of countries) {
 | 
			
		||||
      const code = country.cca2.toLowerCase(); // Country code (ISO 3166-1 alpha-2)
 | 
			
		||||
      const name = country.name.common; // Common name of the country
 | 
			
		||||
      countryNames[code] = name;
 | 
			
		||||
    }
 | 
			
		||||
    return countryNames;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Function to create and display the flag icon
 | 
			
		||||
  function displayFlagIcon(countryCode, countryName) {
 | 
			
		||||
    const flagIcon = document.createElement('span');
 | 
			
		||||
    flagIcon.className = `flag-icon flag-icon-${countryCode.toLowerCase()}`;
 | 
			
		||||
    flagIcon.id = 'flag-icon';
 | 
			
		||||
    flagIcon.title = countryName; // Set the title for the tooltip
 | 
			
		||||
 | 
			
		||||
    // If you want a custom tooltip instead (uncomment the lines below):
 | 
			
		||||
    /*
 | 
			
		||||
    const tooltip = document.createElement('span');
 | 
			
		||||
    tooltip.className = 'tooltip';
 | 
			
		||||
    tooltip.innerText = countryName;
 | 
			
		||||
    flagIcon.appendChild(tooltip);
 | 
			
		||||
 | 
			
		||||
    flagIcon.addEventListener('mouseenter', () => {
 | 
			
		||||
      tooltip.style.display = 'block';
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    flagIcon.addEventListener('mouseleave', () => {
 | 
			
		||||
      tooltip.style.display = 'none';
 | 
			
		||||
    });
 | 
			
		||||
    */
 | 
			
		||||
 | 
			
		||||
    flagContainer.appendChild(flagIcon);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Main logic
 | 
			
		||||
  (async () => {
 | 
			
		||||
    const locale = getBrowserLocale();
 | 
			
		||||
    const countryCode = getCountryCodeFromLocale(locale);
 | 
			
		||||
    const countryNames = await fetchCountryNames(); // Fetch country names
 | 
			
		||||
 | 
			
		||||
    const countryName = countryNames[countryCode.toLowerCase()] || 'Unknown Country'; // Get the country name
 | 
			
		||||
    displayFlagIcon(countryCode, countryName); // Display the flag with country name
 | 
			
		||||
  })();
 | 
			
		||||
});
 | 
			
		||||
@@ -31,7 +31,9 @@
 | 
			
		||||
	%= 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'
 | 
			
		||||
 | 
			
		||||
</head>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,6 @@
 | 
			
		||||
<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 %>
 | 
			
		||||
 
 | 
			
		||||
@@ -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>
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										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 6
 | 
			
		||||
%define release 14
 | 
			
		||||
Version: %{version}
 | 
			
		||||
Release: %{release}%{?dist}
 | 
			
		||||
License: GPL
 | 
			
		||||
@@ -108,6 +108,33 @@ true
 | 
			
		||||
%defattr(-,root,root)
 | 
			
		||||
 | 
			
		||||
%changelog
 | 
			
		||||
* Sun Jul 28 2024 Brian Read <brianr@koozali.org> 11.0.0-14.sme
 | 
			
		||||
- fix [SME: ]
 | 
			
		||||
 | 
			
		||||
* 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]
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user