File Coverage

blib/lib/File/Stat/Trigger.pm
Criterion Covered Total %
statement 1 3 33.3
branch n/a
condition n/a
subroutine 1 1 100.0
pod n/a
total 2 4 50.0


line stmt bran cond sub pod time code
1             package File::Stat::Trigger;
2              
3 2     2   974 use Moose;
  0            
  0            
4             use Moose::Util::TypeConstraints;
5              
6             use File::Stat::OO;
7             use Class::Trigger;
8             use DateTime;
9             use DateTime::Format::DateParse;
10              
11             our $VERSION = '0.05';
12              
13             subtype 'FileStat'
14             => as 'Object'
15             => where { $_->isa('File::Stat::OO') };
16              
17             coerce 'FileStat'
18             => from 'Str',
19             => via { File::Stat::OO->new({ file => $_ }) };
20              
21             subtype 'DateTime'
22             => as 'Object'
23             => where { $_->isa('DateTime') };
24            
25             coerce 'DateTime'
26             => from 'Str'
27             => via { DateTime::Format::DateParse->parse_datetime($_) };
28              
29             has 'file_stat' => (is => 'rw', isa => 'FileStat', coerce => 1);
30              
31             has [ qw<check_atime check_mtime check_ctime> ] =>
32             ( is => 'rw', isa => 'ArrayRef', default => sub { ['!='] } );
33              
34             has [ qw<_atime _mtime _ctime> ] =>
35             ( is => 'rw', isa => 'DateTime', coerce => 1);
36              
37             has 'check_size' => ( is => 'rw', isa => 'ArrayRef', default => sub { ['!='] } );
38              
39             has '_size' => ( is => 'rw', isa => 'Int');
40              
41             has 'auto_stat' => ( is => 'rw', isa => 'Int', default => 0);
42              
43             has 'file' => ( is => 'rw', isa => 'Str');
44              
45             sub BUILD {
46             my ($self) = @_;
47             $self->init_stat();
48             }
49              
50             sub init_stat {
51             my ( $self ) = @_;
52              
53             $self->file_stat(File::Stat::OO->new({ file => $self->file }));
54              
55             $self->file_stat->use_datetime(1);
56             $self->file_stat->stat();
57              
58             $self->_atime( $self->file_stat->atime );
59             $self->_mtime( $self->file_stat->mtime );
60             $self->_ctime( $self->file_stat->ctime );
61             $self->_size( $self->file_stat->size );
62              
63             $self->_atime( $self->check_atime->[1] )
64             if $self->check_atime && $self->check_atime->[1];
65              
66             $self->_mtime( $self->check_mtime->[1] )
67             if $self->check_mtime && $self->check_mtime->[1];
68              
69             $self->_ctime( $self->check_ctime->[1] )
70             if $self->check_ctime && $self->check_ctime->[1];
71              
72             $self->_size( $self->check_size->[1] )
73             if $self->check_size && $self->check_size->[1];
74              
75             return;
76             }
77              
78             sub run {
79             my ($self, $time ) = @_;
80             $time ||= 5;
81             while (1) {
82             $self->scan();
83             sleep($time);
84             }
85             }
86              
87             sub scan {
88             my ($self) = @_;
89             my $fs = $self->file_stat;
90              
91             my $result;
92              
93             # init
94             for ( qw( size_trigger atime_trigger mtime_trigger ctime_trigger ) ){
95             $result->{$_} = 0;
96             }
97              
98             $fs->use_datetime(1);
99             $fs->stat($self->file);
100              
101             if ( $self->check_size && $self->_judge($fs->size, [$self->check_size->[0],$self->_size]) ) {
102             $result->{size_trigger} = $self->call_trigger('size_trigger',$self);
103             $self->_size($fs->size) if ( $self->auto_stat );
104             }
105              
106             for my $st_time ( qw(atime mtime ctime) ) {
107             my $method = 'check_'.$st_time;# check_atime or check_mtime or check_ctime
108             my $_time = '_'.$st_time;# _atime or _mtime or _ctime
109              
110             if ( $self->$method &&
111             $self->_judge($fs->$st_time->epoch, [$self->$method->[0], $self->$_time->epoch] ) ) {
112             $result->{$st_time.'_trigger'} = $self->call_trigger($st_time.'_trigger',$self);
113              
114             $self->$_time($fs->$st_time) if ( $self->auto_stat );
115             }
116             }
117              
118             return $result;
119             }
120              
121             sub size_trigger {
122             my ($self, $code, $check_size) = @_;
123             $self->check_size($check_size) if $check_size;
124             $self->_trigger('size_trigger', $code);
125             }
126              
127             sub atime_trigger {
128             my ($self, $code, $_check_atime) = @_;
129             if ( $_check_atime ) {
130             $self->check_atime($_check_atime);
131             $self->_atime($_check_atime->[1]);
132             }
133             $self->_trigger('atime_trigger', $code);
134             }
135              
136             sub mtime_trigger {
137             my ($self, $code, $_check_mtime) = @_;
138             if ( $_check_mtime ) {
139             $self->check_mtime($_check_mtime);
140             $self->_mtime($_check_mtime->[1]);
141             }
142             $self->_trigger('mtime_trigger', $code);
143             }
144              
145             sub ctime_trigger {
146             my ($self, $code, $_check_ctime) = @_;
147             if ( $_check_ctime ) {
148             $self->check_atime($_check_ctime);
149             $self->_ctime($_check_ctime->[1]);
150             }
151             $self->_trigger('ctime_trigger', $code);
152             }
153              
154             sub _trigger {
155             my ($self, $type, $code) = @_;
156             $self->add_trigger($type,$code);
157             }
158              
159             sub _judge {
160             my ($self, $value, $op) = @_;
161              
162             return unless $op;
163              
164             my $code = "$value $op->[0] $op->[1]";
165              
166             if ( eval $code ) {
167             return 1;
168             }
169              
170             return;
171             }
172              
173             1;
174             __END__
175              
176             =head1 NAME
177              
178             File::Stat::Trigger - The module to monitor the status of file.
179              
180             =head1 SYNOPSIS
181              
182             use File::Stat::Trigger;
183              
184             my $file = 'sample.txt';
185             my $fs = File::Stat::Trigger->new({
186             file => $file,
187             check_atime => ['>=','2008/12/1 12:00:00'],
188             check_ctime => ['>='],
189             check_mtime => ['==', '2008/12/1 12:00:00'],
190             check_size => ['!=',1024],
191             auto_stat => 1,
192             });
193            
194             $fs->size_trigger( sub {
195             my $self = shift;
196             my $i = $self->file_stat->size;
197             } );
198            
199             $fs->atime_trigger(\&sample);
200             $fs->ctime_trigger(\&sample);
201             # $fs->ctime_trigger(\&sample,['!=', '2008/12/1 12:00:00']);
202             $fs->mtime_trigger(\&sample);
203             # $fs->mtime_trigger(\&sample,['!=', '2008/12/1 12:00:00']);
204            
205             my $result = $fs->scan();
206            
207             $result->{size_trigger};# 1
208             $result->{atime_trigger};# 1
209             $result->{ctime_trigger};# 0
210             $result->{mtime_trigger};# 0
211              
212             # This function execute 'scan()' in three interval.
213             $result = $fs->run(3);
214              
215             =head1 DESCRIPTION
216              
217             This module executes the registered function
218             when the stat of file changed and matched parameter.
219              
220             =head1 METHODS
221              
222             =over 4
223              
224             =item new({file=>'filename'...})
225              
226             Set file name, file parameter.
227              
228             =item size_trigger
229              
230             Register size trigger. Set file parameter.
231              
232             =item atime_trigger
233              
234             Register atime trigger. Set file parameter.
235              
236             =item ctime_trigger
237              
238             Register ctime trigger. Set file parameter.
239              
240             =item mtime_trigger
241              
242             Register mtime trigger. Set file parameter.
243              
244             =item scan
245              
246             Scan file stat.
247              
248             =item run(second)
249              
250             This function execute 'scan()' in any interval.
251              
252             =back
253              
254             =head1 AUTHOR
255              
256             Akihito Takeda E<lt>takeda.akihito@gmail.comE<gt>
257              
258             =head1 LICENSE
259              
260             This library is free software; you can redistribute it and/or modify
261             it under the same terms as Perl itself.
262              
263             =cut