File Coverage

lib/App/I18N.pm
Criterion Covered Total %
statement 58 130 44.6
branch 0 32 0.0
condition 1 15 6.6
subroutine 20 29 68.9
pod 0 9 0.0
total 79 215 36.7


line stmt bran cond sub pod time code
1             package App::I18N;
2 1     1   597 use strict;
  1         2  
  1         39  
3 1     1   6 use warnings;
  1         1  
  1         35  
4 1     1   6 use Carp;
  1         2  
  1         83  
5 1     1   938 use File::Copy;
  1         2627  
  1         67  
6 1     1   183173 use File::Find::Rule;
  1         22352  
  1         11  
7 1     1   317 use File::Path qw/mkpath/;
  1         7  
  1         167  
8 1     1   2236 use Locale::Maketext::Extract;
  1         338877  
  1         51  
9 1     1   2700 use Getopt::Long;
  1         14307  
  1         9  
10 1     1   199 use Exporter 'import';
  1         2  
  1         27  
11 1     1   4 use JSON::XS;
  1         2  
  1         59  
12 1     1   806 use YAML::XS;
  1         4404  
  1         69  
13 1     1   11 use File::Basename;
  1         1  
  1         61  
14 1     1   4 use Locale::Maketext::Extract;
  1         2  
  1         18  
15 1     1   462 use App::I18N::Logger;
  1         3  
  1         21  
16 1     1   6 use Cwd;
  1         1  
  1         52  
17 1     1   1082 use Encode;
  1         14462  
  1         120  
18 1     1   11 use File::Spec;
  1         3  
  1         26  
19 1     1   1169 use MIME::Types ();
  1         12799  
  1         33  
20 1     1   14 use constant USE_GETTEXT_STYLE => 1;
  1         2  
  1         2255  
21              
22              
23             # our @EXPORT = qw(_);
24              
25             our $VERSION = '0.034';
26             our $LOGGER;
27             our $LMExtract;
28             our $MIME = MIME::Types->new();
29              
30             sub logger {
31 0   0 0 0 0 $LOGGER ||= App::I18N::Logger->new;
32 0         0 return $LOGGER;
33             }
34              
35             Locale::Maketext::Lexicon::set_option( 'allow_empty' => 1 );
36             Locale::Maketext::Lexicon::set_option( 'use_fuzzy' => 1 );
37             Locale::Maketext::Lexicon::set_option( 'encoding' => "UTF-8" );
38             Locale::Maketext::Lexicon::set_option( 'style' => 'gettext' );
39              
40             sub lm_extract {
41 1   33 1 0 62 return $LMExtract ||= Locale::Maketext::Extract->new(
42             plugins => {
43             'Locale::Maketext::Extract::Plugin::PPI' => [ 'pm','pl' ],
44             'tt2' => [ ],
45             # 'perl' => ['pl','pm','js','json'],
46             'perl' => [ '*' ], # _( ) , gettext( ) , loc( ) ...
47             'mason' => [ ] ,
48             'generic' => [ '*' ],
49             },
50             verbose => 1, warnings => 1 );
51             }
52              
53             sub guess_appname {
54 0     0 0   return lc(basename(getcwd()));
55             }
56              
57             sub pot_name {
58 0     0 0   my $self = shift;
59 0           return guess_appname();
60             }
61              
62              
63             sub _check_mime_type {
64 0     0     my $self = shift;
65 0           my $local_path = shift;
66 0           my $mimeobj = $MIME->mimeTypeOf($local_path);
67 0 0         my $mime_type = ($mimeobj ? $mimeobj->type : "unknown");
68 0 0         return if ( $mime_type =~ /^image/ );
69 0 0         return if ( $mime_type =~ /compressed/ ); # ignore compressed archive files
70             # return if ( $mime_type =~ /^application/ );
71 0           return 1;
72             }
73              
74             sub extract_messages {
75 0     0 0   my ( $self, @dirs ) = @_;
76 0 0         my @files = map { ( -d $_ ) ? File::Find::Rule->file->in($_) : $_ } @dirs;
  0            
77 0           my $logger = $self->logger;
78 0           my $lme = $self->lm_extract;
79 0           foreach my $file (@files) {
80 0 0         next if $file =~ m{(^|/)[\._]svn/};
81 0 0         next if $file =~ m{\~$};
82 0 0         next if $file =~ m{\.pod$};
83 0 0         next if $file =~ m{^\.git};
84 0 0         next unless $self->_check_mime_type($file);
85 0           $logger->info("Extracting messages from '$file'");
86 0           $lme->extract_file($file);
87             }
88             }
89              
90             sub update_catalog {
91 0     0 0   my ( $self, $translation , $cmd ) = @_;
92              
93 0   0       $cmd ||= {};
94              
95 0           my $logger = $self->logger;
96 0           $logger->info( "Updating message catalog '$translation'");
97              
98 0           my $lme = $self->lm_extract;
99 0 0 0       $lme->read_po( $translation ) if -f $translation && $translation !~ m/pot$/;
100              
101             # Reset previously compiled entries before a new compilation
102 0           $lme->set_compiled_entries;
103 0           $lme->compile(USE_GETTEXT_STYLE);
104 0           $lme->write_po($translation);
105              
106             # patch CHARSET
107 0           $logger->info( "Set CHARSET to UTF-8" );
108 0           open my $fh , "<" , $translation;
109 0           my @lines = <$fh>;
110 0           close $fh;
111              
112 0           open my $out_fh , ">" , $translation;
113 0           for my $line ( @lines ) {
114 0           $line =~ s{charset=CHARSET}{charset=UTF-8};
115 0           print $out_fh $line;
116             }
117 0           close $out_fh;
118              
119              
120 0 0         if( $cmd->{mo} ) {
121 0           my $mofile = $translation;
122 0           $mofile =~ s{\.po$}{.mo};
123 0           $logger->info( "Generating MO file: $mofile" );
124 0           system(qq{msgfmt -v $translation -o $mofile});
125             }
126             }
127              
128             sub guess_podir {
129 0     0 0   my ($class,$cmd) = @_;
130 0           my $podir;
131 0 0         $podir = 'po' if -e 'po';
132 0 0         $podir = 'locale' , $cmd->{locale} = 1 if -e 'locale';
133 0 0 0       $podir ||= 'locale' if $cmd->{locale};
134 0   0       $podir ||= 'po';
135 0           return $podir;
136             }
137              
138             sub get_po_path {
139 0     0 0   my ( $self, $podir, $lang, $is_locale ) = @_;
140 0           my $pot_name = App::I18N->pot_name;
141 0           my $path;
142 0 0         if ($is_locale) {
143 0           $path = File::Spec->join( $podir, $lang . ".po" );
144             }
145             else {
146 0           $path = File::Spec->join( $podir, 'locale', $lang, 'LC_MESSAGES', $pot_name . ".po" );
147             }
148 0           return $path;
149             }
150              
151             sub update_catalogs {
152 0     0 0   my ($self,$podir , $cmd ) = @_;
153 0           my @catalogs = grep !m{(^|/)(?:\.svn|\.git)/},
154             File::Find::Rule->file
155             ->name('*.po')->in( $podir);
156              
157 0           my $logger = App::I18N->logger;
158 0 0         unless ( @catalogs ) {
159 0           $logger->error("You have no existing message catalogs.");
160 0           $logger->error("Run `po lang ` to create a new one.");
161 0           $logger->error("Read `po help` to get more info.");
162             return
163 0           }
164              
165 0           foreach my $catalog (@catalogs) {
166 0           $self->update_catalog( $catalog , $cmd );
167             }
168             }
169              
170              
171              
172             # _('Internationalization')
173             # _('Translate me')
174              
175             1;
176             __END__