File Coverage

blib/lib/App/MARC/List.pm
Criterion Covered Total %
statement 93 93 100.0
branch 20 22 90.9
condition 15 15 100.0
subroutine 12 12 100.0
pod 2 2 100.0
total 142 144 98.6


line stmt bran cond sub pod time code
1             package App::MARC::List;
2              
3 4     4   162115 use strict;
  4         9  
  4         169  
4 4     4   34 use warnings;
  4         14  
  4         223  
5              
6 4     4   2459 use Class::Utils qw(set_params);
  4         68129  
  4         94  
7 4     4   425 use English;
  4         16  
  4         27  
8 4     4   2134 use Error::Pure qw(err);
  4         8  
  4         252  
9 4     4   4484 use Getopt::Std;
  4         10255  
  4         318  
10 4     4   2855 use List::MoreUtils qw(uniq);
  4         84903  
  4         33  
11 4     4   6007 use List::Util qw(max);
  4         10  
  4         490  
12 4     4   2359 use MARC::File::XML (BinaryEncoding => 'utf8', RecordFormat => 'MARC21');
  4         702101  
  4         35  
13 4     4   2081 use Unicode::UTF8 qw(decode_utf8 encode_utf8);
  4         3053  
  4         4358  
14              
15             our $VERSION = 0.07;
16              
17             # Constructor.
18             sub new {
19 14     14 1 882618 my ($class, @params) = @_;
20              
21             # Create object.
22 14         43 my $self = bless {}, $class;
23              
24             # Process parameters.
25 14         107 set_params($self, @params);
26              
27             # Object.
28 13         159 return $self;
29             }
30              
31             # Run.
32             sub run {
33 12     12 1 25 my $self = shift;
34              
35             # Process arguments.
36 12         95 $self->{'_opts'} = {
37             'f' => 0,
38             'h' => 0,
39             };
40 12 100 100     82 if (! getopts('fh', $self->{'_opts'})
      100        
41             || $self->{'_opts'}->{'h'}
42             || @ARGV < 2) {
43              
44 4         474 print STDERR "Usage: $0 [-f] [-h] [--version] marc_xml_file field [subfield]\n";
45 4         127 print STDERR "\t-f\t\tPrint frequency.\n";
46 4         65 print STDERR "\t-h\t\tPrint help.\n";
47 4         49 print STDERR "\t--version\tPrint version.\n";
48 4         45 print STDERR "\tmarc_xml_file\tMARC XML file.\n";
49 4         67 print STDERR "\tfield\t\tMARC field (field number or 'leader' string).\n";
50 4         55 print STDERR "\tsubfield\tMARC subfield (for datafields).\n";
51 4         24 return 1;
52             }
53 8         392 $self->{'_marc_xml_file'} = shift @ARGV;
54 8         44 $self->{'_marc_field'} = shift @ARGV;
55 8         26 $self->{'_marc_subfield'} = shift @ARGV;
56              
57 8 100 100     79 if ($self->{'_marc_field'} ne 'leader'
58             && $self->{'_marc_field'} !~ m/^\d+$/ms) {
59              
60 1         8 err "Bad field definition. Must be a 'leader' or numeric value of the field.";
61             }
62              
63 7 100 100     60 if ($self->{'_marc_field'} ne 'leader'
      100        
64             && int($self->{'_marc_field'}) > 9
65             && ! defined $self->{'_marc_subfield'}) {
66              
67 1         8 err 'Subfield is required.';
68             }
69              
70 6         98 my $marc_file = MARC::File::XML->in($self->{'_marc_xml_file'});
71 6         635 my $ret_hr = {};
72 6         12 my $num = 1;
73 6         10 my $previous_record;
74 6         13 while (1) {
75 18         35 my $record = eval {
76 18         77 $marc_file->next;
77             };
78 18 100       54998 if ($EVAL_ERROR) {
79 1 50       82 print STDERR "Cannot process '$num' record. ".
80             (
81             defined $previous_record
82             ? "Previous record is ".encode_utf8($previous_record->title)."\n"
83             : ''
84             );
85 1         55 print STDERR "Error: $EVAL_ERROR\n";
86 1         6 next;
87             }
88 17 100       54 if (! defined $record) {
89 6         18 last;
90             }
91 11         199 $previous_record = $record;
92              
93 11 100       55 if ($self->{'_marc_field'} eq 'leader') {
94 4         16 my $leader = $record->leader;
95 4         50 $ret_hr->{"'".$leader."'"}++;
96             } else {
97 7         29 my @fields = $record->field($self->{'_marc_field'});
98 7         1695 foreach my $field (@fields) {
99 7 100       23 if (defined $self->{'_marc_subfield'}) {
100 6         55 my @subfield_values = $field->subfield($self->{'_marc_subfield'});
101 6         222 foreach my $subfield_value (@subfield_values) {
102 6         31 $ret_hr->{$subfield_value}++;
103             }
104             } else {
105 1         6 my $data = $field->data;
106 1         18 $ret_hr->{$data}++;
107             }
108             }
109             }
110 11         24 $num++;
111             }
112              
113             # Print out.
114 6 100       10 if (%{$ret_hr}) {
  6         23  
115 5 100       20 if ($self->{'_opts'}->{'f'}) {
116 2         41 my $max = max(values %{$ret_hr});
  2         15  
117 2         7 my $num = length($max);
118             print join "\n",
119 4         161 map { sprintf("%${num}s", $ret_hr->{$_}).' '.encode_utf8($_) }
120             reverse sort {
121 3 50       19 $ret_hr->{$a} <=> $ret_hr->{$b}
122             ||
123             $a cmp $b
124             }
125 2         6 keys %{$ret_hr};
  2         12  
126             } else {
127 3         10 print join "\n", map { encode_utf8($_) } sort keys %{$ret_hr};
  3         265  
  3         15  
128             }
129 5         234 print "\n";
130             }
131            
132 6         249 return 0;
133             }
134              
135             1;
136              
137              
138             __END__