http://qs321.pair.com?node_id=496329
Category: Web Stuff
Author/Contact Info
Description:

A simple way to download stuff from KFAI's program archive. I just wrote the thing, it seems to work. I hope so. You'll need mplayer and lame.

KFAI is a public radio station in Minneapolis and it rocketh.

use strict;
use warnings;
use Parallel::ForkManager;
use LWP::Simple;
use DateTime;
use Fatal qw( unlink rename );
use subs qw( main download_all_shows download_show System );
use vars qw( $MAXJOBS @SHOWS $BASEURL );
sub SUNDAY () { 1 }
sub MONDAY () { 2 }
sub TUESDAY () { 3 }
sub WEDNESDAY () { 4 }
sub THURSDAY () { 5 }
sub FRIDAY () { 6 }
sub SATURDAY () { 7 }

@SHOWS = ( { name => "Fubar Omniverse",
             dow => FRIDAY,
             files => [ "fubar-1.rm",
                        "fubar-2.rm" ], },
           { name => "Groove Garden",
             dow => SATURDAY,
             files => [ "groove-1.rm",
                        "groove-2.rm" ], },
           { name => "Radio Riot",
             dow => MONDAY,
             files => [ "rad_riot-1.rm",
                        "rad_riot-2.rm" ], },
           { name => "Strictly Butter",
             dow => SATURDAY,
             files => [ "strikbut-1.rm",
                        "strikbut-2.rm" ], },
           { name => "Louisiana Rhythms",
             dow => FRIDAY,
             files => [ "la_rhthm-1.rm",
                        "la_rhthm-2.rm", ], }, );

$| = 1;
$MAXJOBS = 2;
$BASEURL = "http://helix.kfai.org/ramgen/replay/";

main;
exit;

sub main {
    download_all_shows shows => \ @SHOWS;
    
    return 1;
}

sub download_all_shows {
    my %p = @_;
    my $manager = Parallel::ForkManager->new( $MAXJOBS );
    
    for my $show ( @{$p{shows}} ) {
        for my $file ( @{$show->{files}} ) {
            my $pid = $manager->start and next;
            
            download_show name => $show->{name},
                          dow  => $show->{dow},
                          file => $file;
            
            $manager->finish;
        }
    }
}

sub download_show {
    my %p = @_;
    my $file = $p{file};
    my $name = $p{name};
    my $dow  = $p{dow};
    
    my $dt = DateTime->now;
    
    # Don't download the show if it airs today. I don't know when it
    # goes online but I'm guessing that it happens sometime during the
    # day.
    return if $dt->dow == $dow;
    
    my ( $year, $week );
    if ( not $file =~ /(?<=-)(\d+)/ ) {
        die "Hey! Frumius shit in $file!";
    }
    else {
        # 1: current week
        # 2: last week
        
        my $weeks_old = $1 - 1;
        if ( $dow > $dt->dow ) {
            # If the show airs later in the week, then the week must
            # be the one prior to whatever I'm in.
            ++ $weeks_old;
        }
        
        if ( $weeks_old ) {
            # Move the time back the right # of weeks.
            my $adj = DateTime::Duration->new( weeks => $weeks_old );
            $dt->subtract_duration( $adj );
        }
        
        # Now ask for the 
        $year = $dt->year;
        $week = $dt->week_number;
        
        return if $dt->dow == $dow;
    }
    my ( $wav_file, $mp3_file );
    for ( $wav_file, $mp3_file ) {
        $_ = $file;
        s/(?<=-)\d+\.rm/$year-$week./
    }
    $wav_file .= "wav";
    $mp3_file .= "mp3";
    
    return if -e $mp3_file;
    
    my $url = "$BASEURL$file";
    my ( $real_url ) = get( $url ) =~ /([^\r\n]+)/;
    
    -e $wav_file
      and unlink $wav_file;
    print "Downloading $wav_file\n";
    eval {
        System "mplayer -really-quiet -nojoystick -nolirc -prefer-ipv4
+ -ao pcm -vc dummy -vo null -aofile $wav_file $real_url";
        1;
    } or do {
        unlink $wav_file;
        die $@;
    };
    print "Converting $wav_file -> $mp3_file\n";
    eval {
        System "lame --silent --ty $year --tt '\Q$name\E' --ta '\Q$nam
+e\E' --tn $week -h '\Q$wav_file\E' '\Q$mp3_file\E'";
        1;
    } or do {
        unlink $wav_file;
        die $@;
    };
    -e $wav_file
      and unlink $wav_file;
    print "Done with $mp3_file\n";
    
    1;
}

sub System {
    0 == system @_
      or die "@_ exit code: @{[$?>>8]}. Signal: @{[$>&127]}."
        . ( $?&128
            ? " Core dumped"
            : "" )
          . "\n";
}