2017-10-02 08:31:35 +03:00
#!/usr/bin/perl
use strict ;
use warnings ;
2017-10-02 13:15:11 +03:00
use Getopt::Std ;
2017-10-02 08:31:35 +03:00
use Locale::PO ;
use JSON ;
use Encode ;
# current limits:
# - we do not support plural. forms
# - no message content support
2017-10-02 13:15:11 +03:00
my $ options = { } ;
2018-01-19 14:06:47 +03:00
getopts ( 't:o:v:' , $ options ) ||
2017-10-02 13:15:11 +03:00
die "unable to parse options\n" ;
2017-10-02 08:31:35 +03:00
die "no files specified\n" if ! scalar ( @ ARGV ) ;
#my $filename = shift || die "no po file specified\n";
# like FNV32a, but we only return 31 bits (positive numbers)
sub fnv31a {
my ( $ string ) = @ _ ;
my $ hval = 0x811c9dc5 ;
foreach my $ c ( unpack ( 'C*' , $ string ) ) {
$ hval ^= $ c ;
$ hval += (
( ( $ hval << 1 ) ) +
( ( $ hval << 4 ) ) +
( ( $ hval << 7 ) ) +
( ( $ hval << 8 ) ) +
( ( $ hval << 24 ) ) ) ;
$ hval = $ hval & 0xffffffff ;
}
return $ hval & 0x7fffffff ;
}
2017-10-02 13:16:56 +03:00
my $ catalog = { } ;
2017-10-02 08:31:35 +03:00
foreach my $ filename ( @ ARGV ) {
my $ href = Locale::PO - > load_file_ashash ( $ filename ) ||
die "unable to load '$filename'\n" ;
my $ charset ;
my $ hpo = $ href - > { '""' } || die "no header" ;
my $ header = $ hpo - > dequote ( $ hpo - > msgstr ) ;
if ( $ header =~ m | ^ Content - Type: \ s + text / plain ; \ s + charset = ( \ S + ) $ | im ) {
$ charset = $ 1 ;
} else {
die "unable to get charset\n" if ! $ charset ;
}
foreach my $ k ( keys %$ href ) {
my $ po = $ href - > { $ k } ;
next if $ po - > fuzzy ( ) ; # skip fuzzy entries
my $ ref = $ po - > reference ( ) ;
2018-01-19 14:06:47 +03:00
# skip unused entries
next if ! $ ref ;
# skip entries if t is defined (pve/pmg) and the string is
# not used there or in the widget toolkit
next if $ options - > { t } && $ ref !~ m/($options->{t}|proxmox)\-/ ;
2017-10-02 08:31:35 +03:00
my $ qmsgid = decode ( $ charset , $ po - > msgid ) ;
my $ msgid = $ po - > dequote ( $ qmsgid ) ;
my $ qmsgstr = decode ( $ charset , $ po - > msgstr ) ;
my $ msgstr = $ po - > dequote ( $ qmsgstr ) ;
next if ! length ( $ msgid ) ; # skip header
2017-10-02 13:16:56 +03:00
next if ! length ( $ msgstr ) ; # skip untranslated entries
2017-10-02 08:31:35 +03:00
my $ digest = fnv31a ( $ msgid ) ;
die "duplicate digest" if $ catalog - > { $ digest } ;
$ catalog - > { $ digest } = [ $ msgstr ] ;
# later, we can add plural forms to the array
}
}
my $ json = to_json ( $ catalog , { canonical = > 1 , utf8 = > 1 } ) ;
2018-01-19 14:06:47 +03:00
my $ content = "// $options->{v}\n" ; # write version to beginning
2017-10-02 13:15:11 +03:00
my $ outfile = $ options - > { o } ;
$ content . = "// Proxmox Message Catalog: $outfile\n" if $ outfile ;
$ content . = << __EOD ;
2017-10-04 13:10:40 +03:00
__proxmox_i18n_msgcat__ = $ json ;
2017-10-02 08:31:35 +03:00
function fnv31a ( text ) {
var len = text . length ;
var hval = 0x811c9dc5 ;
for ( var i = 0 ; i < len ; i + + ) {
var c = text . charCodeAt ( i ) ;
hval ^= c ;
hval += ( hval << 1 ) + ( hval << 4 ) + ( hval << 7 ) + ( hval << 8 ) + ( hval << 24 ) ;
}
hval & = 0x7fffffff ;
return hval ;
}
function gettext ( buf ) {
var digest = fnv31a ( buf ) ;
2017-10-04 13:10:40 +03:00
var data = __proxmox_i18n_msgcat__ [ digest ] ;
2017-10-02 08:31:35 +03:00
if ( ! data ) {
return buf ;
}
return data [ 0 ] || buf ;
}
__EOD
2017-10-02 13:15:11 +03:00
if ( $ outfile ) {
open ( my $ fh , '>' , $ outfile ) ||
die "unable to open '$outfile' - $!\n" ;
print $ fh $ content ;
} else {
print $ content ;
}