cleanup and fixes

- cleaned up logger messages
- SIZE_CUTOFF moved to config
- useLink changed to true/false (easier to understand)
- removed which.py (included in extractor.py)
- added a check in the extractor to support transmission (otherwise it
will fail), but note that it will not be able to check if an command is
executable
This commit is contained in:
Joel Kåberg 2013-03-01 10:55:51 +01:00
parent 51226573f9
commit f41b576967
5 changed files with 43 additions and 50 deletions

View file

@ -125,7 +125,7 @@ def category_search(inputDirectory, inputName, inputCategory, root, categories):
def is_sample(filePath, inputName): def is_sample(filePath, inputName):
# 200 MB in bytes # 200 MB in bytes
# Maybe let the users change this? # Maybe let the users change this?
SIZE_CUTOFF = 200 * 1024 * 1024 SIZE_CUTOFF = minSampleSize * 1024 * 1024
# Ignore 'sample' in files unless 'sample' in Torrent Name # Ignore 'sample' in files unless 'sample' in Torrent Name
return ('sample' in filePath.lower()) and (not 'sample' in inputName) and (os.path.getsize(filePath) < SIZE_CUTOFF) return ('sample' in filePath.lower()) and (not 'sample' in inputName) and (os.path.getsize(filePath) < SIZE_CUTOFF)
@ -168,7 +168,7 @@ def flatten(outputDestination):
try: try:
shutil.move(source, target) shutil.move(source, target)
except OSError: except OSError:
Logger.info("FLATTEN: Could not flatten %s", source) Logger.error("FLATTEN: Could not flatten %s", source)
removeEmptyFolders(outputDestination) # Cleanup empty directories removeEmptyFolders(outputDestination) # Cleanup empty directories
@ -191,7 +191,7 @@ def removeEmptyFolders(path):
Logger.debug("REMOVER: Removing empty folder: %s", path) Logger.debug("REMOVER: Removing empty folder: %s", path)
os.rmdir(path) os.rmdir(path)
Logger.info("==========================") # Seperate old from new log
Logger.info("TorrentToMedia %s", VERSION) Logger.info("TorrentToMedia %s", VERSION)
config = ConfigParser.ConfigParser() config = ConfigParser.ConfigParser()
configFilename = os.path.join(os.path.dirname(sys.argv[0]), "autoProcessMedia.cfg") configFilename = os.path.join(os.path.dirname(sys.argv[0]), "autoProcessMedia.cfg")
@ -223,7 +223,8 @@ tvDestination = os.path.normpath(config.get("SickBeard", "outputDirectory"))
movieCategory = config.get("CouchPotato", "category") movieCategory = config.get("CouchPotato", "category")
movieDestination = os.path.normpath(config.get("CouchPotato", "outputDirectory")) movieDestination = os.path.normpath(config.get("CouchPotato", "outputDirectory"))
# Torrent specific # Torrent specific
useLink = int(config.get("Torrent", "useLink")) useLink = config.get("Torrent", "useLink")
minSampleSize = int(config.get("Torrent", "minSampleSize"))
uTorrentWEBui = config.get("Torrent", "uTorrentWEBui") uTorrentWEBui = config.get("Torrent", "uTorrentWEBui")
uTorrentUSR = config.get("Torrent", "uTorrentUSR") uTorrentUSR = config.get("Torrent", "uTorrentUSR")
uTorrentPWD = config.get("Torrent", "uTorrentPWD") uTorrentPWD = config.get("Torrent", "uTorrentPWD")
@ -234,10 +235,6 @@ categories = (config.get("Torrent", "categories")).split(',')
categories.append(movieCategory) categories.append(movieCategory)
categories.append(tvCategory) # now have a list of all categories in use. categories.append(tvCategory) # now have a list of all categories in use.
# setup uTorrentClass
if inputHash:
utorrentClass = UTorrentClient(uTorrentWEBui, uTorrentUSR, uTorrentPWD)
status = int(1) # We start as "failed" until we verify movie file in destination status = int(1) # We start as "failed" until we verify movie file in destination
root = int(0) root = int(0)
video = int(0) video = int(0)
@ -282,7 +279,7 @@ for dirpath, dirnames, filenames in os.walk(inputDirectory):
fileExtention = os.path.splitext(file)[1] fileExtention = os.path.splitext(file)[1]
if fileExtention in mediaContainer: # If the file is a video file if fileExtention in mediaContainer: # If the file is a video file
if is_sample(filePath, inputName): # Ignore samples if is_sample(filePath, inputName): # Ignore samples
Logger.info("MAIN: Ignoring %s sample file. Ignoring", filePath) Logger.info("MAIN: Ignoring sample file: %s ", filePath)
continue continue
else: else:
video = video + 1 video = video + 1
@ -291,7 +288,7 @@ for dirpath, dirnames, filenames in os.walk(inputDirectory):
Logger.info("MAIN: Found video file %s in %s", fileExtention, filePath) Logger.info("MAIN: Found video file %s in %s", fileExtention, filePath)
state = copy_link(source, target, useLink, outputDestination) state = copy_link(source, target, useLink, outputDestination)
if state == False: if state == False:
Logger.info("MAIN: Failed to link file %s", file) Logger.error("MAIN: Failed to link file %s", file)
failed_link = 1 failed_link = 1
elif fileExtention in metaContainer: elif fileExtention in metaContainer:
source = filePath source = filePath
@ -299,7 +296,7 @@ for dirpath, dirnames, filenames in os.walk(inputDirectory):
Logger.info("MAIN: Found metadata file %s for file %s", fileExtention, filePath) Logger.info("MAIN: Found metadata file %s for file %s", fileExtention, filePath)
state = copy_link(source, target, useLink, outputDestination) state = copy_link(source, target, useLink, outputDestination)
if state == False: if state == False:
Logger.info("MAIN: Failed to link file %s", file) Logger.error("MAIN: Failed to link file %s", file)
failed_link = 1 failed_link = 1
elif fileExtention in compressedContainer: elif fileExtention in compressedContainer:
Logger.info("MAIN: Found compressed archive %s for file %s", fileExtention, filePath) Logger.info("MAIN: Found compressed archive %s for file %s", fileExtention, filePath)
@ -310,7 +307,7 @@ for dirpath, dirnames, filenames in os.walk(inputDirectory):
except: except:
Logger.warn("Extraction failed for %s", file) Logger.warn("Extraction failed for %s", file)
else: else:
Logger.info("MAIN: Ignoring unknown filetype %s for file %s", fileExtention, filePath) Logger.debug("MAIN: Ignoring unknown filetype %s for file %s", fileExtention, filePath)
continue continue
flatten(outputDestination) flatten(outputDestination)
@ -321,7 +318,7 @@ for dirpath, dirnames, filenames in os.walk(outputDestination):
fileExtention = os.path.splitext(file)[1] fileExtention = os.path.splitext(file)[1]
if fileExtention in mediaContainer: # If the file is a video file if fileExtention in mediaContainer: # If the file is a video file
if is_sample(filePath, inputName): if is_sample(filePath, inputName):
Logger.info("file %s is a sample file. Removing", filePath) Logger.debug("Removing sample file: %s", filePath)
os.unlink(filePath) # remove samples os.unlink(filePath) # remove samples
else: else:
videofile = filePath videofile = filePath
@ -329,42 +326,47 @@ for dirpath, dirnames, filenames in os.walk(outputDestination):
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) # just to be safe. if status == 0: #### Maybe we should move this to a more appropriate place?
if status == 0:
Logger.info("MAIN: Successful run") Logger.info("MAIN: Successful run")
Logger.debug("MAIN: Calling autoProcess script for successful download.") Logger.debug("MAIN: Calling autoProcess script for successful download.")
elif failed_extract == 1 and failed_link == 0: # failed to extract files only. elif failed_extract == 1 and failed_link == 0: # failed to extract files only.
Logger.info("MAIN: Failed to extract a packed file.") Logger.info("MAIN: Failed to extract a compressed archive")
Logger.debug("MAIN: Assume this to be password protected file.") Logger.debug("MAIN: Assume this to be password protected file.")
Logger.debug("MAIN: Calling autoProcess script for failed download.") Logger.debug("MAIN: Calling autoProcess script for failed download.")
else: else:
Logger.info("MAIN: Something failed! Please check logs. Exiting") Logger.error("MAIN: Something failed! Please check logs. Exiting")
sys.exit(-1) sys.exit(-1)
# Hardlink solution with uTorrent # Hardlink solution with uTorrent
if inputHash and useLink: if inputHash and useLink:
Logger.debug("MAIN: We are using hardlinks with uTorrent, calling uTorrent to pause download") try:
Logger.debug("Connecting to uTorrent: %s", uTorrentWEBui)
utorrentClass = UTorrentClient(uTorrentWEBui, uTorrentUSR, uTorrentPWD)
except:
Logger.error("Failed to connect to uTorrent")
Logger.debug("MAIN: Stoping torrent %s in uTorrent while processing", inputName)
utorrentClass.stop(inputHash) utorrentClass.stop(inputHash)
time.sleep(5) # Give uTorrent some time to catch up with the change time.sleep(5) # Give uTorrent some time to catch up with the change
# Now we pass off to CouchPotato or Sick-Beard # Now we pass off to CouchPotato or Sick-Beard
if inputCategory == movieCategory: if inputCategory == movieCategory:
Logger.info("MAIN: Calling postprocessing script for CouchPotatoServer") # can we use logger while logfile open? Logger.info("MAIN: Calling CouchPotatoServer to post-process: %s", inputName) # can we use logger while logfile open?
autoProcessMovie.process(outputDestination, inputName, status) autoProcessMovie.process(outputDestination, inputName, status)
elif inputCategory == tvCategory: elif inputCategory == tvCategory:
Logger.info("MAIN: Calling postprocessing script for Sick-Beard") # can we use logger while logfile open? Logger.info("MAIN: Calling Sick-Beard to post-process: %s", inputName) # can we use logger while logfile open?
autoProcessTV.processEpisode(outputDestination, inputName, status) autoProcessTV.processEpisode(outputDestination, inputName, status)
# Check if the file still exists in the post-process directory
now = datetime.datetime.now() # set time for timeout now = datetime.datetime.now() # set time for timeout
while os.path.exists(videofile): # while this file is still here, CPS hasn't finished renaming while os.path.exists(videofile): # while this file is still here, CPS hasn't finished renaming
if (datetime.datetime.now() - now) > datetime.timedelta(minutes=3): # note; minimum 1 minute delay in autoProcessMovie if (datetime.datetime.now() - now) > datetime.timedelta(minutes=3): # note; minimum 1 minute delay in autoProcessMovie
Logger.info("MAIN: The file %s has not been moved after 3 minutes.") Logger.info("MAIN: The file %s has not been moved after 3 minutes.", videofile)
break break
time.sleep(10) #Just stop this looping infinitely and hogging resources for 3 minutes ;) time.sleep(10) #Just stop this looping infinitely and hogging resources for 3 minutes ;)
else: # CPS (and SickBeard) have finished. We can now resume seeding. else: # CPS (and SickBeard) have finished. We can now resume seeding.
Logger.info("MAIN: The file %s has been moved. Postprocessing appears to have succeeded." % videofile) Logger.info("MAIN: Post-process appears to have succeeded for: %s", videofile)
# Hardlink solution with uTorrent # Hardlink solution with uTorrent
if inputHash and useLink: if inputHash and useLink:
Logger.debug("MAIN: We are using hardlinks with uTorrent, calling uTorrent to resume download") Logger.debug("MAIN: Starting torrent %s in uTorrent", inputName)
utorrentClass.start(inputHash) utorrentClass.start(inputHash)

View file

@ -28,10 +28,14 @@ watch_dir=
failed_fork=0 failed_fork=0
[Torrent] [Torrent]
# Set to whatever torrent client you use. ###### Set to whatever torrent client you use.
# Supported values: utorrent, transmission, deluge, other ###### Supported values: utorrent, transmission, deluge, other
clientAgent = other clientAgent = other
useLink = 0 ###### useLink - Set to true or false depending on if you want to use hardlinks
useLink = false
###### minSampleSize - Minimum required size to consider a file not an sample file (in MB, eg 200mb)
minSampleSize = 200
###### **insert descriptive comment for categories here** :-)
categories = music,music_videos,pictures,software categories = music,music_videos,pictures,software
###### uTorrent Hardlink solution (You must edit this if your using TorrentToMedia.py with uTorrent) ###### uTorrent Hardlink solution (You must edit this if your using TorrentToMedia.py with uTorrent)
uTorrentWEBui = http://localhost:8090/gui/ uTorrentWEBui = http://localhost:8090/gui/

View file

@ -73,12 +73,16 @@ def extract(dirpath, file, outputDestination):
".7z": ["7zr", "x"], ".7z": ["7zr", "x"],
} }
# Test command exists and if not, remove # Test command exists and if not, remove
for cmd in required_cmds: if not os.getenv('TR_TORRENT_DIR'):
if call(['which', cmd]): #note, returns 0 if exists, or 1 if doesn't exist. for cmd in required_cmds:
for k, v in EXTRACT_COMMANDS.items(): if call(['which', cmd]): #note, returns 0 if exists, or 1 if doesn't exist.
if cmd in v[0]: for k, v in EXTRACT_COMMANDS.items():
Logger.error("EXTRACTOR: %s not found, disabling support for %s", cmd, k) if cmd in v[0]:
del EXTRACT_COMMANDS[k] Logger.error("EXTRACTOR: %s not found, disabling support for %s", cmd, k)
del EXTRACT_COMMANDS[k]
else:
Logger.warn("EXTRACTOR: Cannot determine which tool to use when called from Transmission")
if not EXTRACT_COMMANDS: if not EXTRACT_COMMANDS:
Logger.warn("EXTRACTOR: No archive extracting programs found, plugin will be disabled") Logger.warn("EXTRACTOR: No archive extracting programs found, plugin will be disabled")

View file

@ -1,17 +0,0 @@
def which(program):
# Author Credit: Jay @ http://stackoverflow.com/a/377028
import os
def is_exe(fpath):
return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
fpath, fname = os.path.split(program)
if fpath:
if is_exe(program):
return program
else:
for path in os.environ["PATH"].split(os.pathsep):
exe_file = os.path.join(path, program)
if is_exe(exe_file):
return exe_file
return None

View file

@ -36,6 +36,6 @@ elif len(sys.argv) == 4:
autoProcessMovie.process(sys.argv[1], sys.argv[2], sys.argv[3]) autoProcessMovie.process(sys.argv[1], sys.argv[2], sys.argv[3])
else: else:
Logger.debug("Invalid number of arguments received from client.") Logger.warn("Invalid number of arguments received from client.")
Logger.info("Running autoProcessMovie as a manual run...") Logger.info("Running autoProcessMovie as a manual run...")
autoProcessMovie.process('Manual Run', 'Manual Run', 0) autoProcessMovie.process('Manual Run', 'Manual Run', 0)