source: main/trunk/greenstone2/perllib/cpan/Mojo/File.pm@ 32205

Last change on this file since 32205 was 32205, checked in by ak19, 6 years ago

First set of commits to do with implementing the new 'paged_html' output option of PDFPlugin that uses using xpdftools' new pdftohtml. So far tested only on Linux (64 bit), but things work there so I'm optimistically committing the changes since they work. 2. Committing the pre-built Linux binaries of XPDFtools for both 32 and 64 bit built by the XPDF group. 2. To use the correct bitness variant of xpdftools, setup.bash now exports the BITNESS env var, consulted by gsConvert.pl. 3. All the perl code changes to do with using xpdf tools' pdftohtml to generate paged_html and feed it in the desired form into GS(3): gsConvert.pl, PDFPlugin.pm and its parent ConvertBinaryPFile.pm have been modified to make it all work. xpdftools' pdftohtml generates a folder containing an html file and a screenshot for each page in a PDF (as well as an index.html linking to each page's html). However, we want a single html file that contains each individual 'page' html's content in a div, and need to do some further HTML style, attribute and structure modifications to massage the xpdftool output to what we want for GS. In order to parse and manipulate the HTML 'DOM' to do this, we're using the Mojo::DOM package that Dr Bainbridge found and which he's compiled up. Mojo::DOM is therefore also committed in this revision. Some further changes and some display fixes are required, but need to check with the others about that.

File size: 10.8 KB
Line 
1package Mojo::File;
2use Mojo::Base -strict;
3use overload
4 '@{}' => sub { shift->to_array },
5 bool => sub {1},
6 '""' => sub { ${$_[0]} },
7 fallback => 1;
8
9use Carp 'croak';
10use Cwd 'getcwd';
11use Exporter 'import';
12use File::Basename ();
13use File::Copy qw(copy move);
14use File::Find 'find';
15use File::Path ();
16use File::Spec::Functions
17 qw(abs2rel canonpath catfile file_name_is_absolute rel2abs splitdir);
18use File::Temp ();
19use IO::File ();
20use Mojo::Collection;
21
22our @EXPORT_OK = ('path', 'tempdir', 'tempfile');
23
24sub basename { File::Basename::basename ${shift()}, @_ }
25
26sub child { $_[0]->new(@_) }
27
28sub copy_to {
29 my ($self, $to) = @_;
30 copy($$self, $to) or croak qq{Can't copy file "$$self" to "$to": $!};
31 return $self->new(-d $to ? ($to, File::Basename::basename $self) : $to);
32}
33
34sub dirname { $_[0]->new(scalar File::Basename::dirname ${$_[0]}) }
35
36sub is_abs { file_name_is_absolute ${shift()} }
37
38sub list {
39 my ($self, $options) = (shift, shift // {});
40
41 return Mojo::Collection->new unless -d $$self;
42 opendir(my $dir, $$self) or croak qq{Can't open directory "$$self": $!};
43 my @files = grep { $_ ne '.' && $_ ne '..' } readdir $dir;
44 @files = grep { !/^\./ } @files unless $options->{hidden};
45 @files = map { catfile $$self, $_ } @files;
46 @files = grep { !-d } @files unless $options->{dir};
47
48 return Mojo::Collection->new(map { $self->new($_) } sort @files);
49}
50
51sub list_tree {
52 my ($self, $options) = (shift, shift // {});
53
54 # This may break in the future, but is worth it for performance
55 local $File::Find::skip_pattern = qr/^\./ unless $options->{hidden};
56
57 # The File::Find documentation lies, this is needed for CIFS
58 local $File::Find::dont_use_nlink = 1 if $options->{dont_use_nlink};
59
60 my %all;
61 my $wanted = {wanted => sub { $all{$File::Find::name}++ }, no_chdir => 1};
62 $wanted->{postprocess} = sub { delete $all{$File::Find::dir} }
63 unless $options->{dir};
64 find $wanted, $$self if -d $$self;
65 delete $all{$$self};
66
67 return Mojo::Collection->new(map { $self->new(canonpath $_) } sort keys %all);
68}
69
70sub make_path {
71 my $self = shift;
72 File::Path::make_path $$self, @_;
73 return $self;
74}
75
76sub move_to {
77 my ($self, $to) = @_;
78 move($$self, $to) or croak qq{Can't move file "$$self" to "$to": $!};
79 return $self->new(-d $to ? ($to, File::Basename::basename $self) : $to);
80}
81
82sub new {
83 my $class = shift;
84 my $value = @_ == 1 ? $_[0] : @_ > 1 ? catfile @_ : canonpath getcwd;
85 return bless \$value, ref $class || $class;
86}
87
88sub open {
89 my $self = shift;
90 my $handle = IO::File->new;
91 $handle->open($$self, @_) or croak qq{Can't open file "$$self": $!};
92 return $handle;
93}
94
95sub path { __PACKAGE__->new(@_) }
96
97sub realpath { $_[0]->new(Cwd::realpath ${$_[0]}) }
98
99sub remove_tree {
100 my $self = shift;
101 File::Path::remove_tree $$self, @_;
102 return $self;
103}
104
105sub sibling {
106 my $self = shift;
107 return $self->new(scalar File::Basename::dirname($self), @_);
108}
109
110sub slurp {
111 my $self = shift;
112
113 CORE::open my $file, '<', $$self or croak qq{Can't open file "$$self": $!};
114 my $ret = my $content = '';
115 while ($ret = $file->sysread(my $buffer, 131072, 0)) { $content .= $buffer }
116 croak qq{Can't read from file "$$self": $!} unless defined $ret;
117
118 return $content;
119}
120
121sub spurt {
122 my ($self, $content) = (shift, join '', @_);
123 CORE::open my $file, '>', $$self or croak qq{Can't open file "$$self": $!};
124 ($file->syswrite($content) // -1) == length $content
125 or croak qq{Can't write to file "$$self": $!};
126 return $self;
127}
128
129sub tap { shift->Mojo::Base::tap(@_) }
130
131sub tempdir { __PACKAGE__->new(File::Temp->newdir(@_)) }
132
133sub tempfile { __PACKAGE__->new(File::Temp->new(@_)) }
134
135sub to_abs { $_[0]->new(rel2abs ${$_[0]}) }
136
137sub to_array { [splitdir ${shift()}] }
138
139sub to_rel { $_[0]->new(abs2rel(${$_[0]}, $_[1])) }
140
141sub to_string {"${$_[0]}"}
142
143sub with_roles { shift->Mojo::Base::with_roles(@_) }
144
1451;
146
147=encoding utf8
148
149=head1 NAME
150
151Mojo::File - File system paths
152
153=head1 SYNOPSIS
154
155 use Mojo::File;
156
157 # Portably deal with file system paths
158 my $path = Mojo::File->new('/home/sri/.vimrc');
159 say $path->slurp;
160 say $path->dirname;
161 say $path->basename;
162 say $path->sibling('.bashrc');
163
164 # Use the alternative constructor
165 use Mojo::File 'path';
166 my $path = path('/tmp/foo/bar')->make_path;
167 $path->child('test.txt')->spurt('Hello Mojo!');
168
169=head1 DESCRIPTION
170
171L<Mojo::File> is a scalar-based container for file system paths that provides a
172friendly API for dealing with different operating systems.
173
174 # Access scalar directly to manipulate path
175 my $path = Mojo::File->new('/home/sri/test');
176 $$path .= '.txt';
177
178=head1 FUNCTIONS
179
180L<Mojo::File> implements the following functions, which can be imported
181individually.
182
183=head2 path
184
185 my $path = path;
186 my $path = path('/home/sri/.vimrc');
187 my $path = path('/home', 'sri', '.vimrc');
188 my $path = path(File::Temp->newdir);
189
190Construct a new scalar-based L<Mojo::File> object, defaults to using the current
191working directory.
192
193 # "foo/bar/baz.txt" (on UNIX)
194 path('foo', 'bar', 'baz.txt');
195
196=head2 tempdir
197
198 my $path = tempdir;
199 my $path = tempdir('tempXXXXX');
200
201Construct a new scalar-based L<Mojo::File> object for a temporary directory with
202L<File::Temp>.
203
204 # Longer version
205 my $path = path(File::Temp->newdir('tempXXXXX'));
206
207=head2 tempfile
208
209 my $path = tempfile;
210 my $path = tempfile(DIR => '/tmp');
211
212Construct a new scalar-based L<Mojo::File> object for a temporary file with
213L<File::Temp>.
214
215 # Longer version
216 my $path = path(File::Temp->new(DIR => '/tmp'));
217
218=head1 METHODS
219
220L<Mojo::File> implements the following methods.
221
222=head2 basename
223
224 my $name = $path->basename;
225 my $name = $path->basename('.txt');
226
227Return the last level of the path with L<File::Basename>.
228
229 # ".vimrc" (on UNIX)
230 path('/home/sri/.vimrc')->basename;
231
232 # "test" (on UNIX)
233 path('/home/sri/test.txt')->basename('.txt');
234
235=head2 child
236
237 my $child = $path->child('.vimrc');
238
239Return a new L<Mojo::File> object relative to the path.
240
241 # "/home/sri/.vimrc" (on UNIX)
242 path('/home')->child('sri', '.vimrc');
243
244=head2 copy_to
245
246 my $destination = $path->copy_to('/home/sri');
247 my $destination = $path->copy_to('/home/sri/.vimrc.backup');
248
249Copy file with L<File::Copy> and return the destination as a L<Mojo::File>
250object.
251
252=head2 dirname
253
254 my $name = $path->dirname;
255
256Return all but the last level of the path with L<File::Basename> as a
257L<Mojo::File> object.
258
259 # "/home/sri" (on UNIX)
260 path('/home/sri/.vimrc')->dirname;
261
262=head2 is_abs
263
264 my $bool = $path->is_abs;
265
266Check if the path is absolute.
267
268 # True (on UNIX)
269 path('/home/sri/.vimrc')->is_abs;
270
271 # False (on UNIX)
272 path('.vimrc')->is_abs;
273
274=head2 list
275
276 my $collection = $path->list;
277 my $collection = $path->list({hidden => 1});
278
279List all files in the directory and return a L<Mojo::Collection> object
280containing the results as L<Mojo::File> objects. The list does not include C<.>
281and C<..>.
282
283 # List files
284 say for path('/home/sri/myapp')->list->each;
285
286These options are currently available:
287
288=over 2
289
290=item dir
291
292 dir => 1
293
294Include directories.
295
296=item hidden
297
298 hidden => 1
299
300Include hidden files.
301
302=back
303
304=head2 list_tree
305
306 my $collection = $path->list_tree;
307 my $collection = $path->list_tree({hidden => 1});
308
309List all files recursively in the directory and return a L<Mojo::Collection>
310object containing the results as L<Mojo::File> objects. The list does not
311include C<.> and C<..>.
312
313 # List all templates
314 say for path('/home/sri/myapp/templates')->list_tree->each;
315
316These options are currently available:
317
318=over 2
319
320=item dir
321
322 dir => 1
323
324Include directories.
325
326=item dont_use_nlink
327
328 dont_use_nlink => 1
329
330Force L<File::Find> to always stat directories.
331
332=item hidden
333
334 hidden => 1
335
336Include hidden files and directories.
337
338=back
339
340=head2 make_path
341
342 $path = $path->make_path;
343 $path = $path->make_path({mode => 0711});
344
345Create the directories if they don't already exist, any additional arguments are
346passed through to L<File::Path>.
347
348=head2 move_to
349
350 my $destination = $path->move_to('/home/sri');
351 my $destination = $path->move_to('/home/sri/.vimrc.backup');
352
353Move file with L<File::Copy> and return the destination as a L<Mojo::File>
354object.
355
356=head2 new
357
358 my $path = Mojo::File->new;
359 my $path = Mojo::File->new('/home/sri/.vimrc');
360 my $path = Mojo::File->new('/home', 'sri', '.vimrc');
361 my $path = Mojo::File->new(File::Temp->new);
362 my $path = Mojo::File->new(File::Temp->newdir);
363
364Construct a new L<Mojo::File> object, defaults to using the current working
365directory.
366
367 # "foo/bar/baz.txt" (on UNIX)
368 Mojo::File->new('foo', 'bar', 'baz.txt');
369
370=head2 open
371
372 my $handle = $path->open('+<');
373 my $handle = $path->open('r+');
374 my $handle = $path->open(O_RDWR);
375 my $handle = $path->open('<:encoding(UTF-8)');
376
377Open file with L<IO::File>.
378
379 # Combine "fcntl.h" constants
380 use Fcntl qw(O_CREAT O_EXCL O_RDWR);
381 my $handle = path('/home/sri/test.pl')->open(O_RDWR | O_CREAT | O_EXCL);
382
383=head2 realpath
384
385 my $realpath = $path->realpath;
386
387Resolve the path with L<Cwd> and return the result as a L<Mojo::File> object.
388
389=head2 remove_tree
390
391 $path = $path->remove_tree;
392 $path = $path->remove_tree({keep_root => 1});
393
394Delete this directory and any files and subdirectories it may contain, any
395additional arguments are passed through to L<File::Path>.
396
397=head2 sibling
398
399 my $sibling = $path->sibling('.vimrc');
400
401Return a new L<Mojo::File> object relative to the directory part of the path.
402
403 # "/home/sri/.vimrc" (on UNIX)
404 path('/home/sri/.bashrc')->sibling('.vimrc');
405
406 # "/home/sri/.ssh/known_hosts" (on UNIX)
407 path('/home/sri/.bashrc')->sibling('.ssh', 'known_hosts');
408
409=head2 slurp
410
411 my $bytes = $path->slurp;
412
413Read all data at once from the file.
414
415=head2 spurt
416
417 $path = $path->spurt($bytes);
418 $path = $path->spurt(@chunks_of_bytes);
419
420Write all data at once to the file.
421
422=head2 tap
423
424 $path = $path->tap(sub {...});
425
426Alias for L<Mojo::Base/"tap">.
427
428=head2 to_abs
429
430 my $absolute = $path->to_abs;
431
432Return absolute path as a L<Mojo::File> object, the path does not need to exist
433on the file system.
434
435=head2 to_array
436
437 my $parts = $path->to_array;
438
439Split the path on directory separators.
440
441 # "home:sri:.vimrc" (on UNIX)
442 join ':', @{path('/home/sri/.vimrc')->to_array};
443
444=head2 to_rel
445
446 my $relative = $path->to_rel('/some/base/path');
447
448Return a relative path from the original path to the destination path as a
449L<Mojo::File> object.
450
451 # "sri/.vimrc" (on UNIX)
452 path('/home/sri/.vimrc')->to_rel('/home');
453
454=head2 to_string
455
456 my $str = $path->to_string;
457
458Stringify the path.
459
460=head2 with_roles
461
462 my $new_class = Mojo::File->with_roles('Mojo::File::Role::One');
463 my $new_class = Mojo::File->with_roles('+One', '+Two');
464 $path = $path->with_roles('+One', '+Two');
465
466Alias for L<Mojo::Base/"with_roles">.
467
468=head1 OPERATORS
469
470L<Mojo::File> overloads the following operators.
471
472=head2 array
473
474 my @parts = @$path;
475
476Alias for L</"to_array">.
477
478=head2 bool
479
480 my $bool = !!$path;
481
482Always true.
483
484=head2 stringify
485
486 my $str = "$path";
487
488Alias for L</"to_string">.
489
490=head1 SEE ALSO
491
492L<Mojolicious>, L<Mojolicious::Guides>, L<https://mojolicious.org>.
493
494=cut
Note: See TracBrowser for help on using the repository browser.