rendered paste body#!/usr/bin/python
import os
import sys
import getopt
import shutil
from mutagen.id3 import ID3
from mutagen.flac import FLAC
from mutagen.oggvorbis import OggVorbis
#encoders and decoders
MP3_ENCODER = "lame --silent -r -x --vbr-new -m s -V 0 --tt $TITLE$ --ta $ARTIST$ --tl $ALBUM$ --ty $DATE$ --tn $TRACK$ --tg $GENRE$ - $FILE$ 2>/dev/null"
OGGVORBIS_ENCODER = "oggenc -Q -r -q 8 -t $TITLE$ -a $ARTIST$ -l $ALBUM$ -d $DATE$ -N $TRACK$ -G $GENRE$ - -o $FILE$ 2>/dev/null"
FLAC_DECODER = "flac -s -d --force-raw-format --sign=signed --endian=little $FILE$ -o - 2>/dev/null"
OGGVORBIS_DECODER = "oggdec -Q -s 1 -e 0 -R $FILE$ 2>/dev/null"
MP3_DECODER = "madplay -q -o raw:- $FILE$ 2>/dev/null"
#associated formats
FLAC_FORMAT = "flac"
OGGVORBIS_FORMAT = "ogg"
MP3_FORMAT = "mp3"
SUPPORTED_TARGETS = [MP3_FORMAT,OGGVORBIS_FORMAT]
SUPPORTED_SOURCES = [MP3_FORMAT,OGGVORBIS_FORMAT,FLAC_FORMAT]
#set option defaults
target_format = MP3_FORMAT
target_encoder = MP3_ENCODER
source = os.getcwd()
target = os.getcwd()
verbose = False
def reencode(source_file,target_file):
if (verbose):
print("Found "+source_file);
source_format = source_file.split(".").pop()
target_file = target_file.replace(source_format,target_format)
#if the file exists at the destination already we'll skip it
if (os.path.isfile(target_file)):
if (verbose):
print("Target exists.");
return
if (source_format in SUPPORTED_SOURCES):
#if the formats are the same, why reencode?
if ((target_format in SUPPORTED_TARGETS) and (source_format == target_format)):
shutil.copyfile(source_file,target_file)
if (verbose):
print("Copying to "+target_file);
return
#retrieve the metadata and set the decoder appropriately
if (source_format == FLAC_FORMAT):
audio = FLAC(source_file)
source_decoder = FLAC_DECODER
if (source_format == MP3_FORMAT):
audio = ID3(source_file)
source_decoder = MP3_DECODER
if (source_format == OGGVORBIS_FORMAT):
audio = OggVorbis(source_file)
source_decoder = OGGVORBIS_DECODER
command = target_encoder.replace("$FILE$","\""+target_file+"\"")
command = command.replace("$TITLE$","\""+audio["title"].pop()+"\"")
command = command.replace("$ARTIST$","\""+audio["artist"].pop()+"\"")
command = command.replace("$ALBUM$","\""+audio["album"].pop()+"\"")
command = command.replace("$GENRE$","\""+audio["genre"].pop()+"\"")
command = command.replace("$DATE$","\""+audio["date"].pop()+"\"")
command = command.replace("$TRACK$","\""+audio["tracknumber"].pop()+"\"")
command = source_decoder.replace("$FILE$","\""+source_file+"\"")+" | "+command
if (verbose):
print("Reencoding to "+target_file);
os.popen(command)
else:
if (verbose):
print("Unsupported format.");
#recursively walk through directories, in turn walking through
#subdirectories and processing files accordingly
def recursive_walk(running_directory=""):
for abstract_source_object in os.listdir(os.path.join(source,running_directory)):
source_object = os.path.join(os.path.join(source,running_directory),abstract_source_object)
if os.path.isfile(source_object):
reencode(source_object,os.path.join(os.path.join(target,running_directory),abstract_source_object))
else:
if os.path.isdir(source_object):
target_directory = os.path.join(os.path.join(target,running_directory),abstract_source_object)
if not (os.access(target_directory,os.F_OK+os.W_OK+os.X_OK)):
os.mkdir(target_directory,0755)
recursive_walk(os.path.join(running_directory,abstract_source_object))
#get arguments and set options
try:
opts, args = getopt.getopt(sys.argv[1:], "s:d:t:v", ["source=", "destination=","target=","verbose"])
for opt,arg in opts:
if (opt in ("-v","--verbose")):
verbose = True
if (opt in ("-s","--source")):
source = arg
if (opt in ("-d","--destination")):
target = arg
if (opt in ("-t","--target")):
target_format = arg
#set the encoder
if (target_format == FLAC_FORMAT):
target_encoder = FLAC_ENCODER
if (target_format == MP3_FORMAT):
target_encoder = MP3_ENCODER
if (target_format == OGGVORBIS_FORMAT):
target_encoder = OGGVORBIS_ENCODER
except getopt.GetoptError:
sys.exit(str(getopt.GetoptError))
#check to make sure the directories we're going to use are OK
if not (os.access(source,os.F_OK+os.R_OK+os.X_OK)):
sys.exit("Source directory doesn't exist or isn't accesible!")
if not (os.access(target,os.F_OK+os.W_OK+os.X_OK)):
sys.exit("Destination directory doesn't exist or isn't accesible!")
if not (target_format in SUPPORTED_TARGETS):
sys.exit("Invalid target format!")
#start our walk
recursive_walk()