Browse Source

EntryStore: Add methods for further slicing entry list

Including:

  - children() - get immediate children of entry
  - parent($entry) - get immediate parent of entry
  - days_for($container) - get days in a month or year
  - months_for($year) - get months contained in a year
  - basename($entry) - get basename of an entry

These are used in App::WRT::year() and App::WRT::month(), replacing
some dir_list() invocations and at least somewhat simplifying the code.
Brennen Bearnes 1 month ago
parent
commit
bb32d648c7
6 changed files with 144 additions and 42 deletions
  1. 1
    0
      example/archives/1952/2/13
  2. 24
    23
      lib/App/WRT.pm
  3. 49
    5
      lib/App/WRT/EntryStore.pm
  4. 3
    3
      t/bin-wrt-ls.t
  5. 2
    0
      t/wrt.t
  6. 65
    11
      t/wrt_entrystore.t

+ 1
- 0
example/archives/1952/2/13 View File

@@ -0,0 +1 @@
1
+<p>I still miss you.</p>

+ 24
- 23
lib/App/WRT.pm View File

@@ -1,6 +1,6 @@
1 1
 package App::WRT;
2 2
 
3
-use version; our $VERSION = version->declare("v6.1.0");
3
+use version; our $VERSION = version->declare("v6.2.0");
4 4
 
5 5
 use strict;
6 6
 use warnings;
@@ -623,7 +623,6 @@ sub year {
623 623
   return p('No such year.')
624 624
     unless $self->{entries}->is_dir($year);
625 625
 
626
-  my ($year_file, $year_url) = $self->root_locations($year);
627 626
   my $result;
628 627
 
629 628
   # Handle year directories with index files:
@@ -635,28 +634,30 @@ sub year {
635 634
 
636 635
   $result .= heading("${header_text}${year}", 3);
637 636
 
638
-  my @months = dir_list($year_file, 'high_to_low', qr/^[0-9]{1,2}$/);
637
+  my @months = reverse $self->{entries}->months_for($year);
639 638
 
640 639
   my $year_text;
641 640
   my $count = 0; # explicitly defined for later printing.
642 641
 
643 642
   foreach my $month (@months) {
644 643
     my $month_text = '';
645
-    if ($self->{entries}->is_dir("$year/$month")) {
646
-      my @entries = dir_list(
647
-        "$year_file/$month", 'low_to_high', qr/^[0-9]{1,2}$/
648
-      );
649
-      $count += @entries;
650
-      foreach my $entry (@entries) {
651
-        $month_text .= a({href => "$year_url/$month/$entry/"}, $entry) . "\n";
652
-      }
644
+    my @days = $self->{entries}->days_for($month);
645
+    $count += @days;
646
+
647
+    foreach my $day (@days) {
648
+      my ($day_file, $day_url) = $self->root_locations($day);
649
+      $month_text .= a(
650
+        { href => "${day_url}/" },
651
+        $self->{entries}->basename($day)
652
+      ) . "\n";
653 653
     }
654 654
 
655 655
     $month_text = small("( $month_text )");
656 656
 
657
+    my ($month_file, $month_url) = $self->root_locations($month);
657 658
     my $link = a(
658
-      {href => "$year_url/$month/"},
659
-      App::WRT::Date::month_name($month)
659
+      { href => "${month_url}/" },
660
+      App::WRT::Date::month_name($self->{entries}->basename($month))
660 661
     );
661 662
 
662 663
     $year_text .= table_row(
@@ -690,21 +691,22 @@ sub month {
690 691
 
691 692
   my ($month_file, $month_url) = $self->root_locations($month);
692 693
 
693
-  # If a directory exists for $month, use dir_list to slurp the entry files it
694
-  # contains into @entry_files, sorted numerically.  Then send each entry to
695
-  # entry_markup().
694
+  # If $month is a directory, render those of its children with day-like names:
696 695
   if ($self->{entries}->is_dir($month)) {
697 696
     my $result;
698
-    $result .= $self->entry($month)
697
+    $result = $self->entry($month)
699 698
       if $self->{entries}->has_index($month);
700 699
 
701
-    my @entry_files = dir_list($month_file, 'high_to_low', qr/^[0-9]{1,2}$/);
702
-    foreach my $entry_file (@entry_files) {
703
-      $result .= $self->entry_stamped("$month/$entry_file");
700
+    my @days = reverse $self->{entries}->days_for($month);
701
+
702
+    foreach my $day (@days) {
703
+      $result .= $self->entry_stamped($day);
704 704
     }
705 705
 
706 706
     return $result;
707 707
   } elsif ($self->{entries}->is_file($month)) {
708
+    # If $month is a file, it should just be rendered as a regular entry, more
709
+    # or less:
708 710
     return $self->entry($month);
709 711
   }
710 712
 }
@@ -748,8 +750,7 @@ sub entry_topic_list {
748 750
 
749 751
 =item entry($entry)
750 752
 
751
-Returns the contents of a given entry. Calls dir_list and icon_markup.
752
-Recursively calls itself.
753
+Returns the contents of a given entry.  May recurse, slightly.
753 754
 
754 755
 =cut
755 756
 
@@ -958,7 +959,7 @@ sub fragment_slurp {
958 959
 
959 960
 =item root_locations($file)
960 961
 
961
-Given a file/entry, return the appropriate concatenations with entry_dir and
962
+Given an entry, return the appropriate concatenations with entry_dir and
962 963
 url_root.
963 964
 
964 965
 =cut

+ 49
- 5
lib/App/WRT/EntryStore.pm View File

@@ -189,6 +189,23 @@ sub all_years  { return $_[0]->dates_by_depth(1); }
189 189
 sub all_months { return $_[0]->dates_by_depth(2); }
190 190
 sub all_days   { return $_[0]->dates_by_depth(3); }
191 191
 
192
+=item days_for($month), months_for($year)
193
+
194
+Convenience wrappers for extracting days or months in a given month
195
+or year.
196
+
197
+=cut
198
+
199
+sub days_for {
200
+  my ($self, $container) = @_;
201
+  return grep { m{^ \Q$container\E / }x } $self->all_days();
202
+}
203
+
204
+sub months_for {
205
+  my ($self, $year) = @_;
206
+  return grep { m{^ \Q$year\E / }x } $self->all_months();
207
+}
208
+
192 209
 =item recent_by_depth($depth, $entry_count)
193 210
 
194 211
 Returns the $entry_count most recent dated entries at $depth (1 for year, 2 for
@@ -263,20 +280,18 @@ sub generate_date_hashes {
263 280
   $self->{next_dates} = { reverse %prev };
264 281
 }
265 282
 
266
-=item parent_of($entry)
283
+=item parent($entry)
267 284
 
268 285
 Return an entry's parent, or undef if it's at the top level.
269 286
 
270 287
 =cut
271 288
 
272
-sub parent_of {
289
+sub parent {
273 290
   my $self = shift;
274 291
   my ($entry) = @_;
275 292
 
276 293
   # Explode unless an entry actually exists in the archives:
277
-  unless (grep { $_ eq $entry } $self->all()) {
278
-    croak("No such entry: $entry");
279
-  }
294
+  croak("No such entry: $entry") unless $self->is_extant($entry);
280 295
 
281 296
   my (@components) = split '/', $entry;
282 297
   pop @components;
@@ -286,6 +301,23 @@ sub parent_of {
286 301
   return undef;
287 302
 }
288 303
 
304
+=item children($entry)
305
+
306
+Return an entry's (immediate) children.
307
+
308
+=cut
309
+
310
+sub children {
311
+  my $self = shift;
312
+  my ($entry) = @_;
313
+
314
+  # Explode unless an entry actually exists in the archives:
315
+  croak("No such entry: $entry") unless $self->is_extant($entry);
316
+
317
+  # A cheesy regexp solution to this problem:
318
+  return grep { m{^ \Q$entry\E / [^/]+ $}x } $self->all();
319
+}
320
+
289 321
 =item previous($entry)
290 322
 
291 323
 Return the previous entry at the same depth for the given entry.
@@ -413,6 +445,18 @@ sub has_index {
413 445
   return $self->is_extant($entry . '/index');
414 446
 }
415 447
 
448
+=item basename($entry)
449
+
450
+Get a base name (i.e., filename without path) for a given entry.
451
+
452
+=cut
453
+
454
+sub basename {
455
+  my ($self, $entry) = @_;
456
+  my @parts = split '/', $entry;
457
+  return pop @parts; 
458
+}
459
+
416 460
 =back
417 461
 
418 462
 =cut

+ 3
- 3
t/bin-wrt-ls.t View File

@@ -21,7 +21,7 @@ my $output = sub {
21 21
 my @local_argv = qw(--years);
22 22
 main($output, @local_argv);
23 23
 ok(
24
-  $output_string eq "2012\n2013\n2014\n",
24
+  $output_string eq "1952\n2012\n2013\n2014\n",
25 25
   "Correctly listed years."
26 26
 );
27 27
 
@@ -29,7 +29,7 @@ ok(
29 29
 $output_string = '';
30 30
 main($output, @local_argv);
31 31
 ok(
32
-  $output_string eq "2013/1\n2013/2\n2014/1\n",
32
+  $output_string eq "1952/2\n2013/1\n2013/2\n2014/1\n",
33 33
   "Correctly listed months."
34 34
 );
35 35
 
@@ -37,7 +37,7 @@ ok(
37 37
 $output_string = '';
38 38
 main($output, @local_argv);
39 39
 ok(
40
-  $output_string eq "2014/1/1\n2014/1/2\n",
40
+  $output_string eq "1952/2/13\n2014/1/1\n2014/1/2\n",
41 41
   "Correctly listed days."
42 42
 );
43 43
 

+ 2
- 0
t/wrt.t View File

@@ -111,3 +111,5 @@ chdir 'example';
111 111
     $plaintext_year_index =~ m/\QI'm an index file for an entire year.\E/,
112 112
     "2013's plaintext year index comes through."
113 113
   );
114
+
115
+# displaying years 

+ 65
- 11
t/wrt_entrystore.t View File

@@ -6,7 +6,7 @@ use warnings;
6 6
 use lib 'lib';
7 7
 
8 8
 use Data::Dumper;
9
-use Test::More tests => 21;
9
+use Test::More tests => 28;
10 10
 use App::WRT;
11 11
 
12 12
 chdir 'example';
@@ -23,7 +23,7 @@ chdir 'example';
23 23
 # listing out of all source files:
24 24
 
25 25
   my (@all_source_files) = $w->{entries}->all();
26
-  my $expected_count = 31;
26
+  my $expected_count = 34;
27 27
   diag("got " . scalar @all_source_files . " source files.");
28 28
   ok(
29 29
     scalar @all_source_files == $expected_count,
@@ -41,24 +41,52 @@ chdir 'example';
41 41
 
42 42
   my (@all_day_entries) = $w->{entries}->all_days();
43 43
   ok(
44
-    scalar @all_day_entries == 2,
45
-    'got 2 day entries from example archive, as expected'
44
+    scalar @all_day_entries == 3,
45
+    'got 3 day entries from example archive, as expected'
46 46
   );
47 47
 
48 48
 # listing entries like 2014/1 for a month:
49 49
 
50 50
   my (@all_month_entries) = $w->{entries}->all_months();
51 51
   ok(
52
-    scalar @all_month_entries == 3,
53
-    'got 3 month entries from example archive, as expected'
52
+    scalar @all_month_entries == 4,
53
+    'got 4 month entries from example archive, as expected'
54 54
   );
55 55
 
56 56
 # listing entries like 2014 for a year:
57 57
 
58 58
   my (@all_year_entries) = $w->{entries}->all_years();
59 59
   ok(
60
-    scalar @all_year_entries == 3,
61
-    'got 3 year entries from example archive, as expected'
60
+    scalar @all_year_entries == 4,
61
+    'got 4 year entries from example archive, as expected'
62
+  );
63
+
64
+# listing days contained by a month or year:
65
+
66
+  my (@days_for_jan) = $w->{entries}->days_for('2014/1');
67
+  my @expected_days_for_jan = ('2014/1/1', '2014/1/2');
68
+  is_deeply(
69
+    \@days_for_jan,
70
+    \@expected_days_for_jan,
71
+    'got expected days for january 2014'
72
+  );
73
+
74
+  my (@days_for_1952) = $w->{entries}->days_for('1952');
75
+  my @expected_days_for_1952 = ('1952/2/13');
76
+  is_deeply(
77
+    \@days_for_1952,
78
+    \@expected_days_for_1952,
79
+    'got expected days for 1952'
80
+  );
81
+
82
+# listing months contained by a year:
83
+
84
+  my (@months_for_2013) = $w->{entries}->months_for('2013');
85
+  my @expected_months_for_2013 = ('2013/1', '2013/2');
86
+  is_deeply(
87
+    \@months_for_2013,
88
+    \@expected_months_for_2013,
89
+    'got expected months for 2013'
62 90
   );
63 91
 
64 92
 # next / previous
@@ -106,14 +134,14 @@ chdir 'example';
106 134
 
107 135
 # finding parents of entries:
108 136
 
109
-  my $date_parent = $w->{entries}->parent_of('2014/1/2');
137
+  my $date_parent = $w->{entries}->parent('2014/1/2');
110 138
   ok(
111 139
     $date_parent eq '2014/1',
112 140
     'found correct parent for 2014/1/2'
113 141
   );
114 142
   # diag($date_parent);
115 143
 
116
-  my $icon_parent = $w->{entries}->parent_of('icon_test');
144
+  my $icon_parent = $w->{entries}->parent('icon_test');
117 145
   ok(
118 146
     ! defined $icon_parent,
119 147
     'found no parent for icon_test'
@@ -121,13 +149,22 @@ chdir 'example';
121 149
   # diag($icon_parent);
122 150
 
123 151
   eval {
124
-    $w->{entries}->parent_of('i_do_not_exist');
152
+    $w->{entries}->parent('i_do_not_exist');
125 153
   };
126 154
   ok(
127 155
     $@,
128 156
     "croaked on trying to find parent of a nonexistent entry"
129 157
   );
130 158
 
159
+# finding children of entries
160
+
161
+  my @children = $w->{entries}->children('2013');
162
+  ok(
163
+    @children == 3,
164
+    "got 3 children for 2013"
165
+  );
166
+  # diag(join ', ', @children);
167
+
131 168
 # checking whether entries are directories, flatfiles, etc.
132 169
 
133 170
   ok(
@@ -157,5 +194,22 @@ chdir 'example';
157 194
     'icon_test/textfile does not have an index'
158 195
   );
159 196
 
197
+# basename of an entry:
198
+
199
+  ok(
200
+    $w->{entries}->basename('1969/2/1') eq '1',
201
+    'got an expected basename for a day'
202
+  );
203
+
204
+  ok(
205
+    $w->{entries}->basename('1969/2') eq '2',
206
+    'got an expected basename for a month' 
207
+  );
208
+
209
+  ok(
210
+    $w->{entries}->basename('1969') eq '1969',
211
+    'got an expected basename for a year' 
212
+  );
213
+
160 214
   # diag(Dumper($w->{entries}->{entry_properties}));
161 215
   # diag(Dumper($w->{entries}->{property_entries}));

Loading…
Cancel
Save