#!/usr/bin/perl use strict; use warnings; use Gtk2 '-init'; use Glib qw/TRUE FALSE/; use FileHandle; use Gtk2::Helper; use Linux::CDROM; my $cddrive = "/dev/cdrom"; my $mountedcd = "/media/cdrom1"; our $cd = Linux::CDROM->new("$cddrive"); sub give_err { my ($fh, $msg) = @_; print $fh $msg; $cd->close; exit(1); } sub ripCD { my ($button, $passed) = @_; my $pid = fork(); if ($pid != 0) { return; } my $data = $passed->[0]; my $label =$passed->[1]; my $writefh = $passed->[2]; my $buffer = $passed->[3]; $cd->drive_status == 4 or give_err ($writefh, "No CD in drive! Insert CD and try again. " . $cd->disc_status); my $case_number = $data->get_text; if ($case_number eq "") { $case_number = "temp"; } my $datestamp = `date +%Y%m%d%H%M%S `; my $id = ("$case_number.$datestamp"); chomp($id); system("echo 'Start of new job. ID=$id' >> /usr/rip/cdimport.log"); system("echo '-------------------------------------------------------------------------------' >> /usr/rip/cdimport.log"); print $writefh "ID is $id"; system("mkdir /tmp/$id/"); chdir "/tmp/$id"; my $cdtype = $cd->disc_status; if ($cdtype==CDS_AUDIO) { print $writefh "Status: Ripping Audio CD..."; system("cdparanoia -B -e 2>> /usr/rip/cdimport.log") == 0 or give_err ($writefh, "ERROR: CDParanoia Failed: $?"); print $writefh "Status: Converting to MP3..."; system("find /tmp/$id/ -iname \"*.wav\" -print0 | xargs -0 -n 1 -I '{}' ffmpeg -i '{}' -f mp3 '{}'.mp3 2>> /usr/rip/cdimport.log") == 0 or give_err ($writefh, "ERROR: Failed to convert WAV to MP3: $?"); system("find /tmp/$id/ -iname \"*.mp3\" -print0 | xargs -0 -n 10 rename 's/\.cdda\.wav\.mp3/\.mp3/i' 1>> /usr/rip/cdimport.log") == 0 or give_err ($writefh, "ERROR: Failed to rename files: $?"); system("find /tmp/$id/ -iname \"*.mp3\" -print0 | xargs -0 -n 10 rename 's/track/$id-/i' 1>> /usr/rip/cdimport.log") == 0 or give_err ($writefh, "ERROR: Failed to rename files: $?"); system("find /tmp/$id/ -iname \"*.wav\" -print0 | xargs -0 -n 10 rm -rf 1>> /usr/rip/cdimport.log") == 0 or give_err ($writefh, "ERROR: Failed to delete WAV Files: $?"); } else { print $writefh "Status: Mounting CD-ROM..."; system("umount $cddrive 1>> /usr/rip/cdimport.log"); system("mount $cddrive 1>> /usr/rip/cdimport.log") == 0 or give_err ($writefh, "ERROR: Failed to mount CD-Rom: $?"); print $writefh "Copying CD..."; system("mkdir -v /tmp/$id/ 1>> /usr/rip/cdimport.log"); system("cp $mountedcd/* -vR /tmp/$id/ 1>> /usr/rip/cdimport.log") == 0 or give_err ($writefh, "ERROR: Failed to copy files: $?"); system("chmod -v +w /tmp/$id -R 1>> /usr/rip/cdimport.log") == 0 or give_err ($writefh, "ERROR: Failed to give write permission: $?"); print $writefh "Converting any WAV files to MP3..."; if (system("find /tmp/$id/ -iname \"*.wav\" -print0 | xargs -0 -n 1 -I '{}' ffmpeg -i '{}' -f mp3 '{}'.mp3 1>> /usr/rip/cdimport.log") == 0) { system("find /tmp/$id/ -iname \"*.mp3\" -print0 | xargs -0 -n 10 rename -v 's/\.wav\.mp3/\.mp3/i' 1>> /usr/rip/cdimport.log") == 0 or give_err ($writefh, "ERROR: Failed to rename files: $?"); system("find /tmp/$id/ -iname \"*.wav\" -print0 | xargs -0 -n 10 rm -vrf 1>> /usr/rip/cdimport.log") == 0 or give_err ($writefh, "ERROR: Failed to delete WAV Files: $?"); } else { print $writefh "Failed to convert WAV to MP3 - Skipping"; } system("umount -v $cddrive 1>> /usr/rip/cdimport.log"); } my ($start, $end) = $buffer->get_bounds; open INPUT, "> /tmp/$id/notes.txt"; print INPUT $buffer->get_text($start, $end, TRUE); close INPUT; print $writefh "Creating Archive..."; chdir("/tmp/"); system("tar --verbose --create --bzip2 --file=/usr/rip/pending/$id.bz2 $id/ 1>> /usr/rip/cdimport.log") == 0 or give_err ($writefh, "ERROR: Failed to compress files: $?"); print $writefh "Cleaning up old files..."; system("rm -rfv /tmp/$id/ 1>> /usr/rip/cdimport.log") == 0 or give_err ($writefh, "ERROR: Failed to delete old files: $?"); $cd->eject; $cd->close; print $writefh "Ready for next CD"; exit(0); } sub watch_console { my ($fd, $fh, $buffer) = @_; my $sysbuffer; if ( not sysread($fh, $sysbuffer, 4096) ) { # obviously the connected pipe was closed Gtk2::Helper->remove_watch ($fd) or die "couldn't remove watcher"; close($fh); return 1; } #$buffer->set_text($sysbuffer); $buffer->set_text($sysbuffer); #always return TRUE to continue the callback return 1; } sub updateStatus { my ($fh, $tag, $label) = @_; my $buffer; if ( not sysread($fh, $buffer, 4096) ) { # obviously the connected pipe was closed Gtk2::Helper->remove_watch ($tag) or die "couldn't remove watcher"; # close($fh); return 1; } $label->set_text("$buffer"); return 1; } sub delete_event { Gtk2->main_quit; return FALSE; } # See if this was called with audio or data my $cdtype = $ARGV[0]; my ($readfh, $writefh) = FileHandle::pipe; my $fh = FileHandle->new(); #open ($fh, "/usr/rip/cdimport.log"); open ($fh, "tail -f -s .1 /usr/rip/cdimport.log |"); # Create widgets # Set up main window my $window = Gtk2::Window->new('toplevel'); $window->set_title("Metropolitan Interpreters and Translators"); $window->signal_connect(delete_event => \&delete_event); $window->set_border_width(10); $window->set_size_request( 800, 400); my $box1 = Gtk2::VBox->new(FALSE,0); $window->add($box1); # Create status bar my $label = Gtk2::Label->new("Status: Not running."); $label->set_alignment(0.0, 0.0); $box1->pack_end($label, TRUE, FALSE, 0); # Create Case Number text box my $frame = Gtk2::Frame->new('Enter in the Case Number for this CD'); my $entry = Gtk2::Entry->new; $frame->add($entry); $frame->set_border_width(0); $box1->pack_start($frame, TRUE, TRUE, 0); # Create textview box for notes $frame = Gtk2::Frame->new('Enter in any relevant notes'); my $textBox = Gtk2::TextView->new; my $scroll = Gtk2::ScrolledWindow->new; my $event_box = Gtk2::EventBox->new; my $color = Gtk2::Gdk::Color->parse ("black"); $event_box->modify_bg ('normal', $color); my $align = Gtk2::Alignment->new (0.5, 0.5, 1.0, 1.0); $align->set_border_width (1); $scroll->add($event_box); $event_box->add ($align); $align->add ($textBox); my $buffer = $textBox->get_buffer; my $end_mark = $buffer->create_mark( 'end', $buffer->get_end_iter, FALSE ); $buffer->signal_connect( insert_text => sub { $textBox->scroll_to_mark( $end_mark, 0.0, TRUE, 0.0, 0.0 ); } ); $frame->add($scroll); $box1->pack_start($frame, TRUE, TRUE, 0); $textBox->set_buffer($buffer); # Create console text box $frame = Gtk2::Frame->new('Console Window'); my $ctextBox = Gtk2::TextView->new; my $cscroll = Gtk2::ScrolledWindow->new; my $cevent_box = Gtk2::EventBox->new; $color = Gtk2::Gdk::Color->parse ("black"); $cevent_box->modify_bg ('normal', $color); my $calign = Gtk2::Alignment->new (0.5, 0.5, 1.0, 1.0); $calign->set_border_width (1); $cevent_box->add ($calign); $calign->add ($ctextBox); $cscroll->add($cevent_box); my $cbuffer = $ctextBox->get_buffer; my $cend_mark = $cbuffer->create_mark( 'end', $cbuffer->get_end_iter, FALSE ); $cbuffer->signal_connect( insert_text => sub { $ctextBox->scroll_to_mark( $cend_mark, 0.0, TRUE, 0.0, 0.0 ); } ); $frame->add($cscroll); $box1->pack_end($frame, TRUE, TRUE, 0); $ctextBox->set_buffer($cbuffer); $ctextBox->set_editable(FALSE); $cbuffer->set_text("Console window"); # Create buttons my $box2 = Gtk2::HBox->new(FALSE, 0); my $button = Gtk2::Button->new(" Start "); $button->signal_connect(clicked => \&ripCD, [$entry, $label, $writefh, $buffer, $cdtype]); $box2->pack_start($button, TRUE, FALSE, 10); $button = Gtk2::Button->new(" Cancel "); $button->signal_connect(clicked => \&delete_event); $box2->pack_start($button,TRUE, FALSE, 0); $box1->pack_start($box2, TRUE, FALSE, 0); my $tag; $tag = Gtk2::Helper->add_watch ( $readfh->fileno, 'in', sub { updateStatus ($readfh, $tag, $label); }); my $ctag; $ctag = Gtk2::Helper->add_watch ( $fh->fileno, 'in', sub { watch_console ($ctag, $fh, $cbuffer); }); $window->show_all(); Gtk2->main; system("killall tail");