diff --git a/TorrentToMedia.py b/TorrentToMedia.py index 39b083292..28f09d76d 100755 --- a/TorrentToMedia.py +++ b/TorrentToMedia.py @@ -79,7 +79,7 @@ def process_torrent(input_directory, input_name, input_category, input_hash, inp if section is None: #Check for user_scripts for 'ALL' and 'UNCAT' if usercat in core.CATEGORIES: section = core.CFG.findsection('ALL').isenabled() - usercat = 'ALL' + usercat = 'ALL' else: section = core.CFG.findsection('UNCAT').isenabled() usercat = 'UNCAT' @@ -213,7 +213,7 @@ def process_torrent(input_directory, input_name, input_category, input_hash, inp core.flatten(output_destination) # Now check if video files exist in destination: - if section_name in ['SickBeard', 'NzbDrone', 'Sonarr', 'CouchPotato', 'Radarr']: + if section_name in ['SickBeard', 'NzbDrone', 'Sonarr', 'CouchPotato', 'Radarr', 'Watcher3']: num_videos = len( core.list_media_files(output_destination, media=True, audio=False, meta=False, archives=False)) if num_videos > 0: @@ -227,7 +227,7 @@ def process_torrent(input_directory, input_name, input_category, input_hash, inp # Only these sections can handling failed downloads # so make sure everything else gets through without the check for failed - if section_name not in ['CouchPotato', 'Radarr', 'SickBeard', 'NzbDrone', 'Sonarr']: + if section_name not in ['CouchPotato', 'Radarr', 'SickBeard', 'NzbDrone', 'Sonarr', 'Watcher3']: status = 0 logger.info('Calling {0}:{1} to post-process:{2}'.format(section_name, usercat, input_name)) @@ -241,7 +241,7 @@ def process_torrent(input_directory, input_name, input_category, input_hash, inp ) if section_name == 'UserScript': result = external_script(output_destination, input_name, input_category, section) - elif section_name in ['CouchPotato', 'Radarr']: + elif section_name in ['CouchPotato', 'Radarr', 'Watcher3']: result = movies.process(section_name, output_destination, input_name, status, client_agent, input_hash, input_category) elif section_name in ['SickBeard', 'NzbDrone', 'Sonarr']: if input_hash: diff --git a/_config.yml b/_config.yml new file mode 100644 index 000000000..c4192631f --- /dev/null +++ b/_config.yml @@ -0,0 +1 @@ +theme: jekyll-theme-cayman \ No newline at end of file diff --git a/autoProcessMedia.cfg.spec b/autoProcessMedia.cfg.spec index e3d11cb66..7af48e011 100644 --- a/autoProcessMedia.cfg.spec +++ b/autoProcessMedia.cfg.spec @@ -12,7 +12,7 @@ git_user = # GitHUB branch for repo git_branch = - # Enable/Disable forceful cleaning of leftover files following postprocess + # Enable/Disable forceful cleaning of leftover files following postprocess force_clean = 0 # Enable/Disable logging debug messages to nzbtomedia.log log_debug = 0 @@ -36,7 +36,7 @@ [Posix] ### Process priority setting for External commands (Extractor and Transcoder) on Posix (Unix/Linux/OSX) systems. # Set the Niceness value for the nice command. These range from -20 (most favorable to the process) to 19 (least favorable to the process). - # If entering an integer e.g 'niceness = 4', this is added to the nice command and passed as 'nice -n4' (Default). + # If entering an integer e.g 'niceness = 4', this is added to the nice command and passed as 'nice -n4' (Default). # If entering a comma separated list e.g. 'niceness = nice,4' this will be passed as 'nice 4' (Safer). niceness = nice,-n0 # Set the ionice scheduling class. 0 for none, 1 for real time, 2 for best-effort, 3 for idle. @@ -111,6 +111,36 @@ ##### Set to define import behavior Move or Copy importMode = Copy +[Watcher3] + #### autoProcessing for Movies + #### movie - category that gets called for post-processing with CPS + [[movie]] + enabled = 0 + apikey = + host = localhost + port = 9090 + ###### ADVANCED USE - ONLY EDIT IF YOU KNOW WHAT YOU'RE DOING ###### + ssl = 0 + web_root = + # api key for www.omdbapi.com (used as alternative to imdb) + omdbapikey = + # Enable/Disable linking for Torrents + Torrent_NoLink = 0 + keep_archive = 1 + delete_failed = 0 + wait_for = 0 + extract = 1 + # Set this to minimum required size to consider a media file valid (in MB) + minSize = 0 + # Enable/Disable deleting ignored files (samples and invalid media files) + delete_ignored = 0 + ##### Enable if Watcher3 is on a remote server for this category + remote_path = 0 + ##### Set to path where download client places completed downloads locally for this category + watch_dir = + ##### Set the recursive directory permissions to the following (0 to disable) + chmodDirectory = 0 + [SickBeard] #### autoProcessing for TV Series #### tv - category that gets called for post-processing with SB @@ -266,7 +296,7 @@ apikey = host = localhost port = 8085 - ###### + ###### library = Set to path where you want the processed games to be moved to. ###### ADVANCED USE - ONLY EDIT IF YOU KNOW WHAT YOU'RE DOING ###### ssl = 0 @@ -312,7 +342,7 @@ [Network] # Enter Mount points as LocalPath,RemotePath and separate each pair with '|' # e.g. MountPoints = /volume1/Public/,E:\|/volume2/share/,\\NAS\ - mount_points = + mount_points = [Nzb] ###### clientAgent - Supported clients: sabnzbd, nzbget @@ -331,7 +361,7 @@ useLink = hard ###### outputDirectory - Default output directory (categories will be appended as sub directory to outputDirectory) outputDirectory = /abs/path/to/complete/ - ###### Enter the default path to your default download directory (non-category downloads). this directory is protected by safe_mode. + ###### Enter the default path to your default download directory (non-category downloads). this directory is protected by safe_mode. default_downloadDirectory = ###### Other categories/labels defined for your downloader. Does not include CouchPotato, SickBeard, HeadPhones, Mylar categories. categories = music_videos,pictures,software,manual @@ -374,15 +404,15 @@ plex_host = localhost plex_port = 32400 plex_token = - plex_ssl = 0 + plex_ssl = 0 # Enter Plex category to section mapping as Category,section and separate each pair with '|' # e.g. plex_sections = movie,3|tv,4 - plex_sections = + plex_sections = [Transcoder] # getsubs. enable to download subtitles. getSubs = 0 - # subLanguages. create a list of languages in the order you want them in your subtitles. + # subLanguages. create a list of languages in the order you want them in your subtitles. subLanguages = eng,spa,fra # transcode. enable to use transcoder transcode = 0 @@ -397,7 +427,7 @@ # outputQualityPercent. used as -q:a value. 0 will disable this from being used. outputQualityPercent = 0 # outputVideoPath. Set path you want transcoded videos moved to. Leave blank to disable. - outputVideoPath = + outputVideoPath = # processOutput. 1 will send the outputVideoPath to SickBeard/CouchPotato. 0 will send original files. processOutput = 0 # audioLanguage. set the 3 letter language code you want as your primary audio track. @@ -427,7 +457,7 @@ #### Define custom settings below. outputVideoExtension = .mp4 outputVideoCodec = libx264 - VideoCodecAllow = + VideoCodecAllow = outputVideoPreset = medium outputVideoResolution = 1920:1080 outputVideoFramerate = 24 @@ -435,15 +465,15 @@ outputVideoCRF = 19 outputVideoLevel = 3.1 outputAudioCodec = ac3 - AudioCodecAllow = + AudioCodecAllow = outputAudioChannels = 6 outputAudioBitrate = 640k outputAudioTrack2Codec = libfaac - AudioCodec2Allow = - outputAudioTrack2Channels = 2 + AudioCodec2Allow = + outputAudioTrack2Channels = 2 outputAudioTrack2Bitrate = 128000 outputAudioOtherCodec = libmp3lame - AudioOtherCodecAllow = + AudioOtherCodecAllow = outputAudioOtherChannels = outputAudioOtherBitrate = 128000 outputSubtitleCodec = @@ -500,4 +530,4 @@ # enter a list (comma separated) of Group Tags you want removed from filenames to help with subtitle matching. # e.g remove_group = [rarbag],-NZBgeek # be careful if your "group" is a common "real" word. Please report if you have any group replacements that would fall in this category. - remove_group = + remove_group = diff --git a/core/auto_process/movies.py b/core/auto_process/movies.py index 2661edd12..e7439aa07 100644 --- a/core/auto_process/movies.py +++ b/core/auto_process/movies.py @@ -72,6 +72,8 @@ def process(section, dir_name, input_name=None, status=0, client_agent='manual', base_url = '{0}{1}:{2}{3}/api/command'.format(protocol, host, port, web_root) url2 = '{0}{1}:{2}{3}/api/config/downloadClient'.format(protocol, host, port, web_root) headers = {'X-Api-Key': apikey} + if section == 'Watcher3': + base_url = '{0}{1}:{2}{3}/postprocessing'.format(protocol, host, port, web_root) if not apikey: logger.info('No CouchPotato or Radarr apikey entered. Performing transcoder functions only') release = None @@ -178,7 +180,7 @@ def process(section, dir_name, input_name=None, status=0, client_agent='manual', os.rename(video, video2) if not apikey: # If only using Transcoder functions, exit here. - logger.info('No CouchPotato or Radarr apikey entered. Processing completed.') + logger.info('No CouchPotato or Radarr or Watcher3 apikey entered. Processing completed.') return ProcessResult( message='{0}: Successfully post-processed {1}'.format(section, input_name), status_code=0, @@ -210,9 +212,20 @@ def process(section, dir_name, input_name=None, status=0, client_agent='manual', logger.debug('Opening URL: {0} with PARAMS: {1}'.format(base_url, payload), section) logger.postprocess('Starting DownloadedMoviesScan scan for {0}'.format(input_name), section) + if section == 'Watcher3': + if input_name and os.path.isfile(os.path.join(dir_name, input_name)): + params['media_folder'] = os.path.join(params['media_folder'], input_name) + payload = {'apikey': apikey, 'path': params['media_folder'], 'guid': download_id, 'mode': 'complete'} + if not download_id: + payload.pop('guid') + logger.debug('Opening URL: {0} with PARAMS: {1}'.format(base_url, payload), section) + logger.postprocess('Starting postprocessing scan for {0}'.format(input_name), section) + try: if section == 'CouchPotato': r = requests.get(url, params=params, verify=False, timeout=(30, 1800)) + elif section == 'Watcher3': + r = requests.post(base_url, data=payload, verify=False, timeout=(30, 1800)) else: r = requests.post(base_url, data=json.dumps(payload), headers=headers, stream=True, verify=False, timeout=(30, 1800)) except requests.ConnectionError: @@ -245,6 +258,18 @@ def process(section, dir_name, input_name=None, status=0, client_agent='manual', except Exception as e: logger.warning('No scan id was returned due to: {0}'.format(e), section) scan_id = None + elif section == 'Watcher3' and result['status'] == 'finished': + logger.postprocess('Watcher3 updated status to {0}'.format(result['tasks']['update_movie_status'])) + if result['tasks']['update_movie_status'] == 'Finished': + return ProcessResult( + message='{0}: Successfully post-processed {1}'.format(section, input_name), + status_code=status, + ) + else: + return ProcessResult( + message='{0}: Failed to post-process - changed status to {1}'.format(section, result['tasks']['update_movie_status']), + status_code=1, + ) else: logger.error('FAILED: {0} scan was unable to finish for folder {1}. exiting!'.format(method, dir_name), section) @@ -264,6 +289,20 @@ def process(section, dir_name, input_name=None, status=0, client_agent='manual', message='{0}: Sending failed download back to {0}'.format(section), status_code=1, # Return as failed to flag this in the downloader. ) # Return failed flag, but log the event as successful. + elif section == 'Watcher3': + logger.postprocess('Sending failed download to {0} for CDH processing'.format(section), section) + path = remote_dir(dir_name) if remote_path else dir_name + if input_name and os.path.isfile(os.path.join(dir_name, input_name)): + path = os.path.join(path, input_name) + payload = {'apikey': apikey, 'path': path, 'guid': download_id, 'mode': 'failed'} + r = requests.post(base_url, data=payload, verify=False, timeout=(30, 1800)) + result = r.json() + logger.postprocess('Watcher3 response: {0}'.format(result)) + if result['status'] == 'finished': + return ProcessResult( + message='{0}: Sending failed download back to {0}'.format(section), + status_code=1, # Return as failed to flag this in the downloader. + ) # Return failed flag, but log the event as successful. if delete_failed and os.path.isdir(dir_name) and not os.path.dirname(dir_name) == dir_name: logger.postprocess('Deleting failed files and folder {0}'.format(dir_name), section) diff --git a/nzbToMedia.py b/nzbToMedia.py index 2ab16d59e..1c04cd7b3 100755 --- a/nzbToMedia.py +++ b/nzbToMedia.py @@ -5,7 +5,7 @@ ### NZBGET POST-PROCESSING SCRIPT ### # Post-Process to CouchPotato, SickBeard, Sonarr, Mylar, Gamez, HeadPhones, -# LazyLibrarian, Radarr, Lidarr +# LazyLibrarian, Radarr, Lidarr, Watcher3 # # This script sends the download to your automated media management servers. # @@ -799,7 +799,7 @@ def process(input_directory, input_name=None, status=0, client_agent='manual', d logger.info('Calling {0}:{1} to post-process:{2}'.format(section_name, input_category, input_name)) - if section_name in ['CouchPotato', 'Radarr']: + if section_name in ['CouchPotato', 'Radarr', 'Watcher3']: result = movies.process(section_name, input_directory, input_name, status, client_agent, download_id, input_category, failure_link) elif section_name in ['SickBeard', 'NzbDrone', 'Sonarr']: result = tv.process(section_name, input_directory, input_name, status, client_agent, download_id, input_category, failure_link)