File Coverage

blib/lib/Log/Report/Extract.pm
Criterion Covered Total %
statement 70 104 67.3
branch 12 42 28.5
condition 4 24 16.6
subroutine 17 21 80.9
pod 11 12 91.6
total 114 203 56.1


line stmt bran cond sub pod time code
1             # Copyrights 2007-2017 by [Mark Overmeer].
2             # For other contributors see ChangeLog.
3             # See the manual pages for details on the licensing terms.
4             # Pod stripped from pm file by OODoc 2.02.
5 2     2   101962 use warnings;
  2         4  
  2         59  
6 2     2   9 use strict;
  2         4  
  2         53  
7              
8             package Log::Report::Extract;
9 2     2   8 use vars '$VERSION';
  2         4  
  2         86  
10             $VERSION = '1.09';
11              
12              
13 2     2   10 use Log::Report 'log-report-lexicon';
  2         7  
  2         9  
14 2     2   903 use Log::Report::Lexicon::Index ();
  2         6  
  2         43  
15 2     2   291 use Log::Report::Lexicon::POT ();
  2         6  
  2         3017  
16              
17              
18             sub new(@)
19 1     1 1 1227 { my $class = shift;
20 1         8 (bless {}, $class)->init( {@_} );
21             }
22              
23             sub init($)
24 1     1 0 3 { my ($self, $args) = @_;
25             my $lexi = $args->{lexicon}
26 1 50       4 or error __"extractions require an explicit lexicon directory";
27              
28 1 50 33     8 -d $lexi or mkdir $lexi
29             or fault __x"cannot create lexicon directory {dir}", dir => $lexi;
30              
31 1         8 $self->{LRE_index} = Log::Report::Lexicon::Index->new($lexi);
32 1   50     6 $self->{LRE_charset} = $args->{LRE_charset} || 'utf-8';
33 1         2 $self->{LRE_domains} = {};
34 1         3 $self;
35             }
36              
37             #---------------
38              
39 2     2 1 11 sub index() {shift->{LRE_index}}
40 1     1 1 2 sub charset() {shift->{LRE_charset}}
41 2     2 1 4 sub domains() {sort keys %{shift->{LRE_domains}}}
  2         16  
42              
43              
44             sub pots($)
45 12     12 1 21 { my ($self, $domain) = @_;
46 12         22 my $r = $self->{LRE_domains}{$domain};
47 12 50       29 $r ? @$r : ();
48             }
49              
50              
51             sub addPot($$%)
52 0     0 1 0 { my ($self, $domain, $pot) = @_;
53 0 0       0 push @{$self->{LRE_domains}{$domain}}, ref $pot eq 'ARRAY' ? @$pot : $pot
  0 0       0  
54             if $pot;
55             }
56              
57             #---------------
58              
59             sub process($@)
60 0     0 1 0 { my ($self, $fn, %opts) = @_;
61 0         0 panic "not implemented";
62             }
63              
64              
65             sub cleanup(%)
66 0     0 1 0 { my ($self, %args) = @_;
67 0   0     0 my $keep = $args{keep} || {};
68 0 0       0 $keep = +{ map +($_ => 1), @$keep }
69             if ref $keep eq 'ARRAY';
70              
71 0         0 foreach my $domain ($self->domains)
72 0         0 { $_->keepReferencesTo($keep) for $self->pots($domain);
73             }
74             }
75              
76              
77             sub showStats(;$)
78 0     0 1 0 { my $self = shift;
79 0 0       0 my @domains = @_ ? @_ : $self->domains;
80              
81 0 0       0 dispatcher needs => 'INFO'
82             or return;
83              
84 0         0 foreach my $domain (@domains)
85 0 0       0 { my $pots = $self->{LRE_domains}{$domain} or next;
86 0         0 my ($msgids, $fuzzy, $inactive) = (0, 0, 0);
87              
88 0         0 foreach my $pot (@$pots)
89 0         0 { my $stats = $pot->stats;
90 0 0 0     0 next unless $stats->{fuzzy} || $stats->{inactive};
91              
92 0         0 $msgids = $stats->{msgids};
93 0 0       0 next if $msgids == $stats->{fuzzy}; # ignore the template
94              
95             notice __x
96             "{domain}: {fuzzy%3d} fuzzy, {inact%3d} inactive in {filename}"
97             , domain => $domain, fuzzy => $stats->{fuzzy}
98 0         0 , inact => $stats->{inactive}, filename => $pot->filename;
99              
100 0         0 $fuzzy += $stats->{fuzzy};
101 0         0 $inactive += $stats->{inactive};
102             }
103              
104 0 0 0     0 if($fuzzy || $inactive)
105 0         0 { info __xn
106             "{domain}: one file with {ids} msgids, {f} fuzzy and {i} inactive translations"
107             , "{domain}: {_count} files each {ids} msgids, {f} fuzzy and {i} inactive translations in total"
108             , scalar(@$pots), domain => $domain
109             , f => $fuzzy, ids => $msgids, i => $inactive
110             }
111             else
112 0         0 { info __xn
113             "{domain}: one file with {ids} msgids"
114             , "{domain}: {_count} files with each {ids} msgids"
115             , scalar(@$pots), domain => $domain, ids => $msgids;
116             }
117             }
118             }
119              
120              
121             sub write(;$)
122 3     3 1 684 { my ($self, $domain) = @_;
123 3 100       10 unless(defined $domain) # write all
124 2         9 { $self->write($_) for $self->domains;
125 2         143 return;
126             }
127              
128 1 50       4 my $pots = delete $self->{LRE_domains}{$domain}
129             or return; # nothing found
130              
131 1         3 for my $pot (@$pots)
132 1         4 { $pot->updated;
133 1         4 $pot->write;
134             }
135              
136 1         33 $self;
137             }
138              
139 1     1   4153 sub DESTROY() {shift->write}
140              
141             sub _reset($$)
142 1     1   3 { my ($self, $domain, $fn) = @_;
143              
144 1   33     7 my $pots = $self->{LRE_domains}{$domain}
145             ||= $self->_read_pots($domain);
146              
147 1         6 $_->removeReferencesTo($fn) for @$pots;
148             }
149              
150             sub _read_pots($)
151 1     1   3 { my ($self, $domain) = @_;
152              
153 1         7 my $index = $self->index;
154 1         5 my $charset = $self->charset;
155              
156 1         4 my @pots = map Log::Report::Lexicon::POT->read($_, charset=> $charset),
157             $index->list($domain);
158              
159 1         6 trace __xn "found one pot file for domain {domain}"
160             , "found {_count} pot files for domain {domain}"
161             , @pots, domain => $domain;
162              
163             return \@pots
164 1 50       80 if @pots;
165              
166             # new text-domain found, start template
167 1         20 my $fn = $index->addFile("$domain.$charset.po");
168 1         5 info __x"starting new textdomain {domain}, template in {filename}"
169             , domain => $domain, filename => $fn;
170              
171 1         61 my $pot = Log::Report::Lexicon::POT->new
172             ( textdomain => $domain
173             , filename => $fn
174             , charset => $charset
175             , version => 0.01
176             );
177              
178 1         5 [ $pot ];
179             }
180              
181              
182             sub store($$$$;$)
183 12     12 1 28 { my ($self, $domain, $fn, $linenr, $msgid, $plural) = @_;
184              
185 12         28 my $textdomain = textdomain $domain;
186 12         217 my $context = $textdomain->contextRules;
187              
188 12         43 foreach my $pot ($self->pots($domain))
189 12         14 { my ($stripped, $msgctxts);
190 12 50       19 if($context)
191 0   0     0 { my $lang = $pot->language || 'en';
192 0         0 ($stripped, $msgctxts) = $context->expand($msgid, $lang);
193              
194 0 0 0     0 if($plural && $plural =~ m/\{[^}]*\<\w+/)
195 0         0 { error __x"no context tags allowed in plural `{msgid}'"
196             , msgid => $plural;
197             }
198             }
199             else
200 12         18 { $stripped = $msgid;
201             }
202              
203 12 50 33     33 $msgctxts && @$msgctxts
204             or $msgctxts = [undef];
205              
206             MSGCTXT:
207 12         17 foreach my $msgctxt (@$msgctxts)
208             {
209             #warn "($stripped, $msgctxt)";
210 12 50       28 if(my $po = $pot->msgid($stripped, $msgctxt))
211 0         0 { $po->addReferences( ["$fn:$linenr"]);
212 0 0       0 $po->plural($plural) if $plural;
213 0         0 next MSGCTXT;
214             }
215              
216 12 100       38 my $format = $stripped =~ m/\{/ ? 'perl-brace' : 'perl';
217 12         44 my $po = Log::Report::Lexicon::PO->new
218             ( msgid => $stripped
219             , msgid_plural => $plural
220             , msgctxt => $msgctxt
221             , fuzzy => 1
222             , format => $format
223             , references => [ "$fn:$linenr" ]
224             );
225              
226 12         38 $pot->add($po);
227             }
228             }
229             }
230              
231             1;