#!/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(){ 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; }