pastebin - collaborative debugging tool
kpaste.net RSS


flac import script
Posted by Anonymous on Sat 8th Sep 2012 08:36
raw | new post

  1. #!/usr/bin/perl
  2.  
  3. use 5.14.0;
  4. use strict;
  5. use warnings;
  6. use Cwd qw(abs_path);
  7. use File::Basename qw(basename);
  8. use File::Find qw(find);
  9. use File::Path qw(make_path);
  10. use File::Copy qw(copy);
  11.  
  12. my $library = "/home/sir/Music/Songbird Music";
  13. #my $library = "$ENV{HOME}/test";
  14. my @lacc = qw(EAC "Exact Audio Copy" "XLD X Lossless Decoder" cdparanoia Rubyripper);
  15. my (@log, %files);
  16.  
  17. foreach my $dn (@ARGV) {
  18.         if (! -d $dn) {
  19.                 say "'$dn' is not a directory!";
  20.                 exit;
  21.         }
  22.         find({ wanted => \&action, no_chdir => 1 }, $dn);
  23.         sub action {
  24.                 if (-d) {
  25.                         my $dn = abs_path($File::Find::name);
  26.                         undef %files;
  27.                         @log = getfiles($dn);
  28.                         my $fc = keys(%files);
  29.                         if ($fc > 0) {
  30.                                 say "Importing '$dn'...\n";
  31.                                 import($fc);
  32.                         }
  33.                         else {
  34.                                 say "There are no FLAC files in '$dn'!";
  35.                         }
  36.                 }
  37.         }
  38.        
  39. }
  40.  
  41. if (!@ARGV) {
  42.         my $s = basename($0);
  43.         say "Usage: $s [directory 1] .. [directory N]";
  44.         exit;
  45. }
  46.  
  47. sub gettags {
  48.         my $fn = quotemeta(shift);
  49.         my %alltags;
  50.         open(OUTPUT, '-|', qq{metaflac --no-utf8-convert --export-tags-to=- $fn}) || die "can't run metaflac: $!";
  51.         chomp(my @mflac = (<OUTPUT>));
  52.         foreach (@mflac) {
  53.                 my (@tag, $tagname);
  54.                 @tag = split('=');
  55.                 $tagname = lc($tag[0]);
  56.                 if ($tag[1]) {
  57.                         $tag[1] =~ tr!/\\<>|:;$*"'!!d;
  58.                         push @{$alltags{$tagname}}, $tag[1];
  59.                 }
  60.         }
  61.         close(OUTPUT) || die "can't close metaflac: $!";
  62.         return %alltags;
  63. }
  64.  
  65. sub checktags {
  66.         my $fn = shift;
  67.         my $artist = $files{$fn}{artist}->[0];
  68.         my $album = $files{$fn}{album}->[0];
  69.         if (!$artist || !$album ) {
  70.                 say "'$fn' is NOT tagged!";
  71.                 exit;
  72.         }
  73. }
  74.  
  75. sub getfiles {
  76.         my $dn = shift;
  77.         my @log;
  78.         opendir(my $dh, $dn) or die "Can't open directory '$dn': $!";
  79.         foreach (readdir $dh) {
  80.                 my $fn = "$dn/$_";
  81.                 if (/.flac$/ && -f $fn) {
  82.                         $files{$fn} = { gettags($fn) };
  83.                 }
  84.                 if (/.log$/ && -f $fn) {
  85.                   open(my $text, $fn) or die "Can't open file '$fn': $!";
  86.                   my $line1 = <$text>;
  87.                   close $text or die "Can't close file '$fn': $!";
  88.                   foreach my $req (@lacc) {
  89.                     if ($line1 =~ /$req/) {
  90.                         push(@log, $fn);
  91.                     }
  92.                   }
  93.                 }
  94.         }
  95.         closedir $dh or die "Can't close directory '$dn': $!";
  96.         return(@log);
  97. }
  98.  
  99. sub albumartist {
  100.         my $fn = shift;
  101.         my $tracks = keys %files;
  102.  
  103.         my $artist = $files{$fn}{artist}->[0];
  104.         my %artist;
  105.         my $max;
  106.         if ($tracks == 1) { $max = $tracks } else { $max = $tracks / 2 }
  107.         foreach my $fn (keys %files) { $artist{$files{$fn}{artist}->[0]}++ }
  108.         if (keys(%artist) > $max) {
  109.                 $artist = 'Various Artists';
  110.         }
  111.  
  112.         return $artist;
  113. }
  114.  
  115. sub import {
  116.         my $fc = shift;
  117.         my $cp = 0;
  118.         my $cplog = 1;
  119.         my $total = $fc;
  120.         my ($artist, $album, $albumartist, $discnumber, $newname, $path);
  121.  
  122.  
  123.         foreach my $sf (sort(keys %files)) {
  124.                 checktags($sf);
  125.                 $artist = $files{$sf}{artist}->[0];
  126.                 $album = $files{$sf}{album}->[0];
  127.                 $albumartist = albumartist($sf, $fc);
  128.                 if (exists $files{$sf}{discnumber}->[0]) {
  129.                   $discnumber = $files{$sf}{discnumber}->[0];
  130.                 }
  131.  
  132.                 $path = "$library/$albumartist/$album";
  133.                 if(
  134.                 $cp == 0 &&
  135.                 -d $path
  136.                 ) {
  137.                         say "'$path' already exists!";
  138.                         say "Skipping...\n";
  139.                         return;
  140.                 } else {
  141.                         make_path($path);
  142.                 }
  143.                 my $track = $files{$sf}{tracknumber}->[0];
  144.                 my $title = $files{$sf}{title}->[0];
  145.  
  146.                 if ($discnumber) {
  147.                   $newname = sprintf('%s-%02s. %s.flac', $discnumber, $track, $title);
  148.                 } else {
  149.                   $newname = sprintf('%02s. %s.flac', $track, $title);
  150.                 }
  151.  
  152.                 my $tf = "$path/$newname";
  153.  
  154.                 say "Copying '$sf'\n\tto '$tf'...";
  155.                 copy($sf, $tf) or die "Copy failed: $!";
  156.                 $cp++
  157.         }
  158.         say "Copied $cp / $total files from '$album'.\n";
  159.  
  160.         foreach my $sf (@log) {
  161.  
  162.                 my $tf;
  163.                 if (scalar(@log) > 1) {
  164.                   $tf = "$path/$cplog-$album.log";
  165.                 } else {
  166.                   $tf = "$path/$album.log";
  167.                 }
  168.                        
  169.                 say "Copying '$sf'\n\tto '$tf'...\n";
  170.                 copy($sf, $tf) or die "Copy failed: $!";
  171.                 $cplog++
  172.         }
  173. }

Submit a correction or amendment below (click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.

Syntax highlighting:

To highlight particular lines, prefix each line with {%HIGHLIGHT}




All content is user-submitted.
The administrators of this site (kpaste.net) are not responsible for their content.
Abuse reports should be emailed to us at