Skip to content

Commit a743f7c

Browse files
committed
Initial commit
0 parents  commit a743f7c

File tree

8 files changed

+423
-0
lines changed

8 files changed

+423
-0
lines changed

.editorconfig

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# http://editorconfig.org
2+
3+
root = true
4+
5+
[*]
6+
indent_style = space
7+
indent_size = 4
8+
trim_trailing_whitespace = true
9+
insert_final_newline = true
10+
charset = utf-8
11+
end_of_line = lf
12+
13+
[*.bat]
14+
indent_style = tab
15+
end_of_line = crlf
16+
17+
[LICENSE]
18+
insert_final_newline = false
19+
20+
[Makefile]
21+
indent_style = tab

.gitignore

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
# Byte-compiled / optimized / DLL files
2+
__pycache__/
3+
*.py[cod]
4+
*$py.class
5+
6+
# C extensions
7+
*.so
8+
9+
# Distribution / packaging
10+
.Python
11+
env/
12+
build/
13+
develop-eggs/
14+
dist/
15+
downloads/
16+
eggs/
17+
.eggs/
18+
lib/
19+
lib64/
20+
parts/
21+
sdist/
22+
var/
23+
wheels/
24+
*.egg-info/
25+
.installed.cfg
26+
*.egg
27+
28+
# PyInstaller
29+
# Usually these files are written by a python script from a template
30+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
31+
*.manifest
32+
*.spec
33+
34+
# Installer logs
35+
pip-log.txt
36+
pip-delete-this-directory.txt
37+
38+
# Unit test / coverage reports
39+
htmlcov/
40+
.tox/
41+
.coverage
42+
.coverage.*
43+
.cache
44+
nosetests.xml
45+
coverage.xml
46+
*.cover
47+
.hypothesis/
48+
.pytest_cache/
49+
50+
# Translations
51+
*.mo
52+
*.pot
53+
54+
# Django stuff:
55+
*.log
56+
local_settings.py
57+
58+
# Flask stuff:
59+
instance/
60+
.webassets-cache
61+
62+
# Scrapy stuff:
63+
.scrapy
64+
65+
# Sphinx documentation
66+
docs/_build/
67+
68+
# PyBuilder
69+
target/
70+
71+
# Jupyter Notebook
72+
.ipynb_checkpoints
73+
74+
# pyenv
75+
.python-version
76+
77+
# celery beat schedule file
78+
celerybeat-schedule
79+
80+
# SageMath parsed files
81+
*.sage.py
82+
83+
# dotenv
84+
.env
85+
86+
# virtualenv
87+
.venv
88+
venv/
89+
ENV/
90+
91+
# Spyder project settings
92+
.spyderproject
93+
.spyproject
94+
95+
# Rope project settings
96+
.ropeproject
97+
98+
# mkdocs documentation
99+
/site
100+
101+
# mypy
102+
.mypy_cache/
103+
104+
.vscode/launch.json

LICENSE

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
Apache Software License 2.0
2+
3+
Copyright (c) 2019, Chris Clark
4+
5+
Licensed under the Apache License, Version 2.0 (the "License");
6+
you may not use this file except in compliance with the License.
7+
You may obtain a copy of the License at
8+
9+
http://www.apache.org/licenses/LICENSE-2.0
10+
11+
Unless required by applicable law or agreed to in writing, software
12+
distributed under the License is distributed on an "AS IS" BASIS,
13+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
See the License for the specific language governing permissions and
15+
limitations under the License.
16+

README.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
pynzbgetapi
2+
=====
3+
A simple Python library for using the NZBGetAPI.
4+
5+
Installation
6+
------------
7+
You can get the code from `https://github.com/holiestofhandgrenades/pynzbgetapi`
8+
9+
Example
10+
-------
11+
import pynzbgetapi
12+
13+
ng_api = pynzbgetapi.NZBGetAPI("192.168.0.x", "username", "password")
14+
ng_api.status()
15+
16+
License
17+
-------
18+
This code is released under the Apache license.

pynzbgetapi/__init__.py

Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
"""Basic Python wrapper for the NZBGet API"""
2+
3+
__author__ = """Holiest of Hand Grenades"""
4+
5+
import json
6+
import logging
7+
import ssl
8+
from urllib.parse import quote
9+
import xmlrpc.client
10+
11+
_LOGGER = logging.getLogger(__name__)
12+
13+
14+
class NZBGetAPIException(Exception):
15+
"""Top level module exception."""
16+
pass
17+
18+
19+
class NZBGetAPI:
20+
"""Simple wrapper for NZBGet's API."""
21+
22+
def __init__(
23+
self,
24+
host,
25+
username=None,
26+
password=None,
27+
secure=False,
28+
verify_certificate=True,
29+
port=6789,
30+
):
31+
"""Initialize NZBGet API and set headers needed later."""
32+
33+
ssl = "s" if secure else ""
34+
35+
if username is not None and password is not None:
36+
url = (
37+
f"http{ssl}://{quote(username)}:{quote(password)}@{host}:{port}/xmlrpc"
38+
)
39+
else:
40+
url = f"http{ssl}://{host}:{port}/xmlrpc"
41+
42+
if secure and not verify_certificate:
43+
ssl_ctx = ssl.create_default_context()
44+
ssl_ctx.check_hostname = False
45+
ssl_ctx.verify_mode = ssl.CERT_NONE
46+
47+
self.proxy = xmlrpc.client.ServerProxy(url, context=ssl_ctx)
48+
else:
49+
self.proxy = xmlrpc.client.ServerProxy(url)
50+
51+
def __proxy_call(self, method_call):
52+
try:
53+
# Internal method to transalte xmlrpc exceptions to library ones.
54+
return method_call()
55+
except xmlrpc.client.Error as err:
56+
raise NZBGetAPIException(str(err)) from None
57+
58+
def version(self):
59+
"""Get Version"""
60+
return self.__proxy_call(lambda: self.proxy.version())
61+
62+
def shutdown(self):
63+
"""Shutdown NZBGet"""
64+
return self.__proxy_call(lambda: self.proxy.shutdown())
65+
66+
def reload(self):
67+
"""Reload NZBGet"""
68+
return self.__proxy_call(lambda: self.proxy.reload())
69+
70+
def listgroups(self, number_of_log_entries):
71+
"""Get current groups (NZB Files)"""
72+
return self.__proxy_call(lambda: self.proxy.listgroups(number_of_log_entries))
73+
74+
def listfiles(self, nzbid):
75+
"""Get file list from an nzbfile"""
76+
return self.__proxy_call(lambda: self.proxy.listfiles(0, 0, nzbid))
77+
78+
def history(self, hidden=False):
79+
"""Get History"""
80+
return self.__proxy_call(lambda: self.proxy.history(hidden))
81+
82+
def append(
83+
self,
84+
nzbfilename,
85+
nzbcontent,
86+
category,
87+
priority,
88+
add_to_top,
89+
add_paused,
90+
dupe_key,
91+
dupe_score,
92+
dupe_mode,
93+
pp_parameters,
94+
):
95+
"""Append an NZB to the queue."""
96+
return self.__proxy_call(
97+
lambda: self.proxy.append(
98+
nzbfilename,
99+
nzbcontent,
100+
category,
101+
priority,
102+
add_to_top,
103+
add_paused,
104+
dupe_key,
105+
dupe_score,
106+
dupe_mode,
107+
pp_parameters,
108+
)
109+
)
110+
111+
def editqueue(self, command, param, ids):
112+
"""Edit the queue."""
113+
return self.__proxy_call(lambda: self.proxy.editqueue(command, param, ids))
114+
115+
def scan(self):
116+
"""Scan the nzbdirectory."""
117+
return self.__proxy_call(lambda: self.proxy.scan())
118+
119+
def status(self):
120+
"""Get Status."""
121+
return self.__proxy_call(lambda: self.proxy.status())
122+
123+
def log(self, id_from, number_of_entries):
124+
"""Return the log."""
125+
return self.__proxy_call(lambda: self.proxy.log(id_from, number_of_entries))
126+
127+
def writelog(self, kind, text):
128+
"""Write a new log message."""
129+
return self.__proxy_call(lambda: self.proxy.writelog(kind, text))
130+
131+
def loadlog(self, nzbid, id_from, number_of_entries):
132+
"""Return nzbg-log for a specific nzb-file."""
133+
return self.__proxy_call(
134+
lambda: self.proxy.loadlog(nzbid, id_from, number_of_entries)
135+
)
136+
137+
def servervolumes(self):
138+
"""Collect newsserver historical transfer statistics."""
139+
return self.__proxy_call(lambda: self.proxy.servervolumes())
140+
141+
def resetservervolume(self, server_id, sounter):
142+
"""Reset newsserver historical transfer statistics."""
143+
return self.__proxy_call(
144+
lambda: self.proxy.resetservervolume(server_id, sounter)
145+
)
146+
147+
def rate(self, limit):
148+
"""Set transfer limit."""
149+
return self.__proxy_call(lambda: self.proxy.rate(limit))
150+
151+
def pausedownload(self):
152+
"""Pause download queue."""
153+
return self.__proxy_call(lambda: self.proxy.pausedownload())
154+
155+
def resumedownload(self):
156+
"""Resume downloads."""
157+
return self.__proxy_call(lambda: self.proxy.resumedownload())
158+
159+
def pausepost(self):
160+
"""Pause post-processing."""
161+
return self.__proxy_call(lambda: self.proxy.pausepost())
162+
163+
def resumescan(self):
164+
"""Resume previously paused scanning for new nzbfiles."""
165+
return self.__proxy_call(lambda: self.proxy.resumescan())
166+
167+
def scheduleresume(self, seconds):
168+
"""Schedule resume after expiring of wait interval."""
169+
return self.__proxy_call(lambda: self.proxy.scheduleresume(seconds))
170+
171+
def config(self):
172+
"""Get current config."""
173+
return self.__proxy_call(lambda: self.proxy.config())
174+
175+
def loadconfig(self):
176+
"""Read configuration file from disk."""
177+
return self.__proxy_call(lambda: self.proxy.loadconfig())
178+
179+
def saveconfig(self, options):
180+
"""Save configuration file to disk."""
181+
return self.__proxy_call(lambda: self.proxy.saveconfig(options))
182+
183+
def configtemplates(self, load_from_disk):
184+
"""Return configuration file template and configuration sections"""
185+
return self.__proxy_call(lambda: self.proxy.configtemplaes(load_from_disk))

setup.cfg

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
[bumpversion]
2+
current_version = 0.1.0
3+
commit = True
4+
tag = True
5+
6+
[bumpversion:file:setup.py]
7+
search = version='{current_version}'
8+
replace = version='{new_version}'
9+
10+
[bumpversion:file:pynzbgetapi/__init__.py]
11+
search = __version__ = '{current_version}'
12+
replace = __version__ = '{new_version}'
13+
14+
[bdist_wheel]
15+
universal = 1
16+
17+
[flake8]
18+
exclude = docs
19+
20+
[aliases]
21+
# Define setup.py command aliases here
22+

0 commit comments

Comments
 (0)