fixed some variables, small refactor

if you're using Transmission in Windows use the .bat file
This commit is contained in:
Joel Kåberg 2013-02-18 14:35:47 +01:00
commit 2ba29b4541
3 changed files with 96 additions and 139 deletions

4
TorrentToMedia.bat Normal file
View file

@ -0,0 +1,4 @@
@echo off
echo "Executing nzbToMedia..."
C:\Python27\python.exe C:\Downloaders\nzbToMedia\TorrentToMedia.py %TR_TORRENT_DIR% %TR_TORRENT_NAME%
pause

View file

@ -16,7 +16,7 @@ import autoProcessTV
from nzbToMediaEnv import * from nzbToMediaEnv import *
Logger = logging.getLogger() Logger = logging.getLogger()
logFile = os.path.join(os.path.dirname(sys.argv[0]), "postprocess.log") logFile = os.path.normpath(os.path.join(os.path.dirname(sys.argv[0]), "postprocess.log"))
logging.config.fileConfig(os.path.join(os.path.dirname(sys.argv[0]), "logger.conf")) logging.config.fileConfig(os.path.join(os.path.dirname(sys.argv[0]), "logger.conf"))
fileHandler = logging.FileHandler(logFile, encoding='utf-8', delay=True) fileHandler = logging.FileHandler(logFile, encoding='utf-8', delay=True)
fileHandler.formatter = logging.Formatter('%(asctime)s|%(levelname)-7.7s %(message)s', '%H:%M:%S') fileHandler.formatter = logging.Formatter('%(asctime)s|%(levelname)-7.7s %(message)s', '%H:%M:%S')
@ -33,44 +33,45 @@ Logger.info("Loading config from %s", configFilename)
if not os.path.isfile(configFilename): if not os.path.isfile(configFilename):
Logger.error("You need an autoProcessMedia.cfg file - did you rename and edit the .sample?") Logger.error("You need an autoProcessMedia.cfg file - did you rename and edit the .sample?")
sys.exit(-1) sys.exit(-1)
else:
config.read(configFilename)
# Sick-Beard
tvCategory = config.get("SickBeard", "category")
tvDestination = os.path.normpath(config.get("SickBeard", "outputDirectory"))
# CouchPotato
movieDestination = os.path.normpath(config.get("CouchPotato", "outputDirectory"))
movieCategory = config.get("CouchPotato", "category")
useLink = int(config.get("Torrent", "uselink"))
extractionTool = os.path.normpath(config.get("Torrent", "extractiontool"))
config.read(configFilename) def category_search(inputDirectory, inputCategory, root):
categorySearch = os.path.split(os.path.normpath(inputDirectory)) #Test for blackhole sub-directory.
TV_Cat = config.get("SickBeard", "category") if categorySearch[1] == inputName:
TV_dest = os.path.normpath(config.get("SickBeard", "destination"))
Movie_dest = os.path.normpath(config.get("CouchPotato", "destination"))
Movie_Cat = config.get("CouchPotato", "category")
useLink = int(config.get("Torrent", "uselink"))
extractionTool = config.get("Torrent", "extractiontool")
def category_search(Directory, Category, root):
DirBase = os.path.split(os.path.normpath(Directory)) #Test for blackhole sub-directory.
if DirBase[1] == Name:
Logger.info("Files appear to be in their own directory") Logger.info("Files appear to be in their own directory")
DirBase2 = os.path.split(os.path.normpath(DirBase[0])) categorySearch2 = os.path.split(os.path.normpath(categorySearch[0]))
if DirBase2[1] == Movie_Cat or DirBase2[1] == TV_Cat: if categorySearch2[1] == movieCategory or categorySearch2[1] == tvCategory:
if not Category: if not inputCategory:
Logger.info("Determined Category to be: %s", DirBase2[1]) Logger.info("Determined Category to be: %s", categorySearch2[1])
Category = DirBase2[1] inputCategory = categorySearch2[1]
elif not Category: elif not inputCategory:
Logger.error("Could not identify category from the directory structure. please check downlaoder settings.") Logger.error("Could not identify category from the directory structure. please check downlaoder settings.")
sys.exit(-1) sys.exit(-1)
else: else:
pass pass
elif DirBase[1] == Movie_Cat or DirBase[1] == TV_Cat: elif categorySearch[1] == movieCategory or categorySearch[1] == tvCategory:
if os.path.isdir(os.path.join(Directory, Name)): if os.path.isdir(os.path.join(inputDirectory, inputName)):
Logger.info("Found torrent directory %s in category directory %s", os.path.join(Directory, Name), Directory) Logger.info("Found torrent directory %s in category directory %s", os.path.join(inputDirectory, inputName), inputDirectory)
Directory = os.path.join(Directory, Name) inputDirectory = os.path.join(inputDirectory, inputName)
else: else:
Logger.info("The directory passed is the root directory for category %s", DirBase[1]) Logger.info("The directory passed is the root directory for category %s", categorySearch[1])
Logger.warn("You should change settings to download torrents to their own directory if possible") Logger.warn("You should change settings to download torrents to their own directory if possible")
Logger.info("We will try and determine which files to process, individually") Logger.info("We will try and determine which files to process, individually")
root = 1 root = 1
if not Category: if not inputCategory:
Logger.info("Determined Category to be: %s", DirBase[1]) Logger.info("Determined Category to be: %s", categorySearch[1])
Category = DirBase[1] inputCategory = categorySearch[1]
elif not Category: elif not inputCategory:
Logger.error("Could not identify category from the directory structure. please check downlaoder settings.") Logger.error("Could not identify category from the directory structure. please check downlaoder settings.")
sys.exit(-1) sys.exit(-1)
else: else:
@ -78,35 +79,36 @@ def category_search(Directory, Category, root):
Logger.warn("You should change settings to download torrents to their own directory if possible and include Label/Category directories.") Logger.warn("You should change settings to download torrents to their own directory if possible and include Label/Category directories.")
Logger.info("We will try and determine which files to process, individually") Logger.info("We will try and determine which files to process, individually")
root = 1 root = 1
return Directory, Category, root return inputDirectory, inputCategory, root
def is_sample(file_path, Name): def is_sample(file_path, inputName):
# 200 MB in bytes # 200 MB in bytes
SIZE_CUTOFF = 200 * 1024 * 1024 SIZE_CUTOFF = 200 * 1024 * 1024
# ignore 'sample' in files unless 'sample' in Torrent Name # ignore 'sample' in files unless 'sample' in Torrent Name
if ('sample' in file_path.lower()) and (not 'sample' in Name) and (os.path.getsize(file_path) < SIZE_CUTOFF): if ('sample' in file_path.lower()) and (not 'sample' in inputName) and (os.path.getsize(file_path) < SIZE_CUTOFF):
return True return True
else: else:
return False return False
def copy_link(source, target, useLink, destination): def copy_link(source, target, useLink, outputDestination):
## Create destination folder ## Create destination folder
if not os.path.exists(destination): if not os.path.exists(outputDestination):
try: try:
Logger.debug("Creating destination folder: %s", destination) Logger.debug("Creating destination folder: %s", outputDestination)
os.makedirs(destination) os.makedirs(outputDestination)
except Exception, e: except Exception, e:
Logger.error("Not possible to create destination folder: %s", e) Logger.error("Not possible to create destination folder: %s", e)
return False return False
if useLink: if useLink:
try: try:
Logger.debug("Linking %s to %s", source, target) Logger.debug("Linking %s to %s", source, target)
linktastic.link(source, target) linktastic.link(source, target)
except: except:
if os.path.isfile(target): if os.path.isfile(target):
Logger.info("something went wrong in linktastic.link, but the destination file was created") Logger.info("Something went wrong in linktastic.link, but the destination file was created")
else: else:
Logger.info("something went wrong in linktastic.link. trying to create a copy") Logger.info("Something went wrong in linktastic.link. trying to create a copy")
Logger.debug("Copying %s to %s", source, target) Logger.debug("Copying %s to %s", source, target)
shutil.copy(source, target) shutil.copy(source, target)
else: else:
@ -114,7 +116,7 @@ def copy_link(source, target, useLink, destination):
shutil.copy(source, target) shutil.copy(source, target)
return True return True
def unpack(dirpath, file, destination): def unpack(dirpath, file, outputDestination):
## Using Windows? ## Using Windows?
if os.name == 'nt': if os.name == 'nt':
cmd_7zip = [extractionTool, 'x -y'] cmd_7zip = [extractionTool, 'x -y']
@ -157,30 +159,30 @@ def unpack(dirpath, file, destination):
return False return False
## Create destination folder ## Create destination folder
if not os.path.exists(destination): if not os.path.exists(outputDestination):
try: try:
Logger.debug("Creating destination folder: %s", destination) Logger.debug("Creating destination folder: %s", outputDestination)
os.makedirs(destination) os.makedirs(outputDestination)
except Exception, e: except Exception, e:
Logger.error("Not possible to create destination folder: %s", e) Logger.error("Not possible to create destination folder: %s", e)
return False return False
Logger.info("Extracting %s to %s", fp, destination) Logger.info("Extracting %s to %s", fp, outputDestination)
## Running.. ## Running..
Logger.debug("Extracting %s %s %s %s", cmd[0], cmd[1], fp, destination) Logger.debug("Extracting %s %s %s %s", cmd[0], cmd[1], fp, outputDestination)
pwd = os.getcwd() # Get our Present Working Directory pwd = os.getcwd() # Get our Present Working Directory
os.chdir(destination) #not all unpack commands accept full paths, so just extract into this directory. os.chdir(outputDestination) #not all unpack commands accept full paths, so just extract into this directory.
if os.name == 'nt': #Windows needs quotes around directory structure if os.name == 'nt': #Windows needs quotes around directory structure
try: try:
run = "\"" + cmd[0] + "\" " + cmd[1] + " \"" + fp + "\"" #windows needs quotes around directories. run = "\"" + cmd[0] + "\" " + cmd[1] + " \"" + fp + "\"" #windows needs quotes around directories.
res = call(run) res = call(run)
if res == 0: if res == 0:
Logger.info("Extraction was successful for %s to %s", fp, destination) Logger.info("Extraction was successful for %s to %s", fp, outputDestination)
else: else:
Logger.info("Extraction failed for %s. 7zip result was %s", fp, res) Logger.info("Extraction failed for %s. 7zip result was %s", fp, res)
except: except:
Logger.error("Extraction failed for %s. Could not call command %s %s", fp, run) Logger.error("Extraction failed for %s. Could not call command %s", fp, run)
else: else:
try: try:
if cmd[1] == "": #if calling unzip, we dont want to pass the "" if cmd[1] == "": #if calling unzip, we dont want to pass the ""
@ -188,7 +190,7 @@ def unpack(dirpath, file, destination):
else: else:
res = call([cmd[0], cmd[1], fp]) res = call([cmd[0], cmd[1], fp])
if res == 0: if res == 0:
Logger.info("Extraction was successful for %s to %s", fp, destination) Logger.info("Extraction was successful for %s to %s", fp, outputDestination)
else: else:
Logger.error("Extraction failed for %s. 7zip result was %s", fp, res) Logger.error("Extraction failed for %s. 7zip result was %s", fp, res)
except: except:
@ -196,17 +198,17 @@ def unpack(dirpath, file, destination):
os.chdir(pwd) # Go back to our Original Working Directory os.chdir(pwd) # Go back to our Original Working Directory
return True return True
def flatten(destination): def flatten(outputDestination):
Logger.info("Flattening directory: %s", destination) Logger.info("Flattening directory: %s", outputDestination)
for dirpath, dirnames, filenames in os.walk(destination): #flatten out the directory to make postprocessing easier. for dirpath, dirnames, filenames in os.walk(outputDestination): #flatten out the directory to make postprocessing easier.
if dirpath == destination: if dirpath == outputDestination:
continue #no need to try and move files in the root destination directory. continue #no need to try and move files in the root destination directory.
for filename in filenames: for filename in filenames:
try: try:
shutil.move(os.path.join(dirpath, filename), destination) shutil.move(os.path.join(dirpath, filename), outputDestination)
except OSError: except OSError:
Logger.info("Could not flatten %s", os.path.join(dirpath, filename)) Logger.info("Could not flatten %s", os.path.join(dirpath, filename))
removeEmptyFolders(destination) #cleanup empty directories. removeEmptyFolders(outputDestination) #cleanup empty directories.
def removeEmptyFolders(path): def removeEmptyFolders(path):
Logger.info("Removing empty folders in: %s", path) Logger.info("Removing empty folders in: %s", path)
@ -227,135 +229,86 @@ def removeEmptyFolders(path):
Logger.debug("Removing empty folder: %s", path) Logger.debug("Removing empty folder: %s", path)
os.rmdir(path) os.rmdir(path)
if len(sys.argv) == 4: if len(sys.argv) == 3:
##You can use the following parameters (UTORRENT): ## We will pass in %D, %N from uTorrent, or %TR_TORRENT_DIR% %TR_TORRENT_NAME% from Transmission
## inputDirectory = os.path.normpath(sys.argv[1])
##%F - Name of downloaded file (for single file torrents) inputName = sys.argv[2]
##%D - Directory where files are saved inputCategory = '' # We dont have a category, so assume the last directory is the category for now.
##%N - Title of torrent else:
##%P - Previous state of torrent Logger.error("There was a problem loading variables: Exiting")
##%L - Label
##%T - Tracker
##%M - Status message string (same as status column)
##%I - hex encoded info-hash
##%S - State of torrent
##%K - kind of torrent (single|multi)
##
##Where State is one of:
##
##Error - 1
##Checked - 2
##Paused - 3
##Super seeding - 4
##Seeding - 5
##Downloading - 6
##Super seed [F] - 7
##Seeding [F] - 8
##Downloading [F] - 9
##Queued seed - 10
##Finished - 11
##Queued - 12
##Stopped - 13
## We will pass in %D, %N, %L from uTorrent
Logger.info("Script called from utorrent")
Directory = os.path.normpath(sys.argv[1]) ## %D -- Example output: F:\path\to\dir\My.Series.S01E01.720p.HDTV.x264-2HD
Name = sys.argv[2] ## %N -- Example output: My.Series.S01E01.720p.HDTV.x264-2HD
Category = sys.argv[3] ## %L -- Example output: tvseries ## This is the label in uTorrent
elif len(sys.argv) > 1: #Doesn't match Transmission (1) or uTorrent (4).
Logger.error("The number of arguments passed is %s. Unable to determin the arguments to use; Exiting", len(sys.argv))
sys.exit(-1) sys.exit(-1)
else: Logger.debug("Received Directory: %s | Name: %s", inputDirectory, inputName)
##test for Transmission here.
#TR_APP_VERSION
#TR_TIME_LOCALTIME
#TR_TORRENT_DIR
#TR_TORRENT_HASH
#TR_TORRENT_ID
#TR_TORRENT_NAME
try:
Directory = os.path.normpath(os.getenv('TR_TORRENT_DIR'))
Name = os.getenv('TR_TORRENT_NAME')
Logger.info("Script called from Transmission")
except:
Logger.error("There was a problem loading variables from Transmission: Exiting")
sys.exit(-1)
Category = '' #We dont have a category, so assume the last directory is the category for now.
Logger.debug("Received Directory: %s", Directory)
Logger.debug("Received Torrent Name: %s", Name)
Logger.debug("Received Category: %s", Category)
status = 1 # we start as "failed" until we verify movie file in destination status = 1 # we start as "failed" until we verify movie file in destination
root = 0 root = 0
video = 0 video = 0
video2 = 0 video2 = 0
Directory, Category, root = category_search(Directory, Category, root) # confirm the catgeogy by parsing directory structure. inputDirectory, inputCategory, root = category_search(inputDirectory, inputCategory, root) # confirm the catgeogy by parsing directory structure.
if Category == Movie_Cat: if inputCategory == movieCategory:
destination = os.path.join(Movie_dest, Name) outputDestination = os.path.normpath(os.path.join(movieDestination, inputName))
elif Category == TV_Cat: elif inputCategory == tvCategory:
destination = os.path.join(TV_dest, Name) outputDestination = os.path.normpath(os.path.join(tvDestination, inputName))
else: else:
Logger.info("Category of %s does not match either %s or %s: Exiting", Category, Movie_Cat, TV_Cat) Logger.info("Category of %s does not match either %s or %s: Exiting", inputCategory, movieCategory, tvCategory)
sys.exit(-1) sys.exit(-1)
packed_files = ['.zip', '.rar', '.7z', '.gz', '.bz', '.tar', '.arj'] packed_files = ['.zip', '.rar', '.7z', '.gz', '.bz', '.tar', '.arj']
video_files = ['.mkv', '.avi', '.divx', '.xvid', '.mov', '.wmv', '.mp4', '.mpg', '.mpeg', '.vob', '.iso'] video_files = ['.mkv', '.avi', '.divx', '.xvid', '.mov', '.wmv', '.mp4', '.mpg', '.mpeg', '.vob', '.iso']
meta_files = ['.nfo', '.sub', '.srt', '.jpg', '.gif'] meta_files = ['.nfo', '.sub', '.srt', '.jpg', '.gif']
Logger.debug("scanning files in directory: %s", Directory)
for dirpath, dirnames, filenames in os.walk(Directory): Logger.debug("Scanning files in directory: %s", inputDirectory)
for dirpath, dirnames, filenames in os.walk(inputDirectory):
for file in filenames: for file in filenames:
if root == 1: if root == 1:
Logger.debug("Looking for %s in filename", Name) Logger.debug("Looking for %s in filename", inputName)
if (Name in file) or (file in Name): if (inputName in file) or (file in inputName):
pass #This file does match the Torrent name pass #This file does match the Torrent name
else: else:
continue #This file does not match the Torrent name. Skip it continue #This file does not match the Torrent name. Skip it
file_path = os.path.join(dirpath, file) file_path = os.path.join(dirpath, file)
file_ext = os.path.splitext(file)[1] file_ext = os.path.splitext(file)[1]
if file_ext in video_files: #if the file is a video file. if file_ext in video_files: #if the file is a video file.
if is_sample(file_path, Name): if is_sample(file_path, inputName):
Logger.info("file %s is a sample file. Ignoring", file_path) Logger.info("file %s is a sample file. Ignoring", file_path)
continue #ignore samples continue #ignore samples
video = video + 1 video = video + 1
source = file_path source = file_path
target = os.path.join(destination, file) target = os.path.join(outputDestination, file)
Logger.info("Found video file %s.", file) Logger.info("Found video file %s.", file)
state = copy_link(source, target, useLink, destination) state = copy_link(source, target, useLink, outputDestination)
if state == False: if state == False:
Logger.info("Failed to link file %s.", file) Logger.info("Failed to link file %s.", file)
elif file_ext in meta_files: elif file_ext in meta_files:
source = file_path source = file_path
target = os.path.join(destination, file) target = os.path.join(outputDestination, file)
Logger.info("Found metadata file %s.", file) Logger.info("Found metadata file %s.", file)
state = copy_link(source, target, useLink, destination) state = copy_link(source, target, useLink, outputDestination)
if state == False: if state == False:
Logger.info("Failed to link file %s.", file) Logger.info("Failed to link file %s.", file)
elif file_ext in packed_files: elif file_ext in packed_files:
Logger.info("Found packed file %s.", file) Logger.info("Found packed file %s.", file)
source = file_path source = file_path
target = os.path.join(destination, file) target = os.path.join(outputDestination, file)
state = unpack(dirpath, file, destination) state = unpack(dirpath, file, outputDestination)
if state == False: if state == False:
Logger.info("Failed to unpack file %s.", file) Logger.info("Failed to unpack file %s.", file)
else: else:
Logger.info("Unknown file type %s for file %s. Ignoring", file_ext, file_path) Logger.info("Unknown file type %s for file %s. Ignoring", file_ext, file_path)
continue continue
flatten(destination) flatten(outputDestination)
#now check if movie files exist in destination: #now check if movie files exist in destination:
for dirpath, dirnames, filenames in os.walk(destination): for dirpath, dirnames, filenames in os.walk(outputDestination):
for file in filenames: for file in filenames:
file_path = os.path.join(dirpath, file) file_path = os.path.join(dirpath, file)
file_ext = os.path.splitext(file)[1] file_ext = os.path.splitext(file)[1]
if file_ext in video_files: #if the file is a video file. if file_ext in video_files: #if the file is a video file.
video2 = video2 + 1 video2 = video2 + 1
if video2 >= video and video2 > 0: #check that all video files were moved. if video2 >= video and video2 > 0: #check that all video files were moved.
status = 0 status = 0
status = int(status) status = int(status)
@ -365,7 +318,7 @@ else:
Logger.info("calling autoProcess script for failed download") Logger.info("calling autoProcess script for failed download")
## Now we pass off to CouchPotato or SickBeard. ## Now we pass off to CouchPotato or SickBeard.
# still need to figure out how to log this output. # still need to figure out how to log this output.
if Category == Movie_Cat: if inputCategory == movieCategory:
autoProcessMovie.process(destination, Name, status) autoProcessMovie.process(outputDestination, inputName, status)
elif Category == TV_Cat: elif inputCategory == tvCategory:
autoProcessTV.processEpisode(destination, Name, status) autoProcessTV.processEpisode(outputDestination, inputName, status)

View file

@ -10,7 +10,7 @@ delay = 60
method = renamer method = renamer
delete_failed = 0 delete_failed = 0
category = movies category = movies
destination = /abs/path/to/complete/movies outputDirectory = /abs/path/to/complete/movies
[SickBeard] [SickBeard]
host=localhost host=localhost
@ -22,9 +22,9 @@ ssl=0
watch_dir= watch_dir=
failed_fork=0 failed_fork=0
category = tv category = tv
destination = /abs/path/to/complete/tv outputDirectory = /abs/path/to/complete/tv
[Torrent] [Torrent]
uselink = 0 uselink = 0
extractiontool = 'C:\\Program Files\\7-Zip\\7z.exe' extractiontool = C:\Program Files\7-Zip\7z.exe