I ended up writing a much improved version of my python script that does what SABnzbd's sorter does without relying on categories. I'll post it here if anyone else is interested in using it, it will look through all files in the START_PATH directory and rename them if it recognizes them as TV shows, it matches most naming formats. It will then move them to DESTINATION_PATH\Show\Season X (if it has seasons)\Show S0XEXX.ext. So if a show has a date it will be put into the Dest_path\Show\ directory. It will also rename and move any files that it recognizes as being in the wrong place.
My script should be Linux/OSX compatible too since it's written in Python.
Edit: I made some refinements to the code so it will also match files with spaces and underscores and removed some unnecessary parts
Edit2: I fixed a bug where the script crashed if movies were present. Added movie rename support since it coincided with fixing this bug.
Edit3: Added support for shows like S01E02E03
# This script sorts tv and movie files by identifying frequently used naming schemes
#
# TV files sent to tvdest\show\season\Show S0x E0x.ext
# Movie files sent to movdest\Movie Title.ext
#
# Read comments & edit formatting section of script yourself to modify the file name
# Edit the main loop to change how directories are laid out
#
# Edit the paths below to specify the starting path, tv and movie destination directories.
TV_DESTINATION = "D:\\Videos\\TV"
MOV_DESTINATION = "D:\\Videos\\Movies"
START_PATH = "D:\\Downloads\\Usenet"
##################################################################################
import os
MONTHS = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]
def generate_newname(filename):
""" Parses a filename and returns the new filename if its destination is different from the old location """
global TITLE, SEASON, TYPE
elems = str.split(str.lower(filename.replace("_", ".").replace(" ", ".")), '.') # split the filename by periods etc.
ext = elems[-1]
if ext in ["mkv", "avi", "ts"]: # Edit what extensions you want it to match
TYPE = "tv"
showname = []
for elem in elems[0:-1]: # parse the elements
if not str.isdigit(elem[0:4]): # shows w/o a date
if elem[0] == 's' and elem[1].isdigit():
temp = elem.replace('s', '').split('e')
season = temp[0]
episode = temp[1] if len(temp) == 2 else 'E'.join(temp[1:3]) # s01e01 OR s01e01e02
break
elif elem[0].isdigit():
if elem[1].isdigit():
if elem[2].isdigit() and elem[-1] != 'p' and elem[-1] != 'i': # do not match 720p, 1080i, etc.
if elem[1] == '0': # 101
season = '0' + elem[0]
episode = elem[1:3]
elif len(elem) == 4: # 0101
season = elem[0:2]
episode = elem[2:4]
elif elem[2] == 'x': # 01x01
season, episode = elem.split('x')
elif elem[1] == 'x': # 1x01
season, episode = elem.split('x')
season = '0' + season
break # season found, showname should be before it so break
else: # assume this is a part of showname
showname.append(elem)
else: # this show is probably named using a date, assume year.month.day format
i = elems.index(elem)
TITLE = titler(' '.join(showname))
SEASON = ""
if 'p' in elems[i+1] or 'i' in elems[i+1]: # Looks like a movie. Handle as movie.title.year.quality.otherstuff.ext
TYPE = "movie"
return "%s.%s" % (TITLE, ext) # Rename to Movie Title.ext, elems[i] is year and elems[i+1] is quality
return "%s %s %s %s.%s" % (TITLE, MONTHS[int(elems[i+1]) - 1], elems[i+2], elems[i], ext)
TITLE = titler(' '.join(showname))
SEASON = "Season %s" % (season[-1] if season[0] == '0' else season)
return "%s S%s E%s.%s" % (TITLE, season, episode, ext)
def titler(x): # python's title capitalizes after apostrophes... deal with it for certain cases
return str.title(x).replace("'S", "'s").replace(" In", " in").replace("'T", "'t").replace("'V", "'v").\
replace(" Of ", " of ").replace("Its", "It's").replace("Us", "").strip(" ")
for root, dirs, files in os.walk(START_PATH): # Processes all the files in START_PATH
for old in files:
new = generate_newname(old)
if new:
if TYPE == "tv":
newdir = os.path.join(TV_DESTINATION, TITLE)
if not os.path.exists(newdir): # If the new show directory doesn't exist, create it
os.mkdir(newdir)
newdir = os.path.join(newdir, SEASON)
if not os.path.exists(newdir) and SEASON != "": # If the new season directory doesn't exist, create it
os.mkdir(newdir)
new = os.path.join(newdir, new)
else: # movie
new = os.path.join(MOV_DESTINATION, new)
old = os.path.join(root, old)
if not (os.path.exists(new) or TITLE[0].isdigit()): # make sure there isn't a duplicate file,
try:
os.rename(old, new)
except:
pass