File Coverage

blib/lib/HTML/WebMake/DataSources/DirOfFiles.pm
Criterion Covered Total %
statement 18 147 12.2
branch 0 46 0.0
condition 0 24 0.0
subroutine 6 16 37.5
pod 0 10 0.0
total 24 243 9.8


line stmt bran cond sub pod time code
1             #
2              
3             package HTML::WebMake::DataSources::DirOfFiles;
4              
5             require Exporter;
6 1     1   6 use File::Find;
  1         1406  
  1         97  
7 1     1   7 use Carp;
  1         2  
  1         54  
8 1     1   4 use strict;
  1         1  
  1         30  
9              
10 1     1   636 use HTML::WebMake::DataSourceBase;
  1         2  
  1         21  
11 1     1   498 use HTML::WebMake::MetaTable;
  1         2  
  1         27  
12              
13 1         1583 use vars qw{
14             @ISA @EXPORT
15             $TmpGlobalSelf
16 1     1   4 };
  1         1  
17              
18             @ISA = qw(HTML::WebMake::DataSourceBase);
19             @EXPORT = qw();
20              
21             ###########################################################################
22              
23             sub new {
24 0     0 0   my $class = shift;
25 0   0       $class = ref($class) || $class;
26 0           my $self = $class->SUPER::new (@_);
27 0           bless ($self, $class);
28              
29 0           $self;
30             }
31              
32             # -------------------------------------------------------------------------
33              
34             sub add {
35 0     0 0   my ($self) = @_;
36 0           local ($_);
37              
38 0           my $main = $self->{main};
39 0           my $src = $self->{src};
40              
41 0 0         if ($src eq '') { $src = '.'; }
  0            
42              
43 0           my $use_find = 0;
44 0 0         if ($self->{name} =~ s/^(RE:|)\.\.\.\//$1/) {
45 0           $use_find = 1;
46             }
47 0           my $patt = $main->{util}->glob_to_re ($self->{name});
48 0           my $pattskip = $main->{util}->glob_to_re ($self->{skip});
49 0           my $pattmetas = $main->{util}->glob_to_re ($self->{metatable});
50 0           my @matched;
51             my @matchedmetas;
52              
53 0           $self->{metas} = 0;
54 0 0         if (defined $pattmetas) {
55 0           $self->{metas} = 1;
56 0           dbg ("searching for files that match \"$patt\" or \"$pattmetas\"");
57             } else {
58 0           dbg ("searching for files that match \"$patt\"");
59             }
60              
61 0           $src =~ s,/+$,,;
62              
63 0           my $realsrc;
64 0 0         if ($main->{base_dir} ne '') {
65 0           $realsrc = File::Spec->catdir ($main->{base_dir}, $src);
66             } else {
67 0           $realsrc = $src;
68             }
69              
70             # this regexp is used to convert "/home/jm/jmason.org/raw/index.txt"
71             # to just "index.txt", when "raw" is the searched dir and "/home/jm/jmason.org"
72             # is the $main->{base_dir}.
73 0           $self->{real_to_underdir_re} = qr/\Q$realsrc\E/;
74              
75 0 0         if ($use_find) {
76 0           $self->{found} = [ ];
77 0           $self->{foundmetas} = [ ];
78              
79 0 0         if ($patt =~ m,/,) {
80 0           $self->{find_using_full_path} = 1;
81 0           $patt =~ s/^\^/\//; # replace start-of-string marker with /
82 0 0         if (defined $pattskip) { $pattskip =~ s/^\^/\//; }
  0            
83 0 0         if (defined $pattmetas) { $pattmetas =~ s/^\^/\//; }
  0            
84              
85             } else {
86 0           $self->{find_using_full_path} = 0;
87             }
88              
89 0           $self->{find_file_pattern} = $patt;
90 0           $self->{find_file_pattern_skip} = $pattskip;
91 0           $self->{find_file_pattern_metas} = $pattmetas;
92              
93 0           $TmpGlobalSelf = $self;
94 0           find (\&find_wanted, $realsrc);
95 0           undef $TmpGlobalSelf;
96              
97 0           @matched = @{$self->{found}};
  0            
98 0           delete $self->{found};
99              
100 0 0         if ($self->{metas}) {
101 0           @matchedmetas = @{$self->{foundmetas}};
  0            
102 0           delete $self->{foundmetas};
103             }
104              
105             } else {
106 0 0         if (!opendir (DIR, $realsrc)) {
107 0           warn "can't open ".$self->as_string()." src dir \"$realsrc\": $!\n";
108 0           return;
109             }
110              
111             # grep for files that (a) match the pattern and (b) are files, not dirs
112 0           my @files = readdir(DIR);
113              
114 0 0 0       @matched = grep {
      0        
115 0           /^${patt}$/ &&
116             (!defined $pattskip || !/^${pattskip}$/) &&
117             -f (File::Spec->catfile ($realsrc, $_));
118             } @files;
119              
120 0 0         if (defined $pattmetas) {
121 0 0 0       @matchedmetas = grep {
      0        
122 0           /^${pattmetas}$/ &&
123             (!defined $pattskip || !/^${pattskip}$/) &&
124             -f (File::Spec->catfile ($realsrc, $_));
125             } @files;
126             }
127              
128 0           closedir DIR;
129             }
130              
131             # add all the data content items
132 0           foreach my $name (@matched) {
133 0           my $fname = File::Spec->catfile ($realsrc, $name);
134 0           my $mtime = $main->cached_get_modtime ($fname);
135 0 0 0       if (!defined $mtime || $mtime == 0) {
136 0           warn "cannot stat file $fname\n";
137 0           next;
138             }
139              
140 0           $main->add_source_files ($fname);
141              
142 0           my $fixed = $self->{parent}->fixname ($name);
143 0           $self->{parent}->add_file_to_list ($fixed);
144 0           $self->{parent}->add_location ($fixed, "file:".$fname, $mtime);
145             }
146              
147             # and parse all the metadata files
148 0           foreach my $name (@matchedmetas) {
149 0           my $fname = File::Spec->catfile ($realsrc, $name);
150 0           my $mtime = $main->cached_get_modtime ($fname);
151 0 0 0       if (!defined $mtime || $mtime == 0) {
152 0           warn "cannot stat file $fname\n";
153 0           next;
154             }
155              
156 0           $main->add_source_files ($fname);
157 0           open (IN, "<$fname");
158 0           my $text = join ('', );
159 0           close IN;
160              
161             # if the metatable was loaded from a subdir, all the content
162             # items in that dir will be called e.g. "foo/bar/baz", but the
163             # metatable will contain references to "baz". Fix this...
164 0           $self->{metatable_name_prefix} = '';
165 0 0         if ($name =~ /^(.+[\/\\])[^\/\\]+/) {
166 0           $self->{metatable_name_prefix} = $1;
167             }
168              
169 0           my $tbl = new HTML::WebMake::MetaTable ($self->{main});
170 0           $tbl->set_name_sed_callback ($self, \&fix_names_for_metatable);
171 0           $tbl->parse_metatable ($self->{attrs}, $text);
172             }
173             }
174              
175             sub fix_names_for_metatable {
176 0     0 0   my ($self, $name) = @_;
177 0           $name = $self->{metatable_name_prefix} . $name;
178 0           $name = $self->{parent}->fixname ($name);
179 0           return $name;
180             }
181              
182             sub find_wanted {
183 0 0   0 0   -f $_ or return; # ensure not a dir etc.
184              
185 0           my $self = $TmpGlobalSelf;
186              
187 0           my $matchstr;
188 0 0         if ($self->{find_using_full_path}) {
189 0           $matchstr = $File::Find::name;
190             } else {
191 0           $matchstr = $_;
192             }
193              
194 0           my $skip = $self->{find_file_pattern_skip};
195 0 0 0       return if (defined $skip && $matchstr =~ /${skip}/);
196              
197 0 0         ($matchstr =~ /$self->{find_file_pattern}/) and $self->found_datafile();
198 0 0         if ($self->{metas}) {
199 0 0         ($matchstr =~ /$self->{find_file_pattern_metas}/) and $self->found_metafile();
200             }
201             }
202              
203             sub found_datafile {
204 0     0 0   my $self = shift;
205 0           my $name = $File::Find::name;
206 0           $name =~ s/^$self->{real_to_underdir_re}\/+//g;
207 0           push (@{$self->{found}}, $name);
  0            
208             }
209              
210             sub found_metafile {
211 0     0 0   my $self = shift;
212 0           my $name = $File::Find::name;
213 0           $name =~ s/^$self->{real_to_underdir_re}\/+//g;
214 0           push (@{$self->{foundmetas}}, $name);
  0            
215             }
216              
217             # -------------------------------------------------------------------------
218              
219             sub get_location_url {
220 0     0 0   my ($self, $fname) = @_;
221              
222 0           $fname =~ s/^file://;
223 0           return $fname;
224             }
225              
226             # -------------------------------------------------------------------------
227              
228             sub get_location_contents {
229 0     0 0   my ($self, $fname) = @_;
230              
231 0           $fname =~ s/^file://;
232 0 0         if (!open (IN, "<$fname")) {
233 0           carp "cannot open file \"$fname\"\n"; return "";
  0            
234             }
235 0           my $text = join ('', ); close IN;
  0            
236 0           return $text;
237             }
238              
239             # -------------------------------------------------------------------------
240              
241             sub get_location_mod_time {
242 0     0 0   my ($self, $fname) = @_;
243 0           $fname =~ /^file:/;
244 0           $self->{main}->cached_get_modtime ($');
245             }
246              
247             # -------------------------------------------------------------------------
248              
249 0     0 0   sub dbg { HTML::WebMake::Main::dbg (@_); }
250              
251             # -------------------------------------------------------------------------
252              
253             1;