10.2. Code TODOs to RSSI live by my to-do list. Without it, I'd be a drippy mess of procrastination, and you wouldn't be reading this book right now. It's good to be organized, and especially so with code. Working on the scripts and chapters in this book, I've started to leave messages to myself within them. I mark these out as a new line starting with TODO:. I then have this script run over all of my working directories, parsing each file and looking for those lines. The result is a nice to-do list in my reader application and a morning's work all set out. 10.2.1. Walking Through the CodeWe'll do the usual start, with strict;, warnings;, CGI and XML::RSS. Let's use the File::Find module to do the directory-traversing: use strict; use warnings; use XML::RSS; use CGI qw(:standard); use File::Find; Up near the top, we set the root directory, below which everything will be parsed. You need to change this to match your own setup, but remember that the script checks every file. Setting it to something too high up your filesystem tree might slow the script down magnificently. my $start_directory = "/Users/ben/Code/"; Now, set up the RSS feed, as per usual. Here, we're using a cunning trick, technically against the RSS 2.0 specification, of making the link element a file:// URL. This usually works very well, bringing up your OS's file manager, or the application associated with that particular file, but remember that technically, it's not supposed to work at all. Still, for a locally produced, locally consumed feed, a little slackness on the specification is probably allowed. my $rss = new XML::RSS( version => '2.0' ); $rss->channel( title => "TODOs from $start_directory", link => "file:/$start_directory", description => "Files with TODO messages, from $start_directory" ); Now, use the File::Find module to traverse the directories, opening a filehandle for each one, slurping it in and searching each line with a regular expression for TODO. If it's found, add an item to the RSS feed. find( \&search_and_rss, $start_directory ); sub search_and_rss { open( CODEFILE, "< $File::Find::name" ); while (<CODEFILE>) { if ( $_ =~ m/TODO/ ) { $rss->add_item( title => "$File::Find::name", link => "file:\/\/$File::Find::name", description => "$_ at Line $. of $File::Find::name" ); As a test for the script, I've left a TODO line within itself. It's just a suggestion that a section of code to add the file's last modification date to the RSS feed might be a nice idea; I leave this as an exercise for the reader. Now, close the filehandle: #TODO: Put in date code here } } close(CODEFILE); } And finally, we serve up the feed: print header('application/xml+rss'); print $rss->as_string; 10.2.2. The Entire Listing#!/usr/bin/perl use strict; use warnings; use XML::RSS; use CGI qw(:standard); use File::Find; my $start_directory = "/Users/ben/Code/"; my $rss = new XML::RSS( version => '2.0' ); $rss->channel( title => "TODOs from $start_directory", link => "file:/$start_directory", description => "Files with TODO messages, from $start_directory" ); find( \&search_and_rss, $start_directory ); sub search_and_rss { open( CODEFILE, "< $File::Find::name" ); while (<CODEFILE>) { if ( $_ =~ m/TODO/ ) { $rss->add_item( title => "$File::Find::name", link => "file:\/\/$File::Find::name", description => "$_ at Line $. of $File::Find::name" ); #TODO: Put in date code here } } close(CODEFILE); } print header('application/xml+rss'); print $rss->as_string; |