File Coverage

blib/lib/Data/iRealPro/Input.pm
Criterion Covered Total %
statement 53 83 63.8
branch 14 34 41.1
condition 1 5 20.0
subroutine 11 13 84.6
pod 0 5 0.0
total 79 140 56.4


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: Thu Nov 1 21:08:41 2018
9             # Update Count : 80
10             # Status : Unknown, Use with caution!
11              
12             ################ Common stuff ################
13              
14 10     10   591644 use strict;
  10         115  
  10         308  
15 10     10   53 use warnings;
  10         22  
  10         310  
16 10     10   71 use Carp;
  10         19  
  10         624  
17 10     10   4776 use utf8;
  10         134  
  10         63  
18              
19             package Data::iRealPro::Input;
20              
21 10     10   3631 use Data::iRealPro::URI;
  10         35  
  10         365  
22 10     10   4216 use Data::iRealPro::Input::Text;
  10         25  
  10         326  
23 10     10   69 use Encode qw ( decode_utf8 );
  10         20  
  10         453  
24 10     10   61 use File::Basename ();
  10         19  
  10         9139  
25              
26             sub new {
27 8     8 0 1226 my ( $pkg, $options ) = @_;
28              
29 8         39 my $self = bless( { variant => "irealpro" }, $pkg );
30              
31 8         41 for ( qw( trace debug verbose output variant transpose
32             neatify select suppress-upbeat suppress-text
33             musescore override-alt condense ) ) {
34 104 100       212 $self->{$_} = $options->{$_} if exists $options->{$_};
35             }
36              
37 8         26 for ( qw( playlist catalog ) ) {
38 16 50       51 $self->{$_} = decode_utf8($options->{$_}) if exists $options->{$_};
39             }
40              
41 8         26 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 foreach my $file ( @files ) {
59 0 0       0 warn("Parsing: $file...\n") if $self->{verbose};
60 0 0       0 unless ( $self->{playlist} ) {
61 0         0 my @p = File::Basename::fileparse( $file, qr/\.[^.]*/ );
62 0         0 $self->{playlist} = $p[0];
63             }
64 0         0 my $u = $self->parsefile($file);
65 0 0       0 unless ( $all ) {
66 0         0 $all = $u;
67             }
68             else {
69 0         0 $all->{playlist}->add_songs( $u->{playlist}->songs );
70             }
71             }
72              
73 0 0       0 $all->{playlist}->{name} = $self->{playlist} if $self->{playlist};
74 0         0 $self->apply_selection($all);
75             }
76              
77             sub parsedata {
78 10     10 0 4973 my ( $self, $data ) = @_;
79              
80 10         22 my $all;
81 10 100       23 if ( eval { $data->[0] } ) {
  10         159  
82 1         4 foreach my $d ( @$data ) {
83 2         10 my $u = $self->parsedata($d);
84 2 100       14 if ( $all ) {
85 1         6 $all->{playlist}->add_songs( $u->{playlist}->songs );
86             }
87             else {
88 1         2 $all = $u;
89 1   50     7 $all->{playlist}->{name} ||= "NoName";
90             }
91             }
92 1 50       13 $all->{playlist}->{name} = $self->{playlist} if $self->{playlist};
93 1         5 $self->apply_selection($all);
94             }
95              
96             else {
97 9 100       75 if ( $data =~ /^Song( \d+)?:/ ) {
    50          
98 7         45 $all = Data::iRealPro::Input::Text::encode( $self, $data );
99             }
100             elsif ( $data =~ /^(?:<\?xml.*?>\s*)?
101 0         0 require Data::iRealPro::Input::MusicXML;
102 0         0 $all = Data::iRealPro::Input::MusicXML::encode( $self, $data );
103             }
104             else {
105             # Extract URL.
106 2         66 $data =~ s;^.*?(irealb(?:ook)?://.*?)(?:$|\").*;$1;s;
107 2 50       14 $data = "irealbook://" . $data
108             unless $data =~ m;^(irealb(?:ook)?://.*?);;
109              
110             $all = Data::iRealPro::URI->new( data => $data,
111             debug => $self->{debug},
112             transpose => $self->{transpose},
113 2         28 );
114             }
115             }
116              
117 10 50       43 $all->{playlist}->{name} = $self->{playlist} if $self->{playlist};
118 10         26 return $all;
119             }
120              
121             # Since input can be collected from different sources in spearate calls,
122             # we need to apply a selection manually.
123              
124             sub apply_selection {
125 1     1 0 4 my ( $self, $u ) = @_;
126              
127 1         3 my $i = $self->{select};
128 1 50       4 return $u unless $i;
129              
130 0 0 0       if ( $i > 0 && $i <= @{ $u->{playlist}->songs } ) {
  0            
131             $u->{playlist}->{songs} =
132 0           [ $u->{playlist}->songs->[$i-1] ];
133 0           $u->{playlist}->{songs}->[0]->{songindex} = $i;
134 0           $u->{playlist}->{name} = "";
135             }
136             else {
137 0           Carp::croak("Invalid value in select");
138             }
139 0           return $u;
140             }
141              
142             1;