#!/usr/bin/expect # Rip and send an mp3 to a friend; can do whole CDs while you are # away. Deletes wav files as it goes, conserving space. Optionally # deletes the mp3 too. For more info on Expect see http://expect.nist.gov # Don't put a leading slash on uploadpath. Be sure you have enough disk # space on both ends because I don't check. set cdrom /dev/cdrom ;# path to cdrom set writepath /mnt/rh40/tmp/ ;# path to write local files to set wav(client) /usr/bin/cdda2wav ;# path to your wav maker set enc(client) /home/swain/mp3/l3enc ;# path to your mp3 encoder set ftp(client) /usr/bin/ftp #set wav(client) "/home/swain/mp3/cdda2wav.pl" #set enc(client) "/home/swain/mp3/l3enc.pl" #set ftp(client) "/home/swain/mp3/ftp.pl" set ftp(server) fldjfsjsjfdslk.com set ftp(login) swain set ftp(password) secret set uploadpath "" ;# path on ftp server #set uploadpath pub/users/colin/desslok ;# path on ftp server # Set the track numbers and song names (no spaces!) here. The song # name you choose will end up as songname.mp3 example: # 'set playlist(5) stairway2heaven' will rip track 5 of led zeppelin 4 # and give you stairway2heaven.mp3 You can list tracks in any order # or skip tracks. set playlist(1) roadrunner #set playlist(2) #set playlist(3) #set playlist(4) #set playlist(5) #set playlist(6) tracks #set playlist(7) #set playlist(8) #set playlist(9) cars #set playlist(10) ## End user configuration. ## Everything below here is my fault # These global hashes are akin to C structs in their usage. set wav(list) [lsort -ascii [array names playlist]] set enc(list) "" set ftp(list) "" set wav(running) 0 set enc(running) 0 set ftp(running) 0 # Returns the number of tracks left for all processes proc work_to_do {} { global wav enc ftp set inprogress 0 if { [info exists wav(tracknum)] } { incr inprogress } if { [info exists enc(tracknum)] } { incr inprogress } if { [info exists ftp(tracknum)] } { incr inprogress } return [expr [llength $wav(list)] + \ [llength $enc(list)] + [llength $ftp(list)] + $inprogress] } proc remove_spid { spid } { global spawn_ids set index [lsearch $spawn_ids $spid] set spawn_ids [lreplace $spawn_ids $index $index] } proc push { somelist arg } { upvar $somelist lst lappend lst $arg } # works same as Perl's unshift subroutine proc unshift { listname } { upvar $listname ln ;# ln is a listname, in the upper scope if { [llength $ln] == 0 } { return 0 } set returnvar [lindex $ln 0] set ln [lreplace $ln 0 0] return $returnvar } # main procs proc makewav {} { global wav enc writepath cdrom playlist spawn_ids if { $wav(running) } { return } if [llength $wav(list)] { if { [info exists wav(tracknum)] } { push enc(list) $wav(tracknum) puts "wav(tracknum) $wav(tracknum) -> enc(list) $enc(list)" } set wav(tracknum) [unshift wav(list)] puts "wav(tracknum) $wav(tracknum) from wav(list) $wav(list)" spawn sh -c "$wav(client) -t $wav(tracknum) -x \ -D $cdrom $writepath$playlist($wav(tracknum)).wav \ > /dev/null 2>&1" set wav(spawn_id) $spawn_id lappend spawn_ids $spawn_id puts "wav spawn_id: $spawn_id" set wav(running) 1 } else { if { [info exists wav(tracknum)] } { push enc(list) $wav(tracknum) puts "wav(tracknum) $wav(tracknum) -> enc(list) $enc(list)" unset wav(tracknum) } } } proc encwav {} { global enc ftp writepath playlist spawn_ids if { $enc(running) } { return } if [llength $enc(list)] { if { [info exists enc(tracknum)] } { push ftp(list) $enc(tracknum) puts "enc(tracknum) $enc(tracknum) -> ftp(list) $ftp(list)" } set enc(tracknum) [unshift enc(list)] puts "enc(tracknum) $enc(tracknum) from enc(list) $enc(list)" spawn sh -c "$enc(client) $writepath$playlist($enc(tracknum)).wav \ $writepath$playlist($enc(tracknum)).mp3 -hq -br 128000 \ > /dev/null 2>&1" set enc(spawn_id) $spawn_id lappend spawn_ids $spawn_id puts "enc spawn_id: $spawn_id" set enc(running) 1 } else { if { [info exists enc(tracknum)] } { push ftp(list) $enc(tracknum) puts "enc(tracknum) $enc(tracknum) -> ftp(list) $ftp(list)" unset enc(tracknum) } } } proc ftpenc {} { global ftp uploadpath writepath playlist spawn_ids if { $ftp(running) } { return } if [llength $ftp(list)] { set ftp(tracknum) [unshift ftp(list)] puts "ftp(tracknum) $ftp(tracknum) from ftp(list) $ftp(list)" spawn $ftp(client) $ftp(server) set ftp(spawn_id) $spawn_id lappend spawn_ids $spawn_id puts "ftp spawn_id: $spawn_id" set ftp(running) 1 } else { if { [info exists ftp(tracknum)] } { unset ftp(tracknum) } } } ######## # main # ######## puts "Remaining tracks in all queues: [work_to_do]" set stopvar [expr [work_to_do] * 3 + 1] puts "stopvar $stopvar" set timeout -1 puts "-----------------------------1st polling---------------------" makewav encwav ftpenc while { [work_to_do] != 0 } { expect { -i spawn_ids eof { remove_spid $expect_out(spawn_id) if { $expect_out(spawn_id) == $wav(spawn_id) } { puts "eof from wav ($expect_out(spawn_id) $wav(spawn_id))" set wav(running) 0 } elseif { $expect_out(spawn_id) == $enc(spawn_id) } { puts "eof from enc ($expect_out(spawn_id) $enc(spawn_id))" set enc(running) 0 } elseif {$expect_out(spawn_id) == $ftp(spawn_id) } { puts "eof from ftp ($expect_out(spawn_id) $ftp(spawn_id))" set ftp(running) 0 } else { send_user "eof on spawn_id $expect_out(spawn_id)" send_user " doesn't match! (ids: w: $wav(spawn_id) " send_user "e: $enc(spawn_id) f: $ftp(spawn_id))" exit } send_user "%%%%%%%%%%%%% polling %%%%%%%%%%%%%\n" makewav encwav ftpenc } "ame (" { send -i $expect_out(spawn_id) "$ftp(login)\r"; exp_continue } "assword:" { send -i $expect_out(spawn_id) "$ftp(password)\r"; exp_continue } "logged in" { send -i $expect_out(spawn_id) "put $writepath$playlist($ftp(tracknum)).mp3 $playlist($ftp(tracknum)).mp3\r" exp_continue } "Transfer complete" { send -i $expect_out(spawn_id) "quit\r" exp_continue } } puts "number of remaining tracks: [work_to_do]" set stopvar [expr $stopvar - 1] puts "stopvar $stopvar" if { $stopvar == 0 } { puts "error: limit exceeded" exit } } puts "Program terminated normally." exit # send -i $expect_out(spawn_id) "cd $uploadpath\r"; # exp_continue # } # "command successful" {