Post Processing - nosmokingbandit/watcher GitHub Wiki

Watcher supplies a method to post-process completed or failed downloads for all supported download clients.

Scripts

In watcher/post scripts you will find a python script with the name of your downloader. Copy this to the appropriate scripts directory for your downloader, and rename to watcher.py if you wish.

Depending on your operating system and environment you may need to change the permissions on the script to allow execution.

NZBGet

Open NZBGet and set up a new category in Settings. The category name must match the category set up in Watcher's downloader settings.

In the NZBGet sidebar, open Watcher. If the option is not there you may need to restart NZBGet. Add your Watcher server information. If you are running Watcher behind a proxy such as Apache or Nginx you must use the full path to watcher, as shown in the image.

Save your settings and restart NZBGet.

Sabnzbd

Open the post-processing script in a text editor and modify the conf entry at the top of the file. If you are running Watcher behind a proxy such as Apache or Nginx you must use the full path to watcher, as shown in the example.

conf = {
    'watcherapi': '12345678987654321',
    'watcheraddress': 'http://localhost:9090/watcher',
    'sabkey': 'SABAPIKEY',
    'sabhost': 'localhost',
    'sabport': '8080'
}

Open Sabnzbd and set up a new category. The category name must match the category set up in Watcher's downloader settings.

In Switches, un-check the option to Post-Process Only Verified Jobs.

Save your settings and restart Sabnzbd.

Deluge

Open the post-processing script in a text editor and modify the config section at the top of the file. If you are running Watcher behind a proxy such as Apache or Nginx you must use the full path to watcher, as shown in the example.

The category must match the category in Settings > Downloader.

watcherapi = '12345678987654321'
watcheraddress = 'http://localhost:9090/watcher'
category = 'Watcher'

Open Deluge and open Edit > Preferences. Click on Plugins and enable the plugin Execute. Click on Execute and add a new event Torrent Complete.

If using Linux or a similar OS, enter the path to the post-processing script and click Add.

If using Windows, enter the path to deluge.bat and click Add. In Windows, Deluge is unable to execute python directly. Deluge is, however, able to execute a batch file which in turn executes the python script. deluge.bat must stay in the same directory as deluge.py.

Apply the changes and restart Deluge.

Transmission

Open the post-processing script in a text editor and modify the config section at the top of the file. If you are running Watcher behind a proxy such as Apache or Nginx you must use the full path to watcher, as shown in the example.

The category must match the category in Settings > Downloader.

watcherapi = '12345678987654321'
watcheraddress = 'http://localhost:9090/watcher'
category = 'Watcher'

Close Transmission and edit Transmission's settings.json file. This can be found in ~/.config/transmission/settings.json.

Change the following two lines:

    "script-torrent-done-enabled": true,
    "script-torrent-done-filename": "/path/to/script/transmission.py",

Save your changes and start Transmission.

Getting transmission to execute python scripts directly can be hit-or-miss, so it may be necessary to use a shell script to execute the Watcher post-script:

#!/bin/sh
/usr/bin/python /path/to/script/transmission.py

QBittorrent

Open the post-processing script in a text editor and modify the config section at the top of the file. If you are running Watcher behind a proxy such as Apache or Nginx you must use the full path to watcher, as shown in the example.

The category must match the category in Settings > Downloader.

watcherapi = '12345678987654321'
watcheraddress = 'http://localhost:9090/watcher'
category = 'Watcher'

Open QBittorrent and open Tools > Options. Click on Downloads and scroll to the bottom. Enable Run external program on torrent completion and enter the path to the post-processing script followed by "%N" "%D" "%R" "%I". It my be necessary to preface the script path with python depending on your environment.

Apply settings and restart QBittorrent.

rTorrent

Open the post-processing script in a text editor and modify the config section at the top of the file. If you are running Watcher behind a proxy such as Apache or Nginx you must use the full path to watcher, as shown in the example.

The label must match the label set in Settings > Downloader.

watcherapi = '12345678987654321'
watcheraddress = 'http://localhost:9090/watcher'
category = 'Watcher'

Open your rTorrent config file, typically located at ~/.rtorrent.rc

Add the following line:

system.method.set_key = event.download.finished,Watcher,"execute={/usr/bin/python,/PATH/TO/RTORRENT.PY,\"$d.get_custom1=\",\"$d.get_name=\",\"$d.get_hash=\",\"$d.get_base_path=\"}"

Change /PATH/TO/RTORRENT.PY to the absolute path of the rTorrent post-processing script. If your python binary is in a different location than /usr/bin/python you may need to change that as well.

Save the file and restart rTorrent.

Creating a Post-Processing request

If you need to send a post-processing request manually, or through another script, the process if fairly straightforward.

You will need to send a POST request to the Watcher server, using the url http://ipaddress:9090/postprocessing/

The request needs to pass a JSON object with the following keys:

  • apikey Watcher's API key.
  • mode 'complete' or 'failed'.
  • guid For NZB's the full download link to the file. For torrents or magnets use the torrent hash. Can be none as well, but search results will not be marked as Bad or Finished.
  • path File path to the download. Can be a directory or single file.

A large timeout is necessary for the POST request response when moving large files across slower media. Tailor this to fit your needs.

The response from Watcher will be a JSON object with a large amount of post-processing data.

A quick example of this in python is:

import json
import urllib
import urllib2

data = {'apikey': '123456789abcdef', 'mode': 'complete', 'guid': '123456789ABCDEFEDCBA9876543210', 'path': '/home/user/downloads/Super.Cool.Movie.2017'}

post_data = urllib.urlencode(data)

request = urllib2.Request(url, post_data)

response = json.loads(urllib2.urlopen(request, timeout=300))

A typical response is as follows:

{
    "status": "finished", 
    "tasks": {
        "update_movie_status": "true", 
        "0123456789ABCDEFEDBCA9876543210": {
            "update_SEARCHRESULTS": "true", 
            "update_MARKEDRESULTS": "true"
        }, 
        "mover": {
            "enabled": "true", 
            "response": "true"
        }, 
        "cleanup": {
            "enabled": "true", 
            "response": "true"
        }, 
        "renamer": {
            "enabled": "true", 
            "response": "true"
        }
    }, 
    "data": {
        "orig_filename": "/home/user/downloads/Super.Cool.Movie.2017/Super.Cool.Movie.2017.mkv", 
        "finished_score": 715, 
        "year": "2017", 
        "guid": "0123456789ABCDEFEDBCA9876543210", 
        "audiocodec": "DTS", 
        "predb": "found", 
        "rated": "R", 
        "container": "mkv", 
        "downloadid": "0123456789ABCDEFEDBCA9876543210", 
        "title": "Super Cool Movie", 
        "imdbid": "tt0000000", 
        "filename": "/home/user/downloads/Super Cool Movie (2017) 1080P DTS.mkv", 
        "source": "BluRay", 
        "score": "6.5",
        "new_file_location": "/home/user/Movies/Super Cool Movie (2017) 1080P DTS.mkv", 
        "status": "Snatched", 
        "finished_date": "2017-02-10", 
        "videocodec": "x264", 
        "poster": "images/poster/tt0000000.jpg", 
        "added_date": "2017-01-01", 
        "releasegroup": "", 
        "path": "/home/user/downloads/Super.Cool.Movie.2017/", 
        "apikey": "1c528e78c625e64e9a008d86a1b207cc", 
        "name": "Super.Cool.Movie.2017", 
        "url": "https://www.themoviedb.org/movie/tt000000", 
        "release_date": "2017-01-01", 
        "mode": "complete", 
        "resolution": "1080p"
    }
}

response['status'] be 'finished' if all tasks complete successfully or 'incomplete' should any task fail.

Several other fields may be blank contingent on Watcher's ability to parse the metadata from the information given.