File Coverage

blib/lib/Data/iRealPro/Input.pm
Criterion Covered Total %
statement 53 87 60.9
branch 14 38 36.8
condition 1 5 20.0
subroutine 11 13 84.6
pod 0 5 0.0
total 79 148 53.3


line stmt bran cond sub pod time code
1             #! perl
2              
3             # Data::iRealPro::Input -- parse iRealPro data
4              
5             # Author : Johan Vromans
6             # Created On : Tue Sep 6 16:09:10 2016
7             # Last Modified By: Johan Vromans
8             # Last Modified On: Wed Nov 14 21:35:40 2018
9             # Update Count : 82
10             # Status : Unknown, Use with caution!
11              
12             ################ Common stuff ################
13              
14 12     12   607752 use strict;
  12         125  
  12         350  
15 12     12   62 use warnings;
  12         24  
  12         333  
16 12     12   85 use Carp;
  12         25  
  12         777  
17 12     12   6113 use utf8;
  12         149  
  12         73  
18              
19             package Data::iRealPro::Input;
20              
21 12     12   4716 use Data::iRealPro::URI;
  12         38  
  12         439  
22 12     12   5274 use Data::iRealPro::Input::Text;
  12         33  
  12         398  
23 12     12   96 use Encode qw ( decode_utf8 );
  12         71  
  12         571  
24 12     12   75 use File::Basename ();
  12         22  
  12         11288  
25              
26             sub new {
27 10     10 0 1523 my ( $pkg, $options ) = @_;
28              
29 10         52 my $self = bless( { variant => "irealpro" }, $pkg );
30              
31 10         89 for ( qw( trace debug verbose output variant transpose
32             neatify select suppress-upbeat suppress-text
33             musescore override-alt condense ) ) {
34 130 100       306 $self->{$_} = $options->{$_} if exists $options->{$_};
35             }
36              
37 10         41 for ( qw( playlist catalog ) ) {
38 20 50       68 $self->{$_} = decode_utf8($options->{$_}) if exists $options->{$_};
39             }
40              
41 10         38 return $self;
42             }
43              
44             sub parsefile {
45 0     0 0 0 my ( $self, $file ) = @_;
46              
47 0 0       0 open( my $fd, '<:utf8', $file ) or die("$file: $!\n");
48 0         0 my $data = do { local $/; <$fd> };
  0         0  
  0         0  
49 0         0 my $u = $self->parsedata($data);
50 0 0       0 $u->{playlist}->{name} = $self->{playlist} if $self->{playlist};
51 0         0 return $u;
52             }
53              
54             sub parsefiles {
55 0     0 0 0 my ( $self, @files ) = @_;
56              
57 0         0 my $all;
58 0         0 my $plname = $self->{playlist};
59 0         0 foreach my $file ( @files ) {
60 0 0       0 warn("Parsing: $file...\n") if $self->{verbose};
61 0         0 my $u = $self->parsefile($file);
62 0 0       0 unless ( $all ) {
63 0         0 $all = $u;
64             }
65             else {
66 0         0 $all->{playlist}->add_songs( $u->{playlist}->songs );
67             }
68 0 0       0 unless ( $plname ) {
69 0         0 $plname = $all->{playlist}->{name};
70 0 0       0 $plname = "" if $plname eq "";
71             }
72 0 0       0 unless ( $plname ) {
73 0         0 my @p = File::Basename::fileparse( $file, qr/\.[^.]*/ );
74 0         0 $plname = $p[0];
75             }
76             }
77              
78 0 0       0 $all->{playlist}->{name} = $plname if $plname;
79 0         0 $self->apply_selection($all);
80             }
81              
82             sub parsedata {
83 13     13 0 5440 my ( $self, $data ) = @_;
84              
85 13         26 my $all;
86 13 100       29 if ( eval { $data->[0] } ) {
  13         161  
87 1         4 foreach my $d ( @$data ) {
88 2         10 my $u = $self->parsedata($d);
89 2 100       7 if ( $all ) {
90 1         7 $all->{playlist}->add_songs( $u->{playlist}->songs );
91             }
92             else {
93 1         3 $all = $u;
94 1   50     7 $all->{playlist}->{name} ||= "NoName";
95             }
96             }
97 1 50       5 $all->{playlist}->{name} = $self->{playlist} if $self->{playlist};
98 1         4 $self->apply_selection($all);
99             }
100              
101             else {
102 12 100       94 if ( $data =~ /^Song( \d+)?:/ ) {
    50          
103 10         71 $all = Data::iRealPro::Input::Text::encode( $self, $data );
104             }
105             elsif ( $data =~ /^(?:<\?xml.*?>\s*)?
106 0         0 require Data::iRealPro::Input::MusicXML;
107 0         0 $all = Data::iRealPro::Input::MusicXML::encode( $self, $data );
108             }
109             else {
110             # Extract URL.
111 2         67 $data =~ s;^.*?(irealb(?:ook)?://.*?)(?:$|\").*;$1;s;
112 2 50       13 $data = "irealbook://" . $data
113             unless $data =~ m;^(irealb(?:ook)?://.*?);;
114              
115             $all = Data::iRealPro::URI->new( data => $data,
116             debug => $self->{debug},
117             transpose => $self->{transpose},
118 2         25 );
119             }
120             }
121              
122 13 50       57 $all->{playlist}->{name} = $self->{playlist} if $self->{playlist};
123 13         44 return $all;
124             }
125              
126             # Since input can be collected from different sources in spearate calls,
127             # we need to apply a selection manually.
128              
129             sub apply_selection {
130 1     1 0 4 my ( $self, $u ) = @_;
131              
132 1         2 my $i = $self->{select};
133 1 50       4 return $u unless $i;
134              
135 0 0 0       if ( $i > 0 && $i <= @{ $u->{playlist}->songs } ) {
  0            
136             $u->{playlist}->{songs} =
137 0           [ $u->{playlist}->songs->[$i-1] ];
138 0           $u->{playlist}->{songs}->[0]->{songindex} = $i;
139 0           $u->{playlist}->{name} = "";
140             }
141             else {
142 0           Carp::croak("Invalid value in select");
143             }
144 0           return $u;
145             }
146              
147             1;