Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 34 additions & 10 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
"NZBPO_PROCESSMETHOD",
"NZBPO_FORCEREPLACE",
"NZBPO_ISPRIORITY",
"NZBPO_DELETE",
"NZBPO_VERBOSE",
]

Expand Down Expand Up @@ -115,18 +116,29 @@ def ping_sickchill(url: str) -> int:


def start_post_proccessing(
url: str, path: str, process_method: str, force_replace: int, is_priority: int
url: str,
path: str,
process_method: str,
force_replace: int,
is_priority: int,
delete: int = 0,
failed: int = 0,
nzb_name: str = None,
) -> int:
try:
encoded_params = urllib.parse.urlencode(
{
"cmd": "postprocess",
"path": path,
"process_method": process_method,
"force_replace": force_replace,
"is_priority": is_priority,
}
)
params = {
"cmd": "postprocess",
"path": path,
"process_method": process_method,
"force_replace": force_replace,
"is_priority": is_priority,
"delete": delete,
"failed": failed,
}
if nzb_name:
params["nzbName"] = nzb_name

encoded_params = urllib.parse.urlencode(params)

if VERBOSE:
print(f"[INFO] PARAMS:", encoded_params)
Expand All @@ -148,6 +160,7 @@ def start_post_proccessing(

except JSONDecodeError as ex:
print("[ERROR] Wrong API Key?")
return ERROR

except Exception as ex:
print("[ERROR] Unexpected exception:", ex)
Expand All @@ -162,10 +175,18 @@ def start_post_proccessing(
PROCESS_METHOD = METHODS_MAP[os.environ["NZBPO_PROCESSMETHOD"]]
FORCE_REPLACE = int(os.environ["NZBPO_FORCEREPLACE"] == "yes")
IS_PRIORITY = int(os.environ["NZBPO_ISPRIORITY"] == "yes")
DELETE = int(os.environ["NZBPO_DELETE"] == "yes")

TOTAL_STATUS = os.environ.get("NZBPP_TOTALSTATUS")
STATUS = os.environ.get("NZBPP_STATUS", "")
FAILED = int(TOTAL_STATUS not in (None, "SUCCESS") or STATUS.startswith("FAILURE"))
NZB_NAME = os.environ.get("NZBPP_NZBNAME")


if VERBOSE:
print("[INFO] PATH:", PATH)
if FAILED:
print("[INFO] Download status indicates FAILURE. Sending failed post-processing notification.")


sys.exit(
Expand All @@ -175,5 +196,8 @@ def start_post_proccessing(
PROCESS_METHOD,
FORCE_REPLACE,
IS_PRIORITY,
DELETE,
FAILED,
NZB_NAME,
)
)
17 changes: 15 additions & 2 deletions manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"homepage": "https://github.com/nzbgetcom/Extension-NotifySickChill/",
"kind": "POST-PROCESSING",
"displayName": "Notify SickChill",
"version": "1.0",
"version": "1.1",
"author": "Denis",
"license": "GNU",
"about": "Post-Processing extension to trigger SickChill after downloads.",
Expand Down Expand Up @@ -37,7 +37,7 @@
"displayName": "API Key",
"value": "<API KEY>",
"description": [
"Used to authenticate and authorize access to an SickChill API.",
"Used to authenticate and authorize access to the SickChill API.",
"",
"Can be found in the settings of the web interface of SickChill."
],
Expand Down Expand Up @@ -77,6 +77,19 @@
],
"select": ["no", "yes"]
},
{
"name": "delete",
"displayName": "Delete",
"value": "no",
"description": [
"Delete files and folders after completion of Post-Processing.",
"",
"Recommended when Process Method is Copy, Hard link or Symbolic link:",
"original files remain in the download directory and are removed after processing.",
"With Move it cleans up leftover files and empty folders."
],
"select": ["no", "yes"]
},
{
"name": "Verbose",
"displayName": "Verbose",
Expand Down
107 changes: 106 additions & 1 deletion tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,67 @@ def do_GET(self):
process_method = query_params.get("process_method", [""])[0] == "move"
force_replace = query_params.get("force_replace", [""])[0] == "1"
is_priority = query_params.get("is_priority", [""])[0] == "1"
delete = query_params.get("delete", ["0"])[0] in ["0", "1"]
failed = query_params.get("failed", ["0"])[0] in ["0", "1"]

if cmd and path and process_method and force_replace and is_priority:
if cmd and path and process_method and force_replace and is_priority and delete and failed:
self.send_response(200)
self.send_header("Content-type", "application/json")
self.end_headers()
data = {"data": {}, "message": "Started", "result": "success"}
response = json.dumps(data)
self.wfile.write(response.encode("utf-8"))
else:
self.send_response(400)
self.send_header("Content-type", "application/json")
self.end_headers()
data = {"data": {}, "message": "Failure", "result": "failure"}
response = json.dumps(data)
self.wfile.write(response.encode("utf-8"))


class HttpServerPostprocFailedMock(http.server.BaseHTTPRequestHandler):
def do_GET(self):
parsed_url = urlparse(self.path)
query_params = parse_qs(parsed_url.query)
cmd = query_params.get("cmd", [""])[0] == "postprocess"
path = query_params.get("path", [""])[0] == ROOT_DIR
process_method = query_params.get("process_method", [""])[0] == "move"
force_replace = query_params.get("force_replace", [""])[0] == "1"
is_priority = query_params.get("is_priority", [""])[0] == "1"
delete = query_params.get("delete", ["0"])[0] in ["0", "1"]
failed = query_params.get("failed", [""])[0] == "1"
nzb_name = query_params.get("nzbName", [""])[0] == "Test.Show.S01E01"

if cmd and path and process_method and force_replace and is_priority and delete and failed and nzb_name:
self.send_response(200)
self.send_header("Content-type", "application/json")
self.end_headers()
data = {"data": {}, "message": "Started", "result": "success"}
response = json.dumps(data)
self.wfile.write(response.encode("utf-8"))
else:
self.send_response(400)
self.send_header("Content-type", "application/json")
self.end_headers()
data = {"data": {}, "message": "Failure", "result": "failure"}
response = json.dumps(data)
self.wfile.write(response.encode("utf-8"))


class HttpServerPostprocDeleteMock(http.server.BaseHTTPRequestHandler):
def do_GET(self):
parsed_url = urlparse(self.path)
query_params = parse_qs(parsed_url.query)
cmd = query_params.get("cmd", [""])[0] == "postprocess"
path = query_params.get("path", [""])[0] == ROOT_DIR
process_method = query_params.get("process_method", [""])[0] == "move"
force_replace = query_params.get("force_replace", [""])[0] == "1"
is_priority = query_params.get("is_priority", [""])[0] == "1"
delete = query_params.get("delete", [""])[0] == "1"
failed = query_params.get("failed", [""])[0] == "0"

if cmd and path and process_method and force_replace and is_priority and delete and failed:
self.send_response(200)
self.send_header("Content-type", "application/json")
self.end_headers()
Expand Down Expand Up @@ -101,6 +160,7 @@ def set_default_env():
os.environ["NZBPO_PROCESSMETHOD"] = "Copy"
os.environ["NZBPO_FORCEREPLACE"] = "yes"
os.environ["NZBPO_ISPRIORITY"] = "yes"
os.environ["NZBPO_DELETE"] = "no"
os.environ["NZBPO_VERBOSE"] = "yes"


Expand Down Expand Up @@ -129,6 +189,51 @@ def test_postproc(self):
thread.join()
self.assertEqual(code, SUCCESS)

def test_postproc_delete(self):
set_default_env()
os.environ["NZBPO_PROCESSMETHOD"] = "Move"
os.environ["NZBPO_DELETE"] = "yes"
os.environ["NZBPP_TOTALSTATUS"] = "SUCCESS"
server = http.server.HTTPServer((HOST, int(PORT)), HttpServerPostprocDeleteMock)
thread = threading.Thread(target=server.serve_forever)
thread.start()
[_, code, _] = run_script()
server.shutdown()
server.server_close()
thread.join()
self.assertEqual(code, SUCCESS)

def test_postproc_failed_totalstatus(self):
set_default_env()
os.environ["NZBPO_PROCESSMETHOD"] = "Move"
os.environ["NZBPP_TOTALSTATUS"] = "FAILURE"
os.environ["NZBPP_NZBNAME"] = "Test.Show.S01E01"
server = http.server.HTTPServer((HOST, int(PORT)), HttpServerPostprocFailedMock)
thread = threading.Thread(target=server.serve_forever)
thread.start()
[out, code, _] = run_script()
server.shutdown()
server.server_close()
thread.join()
self.assertTrue("Download status indicates FAILURE" in out)
self.assertEqual(code, SUCCESS)

def test_postproc_failed_status(self):
set_default_env()
os.environ["NZBPO_PROCESSMETHOD"] = "Move"
os.environ["NZBPP_TOTALSTATUS"] = "SUCCESS"
os.environ["NZBPP_STATUS"] = "FAILURE/HEALTH"
os.environ["NZBPP_NZBNAME"] = "Test.Show.S01E01"
server = http.server.HTTPServer((HOST, int(PORT)), HttpServerPostprocFailedMock)
thread = threading.Thread(target=server.serve_forever)
thread.start()
[out, code, _] = run_script()
server.shutdown()
server.server_close()
thread.join()
self.assertTrue("Download status indicates FAILURE" in out)
self.assertEqual(code, SUCCESS)

def test_unsupported_method(self):
set_default_env()
os.environ["NZBPO_PROCESSMETHOD"] = "Unsupported method"
Expand Down
Loading