1 # Blosxom Plugin: entries_cache -*- perl -*-
2 # Author(s): Fletcher T. Penney <http://fletcher.freeshell.org/>
3 # Modified by Steve Schwarz <http://agilitynerd.com/>
5 # Based on entries_index by Rael Dornfest
6 # Documentation help contributed by Iain Cheyne
10 # --- Configurable variables -----
12 $delay = 0 unless defined $delay;
13 # How many minutes delay before entries are re-indexed?
14 # Set to 0 to force reindexing everytime - this
15 # will provide the same behavior as Rael's
16 # entries_index. Though, I am not sure why one
17 # would do this. At least use a small cache time to
18 # improve performance....
19 # SAS - I set this to zero so comments and new files
20 # are immediately visible.
21 $indexname = "$blosxom::plugin_state_dir/.entries_cache.index" unless defined $indexname;
22 $others_indexname = "$blosxom::plugin_state_dir/.entries_cache.others" unless defined $others_indexname;
25 $use_date_tags = 1 unless defined $use_date_tags;
26 # Set to 1 to enable parsing meta- keywords
29 $use_UK_dates = 0 unless defined $use_UK_dates;
30 # Default is mm/dd/yy (US)
31 # Set to 1 to use dd/mm/yy (UK)
33 $update_meta_date = 0 unless defined $update_meta_date;
34 # Add a meta_date tag if it doesn't exist
35 # This will require that perl has write access to your story files
36 # and that you are using the meta plugin.
38 # NOTE: As of version 0.91, you do not NEED the meta plugin...
40 # Be sure to save your text files with UNIX line endings
41 # (any decent text editor should be able to do this) or use the blok
42 # plugin (http://www.enilnomi.net/download.html#blok).
43 # There is some logic in entries_cache to fix this, but do not rely
46 # Lastly, make sure there is at least one blank line between the
47 # entry title and the body. Again, there is some logic in
48 # entries_cache to fix this, but do not rely on it.
50 # The default meta-keywords are compatible with Eric Sherman's
51 # entries_index_tagged defaults:
53 # http://primitiveworker.org/blo.g/development/blosxom/entries_index_tagged/
55 $meta_timestamp = "meta-creation_timestamp:" unless defined $meta_timestamp;
56 # timestamp_tag is the non-human readable date stamp format
57 # used by entries_index, entries_cache, entries_index_tagged,
60 $meta_date = "meta-creation_date:" unless defined $meta_date;
61 # date_tag is a human readable version
63 $strip_meta_dates = 1 unless defined $strip_meta_dates;
64 # Strip meta-tags from story so that
65 # they are not displayed. Unnecessary if you are running the
68 $update_static_rendering = 0 unless defined $update_static_rendering;
69 # Recreate statically rendered files.
70 # When set to 0, Blosxom will not update statically rendered files
71 # even when stories are edited afterwards (Fletcher Penney's default).
72 # Set to 1 if you want to be able to fix typos in statically rendered stories.
74 $index_umask = oct(007) unless defined $index_umask;
75 # Mask for index files : default allows Read/Write for owner and group,
78 $debug = 0 unless defined $debug;
81 # --------------------------------
85 use CGI qw/:standard/;
93 $reindex = 1 if (CGI::param('reindex'));
101 my(%files, %indexes, %others);
104 if ( open CACHE, $indexname) {
105 while ($line = <CACHE>) {
106 # Improved backwards compatibility with entries_index
107 if ($line =~ /\s*'?(.*?)'?\s*=>\s*(\d*),?/) {
112 # See if it's time to reindex
113 $reindex = 1 if ( stat($indexname)->mtime lt ($time - $delay*60) );
115 # No index found, so we need to index
119 # Read cached others index
120 if ( open CACHE, $others_indexname) {
121 while ($line = <CACHE>) {
122 # Improved backwards compatibility with entries_index
123 if ($line =~ /\s*'?(.*)'?\s*=>\s*(.*),?/) {
128 # See if it's time to reindex
129 $reindex = 1 if ( stat($others_indexname)->mtime lt ($time - $delay*60) );
131 # No index found, so we need to index
136 # Perform reindexing if necessary
137 # This code was originally copied from entries_index by Rael Dornfest
138 # Check to see if previously indexed files exist, and then rescan
139 # the datadir for any new files, while preserving the old times
141 # Static mode requires some of the code in this section, and the
142 # speed hit is unimportant for static blogs
144 if ($blosxom::static_or_dynamic eq "static") {
151 # If any files not available, err on side of caution and reindex
152 for my $file (keys %files) { -f $file or do { $reindex++; delete $files{$file} }; }
153 for my $other (keys %others) { -f $other or do { $reindex++; delete $others{$other} }; }
159 my $curr_depth = $File::Find::dir =~ tr[/][];
161 # if ( $blosxom::depth and $curr_depth > $blosxom::depth ) {
162 # # We are beyond depth, so remove files
163 # $files{$File::Find::name} and delete $files{$File::Find::name};
164 # $others{$File::Find::name} and delete $others{$File::Find::name};
168 # Adding support for %others
171 m!^$blosxom::datadir/(?:(.*)/)?(.+)\.$blosxom::file_extension$!
172 and $2 ne 'index' and $2 !~ /^\./ and (-r $File::Find::name)
174 # SAS modified so if meta-creation_date or file timestamp are in the future
175 # and we don't want future entries the file won't be included in the file list
177 if (!$blosxom::show_future_entries and
178 ((extract_date($File::Find::name, $files{$File::Find::name}) > time) or
179 (stat($File::Find::name)->mtime > time))) {
180 $files{$File::Find::name} and delete $files{$File::Find::name};
181 $others{$File::Find::name} and delete $others{$File::Find::name};
183 ( $files{$File::Find::name} || ++$reindex )
184 and ( $files{$File::Find::name} =
185 extract_date($File::Find::name,$files{$File::Find::name}) ||
186 $files{$File::Find::name} ||
187 stat($File::Find::name)->mtime )
192 or !-f "$blosxom::static_dir/$1/index." . $blosxom::static_flavours[0]
193 # Trying to fix for static mode
194 or ( $update_static_rendering && stat("$blosxom::static_dir/$1/index." . $blosxom::static_flavours[0])->mtime < stat($File::Find::name)->mtime )
195 or stat("$blosxom::static_dir/$1/index." . $blosxom::static_flavours[0])->mtime < $files{$File::Find::name}
198 and $d = join('/', (blosxom::nice_date($files{$File::Find::name}))[5,2,3])
199 and $indexes{$d} = $d
200 and $blosxom::static_entries and $indexes{ ($1 ? "$1/" : '') . "$2.$blosxom::file_extension" } = 1;
203 !-d $File::Find::name and -r $File::Find::name and $others{$File::Find::name} = stat($File::Find::name)->mtime
210 # The index was recreated, so we should record the new version
211 my $savemask = umask $index_umask ;
212 if ( open ENTRIES, "> $indexname" ) {
213 foreach (sort keys %files) {
214 print ENTRIES "$_=>$files{$_}\n";
218 warn "couldn't > $indexname: $!\n";
221 if ( open ENTRIES, "> $others_indexname" ) {
222 foreach (sort keys %others) {
223 print ENTRIES "$_=>$others{$_}\n";
227 warn "couldn't > $others_indexname: $!\n";
233 return (\%files, \%indexes, \%others);
239 my ($file, $indexed_date) = @_;
241 my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst);
243 warn "Entries_Cache: Checking $file for meta-tag\n\tComparing to $indexed_date\n" if ($debug == 1);
245 # This is an attempt for compatibility with Eric Sherman's entries_index_tagged
246 # But it does not handle as many date formats, as there are too many additional
247 # necessary modules that I am not willing to require
249 if ( $use_date_tags != 0) {
252 $line = <FILE>; # Read first line ( ie the title)
255 # now, parse the story, and try to correct misformatted stories
256 while ($line = <FILE>) {
257 if ($line =~ /^$meta_timestamp\s*(\d+)/) {
258 # If present, this format is used
261 warn "Entries_Cache: Found meta_timestamp $result for $file\n" if ($debug == 1);
265 if ($line =~ /^$meta_date\s*(.*)/) {
268 warn "Entries_Cache: Found meta-date $result for $file\n" if ($debug == 1);
269 return parsedate($result);
272 if ( $line !~ /^meta.*?:/i) {
273 # line doesn't start with meta... (ie story was not formatted
274 # for meta-tags), or the meta-tags are finished
276 if ($update_meta_date eq 1) {
277 # Don't mess with stories unless using UNIX line endings.
279 if (($line =~ /\r/) || ($new_story =~ /\r/)) {
280 warn "Entries_Cache: File $file has non-UNIX line endings; cannot update metatags...\n";
285 warn "Entries_Cache: Updating meta-tag for $file\n" if ($debug == 1);
286 if ($indexed_date eq 0 || $indexed_date == "") {
287 $indexed_date = stat($file)->mtime;
288 warn "Entries_Cache: No date for $file, using $indexed_date\n" if ($debug == 1);
291 ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime($indexed_date);
294 $hour = sprintf("%02d",$hour);
295 $min = sprintf("%02d",$min);
296 $sec = sprintf("%02d",$sec);
298 warn "Entries_Cache: Adding meta-tag to $file, using $meta_date $mday/$mon/$year $hour:$min:$sec\n" if ($debug == 1);
300 if ($use_UK_dates eq 1) {
301 $new_story .= "$meta_date $mday/$mon/$year $hour:$min:$sec\n\n";
303 $new_story .= "$meta_date $mon/$mday/$year $hour:$min:$sec\n\n";
306 if ( $line !~ /^\s*$/) {
307 # If this line wasn't empty, then add it to story
311 while ($line = <FILE>) {
312 # read remainder of story
317 open (FILE, "> $file") or warn "Unable to update date meta-tag on $file\n";
318 print FILE $new_story;
334 my ($datestring) = @_;
335 #warn "Parsing $datestring\n";
337 # Possible formatting
338 # Month can be 3 letter abbreviation or full name (in English)
339 # Time must be hh:mm or hh:mm:ss in 24 hour format
341 # The remaining 1 or 2 digits are treated as date
342 # ie: May 25 2003 18:40
343 # order is not important as long as pieces are there
345 # Convert the datestring to a time() format
347 # Find "Shorthand" Date
348 if ( $datestring =~ /\d\d?\/\d\d?\/\d\d\d?\d?/) {
349 if ( $use_UK_dates eq 0) {
351 $datestring =~ s/(\d\d?)\/(\d\d?)\/(\d\d\d?\d?)//;
357 $datestring =~ s/(\d\d?)\/(\d\d?)\/(\d\d\d?\d?)//;
363 # Now, clean up year if 2 digit
364 # You may change the 70 to whatever cutoff you like
365 $year += 2000 if ($year < 70 );
366 $year += 1900 if ($year < 100);
370 $mon = 0 if ($datestring =~ s/(Jan|January)//i);
371 $mon = 1 if ($datestring =~ s/(Feb|February)//i);
372 $mon = 2 if ($datestring =~ s/(Mar|March)//i);
373 $mon = 3 if ($datestring =~ s/(Apr|April)//i);
374 $mon = 4 if ($datestring =~ s/(May)//i);
375 $mon = 5 if ($datestring =~ s/(Jun|June)//i);
376 $mon = 6 if ($datestring =~ s/(Jul|July)//i);
377 $mon = 7 if ($datestring =~ s/(Aug|August)//i);
378 $mon = 8 if ($datestring =~ s/(Sep|September)//i);
379 $mon = 9 if ($datestring =~ s/(Oct|October)//i);
380 $mon = 10 if ($datestring =~ s/(Nov|November)//i);
381 $mon = 11 if ($datestring =~ s/(Dec|December)//i);
384 if ($datestring =~ s/(\d\d?):(\d\d)(:\d\d)?//) {
390 if ($datestring =~ s/(\d\d\d\d)//) {
394 if ($datestring =~ s/(\d\d?)//) {
398 return timelocal($sec,$min,$hour,$day,$mon,$year);
403 return 1 if (! $strip_meta_dates);
404 # This code based on Rael's meta plugin
405 my($pkg, $path, $filename, $story_ref, $title_ref, $body_ref) = @_;
407 # Strip date-based meta tags from body
408 $$body_ref =~ s/^$meta_timestamp.*//g;
409 $$body_ref =~ s/^$meta_date.*//g;
421 Blosxom Plug-in: entries_cache
425 Purpose: This plugin reserves original creation timestamp on weblog
426 entries, allowing for editing of entries without altering the original
427 creation time. It maintains an index ($blosxom::plugin_state_dir/
428 .entries_cache.index) of filenames and their creation times. It also adds
429 new entries to the index the first time Blosxom come across them. In
430 addition, it is possible to rely on entries_cache inserting date-based meta
431 tags automatically into entries - this is enabled by the $use_date_tags
432 setting. This makes the entries more portable. Note that if this approach
433 is used, the meta plugin is required: http://www.blosxom.com/downloads/
434 plugins/meta. (NOTE: As of version 0.91 you can use this without the meta
437 Replaces the default $blosxom::entries subroutine
439 The entries_cache plugin is a "souped-up" version of the entries_index
440 plugin. It maintains file modification times in the same manner as the
441 original plugin, but goes one-step further. It uses the modification time
442 of the index file to determine whether to rescan the datadir. If $delay
443 minutes have not passed, it relies on the cached information.
445 You can force a manual scan by appending ?reindex=y to the end of your base
448 The reason for this change is that the original blosxom and the
449 entries_index plugin rescan the datadir each time a page is viewed. This
450 plugin allows you to cache the information to speed up processing times on
451 most page views. According to several posts on the blosxom mailing list,
452 this is one of the big processor hogs. With a $delay setting of 60 minutes,
453 there will only be one page view each hour that has to wait for the full
454 directory scan. To be honest, I have not noticed much of a speed boost
455 during my testing yet, but I imagine it would only appear for sites with a
456 large number of files to be indexed.
463 =head1 VERSION HISTORY
464 0.93 Added the $update_static_rendering and $index_umask
465 configuration variables.
467 0.92 Checks if meta-creation_date is in the future and only displays
468 entry if $show_future_entries is set. Otherwise future articles
469 (by meta-creation_date or file modified time) are not displayed.
470 Don't think this breaks static rendering... haven't tested it.
472 0.91 Improved documentation courtesy of Iain Cheyne - THANKS!!!
473 Now, if you are not running the meta plugin, you will not see any meta tags in your stories
475 0.9 Added parser that detects stories that are not properly formatted for meta-tags and reformats them so that they are.
476 Additionally, it will not update files that have improper line endings ( ie non-UNIX endings).
478 0.8 Fixed typo that caused index to be rebuilt every time... :)
480 0.7 Major revisions - fixed the "Year 1900" bug and an issue with statically generated blogs misbehaving
482 0.61 Fixed bug reading old styled cache files
484 0.6 Added feature to automatically create meta-tags from indexed
487 0.52 Fixed a bug where a new index might not be written
489 0.51 Added dd/mm/yy(yy) and mm/dd/yy(yy) date formatting
491 0.5 Complete rewrite - add support for %others, meta- tags, added backwards compatibility to using the .entries_index.index file from rael's plugin
493 0.2 Removed reliance on Data::Dumper, making it suitable for use on Earthlink
498 Modified by Steve Schwarz
499 based on original code by:
500 Rael Dornfest <rael@oreilly.com>, http://www.raelity.org/
502 This plugin is now maintained by the Blosxom Sourceforge Team,
503 <blosxom-devel@lists.sourceforge.net>.
507 Blosxom Home/Docs/Licensing: http://blosxom.sourceforge.net/
509 Blosxom Plugin Docs: http://blosxom.sourceforge.net/documentation/users/plugins.html
513 None known; please send bug reports and feedback to the Blosxom
514 development mailing list <blosxom-devel@lists.sourceforge.net>.
519 Copyright 2003, Fletcher Penney
520 except for portions copied from entries_index and entries_index_tagged
522 Blosxom and original entries_index plugin
523 Copyright 2003, Rael Dornfest
525 Permission is hereby granted, free of charge, to any person obtaining a
526 copy of this software and associated documentation files (the "Software"),
527 to deal in the Software without restriction, including without limitation
528 the rights to use, copy, modify, merge, publish, distribute, sublicense,
529 and/or sell copies of the Software, and to permit persons to whom the
530 Software is furnished to do so, subject to the following conditions:
532 The above copyright notice and this permission notice shall be included
533 in all copies or substantial portions of the Software.
535 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
536 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
537 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
538 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
539 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
540 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
541 OTHER DEALINGS IN THE SOFTWARE.