nzbToMedia/nzbtomedia/autoProcess/autoProcessTV.py

190 lines
8 KiB
Python

import copy
import logging
import os
import socket
import urllib
import requests
import time
from nzbtomedia.Transcoder import Transcoder
from nzbtomedia.nzbToMediaAutoFork import autoFork
from nzbtomedia.nzbToMediaConfig import config
from nzbtomedia.nzbToMediaSceneExceptions import process_all_exceptions
from nzbtomedia.nzbToMediaUtil import convert_to_ascii, is_sample, flatten, getDirectorySize, delete
Logger = logging.getLogger()
class autoProcessTV:
def processEpisode(self, dirName, nzbName=None, failed=False, clientAgent = "manual", inputCategory=None):
if dirName is None:
Logger.error("No directory was given!")
return 1 # failure
socket.setdefaulttimeout(int(config.NZBTOMEDIA_TIMEOUT)) #initialize socket timeout.
Logger.info("Loading config from %s", config.CONFIG_FILE)
status = int(failed)
section = "SickBeard"
if inputCategory != None and config().has_section(inputCategory):
section = inputCategory
host = config().get(section, "host")
port = config().get(section, "port")
username = config().get(section, "username")
password = config().get(section, "password")
try:
ssl = int(config().get(section, "ssl"))
except (config.NoOptionError, ValueError):
ssl = 0
try:
web_root = config().get(section, "web_root")
except config.NoOptionError:
web_root = ""
try:
watch_dir = config().get(section, "watch_dir")
except config.NoOptionError:
watch_dir = ""
try:
transcode = int(config().get("Transcoder", "transcode"))
except (config.NoOptionError, ValueError):
transcode = 0
try:
delete_failed = int(config().get(section, "delete_failed"))
except (config.NoOptionError, ValueError):
delete_failed = 0
try:
delay = float(config().get(section, "delay"))
except (config.NoOptionError, ValueError):
delay = 0
try:
TimePerGiB = int(config().get(section, "TimePerGiB"))
except (config.NoOptionError, ValueError):
TimePerGiB = 60 # note, if using Network to transfer on 100Mbit LAN, expect ~ 600 MB/minute.
try:
SampleIDs = (config().get("Extensions", "SampleIDs")).split(',')
except (config.NoOptionError, ValueError):
SampleIDs = ['sample','-s.']
try:
nzbExtractionBy = config().get(section, "nzbExtractionBy")
except (config.NoOptionError, ValueError):
nzbExtractionBy = "Downloader"
try:
process_method = config().get(section, "process_method")
except config.NoOptionError:
process_method = None
mediaContainer = (config().get("Extensions", "mediaExtensions")).split(',')
minSampleSize = int(config().get("Extensions", "minSampleSize"))
if not os.path.isdir(dirName) and os.path.isfile(dirName): # If the input directory is a file, assume single file download and split dir/name.
dirName = os.path.split(os.path.normpath(dirName))[0]
SpecificPath = os.path.join(dirName, str(nzbName))
cleanName = os.path.splitext(SpecificPath)
if cleanName[1] == ".nzb":
SpecificPath = cleanName[0]
if os.path.isdir(SpecificPath):
dirName = SpecificPath
# auto-detect fork type
fork, params = autoFork(section)
if fork not in config.SICKBEARD_TORRENT or (clientAgent in ['nzbget','sabnzbd'] and nzbExtractionBy != "Destination"):
if nzbName:
process_all_exceptions(nzbName.lower(), dirName)
nzbName, dirName = convert_to_ascii(nzbName, dirName)
# Now check if tv files exist in destination. Eventually extraction may be done here if nzbExtractionBy == TorrentToMedia
video = int(0)
for dirpath, dirnames, filenames in os.walk(dirName):
for file in filenames:
filePath = os.path.join(dirpath, file)
fileExtension = os.path.splitext(file)[1]
if fileExtension in mediaContainer: # If the file is a video file
if is_sample(filePath, nzbName, minSampleSize, SampleIDs):
Logger.debug("Removing sample file: %s", filePath)
os.unlink(filePath) # remove samples
else:
video = video + 1
if video > 0: # Check that a video exists. if not, assume failed.
flatten(dirName) # to make sure SickBeard can find the video (not in sub-folder)
elif clientAgent == "manual":
Logger.warning("No media files found in directory %s to manually process.", dirName)
return 0 # Success (as far as this script is concerned)
else:
Logger.warning("No media files found in directory %s. Processing this as a failed download", dirName)
status = int(1)
failed = True
dirSize = getDirectorySize(dirName) # get total directory size to calculate needed processing time.
TIME_OUT = int(TimePerGiB) * dirSize # SickBeard needs to complete all moving and renaming before returning the log sequence via url.
TIME_OUT += 60 # Add an extra minute for over-head/processing/metadata.
socket.setdefaulttimeout(int(config.NZBTOMEDIA_TIMEOUT)) #initialize socket timeout.
# configure SB params to pass
params['quiet'] = 1
if nzbName is not None:
params['nzbName'] = nzbName
for param in copy.copy(params):
if param == "failed":
params[param] = failed
if param in ["dirName", "dir"]:
params[param] = dirName
if param == "process_method":
if process_method:
params[param] = process_method
else:
del params[param]
# delete any unused params so we don't pass them to SB by mistake
[params.pop(k) for k,v in params.items() if v is None]
if status == 0:
Logger.info("The download succeeded. Sending process request to SickBeard's %s branch", fork)
elif fork in config.SICKBEARD_FAILED:
Logger.info("The download failed. Sending 'failed' process request to SickBeard's %s branch", fork)
else:
Logger.info("The download failed. SickBeard's %s branch does not handle failed downloads. Nothing to process", fork)
if delete_failed and os.path.isdir(dirName) and not dirName in ['sys.argv[0]','/','']:
Logger.info("Deleting directory: %s", dirName)
delete(dirName)
return 0 # Success (as far as this script is concerned)
if status == 0 and transcode == 1: # only transcode successful downlaods
result = Transcoder().Transcode_directory(dirName)
if result == 0:
Logger.debug("Transcoding succeeded for files in %s", dirName)
else:
Logger.warning("Transcoding failed for files in %s", dirName)
if ssl:
protocol = "https://"
else:
protocol = "http://"
url = protocol + host + ":" + port + web_root + "/home/postprocess/processEpisode?" + urllib.urlencode(params)
if clientAgent == "manual":delay = 0
Logger.info("Waiting for %s seconds to allow SB to process newly extracted files", str(delay))
time.sleep(delay)
Logger.debug("Opening URL: %s", url)
try:
r = requests.get(url, auth=(username, password), stream=True)
except requests.ConnectionError:
Logger.exception("Unable to open URL")
return 1 # failure
for line in r.iter_lines():
if line: Logger.info("%s", line)
if status != 0 and delete_failed and not dirName in ['sys.argv[0]','/','']:
delete(dirName)
return 0 # Success