Skip to content

Instantly share code, notes, and snippets.

@gubi
Last active February 7, 2017 15:25
Show Gist options
  • Save gubi/3e4a104e042b2f439214 to your computer and use it in GitHub Desktop.
Save gubi/3e4a104e042b2f439214 to your computer and use it in GitHub Desktop.
Plex Movie Scanner
#
# Copyright (c) 2010 Plex Development Team. All rights reserved.
#
import re, os, os.path
import Media, VideoFiles, Stack, Utils
SeriesScanner = __import__('Plex Series Scanner')
#nice_match = '(.+) [\(\[]([1-2][0-9]{3})[\)\]]'
nice_match = '(.+) [\(\[]([1-2][0-9]{3})[[\s].+[\)\]]'
standalone_tv_regexs = [ '(.*?)( \(([0-9]+)\))? - ([0-9])+x([0-9]+)(-[0-9]+[Xx]([0-9]+))? - (.*)' ]
# Scans through files, and add to the media list.
def Scan(path, files, mediaList, subdirs, language=None, root=None, **kwargs):
# Scan for video files.
VideoFiles.Scan(path, files, mediaList, subdirs, root)
# Check for DVD rips.
paths = Utils.SplitPath(path)
video_ts = Utils.ContainsFile(files, 'video_ts.ifo')
if video_ts is None:
video_ts = Utils.ContainsFile(files, 'video_ts.bup')
if len(paths) >= 1 and len(paths[0]) > 0 and video_ts is not None:
print "Found a DVD"
name = year = None
# Now find the name.
if paths[-1].lower() == 'video_ts' and len(paths) >= 2:
# Easiest case.
(name, year) = VideoFiles.CleanName(paths[-2])
else:
# Work up until we find a viable candidate.
backwardsPaths = paths
backwardsPaths.reverse()
for p in backwardsPaths:
if re.match(nice_match, p):
(name, year) = VideoFiles.CleanName(p)
break
if name is None:
# Use the topmost path.
(name, year) = VideoFiles.CleanName(paths[0])
movie = Media.Movie(name, year)
# Add the video_ts file first.
movie.parts.append(video_ts)
biggestFile = None
biggestSize = 0
for i in files:
if os.path.splitext(i)[1].lower() == '.vob' and os.path.getsize(i) > biggestSize:
biggestSize = os.path.getsize(i)
biggestFile = i
# Add the biggest part so that we can get thumbnail/art/analysis from it.
if biggestFile is not None:
movie.parts.append(biggestFile)
if len(movie.parts) > 0:
movie.guid = checkNfoFile(movie.parts[0], 1)
mediaList.append(movie)
# Check for Bluray rips.
elif len(paths) >= 3 and paths[-1].lower() == 'stream' and paths[-2].lower() == 'bdmv':
(name, year) = VideoFiles.CleanName(paths[-3])
movie = Media.Movie(name, year)
for i in files:
movie.parts.append(i)
mediaList.append(movie)
else:
# Make movies!
for i in files:
file = os.path.basename(i)
(name, year) = VideoFiles.CleanName(os.path.splitext(file)[0])
# If it matches a TV show, don't scan it as a movie.
tv = False
for rx in SeriesScanner.episode_regexps[0:-2]:
if re.match(rx, file):
print "The file", file, "looked like a TV show so we're skipping it (", rx, ")"
tv = True
if tv == False:
# OK, it's a movie
movie = Media.Movie(name, year)
movie.source = VideoFiles.RetrieveSource(file)
movie.parts.append(i)
mediaList.append(movie)
# Stack the results.
Stack.Scan(path, files, mediaList, subdirs)
# Clean the folder name and try a match on the folder.
if len(path) > 0:
folderName = os.path.basename(path).replace(' ', ' ').replace(' ','.')
(cleanName, year) = VideoFiles.CleanName(folderName)
if len(mediaList) == 1 and re.match(nice_match, cleanName):
res = re.findall(nice_match, cleanName)
mediaList[0].name = res[0][0]
mediaList[0].year = res[0][1]
elif len(mediaList) == 1 and (len(cleanName) > 1 or year is not None):
mediaList[0].name = cleanName
mediaList[0].year = year
# Check for a folder with multiple 'CD' subfolders and massage
foundCDsubdirs = {}
for s in subdirs:
m = re.match('cd[ ]*([0-9]+)', os.path.basename(s).lower())
if m:
foundCDsubdirs[int(m.groups(1)[0])] = s
# More than one cd subdir, let's stack and whack subdirs.
if len(foundCDsubdirs) > 1:
name, year = VideoFiles.CleanName(os.path.basename(path))
movie = Media.Movie(name, year)
movie.guid = checkNfoFile(os.path.dirname(foundCDsubdirs.values()[0]), 1)
keys = foundCDsubdirs.keys()
keys.sort()
for key in keys:
d = foundCDsubdirs[key]
subFiles = []
for f in os.listdir(d):
subFiles.append(os.path.join(d,f))
VideoFiles.Scan(d, subFiles, mediaList, [], None)
subdirs.remove(d)
movie.parts += subFiles
if len(movie.parts) > 0:
mediaList.append(movie)
# See if we can find a GUID.
for mediaItem in mediaList:
if mediaItem.guid is None:
mediaItem.guid = checkNfoFile(mediaItem.parts[0], len(mediaList))
if len(mediaList) == 1:
if mediaList[0].source is None:
mediaList[0].source = VideoFiles.RetrieveSource(path)
# Finally, if any of the subdirectories match a TV show, don't enter!
whack = []
for dir in subdirs:
for rx in standalone_tv_regexs:
res = re.findall(rx, dir)
if len(res):
whack.append(dir)
for w in whack:
subdirs.remove(w)
def checkNfoFile(file, fileCount):
try:
path = None
# Depending on how many media files we have, check differently.
if fileCount == 1:
# Look for any NFO file.
for f in os.listdir(os.path.dirname(file)):
if f[-4:].lower() == '.nfo':
path = os.path.join(os.path.dirname(file), f)
break
else:
# Look for a sidecar NFO file.
path = os.path.splitext(file)[0] + '.nfo'
if path is not None and os.path.exists(path):
nfoText = open(path).read()
m = re.search('(tt[0-9]+)', nfoText)
if m:
return m.groups(1)[0]
except:
print "Warning, couldn't read NFO file."
return None
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment