File Coverage

blib/lib/ZConf/Cron.pm
Criterion Covered Total %
statement 21 210 10.0
branch 0 70 0.0
condition 0 3 0.0
subroutine 7 18 38.8
pod 11 11 100.0
total 39 312 12.5


line stmt bran cond sub pod time code
1             package ZConf::Cron;
2              
3 2     2   56865 use DateTime::Event::Cron;
  2         962310  
  2         74  
4 2     2   26 use DateTime::Duration;
  2         6  
  2         48  
5 2     2   8537 use DateTime::Format::Strptime;
  2         21967  
  2         200  
6 2     2   4101 use ZConf;
  2         444887  
  2         100  
7 2     2   30 use warnings;
  2         4  
  2         77  
8 2     2   12 use strict;
  2         4  
  2         124  
9 2     2   12 use base 'Error::Helper';
  2         5  
  2         4295  
10              
11             =head1 NAME
12              
13             ZConf::Cron - Handles storing cron tabs in ZConf.
14              
15             =head1 VERSION
16              
17             Version 2.0.0
18              
19             =cut
20              
21             our $VERSION = '2.0.0';
22              
23             =head1 SYNOPSIS
24              
25             use ZConf::Cron;
26              
27             my $zccron = ZConf::Cron->new;
28             if($zccron->error){
29             warn('Error:'.$zccron->error.': '.$zccron->errorString);
30             }
31            
32             $zccron->runTab( $tab );
33             if($zccron->error){
34             warn('Error:'.$zccron->error.': '.$zccron->errorString);
35             }
36              
37             =head1 METHODS
38              
39             =head2 new
40              
41             Initiates the module. No arguements are currently taken.
42              
43             my $zccron = ZConf::Cron->new;
44             if($zccron->error){
45             warn('Error:'.$zccron->error.': '.$zccron->errorString);
46             }
47              
48             =cut
49              
50             sub new{
51 0     0 1   my $self={
52             error=>undef,
53             perror=>undef,
54             errorString=>'',
55             zconfconfig=>'zccron',
56             };
57 0           bless $self;
58              
59 0           $self->{zconf}=ZConf->new();
60 0 0         if(defined($self->{zconf}->error)){
61 0           $self->{error}=1;
62 0           $self->{perror}=1;
63 0           $self->{errorString}="Could not initiate ZConf. It failed with '"
64             .$self->{zconf}->error."', '".$self->{zconf}->errorString."'";
65 0           $self->warn;
66 0           return $self;
67             }
68              
69             #sets $self->{init} to a Perl boolean value...
70             #true=config does exist
71             #false=config does not exist
72 0 0         if (!$self->{zconf}->configExists("zccron")){
73 0           $self->{init}=undef;
74             }else {
75 0           $self->{init}=1;
76             }
77              
78 0 0         if ( ! $self->{init} ){
79 0           $self->init;
80 0 0         if ( $self->error ){
81 0           $self->{perror}=1;
82 0           return undef;
83             }
84             }
85              
86 0           $self->{zconf}->read( {config=>$self->{'zconfconfig'}} );
87 0 0         if ( $self->{zconf}->error ){
88 0           $self->{perror}=1;
89 0           $self->{error}=3;
90 0           $self->{errorString}='Failed to initialize ';
91 0           $self->warn;
92 0           return $self;
93             }
94              
95 0           return $self;
96             }
97              
98             =head2 delSet
99              
100             This deletes a set.
101              
102             $zccron->delSet('someSet');
103             if($zccron->error){
104             warn('Error:'.$zccron->error.': '.$zccron->errorString);
105             }
106              
107             =cut
108              
109             sub delSet{
110 0     0 1   my $self=$_[0];
111 0           my $set=$_[1];
112              
113 0 0         if ( ! $self->errorblank ){
114 0           return undef;
115             }
116              
117 0           $self->{zconf}->delSet( $self->{'zconfconfig'} ,$set);
118 0 0         if ($self->{zconf}->error){
119 0           $self->{errorString}='Failed to delete set. set="'.$set.
120             '" error="'.$self->{zconf}->error.
121             '" errorString="'.$self->{zconf}->errorString.'"';
122 0           $self->{error}=10;
123 0           $self->warn;
124 0           return undef;
125             }
126              
127 0           return 1;
128             }
129              
130             =head2 delTab
131              
132             This removes a tab.
133              
134             One arguement is taken and that is the tab to delete.
135              
136             $zccron->delTab('someTab');
137             if($zccron->error){
138             warn('Error:'.$zccron->error.': '.$zccron->errorString);
139             }
140              
141             =cut
142              
143             sub delTab{
144 0     0 1   my $self=$_[0];
145 0           my $tab=$_[1];
146              
147 0 0         if ( ! $self->errorblank ){
148 0           return undef;
149             }
150              
151 0           $self->{zconf}->regexVarDel( $self->{'zconfconfig'} , '^tabs\/'.quotemeta($tab).'$');
152 0 0         if ($self->{zconf}->error) {
153 0           $self->{errorString}='Failed to delete tab, "'.$tab.'" error="'
154             .$self->{zconf}->error.'" errorString="'.$self->{zconf}->errorString.'"';
155 0           $self->{error}=11;
156 0           $self->warn;
157 0           return undef;
158             }
159              
160 0           my $returned=$self->{zconf}->writeSetFromLoadedConfig(
161             {
162             config=>$self->{'zconfconfig'}
163             }
164             );
165 0 0         if ($self->{zconf}->error){
166 0           $self->{errorString}='Failed to save the ZConf config.'.
167             '" error="'.$self->{zconf}->error.
168             '" errorString="'.$self->{zconf}->errorString.'"';
169 0           $self->{error}=7;
170 0           $self->warn;
171 0           return undef;
172             }
173              
174 0           return 1;
175             }
176              
177             =head2 getTab
178              
179             Gets a specified tab.
180              
181             my $tab=zccron->readTab("sometab");
182             if($zccron->error){
183             warn('Error:'.$zccron->error.': '.$zccron->errorString);
184             }
185              
186             =cut
187              
188             sub getTab{
189 0     0 1   my $self=$_[0];
190 0           my $tab=$_[1];
191              
192 0 0         if ( ! $self->errorblank ){
193 0           return undef;
194             }
195              
196 0           $tab='tabs/'.$tab;
197              
198             #errors if the tab is not defined
199 0           my $tabdata=$self->{zconf}->getVar( $self->{'zconfconfig'}, $tab );
200 0 0         if (!defined( $tabdata )){
201 0           $self->{errorString}='The tab "'.$tab.'" is not defined';
202 0           $self->{error}=5;
203 0           $self->warn;
204 0           return undef;
205             }
206              
207 0           return $tabdata;
208             }
209              
210             =head2 init
211              
212             Initializes a specified set.
213              
214             If no set is specified, the default is used.
215              
216             $zccron->init('someSet');
217             if($zccron->error){
218             warn('Error:'.$zccron->error.': '.$zccron->errorString);
219             }
220              
221             =cut
222              
223             sub init{
224 0     0 1   my $self=$_[0];
225 0           my $set=$_[1];
226              
227 0 0         if ( ! $self->errorblank ){
228 0           return undef;
229             }
230              
231             #checks if it exists
232 0           my $configExists = $self->{zconf}->configExists($self->{'zconfconfig'});
233              
234             #creates the config if needed
235 0 0         if (!$configExists){
236 0           $self->{zconf}->createConfig($self->{'zconfconfig'});
237 0 0         if( $self->{zconf}->error ){
238 0           $self->{errorString}='Failed to create the ZConf config "zccron"';
239 0           $self->{error}=8;
240 0           $self->warn;
241 0           return undef;
242             }
243             }
244              
245 0           my $returned=$self->{zconf}->writeSetFromHash({config=>$self->{'zconfconfig'}, set=>$set},{});
246 0 0         if ($self->{zconf}->error){
247 0           $self->{errorString}='Failed to create set. set="'.$set.
248             '" error="'.$self->{zconf}->error.
249             '" errorString="'.$self->{zconf}->errorString.'"';
250 0           $self->{error}=9;
251 0           $self->warn;
252 0           return undef;
253             }
254              
255 0           return 1;
256             }
257              
258             =head2 listSets
259              
260             This gets a list of of sets for the config 'cron'.
261              
262             my @sets=$zccron->getSets;
263             if($zccron->error){
264             warn('Error:'.$zccron->error.': '.$zccron->errorString);
265             }
266              
267             =cut
268              
269             sub listSets{
270 0     0 1   my $self=$_[0];
271 0           my $function='getSets';
272              
273 0           $self->errorblank();
274 0 0         if ($self->{error}) {
275 0           warn($self->{module}.' '.$function.': A permanent error is set');
276 0           return undef;
277             }
278              
279 0           my @sets=$self->{zconf}->getAvailableSets( $self->{'zconfconfig'} );
280 0 0         if ($self->{zconf}->error){
281 0           $self->{errorString}='ZConf->getAvailableSets errored error="'.$self->{zconf}->error.
282             '" errorString="'.$self->{zconf}->errorString.'"';
283 0           $self->{error}=4;
284 0           $self->warn;
285 0           return undef;
286             };
287              
288 0           return @sets;
289             }
290              
291             =head2 listTabs
292              
293             Gets a list of tabs for the current set.
294              
295             my @tabs=$zccron->listTabs();
296             if($zccron->error){
297             warn('Error:'.$zccron->error.': '.$zccron->errorString);
298             }
299              
300             =cut
301              
302             sub listTabs{
303 0     0 1   my $self=$_[0];
304              
305 0 0         if ( ! $self->errorblank ){
306 0           return undef;
307             }
308              
309 0           my @matched = $self->{zconf}->regexVarSearch( $self->{'zconfconfig'} , "^tabs\/");
310              
311 0           my $matchedInt=0;
312 0           while (defined($matched[$matchedInt])){
313 0           $matched[$matchedInt]=~s/^tabs\///;
314 0           $matchedInt++;
315             }
316              
317 0           return @matched;
318             }
319              
320             =head2 runTab
321              
322             This runs the specified tab.
323              
324             One option is taken and that is the specified tab.
325              
326             $zccron->runTab( $tab );
327             if ( $zccron->error ){
328             warn('Error:'.$zccron->error.': '.$zccron->errorString);
329             }
330              
331             =cut
332              
333             sub runTab{
334 0     0 1   my $self=$_[0];
335 0           my $tabName=$_[1];
336              
337 0 0         if ( ! $self->errorblank ){
338 0           return undef;
339             }
340              
341 0 0         if($self->{zconf}->varNameCheck($tabName)){
342 0           $self->{errorString}="'".$tabName."' is not a legit ZConf variable name";
343 0           $self->{error}=2;
344 0           $self->warn;
345 0           return undef;
346             }
347              
348 0           my $tab=$self->getTab( $tabName );
349 0 0         if ( $self->error ){
350 0           $self->warnString('getTab errored');
351 0           return undef;
352             }
353              
354             #splits the lines apart
355 0           my @lines=split(/\n/, $tab);
356              
357             #runs each line
358 0           my $linesInt=0;
359 0           while (defined($lines[$linesInt])){
360 0 0         if (!($lines[$linesInt] =~ /^#/)){
361              
362 0           my $cronline=$lines[$linesInt];
363 0           my $now=DateTime->now;#get the time
364            
365 0           my $dtc = DateTime::Event::Cron->new_from_cron($cronline);
366 0           my $next_datetime_string = $dtc->next;
367 0           my $last_datetime_string = $dtc->previous;
368            
369             #takes the strings and make DateTime objects out of them.
370 0           my $time_string_parse= new DateTime::Format::Strptime(pattern=>'%FT%T');
371 0           my $dt_last=$time_string_parse->parse_datetime($last_datetime_string);
372 0           my $dt_next=$time_string_parse->parse_datetime($next_datetime_string);
373            
374             #check to make sure last or next is within a minute and 15 seconds of now.
375 0           my $interval = DateTime::Duration->new(minutes => 1);
376              
377             #if it falls within 1 minute and 15 secons of now, it runs it
378 0 0 0       if (
379             $self->within_interval($dt_last, $now, $interval) ||
380             $self->within_interval($dt_next, $now, $interval)
381             ){
382 0           system($dtc->command);
383             }
384              
385             }
386              
387 0           $linesInt++;
388             }
389              
390 0           return 1;
391             }
392              
393             =head2 setSet
394              
395             Sets what set is being worked on. It will also read it when this is called.
396              
397             $zccron->setSet('someSet');
398             if($zccron->error){
399             warn('Error:'.$zccron->error.': '.$zccron->errorString);
400             }
401              
402             =cut
403              
404             sub setSet{
405 0     0 1   my $self=$_[0];
406 0           my $set=$_[1];
407              
408 0 0         if ( ! $self->errorblank ){
409 0           return undef;
410             }
411              
412 0 0         if (!defined($set)){
413 0           my $set=$self->{zconf}->chooseSet( $self->{'zconfconfig'} );
414             }
415              
416 0 0         if(!$self->{zconf}->setNameLegit($set)){
417 0           $self->{errorString}="'".$set."' is not a legit ZConf set name";
418 0           $self->{error}=2;
419 0           $self->warn;
420 0           return undef;
421             }
422              
423 0           $self->{zconf}->read(
424             {
425             config=>$self->{'zconfconfig'},
426             set=>$set
427             }
428             );
429 0 0         if($self->{zconf}->error){
430 0           $self->{errorString}="Could not read config. set='".$set."'. error='"
431             .$self->{zconf}->error."' errorString='".$self->{zconf}->errorString."'";
432 0           $self->{error}=3;
433 0           $self->error;
434 0           return undef;
435             }
436              
437 0           return 1;
438             }
439              
440             =head2 setTab
441              
442             Saves a tab. The return is a Perl boolean value.
443              
444             Two values are required. The first one is the name of the tab.
445             The second one is the value of the tab.
446              
447             $zccron->setTab("someTab", $tabValuexs);
448             if($zccron->error){
449             warn('Error:'.$zccron->error.': '.$zccron->errorString);
450             }
451              
452             =cut
453              
454             sub setTab{
455 0     0 1   my $self=$_[0];
456 0           my $tab=$_[1];
457 0           my $value=$_[2];
458              
459 0 0         if ( ! $self->errorblank ){
460 0           return undef;
461             }
462              
463 0 0         if (!defined($value)){
464 0           $self->{errorString}="No value specified for the value of the tab.";
465 0           $self->{error}=6;
466 0           $self->warn;
467 0           return undef;
468             }
469              
470 0 0         if($self->{zconf}->varNameCheck($tab)){
471 0           $self->{errorString}="'".$tab."' is not a legit ZConf variable name";
472 0           $self->{error}=2;
473 0           $self->warn;
474 0           return undef;
475             }
476              
477             #$self->{zconf}->{conf}{zccron}{'tabs/'.$tab}=$value;
478 0           $tab='tabs/'.$tab;
479 0           $self->{zconf}->setVar('zccron', $tab , $value);
480 0 0         if ($self->{zconf}->error) {
481 0           $self->{error}=12;
482 0           $self->{errorString}='setVar failed. error="'.$self->{zconf}->error.'" errorString="'.$self->errorString.'"';
483 0           $self->warn;
484 0           return undef;
485             }
486              
487             #saves it
488 0           $self->{zconf}->writeSetFromLoadedConfig({config=>'zccron'});
489 0 0         if ($self->{zconf}->error){
490 0           $self->{error}=10;
491 0           $self->{errorString}='setVar failed. error="'.$self->{zconf}->error.'" errorString="'.$self->errorString.'"';
492 0           $self->warn;
493 0           return undef;
494             }
495              
496 0           print "saved\n";
497              
498 0           return 1;
499             }
500              
501             =head2 within_interval
502              
503             This is a internal sub.
504              
505             =cut
506              
507             sub within_interval {
508 0     0 1   my ($self, $dt1, $dt2, $interval) = @_;
509            
510             # Make sure $dt1 is less than $dt2
511 0 0         ($dt1, $dt2) = ($dt2, $dt1) if $dt1 > $dt2;
512            
513             # If the older date is more recent than the newer date once we
514             # subtract the interval then the dates are closer than the
515             # interval
516 0 0         if ($dt2 - $interval < $dt1) {
517 0           return 1;
518             } else {
519 0           return 0;
520             }
521             }
522              
523             =head1 ZConf Keys
524              
525             The keys for this are stored in the config 'zccron'.
526              
527             =head2 tabs/
528              
529             Any thing under tabs is considered a tab.
530              
531             =head1 ERROR CODES/HANDLING
532              
533             Error handling is provided by L.
534              
535             =head2 1
536              
537             Failed to intiate ZConf.
538              
539             =head2 2
540              
541             Illegal set name specified.
542              
543             =head2 3
544              
545             Could not read the ZConf config 'zccron'.
546              
547             =head2 4
548              
549             Failed to get the available sets for 'zccron'.
550              
551             =head2 5
552              
553             No tab specified.
554              
555             =head2 6
556              
557             No value for the tab specified.
558              
559             =head2 7
560              
561             Saving the ZConf config failed.
562              
563             =head2 8
564              
565             Failed to create the ZConf config 'zccron'.
566              
567             =head2 9
568              
569             Failed to create set.
570              
571             =head2 10
572              
573             Failed to delete the set.
574              
575             =head2 11
576              
577             Failed to delete the tab.
578              
579             =head2 12
580              
581             Failed to write the tab to ZConf.
582              
583             =head1 AUTHOR
584              
585             Zane C. Bowers, C<< >>
586              
587             =head1 BUGS
588              
589             Please report any bugs or feature requests to C, or through
590             the web interface at L. I will be notified, and then you'll
591             automatically be notified of progress on your bug as I make changes.
592              
593             =head1 SUPPORT
594              
595             You can find documentation for this module with the perldoc command.
596              
597             perldoc ZConf::Cron
598              
599              
600             You can also look for information at:
601              
602             =over 4
603              
604             =item * RT: CPAN's request tracker
605              
606             L
607              
608             =item * AnnoCPAN: Annotated CPAN documentation
609              
610             L
611              
612             =item * CPAN Ratings
613              
614             L
615              
616             =item * Search CPAN
617              
618             L
619              
620             =item * SVN
621              
622             L
623              
624             =back
625              
626              
627             =head1 ACKNOWLEDGEMENTS
628              
629              
630             =head1 COPYRIGHT & LICENSE
631              
632             Copyright 2012 Zane C. Bowers, all rights reserved.
633              
634             This program is free software; you can redistribute it and/or modify it
635             under the same terms as Perl itself.
636              
637              
638             =cut
639              
640             1; # End of ZConf::Cron