From 4eb981635453871fa2a33396391f3f75a6baa8b1 Mon Sep 17 00:00:00 2001 From: Jonathan Druart Date: Wed, 10 Jul 2024 12:16:55 +0200 Subject: [PATCH] Bug 37303: Replace po2json with a JS version When using __() (ie. Gettext.js) we are seeing the translations that are marked as fuzzy. This is definitely not the expected behaviour. It happens because (our version of) po2json are old and no longer maintained, and just embed them. It seems that the bin we have has been upgraded to a JS version (different authors). Test plan: (replace LANG with your language code) 0. Do not apply this patch Edit misc/translator/po/LANG-messages-js.po Mark a string as fuzzy Edit ./intranet-main.tt and add the following lines inside $(document).ready console.log(_("Your string")); console.log(__("Your string")); Replace "Your string" with the string you are actually testing. Update the templates: `koha-translate --update LANG --dev kohadev && restart_all` Go to the Koha home page, open the console. => Notice that the second log in the console is displaying the fuzzy string. 1. Apply this patch Install the new version of po2json using `yarn install` Repeat the previous steps. => With this patch applied both logs show the English version of the string. Remove fuzzy, update the templates and try again. Signed-off-by: Julian Maurice Signed-off-by: Victor Grousset/tuxayo Signed-off-by: Martin Renvoize --- misc/translator/LangInstaller.pm | 10 +- misc/translator/po2json | 253 ------------------------------- package.json | 1 + 3 files changed, 9 insertions(+), 255 deletions(-) delete mode 100755 misc/translator/po2json diff --git a/misc/translator/LangInstaller.pm b/misc/translator/LangInstaller.pm index a0f323121e..fcf78bba98 100644 --- a/misc/translator/LangInstaller.pm +++ b/misc/translator/LangInstaller.pm @@ -28,6 +28,7 @@ use Locale::PO; use FindBin qw( $Bin ); use File::Path qw( make_path ); use File::Copy; +use File::Slurp qw( read_file ); sub set_lang { my ($self, $lang) = @_; @@ -52,7 +53,7 @@ sub new { $self->{po} = {}; $self->{domain} = 'Koha'; $self->{msgfmt} = `which msgfmt`; - $self->{po2json} = "$Bin/po2json"; + $self->{po2json} = "yarn run po2json"; $self->{gzip} = `which gzip`; $self->{gunzip} = `which gunzip`; chomp $self->{msgfmt}; @@ -454,7 +455,12 @@ sub install_messages { make_path($modir); system "$self->{msgfmt} -o $mofile $pofile"; - my $js_locale_data = 'var json_locale_data = {"Koha":' . `$self->{po2json} $js_pofile` . '};'; + my $tmp_po = sprintf '/tmp/%s-messages.po', $self->{lang}; + my $po2json_cmd = sprintf '%s %s %s', $self->{po2json}, $js_pofile, $tmp_po; + `$po2json_cmd`; + my $json = read_file($tmp_po); + + my $js_locale_data = sprintf 'var json_locale_data = {"Koha":%s};', $json; my $progdir = C4::Context->config('intrahtdocs') . '/prog'; mkdir "$progdir/$self->{lang}/js"; open my $fh, '>', "$progdir/$self->{lang}/js/locale_data.js"; diff --git a/misc/translator/po2json b/misc/translator/po2json deleted file mode 100755 index a04d85949f..0000000000 --- a/misc/translator/po2json +++ /dev/null @@ -1,253 +0,0 @@ -#!/usr/bin/env perl -# PODNAME: po2json -# ABSTRACT: Command line tool for converting a po file into a Gettext.js compatible json dataset - -# Copyright (C) 2008, Joshua I. Miller Eunrtst@cpan.orgE, all -# rights reserved. -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU Library General Public License as published -# by the Free Software Foundation; either version 2, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Library General Public License for more details. -# -# You should have received a copy of the GNU Library General Public -# License along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, -# USA. - - -use strict; -use JSON 2.53; -use Locale::PO 0.24; -use File::Basename qw(basename); - -my $gettext_context_glue = "\004"; - -sub usage { - return "$0 {-p} {file.po} > {outputfile.json} - -p : do pretty-printing of json data\n"; -} - -&main; - -sub main -{ - my $src; - - my $pretty = 0; - if ($ARGV[0] =~ /^--?p$/) { - shift @ARGV; - $pretty = 1; - } - - if (length($ARGV[0])) - { - if ($ARGV[0] =~ /^-h/) { - print &usage; - exit 1; - } - - unless (-r $ARGV[0]) { - print "ERROR: Unable to read file [$ARGV[0]]\n"; - die &usage; - } - - $src = $ARGV[0]; - } else { - die &usage; - } - - # we'll be building this data struct - my $json = {}; - - my $plural_form_count; - # get po object stack - my $pos = Locale::PO->load_file_asarray($src) or die "Can't parse po file [$src]."; - - - foreach my $po (@$pos) - { - my $qmsgid1 = $po->msgid; - my $msgid1 = $po->dequote( $qmsgid1 ); - - # on the header - if (length($msgid1) == 0) - { - my $qmsgstr = $po->msgstr; - my $cur = $po->dequote( $qmsgstr ); - my %cur; - foreach my $h (split(/\n/, $cur)) - { - next unless length($h); - my @h = split(':', $h, 2); - - if (length($cur{$h[0]})) { - warn "SKIPPING DUPLICATE HEADER LINE: $h\n"; - } elsif ($h[0] =~ /#-#-#-#-#/) { - warn "SKIPPING ERROR MARKER IN HEADER: $h\n"; - } elsif (@h == 2) { - $cur{$h[0]} = $h[1]; - } else { - warn "PROBLEM LINE IN HEADER: $h\n"; - $cur{$h} = ''; - } - } - - # init header ref - $$json{''} ||= {}; - - # populate header ref - foreach my $key (keys %cur) { - $$json{''}{$key} = length($cur{$key}) ? $cur{$key} : ''; - } - - # save plural form count - if ($$json{''}{'Plural-Forms'}) { - my $t = $$json{''}{'Plural-Forms'}; - $t =~ s/^\s*//; - if ($t =~ /nplurals=(\d+)/) { - $plural_form_count = $1; - } else { - die "ERROR parsing plural forms header [$t]\n"; - } - } else { - warn "NO PLURAL FORM HEADER FOUND - DEFAULTING TO 2\n"; - # just default to 2 - $plural_form_count = 2; - } - - # on a normal msgid - } else { - my $qmsgctxt = $po->msgctxt; - my $msgctxt; - $msgctxt = $po->dequote($qmsgctxt) if $qmsgctxt; - - # build the new msgid key - my $msg_ctxt_id = defined($msgctxt) ? join($gettext_context_glue, ($msgctxt, $msgid1)) : $msgid1; - - # build translation side - my @trans; - - # msgid plural side - my $qmsgid_plural = $po->msgid_plural; - my $msgid2; - $msgid2 = $po->dequote( $qmsgid_plural ) if $qmsgid_plural; - push(@trans, $msgid2); - - # translated string - # this shows up different if we're plural - if (defined($msgid2) && length($msgid2)) - { - my $plurals = $po->msgstr_n; - for (my $i=0; $i<$plural_form_count; $i++) - { - my $qstr = ref($plurals) ? $$plurals{$i} : undef; - my $str; - $str = $po->dequote( $qstr ) if $qstr; - push(@trans, $str); - } - - # singular - } else { - my $qmsgstr = $po->msgstr; - my $msgstr; - $msgstr = $po->dequote( $qmsgstr ) if $qmsgstr; - push(@trans, $msgstr); - } - - $$json{$msg_ctxt_id} = \@trans; - } - } - - - my $jsonobj = JSON->new->canonical( $ENV{CANONICAL} // 1 ); # if you dont want sorted keys, export CANONICAL=0 - my $basename = basename($src); - $basename =~ s/\.pot?$//; - if ($pretty) - { - print $jsonobj->pretty->encode( { $basename => $json }); - } else { - print $jsonobj->encode($json); - } -} - -__END__ - -=pod - -=head1 NAME - -po2json - Command line tool for converting a po file into a Gettext.js compatible json dataset - -=head1 VERSION - -version 0.019 - -=head1 SYNOPSIS - - po2json /path/to/domain.po > domain.json - -=head1 DESCRIPTION - -This takes a PO file, as is created from GNU Gettext's xgettext, and converts it into a JSON file. - -The output is an annonymous associative array. So, if you plan to load this via a