File Coverage

blib/lib/Directory/Organize.pm
Criterion Covered Total %
statement 136 149 91.2
branch 57 78 73.0
condition 22 36 61.1
subroutine 11 11 100.0
pod 6 6 100.0
total 232 280 82.8


line stmt bran cond sub pod time code
1             # vim: set ts=4 sw=4 tw=78 et si:
2              
3             package Directory::Organize;
4              
5 1     1   5663 use strict;
  1         3  
  1         29  
6 1     1   6 use warnings;
  1         2  
  1         26  
7 1     1   439 use version; our $VERSION = qv('v1.0.2');
  1         2031  
  1         5  
8              
9             sub new {
10 1     1 1 11 my $self = shift;
11 1   33     9 my $type = ref($self) || $self;
12              
13 1         3 $self = bless {}, $type;
14 1         5 $self->{basedir} = shift;
15 1         3 $self->set_today();
16              
17 1         3 return $self;
18             } # new();
19              
20             sub get_descriptions {
21 6     6 1 23 my $self = shift;
22              
23 6 50       15 if (!exists $self->{descriptions}) {
24 6         11 $self->_read_descriptions();
25             }
26 6 50       14 return wantarray ? @{$self->{descriptions}} : $self->{descriptions};
  6         30  
27             } # get_descriptions()
28              
29             sub new_dir {
30 3     3 1 15 my ($self,$descr) = @_;
31             my $daydir = sprintf "%4.4d/%2.2d/%2.2d", $self->{tyear}, $self->{tmonth}
32 3         16 , $self->{tday};
33 3         8 my $dirprefix = qq($self->{basedir}/$daydir);
34 3         4 my $suffix = q();
35 3 100       48 if (-d $dirprefix) {
36 1         4 $suffix = 'a';
37 1         19 while (-d qq($dirprefix$suffix)) {
38 0         0 $suffix++;
39             }
40             }
41 3         11 my $path = qq($dirprefix$suffix/);
42 3         6 my $dir = q();
43 3         23 while ($path =~ s{^([^/]*)/}{}) {
44 12 50       37 if ($1) {
45 12         23 $dir .= $1;
46 12 50 66     455 (-d $dir) || mkdir($dir,0777) || return undef;
47 12         83 $dir .= '/';
48             }
49             else {
50 0 0       0 $dir = '/' unless ($dir);
51             }
52             }
53 3         10 my $project = qq($dirprefix$suffix/.project);
54 3 50 33     211 if ($descr and open (my $PROJ,'>',$project)) {
55 3         57 print $PROJ qq($descr\n);
56 3         116 close $PROJ;
57             }
58 3         22 return qq($dirprefix$suffix);
59             } # new_dir()
60              
61             sub set_pattern {
62 2     2 1 197 my ($self,$pattern) = @_;
63              
64             # do nothing with unchanged pattern
65 2 50 66     13 if ($pattern
      33        
66             && defined $self->{pattern}
67             && $self->{pattern} eq $pattern) {
68 0         0 return;
69             }
70 2 50 66     11 if (!$pattern and !defined $self->{pattern}) {
71 0         0 return;
72             }
73 2         4 delete $self->{descriptions};
74 2 100       6 if (!$pattern) {
75 1         2 delete $self->{pattern};
76             }
77             else {
78 1         3 $self->{pattern} = $pattern;
79             }
80             } # set_pattern()
81              
82             sub set_time_constraint {
83 4     4 1 785 my ($self,$op,$year,$month,$day) = @_;
84 4 50 33     27 if (defined $year and $op =~ /^[=<>]$/) {
85 4         14 $self->{tc}->{op} = $op;
86 4         18 $self->{tc}->{year} = sprintf "%04d",$year;
87 4 50       12 $self->{tc}->{month} = sprintf "%02d",$month if (defined $month);
88 4 100       14 $self->{tc}->{day} = sprintf "%02d",$day if (defined $day);
89 4         14 delete $self->{descriptions};
90             }
91             else {
92 0 0       0 if ($self->{tc}) {
93 0         0 delete $self->{descriptions};
94 0         0 delete $self->{tc};
95             }
96             }
97             } # set_time_constraint()
98              
99             sub set_today {
100 7     7 1 806 my $self = shift;
101 7         16 my ($tday,$tmonth,$tyear) = @_;
102 7 100       19 if (defined $tyear) {
103 3         7 $self->{tday} = $tday;
104 3         5 $self->{tmonth} = $tmonth;
105 3         6 $self->{tyear} = $tyear;
106 3         8 return;
107             }
108 4         80 my ($day,$month,$year) = (localtime)[3,4,5];
109 4         13 $year += 1900;
110 4         6 $month += 1;
111 4 100       13 if (defined $tmonth) {
    100          
112 1         3 $self->{tday} = $tday;
113 1         2 $self->{tmonth} = $tmonth;
114 1         3 $self->{tyear} = $year;
115             }
116             elsif (defined $tday) {
117 1         3 $self->{tday} = $tday;
118 1         2 $self->{tmonth} = $month;
119 1         3 $self->{tyear} = $year;
120             }
121             else {
122 2         5 $self->{tday} = $day;
123 2         4 $self->{tmonth} = $month;
124 2         4 $self->{tyear} = $year;
125             }
126 4         10 return;
127             } # set_today()
128              
129             sub _not_in_tc {
130 20     20   50 my ($self,$year,$month,$day) = @_;
131 20         28 my ($tc,$tc_date,$date,$result);
132              
133 20         28 $tc = $self->{tc};
134              
135 20 100       44 if (defined $day) {
    100          
136 8 100       19 if (defined $tc->{day}) {
    50          
137 7         15 $tc_date = $tc->{year} . $tc->{month} . $tc->{day};
138 7         16 $date = $year . $month . substr($day,0,2);
139             }
140             elsif (defined $tc->{month}) {
141 1         3 $tc_date = $tc->{year} . $tc->{month};
142 1         2 $date = $year . $month;
143             }
144             else {
145 0         0 $tc_date = $tc->{year};
146 0         0 $date = $year;
147             }
148             }
149             elsif (defined $month) {
150 8 100       64 if (defined $tc->{day}) {
    50          
151 6         12 $tc_date = $tc->{year} . $tc->{month};
152 6         10 $date = $year . $month;
153 6 100       15 $date++ if ('>' eq $tc->{op});
154 6 100       16 $date-- if ('<' eq $tc->{op});
155             }
156             elsif (defined $tc->{month}) {
157 2         5 $tc_date = $tc->{year} . $tc->{month};
158 2         3 $date = $year . $month;
159             }
160             else {
161 0         0 $tc_date = $tc->{year};
162 0         0 $date = $year;
163             }
164             }
165             else {
166 4 50       9 if (defined $tc->{month}) {
167 4         6 $tc_date = $tc->{year};
168 4         7 $date = $year;
169 4 100       12 $date++ if ('>' eq $tc->{op});
170 4 100       11 $date-- if ('<' eq $tc->{op});
171             }
172             else {
173 0         0 $tc_date = $tc->{year};
174 0         0 $date = $year;
175             }
176             }
177             $result = '<' eq $tc->{op} ? $date ge $tc_date
178 20 100       50 : '>' eq $tc->{op} ? $date le $tc_date
    100          
179             : $date ne $tc_date
180             ;
181 20         88 return $result;
182             } # _not_in_tc()
183              
184             sub _read_descriptions {
185 6     6   10 my $self = shift;
186 6         10 my $base = $self->{basedir};
187 6         11 $self->{descriptions} = [];
188              
189 6 50       178 if (opendir my $BASEDIR, $base) {
190              
191 6         25 my %dirs = map { ("$_" => {}) }
192 6         130 grep { m/^ # match names with
  30         99  
193             \d{4} # four digits
194             $ # exactly
195             /x }
196             readdir( $BASEDIR );
197 6         70 closedir $BASEDIR;
198              
199             YEAR:
200 6         28 for my $year (reverse sort keys %dirs) {
201 6 50 66     26 next if ($self->{tc} && $self->_not_in_tc($year));
202 6 50       143 if (opendir my $YEARDIR, qq($base/$year)) {
203 12         40 my %mdirs = map { ("$_" => {}) }
204 6         97 grep { m/^ # match names with
  24         75  
205             \d{2} # two digits
206             $ # exactly
207             /x }
208             readdir( $YEARDIR );
209 6         20 $dirs{$year} = \%mdirs;
210 6         50 closedir $YEARDIR;
211             }
212              
213             MONTH:
214 6         14 for my $month (reverse sort keys %{$dirs{$year}}) {
  6         37  
215 12 100 100     50 next if ($self->{tc} && $self->_not_in_tc($year,$month));
216 10 50       236 if (opendir my $MONTHDIR, qq($base/$year/$month)) {
217 14         58 my %ddirs = map { ("$_" => {}) }
218 10 100       159 grep { m/^ # match names that start
  34         303  
219             \d{2} # with two digits
220             /x
221             && -d qq($base/$year/$month/$_) }
222             readdir($MONTHDIR);
223 10         30 $dirs{$year}->{$month} = \%ddirs;
224 10         23 close $MONTHDIR;
225             }
226              
227             DAY:
228 10         15 for my $day (reverse sort keys %{$dirs{$year}->{$month}}) {
  10         42  
229             next if ($self->{tc}
230 14 100 100     61 && $self->_not_in_tc($year,$month,$day));
231 13         29 my $path = qq($year/$month/$day);
232 13         18 my $desc = "";
233 13 50 33     575 if (-f qq($base/$path/.project)
234             and open my $PROJECT, '<', qq($base/$path/.project)) {
235 13         201 $desc = <$PROJECT>;
236 13         113 close $PROJECT;
237 13         33 chomp $desc;
238             }
239 13 100 100     54 if ($self->{pattern} && $desc !~ /$self->{pattern}/i) {
240 2         22 next;
241             }
242 11         17 push @{$self->{descriptions}}, [ $path, $desc ];
  11         137  
243             }
244             }
245             }
246             }
247 6         20 return;
248             } # _read_descriptions();
249              
250             1;
251              
252             __END__