#!/usr/bin/env python # This program transcode-syncs SRCDIR to DSTDIR. Basic algorithm: # # For every subpath+filename in SRCDIR: # If no equivalent (transcoded or linked) exists in DSTDIR: # Execute the appropriate command to transcode or link the subpath into SRCDIR # For every subpath+filename in DSTDIR: # If no equivalent exists in SRCDIR: # Remove the subpath from DSTDIR # # SRCDIR is never written to, only read. The resulting DSTDIR is a copy of SRCDIR that can # be read by the PS3 (or whatever) and has minimal size. # Transcode commands can be adapted in the transcoders list. Currently, MKVs get transcoded # into MPEG2 VOBs giving a copy of the original, everything else is just linked. # # To use this, you need the command line tools referenced in TRANSCODERS. For me, this is # currently mencoder and plain old ln :-) import os, sys, shutil SRCDIR="/Volumes/Data/Movies" DSTDIR="/Volumes/Data/Movies PS3" # Adapt TRANSCODERS to do what you want. The format is: # Key: InputFileSuffix # Value: Tuple (OutputFileSuffix, ShellCommandToGetThere) # If InputFileSuffix is equal to OutputFileSuffix, the name of the output file will be the # same as that of the input file. If not, the output file will be called # "InputFileName.OutputFileSuffix" # I.e. in the example below, a file named "SRCDIR/test/dummy.mkv" will be transcoded by # mencoder into "DSTDIR/test/dummy.mkv.vob". TRANSCODERS = { "mkv": ("vob", 'mencoder -oac lavc -of mpeg -lavfopts format=asf -mpegopts format=mpeg2:muxrate=500000:vbuf_size=1194:abuf_size=64 -ovc lavc -lavcopts autoaspect=1:vcodec=mpeg2video:keyint=3:vqscale=2:vqmin=3 -subcp cp1252 -subfont /System/Library/Frameworks/JavaVM.framework/Versions/1.5.0/Home/lib/fonts/LucidaSansRegular.ttf -subfont-text-scale 3 -subfont-outline 1 -subfont-blur 1 -subpos 98 -subdelay 20000 -mc 0 -noskip "%s" -o "%s"'), "avi": ("avi", 'ln -s "%s" "%s"'), "vob": ("vob", 'ln -s "%s" "%s"') } def mkfile_if_not_exist(srcfname, dstfname): try: suffix = srcfname.split(".")[-1] dstsuffix, command = TRANSCODERS[suffix] except: print "Ignoring '"+srcfname+"' (unknown suffix)." return if suffix != dstsuffix: dstfname = dstfname + "." + dstsuffix if os.path.exists(dstfname): print "Ignoring '"+srcfname+"' ('"+dstfname+"' exists)." return if os.path.exists(dstfname + ".LOG"): print "Error: '"+dstfname+".LOG' exists!" return print "Making '"+dstfname+"' from '"+srcfname+"'" # make lock(log)file logfname = dstfname+".LOG" open(logfname, "w").close() # fork here cmdstr = command % (srcfname, dstfname) + ' > "%s" 2>&1' % logfname print "Executing '"+cmdstr+"'" retval = os.system(cmdstr) if retval == 0: print "OK" os.remove(logfname) else: print "Error" def rmfile_if_not_exist(srcfname, dstfname): if dstfname.endswith(".LOG"): print "'"+dstfname+"' is a log file. Not touching it." return print "Checking for '"+dstfname+"'..." # Are the filenames equal and source is still there? Bail. if os.path.exists(srcfname): print "\t'"+srcfname+"' still exists. Bail." return # Let's see how the original filename might look for suffix in TRANSCODERS.keys(): dstsuffix, command = TRANSCODERS[suffix] if suffix != dstsuffix: srcfname2 = srcfname[:-len(dstsuffix)-1] if os.path.exists(srcfname2): print "\t'"+srcfname2+"' still exists. Bail." return print "\tNo good equivalent found. Removing it." os.remove(dstfname) try: os.remove(dstfname+".LOG") except: pass # provide (link or transcode) files that are in SRCDIR but not (yet) in DSTDIR print "\nPROVIDE\n-------\n" for (srcpath, dirnames, filenames) in os.walk(SRCDIR): # create subpath of SRCDIR under DSTDIR if it doesn't exist yet dstpath = DSTDIR + srcpath[len(SRCDIR):] if not os.path.exists(dstpath): print "Making '"+dstpath+"'" os.mkdir(dstpath) # provide files (link or transcode) for fname in filenames: dstfname = dstpath + "/" + fname srcfname = srcpath + "/" + fname mkfile_if_not_exist(srcfname, dstfname) print "\nCLEANUP\n-------\n" # cleanup files and directories that are in DSTDIR but not (anymore) in SRCDIR for (dstpath, dirnames, filenames) in os.walk(DSTDIR): # cleanup entire subpaths that don't exist anymore srcpath = SRCDIR + dstpath[len(DSTDIR):] if not os.path.exists(srcpath): print "'"+srcpath+"' has gone away, removing '"+dstpath+"'" shutil.rmtree(dstpath) # cleanup files for fname in filenames: dstfname = dstpath + "/" + fname srcfname = srcpath + "/" + fname rmfile_if_not_exist(srcfname, dstfname)