From 730ddc3b76ed986ce4360de2c5a0a61714987dad Mon Sep 17 00:00:00 2001 From: Michael Higginis Date: Tue, 31 Jan 2017 10:08:22 -0500 Subject: [PATCH] radarr support --- NZBGetPostProcess.py | 18 +++++++++-- SABPostProcess.py | 11 ++++--- autoProcess.ini.sample | 7 +++++ autoprocess/radarr.py | 68 ++++++++++++++++++++++++++++++++++++++++++ delugePostProcess.py | 9 ++++-- readSettings.py | 23 +++++++++++++- uTorrentPostProcess.py | 12 ++++---- 7 files changed, 131 insertions(+), 17 deletions(-) create mode 100644 autoprocess/radarr.py diff --git a/NZBGetPostProcess.py b/NZBGetPostProcess.py index cc754bf0..461f791a 100755 --- a/NZBGetPostProcess.py +++ b/NZBGetPostProcess.py @@ -22,6 +22,9 @@ # Category for Sonarr #SONARR_CAT=Sonarr +# Category for Radarr +#RADARR_CAT=Radarr + # Category for Sickbeard #SICKBEARD_CAT=Sickbeard @@ -68,7 +71,7 @@ try: from readSettings import ReadSettings from mkvtomp4 import MkvtoMp4 - from autoprocess import autoProcessMovie, autoProcessTV, autoProcessTVSR, sonarr + from autoprocess import autoProcessMovie, autoProcessTV, autoProcessTVSR, sonarr, radarr import logging from logging.config import fileConfig except ImportError: @@ -93,11 +96,12 @@ couchcat = os.environ['NZBPO_CP_CAT'].lower() sonarrcat = os.environ['NZBPO_SONARR_CAT'].lower() + radarrcat = os.environ['NZBPO_RADARR_CAT'].lower() sickbeardcat = os.environ['NZBPO_SICKBEARD_CAT'].lower() sickragecat = os.environ['NZBPO_SICKRAGE_CAT'].lower() bypass = os.environ['NZBPO_BYPASS_CAT'].lower() - categories = [sickbeardcat, couchcat, sonarrcat, sickragecat, bypass] + categories = [sickbeardcat, couchcat, sonarrcat, radarrcat, sickragecat, bypass] log.debug("Path: %s" % path) log.debug("NZB: %s" % nzb) @@ -202,16 +206,24 @@ autoProcessMovie.process(path, settings, nzb, status) sys.exit(POSTPROCESS_SUCCESS) elif (category.lower() == categories[2]): + #DEBUG#print "Sonarr Processing Activated" success = sonarr.processEpisode(path, settings, True) if success: sys.exit(POSTPROCESS_SUCCESS) else: sys.exit(POSTPROCESS_ERROR) elif (category.lower() == categories[3]): + #DEBUG#print "Radarr Processing Activated" + success = radarr.processMovie(path, settings, True) + if success: + sys.exit(POSTPROCESS_SUCCESS) + else: + sys.exit(POSTPROCESS_ERROR) + elif (category.lower() == categories[4]): #DEBUG#print "Sickrage Processing Activated" autoProcessTVSR.processEpisode(path, settings, nzb) sys.exit(POSTPROCESS_SUCCESS) - elif (category.lower() == categories[4]): + elif (category.lower() == categories[5]): #DEBUG#print "Bypass Further Processing" sys.exit(POSTPROCESS_NONE) diff --git a/SABPostProcess.py b/SABPostProcess.py index 86323340..a2950ed9 100755 --- a/SABPostProcess.py +++ b/SABPostProcess.py @@ -2,7 +2,7 @@ import os import sys -from autoprocess import autoProcessTV, autoProcessMovie, autoProcessTVSR, sonarr +from autoprocess import autoProcessTV, autoProcessMovie, autoProcessTVSR, sonarr, radarr from readSettings import ReadSettings from mkvtomp4 import MkvtoMp4 import logging @@ -27,7 +27,7 @@ # 7 Status of post processing. 0 = OK, 1=failed verification, 2=failed unpack, 3=1+2 settings = ReadSettings(os.path.dirname(sys.argv[0]), "autoProcess.ini") -categories = [settings.SAB['sb'], settings.SAB['cp'], settings.SAB['sonarr'], settings.SAB['sr'], settings.SAB['bypass']] +categories = [settings.SAB['sb'], settings.SAB['cp'], settings.SAB['sonarr'], settings.SAB['radarr'], settings.SAB['sr'], settings.SAB['bypass']] category = str(sys.argv[5]).lower() path = str(sys.argv[1]) nzb = str(sys.argv[2]) @@ -51,7 +51,7 @@ if settings.SAB['output_dir']: settings.output_dir = settings.SAB['output_dir'] log.debug("Overriding output_dir to %s." % settings.SAB['output_dir']) - + converter = MkvtoMp4(settings) for r, d, f in os.walk(path): for files in f: @@ -82,8 +82,11 @@ log.info("Passing %s directory to Sonarr." % path) sonarr.processEpisode(path, settings) elif (category == categories[3]): + log.info("Passing %s directory to Radarr." % path) + radarr.processMovie(path, settings) +elif (category == categories[4]): log.info("Passing %s directory to Sickrage." % path) autoProcessTVSR.processEpisode(path, settings, nzb) # Bypass -elif (category == categories[4]): +elif (category == categories[5]): log.info("Bypassing any further processing as per category.") diff --git a/autoProcess.ini.sample b/autoProcess.ini.sample index 03235223..3effe6b6 100644 --- a/autoProcess.ini.sample +++ b/autoProcess.ini.sample @@ -14,6 +14,13 @@ web_root = ssl = 0 apikey = +[Radarr] +host = localhost +port = 7878 +web_root = +ssl = 0 +apikey = + [MP4] ffmpeg = ffmpeg.exe ffprobe = ffprobe.exe diff --git a/autoprocess/radarr.py b/autoprocess/radarr.py new file mode 100644 index 00000000..952bc247 --- /dev/null +++ b/autoprocess/radarr.py @@ -0,0 +1,68 @@ +import sys +import os +import logging +import json + + +def processMovie(dirName, settings, nzbGet=False, logger=None): + + if nzbGet: + errorprefix = "[ERROR] " + infoprefix = "[INFO] " + else: + errorprefix = "" + infoprefix = "" + + # Setup logging + if logger: + log = logger + else: + log = logging.getLogger(__name__) + + log.info("%sRadarr notifier started." % infoprefix) + + # Import Requests + try: + import requests + except ImportError: + log.exception("%sPython module REQUESTS is required. Install with 'pip install requests' then try again." % errorprefix) + log.error("%sPython executable path is %s" % (errorprefix, sys.executable)) + return False + + host = settings.Radarr['host'] + port = settings.Radarr['port'] + apikey = settings.Radarr['apikey'] + + if apikey == '': + log.error("%sYour Radarr API Key can not be blank. Update autoProcess.ini." % errorprefix) + return False + + try: + ssl = int(settings.Radarr['ssl']) + except: + ssl = 0 + if ssl: + protocol = "https://" + else: + protocol = "http://" + + url = protocol + host + ":" + port + "/api/command" + payload = {'name': 'downloadedepisodesscan', 'path': dirName} + headers = {'X-Api-Key': apikey} + + log.debug("Radarr host: %s." % host) + log.debug("Radarr port: %s." % port) + log.debug("Radarr apikey: %s." % apikey) + log.debug("Radarr protocol: %s." % protocol) + log.debug("URL '%s' with payload '%s.'" % (url, payload)) + + log.info("%sRequesting Radarr to scan directory '%s'." % (infoprefix, dirName)) + + try: + r = requests.post(url, data=json.dumps(payload), headers=headers) + rstate = r.json() + log.info("%sRadarr response: %s." % (infoprefix, rstate['state'])) + return True + except: + log.exception("%sUpdate to Radarr failed, check if Radarr is running, autoProcess.ini settings and make sure your Radarr settings are correct (apikey?), or check install of python modules requests." % errorprefix) + return False diff --git a/delugePostProcess.py b/delugePostProcess.py index cfd124bf..2cf25a15 100644 --- a/delugePostProcess.py +++ b/delugePostProcess.py @@ -2,7 +2,7 @@ import os import sys -from autoprocess import autoProcessTV, autoProcessMovie, autoProcessTVSR, sonarr +from autoprocess import autoProcessTV, autoProcessMovie, autoProcessTVSR, sonarr, radarr from readSettings import ReadSettings from mkvtomp4 import MkvtoMp4 from deluge_client import DelugeRPCClient @@ -15,7 +15,7 @@ log.info("Deluge post processing started.") settings = ReadSettings(os.path.dirname(sys.argv[0]), "autoProcess.ini") -categories = [settings.deluge['sb'], settings.deluge['cp'], settings.deluge['sonarr'], settings.deluge['sr'], settings.deluge['bypass']] +categories = [settings.deluge['sb'], settings.deluge['cp'], settings.deluge['sonarr'], settings.deluge['radarr'], settings.deluge['sr'], settings.deluge['bypass']] if len(sys.argv) < 4: log.error("Not enough command line parameters present, are you launching this from deluge?") @@ -107,9 +107,12 @@ log.info("Passing %s directory to Sonarr." % path) sonarr.processEpisode(path, settings) elif (category == categories[3]): + log.info("Passing %s directory to Radarr." % path) + radarr.processMovie(path, settings) +elif (category == categories[4]): log.info("Passing %s directory to Sickrage." % path) autoProcessTVSR.processEpisode(path, settings) -elif (category == categories[4]): +elif (category == categories[5]): log.info("Bypassing any further processing as per category.") if delete_dir: diff --git a/readSettings.py b/readSettings.py index 1257d80c..b808136b 100644 --- a/readSettings.py +++ b/readSettings.py @@ -113,11 +113,18 @@ def __init__(self, directory, filename, logger=None): 'apikey': '', 'ssl': 'False', 'web_root': ''} + # Default settings for Radarr + radarr_defaults = {'host': 'localhost', + 'port': '7878', + 'apikey': '', + 'ssl': 'False', + 'web_root': ''} # Default uTorrent settings utorrent_defaults = {'couchpotato-label': 'couchpotato', 'sickbeard-label': 'sickbeard', 'sickrage-label': 'sickrage', 'sonarr-label': 'sonarr', + 'radarr-label': 'radarr', 'bypass-label': 'bypass', 'convert': 'True', 'webui': 'False', @@ -133,6 +140,7 @@ def __init__(self, directory, filename, logger=None): 'Sickrage-category': 'sickrage', 'Couchpotato-category': 'couchpotato', 'Sonarr-category': 'sonarr', + 'Radarr-category': 'radarr', 'Bypass-category': 'bypass', 'output_directory': ''} # Default Sickrage Settings @@ -149,6 +157,7 @@ def __init__(self, directory, filename, logger=None): 'sickbeard-label': 'sickbeard', 'sickrage-label': 'sickrage', 'sonarr-label': 'sonarr', + 'radarr-label': 'radarr', 'bypass-label': 'bypass', 'convert': 'True', 'host': 'localhost', @@ -163,7 +172,7 @@ def __init__(self, directory, filename, logger=None): 'refresh': 'true', 'token': ''} - defaults = {'SickBeard': sb_defaults, 'CouchPotato': cp_defaults, 'Sonarr': sonarr_defaults, 'MP4': mp4_defaults, 'uTorrent': utorrent_defaults, 'SABNZBD': sab_defaults, 'Sickrage': sr_defaults, 'Deluge': deluge_defaults, 'Plex': plex_defaults} + defaults = {'SickBeard': sb_defaults, 'CouchPotato': cp_defaults, 'Sonarr': sonarr_defaults, 'Radarr': radarr_defaults, 'MP4': mp4_defaults, 'uTorrent': utorrent_defaults, 'SABNZBD': sab_defaults, 'Sickrage': sr_defaults, 'Deluge': deluge_defaults, 'Plex': plex_defaults} write = False # Will be changed to true if a value is missing from the config file and needs to be written config = configparser.SafeConfigParser() @@ -487,6 +496,7 @@ def __init__(self, directory, filename, logger=None): self.uTorrent['sb'] = config.get(section, "sickbeard-label").lower() self.uTorrent['sr'] = config.get(section, "sickrage-label").lower() self.uTorrent['sonarr'] = config.get(section, "sonarr-label").lower() + self.uTorrent['radarr'] = config.get(section, "radarr-label").lower() self.uTorrent['bypass'] = config.get(section, "bypass-label").lower() try: self.uTorrent['convert'] = config.getboolean(section, "convert") @@ -511,6 +521,7 @@ def __init__(self, directory, filename, logger=None): self.deluge['sb'] = config.get(section, "sickbeard-label").lower() self.deluge['sr'] = config.get(section, "sickrage-label").lower() self.deluge['sonarr'] = config.get(section, "sonarr-label").lower() + self.deluge['radarr'] = config.get(section, "radarr-label").lower() self.deluge['bypass'] = config.get(section, "bypass-label").lower() try: self.deluge['convert'] = config.getboolean(section, "convert") @@ -535,6 +546,15 @@ def __init__(self, directory, filename, logger=None): self.Sonarr['ssl'] = config.get(section, "ssl") self.Sonarr['web_root'] = config.get(section, "web_root") + # Read relevant Radarr section information + section = "Radarr" + self.Radarr = {} + self.Radarr['host'] = config.get(section, "host") + self.Radarr['port'] = config.get(section, "port") + self.Radarr['apikey'] = config.get(section, "apikey") + self.Radarr['ssl'] = config.get(section, "ssl") + self.Radarr['web_root'] = config.get(section, "web_root") + # Read Sickbeard section information section = "SickBeard" self.Sickbeard = {} @@ -568,6 +588,7 @@ def __init__(self, directory, filename, logger=None): self.SAB['sb'] = config.get(section, "Sickbeard-category").lower() self.SAB['sr'] = config.get(section, "Sickrage-category").lower() self.SAB['sonarr'] = config.get(section, "Sonarr-category").lower() + self.SAB['radarr'] = config.get(section, "Radarr-category").lower() self.SAB['bypass'] = config.get(section, "Bypass-category").lower() self.SAB['output_dir'] = config.get(section, "output_directory") if self.SAB['output_dir'] == '': diff --git a/uTorrentPostProcess.py b/uTorrentPostProcess.py index 35fa38c5..cdf002f2 100644 --- a/uTorrentPostProcess.py +++ b/uTorrentPostProcess.py @@ -2,7 +2,7 @@ import re import sys import shutil -from autoprocess import autoProcessTV, autoProcessMovie, autoProcessTVSR, sonarr +from autoprocess import autoProcessTV, autoProcessMovie, autoProcessTVSR, sonarr, radarr from readSettings import ReadSettings from mkvtomp4 import MkvtoMp4 import logging @@ -53,7 +53,7 @@ def _sendRequest(session, host='http://localhost:8080/', username=None, password settings = ReadSettings(os.path.dirname(sys.argv[0]), "autoProcess.ini") path = str(sys.argv[3]) label = sys.argv[1].lower() -categories = [settings.uTorrent['cp'], settings.uTorrent['sb'], settings.uTorrent['sonarr'], settings.uTorrent['sr'], settings.uTorrent['bypass']] +categories = [settings.uTorrent['cp'], settings.uTorrent['sb'], settings.uTorrent['sonarr'], settings.uTorrent['radarr'], settings.uTorrent['sr'], settings.uTorrent['bypass']] torrent_hash = sys.argv[6] try: name = sys.argv[7] @@ -138,9 +138,6 @@ def _sendRequest(session, host='http://localhost:8080/', username=None, password try: output = converter.process(inputfile) ignore.append(output['output']) - if (label == categories[2] and settings.relocate_moov): - log.debug("Performing QTFS move because video was converted and Sonarr has no post processing.") - converter.QTFS(output['output']) except: log.exception("Error converting file %s." % inputfile) else: @@ -175,9 +172,12 @@ def _sendRequest(session, host='http://localhost:8080/', username=None, password log.info("Passing %s directory to Sonarr." % path) sonarr.processEpisode(path, settings) elif label == categories[3]: + log.info("Passing %s directory to Radarr." % path) + radarr.processMovie(path, settings) +elif label == categories[4]: log.info("Passing %s directory to Sickrage." % path) autoProcessTVSR.processEpisode(path, settings) -elif label == categories[4]: +elif label == categories[5]: log.info("Bypassing any further processing as per category.") # Run a uTorrent action after conversion.