Bug 5444 Fix misc/translate script for 'standard' Koha install
[koha.git] / misc / translator / LangInstaller.pm
bloba1fef0f40de0b1e3c5312485e7b60921f79bc0e1
1 package LangInstaller;
3 # Copyright (C) 2010 Tamil s.a.r.l.
5 # This file is part of Koha.
7 # Koha is free software; you can redistribute it and/or modify it under the
8 # terms of the GNU General Public License as published by the Free Software
9 # Foundation; either version 2 of the License, or (at your option) any later
10 # version.
12 # Koha is distributed in the hope that it will be useful, but WITHOUT ANY
13 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
14 # A PARTICULAR PURPOSE. See the GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License along
17 # with Koha; if not, write to the Free Software Foundation, Inc.,
18 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 use strict;
21 use warnings;
23 use C4::Context;
24 use YAML::Syck qw( Dump LoadFile );
25 use Locale::PO;
26 use FindBin qw( $Bin );
28 $YAML::Syck::ImplicitTyping = 1;
30 sub set_lang {
31 my ($self, $lang) = @_;
33 $self->{lang} = $lang;
34 $self->{po_path_lang} = $self->{context}->config('intrahtdocs') .
35 "/prog/$lang/modules/admin/preferences";
39 sub new {
40 my ($class, $lang, $pref_only) = @_;
42 my $self = { };
44 my $context = C4::Context->new();
45 $self->{context} = $context;
46 $self->{path_pref_en} = $context->config('intrahtdocs') .
47 '/prog/en/modules/admin/preferences';
48 set_lang( $self, $lang ) if $lang;
49 $self->{pref_only} = $pref_only;
50 $self->{translator_path} = $Bin;
51 $self->{path_po} = $self->{translator_path} . "/po";
52 $self->{po} = {};
54 # Get all .pref file names
55 opendir my $fh, $self->{path_pref_en};
56 my @pref_files = grep { /.pref/ } readdir($fh);
57 close $fh;
58 $self->{pref_files} = \@pref_files;
60 # Get all available language codes
61 opendir $fh, $self->{path_po};
62 my @langs = map { ($_) =~ /(.*)-i-opac/ }
63 grep { $_ =~ /.*-opac-/ } readdir($fh);
64 closedir $fh;
65 $self->{langs} = \@langs;
67 # Map for both interfaces opac/intranet
68 $self->{interface} = {
69 opac => {
70 dir => $context->config('opachtdocs') . '/prog',
71 suffix => '-i-opac-t-prog-v-3002000.po',
73 intranet => {
74 dir => $context->config('intrahtdocs') . '/prog',
75 suffix => '-i-staff-t-prog-v-3002000.po',
79 bless $self, $class;
83 sub po_filename {
84 my $self = shift;
86 my $context = C4::Context->new;
87 my $trans_path = $context->config('intranetdir') . '/misc/translator/po';
88 my $trans_file = "$trans_path/" . $self->{lang} . "-pref.po";
89 return $trans_file;
93 sub po_append {
94 my ($self, $id, $comment) = @_;
95 my $po = $self->{po};
96 my $p = $po->{$id};
97 if ( $p ) {
98 $p->comment( $p->comment . "\n" . $comment );
100 else {
101 $po->{$id} = Locale::PO->new(
102 -comment => $comment,
103 -msgid => $id,
104 -msgstr => ''
110 sub add_prefs {
111 my ($self, $comment, $prefs) = @_;
113 for my $pref ( @$prefs ) {
114 my $pref_name = '';
115 for my $element ( @$pref ) {
116 if ( ref( $element) eq 'HASH' ) {
117 $pref_name = $element->{pref};
118 last;
121 for my $element ( @$pref ) {
122 if ( ref( $element) eq 'HASH' ) {
123 while ( my ($key, $value) = each(%$element) ) {
124 next unless $key eq 'choices';
125 next unless ref($value) eq 'HASH';
126 for my $ckey ( keys %$value ) {
127 my $id = $self->{file} . "#$pref_name# " . $value->{$ckey};
128 $self->po_append( $id, $comment );
132 elsif ( $element ) {
133 $self->po_append( $self->{file} . "#$pref_name# $element", $comment );
140 sub get_trans_text {
141 my ($self, $id) = @_;
143 my $po = $self->{po}->{$id};
144 return unless $po;
145 return Locale::PO->dequote($po->msgstr);
149 sub update_tab_prefs {
150 my ($self, $pref, $prefs) = @_;
152 for my $p ( @$prefs ) {
153 my $pref_name = '';
154 next unless $p;
155 for my $element ( @$p ) {
156 if ( ref( $element) eq 'HASH' ) {
157 $pref_name = $element->{pref};
158 last;
161 for my $i ( 0..@$p-1 ) {
162 my $element = $p->[$i];
163 if ( ref( $element) eq 'HASH' ) {
164 while ( my ($key, $value) = each(%$element) ) {
165 next unless $key eq 'choices';
166 next unless ref($value) eq 'HASH';
167 for my $ckey ( keys %$value ) {
168 my $id = $self->{file} . "#$pref_name# " . $value->{$ckey};
169 my $text = $self->get_trans_text( $id );
170 $value->{$ckey} = $text if $text;
174 elsif ( $element ) {
175 my $text = $self->get_trans_text( $self->{file} . "#$pref_name# $element" );
176 $p->[$i] = $text if $text;
183 sub get_po_from_prefs {
184 my $self = shift;
186 for my $file ( @{$self->{pref_files}} ) {
187 my $pref = LoadFile( $self->{path_pref_en} . "/$file" );
188 $self->{file} = $file;
189 #print Dump($pref), "\n";
190 while ( my ($tab, $tab_content) = each %$pref ) {
191 if ( ref($tab_content) eq 'ARRAY' ) {
192 $self->add_prefs( $tab, $tab_content );
193 next;
195 while ( my ($section, $sysprefs) = each %$tab_content ) {
196 my $comment = "$tab > $section";
197 $self->po_append( $self->{file} . " " . $section, $comment );
198 $self->add_prefs( $comment, $sysprefs );
205 sub save_po {
206 my $self = shift;
207 # Write .po entries into a file put in Koha standard po directory
208 Locale::PO->save_file_fromhash( $self->po_filename, $self->{po} );
209 print "Saved in file: ", $self->po_filename, "\n";
213 sub update_prefs {
214 my $self = shift;
216 print "Update '", $self->{lang}, "' preferences .po file from 'en' .pref files\n";
217 # Get po from current 'en' .pref files
218 $self->get_po_from_prefs();
219 my $po_current = $self->{po};
221 # Get po from previous generation
222 my $po_previous = Locale::PO->load_file_ashash( $self->po_filename );
224 for my $id ( keys %$po_current ) {
225 my $po = $po_previous->{'"'.$id.'"'};
226 next unless $po;
227 my $text = Locale::PO->dequote( $po->msgstr );
228 $po_current->{$id}->msgstr( $text );
231 $self->save_po();
235 sub install_prefs {
236 my $self = shift;
238 unless ( -r $self->{po_path_lang} ) {
239 print "Koha directories hierarchy for ", $self->{lang}, " must be created first\n";
240 exit;
243 # Update the language .po file with last modified 'en' preferences
244 # and load it.
245 $self->update_prefs();
247 for my $file ( @{$self->{pref_files}} ) {
248 my $pref = LoadFile( $self->{path_pref_en} . "/$file" );
249 $self->{file} = $file;
250 while ( my ($tab, $tab_content) = each %$pref ) {
251 if ( ref($tab_content) eq 'ARRAY' ) {
252 $self->update_tab_prefs( $pref, $tab_content );
253 next;
255 while ( my ($section, $sysprefs) = each %$tab_content ) {
256 $self->update_tab_prefs( $pref, $sysprefs );
258 my $ntab = {};
259 for my $section ( keys %$tab_content ) {
260 my $text = $self->get_trans_text($self->{file} . " $section");
261 my $nsection = $text ? $text : $section;
262 $ntab->{$nsection} = $tab_content->{$section};
264 $pref->{$tab} = $ntab;
266 my $file_trans = $self->{po_path_lang} . "/$file";
267 print "Write $file\n";
268 open my $fh, ">", $file_trans;
269 print $fh Dump($pref);
274 sub install_tmpl {
275 my $self = shift;
277 print
278 "Install templates\n";
279 while ( my ($interface, $tmpl) = each %{$self->{interface}} ) {
280 print
281 " Install templates '$interface\n",
282 " From: $tmpl->{dir}/en/\n",
283 " To : $tmpl->{dir}/$self->{lang}\n",
284 " With: $self->{path_po}/$self->{lang}$tmpl->{suffix}\n";
285 my $lang_dir = "$tmpl->{dir}/$self->{lang}";
286 mkdir $lang_dir unless -d $lang_dir;
287 system
288 "$self->{translator_path}/tmpl_process3.pl install " .
289 "-i $tmpl->{dir}/en/ " .
290 "-o $tmpl->{dir}/$self->{lang} ".
291 "-s $self->{path_po}/$self->{lang}$tmpl->{suffix} -r"
296 sub update_tmpl {
297 my $self = shift;
299 print
300 "Update templates\n";
301 while ( my ($interface, $tmpl) = each %{$self->{interface}} ) {
302 print
303 " Update templates '$interface'\n",
304 " From: $tmpl->{dir}/en/\n",
305 " To : $self->{path_po}/$self->{lang}$tmpl->{suffix}\n";
306 my $lang_dir = "$tmpl->{dir}/$self->{lang}";
307 mkdir $lang_dir unless -d $lang_dir;
308 system
309 "$self->{translator_path}/tmpl_process3.pl update " .
310 "-i $tmpl->{dir}/en/ " .
311 "-s $self->{path_po}/$self->{lang}$tmpl->{suffix} -r"
316 sub create_prefs {
317 my $self = shift;
319 $self->get_po_from_prefs();
320 $self->save_po();
324 sub create_tmpl {
325 my $self = shift;
327 print
328 "Create templates\n";
329 while ( my ($interface, $tmpl) = each %{$self->{interface}} ) {
330 print
331 " Create templates .po files for '$interface'\n",
332 " From: $tmpl->{dir}/en/\n",
333 " To : $self->{path_po}/$self->{lang}$tmpl->{suffix}\n";
334 system
335 "$self->{translator_path}/tmpl_process3.pl create " .
336 "-i $tmpl->{dir}/en/ " .
337 "-s $self->{path_po}/$self->{lang}$tmpl->{suffix} -r"
342 sub install {
343 my $self = shift;
344 return unless $self->{lang};
345 $self->install_tmpl() unless $self->{pref_only};
346 $self->install_prefs();
350 sub update {
351 my $self = shift;
352 return unless $self->{lang};
353 $self->update_tmpl() unless $self->{pref_only};
354 $self->update_prefs();
358 sub create {
359 my $self = shift;
360 return unless $self->{lang};
361 $self->create_tmpl() unless $self->{pref_only};
362 $self->create_prefs();
370 =head1 NAME
372 LangInstaller.pm - Handle templates and preferences translation
374 =head1 SYNOPSYS
376 my $installer = LangInstaller->new( 'fr-FR' );
377 $installer->create();
378 $installer->update();
379 $installer->install();
380 for my $lang ( @{$installer->{langs} ) {
381 $installer->set_lang( $lan );
382 $installer->install();
385 =head1 METHODS
387 =head2 new
389 Create a new instance of the installer object.
391 =head2 create
393 For the current language, create .po files for templates and preferences based
394 of the english ('en') version.
396 =head2 update
398 For the current language, update .po files.
400 =head2 install
402 For the current langage C<$self->{lang}, use .po files to translate the english
403 version of templates and preferences files and copy those files in the
404 appropriate directory.
406 =over
408 =item translate create F<lang>
410 Create 3 .po files in F<po> subdirectory: (1) from opac pages templates, (2)
411 intranet templates, and (3) from preferences.
413 =over
415 =item F<lang>-opac.po
417 Contains extracted text from english (en) OPAC templates found in
418 <KOHA_ROOT>/koha-tmpl/opac-tmpl/prog/en/ directory.
420 =item F<lang>-intranet.po
422 Contains extracted text from english (en) intranet templates found in
423 <KOHA_ROOT>/koha-tmpl/intranet-tmpl/prog/en/ directory.
425 =item F<lang>-pref.po
427 Contains extracted text from english (en) preferences. They are found in files
428 located in <KOHA_ROOT>/koha-tmpl/intranet-tmpl/prog/en/admin/preferences
429 directory.
431 =back
433 =item pref-trans update F<lang>
435 Update .po files in F<po> directory, named F<lang>-*.po.
437 =item pref-trans install F<lang>
439 =back
441 =cut