POE::Component::CD::Rip - POE Component for running cdparanoia, a CD ripper.


POE-Component-CD-Rip documentation Contained in the POE-Component-CD-Rip distribution.

Index


Code Index:

NAME

Top

POE::Component::CD::Rip - POE Component for running cdparanoia, a CD ripper.

SYNOPSIS

Top

use POE qw(Component::CD::Rip);

$cd = POE::Component::CD::Rip->new(alias => $alias); $cd->rip(3, "/tmp/03.rip");

$POE::Kernel->run();

DESCRIPTION

Top

This POE component serves to rip tracks from a CD. At present it is merely a wrapper for the cdparanoia program which does the bulk of the work.

METHODS

Top

The module provides an object oriented interface as follows:

new

Used to initialise the system and create a module instance. The following parameters are available:

Indicates the name of a session to which module callbacks will be posted. Default: main.

Indicates the device to rip from. Default: /dev/cdrom.

rip

Used to request that a track be ripped. The following parameters are required:

Indicates the number of the track to rip, starting with 1.

Provides the name of the file where to store the rip.

    e.g. C<$cdr->rip(3, "/tmp/tst.rip");>

CALLBACKS

Top

Callbacks are made to the session indicated in the spawn() method. The names of the functions called back may also be set via the aforementioned method. The following callbacks are issued:

status

Fired during processing. ARG0 is the block number being processed whilst ARG1 represents the percentage of completion expressed as a whole number between 0 and 100.

done

Fired upon completion of a rip. The ARG0 parameter contains the name of the file ripped.

error

Fired on the event of an error.

AUTHOR

Top

Erick Calder <ecalder@cpan.org>

My gratitude to Rocco Caputo and Matt Cashner whose code has helped me put this together.

DATE

Top

$Date: 2002/09/14 22:45:41 $

VERSION

Top

$Revision: 1.2 $

LICENSE AND COPYRIGHT

Top


POE-Component-CD-Rip documentation Contained in the POE-Component-CD-Rip distribution.

#
#	CD ripping POE component
#	Copyright (c) Erick Calder, 2002.
#	All rights reserved.
#

package POE::Component::CD::Rip;

# --- external modules --------------------------------------------------------

use warnings;
use strict;
use Carp;

use POE qw(Wheel::Run Filter::Line Driver::SysRW);

# --- module variables --------------------------------------------------------

use vars qw($VERSION);
$VERSION = substr q$Revision: 1.2 $, 10;

my %stat = (
	':-)' => 'Normal operation, low/no jitter',
	':-|' => 'Normal operation, considerable jitter',
	':-/' => 'Read drift',
	':-P' => 'Unreported loss of streaming in atomic read operation',
	'8-|' => 'Finding read problems at same point during reread; hard to correct',
	':-0' => 'SCSI/ATAPI transport error',
	':-(' => 'Scratch detected',
	';-(' => 'Gave up trying to perform a correction',
	'8-X' => 'Aborted (as per -X) due to a scratch/skip',
	':^D' => 'Finished extracting',
	);

# --- module interface --------------------------------------------------------

sub new {
	my $class = shift;
	my $opts = shift;

	my $self = bless({}, $class);

	my %opts = !defined($opts) ? () : ref($opts) ? %$opts : ($opts, @_);
	%$self = (%$self, %opts);

	$self->{dev} ||= "/dev/cdrom";
	$self->{alias} ||= "main";
	$self->{status} ||= "status";
	$self->{done} ||= "done";

	return $self;
	}

sub rip {
	my $self = shift;
	my ($n, $fn) = @_;

	POE::Session->create(
		inline_states => {
			_start		=> \&_start,
			_stop		=> \&_stop,
			got_output	=> \&got_output,
			got_error	=> \&got_error,
			got_done	=> \&got_done
			},
		args => [$self, $n, $fn]
		);
	}

# --- session handlers --------------------------------------------------------

sub _start {
	my ($heap, $self, $n, $fn) = @_[HEAP, ARG0 .. ARG2];

	$heap->{self} = $self;
	$heap->{n} = $n;
	$heap->{fn} = $fn;

	my @cmd = ("cdparanoia", "-d", $self->{dev}, $n, $fn);
	$heap->{child} = POE::Wheel::Run->new(
		Program		=> \@cmd,
		StdioFilter	=> POE::Filter::Line->new(),	# Child speaks in lines
		Conduit		=> "pty",
		StdoutEvent	=> "got_output", 				# Child wrote to STDOUT
		CloseEvent	=> "got_done",
		);
	}

sub _stop {
	kill 9, $_[HEAP]->{child}->PID;
	}

sub got_output {
	my ($kernel, $heap) = @_[KERNEL, HEAP];
	local $_ = $_[ARG0];

	$heap->{from} = $1	if /from sector\s+(\d+)/;
	$heap->{to} = $1	if /to sector\s+(\d+)/;

	if (/PROGRESS/) {
		my $blk = substr($_, 50, 6); $blk =~ s/\.+/$heap->{from}/;
		my $st = substr($_, 65, 3);	# smiley
		my $stmsg = $stat{$st};
		my $p = ($blk - $heap->{from}) / ($heap->{to} - $heap->{from});
		$p = int(100 * $p);
		my $self = $heap->{self};
		$kernel->post($self->{alias}
			, $self->{status} => [$blk, $p, $st, $stmsg]
			);
		}
	}

sub got_done {
    my ($kernel, $heap) = @_[KERNEL, HEAP];
    my $self = $heap->{self};

    $kernel->post($self->{alias}, $self->{done}, $self->{fn}, $self->{n});
    delete $heap->{child};
	}

sub got_error {
	my ($kernel, $heap) = @_[KERNEL, HEAP];
    my $self = $heap->{self};
	$kernel->post($self->{alias}, $self->{error});
	}

1; # :)

__END__