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   97579 use warnings;
  2         8  
  2         79  
6 2     2   14 use strict;
  2         5  
  2         70  
7              
8             package Log::Report::Extract;
9 2     2   13 use vars '$VERSION';
  2         5  
  2         110  
10             $VERSION = '1.08';
11              
12              
13 2     2   16 use Log::Report 'log-report-lexicon';
  2         9  
  2         15  
14 2     2   1353 use Log::Report::Lexicon::Index ();
  2         7  
  2         45  
15 2     2   539 use Log::Report::Lexicon::POT ();
  2         5  
  2         2021  
16              
17              
18             sub new(@)
19 1     1 1 1984 { my $class = shift;
20 1         15 (bless {}, $class)->init( {@_} );
21             }
22              
23             sub init($)
24 1     1 0 5 { my ($self, $args) = @_;
25             my $lexi = $args->{lexicon}
26 1 50       7 or error __"extractions require an explicit lexicon directory";
27              
28 1 50 33     21 -d $lexi or mkdir $lexi
29             or fault __x"cannot create lexicon directory {dir}", dir => $lexi;
30              
31 1         15 $self->{LRE_index} = Log::Report::Lexicon::Index->new($lexi);
32 1   50     12 $self->{LRE_charset} = $args->{LRE_charset} || 'utf-8';
33 1         4 $self->{LRE_domains} = {};
34 1         5 $self;
35             }
36              
37             #---------------
38              
39 2     2 1 20 sub index() {shift->{LRE_index}}
40 1     1 1 5 sub charset() {shift->{LRE_charset}}
41 2     2 1 8 sub domains() {sort keys %{shift->{LRE_domains}}}
  2         21  
42              
43              
44             sub pots($)
45 12     12 1 47 { my ($self, $domain) = @_;
46 12         38 my $r = $self->{LRE_domains}{$domain};
47 12 50       54 $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 1096 { my ($self, $domain) = @_;
123 3 100       15 unless(defined $domain) # write all
124 2         13 { $self->write($_) for $self->domains;
125 2         71 return;
126             }
127              
128 1 50       7 my $pots = delete $self->{LRE_domains}{$domain}
129             or return; # nothing found
130              
131 1         5 for my $pot (@$pots)
132 1         8 { $pot->updated;
133 1         6 $pot->write;
134             }
135              
136 1         58 $self;
137             }
138              
139 1     1   2925 sub DESTROY() {shift->write}
140              
141             sub _reset($$)
142 1     1   5 { my ($self, $domain, $fn) = @_;
143              
144 1   33     14 my $pots = $self->{LRE_domains}{$domain}
145             ||= $self->_read_pots($domain);
146              
147 1         11 $_->removeReferencesTo($fn) for @$pots;
148             }
149              
150             sub _read_pots($)
151 1     1   5 { my ($self, $domain) = @_;
152              
153 1         20 my $index = $self->index;
154 1         9 my $charset = $self->charset;
155              
156 1         12 my @pots = map Log::Report::Lexicon::POT->read($_, charset=> $charset),
157             $index->list($domain);
158              
159 1         14 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       120 if @pots;
165              
166             # new text-domain found, start template
167 1         9 my $fn = $index->addFile("$domain.$charset.po");
168 1         7 info __x"starting new textdomain {domain}, template in {filename}"
169             , domain => $domain, filename => $fn;
170              
171 1         109 my $pot = Log::Report::Lexicon::POT->new
172             ( textdomain => $domain
173             , filename => $fn
174             , charset => $charset
175             , version => 0.01
176             );
177              
178 1         9 [ $pot ];
179             }
180              
181              
182             sub store($$$$;$)
183 12     12 1 47 { my ($self, $domain, $fn, $linenr, $msgid, $plural) = @_;
184              
185 12         49 my $textdomain = textdomain $domain;
186 12         308 my $context = $textdomain->contextRules;
187              
188 12         83 foreach my $pot ($self->pots($domain))
189 12         30 { my ($stripped, $msgctxts);
190 12 50       35 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         31 { $stripped = $msgid;
201             }
202              
203 12 50 33     88 $msgctxts && @$msgctxts
204             or $msgctxts = [undef];
205              
206             MSGCTXT:
207 12         37 foreach my $msgctxt (@$msgctxts)
208             {
209             #warn "($stripped, $msgctxt)";
210 12 50       57 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       55 my $format = $stripped =~ m/\{/ ? 'perl-brace' : 'perl';
217 12         89 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         66 $pot->add($po);
227             }
228             }
229             }
230              
231             1;