# # CDDB - Read the CDDB entry for an audio CD in your drive # # This module/script gets the CDDB info for an audio cd. You need # LINUX, a cdrom drive and an active internet connection in order # to do that. # # (c) 2004 Armin Obersteiner # # LICENSE # # This library is released under the same conditions as Perl, that # is, either of the following: # # a) the GNU General Public License Version 2 as published by the # Free Software Foundation, # # b) the Artistic License. # package CDDB_cache; use strict; use vars qw($VERSION @ISA @EXPORT @EXPORT_OK $debug $dir $readonly $grep); require Exporter; @ISA = qw(Exporter AutoLoader); # Items to export into callers namespace by default. Note: do not export # names by default without a very good reason. Use EXPORT_OK instead. # Do not simply export all your public functions/methods/constants. @EXPORT_OK = qw( get_cddb get_discids ); $VERSION = '1.0'; use CDDB_get; use File::Find; use Data::Dumper qw(Dumper); #$debug=1; $dir="/tmp/xmcd"; my $CD_DEVICE = "/dev/cdrom"; sub get_discids { my $cd=shift; return CDDB_get::get_discids($cd); } my @files; sub get_cddb { my $config=shift; my $diskid=shift; if($debug) { print STDERR "dir: [$dir] readonly [$readonly] grep [$grep]\n"; } $config->{multi}=0; $CD_DEVICE = $config->{CD_DEVICE} if (defined($config->{CD_DEVICE})); my $did=$diskid; $did=CDDB_get::get_discids($CD_DEVICE) unless($did); #print Dumper($did); printf STDERR "%08x %08lx\n", $did->[0], $did->[0] if($debug); my $sid = sprintf "%08x", $did->[0]; my $id = sprintf "%08x %d", $did->[0], $did->[1]; for(0..$did->[1]-1) { $id.=" ".$did->[2]->[$_]->{frames}; } $id.=" ".int($did->[2]->[$did->[1]]->{frames}/75); print STDERR "id: $id\n" if $debug; @files=(); if($grep) { find({ wanted => sub { next unless -f $File::Find::name; my $tid=`grep -H $sid $File::Find::name`; if($tid =~ /\S+/) { push @files, $File::Find::name; } }, follow=>1}, $dir); } else { find({ wanted => sub { if($_ eq $sid) { push @files, $File::Find::name; } }, follow=>1}, $dir); } print STDERR Dumper(\@files) if $debug; my $file; my $found; for(@files) { open IN,$_; undef $/; $file=; close IN; my ($fid)=$file =~ /DISCID=(\S+)/i; my ($len)=$file =~ /Disc length: (\d+) seconds/i; my ($s)=$file =~ /Track frame offsets:\s+(.*)\s+Disc length/si; my $t=""; my @tr=split /#/,$s; my $c=0; for(@tr) { next unless /(\d+)/; $c++; $t.=" $1"; last if($c>=$did->[1]); } my $tid="$fid $c$t $len"; if($tid eq $id) { $found=$_; last; } } my $toc=$did->[2]; my %cd; if($found) { print STDERR "CDDB_cache: reading from file: $found\n"; my @lines=split /\n/,$file; for(@lines) { push @{$cd{raw}},$_."\n"; #TTITLE0=Bitch (Edit) if(/^TTITLE(\d+)\=\s*(.*)/) { my $t= $2; chomp $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; chomp $t; $cd{'genre'} = $t; } } $cd{tno}=$#{$cd{track}}+1; $cd{frames}[$cd{tno}]=$toc->[$cd{tno}]->{frames}; $cd{id}=$sid; my ($at)=$file=~/DTITLE=(.*?)\n/; my ($artist,$title); #chop $at if($at =~ /\r/); chomp $at; if($at =~ /\//) { ($artist,$title)= $at =~ /^(.*?)\s\/\s(.*)/; } else { $artist=$at; $title=$at; } $cd{artist}=$artist; $cd{title}=$title; my ($cat) = $found =~ /$dir\/(\S+?)\/$sid/; $cd{cat}=$cat; } else { print STDERR "CDDB_cache: reading from network\n"; %cd=CDDB_get::get_cddb($config,$diskid); } print STDERR Dumper(\%cd) if $debug; unless($readonly || $found) { my $file=$dir."/$cd{cat}/$cd{id}"; my $ddir=$dir."/$cd{cat}"; mkdir $ddir,0755; open OUT,">$file"; for(@{$cd{raw}}) { print OUT $_; } close OUT; } return %cd; } 1; __END__