Created
February 4, 2019 14:49
-
-
Save DeepDiver1975/457a01a1a8a1e3df592c84149a1025df to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/perl | |
use strict; | |
use version; | |
use Locale::PO; | |
use Cwd; | |
use Data::Dumper; | |
use File::Path; | |
use File::Basename; | |
use File::Spec; | |
use Digest::MD5 qw(md5 md5_hex md5_base64); | |
sub crawlFiles{ | |
my( $dir ) = @_; | |
my @found = (); | |
opendir( DIR, $dir ); | |
my @files = readdir( DIR ); | |
closedir( DIR ); | |
@files = sort( @files ); | |
foreach my $i ( @files ){ | |
next if substr( $i, 0, 1 ) eq '.'; | |
next if $i eq 'l10n'; | |
if( -d $dir.'/'.$i ){ | |
push( @found, crawlFiles( $dir.'/'.$i )); | |
} | |
else{ | |
push(@found,$dir.'/'.$i) if $i =~ /.*(?<!\.min)\.js$/ || $i =~ /\.php$/; | |
} | |
} | |
return @found; | |
} | |
sub readIgnorelist{ | |
return () unless -e 'l10n/ignorelist'; | |
my %ignore = (); | |
open(IN,'l10n/ignorelist'); | |
while(<IN>){ | |
my $line = $_; | |
chomp($line); | |
$ignore{"./$line"}++; | |
} | |
close(IN); | |
return %ignore; | |
} | |
sub getPluralInfo { | |
my( $info ) = @_; | |
# get string | |
$info =~ s/.*Plural-Forms: (.+)\\n.*/$1/; | |
$info =~ s/^(.*)\\n.*/$1/g; | |
return $info; | |
} | |
sub init() { | |
# let's get the version from stdout of xgettext | |
my $out = `xgettext --version`; | |
# we assume the first line looks like this 'xgettext (GNU gettext-tools) 0.19.3' | |
$out = substr $out, 29, index($out, "\n")-29; | |
$out =~ s/^\s+|\s+$//g; | |
$out = "v" . $out; | |
my $actual = version->parse($out); | |
# 0.18.3 introduced JavaScript as a language option | |
my $expected = version->parse('v0.18.3'); | |
if ($actual < $expected) { | |
die( "Minimum expected version of xgettext is " . $expected . ". Detected: " . $actual ); | |
} | |
} | |
init(); | |
my $app = shift( @ARGV ); | |
my $task = shift( @ARGV ); | |
die( "Usage: l10n.pl app task\ntask: read, write\n" ) unless $task; | |
# Our current position | |
my $whereami = dirname(File::Spec->rel2abs( __FILE__ )); | |
die( "Program must be executed in a l10n-folder called 'l10n'" ) unless $whereami =~ m/\/l10n$/; | |
# Where are i18n-files? | |
my $pwd = dirname(dirname(File::Spec->rel2abs( __FILE__ ))); | |
chdir($pwd); | |
my @dirs = (); | |
push(@dirs, $pwd); | |
# Languages | |
my @languages = (); | |
opendir( DIR, '.' ); | |
my @files = readdir( DIR ); | |
closedir( DIR ); | |
foreach my $i ( @files ){ | |
push( @languages, $i ) if -d $i && substr( $i, 0, 1 ) ne '.'; | |
} | |
if( $task eq 'read' ){ | |
rmtree( 'templates' ); | |
mkdir( 'templates' ) unless -d 'templates'; | |
print "Mode: reading\n"; | |
foreach my $dir ( @dirs ){ | |
my @temp = split( /\//, $dir ); | |
chdir( $dir ); | |
my @totranslate = crawlFiles('.'); | |
my %ignore = readIgnorelist(); | |
my $output = "${whereami}/templates/$app.pot"; | |
my $packageName = "ownCloud $app"; | |
print " Processing $app\n"; | |
foreach my $file ( @totranslate ){ | |
next if $ignore{$file}; | |
my $keywords = ''; | |
if( $file =~ /\.js$/ ){ | |
$keywords = '--keyword=t:2 --keyword=n:2,3'; | |
} | |
else{ | |
$keywords = '--keyword=t --keyword=n:1,2'; | |
} | |
my $language = ( $file =~ /\.js$/ ? 'Javascript' : 'PHP'); | |
my $joinexisting = ( -e $output ? '--join-existing' : ''); | |
print " Reading $file\n"; | |
`xgettext --output="$output" $joinexisting $keywords --language=$language "$file" --add-comments=TRANSLATORS --from-code=UTF-8 --package-version="8.0.0" --package-name="$packageName" --msgid-bugs-address="translations\@owncloud.org"`; | |
} | |
chdir( $whereami ); | |
} | |
} | |
elsif( $task eq 'write' ){ | |
print "Mode: write\n"; | |
foreach my $dir ( @dirs ){ | |
my @temp = split( /\//, $dir ); | |
chdir( $dir.'/l10n' ); | |
print " Processing $app\n"; | |
foreach my $language ( @languages ){ | |
next if $language eq 'templates'; | |
my $input = "${whereami}/$language/$app.po"; | |
next unless -e $input; | |
print " Language $language\n"; | |
my $array = Locale::PO->load_file_asarray( $input ); | |
# Create array | |
my @strings = (); | |
my @js_strings = (); | |
my $plurals; | |
TRANSLATIONS: foreach my $string ( @{$array} ){ | |
if( $string->msgid() eq '""' ){ | |
# Translator information | |
$plurals = getPluralInfo( $string->msgstr()); | |
} | |
elsif( defined( $string->msgstr_n() )){ | |
# plural translations | |
my @variants = (); | |
my $msgid = $string->msgid(); | |
$msgid =~ s/^"(.*)"$/$1/; | |
my $msgid_plural = $string->msgid_plural(); | |
$msgid_plural =~ s/^"(.*)"$/$1/; | |
my $identifier = "_" . $msgid."_::_".$msgid_plural . "_"; | |
foreach my $variant ( sort { $a <=> $b} keys( %{$string->msgstr_n()} )){ | |
next TRANSLATIONS if $string->msgstr_n()->{$variant} eq '""'; | |
push( @variants, $string->msgstr_n()->{$variant} ); | |
} | |
push( @strings, "\"$identifier\" => array(".join(",", @variants).")"); | |
push( @js_strings, "\"$identifier\" : [".join(",", @variants)."]"); | |
} | |
else{ | |
# singular translations | |
next TRANSLATIONS if $string->msgstr() eq '""'; | |
push( @strings, $string->msgid()." => ".$string->msgstr()); | |
push( @js_strings, $string->msgid()." : ".$string->msgstr()); | |
} | |
} | |
next if $#strings == -1; # Skip empty files | |
for (@strings) { | |
s/\$/\\\$/g; | |
} | |
# delete old php file | |
unlink "$language.php"; | |
# Write js file | |
open( OUT, ">$language.js" ); | |
print OUT "OC.L10N.register(\n \"$app\",\n {\n "; | |
print OUT join( ",\n ", @js_strings ); | |
print OUT "\n},\n\"$plurals\");\n"; | |
close( OUT ); | |
# Write json file | |
open( OUT, ">$language.json" ); | |
print OUT "{ \"translations\": "; | |
print OUT "{\n "; | |
print OUT join( ",\n ", @js_strings ); | |
print OUT "\n},\"pluralForm\" :\"$plurals\"\n}"; | |
close( OUT ); | |
} | |
chdir( $whereami ); | |
} | |
} else { | |
print "unknown task!\n"; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment