# Blosxom Plugin: permtimez # Author: Stu MacKenzie # Version: v0.4b 2004-09-15 (7) # License: MIT/Public Domain # permtimez home: http://www.enilnomi.net/download.html # Documentation at the bottom of this file or type: perldoc permtimez ## READ ME ## # Blosxom uses entry file "modification times" (mtime) as # keys for sorting blog entries, and as the values from which # "posted on" dates and times are derived. It's a great system, # until something changes an entry file's mtime -- you edit a # post, upload it a day late, or re-upload an entire site. Such # actions change mtimes, which in turn change the sort order # and displayed dates of your posts. Not good. # # The permtimez plugin overcomes this problem by deriving mtime # values from each entry file's *name* -- date bits in entry # file names are converted to mtime, which is then passed on # to blosxom, which then always sorts and dates your posts # the same way. Edit posts, re-upload your site; to blosxom's # mind, nothing has changed. # # In order for permtimez to work its magic, your entry files # *must* include date information in their names. You can still # use descriptive file names; you just have to start off each # file's name with at least six characters of date info. # Here's how: # # If your post for June 20, 2004 is named "new_cat.txt", rename # the file to "040620new_cat.txt". When permtimez runs, it reads # the date info from the file name, converts it to an mtime, and # sends that mtime to blosxom. No matter when the file was actually # edited, blosxom will always treat it as being from Jun 20, 2004. # Optionally, you can also include time-of-day info in file names. # Let's say you posted twice on June 20th: # 0406201030new_cat.txt -- 10:30 am story about the new cat # 0406201600new_couch.txt -- 4pm story about the new couch you # got after getting the new cat ;-) # # permtimez requires that you pick a single format for date info, # and that you stick with it (i.e. you can't mix and match date # info formats). You can pick from a variety of date info # formats. Here's what permtimez currently supports: # YYMMDD -- as in '04, June 20 # YYYYMMDD -- as in 2004, June 20 # YYDDMM -- as in '04, 20 June # YYYYDDMM -- as in 2004, 20 June # MMDDYY -- as in June 20, '04 # MMDDYYYY -- as in June 20, 2004 # DDMMYY -- as in 20 June, '04 # DDMMYYYY -- as in 20 June, 2004 # # Time-of-day info is always optional; you can choose to include # it (or not) on any entry file name. The format for time-of-day # is invariable: it must always be in the form HHMM # # - - - - - - - - - - - - - - - # CONFIGURATION and USAGE # Enter a date-info format below; drop permtimez into your # plugins folder; blog on # # If you use the wikieditish plugin to edit or add entries # to your blog, you might want to use the modified version # included in the permtimez package: it is capable of auto- # matically adding fomatted date-info to entry file names. # Using the modified wikieditish pluin is not required; but # you may find it convenient. # - - - - - - - - - - - - - - - # # Enjoy! package permtimez; use strict; ##use CGI; use Time::Local 'timelocal_nocheck'; # really hoping everyone has this one.... #use Time::Local; # because this one needs all kind of sanity use Time::localtime; # date_info needs this # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # Configuration Section # # # # # # # # # # # # # # # # # # # # Enter a format string that reflects your date-based # file naming convention. Valid formats are: # YYYYMMDD : as in "20040620new_cat.txt" -- a post from 2004 June 20, about a new cat # YYYYDDMM : as in "20042006new_cat.txt" -- a post from 2004 20 June, about a new cat # MMDDYYYY : as in "20040620new_cat.txt" -- a post from June 20 2004, about a new cat # DDMMYYYY : as in "20040620new_cat.txt" -- a post from 20 June 2004, about a new cat # YYMMDD : as in "040620new_cat.txt" -- a post from '04 June 20, about a new cat # YYDDMM : as in "042006new_cat.txt" -- a post from '04 June 20, about a new cat # MMDDYY : as in "062004new_cat.txt" -- a post from June 20 '04, about a new cat # DDMMYY : as in "200604new_cat.txt" -- a post from 20 June '04, about a new cat # ex: my $format = 'YYYYMMDD'; my $format = 'YYYYMMDD'; # # NOTE: using the YYYYMMDD or YYMMDD format gets # you the ability to sort "by-category, by-date", # using the sortz plugin !! # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # use vars qw'$cur_format $tod'; $cur_format = $format; # for use by other plugins # set up a hash of arrays -- # keys are format "prototypes", and the array elements are: # [0] the element number in the @regxstrs array that holds # regexp strs to extract date bits from the format, and # [1], [2], and [3] are the array elements into which we'll # load the regexp results my %formats = (YYYYMMDD => [0,0,1,2], YYYYDDMM => [0,0,2,1], MMDDYYYY => [1,1,2,0], DDMMYYYY => [1,2,1,0], YYMMDD => [2,0,1,2], YYDDMM => [2,0,2,1], MMDDYY => [2,1,2,0], DDMMYY => [2,2,1,0]); # 3 patterns express all 8 formats my @regxstrs = ('(\d\d\d\d)(\d\d)(\d\d)','(\d\d)(\d\d)(\d\d\d\d)','(\d\d)(\d\d)(\d\d)'); my @formats = @{$formats{$format}}; # get the decoder ring for our format my $len = length($format); # minimum number of digits needed in file name sub start { 1; } # this sub generates properly formatted date-info # strings for new filenames created by wikieditish sub date_info { my $use_hr = shift; my $use_mn = shift; my $c_time = ctime(); # get current seconds # convert seconds into date items my(undef,$mo,$da,$ti,$yr) = ($c_time =~ /(\w{3}) +(\w{3}) +(\d{1,2}) +(\d{2}:\d{2}):\d{2} +(\d{4})$/ ); my ($hr,$mn) = split /:/, $ti; # convert time into hours & minutes $format !~ m/YYYY/ and $yr =~ s/^\d\d//; $da = sprintf("%02d", $da); # pad to two digits $hr = sprintf("%02d", $hr); $mn = sprintf("%02d", $mn); my $mo_num = $blosxom::month2num{$mo}; # hitch a ride on blosxom's converter # magically arrange date items to match user's format my @t = ($yr, $mo_num, $da); my @out; $out[0] = $t[$formats[1]]; $out[1] = $t[$formats[2]]; $out[2] = $t[$formats[3]]; # add TOD bits as requested if ($use_hr) { $out[3] = $hr; if ($use_mn) { $out[4] = $mn; } } return join '', @out; } # this function parses an incoming file name # into appropriate date items per the array # that belongs to the selected format proto sub fname_to_date { my $fname = shift; my ($yr, $mo, $da, $hr, $mn, $sc); # date/time vars my @t; # [0] will hold yr, [1] will hold mo, [2] will hold da $fname =~ s/^.*\///; # delete path up to the file name if ($fname =~ m/^\d{$len,}\D.*$/) { # confirm minimum number of digits are present # parse date items from file name; # magically put the right bits into # the right vars ($t[$formats[1]], $t[$formats[2]], $t[$formats[3]]) = ($fname =~ m/$regxstrs[$formats[0]]/); $yr = $t[0]; $mo = $t[1]; $da = $t[2]; # a bit of tweaking for timelocal() $yr = ($yr+2000) % 2000; # make all years proper 4-digit $mo --; # subtract 1 from month, because timelocal is crazy $mo = $mo % 12; # can't be out-of-range, because timelocal is lame $hr = sprintf("%02d", $hr); # compensate for slop, emptiness in time values $mn = sprintf("%02d", $mn); $sc = sprintf("%02d", $sc); return timelocal_nocheck($sc,$mn,$hr,$da,$mo,$yr); # fake an mtime #return timelocal($sc,$mn,$hr,$da,$mo,$yr); # fake an mtime } } # here's where it all happens: # we read blosxom's list of files, calculating the # user's desired "mtimes" from date-info in entry # file names; every successful calculation replaces # the "real" mtime and blosxom's none the wiser sub filter { my ($pkg, $files_ref, $others_ref) = @_; my $temp; foreach my $key (keys %$files_ref) { $temp = fname_to_date($key) and $temp or next; $$files_ref{$key} = $temp; } 1; } # makes a TOD available to story templates; # minutes are included only if they're significant sub story { $tod = $blosxom::hr12; # if ($blosxom::min ne '00') {$tod .= ":$blosxom::min";} $blosxom::min ne '00' and $tod .= ":$blosxom::min"; $tod .= $blosxom::ampm; } 1; __END__ =head1 NAME Blosxom Plug-in: permtimez =head1 SYNOPSIS permtimez uses date info in entry file names to calculate desired mtimes; these are then swapped in for the 'real' mtimes blosxom gathers during the entries() sub. The "cost" is that bloggers must add date info to file names before using permtimez; the benefit is that post dates and sort order become "permanent," freed from the volatility of 'real' mtimes. =head1 CONFIGURABLE VARIABLES Enter a format for the date info that will lead off every entry file name (choices appear in the config section, above) =head1 INSTALLATION Once a format is entered, just drop this file into your blosxom plugins folder. Blog on. =head1 USAGE NOTE: the only way this plugin will be effective is if your entry file names start with at least 6 digits of date info, per the format selected in the config section. Once that's done, just sit back and let permtimez provide you with reliable, repeatable entry sorts and post dates. A modified version of the wikieditish plugin is available; it's is built to automatically add properly formatted date-info bits to files created by wiki-editing. The modified wikieditish is included in the full permtimez package. The sortz plugin is also available for changing the sorting order of posts. When your date-info format is either YYYYMMDD or YYMMDD sortz allows you to sort by-category, by-date...handy for indexes. =head1 BUGS Address bug reports and comments to the Blosxom mailing list: http://www.yahoogroups.com/group/blosxom =head1 VERSION 2004-09-15 (v0.4b) - split up filtering and sorting; integrated with wikieditish; cleanup 2004-09-14 (v0.3) - parsing now works under 'strict' 2004-09-12 (v0.2) - it's alive =head1 LICENSE this Blosxom Plug-in Copyright 2004, Stu MacKenzie Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.