File Coverage

blib/lib/Flower/Files.pm
Criterion Covered Total %
statement 34 83 40.9
branch 1 18 5.5
condition 1 8 12.5
subroutine 10 18 55.5
pod 0 8 0.0
total 46 135 34.0


line stmt bran cond sub pod time code
1             package Flower::Files;
2              
3             # a container holding the files for a node
4              
5 1     1   1119 use strict;
  1         2  
  1         27  
6 1     1   5 use warnings;
  1         33  
  1         27  
7              
8 1     1   5 use Data::UUID;
  1         2  
  1         61  
9 1     1   6 use File::Find qw/find/;
  1         2  
  1         46  
10 1     1   5 use Scalar::Util qw/refaddr/;
  1         2  
  1         47  
11 1     1   801 use Time::Duration qw/duration concise/;
  1         1879  
  1         65  
12              
13 1     1   484 use Flower::File;
  1         3  
  1         36  
14              
15 1     1   9 use Carp qw/confess/;
  1         2  
  1         46  
16 1     1   5 use feature qw(say);
  1         2  
  1         852  
17             sub new {
18              
19 1     1 0 4 my $class = shift;
20 1   50     15 my $args = shift || {};
21              
22 1 50       15 confess "called as object method" if ref $class;
23              
24 1         6 my $self = {};
25 1         4 bless $self, __PACKAGE__;
26              
27             # initialise
28 1         9 $self->{files} = [];
29              
30 1         10 return $self;
31             }
32              
33             sub remove {
34 0     0 0   my $self = shift;
35 0           my $file = shift;
36             $self->{files} = [
37             map {
38 0 0         if ( refaddr($_) ne refaddr($file) ) {$_}
  0            
39 0           else { () }
40 0           } @{ $self->{files} }
  0            
41             ];
42 0           return $self;
43             }
44              
45             sub list {
46 0     0 0   my $self = shift;
47 0           return @{ $self->{files} };
  0            
48             }
49              
50             sub count {
51 0     0 0   my $self = shift;
52 0           return scalar @{ $self->{files} };
  0            
53             }
54              
55             sub as_hashref {
56 0     0 0   my $self = shift;
57             return [
58             map {
59 0           { uuid => $_->uuid,
  0            
60             filename => $_->filename,
61             size => $_->size,
62             mtime => $_->mtime,
63             nice_size => $_->nice_size,
64             age => concise( duration( time() - $_->mtime ) )
65             }
66             } $self->list
67             ];
68             }
69              
70             # search our list of files for a file with a particular name
71             sub existing_file_with_filename {
72 0     0 0   my $self = shift;
73 0           my $filename = shift;
74              
75 0           foreach ( @{ $self->{files} } ) {
  0            
76 0 0         return $_ if ( $_->filename eq $filename );
77             }
78 0           return;
79             }
80              
81             sub update_all_in_path {
82 0     0 0   my $self = shift;
83 0           my $path = shift;
84              
85             # first nuke any files that have disappeared or can no
86             # longer be read
87 0           foreach ( @{ $self->{files} } ) {
  0            
88 0 0         $self->remove($_) if ( !-r $_->filename );
89             }
90              
91             # omg I hate File::Find
92             find(
93             { no_chdir => 1,
94             wanted => sub {
95 0     0     my $filename = $_;
96 0 0         return unless -f $filename; # exists
97 0 0         return unless -r $filename; # readable
98 0 0         return if -z $filename; # not zero length
99              
100 0           my $file = $self->existing_file_with_filename($filename);
101 0 0 0       if ( $file && ( $file->mtime == ( stat($filename) )[9] ) ) {
102              
103             # do nothing, it's already on our list
104 0           return;
105             }
106 0 0 0       if ( $file && ( $file->mtime != ( stat($filename) )[9] ) ) {
107              
108             # it's changed, so delete it, and then fall through
109             # to create a new object
110 0           $self->remove($file);
111             }
112              
113 0           $file = Flower::File->new_from_local_file(
114             { parent => $self,
115             filename => $filename,
116             path => $path,
117             }
118             );
119 0           push @{ $self->{files} }, $file;
  0            
120 0           return;
121             },
122             },
123 0           $path
124             );
125 0           return;
126             }
127              
128             sub update_files_from_arrayref {
129 0     0 0   my $self = shift;
130 0           my $ref = shift;
131              
132 0           my @new_files;
133 0           foreach (@$ref) {
134             push @new_files,
135             Flower::File->new(
136             { filename => $_->{filename},
137             size => $_->{size},
138             uuid => $_->{uuid},
139             mtime => $_->{mtime},
140 0           parent => $self,
141             }
142             );
143             }
144              
145             # replace the old with the new
146 0           $self->{files} = [@new_files];
147             }
148              
149             1;