CDDB_get
view release on metacpan or search on metacpan
CDDB_get.pm view on Meta::CPAN
sub cddb_sum {
my $n=shift;
my $ret=0;
while ($n > 0) {
$ret += ($n % 10);
$n = int $n / 10;
}
return $ret;
}
sub cddb_discid {
my $total=shift;
my $toc=shift;
my $i=0;
my $t=0;
my $n=0;
while ($i < $total) {
$n = $n + cddb_sum(($toc->[$i]->{min} * 60) + $toc->[$i]->{sec});
$i++;
}
$t = (($toc->[$total]->{min} * 60) + $toc->[$total]->{sec}) -
(($toc->[0]->{min} * 60) + $toc->[0]->{sec});
return (($n % 0xff) << 24 | $t << 8 | $total);
}
sub get_discids {
my $cd=shift;
$CD_DEVICE = $cd if (defined($cd));
my @toc=read_toc($CD_DEVICE);
my $total=$#toc;
my $id=cddb_discid($total,\@toc);
return [$id,$total,\@toc];
}
sub get_cddb {
my $config=shift;
my $diskid=shift;
my $id;
my $toc;
my $total;
my @r;
my $input = $config->{input};
my $multi = $config->{multi};
$input = 0 if $multi;
print STDERR Dumper($config) if $debug;
$CDDB_HOST = $config->{CDDB_HOST} if (defined($config->{CDDB_HOST}));
$CDDB_PORT = $config->{CDDB_PORT} if (defined($config->{CDDB_PORT}));
$CDDB_MODE = $config->{CDDB_MODE} if (defined($config->{CDDB_MODE}));
$CD_DEVICE = $config->{CD_DEVICE} if (defined($config->{CD_DEVICE}));
$HELLO_ID = $config->{HELLO_ID} if (defined($config->{HELLO_ID}));
$PROTO_VERSION = $config->{PROTO_VERSION} if (defined($config->{PROTO_VERSION}));
my $HTTP_PROXY = $config->{HTTP_PROXY} if (defined($config->{HTTP_PROXY}));
my $FW=1 if (defined($config->{FW}));
if(defined($diskid)) {
$id=$diskid->[0];
$total=$diskid->[1];
$toc=$diskid->[2];
} else {
my $diskid=get_discids($CD_DEVICE);
$id=$diskid->[0];
$total=$diskid->[1];
$toc=$diskid->[2];
}
my @list=();
my $return;
my $socket;
my $id2 = sprintf "%08x", $id;
my $query = "cddb query $id2 $total";
for (my $i=0; $i<$total ;$i++) {
$query.=" $toc->[$i]->{frames}";
}
# this was to old total calculation, does not work too well, its included if new version makes problems
# $query.=" ". int(($toc->[$total]->{frames}-$toc->[0]->{frames})/75);
$query.=" ". int(($toc->[$total]->{frames})/75);
print Dumper($toc) if $debug;
if ($CDDB_MODE eq "cddb") {
print STDERR "cddb: connecting to $CDDB_HOST:$CDDB_PORT\n" if $debug;
$socket=IO::Socket::INET->new(PeerAddr=>$CDDB_HOST, PeerPort=>$CDDB_PORT,
Proto=>"tcp",Type=>SOCK_STREAM) or die "cannot connect to cddb db: $CDDB_HOST:$CDDB_PORT [$!]";
$return=<$socket>;
unless ($return =~ /^2\d\d\s+/) {
die "not welcome at cddb db";
}
print $socket "cddb hello $HELLO_ID\n";
$return=<$socket>;
print STDERR "hello return: $return" if $debug;
unless ($return =~ /^2\d\d\s+/) {
die "handshake error at cddb db: $CDDB_HOST:$CDDB_PORT";
}
print $socket "proto $PROTO_VERSION\n";
$return=<$socket>;
print STDERR "proto return: $return" if $debug;
unless ($return =~ /^2\d\d\s+/) {
die "protokoll mismatch error at cddb db: $CDDB_HOST:$CDDB_PORT";
}
print STDERR "cddb: sending: $query\n" if $debug;
print $socket "$query\n";
$return=<$socket>;
chomp $return;
print STDERR "cddb: result: $return\n" if $debug;
} elsif ($CDDB_MODE eq "http") {
my $query2=$query;
$query2 =~ s/ /+/g;
my $id=$HELLO_ID;
$id =~ s/ /+/g;
my $url = "/~cddb/cddb.cgi?cmd=$query2&hello=$id&proto=$PROTO_VERSION";
my $host=$CDDB_HOST;
my $port=80;
my ($user,$pass);
if($HTTP_PROXY) {
if($HTTP_PROXY =~ /^(http:\/\/|)(.+?):(.+)\@(.+?):(.+)/) {
$user=$2;
$pass=$3;
$host=$4;
$port=$5;
} elsif($HTTP_PROXY =~ /^(http:\/\/|)(.+?):(\d+)/) {
$host=$2;
$port=$3;
}
$url="http://$CDDB_HOST".$url." HTTP/1.0";
}
print STDERR "cddb: connecting to $host:$port\n" if $debug;
$socket=IO::Socket::INET->new(PeerAddr=>$host, PeerPort=>$port,
Proto=>"tcp",Type=>SOCK_STREAM) or die "cannot connect to cddb db: $host:$port [$!]";
print STDERR "cddb: http send: GET $url\n" if $debug;
print $socket "GET $url\n";
if($user) {
my $cred = encode_base64("$user:$pass");
print $socket "Proxy-Authorization: Basic $cred\n";
}
print $socket "\n";
print $socket "\n" if $FW;
if($HTTP_PROXY) {
while(<$socket> =~ /^\S+/){};
}
$return=<$socket>;
chomp $return;
print STDERR "cddb: http result: $return\n" if $debug;
} else {
die "unkown mode: $CDDB_MODE for querying cddb";
}
$return =~ s/\r//g;
my ($err) = $return =~ /^(\d\d\d)\s+/;
unless ($err =~ /^2/) {
die "query error at cddb db: $CDDB_HOST:$CDDB_PORT";
}
if($err==202) {
return undef;
} elsif(($err==211) || ($err==210)) {
while(<$socket>) {
last if(/^\./);
push @list,$_;
s/\r//g;
print STDERR "unexact: $_" if $debug;
}
} elsif($err==200) {
$return =~ s/^200 //;
push @list,$return;
} else {
die "cddb: unknown: $return";
}
my @to_get;
unless($multi) {
if (@list) {
my $index;
if($input==1) {
print "This CD could be:\n\n";
my $i=1;
for(@list) {
my ($tit) = $_ =~ /^\S+\s+\S+\s+(.*)/;
print "$i: $tit\n";
$i++
}
print "\n0: none of the above\n\nChoose: ";
my $n=<STDIN>;
$index=int($n);
} else {
$index=1;
}
if ($index == 0) {
return undef;
} else {
push @to_get,$list[$index-1];
}
}
} else {
push @to_get,@list;
}
my $i=0;
for my $get (@to_get) {
#200 misc 0a01e802 Meredith Brooks / Bitch Single
my ($cat,$id,$at) = $get =~ /^(\S+?)\s+(\S+?)\s+(.*)/;
my $artist;
my $title;
if($at =~ /\//) {
($artist,$title)= $at =~ /^(.*?)\s\/\s(.*)/;
} else {
$artist=$at;
$title=$at;
}
my %cd=();
$cd{artist}=$artist;
chomp $title;
$title =~ s/\r//g;
$cd{title}=$title;
$cd{cat}=$cat;
$cd{id}=$id;
my @lines;
$query="cddb read $cat $id";
if ($CDDB_MODE eq "cddb") {
print STDERR "cddb: getting: $query\n" if $debug;
print $socket "$query\n";
while(<$socket>) {
last if(/^\./);
push @lines,$_;
}
if(@to_get-1 == $i) {
print $socket "quit\n";
close $socket;
}
} elsif ($CDDB_MODE eq "http") {
close $socket;
my $query2=$query;
$query2 =~ s/ /+/g;
my $id=$HELLO_ID;
$id =~ s/ /+/g;
my $url = "/~cddb/cddb.cgi?cmd=$query2&hello=$id&proto=$PROTO_VERSION";
my $host=$CDDB_HOST;
my $port=80;
my ($user,$pass);
if($HTTP_PROXY) {
if($HTTP_PROXY =~ /^(http:\/\/|)(.+?):(.+)\@(.+?):(.+)/) {
$user=$2;
$pass=$3;
$host=$4;
$port=$5;
} elsif($HTTP_PROXY =~ /^(http:\/\/|)(.+?):(\d+)/) {
$host=$2;
$port=$3;
}
$url="http://$CDDB_HOST".$url." HTTP/1.0";
}
print STDERR "cddb: connecting to $host:$port\n" if $debug;
$socket=IO::Socket::INET->new(PeerAddr=>$host, PeerPort=>$port,
Proto=>"tcp",Type=>SOCK_STREAM) or die "cannot connect to cddb db: $host:$port [$!]";
print STDERR "cddb: http send: GET $url\n" if $debug;
print $socket "GET $url\n";
if($user) {
my $cred = encode_base64("$user:$pass");
print $socket "Proxy-Authorization: Basic $cred\n";
}
print $socket "\n";
print $socket "\n" if $FW;
if($HTTP_PROXY) {
while(<$socket> =~ /^\S+/){};
}
while(<$socket>) {
last if(/^\./);
push @lines,$_;
}
close $socket;
} else {
die "unkown mode: $CDDB_MODE for querying cddb";
}
# xmcd
#
# Track frame offsets:
# 150
# ...
# 210627
#
# Disc length: 2952 seconds
#
# Revision: 1
# Submitted via: xmcd 2.0
#
for(@lines) {
last if(/^\./);
next if(/^\d\d\d/);
push @{$cd{raw}},$_;
#TTITLE0=Bitch (Edit)
if(/^TTITLE(\d+)\=\s*(.*)/) {
my $t= $2;
chop $t;
$cd{frames}[$1]=$toc->[$1]->{frames};
$cd{data}[$1]=$toc->[$1]->{data};
unless (defined $cd{track}[$1]) {
$cd{track}[$1]=$t;
} else {
$cd{track}[$1]=$cd{track}[$1].$t;
}
} elsif(/^DYEAR=\s*(\d+)/) {
$cd{'year'} = $1;
} elsif(/^DGENRE=\s*(\S+.*)/) {
my $t = $1;
chop $t;
$cd{'genre'} = $t;
} elsif(/^\#\s+Revision:\s+(\d+)/) {
$cd{'revision'} = $1;
}
}
$cd{tno}=$#{$cd{track}}+1;
$cd{frames}[$cd{tno}]=$toc->[$cd{tno}]->{frames};
return %cd unless($multi);
push @r,\%cd;
$i++;
}
return @r;
( run in 0.650 second using v1.01-cache-2.11-cpan-d7a12ab2c7f )