Skip to content

Commit

Permalink
init
Browse files Browse the repository at this point in the history
  • Loading branch information
phnzb committed Sep 24, 2024
0 parents commit 2be7d7d
Show file tree
Hide file tree
Showing 6 changed files with 233 additions and 0 deletions.
32 changes: 32 additions & 0 deletions .github/workflows/tasks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: extension tasks

on:
push:
branches:
- main
tags:
- "v*"

jobs:
prospector:
uses: nzbgetcom/nzbget-extensions/.github/workflows/prospector.yml@feature/workflows

manifest:
uses: nzbgetcom/nzbget-extensions/.github/workflows/manifest.yml@feature/workflows

tests:
uses: nzbgetcom/nzbget-extensions/.github/workflows/python-tests.yml@main
with:
python-versions: "3.6 3.7 3.8 3.9 3.10 3.11 3.12"
supported-python-versions: "3.8 3.9 3.10 3.11 3.12"
test-script: tests.py
debug: true

release:
if: startsWith(github.ref, 'refs/tags/v')
needs: [prospector, manifest, tests]
uses: nzbgetcom/nzbget-extensions/.github/workflows/extension-release.yml@main
with:
release-file-list: main.py manifest.json
release-file-name: example
release-dir: Example
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
__/*
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Example python extension for NZBGet

Simple post-process extension for NZBGet - can be used as starting point.

Extension creates in nzb download directory file _status.txt with download completion timestamp and values of extension options.
72 changes: 72 additions & 0 deletions main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#
# Example post-processing script for NZBGet
#
# Copyright (C) 2024 phnzb <[email protected]>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#

import os
import sys
from datetime import datetime

# Exit codes used by NZBGet
POSTPROCESS_SUCCESS = 93
POSTPROCESS_ERROR = 94
POSTPROCESS_NONE = 95


print("[DETAIL] Script successfully started")
sys.stdout.flush()

# Options passed to script as environment variables
# Check required options
required_options = (
"NZBPO_OPTIONSELECT",
"NZBPO_OPTIONSTRING",
"NZBPO_OPTIONNUMBER"
)
for optname in required_options:
if optname not in os.environ:
print(f"[ERROR] Option {optname[6:]} is missing in configuration file. Please check script settings")
sys.exit(POSTPROCESS_ERROR)

# Check if the script is executed from settings page with a custom command
command = os.environ.get("NZBCP_COMMAND")
test_mode = command == "Test"
if command is not None and not test_mode:
print("[ERROR] Invalid command " + command)
sys.exit(POSTPROCESS_ERROR)

OptionSelect = os.environ["NZBPO_OPTIONSELECT"]
OptionString = os.environ["NZBPO_OPTIONSTRING"]
OptionNumber = int(os.environ["NZBPO_OPTIONNUMBER"])

if test_mode:
print(f"[DETAIL] Script successfully invoked with params: OptionSelect: {OptionSelect}, OptionString: {OptionString}, OptionNumber: {OptionNumber}")
else:
if not os.path.exists(os.environ["NZBPP_DIRECTORY"]):
print("Destination directory doesn\'t exist, exiting")
sys.exit(POSTPROCESS_NONE)
with open(f"{os.environ['NZBPP_DIRECTORY']}/_status.txt", "w", encoding="utf-8") as status:
now = datetime.now()
status.writelines([
f"Completed at: {now}\n",
f"Options: OptionSelect: {OptionSelect}, OptionString: {OptionString}, OptionNumber: {OptionNumber}\n"
])
print("[INFO] Example extension successfully completed")

# All OK, returning exit status 'POSTPROCESS_SUCCESS' (int <93>) to let NZBGet know
# that our script has successfully completed.
sys.exit(POSTPROCESS_SUCCESS)
51 changes: 51 additions & 0 deletions manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
{
"main": "main.py",
"name": "Example",
"homepage": "https://github.com/nzbgetcom/Extension-Example",
"kind": "POST-PROCESSING",
"displayName": "Example",
"version": "1.0",
"author": "phnzb",
"license": "GNU",
"about": "Example NZBGet extension",
"queueEvents": "",
"requirements": [
"This script requires Python 3.8+ to be installed on your system."
],
"description": ["Simple NZBGet Python extension"],
"options": [
{
"name": "OptionSelect",
"displayName": "OptionSelect",
"value": "One",
"description": ["Option with select values"],
"select": ["One", "Two"]
},
{
"name": "OptionString",
"displayName": "OptionString",
"value": "String value",
"description": ["Option with string value"],
"select": []
},
{
"name": "OptionNumber",
"displayName": "OptionNumber",
"value": 0,
"description": [
"Option with number value",
"(range 0 .. 1000)"
],
"select": [0, 1000]
}
],
"commands": [
{
"name": "Test",
"action": "Test command",
"displayName": "Test",
"description": ["Command to test extension"]
}
],
"taskTime": ""
}
72 changes: 72 additions & 0 deletions tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#
# Example post-processing script for NZBGet
#
# Copyright (C) 2024 phnzb <[email protected]>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
import sys
import unittest
import shutil
import os
import subprocess
import pathlib
from os.path import dirname

ROOT_DIR = dirname(__file__)
TEST_DIR = f"{ROOT_DIR}/__"

POSTPROCESS_SUCCESS = 93
POSTPROCESS_ERROR = 94
POSTPROCESS_NONE = 95

def get_python():
if os.name == "nt":
return "python"
return "python3"

def set_defaults():
os.environ["NZBPO_OPTIONSELECT"] = "One"
os.environ["NZBPO_OPTIONSTRING"] = "String value"
os.environ["NZBPO_OPTIONNUMBER"] = "5"
os.environ["NZBPP_DIRECTORY"] = TEST_DIR
shutil.rmtree(TEST_DIR, True)
os.mkdir(TEST_DIR)

def run_script():
sys.stdout.flush()
proc = subprocess.Popen(
[get_python(), ROOT_DIR + "/main.py"],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
env=os.environ.copy(),
)
out, err = proc.communicate()
ret_code = proc.returncode
return (out.decode(), int(ret_code), err.decode())

class Tests(unittest.TestCase):
def test_status(self):
set_defaults()
[_, code, _] = run_script()
self.assertEqual(code, POSTPROCESS_SUCCESS)
status_path=f"{TEST_DIR}/_status.txt"
self.assertTrue(pathlib.Path(status_path).is_file())
with open(status_path) as status:
lines = [line.rstrip('\n') for line in status]
self.assertEqual(len(lines), 2)
self.assertEqual(lines[1], "Options: OptionSelect: One, OptionString: String value, OptionNumber: 5")

if __name__ == "__main__":
unittest.main()

0 comments on commit 2be7d7d

Please sign in to comment.