Hello monks,

I know enough perl to be bad; however I live in a unix userland and some things are more universally accepted than others, one of them being perl. I usually play around in php, but writing this sort of script in php seems wrong.

My goal was for it to be understandable and log songs played via pianobar to csv for use with other things. What ways could this be improved? Any feedback is appreciated.

//ulterior_modem

Script.

use strict; use warnings; # this holds all of the lines output by pianobar. my @input = <STDIN>; # lines parsed into hash. my %data; # file we want to write output to my $file = '/home/ulterior/pandora.log'; # assembled CSV line. my $line; # last line of logfile. my $lastline; # remove newlines from end of all values in array. chomp @input; # build hash from contents of array. foreach my $var (@input) { (my $key, my $value) = split(/\=/, $var); $data{$key} = $value; } # check to see if all the field we want are defined. if (defined($data{title}) && defined($data{artist}) && defined($data{album}) && defined($data{songStationName})) { # compose csv line with/without album art. if (defined($data{coverArt})) { $line = '"'.$data{title}.'","'.$data{album}.'","'.$data{artist}.'"," +'.$data{songStationName}.'","'.$data{coverArt}.'"'."\n"; } else { $line = '"'.$data{title}.'","'.$data{album}.'","'.$data{artist}.'" +,"'.$data{songStationName}.'"'."\n"; } } # check to see if log file exists. if (-e $file) { # check to see if the last line is the same to avoid duplication. $lastline = qx/tail -n 1 $file/; if ($line eq $lastline) { exit(0); } # write csv line to file. else { open(HANDLE, ">>", $file); print(HANDLE "$line"); close(HANDLE); } }

Sample data.

artist=Bastille title=Pompeii album=Pompeii (Remixes) coverArt=http://cont-2.p-cdn.com/images/public/amz/9/5/3/6/800026359_5 +00W_500H.jpg stationName=QuickMix songStationName=Major Tom Radio pRet=1 pRetStr=Everything is fine :) wRet=1 wRetStr=Everything's fine :) songDuration=214 songPlayed=214 rating=0 detailUrl=http://www.pandora.com/bastille/pompeii-remixes/pompeii?dc=2 +32&ad=1:23:1:47805::0:msn:0:0:581:307:IN:18167:0:0:0:0:6:0 stationCount=74 station0=28 Days Radio station1=And so on...

Replies are listed 'Best First'.
Re: RFC: pianobar event example
by RichardK (Parson) on Aug 14, 2014 at 12:13 UTC

    Just to save some typing you could have written :-

    $line = '"'.$data{title}.'","'.$data{album}.'","'.$data{artist}.'" +,"'.$data{songStationName}.'"'; if defined($data{coverArt}) { $line .= ',"' . $data{coverArt} . '"' ; } $line .= "\n";

    But building CSV lines & quoting fields always gets a bit messy, so you might like to look at Text::CSV which knows how to get it right.

    Then your code could look something like this :-

    my @values = map { $data{$_} } qw/title album artist .../; $csv->combine(@values); $line = $csv->string();
      could even save more typing with a hash slice:
      $line = join',', map {qq/"$_"/} @data{qw/title album artist songSt +ationName/};
      although perhaps looking more cryptic, makes inserting and rearranging the columns easier.
      Your Text::CSV example would have
      $csv->combine(@data{qw/title album artist songStationName/});
Re: RFC: pianobar event example
by nevdka (Pilgrim) on Aug 14, 2014 at 00:25 UTC

    When you're building $line you can replace the concatenation operators and ' marks by using qq:

    $line = qq("$data{title}","$data{album}","$data{artist}","$data{songSt +ationN­ame}","$data{coverArt}"\n);

    The documentation is here: Quote and Quote like Operators