| Server IP : 172.64.80.1 / Your IP : 216.73.216.175 Web Server : LiteSpeed System : Linux srv13.swhc.ca 4.18.0-553.126.2.lve.el8.x86_64 #1 SMP Thu May 28 14:12:30 UTC 2026 x86_64 User : hongluck ( 2522) PHP Version : 7.4.33 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : OFF | Pkexec : OFF Directory : /home/hongluck/public_html/old site/webcal/tools/ |
Upload File : |
#!/usr/bin/perl
#
# This tool will update a translation file by doing the following:
# - Insert an empty translation when a missing translation is found.
# The translation will have "<< MISSING >>" right above it to
# make it easy to find.
# - Show the English translation (in a comment) before a missing translation,
# making it easier to add the translation.
# - Translations will be reorganized so that they are divided up into
# the pages that they appear on.
#
# Note: you will lose any comments you put in the translation file
# when using this tool (except for the comments at the very beginning).
#
# Note #2: This will overwrite the existing translation file, so a save
# backup of the translation will be saved with a .bak file extension.
#
# Usage:
# update_translation.pl [-p plugin] languagefile
#
# Example for main WebCalendar translation:
# update_translation.pl French.txt
# or
# update_translation.pl French
#
# Example for plugin "tnn" translation:
# update_translation.pl -p tnn French.txt
# or
# update_translation.pl -p tnn French
#
# Note: this utility should be run from this directory (tools).
#
###########################################################################
$base_dir = "..";
$trans_dir = "../translations";
$base_trans_file = "$trans_dir/English-US.txt";
$plugin = "";
$show_missing = 1; # set to 0 to minimize translation file.
$show_dups = 0; # set to 0 to minimize translation file.
$verbose = 0;
( $this ) = reverse split ( /\//, $0 );
$save_backup = 0;
for ( $i = 0; $i < @ARGV; $i++ ) {
if ( $ARGV[$i] eq "-p" ) {
$plugin = $ARGV[++$i];
} elsif ( $ARGV[$i] eq "-v" ) {
$verbose++;
} else {
$infile = $ARGV[$i];
}
}
die "Usage: $this [-p plugin] language\n" if ( $infile eq "" );
if ( $plugin ne "" ) {
$p_trans_dir = "$base_dir/$plugin/translations";
$p_base_trans_file = "$p_trans_dir/English-US.txt";
$p_base_dir = "$base_dir/$plugin";
} else {
$p_trans_dir = $trans_dir;
$p_base_trans_file = $base_trans_file;
$p_base_dir = $base_dir;
}
if ( $infile !~ /txt$/ ) {
$infile .= ".txt";
}
if ( -f "$trans_dir/$infile" || -f "$p_trans_dir/$infile" ) {
$b_infile = "$trans_dir/$infile";
$infile = "$p_trans_dir/$infile";
}
#print "infile: $infile\nb_infile: $b_infile\ntrans_dir: $trans_dir\n";
die "Usage: $this [-p plugin] language\n" if ( ! -f $infile );
print "Translation file: $infile\n" if ( $verbose );
# Now load the base translation(s) file (English), so that we can include
# the English translation text above a missing translation in a comment.
open ( F, $base_trans_file ) || die "Error opening $base_trans_file";
print "Reading base translation file: $base_trans_file\n" if ( $verbose );
while ( <F> ) {
chop;
s/\r*$//g; # remove annoying CR
next if ( /^#/ );
if ( /\s*:\s*/ ) {
$abbrev = $`;
$base_trans{$abbrev} = $' if ( $abbrev ne 'charset' );
}
}
close ( F );
# read in the plugin base translation file
if ( $plugin ne "" ) {
print "Reading plugin base translation file: $p_base_trans_file\n" if ( $verbose );
open ( F, $p_base_trans_file ) || die "Error opening $p_base_trans_file";
while ( <F> ) {
chop;
s/\r*$//g; # remove annoying CR
next if ( /^#/ );
if ( /\s*:\s*/ ) {
$abbrev = $`;
$base_trans{$abbrev} = $';
}
}
close ( F );
}
#
# Now load the translation file we are going to update.
#
$old = "";
if ( -f $infile ) {
print "Reading current translations from $infile\n" if ( $verbose );
open ( F, $infile ) || die "Error opening $infile";
$in_header = 1;
while ( <F> ) {
$old .= $_;
chop;
s/\r*$//g; # remove annoying CR
if ( $in_header && /^#/ ) {
if ( /Translation last (pagified|updated)/ ) {
# ignore since we will replace this with current date below
} else {
$header .= $_ . "\n";
}
}
next if ( /^#/ );
$in_header = 0;
if ( /\s*:\s*/ ) {
$abbrev = $`;
$trans{$abbrev} = $';
}
}
}
if ( $plugin ne "" ) {
print "Reading current WebCalendar translations from $b_infile\n" if ( $verbose );
open ( F, $b_infile ) || die "Error opening $b_infile";
$in_header = 1;
while ( <F> ) {
chop;
s/\r*$//g; # remove annoying CR
if ( /\s*:\s*/ ) {
$abbrev = $`;
$webcaltrans{$abbrev} = $';
}
}
}
#
# Save a backup copy of old translation file.
#
if ( $save_backup ) {
open ( F, ">$infile.bak" ) || die "Error writing $infile.bak";
print F $old;
close ( F );
print "Backup of translation saved in $infile.bak\n";
}
if ( $header !~ /Translation last updated/ ) {
( $day, $mon, $year ) = ( localtime ( time() ) )[3,4,5];
$header .= "# Translation last updated on " .
sprintf ( "%02d-%02d-%04d", $mon + 1, $day, $year + 1900 ) . "\n";
}
# First get the list of .php files
print "Searching for PHP files in $p_base_dir\n" if ( $verbose );
opendir ( DIR, $p_base_dir ) || die "Error opening $p_base_dir";
@files = grep ( /\.php$/, readdir ( DIR ) );
closedir ( DIR );
if ( -d "$p_base_dir/includes" ) {
print "Searching for PHP files in $p_base_dir/includes\n" if ( $verbose );
opendir ( DIR, "$p_base_dir/includes" ) ||
die "Error opening $p_base_dir/includes";
@incfiles = grep ( /\.php$/, readdir ( DIR ) );
closedir ( DIR );
foreach $f ( @incfiles ) {
push ( @files, "includes/$f" );
}
}
if ( -d "$p_base_dir/includes/js" ) {
print "Searching for PHP files in $p_base_dir/includes/js\n" if ( $verbose );
opendir ( DIR, "$p_base_dir/includes/js" ) ||
die "Error opening $p_base_dir/includes/js";
@incfiles = grep ( /\.php$/, readdir ( DIR ) );
closedir ( DIR );
foreach $f ( @incfiles ) {
push ( @files, "includes/js/$f" );
}
}
if ( $plugin eq "" ) {
push ( @files, "tools/send_reminders.php" );
}
#
# Write new translation file.
#
$notfound = 0;
open ( OUT, ">$infile" ) || die "Error writing $infile: ";
print OUT $header;
if ( $plugin eq '' ) {
if ( defined ( $trans{'charset'} ) ) {
print OUT
"\n\n###############################################\n" .
"# Specify a charset (will be sent within meta tag for each page)\n#\n" .
"charset: $trans{'charset'}\n\n";
$text{'charset'} = 1;
$foundin{'charset'} = " top of this file";
} else {
print OUT "\n# No charset specified (not needed for iso-8859-1)\n" .
"# \"charset\" is used in a meta tag, " .
"do not translate \"charset\" here.\n" .
"# charset:\n\n";
}
}
foreach $f ( @files ) {
$pageHeader = "\n\n###############################################\n# Page: $f\n#\n";
$file = "$p_base_dir/$f";
open ( F, $file ) || die "Error reading $file";
print "Searching $f\n" if ( $verbose );
%thispage = ();
while ( <F> ) {
$data = $_;
while ( $data =~ /(translate|tooltip)\s*\(\s*"/ ) {
$data = $';
if ( $data =~ /"\s*\)/ ) {
$text = $`;
if ( defined ( $thispage{$text} ) ) {
# text already found within this page...
} elsif ( $text eq 'charset' ) {
# ignore...
} elsif ( defined ( $text{$text} ) ) {
if ( ! show_dups ) {
if ( $pageHeader ne '' ) {
print OUT $pageHeader; $pageHeader = '';
}
print OUT "# \"$text\" previously defined (in $foundin{$text})\n"
}
$thispage{$text} = 1;
} else {
if ( ! length ( $trans{$text} ) ) {
if ( $show_missing ) {
if ( length ( $webcaltrans{$text} ) ) {
if ( $pageHeader ne '' ) { print OUT $pageHeader; $pageHeader = ''; }
print OUT "# \"$text\" defined in WebCalendar translation\n";
} else {
if ( $pageHeader ne '' ) { print OUT $pageHeader; $pageHeader = ''; }
print OUT "#\n# << MISSING >>\n# $text:\n";
print OUT "# English text: $base_trans{$text}\n#\n"
if ( length ( $base_trans{$text} ) &&
$base_trans{$text} ne $text );
}
}
$text{$text} = 1;
$thispage{$text} = 1;
$foundin{$text} = $f;
$notfound++ if ( ! length ( $webcaltrans{$text} ) );
} else {
$text{$text} = 1;
$foundin{$text} = $f;
$thispage{$text} = 1;
if ( $pageHeader ne '' ) {
print OUT $pageHeader; $pageHeader = '';
}
printf OUT ( "%s: %s\n", $text, $trans{$text} );
}
}
$data = $';
}
}
}
close ( F );
}
if ( ! $notfound ) {
print STDERR "All text was found in $infile. Good job :-)\n";
} else {
print STDERR "$notfound translation(s) missing.\n";
}
exit 0;