Last active
February 7, 2017 15:25
-
-
Save gubi/3e4a104e042b2f439214 to your computer and use it in GitHub Desktop.
Plex Movie Scanner
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# | |
# 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