#!/usr/bin/perl
# ogg_convert_and_recompress_directories.pl
# Version: 0.1
#
# © 2007-2008 Timo Jyrinki <timo.jyrinki@iki.fi>
#
# Requirements: perl, vorbis-tools
# Optional: mpg321 (for mp3 decoding, otherwise not needed)
#
# TODO:
# - mp3 tag conversion
# - code's variable names are a bit bad... ("subdirectory" may be a file)
#
# Version history:
# 0.1 - First public release. Used on GBs of FLAC / Ogg Vorbis collection.
#       MP3 tested, too.
#
# Licensed under GPLv3 or later, which can be found at
# /usr/share/common-licenses/GPL on Debian and derivatives like Ubuntu
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.

use Getopt::Long;
#use strict;
#use warnings;

my $MUSIC_DIRECTORY;
my $OUTPUT_DIRECTORY;
my @directoryContents;
my $directory="";
my @subDirectoryContents;
my $subDirectory="";
my $exitFlag="";

GetOptions (
  "musicdir=s" => \$MUSIC_DIRECTORY,
  "outputdir=s" => \$OUTPUT_DIRECTORY,
);

if (!$MUSIC_DIRECTORY) {
  print "\nPlease select the music directory with the switch -musicdir\n(eg. -musicdir=/home/shared/music)\n\n";
  $exitFlag = "yes";
}

if (!$OUTPUT_DIRECTORY) {
  print "\nPlease select the output directory with the switch -outputdir\n(eg. -outputdir=/home/shared/music_compressed)\n\n";
  $exitFlag = "yes";
}

if ($exitFlag =~ /yes/) {
  exit;
}

sub handle_subdir($) {
  my $directory=$_[0];

  opendir (SUBDIR_HANDLE, "$MUSIC_DIRECTORY/$directory");
  my @subDirectoryContents = readdir(SUBDIR_HANDLE);

  foreach $subDirectory (@subDirectoryContents) {
    open (SUBDIR_FILE_HANDLE, "$MUSIC_DIRECTORY/$directory/$subDirectory");
# Check if a file entry in the subdirectory is a subsubdirectory
    if (-d SUBDIR_FILE_HANDLE && $subDirectory !~ /^.$/ && $subDirectory !~ /^..$/) {
      print "subdirectory: $subDirectory\n";
      handle_subdir("$directory/$subDirectory");
    }
    elsif (-f SUBDIR_FILE_HANDLE && $subDirectory !~ /^.$/ && $subDirectory !~ /^..$/) {
      print "file: $subDirectory\n";
      if ($subDirectory =~ /\.ogg$/) {
        `vorbiscomment -l "$MUSIC_DIRECTORY/$directory/$subDirectory" > /tmp/comm.txt`;
        `mkdir -p "$OUTPUT_DIRECTORY/$directory"`;
        `oggdec "$MUSIC_DIRECTORY/$directory/$subDirectory" -o "$OUTPUT_DIRECTORY/$directory/$subDirectory.wav"`;
        `oggenc -q 2 "$OUTPUT_DIRECTORY/$directory/$subDirectory.wav" -o "$OUTPUT_DIRECTORY/$directory/$subDirectory"`;
        `vorbiscomment -a "$OUTPUT_DIRECTORY/$directory/$subDirectory" -c /tmp/comm.txt`;
        `rm -f "$OUTPUT_DIRECTORY/$directory/$subDirectory.wav"`;
      }
      if ($subDirectory =~ /\.flac$/) {
        `mkdir -p "$OUTPUT_DIRECTORY/$directory"`;
        `oggenc -q 2 "$MUSIC_DIRECTORY/$directory/$subDirectory" -o "$OUTPUT_DIRECTORY/$directory/$subDirectory.ogg"`;
      }
      if ($subDirectory =~ /\.mp3$/) {
        print "mp3, ID tags not handled! Converting to Ogg Vorbis.\n";
        `mkdir -p "$OUTPUT_DIRECTORY/$directory"`;
        `mpg321 --wav "$OUTPUT_DIRECTORY/$directory/$subDirectory.wav" "$MUSIC_DIRECTORY/$directory/$subDirectory"`;
        `oggenc -q 2 "$OUTPUT_DIRECTORY/$directory/$subDirectory.wav" -o "$OUTPUT_DIRECTORY/$directory/$subDirectory.ogg"`;
# Add ID tag handling code here... read from the mp3 and use vorbiscomment
        `rm -f "$OUTPUT_DIRECTORY/$directory/$subDirectory.wav"`;
      }
    }
    close (SUBDIR_FILE_HANDLE);
  }
  closedir (SUBDIR_HANDLE);
}

## Begin main code

opendir (DIR_HANDLE, $MUSIC_DIRECTORY) or die "Could not open directory $MUSIC_DIRECTORY.\n\n";
@directoryContents = readdir(DIR_HANDLE);

print "Music directory: $MUSIC_DIRECTORY.\n\n";
print "Output directory: $OUTPUT_DIRECTORY.\n\n";

foreach $directory (@directoryContents) {
  open (FILE_HANDLE, "$MUSIC_DIRECTORY/$directory");
  if (-d FILE_HANDLE && $directory !~ /^.$/ && $directory !~ /^..$/) {
    print "directory: $directory\n";
    handle_subdir($directory);
  }
  close (FILE_HANDLE);
}
closedir (DIR_HANDLE);

exit;

