Cover | Table of Contents | Colophon
http://www.curry.com/)http://www.dawnanddrew.com/)http://www.curry.com/)http://www.dawnanddrew.com/)http://www.morningcoffeenotes.com/)http://www.americanheartbreak.com/movabletype/)http://www.coverville.com/)#!/usr/bin/perl -w use LWP::Simple; use strict; # The list of feeds to retrieve my @feeds = qw( http://www.curry.com/xml/rss.xml http://www.boundcast.com/index.xml ); # The title of the network feed my $networkName = "My Network"; # The URL of the home page my $url = "http://www.mysite.com"; # A description of your network my $description = "My very own network"; # Format the current date and time my @days = qw( Sun Mon Tue Wed Thu Fri Sat ); my @months = qw( Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec ); my @t = gmtime( time ); my $date = sprintf( "%s, %d %s %d %02d:%02d:%02d GMT", $days[ $t[6] ], $t[3], $months[ $t[4] ], $t[5] + 1900, $t[2], $t[1], $t[0] ); # Print the header portion of the RSS 2.0 print <<END; Content-type: text/xml <?xml version="1.0"?> <rss version="2.0"> <channel> <title>$networkName</title> <link>$url</link> <description>$description</description> <language>en-us</language> <pubDate>$date</pubDate> <lastBuildDate>$date</lastBuildDate> <generator>Network 1.0</generator> END # Iterate through each feed and find the first # item with an enclosure then print it out foreach my $feed ( @feeds ) { my $data = get $feed; while( $data =~ /(<item>.*?<\/item>)/sg ) { my $item = $1; if ( $item =~ /<enclosure/ ) { print $item; last; } } } # Print the footer print <<END; </channel> </rss> END
feeds array. Then it will combine all the feeds into a new, single RSS 2.0 feed with the name, description, and URL that you specify. Modify the variables at the top of the script before you upload it to your web server.#!/usr/bin/perl -w use Storable qw ( store retrieve ); use FileHandle; use LWP::Simple qw( get ); use strict; # The path to the history file that remembers # what we have downloaded. use constant HISTORY_FILE => ".history"; # The file that includes the URLs of all of the feeds use constant FEEDS_FILE => "feeds.txt"; #The directory to use for output of the enclosure files use constant OUTPUT_DIR => "enclosures"; # Loads all of the feeds from the feeds file and returns # an array. sub feeds_load() { my $feeds = []; my $fh = new FileHandle( FEEDS_FILE ); while( <$fh> ) { chomp; push @$feeds, $_; } $fh->close(); return $feeds; } # Returns the filename from a URL sub parse_filename($) { my ( $fname ) = @_; # Remove the arguments portion of the URL $fname =~ s/\?.*$//; # Trim anything up to the final slash $fname =~ s/.*\///; return $fname; } # Parses a feed and finds the title of the feed and the # URLs for all of the enclosures sub parse_feed($) { my ( $rss ) = @_; my $info = {}; my $urls = []; while( $rss =~ /(\<item\>.*?\<\/item\>)/sg ) { my $item = $1; if ( $item =~ /(\<enclosure.*?\>)/ ) { my $enc = $1; if ( $enc =~ /url=[\"|\'](.*?)[\"|\']/i ) { push @$urls, { url => $1, filename => parse_filename( $1 ) }; } } } $info->{enclosures} = $urls; $rss =~ s/\<item\>.*?\<\/item\>//sg; my $title = ""; if ( $rss =~ /\<title\>(.*?)\<\/title\>/sg ) { $title = $1; # Strip leading and trailing whitespace $title =~ s/^\s+//g; $title =~ s/\s+$//g; # Strip out the returns and line feeds $title =~ s/\n|\r//g; # Strip out any HTML entities $title =~ s/\&.*?;//g; # Strip out any slashes $title =~ s/\///g; } $info->Podcasting Hacks = $title; return $info; } # Grabs and parses a feed. Then adds the enclosures # referenced in the feed to the queue. sub feed_read($$) { my ( $queue, $rss_url ) = @_; print "Reading feed $rss_url\n";
http://activestate.com/) complements thisby making it easy to automate COM objects. I merged these two together to build a Perl script that complements the command-line podcatcher
[Hack #3]
.
File::Find module
[Hack #7]
makes searching through a tree of directories a snap.
Win32::OLEmodule to tell iTunes to import the files.#!perl -w use Win32::OLE; use File::Find; use strict; # iTunes refers to importing as 'converting' in its COM interface. # So we convert each path. sub convert($$) { my ( $itunes, $path ) = @_; # Make sure it's an MP3 file return unless ( $path =~ /[.]mp3$/ ); print "Converting $path\n"; # Start the conversion my $progress = $itunes->ConvertFile2( $path ); # Monitor the SLOW progress my $done = 0; my $lp = -100; while( !$done ) { my $p = int( $progress->ProgressValue() ); my $m = int( $progress->MaxProgressValue() ); if ( $m > 0 ) { my $percent = int( ( $p / $m ) * 100.0 ); $percent = 0 if ( $percent < 0 ); my $delta = $percent - $lp; if ( $delta >= 5 ) { print "\t$percent%\n"; $lp = $percent; } sleep( 2 ); } $done = 1 if ( $p >= $m ); } print "\n"; } # Make sure we get a real path my $searchpath = $ARGV[0]; die "Must specify search path\n" unless ( $searchpath ); # Start up iTunes
http://groups.yahoo.com/group/videobloggers/).
#!/usr/bin/perl -w
use LWP::Simple;
use FileHandle;
use Cwd;
use strict;
# The URL of the RSS feed
use constant URL => "http://www.mysite.com/myrss.xml";
# The artist name for the MP3s
use constant ARTIST => "Artist Name";
# The album name of the MP3s
use constant ALBUM => "Album Name";
# The output directory to put the MP3s into
use constant OUTPUT_DIR => "mp3s";
# Gets the feed and returns a hash of the RSS items, their titles
# and the temporary filenames
sub get_feed($)
{
my $out = {};
my $text = get URL;
while( $text =~ /\<item(.*?)\<\/item\>/gs )
{
my $item = $1;
my ( $title ) = $item =~ /\<title\>(.*?)\<\/title\>/gs;
my ( $desc ) = $item =~ /\<description\>(.*?)\<\/description\>/gs;
$title =~ /[\n|\r]/g;
$desc =~ s/[\n|\r]/ /g;
$desc =~ s/$\<\!\[CDATA\[//;
$desc =~ s/\]\]\>//;
$desc =~ s/\<.*?\>//g;
$desc =~ s/\<\/.*?\>//g;
$desc =~ s/\"//g;
$desc =~ s/\'//g;
$desc =~ s/,//g;
$desc = $title . ". " . $desc;
my $filename = lc $title;
$filename =~ s/ /_/g;
$filename =~ s/[.]//g;
$filename =~ s/-/_/g;
$filename =~ s/\\//g;
$filename =~ s/\///g;
$filename =~ s/^\s+//;
$filename =~ s/\s+$//;
$out->{ $filename } = {
description => $desc,
title => substr($title,0,30)
};
}
return $out;
}
# Turns a story into speech as an AIFF file
sub speakstory($$)
{
my ( $text, $filename ) = @_;
open FH, "|osascript";
print FH "set ofile to POSIX file \"$filename\"\n";
print FH "say \"$text\" saving to ofile\n";
close FH;
}
# Convert an AIFF file to MP3 with the right tags
sub convert($$$)
{
my ( $aiffFile, $mp3File, $desc ) = @_;
print "Creating $mp3File\n";
my $cmd = "lame $aiffFile $mp3File --silent --tt \"$desc\"";
$cmd .= " --ta \"".ARTIST."\" --tl \"".ALBUM."\" -h";
system( $cmd );
}
# Get the feed URL and build MP3s for each of the entries
my $items = get_feed( URL );
foreach my $filename ( keys %$items )
{
speakstory( $items->{ $filename }->{description}, "temp.aiff" );
convert( "temp.aiff", OUTPUT_DIR."/".$filename.".mp3",
$items->{ $filename }->{ title } );
unlink( "temp.aiff" );
}
# Import the files into iTunes
print "Importing the MP3s into iTunes\n";
open FH, "|osascript";
print FH "set ofile to POSIX file \"".getcwd."/".OUTPUT_DIR."\"\n";
print FH "tell application \"iTunes\" to convert ofile\n";
close FH;
http://cpan.org/), which covers every conceivable need.MP3::Info
MP3::Info your script can read and write the ID3 tags in MP3 files.MP4::Info
Ogg::Vorbis::Header
LWP::Simple
LWP::UserAgent
LWP::Simple. With this module, you can simulate a web browser surfing to a site, logging in, getting cookies, making requests, and then leaving. You can automate any complex web task with LWP::UserAgent.http://FeederReader.com/). You can install it into RAM or on a memory card. Installing it on a memory card will leave you more RAM for running programs. Using a program called CabInstl (search for "CabInstl" athttp://www.pocketgear.com/) you can install the CAB file onto your memory card.http://audacity.sf.net/). This is a free application that runs on Macintosh, Windows, and Linux. It can record sound from any source, including the internal microphone on your PC or Macintosh laptop.
http://audacity.sf.net/). This is a free application that runs on Macintosh, Windows, and Linux. It can record sound from any source, including the internal microphone on your PC or Macintosh laptop.
http://core-sound.com/), hooked up through its filter and into a Marantz 660 solid-state recorder
[Hack #69]
. The recorder has a left and right XLR input, both of which are tied into the microphones that connect to either side of the glasses right above your ears.
http://salling.com/) for Mac OS X, you can use your Bluetooth-enabled phone to control every application on your computer. And you can arrange them on your keypad in any way you want.
http://lame.sf.net/), produce CD-quality sound at a bit rate of 192.