#!/usr/bin/perl -W # # A script that compares timestameps in two PO (gettext) files and copies # newer strings into the destination file. # # Copyright (C) 2010 Bogdan 'bogdro' Drozdowski, http://rudy.mif.pg.gda.pl/~bogdro/inne/ # (bogdandr AT op.pl, bogdro AT rudy.mif.pg.gda.pl) # # Licence: # GNU General Public Licence v3+ # # Last modified : 2010-03-21 # # Usage: # compare-po-timestamps-and-copy.pl src_file.po dst_file.po # # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 3 # of the License, 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software Foudation: # Free Software Foundation # 51 Franklin Street, Fifth Floor # Boston, MA 02110-1301 # USA # use strict; use warnings; use Tie::File; use Date::Manip; if ( @ARGV < 1 ) { print "Syntax: $0 src_file.po dst_file.po\n"; exit 1; } my (@output, @input); if ( ! tie (@input, 'Tie::File', $ARGV[0]) ) { # $! is the error message print "$0: $ARGV[0]: $!\n"; exit 2; } if ( ! tie (@output, 'Tie::File', $ARGV[1]) ) { print "$0: $ARGV[1]: $!\n"; untie @input; exit 3; } my $inindex; my $outindex = 0; my %months = ( 'Jan' => '01', 'Feb' => '02', 'Mar' => '03', 'Apr' => '04', 'May' => '05', 'Jun' => '06', 'Jul' => '07', 'Aug' => '08', 'Sep' => '09', 'Oct' => '10', 'Nov' => '11', 'Dec' => '12', ); for ( $inindex = 0; $inindex < @input; $inindex++ ) { $_ = $input[$inindex]; if ( /^#: Last-Modified:/o ) { for ( ; $outindex < @output; $outindex++ ) { last if ( $output[$outindex] =~ /^#: Last-Modified:/o ); } if ( $outindex < @output ) { # a Last-Modified line has just been found. Compare the times # format should be: "Wed, Mar 17 2010 18:57:44" m/^#: Last-Modified:\s*(\w+),\s*(\w+)\s*(\d+)\s*(\d+)\s*(\d+:\d+:\d+)/o; my $d = "$4$months{$2}$3$5"; my $date_src = ParseDate ($d); $output[$outindex] =~ m/^#: Last-Modified:\s*(\w+),\s*(\w+)\s*(\d+)\s*(\d+)\s*(\d+:\d+:\d+)/o; $d = "$4".$months{$2}."$3$5"; my $date_dst = ParseDate ($d); my $result = Date_Cmp ($date_src, $date_dst); if ( $result > 0 ) { # source date later than dest (string is newer). Copy the translation. #print "Found newer\n"; my $origstring = ""; # msgid my $trstring = ""; # msgstr in the source file # find the original English string for ( ; $inindex < @input; $inindex++ ) { if ( $input[$inindex] =~ /^msgid\s*(.*)/o ) { $origstring .= $1; $inindex++; while ( $input[$inindex] =~ /^(".*)/ && $inindex < @input ) { $origstring .= $1; $inindex++; } last; } } # find the original translated string for ( ; $inindex < @input; $inindex++ ) { if ( $input[$inindex] =~ /^msgstr\s*(.*)/o ) { $trstring .= $1; $inindex++; while ( $input[$inindex] =~ /^(".*)/ && $inindex < @input ) { $trstring .= $1; $inindex++; } last; } } # skip the string if empty (like the PO header) if ( $origstring =~ /^""$/ ) { # skip the current string in the output file for ( ; $outindex < @output; $outindex++ ) { last if ( $output[$outindex] =~ /^msgid\s*(.*)/o ); } for ( ; $outindex < @output; $outindex++ ) { last if ( $output[$outindex] =~ /^msgstr\s*(.*)/o ); } next; } #print "\nNewer string to copy: '$origstring', '$trstring'\n"; # find the indices where to paste the string in the destination file for ( ; $outindex < @output; $outindex++ ) { last if ( $output[$outindex] =~ /^msgstr\s*(.*)/o ); } my $startindex = $outindex; $outindex++; for ( ; $outindex < @output; $outindex++ ) { last if ( $output[$outindex] !~ /^"/o ); } my $endindex = $outindex; #print "start=$startindex, end=$endindex\n"; $trstring =~ s/\r/\n/go; $trstring =~ s/\n+/\n/go; my @newlines = ('msgstr ""', split (/\n/o, $trstring)); #for (my $i=0; $i < @newlines; $i++) {print "'".$newlines[$i]."'\n";} splice @output, $startindex, $endindex - $startindex, @newlines; } else { # skip the corresponding string in the destination file for ( ; $outindex < @output; $outindex++ ) { last if ( $output[$outindex] =~ /^msgstr\s*(.*)/o ); } } } } } untie @output; untie @input; #rename $ARGV[0], $ARGV[0];