Tuesday, February 9, 2016

Perl: iTunes XML to CSV (Without XML Parser)

itunes.pl

use constant MODE_NONE => 0;
use constant MODE_FIND_BRAKET_NAME => 1;
use constant MODE_FIND_VALUE =>2;
use constant FALSE =>0;
use constant TRUE => 1;

$mode = MODE_NONE;
$tagName = "";
$value = "";
$keyValue = "";
$openTag = FALSE;
$closeTag = FALSE;
$isTrack = FALSE;

@itunestags = ("Track ID","Name","Artist","Album Artist","Composer","Album","Grouping","Kind","Size","Total Time","Disc Number","Disc Count","Track Number","Track Count","Year","Date Modified","Date Added","Bit Rate","Sample Rate","Play Count","Play Date","Play Date UTC","Skip Count","Skip Date","Release Date","Rating","Album Rating","Album Rating Computed","Normalization","Artwork Count","Persistent ID","Track Type","Protected","Purchased","Location","File Folder Count","Library Folder Count");

print "Track ID,Name,Artist,Album Artist,Composer,Album,Year\n";

while (defined($char = getc())){

        if ($char eq "<"){
                $mode = MODE_FIND_BRAKET_NAME;
                $tagName = "";
        }elsif ($char eq ">"){
                if ($closeTag)
                {
                        if ($value eq "Tracks"){
                                $isTrack = TRUE;
                        }elsif ($value eq "Playlists"){
                                $isTrack = FALSE;
                        }elsif ($value ~~ @itunestags){
                                $keyValue = $value;
                        }else{
                                $value =~ s/"/""/g;

                                if ($value =~ /[,"]/){
                                        $value = "\"" . $value . "\"";
                                }

                                $value =~ s/&#38;/&/g;

                                if ($keyValue ~~ @itunestags){
                                        $track{$keyValue} = $value;
                                }
                        }

                        if ($isTrack && $tagName eq "dict"){
                                printf "%s,%s,%s,%s,%s,%s,%s\n", $track{'Track ID'}, $track{'Name'}, $track{'Artist'}, $track{'Album Artist'}, $track{'Composer'}, $track{'Album'},$track{'Year'};
                                $keyValue ="";
                                %track=();

                        }

                        $value = "";
                        $closeTag = FALSE;
                }else{
                        $mode = MODE_FIND_VALUE;
                        $value = "";
                }
        }else{
                if ($mode == MODE_FIND_BRAKET_NAME){
                        if ($char eq "/"){
                                $closeTag = TRUE;
                        }else{
                                $tagName .= $char;
                        }
                }elsif($mode == MODE_FIND_VALUE){
                        $value .= $char;
                }
        }
}

Bash command:

$ cat ./itunes.xml | perl ./itunes.pl