#!/bin/perl
# NO usage: du -a /mnt/mp3 |sed 's/^[0-9]* //g'|sort |du2map > /tmp/all.map
# YES usage: du -a /mnt/mp3 |sed 's/^[0-9]* //g'|grep '\.(mp3|ogg)''?$' |du2map /mnt/mp3 > /tmp/rnew.map
# cat /tmp/r.du |sed 's/^[0-9]* //g'|grep '\.(mp3|ogg)''?$' |du2map > /tmp/rnew.map
$rootdir = $ARGV[0];
shift;
$prefix = $rootdir .'/';
$curlvl=0;
while (<>){
chomp;
s/^'(.*)'$/\1/;
s/''/'/g;
s/^$prefix//;
@parts = split('/', $_);
parts("\t", "", "", 0, @parts);
}
toleft(0);
sub parts {
my($indent, $path, $fileprefix, $lvl, @parts) = @_;
if (@parts == 1){
track($indent, $path, $fileprefix, $lvl, $parts[0]);
} else {
work($indent, $path, $fileprefix, $lvl, @parts);
}
}
sub gettags {
my($file)= @_;
my($artist, $title, $album, $track, $year, $comment) = ('','', '', '', '','');
my($tag) = 'games/mp3tag';
my($BUFSIZ) = 1024; # size of chunks we try to read
my($debug) = 0;
# $file =~ s/'/''/g;
# $file = "'".$file."'";
# $file =~ s/ /\\ /g;
print STDERR "games/mp3tag $file \n";
pipe(TAG_OUT,WOFD); # Open pipes that will link child and parent
if (($cpid = fork()) == 0) { # in child
close(TAG_OUT);
close(STDOUT); # attach stdout to pipe
open(STDOUT,">&WOFD");
$| = 1; # is this really needed?
@cmd=($tag, $file); # construct tag command line.
exec $tag @cmd; # tag it
die "exec: $tag: $!\n"; # or die
}
# in parent
close(WOFD);
# process results.
while(<TAG_OUT>){
chomp();
# print STDERR "\t$_\n";
if (/^artist: *(.*)/) { $artist = $1};
if (/^title: *(.*)/) { $title = $1};
if (/^album: *(.*)/) { $album = $1};
if (/^track: *(.*)/) { $track = $1};
if (/^year: *(.*)/) { $year = $1};
if (/^comment: *(.*)/) { $comment = $1};
}
if ($year == 0) {
$year = '';
}
return($artist, $title, $album, $track, $year, $comment);
}
sub enc {
my($s) = @_;
$s =~ s/ /~/g;
return $s;
}
sub addencfield {
my($field, $val, $indent) = @_;
if ($val ne "") {
$val =~ s/^[ \t]*//g;
$val =~ s/[ \t]*$//g;
$s = enc($val);
# print STDERR "addencfield($val) -> $s\n";
print $indent."\t".$field." = ".$s."\n";
}
}
sub addtext {
my($val, $indent) = @_;
if ($val ne "") {
# print STDERR "addtext($val)\n";
print $indent."\t".$val."\n";
}
}
sub track {
my($indent, $path, $fileprefix, $lvl, $name)= @_;
my($txt) = $name;
print STDERR "TRACK lvl=$lvl; curlvl=$curlvl path=$path name=$name\n";
toleft($lvl);
my($artist, $title, $album, $track, $year, $comment) = gettags("$rootdir/$path$name");
print STDERR "($artist)($title)($album)($track)($year)($comment)\n";
$txt =~ s/\.(mp3|ogg)$//;
print $indent."track {"."\n";
addencfield("artist", $artist, $indent);
addencfield("title", $title, $indent);
addencfield("album", $album, $indent);
addencfield("tracknr", $track, $indent);
addencfield("year", $year, $indent);
print $indent."\t"."$txt"."\n";
addtext($comment, $indent);
print $indent."\t"."file {$fileprefix$name}"."\n";
print $indent."}"."\n";
if ($track ne "") {
$has_tracknr = 1;
}
}
sub work {
my($indent, $path, $fileprefix, $lvl, @parts)= @_;
my($part)= shift(@parts);
# avoid having a separate 'work level' for directory named mp3
if ($part eq 'mp3') {
parts($indent, $path.$part.'/', $fileprefix.$part.'/', $lvl, @parts);
} else {
if ($val{$lvl} ne $part) {
if ($has_tracknr){
print $indent."\t"."key {tracknr}"."\n";
}
toleft($lvl);
toright($indent, $path, $lvl, $part);
$val{$lvl} = $part;
}
parts($indent."\t", $path.$part.'/', $fileprefix, $lvl+1, @parts);
}
}
sub toleft {
my($lvl) = @_;
# print STDERR "toleft in lvl=$lvl; curlvl=$curlvl\n";
while($curlvl > $lvl){
$curlvl--;
print STDERR "toleft backdent lvl=$lvl; curlvl=$curlvl\n";
print $indent{$curlvl}."}"."\n";
undef $indent{$curlvl};
}
if ($lvl >$curlvl) {
$curlvl = $lvl;
}
# print STDERR "toleft out lvl=$lvl; curlvl=$curlvl\n";
}
sub toright {
my($indent, $path, $lvl, $name)= @_;
print $indent."work {"."\n";
print $indent."\t"."$name"."\n";
print $indent."\t"."path {$name}"."\n";
print $indent."\t"."command {sort}"."\n";
print STDERR "toright todent lvl=$lvl; curlvl=$curlvl\n";
$indent{$lvl} = $indent;
$curlvl = $lvl;
$has_tracknr = 0;
}
# some support routines for the select code.
sub addBits {
local($fd) = @_;
vec($fileDescs, $fd, 1) = 1;
$fds{$fd} = 1;
}
sub delBits {
local($fd) = @_;
vec($fileDescs, $fd, 1) = 0;
delete $fds{$fd};
}
sub allEofBits {
! keys %fds;
}
sub printVec {
local($v) = @_;
local($i, $result);
for ($i = (8*length($v)) - 1; $i >= 0; $i--) {
$result .= (vec($v, $i, 1)) ? "1" : "0";
}
$result;
}
|