mirror of
https://github.com/sabnzbd/sabnzbd.git
synced 2026-01-06 06:28:45 -05:00
Compare commits
130 Commits
3.2.0Beta2
...
3.3.0Beta3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
43817aef20 | ||
|
|
81a7a58299 | ||
|
|
4ae1c21b6f | ||
|
|
8ffa3e5d4c | ||
|
|
ac6ebe1f99 | ||
|
|
a5c07e7873 | ||
|
|
94c4f6008d | ||
|
|
615c296023 | ||
|
|
d227611ee8 | ||
|
|
acf00c723f | ||
|
|
adb3913daa | ||
|
|
faf1a44944 | ||
|
|
9f5cb9ffff | ||
|
|
068c653a2a | ||
|
|
b1c922bb75 | ||
|
|
4879fbc6d4 | ||
|
|
e7dc81eb38 | ||
|
|
c2fa08598e | ||
|
|
d23ca4a38e | ||
|
|
078b608582 | ||
|
|
a64457973f | ||
|
|
00ef13fe9f | ||
|
|
b4a7f2fdf6 | ||
|
|
a482bb7acc | ||
|
|
ce46eeac49 | ||
|
|
110dbf6cca | ||
|
|
c93de2dd6f | ||
|
|
be88f5152f | ||
|
|
efda5bab4d | ||
|
|
d491eb1af0 | ||
|
|
e249dbfc67 | ||
|
|
c994ae5798 | ||
|
|
cba61bd8fb | ||
|
|
a72440ee6b | ||
|
|
cd3ed40ff3 | ||
|
|
cf3ce5e31d | ||
|
|
bdcbc5e011 | ||
|
|
c2d3ce348f | ||
|
|
970d580e4b | ||
|
|
d2f9721576 | ||
|
|
8a39e5827b | ||
|
|
89c8b6a0a5 | ||
|
|
238f0a6108 | ||
|
|
19950569cb | ||
|
|
a19553dddd | ||
|
|
c383a5b120 | ||
|
|
dab7243ccd | ||
|
|
ccf15ab4a3 | ||
|
|
25a3ef2b3e | ||
|
|
9bdaae8d9f | ||
|
|
4115651998 | ||
|
|
58349082df | ||
|
|
aa75828296 | ||
|
|
10eaf6e278 | ||
|
|
04e22571e9 | ||
|
|
bc8b9e7c8b | ||
|
|
b6213654ef | ||
|
|
9ba17d5338 | ||
|
|
dde453744d | ||
|
|
a86273f213 | ||
|
|
2b312dfa6f | ||
|
|
800c7182c1 | ||
|
|
cbbd5faf24 | ||
|
|
bb9c8f04e2 | ||
|
|
50469903dc | ||
|
|
b8f6cf11d6 | ||
|
|
f0d4f76e0f | ||
|
|
05f0a12d16 | ||
|
|
a1cad730ad | ||
|
|
3e8c738496 | ||
|
|
940dd3e3c0 | ||
|
|
6de4e1a401 | ||
|
|
0a8747f600 | ||
|
|
68a5e7c8f7 | ||
|
|
c3d4bf5428 | ||
|
|
0cac0bc761 | ||
|
|
05427b7b3b | ||
|
|
9e73f9b5e0 | ||
|
|
5ec41bafbe | ||
|
|
cb67cc8c3d | ||
|
|
d35619805f | ||
|
|
cb26758d53 | ||
|
|
9783674890 | ||
|
|
270eeda3e2 | ||
|
|
24d3d064bb | ||
|
|
e8eec80696 | ||
|
|
c366504868 | ||
|
|
c7b54856c5 | ||
|
|
10c56e08d4 | ||
|
|
4af51b4a76 | ||
|
|
65cc03da14 | ||
|
|
e908cb0df5 | ||
|
|
ae2cee3fda | ||
|
|
0467ed7ffc | ||
|
|
d5453b4aa4 | ||
|
|
7096a785db | ||
|
|
c80db13c28 | ||
|
|
b971045cd2 | ||
|
|
61d4ccbf1b | ||
|
|
c3b237466c | ||
|
|
29c727319d | ||
|
|
52c5dc589d | ||
|
|
35cad9bf22 | ||
|
|
b108876017 | ||
|
|
52bfff953a | ||
|
|
65278c4489 | ||
|
|
3a4a925ab0 | ||
|
|
6ef5d41c25 | ||
|
|
b9b9f46fbe | ||
|
|
8d014e579d | ||
|
|
f2fc9f10f9 | ||
|
|
f131155fd8 | ||
|
|
691e24a1d8 | ||
|
|
794a6f4454 | ||
|
|
41bf8525cf | ||
|
|
6ebf486c09 | ||
|
|
899ae94fcf | ||
|
|
d3cd5019d9 | ||
|
|
1e4719558f | ||
|
|
29ab83b9c0 | ||
|
|
4b4d170ce1 | ||
|
|
8b0a12e0ba | ||
|
|
430318ead7 | ||
|
|
32f6ec63f2 | ||
|
|
a3181c8f76 | ||
|
|
412d169f58 | ||
|
|
d1c2e6e0dd | ||
|
|
4f9ac56de0 | ||
|
|
9641dc82f9 | ||
|
|
e68413b73c |
1
.github/workflows/black.yml
vendored
1
.github/workflows/black.yml
vendored
@@ -19,3 +19,4 @@ jobs:
|
||||
--line-length=120
|
||||
--target-version=py36
|
||||
--check
|
||||
--diff
|
||||
|
||||
54
.github/workflows/build_release.yml
vendored
54
.github/workflows/build_release.yml
vendored
@@ -6,6 +6,8 @@ jobs:
|
||||
build_windows:
|
||||
name: Build Windows binary
|
||||
runs-on: windows-latest
|
||||
env:
|
||||
AUTOMATION_GITHUB_TOKEN: ${{ secrets.AUTOMATION_GITHUB_TOKEN }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up Python 3.9 (64bit)
|
||||
@@ -38,28 +40,27 @@ jobs:
|
||||
with:
|
||||
path: "*-win-setup.exe"
|
||||
name: Windows installer
|
||||
- name: Set up Python 3.9 (32bit)
|
||||
- name: Set up Python 3.8 (32bit and legacy)
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: 3.9
|
||||
python-version: 3.8
|
||||
architecture: x86
|
||||
- name: Install Python dependencies (32bit)
|
||||
- name: Install Python dependencies (32bit and legacy)
|
||||
run: |
|
||||
python --version
|
||||
pip install --upgrade pip wheel
|
||||
pip install --upgrade -r requirements.txt
|
||||
pip install --upgrade -r builder/requirements.txt
|
||||
- name: Build Windows standalone binary (32bit)
|
||||
- name: Build Windows standalone binary (32bit and legacy)
|
||||
run: python builder/package.py binary
|
||||
- name: Upload Windows standalone binary (32bit)
|
||||
- name: Upload Windows standalone binary (32bit and legacy)
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
path: "*-win32-bin.zip"
|
||||
name: Windows Windows standalone binary (32bit)
|
||||
name: Windows Windows standalone binary (32bit and legacy)
|
||||
- name: Prepare official release
|
||||
if: env.AUTOMATION_GITHUB_TOKEN && !startsWith(github.ref, 'refs/tags/')
|
||||
run: python builder/package.py release
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.AUTOMATION_GITHUB_TOKEN }}
|
||||
|
||||
build_macos:
|
||||
name: Build macOS binary
|
||||
@@ -68,18 +69,31 @@ jobs:
|
||||
SIGNING_AUTH: ${{ secrets.SIGNING_AUTH }}
|
||||
NOTARIZATION_USER: ${{ secrets.NOTARIZATION_USER }}
|
||||
NOTARIZATION_PASS: ${{ secrets.NOTARIZATION_PASS }}
|
||||
AUTOMATION_GITHUB_TOKEN: ${{ secrets.AUTOMATION_GITHUB_TOKEN }}
|
||||
# We need the official Python, because the GA ones only support newer macOS versions
|
||||
# The deployment target is picked up by the Python build tools automatically
|
||||
# If updated, make sure to also set LSMinimumSystemVersion in SABnzbd.spec
|
||||
PYTHON_VERSION: 3.9.4
|
||||
MACOSX_DEPLOYMENT_TARGET: 10.9
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up Python 3.9
|
||||
uses: actions/setup-python@v2
|
||||
- name: Cache Python download
|
||||
id: cache-python-download
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
python-version: 3.9
|
||||
path: ~/python.pkg
|
||||
key: macOS-Python-${{ env.PYTHON_VERSION }}
|
||||
- name: Get Python
|
||||
if: steps.cache-python-download.outputs.cache-hit != 'true'
|
||||
run: curl https://www.python.org/ftp/python/${PYTHON_VERSION}/python-${PYTHON_VERSION}-macosx10.9.pkg -o ~/python.pkg
|
||||
- name: Install Python
|
||||
run: sudo installer -pkg ~/python.pkg -target /
|
||||
- name: Install Python dependencies
|
||||
run: |
|
||||
python --version
|
||||
pip install --upgrade pip wheel
|
||||
pip install --upgrade -r requirements.txt
|
||||
pip install --upgrade -r builder/requirements.txt
|
||||
python3 --version
|
||||
pip3 install --upgrade pip wheel
|
||||
pip3 install --upgrade -r requirements.txt
|
||||
pip3 install --upgrade -r builder/requirements.txt
|
||||
- name: Import macOS codesign certificates
|
||||
uses: apple-actions/import-codesign-certs@v1
|
||||
if: env.SIGNING_AUTH
|
||||
@@ -88,15 +102,13 @@ jobs:
|
||||
p12-password: ${{ secrets.CERTIFICATES_P12_PASSWORD }}
|
||||
- name: Build macOS binary
|
||||
run: |
|
||||
python builder/package.py app
|
||||
python builder/make_dmg.py
|
||||
python3 builder/package.py app
|
||||
python3 builder/make_dmg.py
|
||||
- name: Upload macOS binary
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
path: "*-osx.dmg"
|
||||
name: macOS binary (not notarized)
|
||||
- name: Prepare official release
|
||||
run: python builder/package.py release
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.AUTOMATION_GITHUB_TOKEN }}
|
||||
|
||||
if: env.AUTOMATION_GITHUB_TOKEN && !startsWith(github.ref, 'refs/tags/')
|
||||
run: python3 builder/package.py release
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -31,6 +31,9 @@ SABnzbd-*/
|
||||
*.wp[ru]
|
||||
.idea
|
||||
|
||||
# VScode
|
||||
.vscode/
|
||||
|
||||
# Testing folders
|
||||
.cache
|
||||
.xprocess
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
SABnzbd 3.2.0
|
||||
SABnzbd 3.3.0
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
0) LICENSE
|
||||
|
||||
@@ -14,13 +14,13 @@
|
||||
For these the server blocking method is not very favourable.
|
||||
There is an INI-only option that will limit blocks to 1 minute.
|
||||
no_penalties = 1
|
||||
See: https://sabnzbd.org/wiki/configuration/3.2/special
|
||||
See: https://sabnzbd.org/wiki/configuration/3.3/special
|
||||
|
||||
- Some third-party utilties try to probe SABnzbd API in such a way that you will
|
||||
often see warnings about unauthenticated access.
|
||||
If you are sure these probes are harmless, you can suppress the warnings by
|
||||
setting the option "api_warnings" to 0.
|
||||
See: https://sabnzbd.org/wiki/configuration/3.2/special
|
||||
See: https://sabnzbd.org/wiki/configuration/3.3/special
|
||||
|
||||
- On macOS you may encounter downloaded files with foreign characters.
|
||||
The par2 repair may fail when the files were created on a Windows system.
|
||||
|
||||
4
PKG-INFO
4
PKG-INFO
@@ -1,7 +1,7 @@
|
||||
Metadata-Version: 1.0
|
||||
Name: SABnzbd
|
||||
Version: 3.2.0Beta2
|
||||
Summary: SABnzbd-3.2.0Beta2
|
||||
Version: 3.3.0Beta3
|
||||
Summary: SABnzbd-3.3.0Beta3
|
||||
Home-page: https://sabnzbd.org
|
||||
Author: The SABnzbd Team
|
||||
Author-email: team@sabnzbd.org
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
SABnzbd - The automated Usenet download tool
|
||||
============================================
|
||||
|
||||
[](https://travis-ci.org/sabnzbd/sabnzbd)
|
||||
[](https://ci.appveyor.com/project/Safihre/sabnzbd)
|
||||
[](https://snapcraft.io/sabnzbd)
|
||||

|
||||

|
||||
[](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html)
|
||||
|
||||
|
||||
SABnzbd is an Open Source Binary Newsreader written in Python.
|
||||
|
||||
It's totally free, easy to use, and works practically everywhere.
|
||||
|
||||
82
README.mkd
82
README.mkd
@@ -1,59 +1,39 @@
|
||||
Release Notes - SABnzbd 3.2.0 Beta 2
|
||||
Release Notes - SABnzbd 3.3.0 Beta 3
|
||||
=========================================================
|
||||
|
||||
Changes since 3.2.0 Beta 1 were added below.
|
||||
## Changes and bugfixes since 3.3.0 Beta 2
|
||||
- Failing articles could result in jobs being stuck at 99%.
|
||||
- Some NZB files would incorrectly be marked as empty.
|
||||
- CRC/yEnc errors would be counted twice as bad articles.
|
||||
- API-call `history` would not filter active post-processing `nzo_ids`.
|
||||
- RSS `Read All Feeds` button would result in a crash.
|
||||
- Support prefix and netmask for `local_ranges`.
|
||||
- Windows: `Deobfuscate final filenames` could fail to deobfuscate.
|
||||
|
||||
## Changes since 3.1.1
|
||||
- Python 3.6 is the minimum required version.
|
||||
- macOS release is currently restricted to macOS 10.14 (Mojave) and above
|
||||
due to changes in our build platform. We are still trying to resolve this.
|
||||
- Post-processing can be aborted at any stage, including scripts.
|
||||
- Improvements in the downloader to reduce CPU-load.
|
||||
- Custom date ranges for server graphs can be selected.
|
||||
- Keep track of article fetching success-rate of each server.
|
||||
- Added option to add download quota warning for each server.
|
||||
- Added option to add expiration waring for each server.
|
||||
- Added `Minimum Free Space for Completed Download Folder` option.
|
||||
- Added option to `Auto resume` for both `Minimum Free Space` settings.
|
||||
- Multiple additional Queue and History columns can be added.
|
||||
- Added option to always use full screen width.
|
||||
- Additional interface settings can be stored server-side.
|
||||
- Using SSDP, SABnzbd instances are now listed in `Network` on Windows.
|
||||
- Improvements to parsing of job name and filenames listed in the NZB.
|
||||
- RSS titles can be edited.
|
||||
- Sanitize all filenames to a maximum of 245 characters.
|
||||
- Show commit hash when running from `git` sources.
|
||||
- Notify through Notifications if new version is available.
|
||||
- Program shutdown time reduced to almost instant.
|
||||
- Added `10 GB` test download.
|
||||
- IPv6 is no longer preferred in HappyEyeballs address selection.
|
||||
- API-calls `queue` and `history` can now be filtered by `nzo_id`.
|
||||
- Inreased garbage collection rate to reduce memory usage.
|
||||
- Windows: `Temporary Download` job folders no longer have a maximum length.
|
||||
- Windows/macOS: Update UnRar to 6.0.0 and MultiPar to 1.3.1.3.
|
||||
## Changes and bugfixes since 3.3.0 Beta 1
|
||||
- Binaries would show an error when starting.
|
||||
|
||||
## Changes since 3.2.1
|
||||
- The `External internet access` will automatically detect local network
|
||||
and no longer requires the ranges to be defined. Custom ranges can still
|
||||
be defined through `local_ranges` in Special settings.
|
||||
- The `Unwanted extensions` detection can be set to `Whitelist`-mode.
|
||||
This will block or pause all jobs with non-matching extensions.
|
||||
- Servers article statistics are shown in K, G, M-notation.
|
||||
- Resolution added as a pattern key (`%r`) for Sorting.
|
||||
- Revised handling of categories, scripts, and priorities when adding NZB's.
|
||||
- Download statistics are also shown when no History is shown.
|
||||
- Confirm rename if Direct Unpack is active for the job.
|
||||
- Obfuscated-RAR detection will always be performed.
|
||||
- All requests will be logged, not just API calls.
|
||||
|
||||
## Bugfixes since 3.1.1
|
||||
- Memory could leak after jobs were removed from the queue.
|
||||
- The active browser URL is used during the wizard.
|
||||
- Repairing or Retrying jobs could result in a crash.
|
||||
- API-call `reset_quota` returned nothing.
|
||||
- New categories were not always forced to lowercase.
|
||||
- Broken downloads could result in crash during RAR-renaming
|
||||
- Improved obfuscation detection for `Deobfuscate final filenames`.
|
||||
- Keep original priority of duplicate jobs.
|
||||
- Increase Maximum number of connections per server to `1000`.
|
||||
- Update encryption check to handle partially assembled files.
|
||||
- Don't activate Windows notifications when running as service.
|
||||
- Crash in API-call to delete history items for non-existing `nzo_id`.
|
||||
- Prevent repetition of unwanted extension warnings.
|
||||
- Correct notification category for failed URL fetches.
|
||||
- Improvements to the `Add NZB` modal window.
|
||||
- Sort script drop-down list alphabetically.
|
||||
- Direct Unpack stability fixes.
|
||||
- macOS: Program shutdown could fail.
|
||||
- macOS: Tray text was misaligned on macOS 11 (Big Sur).
|
||||
- Windows: Improved handling of some MultiPar output.
|
||||
- Windows: Program restart failed.
|
||||
- Prevent failed post-processing if job name ends in multiple dots or spaces.
|
||||
- Jobs could be stuck in the queue or duplicate if they had missing articles.
|
||||
- Login page could be accessed even if `External internet access` was set
|
||||
to `No access`. All other access would still be blocked.
|
||||
- Ignore duplicate files inside messy NZB's.
|
||||
- macOS: disk space would be incorrect for very large disks.
|
||||
|
||||
## Upgrade notices
|
||||
- The download statistics file `totals10.sab` is updated in this
|
||||
|
||||
135
SABnzbd.py
135
SABnzbd.py
@@ -19,7 +19,7 @@ import sys
|
||||
|
||||
if sys.hexversion < 0x03060000:
|
||||
print("Sorry, requires Python 3.6 or above")
|
||||
print("You can read more at: https://sabnzbd.org/python3")
|
||||
print("You can read more at: https://sabnzbd.org/wiki/installation/install-off-modules")
|
||||
sys.exit(1)
|
||||
|
||||
import logging
|
||||
@@ -48,7 +48,7 @@ try:
|
||||
except ImportError as e:
|
||||
print("Not all required Python modules are available, please check requirements.txt")
|
||||
print("Missing module:", e.name)
|
||||
print("You can read more at: https://sabnzbd.org/python3")
|
||||
print("You can read more at: https://sabnzbd.org/wiki/installation/install-off-modules")
|
||||
print("If you still experience problems, remove all .pyc files in this folder and subfolders")
|
||||
sys.exit(1)
|
||||
|
||||
@@ -68,7 +68,8 @@ from sabnzbd.misc import (
|
||||
get_serv_parms,
|
||||
get_from_url,
|
||||
upload_file_to_sabnzbd,
|
||||
probablyipv4,
|
||||
is_localhost,
|
||||
is_lan_addr,
|
||||
)
|
||||
from sabnzbd.filesystem import get_ext, real_path, long_path, globber_full, remove_file
|
||||
from sabnzbd.panic import panic_tmpl, panic_port, panic_host, panic, launch_a_browser
|
||||
@@ -101,13 +102,13 @@ LOG_FLAG = False
|
||||
|
||||
|
||||
def guard_loglevel():
|
||||
""" Callback function for guarding loglevel """
|
||||
"""Callback function for guarding loglevel"""
|
||||
global LOG_FLAG
|
||||
LOG_FLAG = True
|
||||
|
||||
|
||||
def warning_helpful(*args, **kwargs):
|
||||
""" Wrapper to ignore helpfull warnings if desired """
|
||||
"""Wrapper to ignore helpfull warnings if desired"""
|
||||
if sabnzbd.cfg.helpfull_warnings():
|
||||
return logging.warning(*args, **kwargs)
|
||||
return logging.info(*args, **kwargs)
|
||||
@@ -122,29 +123,42 @@ class GUIHandler(logging.Handler):
|
||||
"""
|
||||
|
||||
def __init__(self, size):
|
||||
""" Initializes the handler """
|
||||
"""Initializes the handler"""
|
||||
logging.Handler.__init__(self)
|
||||
self._size: int = size
|
||||
self.store: List[Dict[str, Any]] = []
|
||||
|
||||
def emit(self, record: logging.LogRecord):
|
||||
""" Emit a record by adding it to our private queue """
|
||||
"""Emit a record by adding it to our private queue"""
|
||||
# If % is part of the msg, this could fail
|
||||
try:
|
||||
parsed_msg = record.msg % record.args
|
||||
except TypeError:
|
||||
parsed_msg = record.msg + str(record.args)
|
||||
|
||||
if record.levelno == logging.WARNING:
|
||||
sabnzbd.notifier.send_notification(T("Warning"), parsed_msg, "warning")
|
||||
else:
|
||||
sabnzbd.notifier.send_notification(T("Error"), parsed_msg, "error")
|
||||
warning = {
|
||||
"type": record.levelname,
|
||||
"text": parsed_msg,
|
||||
"time": int(time.time()),
|
||||
"origin": "%s%d" % (record.filename, record.lineno),
|
||||
}
|
||||
|
||||
# Append traceback, if available
|
||||
warning = {"type": record.levelname, "text": parsed_msg, "time": int(time.time())}
|
||||
if record.exc_info:
|
||||
warning["text"] = "%s\n%s" % (warning["text"], traceback.format_exc())
|
||||
|
||||
# Do not notify the same notification within 1 minute from the same source
|
||||
# This prevents endless looping if the notification service itself throws an error/warning
|
||||
# We don't check based on message content, because if it includes a timestamp it's not unique
|
||||
if not any(
|
||||
stored_warning["origin"] == warning["origin"] and stored_warning["time"] + DEF_TIMEOUT > time.time()
|
||||
for stored_warning in self.store
|
||||
):
|
||||
if record.levelno == logging.WARNING:
|
||||
sabnzbd.notifier.send_notification(T("Warning"), parsed_msg, "warning")
|
||||
else:
|
||||
sabnzbd.notifier.send_notification(T("Error"), parsed_msg, "error")
|
||||
|
||||
# Loose the oldest record
|
||||
if len(self.store) >= self._size:
|
||||
self.store.pop(0)
|
||||
@@ -157,7 +171,7 @@ class GUIHandler(logging.Handler):
|
||||
return len(self.store)
|
||||
|
||||
def content(self):
|
||||
""" Return an array with last records """
|
||||
"""Return an array with last records"""
|
||||
return self.store
|
||||
|
||||
|
||||
@@ -195,6 +209,7 @@ def print_help():
|
||||
print(" --no-login Start with username and password reset")
|
||||
print(" --log-all Log all article handling (for developers)")
|
||||
print(" --disable-file-log Logging is only written to console")
|
||||
print(" --console Force logging to console")
|
||||
print(" --new Run a new instance of SABnzbd")
|
||||
print()
|
||||
print("NZB (or related) file:")
|
||||
@@ -221,7 +236,7 @@ GNU GENERAL PUBLIC LICENSE Version 2 or (at your option) any later version.
|
||||
|
||||
|
||||
def daemonize():
|
||||
""" Daemonize the process, based on various StackOverflow answers """
|
||||
"""Daemonize the process, based on various StackOverflow answers"""
|
||||
try:
|
||||
pid = os.fork()
|
||||
if pid > 0:
|
||||
@@ -263,7 +278,7 @@ def daemonize():
|
||||
|
||||
|
||||
def abort_and_show_error(browserhost, cherryport, err=""):
|
||||
""" Abort program because of CherryPy troubles """
|
||||
"""Abort program because of CherryPy troubles"""
|
||||
logging.error(T("Failed to start web-interface") + " : " + str(err))
|
||||
if not sabnzbd.DAEMON:
|
||||
if "49" in err:
|
||||
@@ -275,7 +290,7 @@ def abort_and_show_error(browserhost, cherryport, err=""):
|
||||
|
||||
|
||||
def identify_web_template(key, defweb, wdir):
|
||||
""" Determine a correct web template set, return full template path """
|
||||
"""Determine a correct web template set, return full template path"""
|
||||
if wdir is None:
|
||||
try:
|
||||
wdir = fix_webname(key())
|
||||
@@ -306,7 +321,7 @@ def identify_web_template(key, defweb, wdir):
|
||||
|
||||
|
||||
def check_template_scheme(color, web_dir):
|
||||
""" Check existence of color-scheme """
|
||||
"""Check existence of color-scheme"""
|
||||
if color and os.path.exists(os.path.join(web_dir, "static", "stylesheets", "colorschemes", color + ".css")):
|
||||
return color
|
||||
elif color and os.path.exists(os.path.join(web_dir, "static", "stylesheets", "colorschemes", color)):
|
||||
@@ -333,7 +348,7 @@ def fix_webname(name):
|
||||
|
||||
|
||||
def get_user_profile_paths(vista_plus):
|
||||
""" Get the default data locations on Windows"""
|
||||
"""Get the default data locations on Windows"""
|
||||
if sabnzbd.DAEMON:
|
||||
# In daemon mode, do not try to access the user profile
|
||||
# just assume that everything defaults to the program dir
|
||||
@@ -392,7 +407,7 @@ def get_user_profile_paths(vista_plus):
|
||||
|
||||
|
||||
def print_modules():
|
||||
""" Log all detected optional or external modules """
|
||||
"""Log all detected optional or external modules"""
|
||||
if sabnzbd.decoder.SABYENC_ENABLED:
|
||||
# Yes, we have SABYenc, and it's the correct version, so it's enabled
|
||||
logging.info("SABYenc module (v%s)... found!", sabnzbd.decoder.SABYENC_VERSION)
|
||||
@@ -469,7 +484,7 @@ def print_modules():
|
||||
|
||||
|
||||
def all_localhosts():
|
||||
""" Return all unique values of localhost in order of preference """
|
||||
"""Return all unique values of localhost in order of preference"""
|
||||
ips = ["127.0.0.1"]
|
||||
try:
|
||||
# Check whether IPv6 is available and enabled
|
||||
@@ -497,7 +512,7 @@ def all_localhosts():
|
||||
|
||||
|
||||
def check_resolve(host):
|
||||
""" Return True if 'host' resolves """
|
||||
"""Return True if 'host' resolves"""
|
||||
try:
|
||||
socket.getaddrinfo(host, None)
|
||||
except socket.error:
|
||||
@@ -532,7 +547,7 @@ def get_webhost(cherryhost, cherryport, https_port):
|
||||
# Valid user defined name?
|
||||
info = socket.getaddrinfo(cherryhost, None)
|
||||
except socket.error:
|
||||
if cherryhost not in LOCALHOSTS:
|
||||
if not is_localhost(cherryhost):
|
||||
cherryhost = "0.0.0.0"
|
||||
try:
|
||||
info = socket.getaddrinfo(localhost, None)
|
||||
@@ -599,7 +614,7 @@ def get_webhost(cherryhost, cherryport, https_port):
|
||||
except socket.error:
|
||||
cherryhost = cherryhost.strip("[]")
|
||||
|
||||
if ipv6 and ipv4 and browserhost not in LOCALHOSTS:
|
||||
if ipv6 and ipv4 and not is_localhost(browserhost):
|
||||
sabnzbd.AMBI_LOCALHOST = True
|
||||
logging.info("IPV6 has priority on this system, potential Firefox issue")
|
||||
|
||||
@@ -640,7 +655,7 @@ def get_webhost(cherryhost, cherryport, https_port):
|
||||
|
||||
|
||||
def attach_server(host, port, cert=None, key=None, chain=None):
|
||||
""" Define and attach server, optionally HTTPS """
|
||||
"""Define and attach server, optionally HTTPS"""
|
||||
if sabnzbd.cfg.ipv6_hosting() or "::1" not in host:
|
||||
http_server = cherrypy._cpserver.Server()
|
||||
http_server.bind_addr = (host, port)
|
||||
@@ -653,7 +668,7 @@ def attach_server(host, port, cert=None, key=None, chain=None):
|
||||
|
||||
|
||||
def is_sabnzbd_running(url):
|
||||
""" Return True when there's already a SABnzbd instance running. """
|
||||
"""Return True when there's already a SABnzbd instance running."""
|
||||
try:
|
||||
url = "%s&mode=version" % url
|
||||
# Do this without certificate verification, few installations will have that
|
||||
@@ -666,7 +681,7 @@ def is_sabnzbd_running(url):
|
||||
|
||||
|
||||
def find_free_port(host, currentport):
|
||||
""" Return a free port, 0 when nothing is free """
|
||||
"""Return a free port, 0 when nothing is free"""
|
||||
n = 0
|
||||
while n < 10 and currentport <= 49151:
|
||||
try:
|
||||
@@ -820,7 +835,7 @@ def commandline_handler():
|
||||
|
||||
|
||||
def get_f_option(opts):
|
||||
""" Return value of the -f option """
|
||||
"""Return value of the -f option"""
|
||||
for opt, arg in opts:
|
||||
if opt == "-f":
|
||||
return arg
|
||||
@@ -845,6 +860,7 @@ def main():
|
||||
cherrypylogging = None
|
||||
clean_up = False
|
||||
logging_level = None
|
||||
console_logging = False
|
||||
no_file_log = False
|
||||
web_dir = None
|
||||
vista_plus = False
|
||||
@@ -900,6 +916,8 @@ def main():
|
||||
if logging_level < -1 or logging_level > 2:
|
||||
print_help()
|
||||
exit_sab(1)
|
||||
elif opt == "--console":
|
||||
console_logging = True
|
||||
elif opt in ("-v", "--version"):
|
||||
print_version()
|
||||
exit_sab(0)
|
||||
@@ -941,8 +959,8 @@ def main():
|
||||
sabnzbd.DIR_LANGUAGE = real_path(sabnzbd.DIR_PROG, DEF_LANGUAGE)
|
||||
org_dir = os.getcwd()
|
||||
|
||||
# Need console logging for SABnzbd.py and SABnzbd-console.exe
|
||||
console_logging = (not hasattr(sys, "frozen")) or (sabnzbd.MY_NAME.lower().find("-console") > 0)
|
||||
# Need console logging if requested, for SABnzbd.py and SABnzbd-console.exe
|
||||
console_logging = console_logging or sabnzbd.MY_NAME.lower().find("-console") > 0 or not hasattr(sys, "frozen")
|
||||
console_logging = console_logging and not sabnzbd.DAEMON
|
||||
|
||||
LOGLEVELS = (logging.FATAL, logging.WARNING, logging.INFO, logging.DEBUG)
|
||||
@@ -1485,34 +1503,37 @@ def main():
|
||||
check_latest_version()
|
||||
autorestarted = False
|
||||
|
||||
# bonjour/zeroconf needs an ip. Lets try to find it.
|
||||
external_host = localipv4() # IPv4 address of the LAN interface. This is the normal use case
|
||||
if not external_host:
|
||||
# None, so no network / default route, so let's set to ...
|
||||
external_host = "127.0.0.1"
|
||||
elif probablyipv4(cherryhost) and cherryhost not in LOCALHOSTS + ("0.0.0.0", "::"):
|
||||
# a hard-configured cherryhost other than the usual, so let's take that (good or wrong)
|
||||
external_host = cherryhost
|
||||
logging.debug("bonjour/zeroconf/SSDP using host: %s", external_host)
|
||||
sabnzbd.zconfig.set_bonjour(external_host, cherryport)
|
||||
|
||||
# Start SSDP if SABnzbd is running exposed
|
||||
if cherryhost not in LOCALHOSTS:
|
||||
# Set URL for browser for external hosts
|
||||
if enable_https:
|
||||
ssdp_url = "https://%s:%s%s" % (external_host, cherryport, sabnzbd.cfg.url_base())
|
||||
# Start SSDP and Bonjour if SABnzbd isn't listening on localhost only
|
||||
if sabnzbd.cfg.enable_broadcast() and not is_localhost(cherryhost):
|
||||
# Try to find a LAN IP address for SSDP/Bonjour
|
||||
if is_lan_addr(cherryhost):
|
||||
# A specific listening address was configured, use that
|
||||
external_host = cherryhost
|
||||
else:
|
||||
ssdp_url = "http://%s:%s%s" % (external_host, cherryport, sabnzbd.cfg.url_base())
|
||||
ssdp.start_ssdp(
|
||||
external_host,
|
||||
"SABnzbd",
|
||||
ssdp_url,
|
||||
"SABnzbd %s" % sabnzbd.__version__,
|
||||
"SABnzbd Team",
|
||||
"https://sabnzbd.org/",
|
||||
"SABnzbd %s" % sabnzbd.__version__,
|
||||
ssdp_broadcast_interval=sabnzbd.cfg.ssdp_broadcast_interval(),
|
||||
)
|
||||
# Fall back to the IPv4 address of the LAN interface
|
||||
external_host = localipv4()
|
||||
logging.debug("Using %s as host address for Bonjour and SSDP", external_host)
|
||||
|
||||
if is_lan_addr(external_host):
|
||||
sabnzbd.zconfig.set_bonjour(external_host, cherryport)
|
||||
|
||||
# Set URL for browser for external hosts
|
||||
ssdp_url = "%s://%s:%s%s" % (
|
||||
("https" if enable_https else "http"),
|
||||
external_host,
|
||||
cherryport,
|
||||
sabnzbd.cfg.url_base(),
|
||||
)
|
||||
ssdp.start_ssdp(
|
||||
external_host,
|
||||
"SABnzbd",
|
||||
ssdp_url,
|
||||
"SABnzbd %s" % sabnzbd.__version__,
|
||||
"SABnzbd Team",
|
||||
"https://sabnzbd.org/",
|
||||
"SABnzbd %s" % sabnzbd.__version__,
|
||||
ssdp_broadcast_interval=sabnzbd.cfg.ssdp_broadcast_interval(),
|
||||
)
|
||||
|
||||
# Have to keep this running, otherwise logging will terminate
|
||||
timer = 0
|
||||
@@ -1614,7 +1635,7 @@ if sabnzbd.WIN32:
|
||||
import servicemanager
|
||||
|
||||
class SABnzbd(win32serviceutil.ServiceFramework):
|
||||
""" Win32 Service Handler """
|
||||
"""Win32 Service Handler"""
|
||||
|
||||
_svc_name_ = "SABnzbd"
|
||||
_svc_display_name_ = "SABnzbd Binary Newsreader"
|
||||
|
||||
@@ -71,14 +71,14 @@ def safe_remove(path):
|
||||
|
||||
|
||||
def delete_files_glob(name):
|
||||
""" Delete one file or set of files from wild-card spec """
|
||||
"""Delete one file or set of files from wild-card spec"""
|
||||
for f in glob.glob(name):
|
||||
if os.path.exists(f):
|
||||
os.remove(f)
|
||||
|
||||
|
||||
def run_external_command(command):
|
||||
""" Wrapper to ease the use of calling external programs """
|
||||
"""Wrapper to ease the use of calling external programs"""
|
||||
process = subprocess.Popen(command, text=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
output, _ = process.communicate()
|
||||
ret = process.wait()
|
||||
@@ -90,7 +90,7 @@ def run_external_command(command):
|
||||
|
||||
|
||||
def run_git_command(parms):
|
||||
""" Run git command, raise error if it failed """
|
||||
"""Run git command, raise error if it failed"""
|
||||
return run_external_command(["git"] + parms)
|
||||
|
||||
|
||||
@@ -408,7 +408,7 @@ if __name__ == "__main__":
|
||||
# Release to github
|
||||
if "release" in sys.argv:
|
||||
# Check if tagged as release and check for token
|
||||
gh_token = os.environ.get("GITHUB_TOKEN", "")
|
||||
gh_token = os.environ.get("AUTOMATION_GITHUB_TOKEN", "")
|
||||
if RELEASE_THIS and gh_token:
|
||||
gh_obj = github.Github(gh_token)
|
||||
gh_repo = gh_obj.get_repo("sabnzbd/sabnzbd")
|
||||
@@ -543,7 +543,7 @@ if __name__ == "__main__":
|
||||
)
|
||||
else:
|
||||
print("To push release to GitHub, add 'draft release' to the commit message.")
|
||||
print("Or missing the GITHUB_TOKEN, cannot push to GitHub without it.")
|
||||
print("Or missing the AUTOMATION_GITHUB_TOKEN, cannot push to GitHub without it.")
|
||||
|
||||
# Reset!
|
||||
run_git_command(["reset", "--hard"])
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Basic build requirements
|
||||
pyinstaller
|
||||
pyinstaller==4.2
|
||||
setuptools
|
||||
pkginfo
|
||||
certifi
|
||||
|
||||
@@ -237,6 +237,13 @@ Function .onInit
|
||||
Abort
|
||||
${EndIf}
|
||||
|
||||
; Python 3.9 no longer supports Windows 7
|
||||
${If} ${AtMostWin8}
|
||||
MessageBox MB_OK $(MsgNoWin7)
|
||||
ExecShell "open" "https://sabnzbd.org/downloads"
|
||||
Abort
|
||||
${EndIf}
|
||||
|
||||
;------------------------------------------------------------------
|
||||
; Change settings based on if SAB was already installed
|
||||
ReadRegStr $PREV_INST_DIR HKEY_LOCAL_MACHINE "SOFTWARE\SABnzbd" ""
|
||||
@@ -373,6 +380,8 @@ SectionEnd
|
||||
|
||||
LangString MsgOnly64bit ${LANG_ENGLISH} "The installer only supports 64-bit Windows, use the standalone version to run on 32-bit Windows."
|
||||
|
||||
LangString MsgNoWin7 ${LANG_ENGLISH} "The installer only supports Windows 8.1 and above, use the standalone legacy version to run on older Windows version."
|
||||
|
||||
LangString MsgUninstall ${LANG_ENGLISH} "This will uninstall SABnzbd from your system"
|
||||
|
||||
LangString MsgRunAtStart ${LANG_ENGLISH} "Run at startup"
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#set global $root = '../../'#
|
||||
#end if#
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="$active_lang">
|
||||
<html lang="$active_lang" #if $rtl#dir="rtl"#end if#>
|
||||
<head>
|
||||
<title>
|
||||
SABnzbd $T('menu-config')
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!--#set global $pane="Config"#-->
|
||||
<!--#set global $help_uri="configuration/3.2/configure"#-->
|
||||
<!--#set global $help_uri="configuration/3.3/configure"#-->
|
||||
<!--#include $webdir + "/_inc_header_uc.tmpl"#-->
|
||||
|
||||
<!--#from sabnzbd.encoding import CODEPAGE#-->
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!--#set global $pane="Categories"#-->
|
||||
<!--#set global $help_uri="configuration/3.2/categories"#-->
|
||||
<!--#set global $help_uri="configuration/3.3/categories"#-->
|
||||
<!--#include $webdir + "/_inc_header_uc.tmpl"#-->
|
||||
<div class="colmask">
|
||||
<div class="section">
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!--#set global $pane="Folders"#-->
|
||||
<!--#set global $help_uri="configuration/3.2/folders"#-->
|
||||
<!--#set global $help_uri="configuration/3.3/folders"#-->
|
||||
<!--#include $webdir + "/_inc_header_uc.tmpl"#-->
|
||||
|
||||
<div class="colmask">
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!--#set global $pane="General"#-->
|
||||
<!--#set global $help_uri="configuration/3.2/general"#-->
|
||||
<!--#set global $help_uri="configuration/3.3/general"#-->
|
||||
<!--#include $webdir + "/_inc_header_uc.tmpl"#-->
|
||||
|
||||
<div class="colmask">
|
||||
@@ -131,12 +131,7 @@
|
||||
<option value="5" <!--#if $inet_exposure == 5 then 'selected="selected"' else ""#-->>$T('inet-ui') - $T('inet-external_login')</option>
|
||||
</optgroup>
|
||||
</select>
|
||||
<span class="desc">$T('explain-inet_exposure').replace('. ','.<br><span class="label label-warning">'+$T('warning').upper()+'</span> ')</span>
|
||||
</div>
|
||||
<div class="field-pair">
|
||||
<label class="config" for="local_ranges">$T('opt-local_ranges')</label>
|
||||
<input type="text" name="local_ranges" id="local_ranges" value="$local_ranges" />
|
||||
<span class="desc">$T('explain-local_ranges')</span>
|
||||
<span class="desc">$T('explain-inet_exposure')</span>
|
||||
</div>
|
||||
<div class="field-pair">
|
||||
<label class="config" for="apikey_display">$T('opt-apikey')</label>
|
||||
@@ -260,17 +255,18 @@
|
||||
|
||||
// Highlight in case user is not safe
|
||||
// So when exposed to internet and no password, no external limit or no username/password
|
||||
var safeCheck = \$('#host, #local_ranges, #inet_exposure, #${pid}_wu, #${pid}_wp')
|
||||
var safeCheck = \$('#host, #inet_exposure, #${pid}_wu, #${pid}_wp')
|
||||
function checkSafety() {
|
||||
if(\$('#host').val() != 'localhost' && \$('#host').val() != '127.0.0.1') {
|
||||
// No limitation on local-network
|
||||
if(!\$('#local_ranges').val() || \$('#inet_exposure').val() > 3) {
|
||||
if(\$('#inet_exposure').val() > 3) {
|
||||
// And no username and password?
|
||||
if(!\$('#${pid}_wu').val() || !\$('#${pid}_wp').val()) {
|
||||
// Add warning icon if not there already
|
||||
if(!\$('.host-warning').length) {
|
||||
safeCheck.after('<span class="glyphicon glyphicon-alert host-warning"></span>')
|
||||
\$('.host-warning').tooltip({'title': '$T('checkSafety')'})
|
||||
safeCheck.addClass('host-warning-highlight')
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!--#set global $pane="Email"#-->
|
||||
<!--#set global $help_uri="configuration/3.2/notifications"#-->
|
||||
<!--#set global $help_uri="configuration/3.3/notifications"#-->
|
||||
<!--#include $webdir + "/_inc_header_uc.tmpl"#-->
|
||||
|
||||
<!--#def show_notify_checkboxes($section_label)#-->
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!--#set global $pane="RSS"#-->
|
||||
<!--#set global $help_uri="configuration/3.2/rss"#-->
|
||||
<!--#set global $help_uri="configuration/3.3/rss"#-->
|
||||
<!--#include $webdir + "/_inc_header_uc.tmpl"#-->
|
||||
<!--#import html#-->
|
||||
<div class="colmask">
|
||||
@@ -10,7 +10,7 @@
|
||||
<p>$T('explain-RSS')</p>
|
||||
<form action="add_rss_feed" method="post" autocomplete="off">
|
||||
<input type="hidden" name="apikey" value="$apikey" />
|
||||
<table class="catTable">
|
||||
<table class="catTable addRssTable">
|
||||
<tr>
|
||||
<th> </th>
|
||||
<th>$T('name')</th>
|
||||
@@ -21,10 +21,10 @@
|
||||
<td>
|
||||
<input type="checkbox" name="enable" value="1" checked />
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" name="feed" class="smaller_input" value="$feed" />
|
||||
<td class="new-feed-title">
|
||||
<input type="text" name="feed" value="$feed" />
|
||||
</td>
|
||||
<td>
|
||||
<td class="new-feed-url">
|
||||
<input type="text" name="uri" placeholder="$T('addMultipleFeeds')" />
|
||||
</td>
|
||||
<td class="nowrap">
|
||||
@@ -59,7 +59,7 @@
|
||||
<td class="controls">
|
||||
<button type="button" class="btn btn-default testFeed" rel="$feed_item_html"><span class="glyphicon glyphicon-sort"></span> $T('button-preFeed')</button>
|
||||
<input type="hidden" name="uri" value="$rss[$feed_item]['uris']" />
|
||||
<button type="button" class="btn btn-default editFeed" rel="$feed_item_html"><span class="glyphicon glyphicon-pencil"></span> $T('Edit')</button>
|
||||
<button type="button" class="btn btn-default editFeed" rel="$feed_item_html"><span class="glyphicon glyphicon-pencil"></span> $T('rss-edit')</button>
|
||||
<button type="button" class="btn btn-default delFeed" rel="$feed_item_html"><span class="glyphicon glyphicon-trash"></span></button>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -92,7 +92,7 @@
|
||||
<label class="config narrow" for="rss_rate">$T('opt-rss_rate')</label>
|
||||
<input type="number" name="rss_rate" id="rss_rate" value="$rss_rate" min="15" max="1440" />
|
||||
<button type="submit" class="btn btn-default"><span class="glyphicon glyphicon-ok"></span> $T('button-save')</button>
|
||||
<span class="config narrow"> $T('Next scan at:') $rss_next</span>
|
||||
<span class="config narrow"> $T('rss-nextscan'): $rss_next</span>
|
||||
<span class="desc narrow">$T('explain-rss_rate')</span>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!--#set global $pane="Scheduling"#-->
|
||||
<!--#set global $help_uri="configuration/3.2/scheduling"#-->
|
||||
<!--#set global $help_uri="configuration/3.3/scheduling"#-->
|
||||
<!--#include $webdir + "/_inc_header_uc.tmpl"#-->
|
||||
|
||||
<%
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!--#set global $pane="Servers"#-->
|
||||
<!--#set global $help_uri="configuration/3.2/servers"#-->
|
||||
<!--#set global $help_uri="configuration/3.3/servers"#-->
|
||||
<!--#include $webdir + "/_inc_header_uc.tmpl"#-->
|
||||
|
||||
<!--#import json#-->
|
||||
@@ -144,7 +144,7 @@
|
||||
|
||||
<div class="section <!--#if int($server['enable']) == 0 then 'server-disabled' else ""#-->">
|
||||
<div class="col2 <!--#if int($server['enable']) == 0 then 'server-disabled' else ""#-->">
|
||||
<h3>$server['displayname'] <a href="$helpuri$help_uri" target="_blank"><span class="glyphicon glyphicon-question-sign"></span></a></h3>
|
||||
<h3 title="$server['displayname']">$server['displayname'] <a href="$helpuri$help_uri" target="_blank"><span class="glyphicon glyphicon-question-sign"></span></a></h3>
|
||||
<!--#if int($server['enable']) != 0 #-->
|
||||
<!--#if $last_prio != $server['priority'] and $cur_prio_color+1 < len($prio_colors) #-->
|
||||
<!--#set $cur_prio_color = $cur_prio_color+1 #-->
|
||||
@@ -273,6 +273,9 @@
|
||||
<b>$T('srv-article-availability'):</b><br/>
|
||||
$T('selectedDates'): <span id="server-article-value-${cur}"></span>
|
||||
</p>
|
||||
<!--#if $server['expire_date']#-->
|
||||
<p><b>$T('srv-expire_date'):</b> $(server['expire_date'])</p>
|
||||
<!--#end if#-->
|
||||
<!--#if $server['quota']#-->
|
||||
<p><b>$T('quota-left'):</b> $(server['quota_left'])B</p>
|
||||
<!--#end if#-->
|
||||
@@ -385,7 +388,8 @@
|
||||
|
||||
// If values were missing
|
||||
if(!isNaN(articleRatio)) {
|
||||
\$('#server-article-value-' + server_id).text('$T("srv-articles-tried")'.replace('%f', articleRatio).replace('%d', totalArticlesTriedThisRange))
|
||||
// Use filesize to convert to unit-display
|
||||
\$('#server-article-value-' + server_id).text('$T("srv-articles-tried")'.replace('%f', articleRatio).replace('%d', filesize(totalArticlesTriedThisRange, {unix: true, round: 0, spacer: "", base: 1})))
|
||||
} else {
|
||||
\$('#server-article-value-' + server_id).text('$T("notAvailable")')
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!--#set global $pane="Sorting"#-->
|
||||
<!--#set global $help_uri="configuration/3.2/sorting"#-->
|
||||
<!--#set global $help_uri="configuration/3.3/sorting"#-->
|
||||
<!--#include $webdir + "/_inc_header_uc.tmpl"#-->
|
||||
|
||||
<div class="colmask">
|
||||
@@ -130,6 +130,11 @@
|
||||
<td>%e_n</td>
|
||||
<td>$T('ep-us-name')</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="align-right"><b>$T('Resolution'):</b></td>
|
||||
<td>%r</td>
|
||||
<td>1080p</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="align-right"><b>$T('fileExt'):</b></td>
|
||||
<td>%ext</td>
|
||||
@@ -245,6 +250,11 @@
|
||||
<td>%y</td>
|
||||
<td>2009</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="align-right"><b>$T('Resolution'):</b></td>
|
||||
<td>%r</td>
|
||||
<td>1080p</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="align-right"><b>$T('extension'):</b></td>
|
||||
<td>%ext</td>
|
||||
@@ -407,6 +417,11 @@
|
||||
<td>%0decade</td>
|
||||
<td>2000</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="align-right"><b>$T('Resolution'):</b></td>
|
||||
<td>%r</td>
|
||||
<td>1080p</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="align-right"><b>$T('orgFilename'):</b></td>
|
||||
<td>%fn</td>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!--#set global $pane="Special"#-->
|
||||
<!--#set global $help_uri="configuration/3.2/special"#-->
|
||||
<!--#set global $help_uri="configuration/3.3/special"#-->
|
||||
<!--#include $webdir + "/_inc_header_uc.tmpl"#-->
|
||||
|
||||
<div class="colmask">
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!--#set global $pane="Switches"#-->
|
||||
<!--#set global $help_uri="configuration/3.2/switches"#-->
|
||||
<!--#set global $help_uri="configuration/3.3/switches"#-->
|
||||
<!--#include $webdir + "/_inc_header_uc.tmpl"#-->
|
||||
|
||||
<div class="colmask">
|
||||
@@ -120,6 +120,10 @@
|
||||
</div>
|
||||
<div class="field-pair">
|
||||
<label class="config" for="unwanted_extensions">$T('opt-unwanted_extensions')</label>
|
||||
<select name="unwanted_extensions_mode" id="unwanted_extensions_mode">
|
||||
<option value="0" <!--#if int($unwanted_extensions_mode) == 0 then 'selected="selected"' else ""#--> >$T('unwanted_extensions_blacklist')</option>
|
||||
<option value="1" <!--#if int($unwanted_extensions_mode) == 1 then 'selected="selected"' else ""#--> >$T('unwanted_extensions_whitelist')</option>
|
||||
</select>
|
||||
<input type="text" name="unwanted_extensions" id="unwanted_extensions" value="$unwanted_extensions"/>
|
||||
<span class="desc">$T('explain-unwanted_extensions')</span>
|
||||
</div>
|
||||
@@ -136,8 +140,8 @@
|
||||
<label class="config" for="auto_sort">$T('opt-auto_sort')</label>
|
||||
<select name="auto_sort" id="auto_sort">
|
||||
<option value="">$T('default')</option>
|
||||
<option value="avg_age asc" <!--#if $auto_sort == "avg_age asc" then 'selected="selected"' else ""#--> >$T('Glitter-sortAgeAsc')</option>
|
||||
<option value="avg_age desc" <!--#if $auto_sort == "avg_age desc" then 'selected="selected"' else ""#--> >$T('Glitter-sortAgeDesc')</option>
|
||||
<option value="avg_age desc" <!--#if $auto_sort == "avg_age desc" then 'selected="selected"' else ""#--> >$T('Glitter-sortAgeAsc')</option>
|
||||
<option value="avg_age asc" <!--#if $auto_sort == "avg_age asc" then 'selected="selected"' else ""#--> >$T('Glitter-sortAgeDesc')</option>
|
||||
<option value="name asc" <!--#if $auto_sort == "name asc" then 'selected="selected"' else ""#--> >$T('Glitter-sortNameAsc')</option>
|
||||
<option value="name desc" <!--#if $auto_sort == "name desc" then 'selected="selected"' else ""#--> >$T('Glitter-sortNameDesc')</option>
|
||||
<option value="size asc" <!--#if $auto_sort == "size asc" then 'selected="selected"' else ""#--> >$T('Glitter-sortSizeAsc')</option>
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -550,6 +550,16 @@ tr.separator {
|
||||
padding-right: 13px;
|
||||
}
|
||||
/* -- */
|
||||
.RSS .addRssTable,
|
||||
.RSS .addRssTable input[type="text"] {
|
||||
width: 100%;
|
||||
}
|
||||
.RSS .addRssTable .new-feed-title {
|
||||
max-width: 250px;
|
||||
}
|
||||
.RSS .addRssTable .new-feed-url {
|
||||
width: 70%;
|
||||
}
|
||||
h2.activeRSS {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
@@ -559,12 +569,12 @@ h2.activeRSS {
|
||||
text-decoration: underline !important;
|
||||
}
|
||||
.favicon {
|
||||
background-position: center center!important;
|
||||
background-size: 16px 16px;
|
||||
background-position: center center !important;
|
||||
background-size: 22px 22px;
|
||||
opacity: 1;
|
||||
top: -1px;
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
height: 22px;
|
||||
width: 22px;
|
||||
float: left;
|
||||
margin: 0 6px 0 2px;
|
||||
text-align: center;
|
||||
@@ -584,6 +594,7 @@ h2.activeRSS {
|
||||
}
|
||||
#subscriptions {
|
||||
border: 1px solid #E5E5E5;
|
||||
width: 100%;
|
||||
}
|
||||
.data-row {
|
||||
border-top: 1px solid #E5E5E5;
|
||||
@@ -595,6 +606,7 @@ h2.activeRSS {
|
||||
#subscriptions .chk {
|
||||
padding: 8px 5px 5px;
|
||||
vertical-align: middle;
|
||||
width: 40px;
|
||||
}
|
||||
#subscriptions .title {
|
||||
font-weight: bold;
|
||||
@@ -602,10 +614,11 @@ h2.activeRSS {
|
||||
width: auto;
|
||||
}
|
||||
#subscriptions .favicon {
|
||||
margin-left: 8px;
|
||||
margin-left: 7px;
|
||||
margin-top: -2px;
|
||||
}
|
||||
.ie6 .subscription-title {
|
||||
width: 20em;
|
||||
#subscriptions .glyphicon {
|
||||
margin-top: 3px;
|
||||
}
|
||||
.subscription-title,
|
||||
.subscription-title:hover {
|
||||
@@ -1090,6 +1103,10 @@ input[type="checkbox"] {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
||||
.host-warning-highlight {
|
||||
border-color: #F0AD4E !important;
|
||||
}
|
||||
|
||||
.fileBrowser .glyphicon {
|
||||
margin-right: 2px;
|
||||
top: 1px;
|
||||
@@ -1168,6 +1185,31 @@ input[type="checkbox"] {
|
||||
100% { transform: rotate(359deg); }
|
||||
}
|
||||
|
||||
/***
|
||||
RTL Fixes
|
||||
***/
|
||||
html[dir="rtl"] .col1 input[type='checkbox'],
|
||||
html[dir="rtl"] .col2 h3 a {
|
||||
left: 5px;
|
||||
}
|
||||
|
||||
html[dir="rtl"] .modal-header .close {
|
||||
float: left;
|
||||
}
|
||||
|
||||
html[dir="rtl"] .field-pair {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
html[dir="rtl"] .Sorting .presets.float-left,
|
||||
html[dir="rtl"] .checkbox-days {
|
||||
float: none;
|
||||
}
|
||||
|
||||
html[dir="rtl"] .Scheduling form[action="addSchedule"] input[type="checkbox"] {
|
||||
right: 5px;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 1200px) {
|
||||
.Categories input[name="dir"] {
|
||||
max-width: 240px !important;
|
||||
|
||||
@@ -224,4 +224,10 @@
|
||||
<span data-bind="text: history.downloadedMonth"></span>B $T('Glitter-thisMonth')
|
||||
<span data-bind="text: history.downloadedTotal"></span>B $T('Glitter-total')
|
||||
</div>
|
||||
</div>
|
||||
<div class="info-container history-info" data-bind="visible: !hasHistory() && !displayTabbed()" style="display: none">
|
||||
<span class="glyphicon glyphicon-save"></span>
|
||||
<span data-bind="text: history.downloadedToday"></span>B $T('Glitter-today')
|
||||
<span data-bind="text: history.downloadedMonth"></span>B $T('Glitter-thisMonth')
|
||||
<span data-bind="text: history.downloadedTotal"></span>B $T('Glitter-total')
|
||||
</div>
|
||||
@@ -86,34 +86,34 @@
|
||||
<div class="tab-content">
|
||||
<div class="tab-pane fade in active" id="options-status">
|
||||
<div class="row">
|
||||
<div class="col-sm-6">$T('dashboard-localIP4')</div>
|
||||
<div class="col-sm-6">$T('dashboard-localIP4') </div>
|
||||
<div class="col-sm-6" data-bind="visible: hasStatusInfo, text: !statusInfo.localipv4() ? '$T('dashboard-connectionError')' : statusInfo.localipv4(), css: { 'options-bad-status' : !statusInfo.localipv4() }"></div>
|
||||
<div class="col-sm-6 col-loading" data-bind="visible: !hasStatusInfo()">$T('Glitter-loading')<span class="loader-dot-one">.</span><span class="loader-dot-two">.</span><span class="loader-dot-three">.</span></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-6">$T('dashboard-publicIP4')</div>
|
||||
<div class="col-sm-6">$T('dashboard-publicIP4') </div>
|
||||
<div class="col-sm-6" data-bind="visible: hasStatusInfo, text: !statusInfo.publicipv4() ? '$T('dashboard-connectionError')' : statusInfo.publicipv4(), css: { 'options-bad-status ' : !statusInfo.publicipv4() }"></div>
|
||||
<div class="col-sm-6 col-loading" data-bind="visible: !hasStatusInfo()">$T('Glitter-loading')<span class="loader-dot-one">.</span><span class="loader-dot-two">.</span><span class="loader-dot-three">.</span></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-6">$T('dashboard-IP6')</div>
|
||||
<div class="col-sm-6">$T('dashboard-IP6') </div>
|
||||
<div class="col-sm-6" data-bind="visible: hasStatusInfo, text: statusInfo.ipv6"></div>
|
||||
<div class="col-sm-6 col-loading" data-bind="visible: !hasStatusInfo()">$T('Glitter-loading')<span class="loader-dot-one">.</span><span class="loader-dot-two">.</span><span class="loader-dot-three">.</span></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-6">$T('dashboard-NameserverDNS')</div>
|
||||
<div class="col-sm-6">$T('dashboard-NameserverDNS') </div>
|
||||
<div class="col-sm-6" data-bind="visible: hasStatusInfo, text: !statusInfo.dnslookup() ? '$T('dashboard-connectionError')' : statusInfo.dnslookup(), css: { 'options-bad-status' : (statusInfo.dnslookup() != 'OK') }"></div>
|
||||
<div class="col-sm-6 col-loading" data-bind="visible: !hasStatusInfo()">$T('Glitter-loading')<span class="loader-dot-one">.</span><span class="loader-dot-two">.</span><span class="loader-dot-three">.</span></div>
|
||||
</div>
|
||||
<hr/>
|
||||
<div class="row">
|
||||
<div class="col-sm-6">$T('cache')</div>
|
||||
<div class="col-sm-6">$T('cache') </div>
|
||||
<div class="col-sm-6">
|
||||
<span data-bind="text: cacheSize"></span> (<span data-bind="text: cacheArticles"></span> $T('Glitter-articles'))
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-6">$T('dashboard-systemPerformance')</div>
|
||||
<div class="col-sm-6">$T('dashboard-systemPerformance') </div>
|
||||
<div class="col-sm-6" data-bind="visible: hasPerformanceInfo">
|
||||
<span data-bind="text: statusInfo.pystone"></span>
|
||||
<a href="#" data-bind="click: testDiskSpeed" data-tooltip="true" data-placement="right" title="$T('dashboard-repeatTest')"><span class="glyphicon glyphicon-repeat"></span></a>
|
||||
@@ -122,7 +122,7 @@
|
||||
<div class="col-sm-6 col-loading" data-bind="visible: !hasPerformanceInfo()">$T('Glitter-loading')<span class="loader-dot-one">.</span><span class="loader-dot-two">.</span><span class="loader-dot-three">.</span></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-6">$T('dashboard-downloadDirSpeed')</div>
|
||||
<div class="col-sm-6">$T('dashboard-downloadDirSpeed') </div>
|
||||
<div class="col-sm-6" data-bind="visible: hasPerformanceInfo">
|
||||
<span data-bind="text: statusInfo.downloaddirspeed()"></span> MB/s
|
||||
<a href="#" class="diskspeed-button" data-bind="click: testDiskSpeed" data-tooltip="true" data-placement="right" title="$T('dashboard-repeatTest')"><span class="glyphicon glyphicon-repeat"></span></a>
|
||||
@@ -131,7 +131,7 @@
|
||||
<div class="col-sm-6 col-loading" data-bind="visible: !hasPerformanceInfo()">$T('Glitter-loading')<span class="loader-dot-one">.</span><span class="loader-dot-two">.</span><span class="loader-dot-three">.</span></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-6">$T('dashboard-completeDirSpeed')</div>
|
||||
<div class="col-sm-6">$T('dashboard-completeDirSpeed') </div>
|
||||
<div class="col-sm-6" data-bind="visible: hasPerformanceInfo">
|
||||
<span data-bind="text: statusInfo.completedirspeed()"></span> MB/s
|
||||
<a href="#" class="diskspeed-button" data-bind="click: testDiskSpeed" data-tooltip="true" data-placement="right" title="$T('dashboard-repeatTest')"><span class="glyphicon glyphicon-repeat"></span></a>
|
||||
@@ -140,7 +140,7 @@
|
||||
<div class="col-sm-6 col-loading" data-bind="visible: !hasPerformanceInfo()">$T('Glitter-loading')<span class="loader-dot-one">.</span><span class="loader-dot-two">.</span><span class="loader-dot-three">.</span></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-6">$T('dashboard-internetBandwidth')</div>
|
||||
<div class="col-sm-6">$T('dashboard-internetBandwidth') </div>
|
||||
<div class="col-sm-6" data-bind="visible: hasPerformanceInfo">
|
||||
<span data-bind="text: statusInfo.internetbandwidth()"></span> MB/s
|
||||
<a href="#" class="diskspeed-button" data-bind="click: testDiskSpeed" data-tooltip="true" data-placement="right" title="$T('dashboard-repeatTest')"><span class="glyphicon glyphicon-repeat"></span></a>
|
||||
@@ -149,7 +149,7 @@
|
||||
<div class="col-sm-6 col-loading" data-bind="visible: !hasPerformanceInfo()">$T('Glitter-loading')<span class="loader-dot-one">.</span><span class="loader-dot-two">.</span><span class="loader-dot-three">.</span></div>
|
||||
</div>
|
||||
<div class="row test-download">
|
||||
<div class="col-sm-6">$T('dashboard-testDownload')</div>
|
||||
<div class="col-sm-6">$T('dashboard-testDownload') </div>
|
||||
<div class="col-sm-6">
|
||||
<a href="#" class="btn btn-default" data-bind="click: testDownload" data-size="100MB" data-tooltip="true" data-placement="top" title="$T('dashboard-testDownload-explain')"><span class="glyphicon glyphicon-download-alt"></span> 100 MB</a>
|
||||
<a href="#" class="btn btn-default" data-bind="click: testDownload" data-size="1000MB" data-tooltip="true" data-placement="top" title="$T('dashboard-testDownload-explain')"><span class="glyphicon glyphicon-download-alt"></span> 1 GB</a>
|
||||
|
||||
@@ -109,7 +109,7 @@
|
||||
<form data-bind="submit: editingNameSubmit">
|
||||
<input type="text" data-bind="value: nameForEdit, visible: editingName(), hasfocus: editingName" />
|
||||
</form>
|
||||
<div class="name-icons direct-unpack hover-button" data-bind="visible: direct_unpack">
|
||||
<div class="name-icons direct-unpack hover-button" data-bind="visible: direct_unpack() && !editingName()">
|
||||
<span class="glyphicon glyphicon-compressed"></span> <span data-bind="text: direct_unpack"></span>
|
||||
</div>
|
||||
<div class="name-options" data-bind="visible: !editingName(), css: { disabled: isGrabbing() }">
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<!DOCTYPE html>
|
||||
<!--#set $active_lang=$active_lang.replace('_', '-').lower()#-->
|
||||
<html lang="$active_lang" id="sabnzbd" data-bind="filedrop: { overlaySelector: '.main-filedrop', onFileDrop: addNZBFromFile }">
|
||||
<html lang="$active_lang" <!--#if $rtl#-->dir="rtl"<!--#end if#--> id="sabnzbd" data-bind="filedrop: { overlaySelector: '.main-filedrop', onFileDrop: addNZBFromFile }">
|
||||
<head>
|
||||
<!--
|
||||
Glitter V2
|
||||
@@ -36,7 +36,7 @@
|
||||
<link rel="stylesheet" type="text/css" href="./static/bootstrap/css/bootstrap.min.css?v=$version" />
|
||||
<link rel="stylesheet" type="text/css" href="./static/stylesheets/glitter.css?v=$version" />
|
||||
<link rel="stylesheet" type="text/css" href="./static/stylesheets/glitter.mobile.css?v=$version" media="all and (max-width: 768px)" />
|
||||
<!--#if $color_scheme not in ('Default', '') #-->
|
||||
<!--#if $color_scheme not in ('Light', '') #-->
|
||||
<link rel="stylesheet" type="text/css" href="./static/stylesheets/colorschemes/${color_scheme}.css?v=$version"/>
|
||||
<!--#end if#-->
|
||||
|
||||
@@ -52,15 +52,17 @@
|
||||
var glitterTranslate = new Object();
|
||||
glitterTranslate.paused = "$T('post-Paused')";
|
||||
glitterTranslate.left = "$T('Glitter-left')";
|
||||
glitterTranslate.clearWarn = "$T('Glitter-confirmClearWarnings')";
|
||||
glitterTranslate.clearWarn = "$T('confirm')";
|
||||
glitterTranslate.pausePromptFail = "$T('Glitter-pausePromptFail')"
|
||||
glitterTranslate.pauseFor = "$T('pauseFor')"
|
||||
glitterTranslate.minutes = "$T('mins')"
|
||||
glitterTranslate.shutdown = "$T('shutdownOK?')";
|
||||
glitterTranslate.restart = "$T('explain-Restart') $T('explain-needNewLogin')".replace(/\<br(\s*\/|)\>/g, '\n');
|
||||
glitterTranslate.repair = "$T('explain-Repair')".replace(/<br \/>/g, "\n").replace(/"/g,'"');
|
||||
glitterTranslate.removeDown = "$T('Glitter-confirmClearDownloads')";
|
||||
glitterTranslate.removeDow1 = "$T('Glitter-confirmClear1Download')";
|
||||
glitterTranslate.deleteMsg = "$T('nzo-delete')";
|
||||
glitterTranslate.removeDown = "$T('confirm')";
|
||||
glitterTranslate.removeDow1 = "$T('confirm')";
|
||||
glitterTranslate.renameAbort = "$T('Glitter-confirmAbortDirectUnpack')\n$T('confirm')";
|
||||
glitterTranslate.retryAll = "$T('link-retryAll')?";
|
||||
glitterTranslate.fetch = "$T('Glitter-fetch')";
|
||||
glitterTranslate.encrypted = "$T('Glitter-encrypted')";
|
||||
|
||||
@@ -421,7 +421,7 @@ function HistoryModel(parent, data) {
|
||||
// Delete button
|
||||
self.deleteSlot = function(item, event) {
|
||||
// Confirm?
|
||||
if(!self.parent.parent.confirmDeleteHistory() || confirm(glitterTranslate.removeDow1)) {
|
||||
if(!self.parent.parent.confirmDeleteHistory() || confirm(glitterTranslate.deleteMsg + ":\n" + item.historyStatus.name() + "\n\n" + glitterTranslate.removeDow1)) {
|
||||
// Are we still processing and it can be stopped?
|
||||
if(item.processingDownload() == 2) {
|
||||
callAPI({
|
||||
|
||||
@@ -652,6 +652,9 @@ function QueueModel(parent, data) {
|
||||
// Anything change or empty?
|
||||
if(!newName || self.name() == newName) return;
|
||||
|
||||
// Rename would abort Direct Unpack, so ask if user is sure
|
||||
if(self.direct_unpack() && !confirm(glitterTranslate.renameAbort)) return;
|
||||
|
||||
// Send rename
|
||||
callAPI({
|
||||
mode: 'queue',
|
||||
@@ -724,7 +727,7 @@ function QueueModel(parent, data) {
|
||||
// Remove 1 download from queue
|
||||
self.removeDownload = function(item, event) {
|
||||
// Confirm and remove
|
||||
if(!self.parent.parent.confirmDeleteQueue() || confirm(glitterTranslate.removeDow1)) {
|
||||
if(!self.parent.parent.confirmDeleteQueue() || confirm(glitterTranslate.deleteMsg + ":\n" + item.name() + "\n\n" + glitterTranslate.removeDow1)) {
|
||||
var itemToDelete = this;
|
||||
|
||||
// Show notification
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
@import url('Night.css') screen and (prefers-color-scheme: dark);
|
||||
@@ -55,6 +55,10 @@ legend,
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.form-control[disabled] {
|
||||
opacity: 0.65;
|
||||
}
|
||||
|
||||
.progress {
|
||||
background-color: #DADADA;
|
||||
}
|
||||
@@ -126,6 +130,10 @@ select.form-control,
|
||||
.main-content .btn-default,
|
||||
.modal-body .btn-default,
|
||||
.modal-footer .btn-default,
|
||||
.btn-default.disabled:hover,
|
||||
.btn-default.disabled:active,
|
||||
.btn-default.disabled:focus,
|
||||
.form-control[disabled],
|
||||
#modal-options .options-function-box .input-group-addon {
|
||||
background-color: #555555;
|
||||
color: #EBEBEB;
|
||||
@@ -157,6 +165,8 @@ tbody>tr:last-child td,
|
||||
input,
|
||||
input.form-control,
|
||||
.input-group-addon,
|
||||
.search-box input:focus,
|
||||
.search-box input:valid,
|
||||
select.form-control,
|
||||
#modal-options .table-server-connections th,
|
||||
.main-content .btn-default,
|
||||
|
||||
@@ -1979,6 +1979,45 @@ input[name="nzbURL"] {
|
||||
}
|
||||
}
|
||||
|
||||
/***
|
||||
RTL Fixes
|
||||
***/
|
||||
|
||||
html[dir="rtl"] .navbar-nav {
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
html[dir="rtl"] .queue h2,
|
||||
html[dir="rtl"] .history h2 {
|
||||
float: right;
|
||||
}
|
||||
|
||||
html[dir="rtl"] .dropdown-menu {
|
||||
text-align: right;
|
||||
direction: rtl;
|
||||
}
|
||||
|
||||
html[dir="rtl"] .speedlimit-dropdown,
|
||||
html[dir="rtl"] .progress-indicator,
|
||||
html[dir="rtl"] #modal-item-filelist,
|
||||
html[dir="rtl"] #modal-item-files .modal-title,
|
||||
html[dir="rtl"] .info-container-box,
|
||||
html[dir="rtl"] .queue-table,
|
||||
html[dir="rtl"] .history-table {
|
||||
direction: ltr;
|
||||
}
|
||||
|
||||
html[dir="rtl"] .search-box a {
|
||||
right: initial;
|
||||
left: 8px;
|
||||
}
|
||||
|
||||
html[dir="rtl"] .navbar-logo,
|
||||
html[dir="rtl"] .info-container,
|
||||
html[dir="rtl"] .modal-header .close,
|
||||
html[dir="rtl"] #modal-options .modal-header a {
|
||||
float: left;
|
||||
}
|
||||
|
||||
/***
|
||||
Bootstrap overwrites
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-3.2.0-develop\n"
|
||||
"Project-Id-Version: SABnzbd-3.3.0-develop\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: team@sabnzbd.org\n"
|
||||
"Language-Team: SABnzbd <team@sabnzbd.org>\n"
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-3.2.0-develop\n"
|
||||
"Project-Id-Version: SABnzbd-3.3.0-develop\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:56+0000\n"
|
||||
"Language-Team: Czech (https://www.transifex.com/sabnzbd/teams/111101/cs/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-3.2.0-develop\n"
|
||||
"Project-Id-Version: SABnzbd-3.3.0-develop\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:56+0000\n"
|
||||
"Last-Translator: Safihre <safihre@sabnzbd.org>, 2020\n"
|
||||
"Language-Team: Danish (https://www.transifex.com/sabnzbd/teams/111101/da/)\n"
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-3.2.0-develop\n"
|
||||
"Project-Id-Version: SABnzbd-3.3.0-develop\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:56+0000\n"
|
||||
"Last-Translator: Safihre <safihre@sabnzbd.org>, 2020\n"
|
||||
"Language-Team: German (https://www.transifex.com/sabnzbd/teams/111101/de/)\n"
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-3.2.0-develop\n"
|
||||
"Project-Id-Version: SABnzbd-3.3.0-develop\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:56+0000\n"
|
||||
"Last-Translator: Safihre <safihre@sabnzbd.org>, 2020\n"
|
||||
"Language-Team: Spanish (https://www.transifex.com/sabnzbd/teams/111101/es/)\n"
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-3.2.0-develop\n"
|
||||
"Project-Id-Version: SABnzbd-3.3.0-develop\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:56+0000\n"
|
||||
"Last-Translator: Safihre <safihre@sabnzbd.org>, 2020\n"
|
||||
"Language-Team: Finnish (https://www.transifex.com/sabnzbd/teams/111101/fi/)\n"
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-3.2.0-develop\n"
|
||||
"Project-Id-Version: SABnzbd-3.3.0-develop\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:56+0000\n"
|
||||
"Last-Translator: Safihre <safihre@sabnzbd.org>, 2020\n"
|
||||
"Language-Team: French (https://www.transifex.com/sabnzbd/teams/111101/fr/)\n"
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-3.2.0-develop\n"
|
||||
"Project-Id-Version: SABnzbd-3.3.0-develop\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:56+0000\n"
|
||||
"Last-Translator: ION, 2020\n"
|
||||
"Language-Team: Hebrew (https://www.transifex.com/sabnzbd/teams/111101/he/)\n"
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-3.2.0-develop\n"
|
||||
"Project-Id-Version: SABnzbd-3.3.0-develop\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:56+0000\n"
|
||||
"Last-Translator: Safihre <safihre@sabnzbd.org>, 2020\n"
|
||||
"Language-Team: Norwegian Bokmål (https://www.transifex.com/sabnzbd/teams/111101/nb/)\n"
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-3.2.0-develop\n"
|
||||
"Project-Id-Version: SABnzbd-3.3.0-develop\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:56+0000\n"
|
||||
"Last-Translator: Safihre <safihre@sabnzbd.org>, 2020\n"
|
||||
"Language-Team: Dutch (https://www.transifex.com/sabnzbd/teams/111101/nl/)\n"
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-3.2.0-develop\n"
|
||||
"Project-Id-Version: SABnzbd-3.3.0-develop\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:56+0000\n"
|
||||
"Last-Translator: Safihre <safihre@sabnzbd.org>, 2020\n"
|
||||
"Language-Team: Polish (https://www.transifex.com/sabnzbd/teams/111101/pl/)\n"
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-3.2.0-develop\n"
|
||||
"Project-Id-Version: SABnzbd-3.3.0-develop\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:56+0000\n"
|
||||
"Last-Translator: Safihre <safihre@sabnzbd.org>, 2020\n"
|
||||
"Language-Team: Portuguese (Brazil) (https://www.transifex.com/sabnzbd/teams/111101/pt_BR/)\n"
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-3.2.0-develop\n"
|
||||
"Project-Id-Version: SABnzbd-3.3.0-develop\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:56+0000\n"
|
||||
"Last-Translator: Safihre <safihre@sabnzbd.org>, 2020\n"
|
||||
"Language-Team: Romanian (https://www.transifex.com/sabnzbd/teams/111101/ro/)\n"
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-3.2.0-develop\n"
|
||||
"Project-Id-Version: SABnzbd-3.3.0-develop\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:56+0000\n"
|
||||
"Last-Translator: Safihre <safihre@sabnzbd.org>, 2020\n"
|
||||
"Language-Team: Russian (https://www.transifex.com/sabnzbd/teams/111101/ru/)\n"
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-3.2.0-develop\n"
|
||||
"Project-Id-Version: SABnzbd-3.3.0-develop\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:56+0000\n"
|
||||
"Last-Translator: Safihre <safihre@sabnzbd.org>, 2020\n"
|
||||
"Language-Team: Serbian (https://www.transifex.com/sabnzbd/teams/111101/sr/)\n"
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-3.2.0-develop\n"
|
||||
"Project-Id-Version: SABnzbd-3.3.0-develop\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:56+0000\n"
|
||||
"Last-Translator: Safihre <safihre@sabnzbd.org>, 2020\n"
|
||||
"Language-Team: Swedish (https://www.transifex.com/sabnzbd/teams/111101/sv/)\n"
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-3.2.0-develop\n"
|
||||
"Project-Id-Version: SABnzbd-3.3.0-develop\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:56+0000\n"
|
||||
"Last-Translator: Safihre <safihre@sabnzbd.org>, 2020\n"
|
||||
"Language-Team: Chinese (China) (https://www.transifex.com/sabnzbd/teams/111101/zh_CN/)\n"
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-3.2.0-develop\n"
|
||||
"Project-Id-Version: SABnzbd-3.3.0-develop\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: team@sabnzbd.org\n"
|
||||
"Language-Team: SABnzbd <team@sabnzbd.org>\n"
|
||||
@@ -567,6 +567,15 @@ msgstr ""
|
||||
msgid "Failed moving %s to %s"
|
||||
msgstr ""
|
||||
|
||||
#. Error message
|
||||
#: sabnzbd/filesystem.py
|
||||
msgid "Blocked attempt to create directory %s"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/interface.py
|
||||
msgid "Refused connection from:"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/interface.py
|
||||
msgid "Refused connection with hostname \"%s\" from:"
|
||||
msgstr ""
|
||||
@@ -596,6 +605,7 @@ msgstr ""
|
||||
msgid "Authentication failed, check username/password."
|
||||
msgstr ""
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/interface.py
|
||||
msgid "Unsuccessful login attempt from %s"
|
||||
msgstr ""
|
||||
@@ -1114,10 +1124,6 @@ msgstr ""
|
||||
msgid "%s -> Unknown encoding"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "%s => missing from all servers, discarding"
|
||||
msgstr ""
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Invalid NZB file %s, skipping (reason=%s, line=%s)"
|
||||
@@ -2984,20 +2990,12 @@ msgstr ""
|
||||
msgid "API Key QR Code"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "List of local network ranges"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "All local network addresses start with these prefixes (often \"192.168.1.\")"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "External internet access"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "You can set access rights for systems outside your local network. Requires List of local network ranges to be defined."
|
||||
msgid "You can set access rights for systems outside your local network."
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
@@ -3262,7 +3260,7 @@ msgid "Action when unwanted extension detected"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Action when an unwanted extension is detected in RAR files"
|
||||
msgid "Action when an unwanted extension is detected"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
@@ -3270,7 +3268,15 @@ msgid "Unwanted extensions"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "List all unwanted extensions. For example: <b>exe</b> or <b>exe, com</b>"
|
||||
msgid "Blacklist"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Whitelist"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Select a mode and list all (un)wanted extensions. For example: <b>exe</b> or <b>exe, com</b>"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
@@ -3771,6 +3777,16 @@ msgstr ""
|
||||
msgid "Force Download"
|
||||
msgstr ""
|
||||
|
||||
#. Config->RSS edit button
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Edit"
|
||||
msgstr ""
|
||||
|
||||
#. Config->RSS when will be the next RSS scan
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Next scan at"
|
||||
msgstr ""
|
||||
|
||||
#. Config->RSS table column header
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Filter"
|
||||
@@ -4539,6 +4555,10 @@ msgstr ""
|
||||
msgid "View Script Log"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Renaming the job will abort Direct Unpack."
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "LocalStorage (cookies) are disabled in your browser, interface settings will be lost after you close the browser!"
|
||||
msgstr ""
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-3.2.0-develop\n"
|
||||
"Project-Id-Version: SABnzbd-3.3.0-develop\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:49+0000\n"
|
||||
"Last-Translator: Pavel C <quoing_transifex@mess.cz>, 2021\n"
|
||||
"Language-Team: Czech (https://www.transifex.com/sabnzbd/teams/111101/cs/)\n"
|
||||
@@ -596,6 +596,15 @@ msgstr "Chyba vytváření (%s)"
|
||||
msgid "Failed moving %s to %s"
|
||||
msgstr "Chyba přesunu %s do %s"
|
||||
|
||||
#. Error message
|
||||
#: sabnzbd/filesystem.py
|
||||
msgid "Blocked attempt to create directory %s"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/interface.py
|
||||
msgid "Refused connection from:"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/interface.py
|
||||
msgid "Refused connection with hostname \"%s\" from:"
|
||||
msgstr "Odmítnuté spojení s hostem \"%s\" z:"
|
||||
@@ -637,6 +646,7 @@ msgstr ""
|
||||
msgid "Authentication failed, check username/password."
|
||||
msgstr "Přihlášené selhalo, zkontrolujte jméno a heslo."
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/interface.py
|
||||
msgid "Unsuccessful login attempt from %s"
|
||||
msgstr "Nezdařený pokus o přihlášení od %s"
|
||||
@@ -1178,10 +1188,6 @@ msgstr "NZB přidáno do fronty"
|
||||
msgid "%s -> Unknown encoding"
|
||||
msgstr "%s -> Neznámé kódování"
|
||||
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "%s => missing from all servers, discarding"
|
||||
msgstr ""
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Invalid NZB file %s, skipping (reason=%s, line=%s)"
|
||||
@@ -3096,23 +3102,12 @@ msgstr "Generovat nový klíč"
|
||||
msgid "API Key QR Code"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "List of local network ranges"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid ""
|
||||
"All local network addresses start with these prefixes (often \"192.168.1.\")"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "External internet access"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid ""
|
||||
"You can set access rights for systems outside your local network. Requires "
|
||||
"List of local network ranges to be defined."
|
||||
msgid "You can set access rights for systems outside your local network."
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
@@ -3408,16 +3403,25 @@ msgid "Action when unwanted extension detected"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Action when an unwanted extension is detected in RAR files"
|
||||
msgid "Action when an unwanted extension is detected"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Unwanted extensions"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Blacklist"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Whitelist"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid ""
|
||||
"List all unwanted extensions. For example: <b>exe</b> or <b>exe, com</b>"
|
||||
"Select a mode and list all (un)wanted extensions. For example: <b>exe</b> or"
|
||||
" <b>exe, com</b>"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
@@ -3946,6 +3950,16 @@ msgstr ""
|
||||
msgid "Force Download"
|
||||
msgstr ""
|
||||
|
||||
#. Config->RSS edit button
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Edit"
|
||||
msgstr ""
|
||||
|
||||
#. Config->RSS when will be the next RSS scan
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Next scan at"
|
||||
msgstr ""
|
||||
|
||||
#. Config->RSS table column header
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Filter"
|
||||
@@ -4724,6 +4738,10 @@ msgstr ""
|
||||
msgid "View Script Log"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Renaming the job will abort Direct Unpack."
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid ""
|
||||
"LocalStorage (cookies) are disabled in your browser, interface settings will"
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-3.2.0-develop\n"
|
||||
"Project-Id-Version: SABnzbd-3.3.0-develop\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:49+0000\n"
|
||||
"Last-Translator: Safihre <safihre@sabnzbd.org>, 2020\n"
|
||||
"Language-Team: Danish (https://www.transifex.com/sabnzbd/teams/111101/da/)\n"
|
||||
@@ -607,6 +607,15 @@ msgstr "Oprettelse af (%s) mislykkedes"
|
||||
msgid "Failed moving %s to %s"
|
||||
msgstr "Det lykkedes ikke at flytte %s til %s"
|
||||
|
||||
#. Error message
|
||||
#: sabnzbd/filesystem.py
|
||||
msgid "Blocked attempt to create directory %s"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/interface.py
|
||||
msgid "Refused connection from:"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/interface.py
|
||||
msgid "Refused connection with hostname \"%s\" from:"
|
||||
msgstr ""
|
||||
@@ -648,6 +657,7 @@ msgstr ""
|
||||
msgid "Authentication failed, check username/password."
|
||||
msgstr "Godkendelse mislykkedes, kontrollere brugernavn/adgangskode."
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/interface.py
|
||||
msgid "Unsuccessful login attempt from %s"
|
||||
msgstr "Mislykkede login forsøg fra %s"
|
||||
@@ -1187,10 +1197,6 @@ msgstr "NZB tilføjet i køen"
|
||||
msgid "%s -> Unknown encoding"
|
||||
msgstr "%s -> Ukendt kodning"
|
||||
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "%s => missing from all servers, discarding"
|
||||
msgstr "%s => mangler fra alle servere, afviser"
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Invalid NZB file %s, skipping (reason=%s, line=%s)"
|
||||
@@ -3153,28 +3159,13 @@ msgstr "Generere Ny Nøgle"
|
||||
msgid "API Key QR Code"
|
||||
msgstr "API nøgle QR kode"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "List of local network ranges"
|
||||
msgstr "Liste over lokale netværk intervaller"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid ""
|
||||
"All local network addresses start with these prefixes (often \"192.168.1.\")"
|
||||
msgstr ""
|
||||
"Alle lokale netværksadresser starter med disse præfikser (ofte "
|
||||
"\"192.168.1.\")"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "External internet access"
|
||||
msgstr "Eksterne internetadgang"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid ""
|
||||
"You can set access rights for systems outside your local network. Requires "
|
||||
"List of local network ranges to be defined."
|
||||
msgid "You can set access rights for systems outside your local network."
|
||||
msgstr ""
|
||||
"Du kan angive adgangsrettigheder for systemer uden for dit lokale netværk. "
|
||||
"Kræver liste over lokale netværks intervaller, skal defineres."
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "No access"
|
||||
@@ -3495,18 +3486,26 @@ msgid "Action when unwanted extension detected"
|
||||
msgstr "Aktion når uønsket extension er fundet"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Action when an unwanted extension is detected in RAR files"
|
||||
msgstr "Aktion når uønsket extension er fundet i RAR fil"
|
||||
msgid "Action when an unwanted extension is detected"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Unwanted extensions"
|
||||
msgstr "Uønsket extension"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid ""
|
||||
"List all unwanted extensions. For example: <b>exe</b> or <b>exe, com</b>"
|
||||
msgid "Blacklist"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Whitelist"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid ""
|
||||
"Select a mode and list all (un)wanted extensions. For example: <b>exe</b> or"
|
||||
" <b>exe, com</b>"
|
||||
msgstr ""
|
||||
"Vis alle uønskede extensions. For eksempel: <b>exe</b> or <b>exe, com</b>"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Enable SFV-based checks"
|
||||
@@ -4054,6 +4053,16 @@ msgstr "Læs Feed"
|
||||
msgid "Force Download"
|
||||
msgstr "Gennemtving download"
|
||||
|
||||
#. Config->RSS edit button
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Edit"
|
||||
msgstr ""
|
||||
|
||||
#. Config->RSS when will be the next RSS scan
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Next scan at"
|
||||
msgstr ""
|
||||
|
||||
#. Config->RSS table column header
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Filter"
|
||||
@@ -4842,6 +4851,10 @@ msgstr "Skjul/vis komplette filer"
|
||||
msgid "View Script Log"
|
||||
msgstr "Vis scriptlog"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Renaming the job will abort Direct Unpack."
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid ""
|
||||
"LocalStorage (cookies) are disabled in your browser, interface settings will"
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-3.2.0-develop\n"
|
||||
"Project-Id-Version: SABnzbd-3.3.0-develop\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:49+0000\n"
|
||||
"Last-Translator: reloxx13 <reloxx@interia.pl>, 2021\n"
|
||||
"Language-Team: German (https://www.transifex.com/sabnzbd/teams/111101/de/)\n"
|
||||
@@ -628,6 +628,15 @@ msgstr "Erstellen von %s fehlgeschlagen"
|
||||
msgid "Failed moving %s to %s"
|
||||
msgstr "Verschieben von %s nach %s fehlgeschlagen"
|
||||
|
||||
#. Error message
|
||||
#: sabnzbd/filesystem.py
|
||||
msgid "Blocked attempt to create directory %s"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/interface.py
|
||||
msgid "Refused connection from:"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/interface.py
|
||||
msgid "Refused connection with hostname \"%s\" from:"
|
||||
msgstr "Verbindung vom Host \"%s\" abgelehnt von:"
|
||||
@@ -670,6 +679,7 @@ msgid "Authentication failed, check username/password."
|
||||
msgstr ""
|
||||
"Authentifizierung fehlgeschlagen. Überprüfen Sie Benutzername und Passwort."
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/interface.py
|
||||
msgid "Unsuccessful login attempt from %s"
|
||||
msgstr "Fehlerhafter Login Versuch von %s"
|
||||
@@ -1224,10 +1234,6 @@ msgstr "NZB zur Warteschlange hinzugefügt"
|
||||
msgid "%s -> Unknown encoding"
|
||||
msgstr "%s -> Unbekannte Kodierung"
|
||||
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "%s => missing from all servers, discarding"
|
||||
msgstr "%s wurde auf keinem Server gefunden und daher übersprungen"
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Invalid NZB file %s, skipping (reason=%s, line=%s)"
|
||||
@@ -3232,28 +3238,13 @@ msgstr "Neuen Schlüssel generieren"
|
||||
msgid "API Key QR Code"
|
||||
msgstr "API-Key OR-Code"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "List of local network ranges"
|
||||
msgstr "Liste der lokalen Netzwerkadressenbereiche"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid ""
|
||||
"All local network addresses start with these prefixes (often \"192.168.1.\")"
|
||||
msgstr ""
|
||||
"Alle lokalen Netzwerkadressen starten mit diesen Präfixen (oft "
|
||||
"\"192.168.1.1\")"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "External internet access"
|
||||
msgstr "Externer Internetzugriff"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid ""
|
||||
"You can set access rights for systems outside your local network. Requires "
|
||||
"List of local network ranges to be defined."
|
||||
msgid "You can set access rights for systems outside your local network."
|
||||
msgstr ""
|
||||
"Du kannst Zugriffsrechte für Systeme ausserhalb deines Netzwerkes setzen. "
|
||||
"Benötigt die Definition einer Liste von lokalen Netzwerkbereichen."
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "No access"
|
||||
@@ -3592,19 +3583,26 @@ msgid "Action when unwanted extension detected"
|
||||
msgstr "Aktion bei ungewollter Dateienendung"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Action when an unwanted extension is detected in RAR files"
|
||||
msgstr "Aktion bei ungewollter Dateiendung innerhalb RAR-Archiven"
|
||||
msgid "Action when an unwanted extension is detected"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Unwanted extensions"
|
||||
msgstr "Ungewollte Dateiendungen"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid ""
|
||||
"List all unwanted extensions. For example: <b>exe</b> or <b>exe, com</b>"
|
||||
msgid "Blacklist"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Whitelist"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid ""
|
||||
"Select a mode and list all (un)wanted extensions. For example: <b>exe</b> or"
|
||||
" <b>exe, com</b>"
|
||||
msgstr ""
|
||||
"Liste aller ungewollter Dateiendungen. Zum Beispiel: <b>exe</b> or <b>exe, "
|
||||
"com</b>"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Enable SFV-based checks"
|
||||
@@ -4174,6 +4172,16 @@ msgstr "Feed lesen"
|
||||
msgid "Force Download"
|
||||
msgstr "Download erzwingen"
|
||||
|
||||
#. Config->RSS edit button
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Edit"
|
||||
msgstr ""
|
||||
|
||||
#. Config->RSS when will be the next RSS scan
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Next scan at"
|
||||
msgstr ""
|
||||
|
||||
#. Config->RSS table column header
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Filter"
|
||||
@@ -4966,6 +4974,10 @@ msgstr "Vollendete Dateien anzeigen/verstecken"
|
||||
msgid "View Script Log"
|
||||
msgstr "Skript-Protokoll anzeigen"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Renaming the job will abort Direct Unpack."
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid ""
|
||||
"LocalStorage (cookies) are disabled in your browser, interface settings will"
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-3.2.0-develop\n"
|
||||
"Project-Id-Version: SABnzbd-3.3.0-develop\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:49+0000\n"
|
||||
"Last-Translator: 1024mb <angelb2203@gmail.com>, 2020\n"
|
||||
"Language-Team: Spanish (https://www.transifex.com/sabnzbd/teams/111101/es/)\n"
|
||||
@@ -628,6 +628,15 @@ msgstr "Error al crear (%s)"
|
||||
msgid "Failed moving %s to %s"
|
||||
msgstr "Error al mover %s a %s"
|
||||
|
||||
#. Error message
|
||||
#: sabnzbd/filesystem.py
|
||||
msgid "Blocked attempt to create directory %s"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/interface.py
|
||||
msgid "Refused connection from:"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/interface.py
|
||||
msgid "Refused connection with hostname \"%s\" from:"
|
||||
msgstr "Se deniega la conexión con el nombre de equipo \"%s\" desde:"
|
||||
@@ -669,6 +678,7 @@ msgstr ""
|
||||
msgid "Authentication failed, check username/password."
|
||||
msgstr "Autenticación fallida, compruebe el usuario o la contraseña."
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/interface.py
|
||||
msgid "Unsuccessful login attempt from %s"
|
||||
msgstr "Intento fallido de inicio de sesión desde %s"
|
||||
@@ -1230,10 +1240,6 @@ msgstr "NZB añadido a la cola"
|
||||
msgid "%s -> Unknown encoding"
|
||||
msgstr "%s -> Codificación desconocida"
|
||||
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "%s => missing from all servers, discarding"
|
||||
msgstr "%s => faltando de todos servidores, desechando"
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Invalid NZB file %s, skipping (reason=%s, line=%s)"
|
||||
@@ -3235,28 +3241,13 @@ msgstr "Generar nueva clave"
|
||||
msgid "API Key QR Code"
|
||||
msgstr "Código QR de la clave API"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "List of local network ranges"
|
||||
msgstr "Lista de rangos de red local"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid ""
|
||||
"All local network addresses start with these prefixes (often \"192.168.1.\")"
|
||||
msgstr ""
|
||||
"Todas las direcciones de red locales comienzan con estos prefijos (a menudo "
|
||||
"\" 192.168.1 . \" )"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "External internet access"
|
||||
msgstr "Acceso a internet externa"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid ""
|
||||
"You can set access rights for systems outside your local network. Requires "
|
||||
"List of local network ranges to be defined."
|
||||
msgid "You can set access rights for systems outside your local network."
|
||||
msgstr ""
|
||||
"Puede configurar los derechos de acceso para los sistemas fuera de su red "
|
||||
"local. Es necesario definir los rangos de la lista de red local."
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "No access"
|
||||
@@ -3583,19 +3574,26 @@ msgid "Action when unwanted extension detected"
|
||||
msgstr "Acción al detectar extensiones no deseadas"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Action when an unwanted extension is detected in RAR files"
|
||||
msgstr "Acción cuando se detecta una extensión no deseada en archivos RAR"
|
||||
msgid "Action when an unwanted extension is detected"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Unwanted extensions"
|
||||
msgstr "extensiones no deseadas"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid ""
|
||||
"List all unwanted extensions. For example: <b>exe</b> or <b>exe, com</b>"
|
||||
msgid "Blacklist"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Whitelist"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid ""
|
||||
"Select a mode and list all (un)wanted extensions. For example: <b>exe</b> or"
|
||||
" <b>exe, com</b>"
|
||||
msgstr ""
|
||||
"Enumerar todas las extensiones no deseadas . Por ejemplo : < b> exe < / b > "
|
||||
"o < b> exe, com < / b >"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Enable SFV-based checks"
|
||||
@@ -4166,6 +4164,16 @@ msgstr "Leer Fuente"
|
||||
msgid "Force Download"
|
||||
msgstr "Forzar Descarga"
|
||||
|
||||
#. Config->RSS edit button
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Edit"
|
||||
msgstr ""
|
||||
|
||||
#. Config->RSS when will be the next RSS scan
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Next scan at"
|
||||
msgstr ""
|
||||
|
||||
#. Config->RSS table column header
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Filter"
|
||||
@@ -4960,6 +4968,10 @@ msgstr "Ocultar/Mostrar ficheros completados"
|
||||
msgid "View Script Log"
|
||||
msgstr "Ver bitacora de Scripts"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Renaming the job will abort Direct Unpack."
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid ""
|
||||
"LocalStorage (cookies) are disabled in your browser, interface settings will"
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-3.2.0-develop\n"
|
||||
"Project-Id-Version: SABnzbd-3.3.0-develop\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:49+0000\n"
|
||||
"Last-Translator: Safihre <safihre@sabnzbd.org>, 2020\n"
|
||||
"Language-Team: Finnish (https://www.transifex.com/sabnzbd/teams/111101/fi/)\n"
|
||||
@@ -603,6 +603,15 @@ msgstr "Kohteen (%s) luominen epäonnistui"
|
||||
msgid "Failed moving %s to %s"
|
||||
msgstr "Kohteen %s siirtäminen kohteeseen %s epäonnistui"
|
||||
|
||||
#. Error message
|
||||
#: sabnzbd/filesystem.py
|
||||
msgid "Blocked attempt to create directory %s"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/interface.py
|
||||
msgid "Refused connection from:"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/interface.py
|
||||
msgid "Refused connection with hostname \"%s\" from:"
|
||||
msgstr ""
|
||||
@@ -644,6 +653,7 @@ msgstr ""
|
||||
msgid "Authentication failed, check username/password."
|
||||
msgstr "Varmennus epäonnistui, tarkista käyttäjänimi/salasana."
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/interface.py
|
||||
msgid "Unsuccessful login attempt from %s"
|
||||
msgstr ""
|
||||
@@ -1180,10 +1190,6 @@ msgstr "NZB lisätty jonoon"
|
||||
msgid "%s -> Unknown encoding"
|
||||
msgstr "%s -> Tuntematon koodaus"
|
||||
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "%s => missing from all servers, discarding"
|
||||
msgstr "%s => puuttuu kaikilta palvelimilta, hylätään"
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Invalid NZB file %s, skipping (reason=%s, line=%s)"
|
||||
@@ -3152,25 +3158,12 @@ msgstr "Luo uusi avain"
|
||||
msgid "API Key QR Code"
|
||||
msgstr "API avaimen QR-koodi"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "List of local network ranges"
|
||||
msgstr "Lista paikallisista verkko-osoitealueista"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid ""
|
||||
"All local network addresses start with these prefixes (often \"192.168.1.\")"
|
||||
msgstr ""
|
||||
"Kaikki paikalliset verkko-osoitteet alkavat näillä etuliitteillä (yleensä "
|
||||
"\"192.168.1.\")"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "External internet access"
|
||||
msgstr "Ulkoinen ohjelman käyttö"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid ""
|
||||
"You can set access rights for systems outside your local network. Requires "
|
||||
"List of local network ranges to be defined."
|
||||
msgid "You can set access rights for systems outside your local network."
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
@@ -3492,19 +3485,26 @@ msgid "Action when unwanted extension detected"
|
||||
msgstr "Toiminto kun havaitaan ei toivottu tiedostopääte"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Action when an unwanted extension is detected in RAR files"
|
||||
msgstr "Toiminto kun ei toivottu tiedostopääte havaitaan RAR arkistossa"
|
||||
msgid "Action when an unwanted extension is detected"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Unwanted extensions"
|
||||
msgstr "Ei toivotut tiedostopäätteet"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid ""
|
||||
"List all unwanted extensions. For example: <b>exe</b> or <b>exe, com</b>"
|
||||
msgid "Blacklist"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Whitelist"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid ""
|
||||
"Select a mode and list all (un)wanted extensions. For example: <b>exe</b> or"
|
||||
" <b>exe, com</b>"
|
||||
msgstr ""
|
||||
"Lista ei toivotuista tiedostopäätteistä. Esimerkiksi: <b>exe</b> tai <b>exe,"
|
||||
" com</b>"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Enable SFV-based checks"
|
||||
@@ -4053,6 +4053,16 @@ msgstr "Lue syöte"
|
||||
msgid "Force Download"
|
||||
msgstr "Pakota lataus"
|
||||
|
||||
#. Config->RSS edit button
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Edit"
|
||||
msgstr ""
|
||||
|
||||
#. Config->RSS when will be the next RSS scan
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Next scan at"
|
||||
msgstr ""
|
||||
|
||||
#. Config->RSS table column header
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Filter"
|
||||
@@ -4843,6 +4853,10 @@ msgstr "Piilota/näytä valmistuneet tiedostot"
|
||||
msgid "View Script Log"
|
||||
msgstr "Näytä skriptien loki"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Renaming the job will abort Direct Unpack."
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid ""
|
||||
"LocalStorage (cookies) are disabled in your browser, interface settings will"
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-3.2.0-develop\n"
|
||||
"Project-Id-Version: SABnzbd-3.3.0-develop\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:49+0000\n"
|
||||
"Last-Translator: Fred L <88com88@gmail.com>, 2021\n"
|
||||
"Language-Team: French (https://www.transifex.com/sabnzbd/teams/111101/fr/)\n"
|
||||
@@ -630,6 +630,15 @@ msgstr "Échec lors de la création de (%s)"
|
||||
msgid "Failed moving %s to %s"
|
||||
msgstr "Échec lors du déplacement de %s vers %s"
|
||||
|
||||
#. Error message
|
||||
#: sabnzbd/filesystem.py
|
||||
msgid "Blocked attempt to create directory %s"
|
||||
msgstr "Tentative bloquée de création du répertoire %s"
|
||||
|
||||
#: sabnzbd/interface.py
|
||||
msgid "Refused connection from:"
|
||||
msgstr "Connexion refusée de:"
|
||||
|
||||
#: sabnzbd/interface.py
|
||||
msgid "Refused connection with hostname \"%s\" from:"
|
||||
msgstr "Connexion refusée avec le nom d'hôte \"%s\" à partir de :"
|
||||
@@ -671,6 +680,7 @@ msgstr ""
|
||||
msgid "Authentication failed, check username/password."
|
||||
msgstr "Echec d'authentification, vérifiez les identifiant/mot de passe."
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/interface.py
|
||||
msgid "Unsuccessful login attempt from %s"
|
||||
msgstr "Echec de la tentative de connexion de %s"
|
||||
@@ -1227,10 +1237,6 @@ msgstr "NZB ajouté à la file d'attente"
|
||||
msgid "%s -> Unknown encoding"
|
||||
msgstr "%s -> Encodage inconnu"
|
||||
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "%s => missing from all servers, discarding"
|
||||
msgstr "%s => absent de tous les serveurs, rejeté"
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Invalid NZB file %s, skipping (reason=%s, line=%s)"
|
||||
@@ -3234,28 +3240,15 @@ msgstr "Générer une nouvelle clé"
|
||||
msgid "API Key QR Code"
|
||||
msgstr "Clé API code QR"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "List of local network ranges"
|
||||
msgstr "Liste des plages de réseau local"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid ""
|
||||
"All local network addresses start with these prefixes (often \"192.168.1.\")"
|
||||
msgstr ""
|
||||
"Toutes les adresses de réseau local commencent par ces préfixes (souvent "
|
||||
"\"192.168.1.\" )"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "External internet access"
|
||||
msgstr "Accès Internet externe"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid ""
|
||||
"You can set access rights for systems outside your local network. Requires "
|
||||
"List of local network ranges to be defined."
|
||||
msgid "You can set access rights for systems outside your local network."
|
||||
msgstr ""
|
||||
"Vous pouvez définir les droits d'accès pour les systèmes en dehors de votre "
|
||||
"réseau local. Requiert la liste des plages de réseaux locaux à définir."
|
||||
"Vous pouvez définir des droits d'accès pour les systèmes en dehors de votre "
|
||||
"réseau local."
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "No access"
|
||||
@@ -3594,19 +3587,28 @@ msgid "Action when unwanted extension detected"
|
||||
msgstr "Action si une extension indésirable est détecté"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Action when an unwanted extension is detected in RAR files"
|
||||
msgstr "Action si une extension indésirable est détecté dans les fichiers RAR"
|
||||
msgid "Action when an unwanted extension is detected"
|
||||
msgstr "Action lorsqu'une extension indésirable est détectée"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Unwanted extensions"
|
||||
msgstr "Extensions indésirables"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Blacklist"
|
||||
msgstr "Liste noire"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Whitelist"
|
||||
msgstr "Liste blanche"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid ""
|
||||
"List all unwanted extensions. For example: <b>exe</b> or <b>exe, com</b>"
|
||||
"Select a mode and list all (un)wanted extensions. For example: <b>exe</b> or"
|
||||
" <b>exe, com</b>"
|
||||
msgstr ""
|
||||
"Afficher toutes les extensions indésirables. Par exemple : <b>exe</b> or "
|
||||
"<b>exe, com</b>"
|
||||
"Sélectionnez un mode et listez toutes les extensions (non) souhaitées. Par "
|
||||
"exemple: <b>exe</b> ou <b>exe, com</b>"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Enable SFV-based checks"
|
||||
@@ -4182,6 +4184,16 @@ msgstr "Lire le flux RSS"
|
||||
msgid "Force Download"
|
||||
msgstr "Forcer le téléchargement"
|
||||
|
||||
#. Config->RSS edit button
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Edit"
|
||||
msgstr "Modifier"
|
||||
|
||||
#. Config->RSS when will be the next RSS scan
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Next scan at"
|
||||
msgstr "Prochain scan à"
|
||||
|
||||
#. Config->RSS table column header
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Filter"
|
||||
@@ -4978,6 +4990,10 @@ msgstr "Afficher/masquer les fichiers terminés"
|
||||
msgid "View Script Log"
|
||||
msgstr "Afficher le journal des scripts"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Renaming the job will abort Direct Unpack."
|
||||
msgstr "Renommer la tâche annulera la Décompression Directe."
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid ""
|
||||
"LocalStorage (cookies) are disabled in your browser, interface settings will"
|
||||
|
||||
1076
po/main/he.po
1076
po/main/he.po
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-3.2.0-develop\n"
|
||||
"Project-Id-Version: SABnzbd-3.3.0-develop\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:49+0000\n"
|
||||
"Last-Translator: Safihre <safihre@sabnzbd.org>, 2020\n"
|
||||
"Language-Team: Norwegian Bokmål (https://www.transifex.com/sabnzbd/teams/111101/nb/)\n"
|
||||
@@ -599,6 +599,15 @@ msgstr "Opprettelse av (%s) mislyktes"
|
||||
msgid "Failed moving %s to %s"
|
||||
msgstr "Kunne ikke flytte %s til %s"
|
||||
|
||||
#. Error message
|
||||
#: sabnzbd/filesystem.py
|
||||
msgid "Blocked attempt to create directory %s"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/interface.py
|
||||
msgid "Refused connection from:"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/interface.py
|
||||
msgid "Refused connection with hostname \"%s\" from:"
|
||||
msgstr ""
|
||||
@@ -640,6 +649,7 @@ msgstr ""
|
||||
msgid "Authentication failed, check username/password."
|
||||
msgstr "Godkjenning mislyktes, kontroller brukernavn og passord."
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/interface.py
|
||||
msgid "Unsuccessful login attempt from %s"
|
||||
msgstr "Mislykket påloggingsforsøk fra %s"
|
||||
@@ -1177,10 +1187,6 @@ msgstr "NZB er lagt til i køen"
|
||||
msgid "%s -> Unknown encoding"
|
||||
msgstr "%s -> Ukjent koding"
|
||||
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "%s => missing from all servers, discarding"
|
||||
msgstr "%s => mangler på alle servere, fjerner"
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Invalid NZB file %s, skipping (reason=%s, line=%s)"
|
||||
@@ -3140,24 +3146,12 @@ msgstr "Generer Ny Nøkkel"
|
||||
msgid "API Key QR Code"
|
||||
msgstr "API-nøkkel QR-kode"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "List of local network ranges"
|
||||
msgstr "Liste over lokale nettverksområder"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid ""
|
||||
"All local network addresses start with these prefixes (often \"192.168.1.\")"
|
||||
msgstr ""
|
||||
"Alle lokale nettverksadresser starter med disse prefix (ofte \"192.168.1.\")"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "External internet access"
|
||||
msgstr "Ekstern internettilgang"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid ""
|
||||
"You can set access rights for systems outside your local network. Requires "
|
||||
"List of local network ranges to be defined."
|
||||
msgid "You can set access rights for systems outside your local network."
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
@@ -3474,19 +3468,26 @@ msgid "Action when unwanted extension detected"
|
||||
msgstr "Handling når uønsket filtype oppdaget"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Action when an unwanted extension is detected in RAR files"
|
||||
msgstr "Handling når uønsket filtype blir oppdaget i RAR filer."
|
||||
msgid "Action when an unwanted extension is detected"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Unwanted extensions"
|
||||
msgstr "Uønsket filtyper"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid ""
|
||||
"List all unwanted extensions. For example: <b>exe</b> or <b>exe, com</b>"
|
||||
msgid "Blacklist"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Whitelist"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid ""
|
||||
"Select a mode and list all (un)wanted extensions. For example: <b>exe</b> or"
|
||||
" <b>exe, com</b>"
|
||||
msgstr ""
|
||||
"Skriv alle uønskende filtyper. For eksempel: <b>exe</b> eller <b>exe, "
|
||||
"com</b>"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Enable SFV-based checks"
|
||||
@@ -4029,6 +4030,16 @@ msgstr "Les kilde"
|
||||
msgid "Force Download"
|
||||
msgstr "Tving nedlasting"
|
||||
|
||||
#. Config->RSS edit button
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Edit"
|
||||
msgstr ""
|
||||
|
||||
#. Config->RSS when will be the next RSS scan
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Next scan at"
|
||||
msgstr ""
|
||||
|
||||
#. Config->RSS table column header
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Filter"
|
||||
@@ -4814,6 +4825,10 @@ msgstr "Skjul/vis fullførte filer"
|
||||
msgid "View Script Log"
|
||||
msgstr "Se skriptlogg"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Renaming the job will abort Direct Unpack."
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid ""
|
||||
"LocalStorage (cookies) are disabled in your browser, interface settings will"
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-3.2.0-develop\n"
|
||||
"Project-Id-Version: SABnzbd-3.3.0-develop\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:49+0000\n"
|
||||
"Last-Translator: Safihre <safihre@sabnzbd.org>, 2021\n"
|
||||
"Language-Team: Dutch (https://www.transifex.com/sabnzbd/teams/111101/nl/)\n"
|
||||
@@ -329,7 +329,7 @@ msgstr "Serveradres verplicht"
|
||||
|
||||
#: sabnzbd/cfg.py
|
||||
msgid "%s is not a valid script"
|
||||
msgstr ""
|
||||
msgstr "%s is geen geldig script."
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/config.py
|
||||
@@ -509,12 +509,12 @@ msgstr "Afsluiten"
|
||||
#. Warning message
|
||||
#: sabnzbd/downloader.py
|
||||
msgid "Server %s is expiring in %s day(s)"
|
||||
msgstr ""
|
||||
msgstr "Server %s verloopt over %s dag(en)."
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/downloader.py
|
||||
msgid "Server %s has used the specified quota"
|
||||
msgstr ""
|
||||
msgstr "Het beschikbare quotum voor server %s is verbruikt. "
|
||||
|
||||
#: sabnzbd/emailer.py
|
||||
msgid "Failed to connect to mail server"
|
||||
@@ -619,6 +619,15 @@ msgstr "Aanmaken (%s) mislukt"
|
||||
msgid "Failed moving %s to %s"
|
||||
msgstr "Verplaatsen van %s naar %s mislukt"
|
||||
|
||||
#. Error message
|
||||
#: sabnzbd/filesystem.py
|
||||
msgid "Blocked attempt to create directory %s"
|
||||
msgstr "Poging om map %s aan te maken geblokkeerd"
|
||||
|
||||
#: sabnzbd/interface.py
|
||||
msgid "Refused connection from:"
|
||||
msgstr "Verbinding geweigerd van: "
|
||||
|
||||
#: sabnzbd/interface.py
|
||||
msgid "Refused connection with hostname \"%s\" from:"
|
||||
msgstr "Verbinding met hostnaam \"%s\" geweigerd van:"
|
||||
@@ -660,6 +669,7 @@ msgstr ""
|
||||
msgid "Authentication failed, check username/password."
|
||||
msgstr "Inloggen mislukt, controleer gebruikersnaam en wachtwoord."
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/interface.py
|
||||
msgid "Unsuccessful login attempt from %s"
|
||||
msgstr "Mislukte login progin bij %s"
|
||||
@@ -1209,10 +1219,6 @@ msgstr "Download aan wachtrij toegevoegd"
|
||||
msgid "%s -> Unknown encoding"
|
||||
msgstr "%s -> Onbekende codering"
|
||||
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "%s => missing from all servers, discarding"
|
||||
msgstr "%s => ontbreekt op alle servers, overslaan"
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Invalid NZB file %s, skipping (reason=%s, line=%s)"
|
||||
@@ -1660,7 +1666,7 @@ msgstr "RAR bestanden zijn niet verifieerbaar"
|
||||
|
||||
#: sabnzbd/postproc.py
|
||||
msgid "Trying RAR renamer"
|
||||
msgstr ""
|
||||
msgstr "RAR-hernoeming wordt geprobeerd"
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/postproc.py
|
||||
@@ -3204,28 +3210,14 @@ msgstr "Maak een nieuwe sleutel"
|
||||
msgid "API Key QR Code"
|
||||
msgstr "QR-code van de API-sleutel"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "List of local network ranges"
|
||||
msgstr "Lijst van lokale netwerk bereiken"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid ""
|
||||
"All local network addresses start with these prefixes (often \"192.168.1.\")"
|
||||
msgstr ""
|
||||
"Alle lokale netwerk adressen die beginnen met deze reeks (vaak "
|
||||
"\"192.168.1.\")"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "External internet access"
|
||||
msgstr "Externe toegang"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid ""
|
||||
"You can set access rights for systems outside your local network. Requires "
|
||||
"List of local network ranges to be defined."
|
||||
msgid "You can set access rights for systems outside your local network."
|
||||
msgstr ""
|
||||
"Je kunt toegangsrechten instellen voor systemen buiten je lokale netwerk. "
|
||||
"Hiervoor geef je een lijst van netwerk-bereiken in."
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "No access"
|
||||
@@ -3551,20 +3543,28 @@ msgid "Action when unwanted extension detected"
|
||||
msgstr "Actie bij ontdekken van ongewenste extensie"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Action when an unwanted extension is detected in RAR files"
|
||||
msgstr ""
|
||||
"Actie wanneer een ongewenste extensie wordt gevonden in een RAR-bestand"
|
||||
msgid "Action when an unwanted extension is detected"
|
||||
msgstr "Actie bij ontdekken van een ongewenste extensie"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Unwanted extensions"
|
||||
msgstr "Ongewenste extensies"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Blacklist"
|
||||
msgstr "Blacklist"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Whitelist"
|
||||
msgstr "Whitelist"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid ""
|
||||
"List all unwanted extensions. For example: <b>exe</b> or <b>exe, com</b>"
|
||||
"Select a mode and list all (un)wanted extensions. For example: <b>exe</b> or"
|
||||
" <b>exe, com</b>"
|
||||
msgstr ""
|
||||
"Lijst van alle ongewenste extensies. Voorbeeld: <b>exe</b> or <b>exe, "
|
||||
"com</b>"
|
||||
"Kies een stand en voer een lijst van alle (on)gewenste extensies in. "
|
||||
"Voorbeeld: <b>exe</b> or <b>exe, com</b>"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Enable SFV-based checks"
|
||||
@@ -3962,11 +3962,11 @@ msgstr "Tijdslimiet"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Account expiration date"
|
||||
msgstr ""
|
||||
msgstr "Verloopdatum"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Warn 5 days in advance of account expiration date."
|
||||
msgstr ""
|
||||
msgstr "Ontvang 5 dagen voor de verloopdatum een waarschuwing."
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid ""
|
||||
@@ -3974,6 +3974,10 @@ msgid ""
|
||||
"optionally follow with K,M,G.<br />Warn when it reaches 0, checked every few"
|
||||
" minutes."
|
||||
msgstr ""
|
||||
"Quotum voor dit account, wordt geteld vanaf het moment dat het voor het "
|
||||
"eerst ingesteld wordt. In bytes, in K,M,G notatie.<br />Er wordt een "
|
||||
"waarschuwing gegeven als het quotum bereikt is, dit wordt elke paar minuten "
|
||||
"gecontroleerd."
|
||||
|
||||
#. Server's retention time in days
|
||||
#: sabnzbd/skintext.py
|
||||
@@ -4131,6 +4135,16 @@ msgstr "Uitlezen"
|
||||
msgid "Force Download"
|
||||
msgstr "Forceer download"
|
||||
|
||||
#. Config->RSS edit button
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Edit"
|
||||
msgstr "Wijzigen"
|
||||
|
||||
#. Config->RSS when will be the next RSS scan
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Next scan at"
|
||||
msgstr "Wordt uitgevoerd om"
|
||||
|
||||
#. Config->RSS table column header
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Filter"
|
||||
@@ -4923,6 +4937,10 @@ msgstr "Toon/verberg voltooide bestanden"
|
||||
msgid "View Script Log"
|
||||
msgstr "Toon Script resultaat"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Renaming the job will abort Direct Unpack."
|
||||
msgstr "Als je de naam wijzigt zal het Direct Uitpakken gestopt worden."
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid ""
|
||||
"LocalStorage (cookies) are disabled in your browser, interface settings will"
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-3.2.0-develop\n"
|
||||
"Project-Id-Version: SABnzbd-3.3.0-develop\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:49+0000\n"
|
||||
"Last-Translator: Safihre <safihre@sabnzbd.org>, 2020\n"
|
||||
"Language-Team: Polish (https://www.transifex.com/sabnzbd/teams/111101/pl/)\n"
|
||||
@@ -598,6 +598,15 @@ msgstr "Nie udało się utworzyć (%s)"
|
||||
msgid "Failed moving %s to %s"
|
||||
msgstr "Nie udało się przenieść %s do %s"
|
||||
|
||||
#. Error message
|
||||
#: sabnzbd/filesystem.py
|
||||
msgid "Blocked attempt to create directory %s"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/interface.py
|
||||
msgid "Refused connection from:"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/interface.py
|
||||
msgid "Refused connection with hostname \"%s\" from:"
|
||||
msgstr ""
|
||||
@@ -639,6 +648,7 @@ msgstr ""
|
||||
msgid "Authentication failed, check username/password."
|
||||
msgstr "Błąd połączenia, sprawdź nazwę użytkownika i hasło."
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/interface.py
|
||||
msgid "Unsuccessful login attempt from %s"
|
||||
msgstr ""
|
||||
@@ -1178,10 +1188,6 @@ msgstr "NZB dodany do kolejki"
|
||||
msgid "%s -> Unknown encoding"
|
||||
msgstr "%s -> Nieznane kodowanie"
|
||||
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "%s => missing from all servers, discarding"
|
||||
msgstr "%s => nie znaleziono na żadnym serwerze, porzucam"
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Invalid NZB file %s, skipping (reason=%s, line=%s)"
|
||||
@@ -3143,25 +3149,12 @@ msgstr "Utwórz nowy klucz"
|
||||
msgid "API Key QR Code"
|
||||
msgstr "Kod QR klucza API"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "List of local network ranges"
|
||||
msgstr "Lista zakresów sieci lokalnych"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid ""
|
||||
"All local network addresses start with these prefixes (often \"192.168.1.\")"
|
||||
msgstr ""
|
||||
"Wszystkie lokalne adresy sieciowe zaczynają się od tych prefiksów (często "
|
||||
"\"192.168.1.\")"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "External internet access"
|
||||
msgstr "Dostęp z zewnątrz"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid ""
|
||||
"You can set access rights for systems outside your local network. Requires "
|
||||
"List of local network ranges to be defined."
|
||||
msgid "You can set access rights for systems outside your local network."
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
@@ -3480,20 +3473,26 @@ msgid "Action when unwanted extension detected"
|
||||
msgstr "Działanie dla niepożądanych rozszerzeń"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Action when an unwanted extension is detected in RAR files"
|
||||
msgid "Action when an unwanted extension is detected"
|
||||
msgstr ""
|
||||
"Działanie, które zostanie podjęte po wykryciu w pliku RAR niepożądanego "
|
||||
"rozszerzenia"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Unwanted extensions"
|
||||
msgstr "Niepożądane rozszerzenia"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid ""
|
||||
"List all unwanted extensions. For example: <b>exe</b> or <b>exe, com</b>"
|
||||
msgid "Blacklist"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Whitelist"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid ""
|
||||
"Select a mode and list all (un)wanted extensions. For example: <b>exe</b> or"
|
||||
" <b>exe, com</b>"
|
||||
msgstr ""
|
||||
"Lista niepożądanych rozszerzeń. Przykład: <b>exe</b> lub <b>exe, com</b>"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Enable SFV-based checks"
|
||||
@@ -4039,6 +4038,16 @@ msgstr "Pobierz kanał"
|
||||
msgid "Force Download"
|
||||
msgstr "Wymuś pobranie"
|
||||
|
||||
#. Config->RSS edit button
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Edit"
|
||||
msgstr ""
|
||||
|
||||
#. Config->RSS when will be the next RSS scan
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Next scan at"
|
||||
msgstr ""
|
||||
|
||||
#. Config->RSS table column header
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Filter"
|
||||
@@ -4824,6 +4833,10 @@ msgstr "Pokaż/ukryj ukończone pliki"
|
||||
msgid "View Script Log"
|
||||
msgstr "Zobacz log skryptu"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Renaming the job will abort Direct Unpack."
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid ""
|
||||
"LocalStorage (cookies) are disabled in your browser, interface settings will"
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-3.2.0-develop\n"
|
||||
"Project-Id-Version: SABnzbd-3.3.0-develop\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:49+0000\n"
|
||||
"Last-Translator: Safihre <safihre@sabnzbd.org>, 2020\n"
|
||||
"Language-Team: Portuguese (Brazil) (https://www.transifex.com/sabnzbd/teams/111101/pt_BR/)\n"
|
||||
@@ -602,6 +602,15 @@ msgstr "Falha ao criar (%s)"
|
||||
msgid "Failed moving %s to %s"
|
||||
msgstr "Falha ao mover %s para %s"
|
||||
|
||||
#. Error message
|
||||
#: sabnzbd/filesystem.py
|
||||
msgid "Blocked attempt to create directory %s"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/interface.py
|
||||
msgid "Refused connection from:"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/interface.py
|
||||
msgid "Refused connection with hostname \"%s\" from:"
|
||||
msgstr ""
|
||||
@@ -643,6 +652,7 @@ msgstr ""
|
||||
msgid "Authentication failed, check username/password."
|
||||
msgstr "Falha de autenticação, verifique usuário / senha."
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/interface.py
|
||||
msgid "Unsuccessful login attempt from %s"
|
||||
msgstr ""
|
||||
@@ -1179,10 +1189,6 @@ msgstr "NZB adicionado à fila"
|
||||
msgid "%s -> Unknown encoding"
|
||||
msgstr "%s -> Codificação desconhecida"
|
||||
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "%s => missing from all servers, discarding"
|
||||
msgstr "%s => faltando em todos os servidores. Descartando"
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Invalid NZB file %s, skipping (reason=%s, line=%s)"
|
||||
@@ -3148,25 +3154,12 @@ msgstr "Gerar Nova Chave"
|
||||
msgid "API Key QR Code"
|
||||
msgstr "API Key QR Code"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "List of local network ranges"
|
||||
msgstr "Lista de intervalos de rede local"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid ""
|
||||
"All local network addresses start with these prefixes (often \"192.168.1.\")"
|
||||
msgstr ""
|
||||
"Todas os endereços da rede local começam com esse prefixo (geralmente "
|
||||
"\"192.168.1.\")"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "External internet access"
|
||||
msgstr "Acesso externo da Internet"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid ""
|
||||
"You can set access rights for systems outside your local network. Requires "
|
||||
"List of local network ranges to be defined."
|
||||
msgid "You can set access rights for systems outside your local network."
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
@@ -3484,19 +3477,26 @@ msgid "Action when unwanted extension detected"
|
||||
msgstr "Ação quando extensão indesejada for detectada"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Action when an unwanted extension is detected in RAR files"
|
||||
msgstr "Ação quando uma extensão indesejada é detectada em arquivos RAR"
|
||||
msgid "Action when an unwanted extension is detected"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Unwanted extensions"
|
||||
msgstr "Extensões indesejadas"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid ""
|
||||
"List all unwanted extensions. For example: <b>exe</b> or <b>exe, com</b>"
|
||||
msgid "Blacklist"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Whitelist"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid ""
|
||||
"Select a mode and list all (un)wanted extensions. For example: <b>exe</b> or"
|
||||
" <b>exe, com</b>"
|
||||
msgstr ""
|
||||
"Lista todas as extensões indesejadas. Por exemplo: <b>exe</b> ou <b>exe, "
|
||||
"com</b>"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Enable SFV-based checks"
|
||||
@@ -4042,6 +4042,16 @@ msgstr "Ler Feed"
|
||||
msgid "Force Download"
|
||||
msgstr "Forçar Download"
|
||||
|
||||
#. Config->RSS edit button
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Edit"
|
||||
msgstr ""
|
||||
|
||||
#. Config->RSS when will be the next RSS scan
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Next scan at"
|
||||
msgstr ""
|
||||
|
||||
#. Config->RSS table column header
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Filter"
|
||||
@@ -4827,6 +4837,10 @@ msgstr "Esconder/Exibir arquivos completos"
|
||||
msgid "View Script Log"
|
||||
msgstr "Exibir Log do Script"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Renaming the job will abort Direct Unpack."
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid ""
|
||||
"LocalStorage (cookies) are disabled in your browser, interface settings will"
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-3.2.0-develop\n"
|
||||
"Project-Id-Version: SABnzbd-3.3.0-develop\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:49+0000\n"
|
||||
"Last-Translator: Eduard Baniceru <war4peace@gmail.com>, 2021\n"
|
||||
"Language-Team: Romanian (https://www.transifex.com/sabnzbd/teams/111101/ro/)\n"
|
||||
@@ -616,6 +616,15 @@ msgstr "Facere nereuşită (%s)"
|
||||
msgid "Failed moving %s to %s"
|
||||
msgstr "Mutare %s în %s nereuşită"
|
||||
|
||||
#. Error message
|
||||
#: sabnzbd/filesystem.py
|
||||
msgid "Blocked attempt to create directory %s"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/interface.py
|
||||
msgid "Refused connection from:"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/interface.py
|
||||
msgid "Refused connection with hostname \"%s\" from:"
|
||||
msgstr "Conectare refuzată cu gazda „%s” de la:"
|
||||
@@ -657,6 +666,7 @@ msgstr ""
|
||||
msgid "Authentication failed, check username/password."
|
||||
msgstr "Autentificare nereuşită, verifică nume utilizator/parolă."
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/interface.py
|
||||
msgid "Unsuccessful login attempt from %s"
|
||||
msgstr "Încercare de conectare nereușită de la %s"
|
||||
@@ -1205,10 +1215,6 @@ msgstr "NZB adăugat în coadă"
|
||||
msgid "%s -> Unknown encoding"
|
||||
msgstr "%s -> Codificare Necunoscută"
|
||||
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "%s => missing from all servers, discarding"
|
||||
msgstr "%s => lipsă de pe toate serverele, ignorare"
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Invalid NZB file %s, skipping (reason=%s, line=%s)"
|
||||
@@ -3175,23 +3181,12 @@ msgstr "Generează o Cheie Nouă"
|
||||
msgid "API Key QR Code"
|
||||
msgstr "Cheie API sau Cod QR"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "List of local network ranges"
|
||||
msgstr "Listă de rețele locale"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid ""
|
||||
"All local network addresses start with these prefixes (often \"192.168.1.\")"
|
||||
msgstr "Toate rețelele locale încep cu acest prefixe (de regulă \"192.168.1.\")"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "External internet access"
|
||||
msgstr "Acces extern la internet"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid ""
|
||||
"You can set access rights for systems outside your local network. Requires "
|
||||
"List of local network ranges to be defined."
|
||||
msgid "You can set access rights for systems outside your local network."
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
@@ -3508,19 +3503,26 @@ msgid "Action when unwanted extension detected"
|
||||
msgstr "Acțiune când se detectează o extensie nedorită"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Action when an unwanted extension is detected in RAR files"
|
||||
msgstr "Acțiune când se detectează extensie nedorită într-un fișier RAR"
|
||||
msgid "Action when an unwanted extension is detected"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Unwanted extensions"
|
||||
msgstr "Extensii nedorite"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid ""
|
||||
"List all unwanted extensions. For example: <b>exe</b> or <b>exe, com</b>"
|
||||
msgid "Blacklist"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Whitelist"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid ""
|
||||
"Select a mode and list all (un)wanted extensions. For example: <b>exe</b> or"
|
||||
" <b>exe, com</b>"
|
||||
msgstr ""
|
||||
"Listă cu toate extensiile nedorite. De exemplu: <b>exe</b> or <b>exe, "
|
||||
"com</b>"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Enable SFV-based checks"
|
||||
@@ -4068,6 +4070,16 @@ msgstr "Citeşte Flux"
|
||||
msgid "Force Download"
|
||||
msgstr "Descărcare Forţată"
|
||||
|
||||
#. Config->RSS edit button
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Edit"
|
||||
msgstr ""
|
||||
|
||||
#. Config->RSS when will be the next RSS scan
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Next scan at"
|
||||
msgstr ""
|
||||
|
||||
#. Config->RSS table column header
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Filter"
|
||||
@@ -4851,6 +4863,10 @@ msgstr "Ascunde/arată fișierele finalizate"
|
||||
msgid "View Script Log"
|
||||
msgstr "Vezi Jurnal Script"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Renaming the job will abort Direct Unpack."
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid ""
|
||||
"LocalStorage (cookies) are disabled in your browser, interface settings will"
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-3.2.0-develop\n"
|
||||
"Project-Id-Version: SABnzbd-3.3.0-develop\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:49+0000\n"
|
||||
"Last-Translator: Safihre <safihre@sabnzbd.org>, 2020\n"
|
||||
"Language-Team: Russian (https://www.transifex.com/sabnzbd/teams/111101/ru/)\n"
|
||||
@@ -598,6 +598,15 @@ msgstr "Не удалось создать (%s)"
|
||||
msgid "Failed moving %s to %s"
|
||||
msgstr "Не удалось переместить %s в %s"
|
||||
|
||||
#. Error message
|
||||
#: sabnzbd/filesystem.py
|
||||
msgid "Blocked attempt to create directory %s"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/interface.py
|
||||
msgid "Refused connection from:"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/interface.py
|
||||
msgid "Refused connection with hostname \"%s\" from:"
|
||||
msgstr ""
|
||||
@@ -639,6 +648,7 @@ msgstr ""
|
||||
msgid "Authentication failed, check username/password."
|
||||
msgstr "Ошибка проверки подлинности. Проверьте имя и пароль."
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/interface.py
|
||||
msgid "Unsuccessful login attempt from %s"
|
||||
msgstr ""
|
||||
@@ -1179,10 +1189,6 @@ msgstr "NZB-файл добавлен в очередь"
|
||||
msgid "%s -> Unknown encoding"
|
||||
msgstr "%s -> неизвестная кодировка"
|
||||
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "%s => missing from all servers, discarding"
|
||||
msgstr "%s => отсутствует на всех серверах, отброшен"
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Invalid NZB file %s, skipping (reason=%s, line=%s)"
|
||||
@@ -3141,23 +3147,12 @@ msgstr "Создать новый ключ"
|
||||
msgid "API Key QR Code"
|
||||
msgstr "QR-код ключа API"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "List of local network ranges"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid ""
|
||||
"All local network addresses start with these prefixes (often \"192.168.1.\")"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "External internet access"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid ""
|
||||
"You can set access rights for systems outside your local network. Requires "
|
||||
"List of local network ranges to be defined."
|
||||
msgid "You can set access rights for systems outside your local network."
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
@@ -3476,16 +3471,25 @@ msgid "Action when unwanted extension detected"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Action when an unwanted extension is detected in RAR files"
|
||||
msgid "Action when an unwanted extension is detected"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Unwanted extensions"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Blacklist"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Whitelist"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid ""
|
||||
"List all unwanted extensions. For example: <b>exe</b> or <b>exe, com</b>"
|
||||
"Select a mode and list all (un)wanted extensions. For example: <b>exe</b> or"
|
||||
" <b>exe, com</b>"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
@@ -4027,6 +4031,16 @@ msgstr "Прочитать ленту"
|
||||
msgid "Force Download"
|
||||
msgstr "Загрузить принудительно"
|
||||
|
||||
#. Config->RSS edit button
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Edit"
|
||||
msgstr ""
|
||||
|
||||
#. Config->RSS when will be the next RSS scan
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Next scan at"
|
||||
msgstr ""
|
||||
|
||||
#. Config->RSS table column header
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Filter"
|
||||
@@ -4817,6 +4831,10 @@ msgstr ""
|
||||
msgid "View Script Log"
|
||||
msgstr "Просмотреть журнал сценария"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Renaming the job will abort Direct Unpack."
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid ""
|
||||
"LocalStorage (cookies) are disabled in your browser, interface settings will"
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-3.2.0-develop\n"
|
||||
"Project-Id-Version: SABnzbd-3.3.0-develop\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:49+0000\n"
|
||||
"Last-Translator: Safihre <safihre@sabnzbd.org>, 2020\n"
|
||||
"Language-Team: Serbian (https://www.transifex.com/sabnzbd/teams/111101/sr/)\n"
|
||||
@@ -597,6 +597,15 @@ msgstr "Neuspešno kreiranje (%s)"
|
||||
msgid "Failed moving %s to %s"
|
||||
msgstr "Neuspešno premeštanje %s u %s"
|
||||
|
||||
#. Error message
|
||||
#: sabnzbd/filesystem.py
|
||||
msgid "Blocked attempt to create directory %s"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/interface.py
|
||||
msgid "Refused connection from:"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/interface.py
|
||||
msgid "Refused connection with hostname \"%s\" from:"
|
||||
msgstr ""
|
||||
@@ -636,6 +645,7 @@ msgstr ""
|
||||
msgid "Authentication failed, check username/password."
|
||||
msgstr "Аутентификација погрешна, проверити име/лозинку."
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/interface.py
|
||||
msgid "Unsuccessful login attempt from %s"
|
||||
msgstr ""
|
||||
@@ -1173,10 +1183,6 @@ msgstr "NZB додат у ред"
|
||||
msgid "%s -> Unknown encoding"
|
||||
msgstr "%s -> Непознато енкодирање"
|
||||
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "%s => missing from all servers, discarding"
|
||||
msgstr "%s => фали на свим серверима, одбацивање"
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Invalid NZB file %s, skipping (reason=%s, line=%s)"
|
||||
@@ -3128,25 +3134,12 @@ msgstr "Генериши нов кључ"
|
||||
msgid "API Key QR Code"
|
||||
msgstr "QR Код АПИ кључа"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "List of local network ranges"
|
||||
msgstr "Lista lokalnih mrežnih raspona"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid ""
|
||||
"All local network addresses start with these prefixes (often \"192.168.1.\")"
|
||||
msgstr ""
|
||||
"Sve lokalne mrežne adrese počinju sa sledećim prefiksima (najčešće "
|
||||
"\"192.168.1.\")"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "External internet access"
|
||||
msgstr "Екстерни приступ интернету"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid ""
|
||||
"You can set access rights for systems outside your local network. Requires "
|
||||
"List of local network ranges to be defined."
|
||||
msgid "You can set access rights for systems outside your local network."
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
@@ -3464,18 +3457,26 @@ msgid "Action when unwanted extension detected"
|
||||
msgstr "Radnja kada je otkrivena neželjena ekstenzija"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Action when an unwanted extension is detected in RAR files"
|
||||
msgstr "Radnja kada je otkrivena neželjena ekstenzija u RAR datotekama"
|
||||
msgid "Action when an unwanted extension is detected"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Unwanted extensions"
|
||||
msgstr "Neželjene ekstenzije"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid ""
|
||||
"List all unwanted extensions. For example: <b>exe</b> or <b>exe, com</b>"
|
||||
msgid "Blacklist"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Whitelist"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid ""
|
||||
"Select a mode and list all (un)wanted extensions. For example: <b>exe</b> or"
|
||||
" <b>exe, com</b>"
|
||||
msgstr ""
|
||||
"Lista svih neželjenih ekstenzija. Na primer: <b>exe</b> or <b>exe, com</b>"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Enable SFV-based checks"
|
||||
@@ -4015,6 +4016,16 @@ msgstr "Читај фид"
|
||||
msgid "Force Download"
|
||||
msgstr "Натерај преузимање"
|
||||
|
||||
#. Config->RSS edit button
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Edit"
|
||||
msgstr ""
|
||||
|
||||
#. Config->RSS when will be the next RSS scan
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Next scan at"
|
||||
msgstr ""
|
||||
|
||||
#. Config->RSS table column header
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Filter"
|
||||
@@ -4799,6 +4810,10 @@ msgstr "Sakrij/prikaži sve završene datoteke"
|
||||
msgid "View Script Log"
|
||||
msgstr "Види извештај скрипта"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Renaming the job will abort Direct Unpack."
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid ""
|
||||
"LocalStorage (cookies) are disabled in your browser, interface settings will"
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-3.2.0-develop\n"
|
||||
"Project-Id-Version: SABnzbd-3.3.0-develop\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:49+0000\n"
|
||||
"Last-Translator: Safihre <safihre@sabnzbd.org>, 2020\n"
|
||||
"Language-Team: Swedish (https://www.transifex.com/sabnzbd/teams/111101/sv/)\n"
|
||||
@@ -597,6 +597,15 @@ msgstr "Skapande av (%s) misslyckades"
|
||||
msgid "Failed moving %s to %s"
|
||||
msgstr "Det gick inte att flyta %s till %s"
|
||||
|
||||
#. Error message
|
||||
#: sabnzbd/filesystem.py
|
||||
msgid "Blocked attempt to create directory %s"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/interface.py
|
||||
msgid "Refused connection from:"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/interface.py
|
||||
msgid "Refused connection with hostname \"%s\" from:"
|
||||
msgstr ""
|
||||
@@ -638,6 +647,7 @@ msgstr ""
|
||||
msgid "Authentication failed, check username/password."
|
||||
msgstr "Autentisering misslyckades, kontrollera användarnamn och lösenord."
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/interface.py
|
||||
msgid "Unsuccessful login attempt from %s"
|
||||
msgstr ""
|
||||
@@ -1177,10 +1187,6 @@ msgstr "NZB tillagd i kön"
|
||||
msgid "%s -> Unknown encoding"
|
||||
msgstr "%s -> Okänd kodning"
|
||||
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "%s => missing from all servers, discarding"
|
||||
msgstr "%s => saknas från alla servrar, kastar"
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Invalid NZB file %s, skipping (reason=%s, line=%s)"
|
||||
@@ -3139,25 +3145,12 @@ msgstr "Generera Ny Nyckel"
|
||||
msgid "API Key QR Code"
|
||||
msgstr "API- eller QR-kod"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "List of local network ranges"
|
||||
msgstr "Lista av lokala nätverksomfång"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid ""
|
||||
"All local network addresses start with these prefixes (often \"192.168.1.\")"
|
||||
msgstr ""
|
||||
"Alla lokala nätverksadresser startar med dessa prefixer (ofta "
|
||||
"\"192.168.1.\")"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "External internet access"
|
||||
msgstr "Extern internetåtkomst"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid ""
|
||||
"You can set access rights for systems outside your local network. Requires "
|
||||
"List of local network ranges to be defined."
|
||||
msgid "You can set access rights for systems outside your local network."
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
@@ -3473,18 +3466,26 @@ msgid "Action when unwanted extension detected"
|
||||
msgstr "Händelse när oönskad filändelse hittad"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Action when an unwanted extension is detected in RAR files"
|
||||
msgstr "Händelse när en oönskad filändelse är hittad i RAR-filer."
|
||||
msgid "Action when an unwanted extension is detected"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Unwanted extensions"
|
||||
msgstr "Oönskade filändelser"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid ""
|
||||
"List all unwanted extensions. For example: <b>exe</b> or <b>exe, com</b>"
|
||||
msgid "Blacklist"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Whitelist"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid ""
|
||||
"Select a mode and list all (un)wanted extensions. For example: <b>exe</b> or"
|
||||
" <b>exe, com</b>"
|
||||
msgstr ""
|
||||
"Lista alla oönskade filändelser. Till Exempel: <b>exe</b> or <b>exe, com</b>"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Enable SFV-based checks"
|
||||
@@ -4028,6 +4029,16 @@ msgstr "Läs flöde"
|
||||
msgid "Force Download"
|
||||
msgstr "Tvinga nedladdning"
|
||||
|
||||
#. Config->RSS edit button
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Edit"
|
||||
msgstr ""
|
||||
|
||||
#. Config->RSS when will be the next RSS scan
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Next scan at"
|
||||
msgstr ""
|
||||
|
||||
#. Config->RSS table column header
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Filter"
|
||||
@@ -4811,6 +4822,10 @@ msgstr "Visa/göm färdiga filer"
|
||||
msgid "View Script Log"
|
||||
msgstr "Visa skriptlogg"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Renaming the job will abort Direct Unpack."
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid ""
|
||||
"LocalStorage (cookies) are disabled in your browser, interface settings will"
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-3.2.0-develop\n"
|
||||
"Project-Id-Version: SABnzbd-3.3.0-develop\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:49+0000\n"
|
||||
"Last-Translator: Safihre <safihre@sabnzbd.org>, 2020\n"
|
||||
"Language-Team: Chinese (China) (https://www.transifex.com/sabnzbd/teams/111101/zh_CN/)\n"
|
||||
@@ -594,6 +594,15 @@ msgstr "创建失败 (%s)"
|
||||
msgid "Failed moving %s to %s"
|
||||
msgstr "将 %s 移动到 %s 失败"
|
||||
|
||||
#. Error message
|
||||
#: sabnzbd/filesystem.py
|
||||
msgid "Blocked attempt to create directory %s"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/interface.py
|
||||
msgid "Refused connection from:"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/interface.py
|
||||
msgid "Refused connection with hostname \"%s\" from:"
|
||||
msgstr ""
|
||||
@@ -629,6 +638,7 @@ msgstr "缺身份认证信息,请在第三方程序中输入“配置”->“
|
||||
msgid "Authentication failed, check username/password."
|
||||
msgstr "身份认证失败,请检查用户名/密码。"
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/interface.py
|
||||
msgid "Unsuccessful login attempt from %s"
|
||||
msgstr "%s 中有失败的登陆请求"
|
||||
@@ -1163,10 +1173,6 @@ msgstr "NZB 已添加到队列"
|
||||
msgid "%s -> Unknown encoding"
|
||||
msgstr "%s -> 未知编码"
|
||||
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "%s => missing from all servers, discarding"
|
||||
msgstr "%s => 所有服务器均缺失,正在舍弃"
|
||||
|
||||
#. Warning message
|
||||
#: sabnzbd/nzbstuff.py
|
||||
msgid "Invalid NZB file %s, skipping (reason=%s, line=%s)"
|
||||
@@ -3107,24 +3113,13 @@ msgstr "生成新的 Key"
|
||||
msgid "API Key QR Code"
|
||||
msgstr "API Key QR 码"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "List of local network ranges"
|
||||
msgstr "本地网段列表"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid ""
|
||||
"All local network addresses start with these prefixes (often \"192.168.1.\")"
|
||||
msgstr "本地网络地址以这些前缀开头 (通常为“192.168.1.”)"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "External internet access"
|
||||
msgstr "外部互联网访问"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid ""
|
||||
"You can set access rights for systems outside your local network. Requires "
|
||||
"List of local network ranges to be defined."
|
||||
msgstr "您可以设定非本地网络的访问权限。要求定义本地网络列表。"
|
||||
msgid "You can set access rights for systems outside your local network."
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "No access"
|
||||
@@ -3420,17 +3415,26 @@ msgid "Action when unwanted extension detected"
|
||||
msgstr "侦测到不需要的扩展名时的操作"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Action when an unwanted extension is detected in RAR files"
|
||||
msgstr "RAR 文件中侦测到不需要的扩展名时的操作"
|
||||
msgid "Action when an unwanted extension is detected"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Unwanted extensions"
|
||||
msgstr "不需要的扩展名"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Blacklist"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Whitelist"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid ""
|
||||
"List all unwanted extensions. For example: <b>exe</b> or <b>exe, com</b>"
|
||||
msgstr "所有不需要扩展名的列表。例如: <b>exe</b> 或 <b>exe, com</b>"
|
||||
"Select a mode and list all (un)wanted extensions. For example: <b>exe</b> or"
|
||||
" <b>exe, com</b>"
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Enable SFV-based checks"
|
||||
@@ -3960,6 +3964,16 @@ msgstr "读取 Feed"
|
||||
msgid "Force Download"
|
||||
msgstr "强制下载"
|
||||
|
||||
#. Config->RSS edit button
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Edit"
|
||||
msgstr ""
|
||||
|
||||
#. Config->RSS when will be the next RSS scan
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Next scan at"
|
||||
msgstr ""
|
||||
|
||||
#. Config->RSS table column header
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Filter"
|
||||
@@ -4742,6 +4756,10 @@ msgstr "隐藏/显示已完成文件"
|
||||
msgid "View Script Log"
|
||||
msgstr "查看脚本日志"
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid "Renaming the job will abort Direct Unpack."
|
||||
msgstr ""
|
||||
|
||||
#: sabnzbd/skintext.py
|
||||
msgid ""
|
||||
"LocalStorage (cookies) are disabled in your browser, interface settings will"
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-3.0.0-develop\n"
|
||||
"Project-Id-Version: SABnzbd-3.3.0-develop\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: team@sabnzbd.org\n"
|
||||
"Language-Team: SABnzbd <team@sabnzbd.org>\n"
|
||||
@@ -13,55 +13,59 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Show Release Notes"
|
||||
msgstr ""
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Support the project, Donate!"
|
||||
msgstr ""
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Please close \"SABnzbd.exe\" first"
|
||||
msgstr ""
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "The SABnzbd Windows Service changed in SABnzbd 3.0.0. \\nYou will need to reinstall the SABnzbd service. \\n\\nClick `OK` to remove the existing services or `Cancel` to cancel this upgrade."
|
||||
msgstr ""
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "The installer only supports 64-bit Windows, use the standalone version to run on 32-bit Windows."
|
||||
msgstr ""
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "The installer only supports Windows 8.1 and above, use the standalone legacy version to run on older Windows version."
|
||||
msgstr ""
|
||||
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "This will uninstall SABnzbd from your system"
|
||||
msgstr ""
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Run at startup"
|
||||
msgstr ""
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Desktop Icon"
|
||||
msgstr ""
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "NZB File association"
|
||||
msgstr ""
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Delete Program"
|
||||
msgstr ""
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Delete Settings"
|
||||
msgstr ""
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "You cannot overwrite an existing installation. \\n\\nClick `OK` to remove the previous version or `Cancel` to cancel this upgrade."
|
||||
msgstr ""
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Your settings and data will be preserved."
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-3.0.0-develop\n"
|
||||
"Project-Id-Version: SABnzbd-3.3.0-develop\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:56+0000\n"
|
||||
"Language-Team: Czech (https://www.transifex.com/sabnzbd/teams/111101/cs/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@@ -13,61 +13,67 @@ msgstr ""
|
||||
"Language: cs\n"
|
||||
"Plural-Forms: nplurals=4; plural=(n == 1 && n % 1 == 0) ? 0 : (n >= 2 && n <= 4 && n % 1 == 0) ? 1: (n % 1 != 0 ) ? 2 : 3;\n"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Show Release Notes"
|
||||
msgstr ""
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Support the project, Donate!"
|
||||
msgstr ""
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Please close \"SABnzbd.exe\" first"
|
||||
msgstr ""
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid ""
|
||||
"The SABnzbd Windows Service changed in SABnzbd 3.0.0. \\nYou will need to "
|
||||
"reinstall the SABnzbd service. \\n\\nClick `OK` to remove the existing "
|
||||
"services or `Cancel` to cancel this upgrade."
|
||||
msgstr ""
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid ""
|
||||
"The installer only supports 64-bit Windows, use the standalone version to "
|
||||
"run on 32-bit Windows."
|
||||
msgstr ""
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid ""
|
||||
"The installer only supports Windows 8.1 and above, use the standalone legacy"
|
||||
" version to run on older Windows version."
|
||||
msgstr ""
|
||||
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "This will uninstall SABnzbd from your system"
|
||||
msgstr ""
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Run at startup"
|
||||
msgstr ""
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Desktop Icon"
|
||||
msgstr ""
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "NZB File association"
|
||||
msgstr ""
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Delete Program"
|
||||
msgstr ""
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Delete Settings"
|
||||
msgstr ""
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid ""
|
||||
"You cannot overwrite an existing installation. \\n\\nClick `OK` to remove "
|
||||
"the previous version or `Cancel` to cancel this upgrade."
|
||||
msgstr ""
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Your settings and data will be preserved."
|
||||
msgstr ""
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-3.0.0-develop\n"
|
||||
"Project-Id-Version: SABnzbd-3.3.0-develop\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:56+0000\n"
|
||||
"Last-Translator: Safihre <safihre@sabnzbd.org>, 2020\n"
|
||||
"Language-Team: Danish (https://www.transifex.com/sabnzbd/teams/111101/da/)\n"
|
||||
@@ -17,56 +17,62 @@ msgstr ""
|
||||
"Language: da\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Show Release Notes"
|
||||
msgstr "Vis udgivelsesbemærkninger"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Support the project, Donate!"
|
||||
msgstr "Støt projektet, donér!"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Please close \"SABnzbd.exe\" first"
|
||||
msgstr "Luk venligst \"SABnzbd.exe\" først"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid ""
|
||||
"The SABnzbd Windows Service changed in SABnzbd 3.0.0. \\nYou will need to "
|
||||
"reinstall the SABnzbd service. \\n\\nClick `OK` to remove the existing "
|
||||
"services or `Cancel` to cancel this upgrade."
|
||||
msgstr ""
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid ""
|
||||
"The installer only supports 64-bit Windows, use the standalone version to "
|
||||
"run on 32-bit Windows."
|
||||
msgstr ""
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid ""
|
||||
"The installer only supports Windows 8.1 and above, use the standalone legacy"
|
||||
" version to run on older Windows version."
|
||||
msgstr ""
|
||||
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "This will uninstall SABnzbd from your system"
|
||||
msgstr "Dette vil afinstallere SABnzbd fra dit system"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Run at startup"
|
||||
msgstr "Kør ved opstart"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Desktop Icon"
|
||||
msgstr "Skrivebordsikon"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "NZB File association"
|
||||
msgstr "NZB-filtilknytning"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Delete Program"
|
||||
msgstr "Slet program"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Delete Settings"
|
||||
msgstr "Slet indstillinger"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid ""
|
||||
"You cannot overwrite an existing installation. \\n\\nClick `OK` to remove "
|
||||
"the previous version or `Cancel` to cancel this upgrade."
|
||||
@@ -75,6 +81,6 @@ msgstr ""
|
||||
"fjerne den tidligere version eller `Annuller` for at annullere "
|
||||
"opgraderingen."
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Your settings and data will be preserved."
|
||||
msgstr "Dine indstillinger og data vil blive bevaret."
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-3.0.0-develop\n"
|
||||
"Project-Id-Version: SABnzbd-3.3.0-develop\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:56+0000\n"
|
||||
"Last-Translator: Safihre <safihre@sabnzbd.org>, 2020\n"
|
||||
"Language-Team: German (https://www.transifex.com/sabnzbd/teams/111101/de/)\n"
|
||||
@@ -17,19 +17,19 @@ msgstr ""
|
||||
"Language: de\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Show Release Notes"
|
||||
msgstr "Versionshinweise anzeigen"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Support the project, Donate!"
|
||||
msgstr "Bitte unterstützen Sie das Projekt durch eine Spende!"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Please close \"SABnzbd.exe\" first"
|
||||
msgstr "Schliessen Sie bitte zuerst \"SABnzbd.exe\"."
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid ""
|
||||
"The SABnzbd Windows Service changed in SABnzbd 3.0.0. \\nYou will need to "
|
||||
"reinstall the SABnzbd service. \\n\\nClick `OK` to remove the existing "
|
||||
@@ -38,7 +38,7 @@ msgstr ""
|
||||
"Aufgrund von Änderungen am SABnzbd Windows Service ab Version 3.0.0 ist es nötig,\\nden Windows Service neu zu installieren.\\n\\n\r\n"
|
||||
"Drücke `OK` um den existierenden Service zu löschen oder `Abbrechen` um dieses Upgrade abzubrechen."
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid ""
|
||||
"The installer only supports 64-bit Windows, use the standalone version to "
|
||||
"run on 32-bit Windows."
|
||||
@@ -46,31 +46,37 @@ msgstr ""
|
||||
"Der Installer unterstützt nur Windows 64-bit. Benutze die Standalone Version"
|
||||
" für Windows 32-bit."
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid ""
|
||||
"The installer only supports Windows 8.1 and above, use the standalone legacy"
|
||||
" version to run on older Windows version."
|
||||
msgstr ""
|
||||
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "This will uninstall SABnzbd from your system"
|
||||
msgstr "Dies entfernt SABnzbd von Ihrem System"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Run at startup"
|
||||
msgstr "Beim Systemstart ausführen"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Desktop Icon"
|
||||
msgstr "Desktop-Symbol"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "NZB File association"
|
||||
msgstr "Mit NZB-Dateien verknüpfen"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Delete Program"
|
||||
msgstr "Programm löschen"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Delete Settings"
|
||||
msgstr "Einstellungen löschen"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid ""
|
||||
"You cannot overwrite an existing installation. \\n\\nClick `OK` to remove "
|
||||
"the previous version or `Cancel` to cancel this upgrade."
|
||||
@@ -79,6 +85,6 @@ msgstr ""
|
||||
"Sie 'OK', um die vorherige Version zu entfernen oder 'Abbrechen' um die "
|
||||
"Aktualisierung abzubrechen."
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Your settings and data will be preserved."
|
||||
msgstr "Ihre Einstellungen und Daten bleiben erhalten."
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-3.0.0-develop\n"
|
||||
"Project-Id-Version: SABnzbd-3.3.0-develop\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:56+0000\n"
|
||||
"Last-Translator: Ester Molla Aragones <moarages@gmail.com>, 2020\n"
|
||||
"Language-Team: Spanish (https://www.transifex.com/sabnzbd/teams/111101/es/)\n"
|
||||
@@ -18,19 +18,19 @@ msgstr ""
|
||||
"Language: es\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Show Release Notes"
|
||||
msgstr "Mostrar notas de la versión"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Support the project, Donate!"
|
||||
msgstr "¡Apoye el proyecto, haga una donación!"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Please close \"SABnzbd.exe\" first"
|
||||
msgstr "Por favor cierre primero \"SABnzbd.exe\""
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid ""
|
||||
"The SABnzbd Windows Service changed in SABnzbd 3.0.0. \\nYou will need to "
|
||||
"reinstall the SABnzbd service. \\n\\nClick `OK` to remove the existing "
|
||||
@@ -41,7 +41,7 @@ msgstr ""
|
||||
"en \"OK\" para eliminar los servicios existentes o \"Cancelar\" para "
|
||||
"cancelar la actualización."
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid ""
|
||||
"The installer only supports 64-bit Windows, use the standalone version to "
|
||||
"run on 32-bit Windows."
|
||||
@@ -49,31 +49,37 @@ msgstr ""
|
||||
"El instalador solo admite Windows 64-bit, utilice la versión independiente "
|
||||
"para ejecutar Windows 32-bit."
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid ""
|
||||
"The installer only supports Windows 8.1 and above, use the standalone legacy"
|
||||
" version to run on older Windows version."
|
||||
msgstr ""
|
||||
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "This will uninstall SABnzbd from your system"
|
||||
msgstr "Esto desinstalará SABnzbd de su sistema"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Run at startup"
|
||||
msgstr "Ejecutar al inicio"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Desktop Icon"
|
||||
msgstr "Icono del escritorio"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "NZB File association"
|
||||
msgstr "Asociación de archivos NZB"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Delete Program"
|
||||
msgstr "Eliminar programa"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Delete Settings"
|
||||
msgstr "Eliminar Ajustes"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid ""
|
||||
"You cannot overwrite an existing installation. \\n\\nClick `OK` to remove "
|
||||
"the previous version or `Cancel` to cancel this upgrade."
|
||||
@@ -81,6 +87,6 @@ msgstr ""
|
||||
"No es posible sobrescribir una instalación existente. \\n\\nPresione `OK' "
|
||||
"para quitar la versión anterior o 'Cancelar' para cancelar la actualización."
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Your settings and data will be preserved."
|
||||
msgstr "Tus ajustes y datos se mantendrán intactos."
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-3.0.0-develop\n"
|
||||
"Project-Id-Version: SABnzbd-3.3.0-develop\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:56+0000\n"
|
||||
"Last-Translator: Safihre <safihre@sabnzbd.org>, 2020\n"
|
||||
"Language-Team: Finnish (https://www.transifex.com/sabnzbd/teams/111101/fi/)\n"
|
||||
@@ -17,56 +17,62 @@ msgstr ""
|
||||
"Language: fi\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Show Release Notes"
|
||||
msgstr "Näytä julkaisutiedot"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Support the project, Donate!"
|
||||
msgstr "Tue projektia, lahjoita!"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Please close \"SABnzbd.exe\" first"
|
||||
msgstr "Ole hyvä ja sulje \"SABnzbd.exe\" ensin"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid ""
|
||||
"The SABnzbd Windows Service changed in SABnzbd 3.0.0. \\nYou will need to "
|
||||
"reinstall the SABnzbd service. \\n\\nClick `OK` to remove the existing "
|
||||
"services or `Cancel` to cancel this upgrade."
|
||||
msgstr ""
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid ""
|
||||
"The installer only supports 64-bit Windows, use the standalone version to "
|
||||
"run on 32-bit Windows."
|
||||
msgstr ""
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid ""
|
||||
"The installer only supports Windows 8.1 and above, use the standalone legacy"
|
||||
" version to run on older Windows version."
|
||||
msgstr ""
|
||||
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "This will uninstall SABnzbd from your system"
|
||||
msgstr "Tämä poistaa SABnzbd:n tietokoneestasi"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Run at startup"
|
||||
msgstr "Suorita käynnistyksen yhteydessä"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Desktop Icon"
|
||||
msgstr "Työpöydän kuvake"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "NZB File association"
|
||||
msgstr "NZB tiedostosidos"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Delete Program"
|
||||
msgstr "Poista sovellus"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Delete Settings"
|
||||
msgstr "Poista asetukset"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid ""
|
||||
"You cannot overwrite an existing installation. \\n\\nClick `OK` to remove "
|
||||
"the previous version or `Cancel` to cancel this upgrade."
|
||||
@@ -74,6 +80,6 @@ msgstr ""
|
||||
"Et voi asentaa tätä vanhan asennuksen päälle. \\n\\nPaina `OK` poistaaksesi "
|
||||
"edellisen version tai paina `Peruuta` peruuttaaksesi tämän päivityksen."
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Your settings and data will be preserved."
|
||||
msgstr "Asetuksiasi ja tietojasi ei poisteta."
|
||||
|
||||
@@ -4,12 +4,13 @@
|
||||
#
|
||||
# Translators:
|
||||
# Safihre <safihre@sabnzbd.org>, 2020
|
||||
# Fred L <88com88@gmail.com>, 2021
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-3.0.0-develop\n"
|
||||
"Project-Id-Version: SABnzbd-3.3.0-develop\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:56+0000\n"
|
||||
"Last-Translator: Safihre <safihre@sabnzbd.org>, 2020\n"
|
||||
"Last-Translator: Fred L <88com88@gmail.com>, 2021\n"
|
||||
"Language-Team: French (https://www.transifex.com/sabnzbd/teams/111101/fr/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
@@ -17,19 +18,19 @@ msgstr ""
|
||||
"Language: fr\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Show Release Notes"
|
||||
msgstr "Afficher les notes de version"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Support the project, Donate!"
|
||||
msgstr "Soutenez le projet, faites un don !"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Please close \"SABnzbd.exe\" first"
|
||||
msgstr "Merci de fermer \"SABnzbd.exe\" avant l'installation"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid ""
|
||||
"The SABnzbd Windows Service changed in SABnzbd 3.0.0. \\nYou will need to "
|
||||
"reinstall the SABnzbd service. \\n\\nClick `OK` to remove the existing "
|
||||
@@ -39,7 +40,7 @@ msgstr ""
|
||||
" réinstaller le service SABnzbd. \\n\\nCliquez sur 'OK' pour supprimer les "
|
||||
"services existants ou sur 'Annuler' pour annuler cette mise à niveau."
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid ""
|
||||
"The installer only supports 64-bit Windows, use the standalone version to "
|
||||
"run on 32-bit Windows."
|
||||
@@ -47,31 +48,40 @@ msgstr ""
|
||||
"Le programme d'installation ne prend en charge que Windows 64 bits, utilisez"
|
||||
" la version standalone pour l'exécuter sur Windows 32 bits."
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid ""
|
||||
"The installer only supports Windows 8.1 and above, use the standalone legacy"
|
||||
" version to run on older Windows version."
|
||||
msgstr ""
|
||||
"Le programme d'installation ne prend en charge que Windows 8.1 et supérieur,"
|
||||
" utilisez la version autonome legacy pour les versions antérieures de "
|
||||
"Windows."
|
||||
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "This will uninstall SABnzbd from your system"
|
||||
msgstr "Ceci désinstallera SABnzbd de votre système"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Run at startup"
|
||||
msgstr "Lancer au démarrage"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Desktop Icon"
|
||||
msgstr "Icône sur le Bureau"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "NZB File association"
|
||||
msgstr "Association des fichiers NZB"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Delete Program"
|
||||
msgstr "Supprimer le programme"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Delete Settings"
|
||||
msgstr "Supprimer les paramètres"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid ""
|
||||
"You cannot overwrite an existing installation. \\n\\nClick `OK` to remove "
|
||||
"the previous version or `Cancel` to cancel this upgrade."
|
||||
@@ -80,6 +90,6 @@ msgstr ""
|
||||
"pour supprimer la version précédente ou `Annuler` pour annuler cette mise à "
|
||||
"niveau."
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Your settings and data will be preserved."
|
||||
msgstr "Vos paramètres et données seront conservés."
|
||||
|
||||
@@ -4,12 +4,13 @@
|
||||
#
|
||||
# Translators:
|
||||
# Safihre <safihre@sabnzbd.org>, 2020
|
||||
# ION, 2021
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-3.0.0-develop\n"
|
||||
"Project-Id-Version: SABnzbd-3.3.0-develop\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:56+0000\n"
|
||||
"Last-Translator: Safihre <safihre@sabnzbd.org>, 2020\n"
|
||||
"Last-Translator: ION, 2021\n"
|
||||
"Language-Team: Hebrew (https://www.transifex.com/sabnzbd/teams/111101/he/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
@@ -17,29 +18,29 @@ msgstr ""
|
||||
"Language: he\n"
|
||||
"Plural-Forms: nplurals=4; plural=(n == 1 && n % 1 == 0) ? 0 : (n == 2 && n % 1 == 0) ? 1: (n % 10 == 0 && n % 1 == 0 && n > 10) ? 2 : 3;\n"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Show Release Notes"
|
||||
msgstr "הראה הערות שחרור"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Support the project, Donate!"
|
||||
msgstr "תמוך במיזם, תרום!"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Please close \"SABnzbd.exe\" first"
|
||||
msgstr "אנא סגור את \"SABnzbd.exe\" תחילה"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid ""
|
||||
"The SABnzbd Windows Service changed in SABnzbd 3.0.0. \\nYou will need to "
|
||||
"reinstall the SABnzbd service. \\n\\nClick `OK` to remove the existing "
|
||||
"services or `Cancel` to cancel this upgrade."
|
||||
msgstr ""
|
||||
"שירות SABnzbd Windows השתנה בגרסה SABnzbd 3.0.0. \\nתצטרך להתקין מחדש את "
|
||||
"השירות SABnzbd. \\n\\nלחץ `אשר` כדי להסיר את השירותים הקיימים או `בטל` כדי "
|
||||
"לבטל שדרוג זה."
|
||||
"שירות Windows של SABnzbd השתנה ב־SABnzbd 3.0.0. \\nתצטרך להתקין מחדש את "
|
||||
"השירות של SABnzbd. \\n\\nלחץ על `אישור` כדי להסיר את השירותים הקיימים או על "
|
||||
"`ביטול` כדי לבטל שדרוג זה."
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid ""
|
||||
"The installer only supports 64-bit Windows, use the standalone version to "
|
||||
"run on 32-bit Windows."
|
||||
@@ -47,38 +48,46 @@ msgstr ""
|
||||
"המתקין תומך רק במערכת Windows מסוג 64־סיביות, השתמש בגרסה העצמאית כדי להריץ "
|
||||
"על Windows מסוג 32־סיביות."
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid ""
|
||||
"The installer only supports Windows 8.1 and above, use the standalone legacy"
|
||||
" version to run on older Windows version."
|
||||
msgstr ""
|
||||
"המתקין תומך רק במערכת Windows 8.1 ומעלה, השתמש בגרסה העצמאית המיושנת כדי "
|
||||
"להריץ על גרסת Windows ישנה יותר."
|
||||
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "This will uninstall SABnzbd from your system"
|
||||
msgstr "זה יסיר את SABnzbd ממערכתך"
|
||||
msgstr "זה יסיר את SABnzbd מהמערכת שלך"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Run at startup"
|
||||
msgstr "הפעלה בהזנק"
|
||||
msgstr "הרץ בהזנק"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Desktop Icon"
|
||||
msgstr "צלמית שולחן עבודה"
|
||||
msgstr "צור קיצור דרך בשולחן העבודה"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "NZB File association"
|
||||
msgstr "NZB שיוך קבצי"
|
||||
msgstr "NZB שייך קבצי"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Delete Program"
|
||||
msgstr "מחק תוכנית"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Delete Settings"
|
||||
msgstr "מחק הגדרות"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid ""
|
||||
"You cannot overwrite an existing installation. \\n\\nClick `OK` to remove "
|
||||
"the previous version or `Cancel` to cancel this upgrade."
|
||||
msgstr ""
|
||||
"אינך יכול לדרוס התקנה קיימת.\\n\\nלחץ על `אישור` כדי להסיר את הגרסה הקודמת "
|
||||
"אינך יכול לדרוס התקנה קיימת. \\n\\nלחץ על `אישור` כדי להסיר את הגרסה הקודמת "
|
||||
"או על `ביטול` כדי לבטל שדרוג זה."
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Your settings and data will be preserved."
|
||||
msgstr "ההגדרות והנתונים שלך יישמרו."
|
||||
msgstr "ההגדרות והנתונים שלך ישתמרו."
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-3.0.0-develop\n"
|
||||
"Project-Id-Version: SABnzbd-3.3.0-develop\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:56+0000\n"
|
||||
"Last-Translator: Safihre <safihre@sabnzbd.org>, 2020\n"
|
||||
"Language-Team: Norwegian Bokmål (https://www.transifex.com/sabnzbd/teams/111101/nb/)\n"
|
||||
@@ -17,56 +17,62 @@ msgstr ""
|
||||
"Language: nb\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Show Release Notes"
|
||||
msgstr "Vis versjonsmerknader"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Support the project, Donate!"
|
||||
msgstr "Støtt prosjektet, donèr!"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Please close \"SABnzbd.exe\" first"
|
||||
msgstr "Vennligst lukk \"SABnzbd.exe\" først"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid ""
|
||||
"The SABnzbd Windows Service changed in SABnzbd 3.0.0. \\nYou will need to "
|
||||
"reinstall the SABnzbd service. \\n\\nClick `OK` to remove the existing "
|
||||
"services or `Cancel` to cancel this upgrade."
|
||||
msgstr ""
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid ""
|
||||
"The installer only supports 64-bit Windows, use the standalone version to "
|
||||
"run on 32-bit Windows."
|
||||
msgstr ""
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid ""
|
||||
"The installer only supports Windows 8.1 and above, use the standalone legacy"
|
||||
" version to run on older Windows version."
|
||||
msgstr ""
|
||||
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "This will uninstall SABnzbd from your system"
|
||||
msgstr "Dette vil avinstallere SABnzbd fra ditt system"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Run at startup"
|
||||
msgstr "Kjør ved oppstart"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Desktop Icon"
|
||||
msgstr "Skrivebordsikon"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "NZB File association"
|
||||
msgstr "NZB-filassosiering"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Delete Program"
|
||||
msgstr "Fjern program"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Delete Settings"
|
||||
msgstr "Slett innstillinger"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid ""
|
||||
"You cannot overwrite an existing installation. \\n\\nClick `OK` to remove "
|
||||
"the previous version or `Cancel` to cancel this upgrade."
|
||||
@@ -75,6 +81,6 @@ msgstr ""
|
||||
" fjerne tidligere installasjon, eller 'Avbryt' for å avbryte denne "
|
||||
"oppgraderingen."
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Your settings and data will be preserved."
|
||||
msgstr "Dine innstillinger og data vil bli tatt vare på."
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
# team@sabnzbd.org
|
||||
#
|
||||
# Translators:
|
||||
# Safihre <safihre@sabnzbd.org>, 2020
|
||||
# Safihre <safihre@sabnzbd.org>, 2021
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-3.0.0-develop\n"
|
||||
"Project-Id-Version: SABnzbd-3.3.0-develop\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:56+0000\n"
|
||||
"Last-Translator: Safihre <safihre@sabnzbd.org>, 2020\n"
|
||||
"Last-Translator: Safihre <safihre@sabnzbd.org>, 2021\n"
|
||||
"Language-Team: Dutch (https://www.transifex.com/sabnzbd/teams/111101/nl/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
@@ -17,19 +17,19 @@ msgstr ""
|
||||
"Language: nl\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Show Release Notes"
|
||||
msgstr "Toon opmerkingen bij deze uitgave"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Support the project, Donate!"
|
||||
msgstr "Steun het project, doneer!"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Please close \"SABnzbd.exe\" first"
|
||||
msgstr "Sluit \"SABnzbd.exe\" eerst af"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid ""
|
||||
"The SABnzbd Windows Service changed in SABnzbd 3.0.0. \\nYou will need to "
|
||||
"reinstall the SABnzbd service. \\n\\nClick `OK` to remove the existing "
|
||||
@@ -38,7 +38,7 @@ msgstr ""
|
||||
"De SABnzbd Windows Service is aangepast in SABnzbd 3.0.0. Hierdoor zal je de service opnieuw moeten installeren.\\n\\n\n"
|
||||
"Klik `Ok` om de bestaande services te verwijderen of `Annuleren` om te stoppen."
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid ""
|
||||
"The installer only supports 64-bit Windows, use the standalone version to "
|
||||
"run on 32-bit Windows."
|
||||
@@ -46,31 +46,40 @@ msgstr ""
|
||||
"Alleen 64-bit wordt ondersteund in de installer, download de standalone "
|
||||
"versie om SABnzbd uit te voeren op 32-bit Windows."
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid ""
|
||||
"The installer only supports Windows 8.1 and above, use the standalone legacy"
|
||||
" version to run on older Windows version."
|
||||
msgstr ""
|
||||
"Alleen Windows 8.1 en nieuwer worden ondersteund door de installer, download"
|
||||
" de standalone legacy versie om SABnzbd uit te voeren op oudere versies van "
|
||||
"Windows."
|
||||
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "This will uninstall SABnzbd from your system"
|
||||
msgstr "Dit verwijdert SABnzbd van je systeem"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Run at startup"
|
||||
msgstr "Starten met Windows"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Desktop Icon"
|
||||
msgstr "Bureaubladpictogram"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "NZB File association"
|
||||
msgstr "NZB-bestanden openen met SABnzbd"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Delete Program"
|
||||
msgstr "Programma verwijderen"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Delete Settings"
|
||||
msgstr "Verwijder alle instellingen"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid ""
|
||||
"You cannot overwrite an existing installation. \\n\\nClick `OK` to remove "
|
||||
"the previous version or `Cancel` to cancel this upgrade."
|
||||
@@ -78,6 +87,6 @@ msgstr ""
|
||||
"U kunt geen bestaande installatie overschrijven.\\n\\nKlik op `OK` om de "
|
||||
"vorige versie te verwijderen of op `Annuleren` om te stoppen."
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Your settings and data will be preserved."
|
||||
msgstr "Je instellingen en bestanden blijven behouden."
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-3.0.0-develop\n"
|
||||
"Project-Id-Version: SABnzbd-3.3.0-develop\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:56+0000\n"
|
||||
"Last-Translator: Safihre <safihre@sabnzbd.org>, 2020\n"
|
||||
"Language-Team: Polish (https://www.transifex.com/sabnzbd/teams/111101/pl/)\n"
|
||||
@@ -17,56 +17,62 @@ msgstr ""
|
||||
"Language: pl\n"
|
||||
"Plural-Forms: nplurals=4; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4) && (n%100<12 || n%100>14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && n%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3);\n"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Show Release Notes"
|
||||
msgstr "Pokaż informacje o wydaniu"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Support the project, Donate!"
|
||||
msgstr "Wspomóż projekt!"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Please close \"SABnzbd.exe\" first"
|
||||
msgstr "Najpierw zamknij SABnzbd.exe"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid ""
|
||||
"The SABnzbd Windows Service changed in SABnzbd 3.0.0. \\nYou will need to "
|
||||
"reinstall the SABnzbd service. \\n\\nClick `OK` to remove the existing "
|
||||
"services or `Cancel` to cancel this upgrade."
|
||||
msgstr ""
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid ""
|
||||
"The installer only supports 64-bit Windows, use the standalone version to "
|
||||
"run on 32-bit Windows."
|
||||
msgstr ""
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid ""
|
||||
"The installer only supports Windows 8.1 and above, use the standalone legacy"
|
||||
" version to run on older Windows version."
|
||||
msgstr ""
|
||||
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "This will uninstall SABnzbd from your system"
|
||||
msgstr "To odinstaluje SABnzbd z systemu"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Run at startup"
|
||||
msgstr "Uruchom wraz z systemem"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Desktop Icon"
|
||||
msgstr "Ikona pulpitu"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "NZB File association"
|
||||
msgstr "powiązanie pliku NZB"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Delete Program"
|
||||
msgstr "Usuń program"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Delete Settings"
|
||||
msgstr "Skasuj obecne ustawienia"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid ""
|
||||
"You cannot overwrite an existing installation. \\n\\nClick `OK` to remove "
|
||||
"the previous version or `Cancel` to cancel this upgrade."
|
||||
@@ -74,6 +80,6 @@ msgstr ""
|
||||
"Nie można nadpisać istniejącej instalacji. \\n\\n Naciśnij `OK`, aby usunąć "
|
||||
"poprzednia wersję lub `Anuluj` aby anulować aktualizację."
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Your settings and data will be preserved."
|
||||
msgstr "Twoje ustawienia i dane zostaną zachowane."
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-3.0.0-develop\n"
|
||||
"Project-Id-Version: SABnzbd-3.3.0-develop\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:56+0000\n"
|
||||
"Last-Translator: Safihre <safihre@sabnzbd.org>, 2020\n"
|
||||
"Language-Team: Portuguese (Brazil) (https://www.transifex.com/sabnzbd/teams/111101/pt_BR/)\n"
|
||||
@@ -17,56 +17,62 @@ msgstr ""
|
||||
"Language: pt_BR\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Show Release Notes"
|
||||
msgstr "Mostrar Notas de Lançamento"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Support the project, Donate!"
|
||||
msgstr "Apoie o projeto. Faça uma doação!"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Please close \"SABnzbd.exe\" first"
|
||||
msgstr "Por favor, feche \"SABnzbd.exe\" primeiro"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid ""
|
||||
"The SABnzbd Windows Service changed in SABnzbd 3.0.0. \\nYou will need to "
|
||||
"reinstall the SABnzbd service. \\n\\nClick `OK` to remove the existing "
|
||||
"services or `Cancel` to cancel this upgrade."
|
||||
msgstr ""
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid ""
|
||||
"The installer only supports 64-bit Windows, use the standalone version to "
|
||||
"run on 32-bit Windows."
|
||||
msgstr ""
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid ""
|
||||
"The installer only supports Windows 8.1 and above, use the standalone legacy"
|
||||
" version to run on older Windows version."
|
||||
msgstr ""
|
||||
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "This will uninstall SABnzbd from your system"
|
||||
msgstr "Isso irá desinstalar SABnzbd de seu sistema"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Run at startup"
|
||||
msgstr "Executar na inicialização"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Desktop Icon"
|
||||
msgstr "Ícone na Área de Trabalho"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "NZB File association"
|
||||
msgstr "Associação com Arquivos NZB"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Delete Program"
|
||||
msgstr "Excluir o Programa"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Delete Settings"
|
||||
msgstr "Apagar Configurações"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid ""
|
||||
"You cannot overwrite an existing installation. \\n\\nClick `OK` to remove "
|
||||
"the previous version or `Cancel` to cancel this upgrade."
|
||||
@@ -74,6 +80,6 @@ msgstr ""
|
||||
"Você não pode substituir uma instalação existente. \\n\\nClique `OK` para "
|
||||
"remover a versão anterior ou `Cancelar` para cancelar esta atualização."
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Your settings and data will be preserved."
|
||||
msgstr "Suas configurações e os dados serão preservados."
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-3.0.0-develop\n"
|
||||
"Project-Id-Version: SABnzbd-3.3.0-develop\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:56+0000\n"
|
||||
"Last-Translator: Safihre <safihre@sabnzbd.org>, 2020\n"
|
||||
"Language-Team: Romanian (https://www.transifex.com/sabnzbd/teams/111101/ro/)\n"
|
||||
@@ -17,56 +17,62 @@ msgstr ""
|
||||
"Language: ro\n"
|
||||
"Plural-Forms: nplurals=3; plural=(n==1?0:(((n%100>19)||((n%100==0)&&(n!=0)))?2:1));\n"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Show Release Notes"
|
||||
msgstr "Arată Notele de Publicare"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Support the project, Donate!"
|
||||
msgstr "Susţine proiectul, Donează!"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Please close \"SABnzbd.exe\" first"
|
||||
msgstr "Închideţi mai întâi \"SABnzbd.exe\""
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid ""
|
||||
"The SABnzbd Windows Service changed in SABnzbd 3.0.0. \\nYou will need to "
|
||||
"reinstall the SABnzbd service. \\n\\nClick `OK` to remove the existing "
|
||||
"services or `Cancel` to cancel this upgrade."
|
||||
msgstr ""
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid ""
|
||||
"The installer only supports 64-bit Windows, use the standalone version to "
|
||||
"run on 32-bit Windows."
|
||||
msgstr ""
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid ""
|
||||
"The installer only supports Windows 8.1 and above, use the standalone legacy"
|
||||
" version to run on older Windows version."
|
||||
msgstr ""
|
||||
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "This will uninstall SABnzbd from your system"
|
||||
msgstr "Acest lucru va dezinstala SABnzbd din sistem"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Run at startup"
|
||||
msgstr "Executare la pornire"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Desktop Icon"
|
||||
msgstr "Icoană Desktop"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "NZB File association"
|
||||
msgstr "Asociere cu Fişierele NZB"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Delete Program"
|
||||
msgstr "Şterge Program"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Delete Settings"
|
||||
msgstr "Ştergeţi Setări"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid ""
|
||||
"You cannot overwrite an existing installation. \\n\\nClick `OK` to remove "
|
||||
"the previous version or `Cancel` to cancel this upgrade."
|
||||
@@ -74,6 +80,6 @@ msgstr ""
|
||||
"Nu puteți suprascrie instalarea existentă. \\n\\nClick `OK` pentru a elimina"
|
||||
" versiunea anterioară sau `Anulare` pentru a anula actualizarea."
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Your settings and data will be preserved."
|
||||
msgstr "Setările şi informaţiile vor fi salvate."
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-3.0.0-develop\n"
|
||||
"Project-Id-Version: SABnzbd-3.3.0-develop\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:56+0000\n"
|
||||
"Last-Translator: Safihre <safihre@sabnzbd.org>, 2020\n"
|
||||
"Language-Team: Russian (https://www.transifex.com/sabnzbd/teams/111101/ru/)\n"
|
||||
@@ -17,56 +17,62 @@ msgstr ""
|
||||
"Language: ru\n"
|
||||
"Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);\n"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Show Release Notes"
|
||||
msgstr "Показать заметки о выпуске"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Support the project, Donate!"
|
||||
msgstr "Поддержите проект. Сделайте пожертвование!"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Please close \"SABnzbd.exe\" first"
|
||||
msgstr "Завершите сначала работу процесса SABnzbd.exe"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid ""
|
||||
"The SABnzbd Windows Service changed in SABnzbd 3.0.0. \\nYou will need to "
|
||||
"reinstall the SABnzbd service. \\n\\nClick `OK` to remove the existing "
|
||||
"services or `Cancel` to cancel this upgrade."
|
||||
msgstr ""
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid ""
|
||||
"The installer only supports 64-bit Windows, use the standalone version to "
|
||||
"run on 32-bit Windows."
|
||||
msgstr ""
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid ""
|
||||
"The installer only supports Windows 8.1 and above, use the standalone legacy"
|
||||
" version to run on older Windows version."
|
||||
msgstr ""
|
||||
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "This will uninstall SABnzbd from your system"
|
||||
msgstr "Приложение SABnzbd будет удалено из вашей системы"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Run at startup"
|
||||
msgstr "Запускать вместе с системой"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Desktop Icon"
|
||||
msgstr "Значок на рабочем столе"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "NZB File association"
|
||||
msgstr "Ассоциировать с файлами NZB"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Delete Program"
|
||||
msgstr "Удалить программу"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Delete Settings"
|
||||
msgstr "Удалить параметры"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid ""
|
||||
"You cannot overwrite an existing installation. \\n\\nClick `OK` to remove "
|
||||
"the previous version or `Cancel` to cancel this upgrade."
|
||||
@@ -75,6 +81,6 @@ msgstr ""
|
||||
"удалить предыдущую версию, нажмите кнопку «ОК». Чтобы отменить обновление, "
|
||||
"нажмите кнопку «Отмена»."
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Your settings and data will be preserved."
|
||||
msgstr "Ваши параметры и данные будут сохранены."
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-3.0.0-develop\n"
|
||||
"Project-Id-Version: SABnzbd-3.3.0-develop\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:56+0000\n"
|
||||
"Last-Translator: Safihre <safihre@sabnzbd.org>, 2020\n"
|
||||
"Language-Team: Serbian (https://www.transifex.com/sabnzbd/teams/111101/sr/)\n"
|
||||
@@ -17,56 +17,62 @@ msgstr ""
|
||||
"Language: sr\n"
|
||||
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Show Release Notes"
|
||||
msgstr "Прикажи белешке о издању"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Support the project, Donate!"
|
||||
msgstr "Подржите пројекат, дајте добровољан прилог!"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Please close \"SABnzbd.exe\" first"
|
||||
msgstr "Прво затворите „SABnzbd.exe“"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid ""
|
||||
"The SABnzbd Windows Service changed in SABnzbd 3.0.0. \\nYou will need to "
|
||||
"reinstall the SABnzbd service. \\n\\nClick `OK` to remove the existing "
|
||||
"services or `Cancel` to cancel this upgrade."
|
||||
msgstr ""
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid ""
|
||||
"The installer only supports 64-bit Windows, use the standalone version to "
|
||||
"run on 32-bit Windows."
|
||||
msgstr ""
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid ""
|
||||
"The installer only supports Windows 8.1 and above, use the standalone legacy"
|
||||
" version to run on older Windows version."
|
||||
msgstr ""
|
||||
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "This will uninstall SABnzbd from your system"
|
||||
msgstr "Ово ће уклонити САБнзбд са вашег система"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Run at startup"
|
||||
msgstr "Покрени са системом"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Desktop Icon"
|
||||
msgstr "Иконица радне површи"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "NZB File association"
|
||||
msgstr "Придруживање НЗБ датотеке"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Delete Program"
|
||||
msgstr "Обриши програм"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Delete Settings"
|
||||
msgstr "Обриши подешавања"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid ""
|
||||
"You cannot overwrite an existing installation. \\n\\nClick `OK` to remove "
|
||||
"the previous version or `Cancel` to cancel this upgrade."
|
||||
@@ -74,6 +80,6 @@ msgstr ""
|
||||
"Не можете да препишете постојећу инсталацију. \\n\\nПритисните „У реду“ да "
|
||||
"уклоните претходно издање или „Откажи“ да поништите ову надоградњу."
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Your settings and data will be preserved."
|
||||
msgstr "Ваша подешавања и подаци биће сачувани."
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-3.0.0-develop\n"
|
||||
"Project-Id-Version: SABnzbd-3.3.0-develop\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:56+0000\n"
|
||||
"Last-Translator: Safihre <safihre@sabnzbd.org>, 2020\n"
|
||||
"Language-Team: Swedish (https://www.transifex.com/sabnzbd/teams/111101/sv/)\n"
|
||||
@@ -17,56 +17,62 @@ msgstr ""
|
||||
"Language: sv\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Show Release Notes"
|
||||
msgstr "Visa releasenoteringar"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Support the project, Donate!"
|
||||
msgstr "Donera och stöd detta projekt!"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Please close \"SABnzbd.exe\" first"
|
||||
msgstr "Var vänlig stäng \"SABnzbd.exe\" först"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid ""
|
||||
"The SABnzbd Windows Service changed in SABnzbd 3.0.0. \\nYou will need to "
|
||||
"reinstall the SABnzbd service. \\n\\nClick `OK` to remove the existing "
|
||||
"services or `Cancel` to cancel this upgrade."
|
||||
msgstr ""
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid ""
|
||||
"The installer only supports 64-bit Windows, use the standalone version to "
|
||||
"run on 32-bit Windows."
|
||||
msgstr ""
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid ""
|
||||
"The installer only supports Windows 8.1 and above, use the standalone legacy"
|
||||
" version to run on older Windows version."
|
||||
msgstr ""
|
||||
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "This will uninstall SABnzbd from your system"
|
||||
msgstr "Detta kommer att avinstallera SABnzbd från systemet"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Run at startup"
|
||||
msgstr "Kör vid uppstart"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Desktop Icon"
|
||||
msgstr "Skrivbordsikon"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "NZB File association"
|
||||
msgstr "NZB Filassosication"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Delete Program"
|
||||
msgstr "Radera programmet"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Delete Settings"
|
||||
msgstr "Radera inställningar"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid ""
|
||||
"You cannot overwrite an existing installation. \\n\\nClick `OK` to remove "
|
||||
"the previous version or `Cancel` to cancel this upgrade."
|
||||
@@ -75,6 +81,6 @@ msgstr ""
|
||||
"avinstallera tidigare version eller 'Avbryt' för att avbryta denna "
|
||||
"uppgradering."
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Your settings and data will be preserved."
|
||||
msgstr "Dina inställningar och ditt data kommer att bevaras."
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SABnzbd-3.0.0-develop\n"
|
||||
"Project-Id-Version: SABnzbd-3.3.0-develop\n"
|
||||
"PO-Revision-Date: 2020-06-27 15:56+0000\n"
|
||||
"Last-Translator: Safihre <safihre@sabnzbd.org>, 2020\n"
|
||||
"Language-Team: Chinese (China) (https://www.transifex.com/sabnzbd/teams/111101/zh_CN/)\n"
|
||||
@@ -17,61 +17,67 @@ msgstr ""
|
||||
"Language: zh_CN\n"
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Show Release Notes"
|
||||
msgstr "显示版本说明"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Support the project, Donate!"
|
||||
msgstr "支持该项目,捐助!"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Please close \"SABnzbd.exe\" first"
|
||||
msgstr "请先关闭 \"SABnzbd.exe\""
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid ""
|
||||
"The SABnzbd Windows Service changed in SABnzbd 3.0.0. \\nYou will need to "
|
||||
"reinstall the SABnzbd service. \\n\\nClick `OK` to remove the existing "
|
||||
"services or `Cancel` to cancel this upgrade."
|
||||
msgstr ""
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid ""
|
||||
"The installer only supports 64-bit Windows, use the standalone version to "
|
||||
"run on 32-bit Windows."
|
||||
msgstr ""
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid ""
|
||||
"The installer only supports Windows 8.1 and above, use the standalone legacy"
|
||||
" version to run on older Windows version."
|
||||
msgstr ""
|
||||
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "This will uninstall SABnzbd from your system"
|
||||
msgstr "这将从您的系统中卸载 SABnzbd"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Run at startup"
|
||||
msgstr "启动时运行"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Desktop Icon"
|
||||
msgstr "桌面图标"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "NZB File association"
|
||||
msgstr "NZB 文件关联"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Delete Program"
|
||||
msgstr "删除程序"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Delete Settings"
|
||||
msgstr "删除设置"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid ""
|
||||
"You cannot overwrite an existing installation. \\n\\nClick `OK` to remove "
|
||||
"the previous version or `Cancel` to cancel this upgrade."
|
||||
msgstr "不可以覆盖安装。\\n\\n点击“确定”可移除旧版,或点击“取消”取消升级。"
|
||||
|
||||
#: NSIS_Installer.nsi
|
||||
#: builder/win/NSIS_Installer.nsi
|
||||
msgid "Your settings and data will be preserved."
|
||||
msgstr "您的设置及数据将会保留。"
|
||||
|
||||
@@ -20,10 +20,13 @@ import logging
|
||||
import datetime
|
||||
import tempfile
|
||||
import pickle
|
||||
import ctypes
|
||||
import ctypes.util
|
||||
import gzip
|
||||
import time
|
||||
import socket
|
||||
import cherrypy
|
||||
import platform
|
||||
import sys
|
||||
import ssl
|
||||
from threading import Lock, Thread, Condition
|
||||
@@ -33,15 +36,13 @@ from typing import Any, AnyStr
|
||||
# Determine platform flags
|
||||
##############################################################################
|
||||
WIN32 = DARWIN = FOUNDATION = WIN64 = DOCKER = False
|
||||
KERNEL32 = None
|
||||
KERNEL32 = LIBC = MACOSLIBC = None
|
||||
|
||||
if os.name == "nt":
|
||||
WIN32 = True
|
||||
from sabnzbd.utils.apireg import del_connection_info
|
||||
|
||||
try:
|
||||
import ctypes
|
||||
|
||||
KERNEL32 = ctypes.windll.LoadLibrary("Kernel32.dll")
|
||||
except:
|
||||
pass
|
||||
@@ -56,12 +57,21 @@ elif os.name == "posix":
|
||||
except:
|
||||
pass
|
||||
|
||||
import platform
|
||||
# See if we have the GNU glibc malloc_trim() memory release function
|
||||
try:
|
||||
LIBC = ctypes.CDLL("libc.so.6")
|
||||
LIBC.malloc_trim(0) # try the malloc_trim() call, which is a GNU extension
|
||||
except:
|
||||
# No malloc_trim(), probably because no glibc
|
||||
LIBC = None
|
||||
pass
|
||||
|
||||
# Parse macOS version numbers
|
||||
if platform.system().lower() == "darwin":
|
||||
DARWIN = True
|
||||
# 12 = Sierra, 11 = ElCaptain, 10 = Yosemite, 9 = Mavericks, 8 = MountainLion
|
||||
DARWIN_VERSION = int(platform.mac_ver()[0].split(".")[1])
|
||||
MACOSLIBC = ctypes.CDLL(ctypes.util.find_library("c"), use_errno=True) # the MacOS C library
|
||||
try:
|
||||
import Foundation
|
||||
import sabnzbd.utils.sleepless as sleepless
|
||||
@@ -70,6 +80,7 @@ elif os.name == "posix":
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
# Imported to be referenced from other files directly
|
||||
from sabnzbd.version import __version__, __baseline__
|
||||
|
||||
@@ -184,7 +195,6 @@ DOWNLOAD_DIR_SPEED = 0
|
||||
COMPLETE_DIR_SPEED = 0
|
||||
INTERNET_BANDWIDTH = 0
|
||||
|
||||
|
||||
# Rendering of original command line arguments in Config
|
||||
CMDLINE = " ".join(['"%s"' % arg for arg in sys.argv])
|
||||
|
||||
@@ -442,13 +452,13 @@ def halt():
|
||||
|
||||
|
||||
def notify_shutdown_loop():
|
||||
""" Trigger the main loop to wake up"""
|
||||
"""Trigger the main loop to wake up"""
|
||||
with sabnzbd.SABSTOP_CONDITION:
|
||||
sabnzbd.SABSTOP_CONDITION.notify()
|
||||
|
||||
|
||||
def shutdown_program():
|
||||
""" Stop program after halting and saving """
|
||||
"""Stop program after halting and saving"""
|
||||
if not sabnzbd.SABSTOP:
|
||||
logging.info("[%s] Performing SABnzbd shutdown", misc.caller_name())
|
||||
sabnzbd.halt()
|
||||
@@ -458,7 +468,7 @@ def shutdown_program():
|
||||
|
||||
|
||||
def trigger_restart(timeout=None):
|
||||
""" Trigger a restart by setting a flag an shutting down CP """
|
||||
"""Trigger a restart by setting a flag an shutting down CP"""
|
||||
# Sometimes we need to wait a bit to send good-bye to the browser
|
||||
if timeout:
|
||||
time.sleep(timeout)
|
||||
@@ -472,22 +482,22 @@ def trigger_restart(timeout=None):
|
||||
# Misc Wrappers
|
||||
##############################################################################
|
||||
def new_limit():
|
||||
""" Callback for article cache changes """
|
||||
"""Callback for article cache changes"""
|
||||
sabnzbd.ArticleCache.new_limit(cfg.cache_limit.get_int())
|
||||
|
||||
|
||||
def guard_restart():
|
||||
""" Callback for config options requiring a restart """
|
||||
"""Callback for config options requiring a restart"""
|
||||
sabnzbd.RESTART_REQ = True
|
||||
|
||||
|
||||
def guard_top_only():
|
||||
""" Callback for change of top_only option """
|
||||
"""Callback for change of top_only option"""
|
||||
sabnzbd.NzbQueue.set_top_only(cfg.top_only())
|
||||
|
||||
|
||||
def guard_pause_on_pp():
|
||||
""" Callback for change of pause-download-on-pp """
|
||||
"""Callback for change of pause-download-on-pp"""
|
||||
if cfg.pause_on_post_processing():
|
||||
pass # Not safe to idle downloader, because we don't know
|
||||
# if post-processing is active now
|
||||
@@ -496,17 +506,17 @@ def guard_pause_on_pp():
|
||||
|
||||
|
||||
def guard_quota_size():
|
||||
""" Callback for change of quota_size """
|
||||
"""Callback for change of quota_size"""
|
||||
sabnzbd.BPSMeter.change_quota()
|
||||
|
||||
|
||||
def guard_quota_dp():
|
||||
""" Callback for change of quota_day or quota_period """
|
||||
"""Callback for change of quota_day or quota_period"""
|
||||
sabnzbd.Scheduler.restart()
|
||||
|
||||
|
||||
def guard_language():
|
||||
""" Callback for change of the interface language """
|
||||
"""Callback for change of the interface language"""
|
||||
sabnzbd.lang.set_language(cfg.language())
|
||||
sabnzbd.api.clear_trans_cache()
|
||||
|
||||
@@ -524,12 +534,12 @@ def set_https_verification(value):
|
||||
|
||||
|
||||
def guard_https_ver():
|
||||
""" Callback for change of https verification """
|
||||
"""Callback for change of https verification"""
|
||||
set_https_verification(cfg.enable_https_verification())
|
||||
|
||||
|
||||
def add_url(url, pp=None, script=None, cat=None, priority=None, nzbname=None, password=None):
|
||||
""" Add NZB based on a URL, attributes optional """
|
||||
"""Add NZB based on a URL, attributes optional"""
|
||||
if "http" not in url:
|
||||
return
|
||||
if not pp or pp == "-1":
|
||||
@@ -558,7 +568,7 @@ def add_url(url, pp=None, script=None, cat=None, priority=None, nzbname=None, pa
|
||||
|
||||
|
||||
def save_state():
|
||||
""" Save all internal bookkeeping to disk """
|
||||
"""Save all internal bookkeeping to disk"""
|
||||
config.save_config()
|
||||
sabnzbd.ArticleCache.flush_articles()
|
||||
sabnzbd.NzbQueue.save()
|
||||
@@ -570,14 +580,14 @@ def save_state():
|
||||
|
||||
|
||||
def pause_all():
|
||||
""" Pause all activities than cause disk access """
|
||||
"""Pause all activities than cause disk access"""
|
||||
sabnzbd.PAUSED_ALL = True
|
||||
sabnzbd.Downloader.pause()
|
||||
logging.debug("PAUSED_ALL active")
|
||||
|
||||
|
||||
def unpause_all():
|
||||
""" Resume all activities """
|
||||
"""Resume all activities"""
|
||||
sabnzbd.PAUSED_ALL = False
|
||||
sabnzbd.Downloader.resume()
|
||||
logging.debug("PAUSED_ALL inactive")
|
||||
@@ -589,20 +599,20 @@ def unpause_all():
|
||||
|
||||
|
||||
def backup_exists(filename: str) -> bool:
|
||||
""" Return True if backup exists and no_dupes is set """
|
||||
"""Return True if backup exists and no_dupes is set"""
|
||||
path = cfg.nzb_backup_dir.get_path()
|
||||
return path and os.path.exists(os.path.join(path, filename + ".gz"))
|
||||
|
||||
|
||||
def backup_nzb(filename: str, data: AnyStr):
|
||||
""" Backup NZB file """
|
||||
"""Backup NZB file"""
|
||||
path = cfg.nzb_backup_dir.get_path()
|
||||
if path:
|
||||
save_compressed(path, filename, data)
|
||||
|
||||
|
||||
def save_compressed(folder: str, filename: str, data: AnyStr):
|
||||
""" Save compressed NZB file in folder """
|
||||
"""Save compressed NZB file in folder"""
|
||||
if filename.endswith(".nzb"):
|
||||
filename += ".gz"
|
||||
else:
|
||||
@@ -718,7 +728,7 @@ def add_nzbfile(
|
||||
|
||||
|
||||
def enable_server(server):
|
||||
""" Enable server (scheduler only) """
|
||||
"""Enable server (scheduler only)"""
|
||||
try:
|
||||
config.get_config("servers", server).enable.set(1)
|
||||
except:
|
||||
@@ -729,7 +739,7 @@ def enable_server(server):
|
||||
|
||||
|
||||
def disable_server(server):
|
||||
""" Disable server (scheduler only) """
|
||||
"""Disable server (scheduler only)"""
|
||||
try:
|
||||
config.get_config("servers", server).enable.set(0)
|
||||
except:
|
||||
@@ -740,7 +750,7 @@ def disable_server(server):
|
||||
|
||||
|
||||
def system_shutdown():
|
||||
""" Shutdown system after halting download and saving bookkeeping """
|
||||
"""Shutdown system after halting download and saving bookkeeping"""
|
||||
logging.info("Performing system shutdown")
|
||||
|
||||
Thread(target=halt).start()
|
||||
@@ -756,7 +766,7 @@ def system_shutdown():
|
||||
|
||||
|
||||
def system_hibernate():
|
||||
""" Hibernate system """
|
||||
"""Hibernate system"""
|
||||
logging.info("Performing system hybernation")
|
||||
if sabnzbd.WIN32:
|
||||
powersup.win_hibernate()
|
||||
@@ -767,7 +777,7 @@ def system_hibernate():
|
||||
|
||||
|
||||
def system_standby():
|
||||
""" Standby system """
|
||||
"""Standby system"""
|
||||
logging.info("Performing system standby")
|
||||
if sabnzbd.WIN32:
|
||||
powersup.win_standby()
|
||||
@@ -778,7 +788,7 @@ def system_standby():
|
||||
|
||||
|
||||
def restart_program():
|
||||
""" Restart program (used by scheduler) """
|
||||
"""Restart program (used by scheduler)"""
|
||||
logging.info("Scheduled restart request")
|
||||
# Just set the stop flag, because stopping CherryPy from
|
||||
# the scheduler is not reliable
|
||||
@@ -821,7 +831,7 @@ def change_queue_complete_action(action, new=True):
|
||||
|
||||
|
||||
def run_script(script):
|
||||
""" Run a user script (queue complete only) """
|
||||
"""Run a user script (queue complete only)"""
|
||||
script_path = filesystem.make_script_path(script)
|
||||
if script_path:
|
||||
try:
|
||||
@@ -832,7 +842,7 @@ def run_script(script):
|
||||
|
||||
|
||||
def keep_awake():
|
||||
""" If we still have work to do, keep Windows/macOS system awake """
|
||||
"""If we still have work to do, keep Windows/macOS system awake"""
|
||||
if KERNEL32 or FOUNDATION:
|
||||
if sabnzbd.cfg.keep_awake():
|
||||
ES_CONTINUOUS = 0x80000000
|
||||
@@ -880,7 +890,7 @@ def get_new_id(prefix, folder, check_list=None):
|
||||
|
||||
|
||||
def save_data(data, _id, path, do_pickle=True, silent=False):
|
||||
""" Save data to a diskfile """
|
||||
"""Save data to a diskfile"""
|
||||
if not silent:
|
||||
logging.debug("[%s] Saving data for %s in %s", misc.caller_name(), _id, path)
|
||||
path = os.path.join(path, _id)
|
||||
@@ -907,7 +917,7 @@ def save_data(data, _id, path, do_pickle=True, silent=False):
|
||||
|
||||
|
||||
def load_data(data_id, path, remove=True, do_pickle=True, silent=False):
|
||||
""" Read data from disk file """
|
||||
"""Read data from disk file"""
|
||||
path = os.path.join(path, data_id)
|
||||
|
||||
if not os.path.exists(path):
|
||||
@@ -939,7 +949,7 @@ def load_data(data_id, path, remove=True, do_pickle=True, silent=False):
|
||||
|
||||
|
||||
def remove_data(_id: str, path: str):
|
||||
""" Remove admin file """
|
||||
"""Remove admin file"""
|
||||
path = os.path.join(path, _id)
|
||||
try:
|
||||
if os.path.exists(path):
|
||||
@@ -949,19 +959,19 @@ def remove_data(_id: str, path: str):
|
||||
|
||||
|
||||
def save_admin(data: Any, data_id: str):
|
||||
""" Save data in admin folder in specified format """
|
||||
"""Save data in admin folder in specified format"""
|
||||
logging.debug("[%s] Saving data for %s", misc.caller_name(), data_id)
|
||||
save_data(data, data_id, cfg.admin_dir.get_path())
|
||||
|
||||
|
||||
def load_admin(data_id: str, remove=False, silent=False) -> Any:
|
||||
""" Read data in admin folder in specified format """
|
||||
"""Read data in admin folder in specified format"""
|
||||
logging.debug("[%s] Loading data for %s", misc.caller_name(), data_id)
|
||||
return load_data(data_id, cfg.admin_dir.get_path(), remove=remove, silent=silent)
|
||||
|
||||
|
||||
def request_repair():
|
||||
""" Request a full repair on next restart """
|
||||
"""Request a full repair on next restart"""
|
||||
path = os.path.join(cfg.admin_dir.get_path(), REPAIR_REQUEST)
|
||||
try:
|
||||
with open(path, "w") as f:
|
||||
@@ -971,7 +981,7 @@ def request_repair():
|
||||
|
||||
|
||||
def check_repair_request():
|
||||
""" Return True if repair request found, remove afterwards """
|
||||
"""Return True if repair request found, remove afterwards"""
|
||||
path = os.path.join(cfg.admin_dir.get_path(), REPAIR_REQUEST)
|
||||
if os.path.exists(path):
|
||||
try:
|
||||
@@ -1034,7 +1044,7 @@ def check_all_tasks():
|
||||
|
||||
|
||||
def pid_file(pid_path=None, pid_file=None, port=0):
|
||||
""" Create or remove pid file """
|
||||
"""Create or remove pid file"""
|
||||
if not sabnzbd.WIN32:
|
||||
if pid_path and pid_path.startswith("/"):
|
||||
sabnzbd.DIR_PID = os.path.join(pid_path, "sabnzbd-%d.pid" % port)
|
||||
@@ -1067,14 +1077,14 @@ def check_incomplete_vs_complete():
|
||||
|
||||
|
||||
def wait_for_download_folder():
|
||||
""" Wait for download folder to become available """
|
||||
"""Wait for download folder to become available"""
|
||||
while not cfg.download_dir.test_path():
|
||||
logging.debug('Waiting for "incomplete" folder')
|
||||
time.sleep(2.0)
|
||||
|
||||
|
||||
def test_ipv6():
|
||||
""" Check if external IPv6 addresses are reachable """
|
||||
"""Check if external IPv6 addresses are reachable"""
|
||||
if not cfg.selftest_host():
|
||||
# User disabled the test, assume active IPv6
|
||||
return True
|
||||
@@ -1102,7 +1112,7 @@ def test_ipv6():
|
||||
|
||||
|
||||
def test_cert_checking():
|
||||
""" Test quality of certificate validation """
|
||||
"""Test quality of certificate validation"""
|
||||
# User disabled the test, assume proper SSL certificates
|
||||
if not cfg.selftest_host():
|
||||
return True
|
||||
@@ -1129,7 +1139,7 @@ def test_cert_checking():
|
||||
|
||||
|
||||
def history_updated():
|
||||
""" To make sure we always have a fresh history """
|
||||
"""To make sure we always have a fresh history"""
|
||||
sabnzbd.LAST_HISTORY_UPDATE += 1
|
||||
# Never go over the limit
|
||||
if sabnzbd.LAST_HISTORY_UPDATE + 1 >= sys.maxsize:
|
||||
|
||||
268
sabnzbd/api.py
268
sabnzbd/api.py
@@ -29,7 +29,7 @@ import json
|
||||
import cherrypy
|
||||
import locale
|
||||
from threading import Thread
|
||||
from typing import List, Tuple
|
||||
from typing import Tuple, Optional, List
|
||||
|
||||
import sabnzbd
|
||||
from sabnzbd.constants import (
|
||||
@@ -59,10 +59,11 @@ from sabnzbd.misc import (
|
||||
opts_to_pp,
|
||||
)
|
||||
from sabnzbd.filesystem import diskspace, get_ext, clip_path, remove_all, list_scripts
|
||||
from sabnzbd.encoding import xml_name
|
||||
from sabnzbd.encoding import xml_name, utob
|
||||
from sabnzbd.utils.servertests import test_nntp_server_dict
|
||||
from sabnzbd.getipaddress import localipv4, publicipv4, ipv6, addresslookup
|
||||
from sabnzbd.database import build_history_info, unpack_history_info, HistoryDB
|
||||
from sabnzbd.lang import is_rtl
|
||||
import sabnzbd.notifier
|
||||
import sabnzbd.rss
|
||||
import sabnzbd.emailer
|
||||
@@ -85,26 +86,7 @@ _MSG_BAD_SERVER_PARMS = "Incorrect server settings"
|
||||
|
||||
|
||||
def api_handler(kwargs):
|
||||
""" API Dispatcher """
|
||||
if cfg.api_logging():
|
||||
# Was it proxy forwarded?
|
||||
xff = cherrypy.request.headers.get("X-Forwarded-For")
|
||||
if xff:
|
||||
logging.debug(
|
||||
"API-call from %s (X-Forwarded-For: %s) [%s] %s",
|
||||
cherrypy.request.remote.ip,
|
||||
xff,
|
||||
cherrypy.request.headers.get("User-Agent", "??"),
|
||||
kwargs,
|
||||
)
|
||||
else:
|
||||
logging.debug(
|
||||
"API-call from %s [%s] %s",
|
||||
cherrypy.request.remote.ip,
|
||||
cherrypy.request.headers.get("User-Agent", "??"),
|
||||
kwargs,
|
||||
)
|
||||
|
||||
"""API Dispatcher"""
|
||||
# Clean-up the arguments
|
||||
for vr in ("mode", "output", "name"):
|
||||
if vr in kwargs and isinstance(kwargs[vr], list):
|
||||
@@ -114,23 +96,18 @@ def api_handler(kwargs):
|
||||
output = kwargs.get("output", "")
|
||||
name = kwargs.get("name", "")
|
||||
|
||||
if mode not in ("version", "auth"):
|
||||
msg = sabnzbd.interface.check_apikey(kwargs)
|
||||
if msg:
|
||||
return report(output, msg)
|
||||
|
||||
response = _api_table.get(mode, (_api_undefined, 2))[0](name, output, kwargs)
|
||||
return response
|
||||
|
||||
|
||||
def _api_get_config(name, output, kwargs):
|
||||
""" API: accepts output, keyword, section """
|
||||
"""API: accepts output, keyword, section"""
|
||||
_, data = config.get_dconfig(kwargs.get("section"), kwargs.get("keyword"))
|
||||
return report(output, keyword="config", data=data)
|
||||
|
||||
|
||||
def _api_set_config(name, output, kwargs):
|
||||
""" API: accepts output, keyword, section """
|
||||
"""API: accepts output, keyword, section"""
|
||||
if cfg.configlock():
|
||||
return report(output, _MSG_CONFIG_LOCKED)
|
||||
if kwargs.get("section") == "servers":
|
||||
@@ -149,7 +126,7 @@ def _api_set_config(name, output, kwargs):
|
||||
|
||||
|
||||
def _api_set_config_default(name, output, kwargs):
|
||||
""" API: Reset requested config variables back to defaults. Currently only for misc-section """
|
||||
"""API: Reset requested config variables back to defaults. Currently only for misc-section"""
|
||||
if cfg.configlock():
|
||||
return report(output, _MSG_CONFIG_LOCKED)
|
||||
keywords = kwargs.get("keyword", [])
|
||||
@@ -164,7 +141,7 @@ def _api_set_config_default(name, output, kwargs):
|
||||
|
||||
|
||||
def _api_del_config(name, output, kwargs):
|
||||
""" API: accepts output, keyword, section """
|
||||
"""API: accepts output, keyword, section"""
|
||||
if cfg.configlock():
|
||||
return report(output, _MSG_CONFIG_LOCKED)
|
||||
if del_from_section(kwargs):
|
||||
@@ -174,13 +151,13 @@ def _api_del_config(name, output, kwargs):
|
||||
|
||||
|
||||
def _api_queue(name, output, kwargs):
|
||||
""" API: Dispatcher for mode=queue """
|
||||
"""API: Dispatcher for mode=queue"""
|
||||
value = kwargs.get("value", "")
|
||||
return _api_queue_table.get(name, (_api_queue_default, 2))[0](output, value, kwargs)
|
||||
|
||||
|
||||
def _api_queue_delete(output, value, kwargs):
|
||||
""" API: accepts output, value """
|
||||
"""API: accepts output, value"""
|
||||
if value.lower() == "all":
|
||||
removed = sabnzbd.NzbQueue.remove_all(kwargs.get("search"))
|
||||
return report(output, keyword="", data={"status": bool(removed), "nzo_ids": removed})
|
||||
@@ -194,7 +171,7 @@ def _api_queue_delete(output, value, kwargs):
|
||||
|
||||
|
||||
def _api_queue_delete_nzf(output, value, kwargs):
|
||||
""" API: accepts value(=nzo_id), value2(=nzf_id) """
|
||||
"""API: accepts value(=nzo_id), value2(=nzf_id)"""
|
||||
value2 = kwargs.get("value2")
|
||||
if value and value2:
|
||||
removed = sabnzbd.NzbQueue.remove_nzf(value, value2, force_delete=True)
|
||||
@@ -204,7 +181,7 @@ def _api_queue_delete_nzf(output, value, kwargs):
|
||||
|
||||
|
||||
def _api_queue_rename(output, value, kwargs):
|
||||
""" API: accepts output, value(=old name), value2(=new name), value3(=password) """
|
||||
"""API: accepts output, value(=old name), value2(=new name), value3(=password)"""
|
||||
value2 = kwargs.get("value2")
|
||||
value3 = kwargs.get("value3")
|
||||
if value and value2:
|
||||
@@ -215,19 +192,19 @@ def _api_queue_rename(output, value, kwargs):
|
||||
|
||||
|
||||
def _api_queue_change_complete_action(output, value, kwargs):
|
||||
""" API: accepts output, value(=action) """
|
||||
"""API: accepts output, value(=action)"""
|
||||
sabnzbd.change_queue_complete_action(value)
|
||||
return report(output)
|
||||
|
||||
|
||||
def _api_queue_purge(output, value, kwargs):
|
||||
""" API: accepts output """
|
||||
"""API: accepts output"""
|
||||
removed = sabnzbd.NzbQueue.remove_all(kwargs.get("search"))
|
||||
return report(output, keyword="", data={"status": bool(removed), "nzo_ids": removed})
|
||||
|
||||
|
||||
def _api_queue_pause(output, value, kwargs):
|
||||
""" API: accepts output, value(=list of nzo_id) """
|
||||
"""API: accepts output, value(=list of nzo_id)"""
|
||||
if value:
|
||||
items = value.split(",")
|
||||
handled = sabnzbd.NzbQueue.pause_multiple_nzo(items)
|
||||
@@ -237,7 +214,7 @@ def _api_queue_pause(output, value, kwargs):
|
||||
|
||||
|
||||
def _api_queue_resume(output, value, kwargs):
|
||||
""" API: accepts output, value(=list of nzo_id) """
|
||||
"""API: accepts output, value(=list of nzo_id)"""
|
||||
if value:
|
||||
items = value.split(",")
|
||||
handled = sabnzbd.NzbQueue.resume_multiple_nzo(items)
|
||||
@@ -247,7 +224,7 @@ def _api_queue_resume(output, value, kwargs):
|
||||
|
||||
|
||||
def _api_queue_priority(output, value, kwargs):
|
||||
""" API: accepts output, value(=nzo_id), value2(=priority) """
|
||||
"""API: accepts output, value(=nzo_id), value2(=priority)"""
|
||||
value2 = kwargs.get("value2")
|
||||
if value and value2:
|
||||
try:
|
||||
@@ -265,7 +242,7 @@ def _api_queue_priority(output, value, kwargs):
|
||||
|
||||
|
||||
def _api_queue_sort(output, value, kwargs):
|
||||
""" API: accepts output, sort, dir """
|
||||
"""API: accepts output, sort, dir"""
|
||||
sort = kwargs.get("sort")
|
||||
direction = kwargs.get("dir", "")
|
||||
if sort:
|
||||
@@ -276,7 +253,7 @@ def _api_queue_sort(output, value, kwargs):
|
||||
|
||||
|
||||
def _api_queue_default(output, value, kwargs):
|
||||
""" API: accepts output, sort, dir, start, limit """
|
||||
"""API: accepts output, sort, dir, start, limit"""
|
||||
start = int_conv(kwargs.get("start"))
|
||||
limit = int_conv(kwargs.get("limit"))
|
||||
search = kwargs.get("search")
|
||||
@@ -287,7 +264,7 @@ def _api_queue_default(output, value, kwargs):
|
||||
|
||||
|
||||
def _api_queue_rating(output, value, kwargs):
|
||||
""" API: accepts output, value(=nzo_id), type, setting, detail """
|
||||
"""API: accepts output, value(=nzo_id), type, setting, detail"""
|
||||
vote_map = {"up": sabnzbd.Rating.VOTE_UP, "down": sabnzbd.Rating.VOTE_DOWN}
|
||||
flag_map = {
|
||||
"spam": sabnzbd.Rating.FLAG_SPAM,
|
||||
@@ -319,17 +296,17 @@ def _api_queue_rating(output, value, kwargs):
|
||||
|
||||
|
||||
def _api_options(name, output, kwargs):
|
||||
""" API: accepts output """
|
||||
"""API: accepts output"""
|
||||
return options_list(output)
|
||||
|
||||
|
||||
def _api_translate(name, output, kwargs):
|
||||
""" API: accepts output, value(=acronym) """
|
||||
"""API: accepts output, value(=acronym)"""
|
||||
return report(output, keyword="value", data=T(kwargs.get("value", "")))
|
||||
|
||||
|
||||
def _api_addfile(name, output, kwargs):
|
||||
""" API: accepts name, output, pp, script, cat, priority, nzbname """
|
||||
"""API: accepts name, output, pp, script, cat, priority, nzbname"""
|
||||
# Normal upload will send the nzb in a kw arg called name or nzbfile
|
||||
if not name or isinstance(name, str):
|
||||
name = kwargs.get("nzbfile", None)
|
||||
@@ -355,7 +332,7 @@ def _api_addfile(name, output, kwargs):
|
||||
|
||||
|
||||
def _api_retry(name, output, kwargs):
|
||||
""" API: accepts name, output, value(=nzo_id), nzbfile(=optional NZB), password (optional) """
|
||||
"""API: accepts name, output, value(=nzo_id), nzbfile(=optional NZB), password (optional)"""
|
||||
value = kwargs.get("value")
|
||||
# Normal upload will send the nzb in a kw arg called nzbfile
|
||||
if name is None or isinstance(name, str):
|
||||
@@ -371,7 +348,7 @@ def _api_retry(name, output, kwargs):
|
||||
|
||||
|
||||
def _api_cancel_pp(name, output, kwargs):
|
||||
""" API: accepts name, output, value(=nzo_id) """
|
||||
"""API: accepts name, output, value(=nzo_id)"""
|
||||
nzo_id = kwargs.get("value")
|
||||
if sabnzbd.PostProcessor.cancel_pp(nzo_id):
|
||||
return report(output, keyword="", data={"status": True, "nzo_id": nzo_id})
|
||||
@@ -380,7 +357,7 @@ def _api_cancel_pp(name, output, kwargs):
|
||||
|
||||
|
||||
def _api_addlocalfile(name, output, kwargs):
|
||||
""" API: accepts name, output, pp, script, cat, priority, nzbname """
|
||||
"""API: accepts name, output, pp, script, cat, priority, nzbname"""
|
||||
if name:
|
||||
if os.path.exists(name):
|
||||
pp = kwargs.get("pp")
|
||||
@@ -418,7 +395,7 @@ def _api_addlocalfile(name, output, kwargs):
|
||||
|
||||
|
||||
def _api_switch(name, output, kwargs):
|
||||
""" API: accepts output, value(=first id), value2(=second id) """
|
||||
"""API: accepts output, value(=first id), value2(=second id)"""
|
||||
value = kwargs.get("value")
|
||||
value2 = kwargs.get("value2")
|
||||
if value and value2:
|
||||
@@ -430,7 +407,7 @@ def _api_switch(name, output, kwargs):
|
||||
|
||||
|
||||
def _api_change_cat(name, output, kwargs):
|
||||
""" API: accepts output, value(=nzo_id), value2(=category) """
|
||||
"""API: accepts output, value(=nzo_id), value2(=category)"""
|
||||
value = kwargs.get("value")
|
||||
value2 = kwargs.get("value2")
|
||||
if value and value2:
|
||||
@@ -445,7 +422,7 @@ def _api_change_cat(name, output, kwargs):
|
||||
|
||||
|
||||
def _api_change_script(name, output, kwargs):
|
||||
""" API: accepts output, value(=nzo_id), value2(=script) """
|
||||
"""API: accepts output, value(=nzo_id), value2(=script)"""
|
||||
value = kwargs.get("value")
|
||||
value2 = kwargs.get("value2")
|
||||
if value and value2:
|
||||
@@ -460,7 +437,7 @@ def _api_change_script(name, output, kwargs):
|
||||
|
||||
|
||||
def _api_change_opts(name, output, kwargs):
|
||||
""" API: accepts output, value(=nzo_id), value2(=pp) """
|
||||
"""API: accepts output, value(=nzo_id), value2(=pp)"""
|
||||
value = kwargs.get("value")
|
||||
value2 = kwargs.get("value2")
|
||||
result = 0
|
||||
@@ -470,13 +447,13 @@ def _api_change_opts(name, output, kwargs):
|
||||
|
||||
|
||||
def _api_fullstatus(name, output, kwargs):
|
||||
""" API: full history status"""
|
||||
"""API: full history status"""
|
||||
status = build_status(skip_dashboard=kwargs.get("skip_dashboard", 1), output=output)
|
||||
return report(output, keyword="status", data=status)
|
||||
|
||||
|
||||
def _api_history(name, output, kwargs):
|
||||
""" API: accepts output, value(=nzo_id), start, limit, search, nzo_ids """
|
||||
"""API: accepts output, value(=nzo_id), start, limit, search, nzo_ids"""
|
||||
value = kwargs.get("value", "")
|
||||
start = int_conv(kwargs.get("start"))
|
||||
limit = int_conv(kwargs.get("limit"))
|
||||
@@ -493,6 +470,9 @@ def _api_history(name, output, kwargs):
|
||||
if categories and not isinstance(categories, list):
|
||||
categories = [categories]
|
||||
|
||||
if nzo_ids and not isinstance(nzo_ids, list):
|
||||
nzo_ids = nzo_ids.split(",")
|
||||
|
||||
if not limit:
|
||||
limit = cfg.history_limit()
|
||||
|
||||
@@ -537,7 +517,7 @@ def _api_history(name, output, kwargs):
|
||||
|
||||
|
||||
def _api_get_files(name, output, kwargs):
|
||||
""" API: accepts output, value(=nzo_id) """
|
||||
"""API: accepts output, value(=nzo_id)"""
|
||||
value = kwargs.get("value")
|
||||
if value:
|
||||
return report(output, keyword="files", data=build_file_list(value))
|
||||
@@ -546,7 +526,7 @@ def _api_get_files(name, output, kwargs):
|
||||
|
||||
|
||||
def _api_addurl(name, output, kwargs):
|
||||
""" API: accepts name, output, pp, script, cat, priority, nzbname """
|
||||
"""API: accepts name, output, pp, script, cat, priority, nzbname"""
|
||||
pp = kwargs.get("pp")
|
||||
script = kwargs.get("script")
|
||||
cat = kwargs.get("cat")
|
||||
@@ -564,27 +544,27 @@ def _api_addurl(name, output, kwargs):
|
||||
|
||||
|
||||
def _api_pause(name, output, kwargs):
|
||||
""" API: accepts output """
|
||||
"""API: accepts output"""
|
||||
sabnzbd.Scheduler.plan_resume(0)
|
||||
sabnzbd.Downloader.pause()
|
||||
return report(output)
|
||||
|
||||
|
||||
def _api_resume(name, output, kwargs):
|
||||
""" API: accepts output """
|
||||
"""API: accepts output"""
|
||||
sabnzbd.Scheduler.plan_resume(0)
|
||||
sabnzbd.unpause_all()
|
||||
return report(output)
|
||||
|
||||
|
||||
def _api_shutdown(name, output, kwargs):
|
||||
""" API: accepts output """
|
||||
"""API: accepts output"""
|
||||
sabnzbd.shutdown_program()
|
||||
return report(output)
|
||||
|
||||
|
||||
def _api_warnings(name, output, kwargs):
|
||||
""" API: accepts name, output """
|
||||
"""API: accepts name, output"""
|
||||
if name == "clear":
|
||||
return report(output, keyword="warnings", data=sabnzbd.GUIHANDLER.clear())
|
||||
elif name == "show":
|
||||
@@ -595,22 +575,22 @@ def _api_warnings(name, output, kwargs):
|
||||
|
||||
|
||||
def _api_get_cats(name, output, kwargs):
|
||||
""" API: accepts output """
|
||||
"""API: accepts output"""
|
||||
return report(output, keyword="categories", data=list_cats(False))
|
||||
|
||||
|
||||
def _api_get_scripts(name, output, kwargs):
|
||||
""" API: accepts output """
|
||||
"""API: accepts output"""
|
||||
return report(output, keyword="scripts", data=list_scripts())
|
||||
|
||||
|
||||
def _api_version(name, output, kwargs):
|
||||
""" API: accepts output """
|
||||
"""API: accepts output"""
|
||||
return report(output, keyword="version", data=sabnzbd.__version__)
|
||||
|
||||
|
||||
def _api_auth(name, output, kwargs):
|
||||
""" API: accepts output """
|
||||
"""API: accepts output"""
|
||||
auth = "None"
|
||||
if not cfg.disable_key():
|
||||
auth = "badkey"
|
||||
@@ -628,7 +608,7 @@ def _api_auth(name, output, kwargs):
|
||||
|
||||
|
||||
def _api_restart(name, output, kwargs):
|
||||
""" API: accepts output """
|
||||
"""API: accepts output"""
|
||||
logging.info("Restart requested by API")
|
||||
# Do the shutdown async to still send goodbye to browser
|
||||
Thread(target=sabnzbd.trigger_restart, kwargs={"timeout": 1}).start()
|
||||
@@ -636,7 +616,7 @@ def _api_restart(name, output, kwargs):
|
||||
|
||||
|
||||
def _api_restart_repair(name, output, kwargs):
|
||||
""" API: accepts output """
|
||||
"""API: accepts output"""
|
||||
logging.info("Queue repair requested by API")
|
||||
sabnzbd.request_repair()
|
||||
# Do the shutdown async to still send goodbye to browser
|
||||
@@ -645,26 +625,26 @@ def _api_restart_repair(name, output, kwargs):
|
||||
|
||||
|
||||
def _api_disconnect(name, output, kwargs):
|
||||
""" API: accepts output """
|
||||
"""API: accepts output"""
|
||||
sabnzbd.Downloader.disconnect()
|
||||
return report(output)
|
||||
|
||||
|
||||
def _api_osx_icon(name, output, kwargs):
|
||||
""" API: accepts output, value """
|
||||
"""API: accepts output, value"""
|
||||
value = kwargs.get("value", "1").strip()
|
||||
cfg.osx_menu.set(value != "0")
|
||||
return report(output)
|
||||
|
||||
|
||||
def _api_rescan(name, output, kwargs):
|
||||
""" API: accepts output """
|
||||
"""API: accepts output"""
|
||||
sabnzbd.NzbQueue.scan_jobs(all_jobs=False, action=True)
|
||||
return report(output)
|
||||
|
||||
|
||||
def _api_eval_sort(name, output, kwargs):
|
||||
""" API: evaluate sorting expression """
|
||||
"""API: evaluate sorting expression"""
|
||||
name = kwargs.get("name", "")
|
||||
value = kwargs.get("value", "")
|
||||
title = kwargs.get("title")
|
||||
@@ -677,43 +657,43 @@ def _api_eval_sort(name, output, kwargs):
|
||||
|
||||
|
||||
def _api_watched_now(name, output, kwargs):
|
||||
""" API: accepts output """
|
||||
"""API: accepts output"""
|
||||
sabnzbd.DirScanner.scan()
|
||||
return report(output)
|
||||
|
||||
|
||||
def _api_resume_pp(name, output, kwargs):
|
||||
""" API: accepts output """
|
||||
"""API: accepts output"""
|
||||
sabnzbd.PostProcessor.paused = False
|
||||
return report(output)
|
||||
|
||||
|
||||
def _api_pause_pp(name, output, kwargs):
|
||||
""" API: accepts output """
|
||||
"""API: accepts output"""
|
||||
sabnzbd.PostProcessor.paused = True
|
||||
return report(output)
|
||||
|
||||
|
||||
def _api_rss_now(name, output, kwargs):
|
||||
""" API: accepts output """
|
||||
"""API: accepts output"""
|
||||
# Run RSS scan async, because it can take a long time
|
||||
sabnzbd.Scheduler.force_rss()
|
||||
return report(output)
|
||||
|
||||
|
||||
def _api_retry_all(name, output, kwargs):
|
||||
""" API: Retry all failed items in History """
|
||||
"""API: Retry all failed items in History"""
|
||||
return report(output, keyword="status", data=retry_all_jobs())
|
||||
|
||||
|
||||
def _api_reset_quota(name, output, kwargs):
|
||||
""" Reset quota left """
|
||||
"""Reset quota left"""
|
||||
sabnzbd.BPSMeter.reset_quota(force=True)
|
||||
return report(output)
|
||||
|
||||
|
||||
def _api_test_email(name, output, kwargs):
|
||||
""" API: send a test email, return result """
|
||||
"""API: send a test email, return result"""
|
||||
logging.info("Sending test email")
|
||||
pack = {"download": ["action 1", "action 2"], "unpack": ["action 1", "action 2"]}
|
||||
res = sabnzbd.emailer.endjob(
|
||||
@@ -735,61 +715,61 @@ def _api_test_email(name, output, kwargs):
|
||||
|
||||
|
||||
def _api_test_windows(name, output, kwargs):
|
||||
""" API: send a test to Windows, return result """
|
||||
"""API: send a test to Windows, return result"""
|
||||
logging.info("Sending test notification")
|
||||
res = sabnzbd.notifier.send_windows("SABnzbd", T("Test Notification"), "other")
|
||||
return report(output, error=res)
|
||||
|
||||
|
||||
def _api_test_notif(name, output, kwargs):
|
||||
""" API: send a test to Notification Center, return result """
|
||||
"""API: send a test to Notification Center, return result"""
|
||||
logging.info("Sending test notification")
|
||||
res = sabnzbd.notifier.send_notification_center("SABnzbd", T("Test Notification"), "other")
|
||||
return report(output, error=res)
|
||||
|
||||
|
||||
def _api_test_osd(name, output, kwargs):
|
||||
""" API: send a test OSD notification, return result """
|
||||
"""API: send a test OSD notification, return result"""
|
||||
logging.info("Sending OSD notification")
|
||||
res = sabnzbd.notifier.send_notify_osd("SABnzbd", T("Test Notification"))
|
||||
return report(output, error=res)
|
||||
|
||||
|
||||
def _api_test_prowl(name, output, kwargs):
|
||||
""" API: send a test Prowl notification, return result """
|
||||
"""API: send a test Prowl notification, return result"""
|
||||
logging.info("Sending Prowl notification")
|
||||
res = sabnzbd.notifier.send_prowl("SABnzbd", T("Test Notification"), "other", force=True, test=kwargs)
|
||||
return report(output, error=res)
|
||||
|
||||
|
||||
def _api_test_pushover(name, output, kwargs):
|
||||
""" API: send a test Pushover notification, return result """
|
||||
"""API: send a test Pushover notification, return result"""
|
||||
logging.info("Sending Pushover notification")
|
||||
res = sabnzbd.notifier.send_pushover("SABnzbd", T("Test Notification"), "other", force=True, test=kwargs)
|
||||
return report(output, error=res)
|
||||
|
||||
|
||||
def _api_test_pushbullet(name, output, kwargs):
|
||||
""" API: send a test Pushbullet notification, return result """
|
||||
"""API: send a test Pushbullet notification, return result"""
|
||||
logging.info("Sending Pushbullet notification")
|
||||
res = sabnzbd.notifier.send_pushbullet("SABnzbd", T("Test Notification"), "other", force=True, test=kwargs)
|
||||
return report(output, error=res)
|
||||
|
||||
|
||||
def _api_test_nscript(name, output, kwargs):
|
||||
""" API: execute a test notification script, return result """
|
||||
"""API: execute a test notification script, return result"""
|
||||
logging.info("Executing notification script")
|
||||
res = sabnzbd.notifier.send_nscript("SABnzbd", T("Test Notification"), "other", force=True, test=kwargs)
|
||||
return report(output, error=res)
|
||||
|
||||
|
||||
def _api_undefined(name, output, kwargs):
|
||||
""" API: accepts output """
|
||||
"""API: accepts output"""
|
||||
return report(output, _MSG_NOT_IMPLEMENTED)
|
||||
|
||||
|
||||
def _api_browse(name, output, kwargs):
|
||||
""" Return tree of local path """
|
||||
"""Return tree of local path"""
|
||||
compact = kwargs.get("compact")
|
||||
|
||||
if compact and compact == "1":
|
||||
@@ -803,14 +783,14 @@ def _api_browse(name, output, kwargs):
|
||||
|
||||
|
||||
def _api_config(name, output, kwargs):
|
||||
""" API: Dispatcher for "config" """
|
||||
"""API: Dispatcher for "config" """
|
||||
if cfg.configlock():
|
||||
return report(output, _MSG_CONFIG_LOCKED)
|
||||
return _api_config_table.get(name, (_api_config_undefined, 2))[0](output, kwargs)
|
||||
|
||||
|
||||
def _api_config_speedlimit(output, kwargs):
|
||||
""" API: accepts output, value(=speed) """
|
||||
"""API: accepts output, value(=speed)"""
|
||||
value = kwargs.get("value")
|
||||
if not value:
|
||||
value = "0"
|
||||
@@ -819,12 +799,12 @@ def _api_config_speedlimit(output, kwargs):
|
||||
|
||||
|
||||
def _api_config_get_speedlimit(output, kwargs):
|
||||
""" API: accepts output """
|
||||
"""API: accepts output"""
|
||||
return report(output, keyword="speedlimit", data=sabnzbd.Downloader.get_limit())
|
||||
|
||||
|
||||
def _api_config_set_colorscheme(output, kwargs):
|
||||
""" API: accepts output"""
|
||||
"""API: accepts output"""
|
||||
value = kwargs.get("value")
|
||||
if value:
|
||||
cfg.web_color.set(value)
|
||||
@@ -834,21 +814,21 @@ def _api_config_set_colorscheme(output, kwargs):
|
||||
|
||||
|
||||
def _api_config_set_pause(output, kwargs):
|
||||
""" API: accepts output, value(=pause interval) """
|
||||
"""API: accepts output, value(=pause interval)"""
|
||||
value = kwargs.get("value")
|
||||
sabnzbd.Scheduler.plan_resume(int_conv(value))
|
||||
return report(output)
|
||||
|
||||
|
||||
def _api_config_set_apikey(output, kwargs):
|
||||
""" API: accepts output """
|
||||
"""API: accepts output"""
|
||||
cfg.api_key.set(config.create_api_key())
|
||||
config.save_config()
|
||||
return report(output, keyword="apikey", data=cfg.api_key())
|
||||
|
||||
|
||||
def _api_config_set_nzbkey(output, kwargs):
|
||||
""" API: accepts output """
|
||||
"""API: accepts output"""
|
||||
cfg.nzb_key.set(config.create_api_key())
|
||||
config.save_config()
|
||||
return report(output, keyword="nzbkey", data=cfg.nzb_key())
|
||||
@@ -869,7 +849,7 @@ def _api_config_regenerate_certs(output, kwargs):
|
||||
|
||||
|
||||
def _api_config_test_server(output, kwargs):
|
||||
""" API: accepts output, server-params """
|
||||
"""API: accepts output, server-params"""
|
||||
result, msg = test_nntp_server_dict(kwargs)
|
||||
response = {"result": result, "message": msg}
|
||||
if output:
|
||||
@@ -879,12 +859,12 @@ def _api_config_test_server(output, kwargs):
|
||||
|
||||
|
||||
def _api_config_undefined(output, kwargs):
|
||||
""" API: accepts output """
|
||||
"""API: accepts output"""
|
||||
return report(output, _MSG_NOT_IMPLEMENTED)
|
||||
|
||||
|
||||
def _api_server_stats(name, output, kwargs):
|
||||
""" API: accepts output """
|
||||
"""API: accepts output"""
|
||||
sum_t, sum_m, sum_w, sum_d = sabnzbd.BPSMeter.get_sums()
|
||||
stats = {"total": sum_t, "month": sum_m, "week": sum_w, "day": sum_d, "servers": {}}
|
||||
|
||||
@@ -944,27 +924,27 @@ _api_table = {
|
||||
"version": (_api_version, 1),
|
||||
"auth": (_api_auth, 1),
|
||||
"restart": (_api_restart, 3),
|
||||
"restart_repair": (_api_restart_repair, 2),
|
||||
"restart_repair": (_api_restart_repair, 3),
|
||||
"disconnect": (_api_disconnect, 2),
|
||||
"osx_icon": (_api_osx_icon, 3),
|
||||
"gc_stats": (_api_gc_stats, 3),
|
||||
"rescan": (_api_rescan, 2),
|
||||
"eval_sort": (_api_eval_sort, 2),
|
||||
"eval_sort": (_api_eval_sort, 3),
|
||||
"watched_now": (_api_watched_now, 2),
|
||||
"resume_pp": (_api_resume_pp, 2),
|
||||
"pause_pp": (_api_pause_pp, 2),
|
||||
"rss_now": (_api_rss_now, 2),
|
||||
"browse": (_api_browse, 2),
|
||||
"browse": (_api_browse, 3),
|
||||
"retry_all": (_api_retry_all, 2),
|
||||
"reset_quota": (_api_reset_quota, 2),
|
||||
"test_email": (_api_test_email, 2),
|
||||
"test_windows": (_api_test_windows, 2),
|
||||
"test_notif": (_api_test_notif, 2),
|
||||
"test_osd": (_api_test_osd, 2),
|
||||
"test_pushover": (_api_test_pushover, 2),
|
||||
"test_pushbullet": (_api_test_pushbullet, 2),
|
||||
"test_prowl": (_api_test_prowl, 2),
|
||||
"test_nscript": (_api_test_nscript, 2),
|
||||
"reset_quota": (_api_reset_quota, 3),
|
||||
"test_email": (_api_test_email, 3),
|
||||
"test_windows": (_api_test_windows, 3),
|
||||
"test_notif": (_api_test_notif, 3),
|
||||
"test_osd": (_api_test_osd, 3),
|
||||
"test_pushover": (_api_test_pushover, 3),
|
||||
"test_pushbullet": (_api_test_pushbullet, 3),
|
||||
"test_prowl": (_api_test_prowl, 3),
|
||||
"test_nscript": (_api_test_nscript, 3),
|
||||
}
|
||||
|
||||
_api_queue_table = {
|
||||
@@ -984,23 +964,24 @@ _api_config_table = {
|
||||
"speedlimit": (_api_config_speedlimit, 2),
|
||||
"set_speedlimit": (_api_config_speedlimit, 2),
|
||||
"get_speedlimit": (_api_config_get_speedlimit, 2),
|
||||
"set_colorscheme": (_api_config_set_colorscheme, 2),
|
||||
"set_pause": (_api_config_set_pause, 2),
|
||||
"set_colorscheme": (_api_config_set_colorscheme, 3),
|
||||
"set_apikey": (_api_config_set_apikey, 3),
|
||||
"set_nzbkey": (_api_config_set_nzbkey, 3),
|
||||
"regenerate_certs": (_api_config_regenerate_certs, 3),
|
||||
"test_server": (_api_config_test_server, 2),
|
||||
"test_server": (_api_config_test_server, 3),
|
||||
}
|
||||
|
||||
|
||||
def api_level(cmd, name):
|
||||
""" Return access level required for this API call """
|
||||
if cmd in _api_table:
|
||||
return _api_table[cmd][1]
|
||||
if name == "queue" and cmd in _api_queue_table:
|
||||
return _api_queue_table[cmd][1]
|
||||
if name == "config" and cmd in _api_config_table:
|
||||
return _api_config_table[cmd][1]
|
||||
def api_level(mode: str, name: str) -> int:
|
||||
"""Return access level required for this API call"""
|
||||
if mode == "queue" and name in _api_queue_table:
|
||||
return _api_queue_table[name][1]
|
||||
if mode == "config" and name in _api_config_table:
|
||||
return _api_config_table[name][1]
|
||||
if mode in _api_table:
|
||||
return _api_table[mode][1]
|
||||
# It is invalid if it's none of these, but that's is handled somewhere else
|
||||
return 4
|
||||
|
||||
|
||||
@@ -1021,7 +1002,7 @@ def report(output, error=None, keyword="value", data=None):
|
||||
info = data
|
||||
else:
|
||||
info = {keyword: data}
|
||||
response = json.dumps(info).encode("utf-8")
|
||||
response = utob(json.dumps(info))
|
||||
|
||||
elif output == "xml":
|
||||
if not keyword:
|
||||
@@ -1110,7 +1091,7 @@ class xml_factory:
|
||||
|
||||
|
||||
def handle_server_api(output, kwargs):
|
||||
""" Special handler for API-call 'set_config' [servers] """
|
||||
"""Special handler for API-call 'set_config' [servers]"""
|
||||
name = kwargs.get("keyword")
|
||||
if not name:
|
||||
name = kwargs.get("name")
|
||||
@@ -1128,7 +1109,7 @@ def handle_server_api(output, kwargs):
|
||||
|
||||
|
||||
def handle_rss_api(output, kwargs):
|
||||
""" Special handler for API-call 'set_config' [rss] """
|
||||
"""Special handler for API-call 'set_config' [rss]"""
|
||||
name = kwargs.get("keyword")
|
||||
if not name:
|
||||
name = kwargs.get("name")
|
||||
@@ -1162,7 +1143,7 @@ def handle_rss_api(output, kwargs):
|
||||
|
||||
|
||||
def handle_cat_api(output, kwargs):
|
||||
""" Special handler for API-call 'set_config' [categories] """
|
||||
"""Special handler for API-call 'set_config' [categories]"""
|
||||
name = kwargs.get("keyword")
|
||||
if not name:
|
||||
name = kwargs.get("name")
|
||||
@@ -1406,7 +1387,7 @@ def build_queue(start=0, limit=0, trans=False, output=None, search=None, nzo_ids
|
||||
|
||||
|
||||
def fast_queue() -> Tuple[bool, int, float, str]:
|
||||
""" Return paused, bytes_left, bpsnow, time_left """
|
||||
"""Return paused, bytes_left, bpsnow, time_left"""
|
||||
bytes_left = sabnzbd.sabnzbd.NzbQueue.remaining()
|
||||
paused = sabnzbd.Downloader.paused
|
||||
bpsnow = sabnzbd.BPSMeter.bps
|
||||
@@ -1486,7 +1467,7 @@ def options_list(output):
|
||||
|
||||
|
||||
def retry_job(job, new_nzb=None, password=None):
|
||||
""" Re enter failed job in the download queue """
|
||||
"""Re enter failed job in the download queue"""
|
||||
if job:
|
||||
history_db = sabnzbd.get_db_connection()
|
||||
futuretype, url, pp, script, cat = history_db.get_other(job)
|
||||
@@ -1503,7 +1484,7 @@ def retry_job(job, new_nzb=None, password=None):
|
||||
|
||||
|
||||
def retry_all_jobs():
|
||||
""" Re enter all failed jobs in the download queue """
|
||||
"""Re enter all failed jobs in the download queue"""
|
||||
# Fetch all retryable folders from History
|
||||
items = sabnzbd.api.build_history()[0]
|
||||
nzo_ids = []
|
||||
@@ -1514,14 +1495,14 @@ def retry_all_jobs():
|
||||
|
||||
|
||||
def del_job_files(job_paths):
|
||||
""" Remove files of each path in the list """
|
||||
"""Remove files of each path in the list"""
|
||||
for path in job_paths:
|
||||
if path and clip_path(path).lower().startswith(cfg.download_dir.get_clipped_path().lower()):
|
||||
remove_all(path, recursive=True)
|
||||
|
||||
|
||||
def del_hist_job(job, del_files):
|
||||
""" Remove history element """
|
||||
"""Remove history element"""
|
||||
if job:
|
||||
path = sabnzbd.PostProcessor.get_path(job)
|
||||
if path:
|
||||
@@ -1533,7 +1514,7 @@ def del_hist_job(job, del_files):
|
||||
|
||||
|
||||
def Tspec(txt):
|
||||
""" Translate special terms """
|
||||
"""Translate special terms"""
|
||||
if txt == "None":
|
||||
return T("None")
|
||||
elif txt in ("Default", "*"):
|
||||
@@ -1562,14 +1543,14 @@ def Ttemplate(txt):
|
||||
|
||||
|
||||
def clear_trans_cache():
|
||||
""" Clean cache for skin translations """
|
||||
"""Clean cache for skin translations"""
|
||||
global _SKIN_CACHE
|
||||
_SKIN_CACHE = {}
|
||||
sabnzbd.WEBUI_READY = True
|
||||
|
||||
|
||||
def build_header(webdir="", output=None, trans_functions=True):
|
||||
""" Build the basic header """
|
||||
"""Build the basic header"""
|
||||
try:
|
||||
uptime = calc_age(sabnzbd.START)
|
||||
except:
|
||||
@@ -1600,6 +1581,7 @@ def build_header(webdir="", output=None, trans_functions=True):
|
||||
header["restart_req"] = sabnzbd.RESTART_REQ
|
||||
header["pid"] = os.getpid()
|
||||
header["active_lang"] = cfg.language()
|
||||
header["rtl"] = is_rtl(header["active_lang"])
|
||||
|
||||
header["my_lcldata"] = clip_path(sabnzbd.DIR_LCLDATA)
|
||||
header["my_home"] = clip_path(sabnzbd.DIR_HOME)
|
||||
@@ -1646,7 +1628,7 @@ def build_header(webdir="", output=None, trans_functions=True):
|
||||
|
||||
|
||||
def build_queue_header(search=None, nzo_ids=None, start=0, limit=0, output=None):
|
||||
""" Build full queue header """
|
||||
"""Build full queue header"""
|
||||
|
||||
header = build_header(output=output)
|
||||
|
||||
@@ -1683,7 +1665,14 @@ def build_queue_header(search=None, nzo_ids=None, start=0, limit=0, output=None)
|
||||
return header, qnfo.list, bytespersec, qnfo.q_fullsize, qnfo.bytes_left_previous_page
|
||||
|
||||
|
||||
def build_history(start=0, limit=0, search=None, failed_only=0, categories=None, nzo_ids=None):
|
||||
def build_history(
|
||||
start: int = 0,
|
||||
limit: int = 0,
|
||||
search: Optional[str] = None,
|
||||
failed_only: int = 0,
|
||||
categories: Optional[List[str]] = None,
|
||||
nzo_ids: Optional[List[str]] = None,
|
||||
):
|
||||
"""Combine the jobs still in post-processing and the database history"""
|
||||
if not limit:
|
||||
limit = 1000000
|
||||
@@ -1706,6 +1695,9 @@ def build_history(start=0, limit=0, search=None, failed_only=0, categories=None,
|
||||
except:
|
||||
logging.error(T("Failed to compile regex for search term: %s"), search_text)
|
||||
|
||||
if nzo_ids:
|
||||
postproc_queue = [nzo for nzo in postproc_queue if nzo.nzo_id in nzo_ids]
|
||||
|
||||
# Multi-page support for postproc items
|
||||
postproc_queue_size = len(postproc_queue)
|
||||
if start > postproc_queue_size:
|
||||
@@ -1790,7 +1782,7 @@ def build_history(start=0, limit=0, search=None, failed_only=0, categories=None,
|
||||
|
||||
|
||||
def get_active_history(queue, items):
|
||||
""" Get the currently in progress and active history queue. """
|
||||
"""Get the currently in progress and active history queue."""
|
||||
for nzo in queue:
|
||||
item = {}
|
||||
(
|
||||
@@ -1833,7 +1825,7 @@ def get_active_history(queue, items):
|
||||
|
||||
|
||||
def calc_timeleft(bytesleft, bps):
|
||||
""" Calculate the time left in the format HH:MM:SS """
|
||||
"""Calculate the time left in the format HH:MM:SS"""
|
||||
try:
|
||||
if bytesleft <= 0:
|
||||
return "0:00:00"
|
||||
@@ -1885,7 +1877,7 @@ def plural_to_single(kw, def_kw=""):
|
||||
|
||||
|
||||
def del_from_section(kwargs):
|
||||
""" Remove keyword in section """
|
||||
"""Remove keyword in section"""
|
||||
section = kwargs.get("section", "")
|
||||
if section in ("servers", "rss", "categories"):
|
||||
keyword = kwargs.get("keyword")
|
||||
@@ -1903,7 +1895,7 @@ def del_from_section(kwargs):
|
||||
|
||||
|
||||
def history_remove_failed():
|
||||
""" Remove all failed jobs from history, including files """
|
||||
"""Remove all failed jobs from history, including files"""
|
||||
logging.info("Scheduled removal of all failed jobs")
|
||||
with HistoryDB() as history_db:
|
||||
del_job_files(history_db.get_failed_paths())
|
||||
@@ -1911,7 +1903,7 @@ def history_remove_failed():
|
||||
|
||||
|
||||
def history_remove_completed():
|
||||
""" Remove all completed jobs from history """
|
||||
"""Remove all completed jobs from history"""
|
||||
logging.info("Scheduled removal of all completed jobs")
|
||||
with HistoryDB() as history_db:
|
||||
history_db.remove_completed()
|
||||
|
||||
@@ -55,7 +55,7 @@ class ArticleCache:
|
||||
return ANFO(len(self.__article_table), abs(self.__cache_size), self.__cache_limit_org)
|
||||
|
||||
def new_limit(self, limit: int):
|
||||
""" Called when cache limit changes """
|
||||
"""Called when cache limit changes"""
|
||||
self.__cache_limit_org = limit
|
||||
if limit < 0:
|
||||
self.__cache_limit = self.__cache_upper_limit
|
||||
@@ -70,20 +70,20 @@ class ArticleCache:
|
||||
|
||||
@synchronized(ARTICLE_COUNTER_LOCK)
|
||||
def reserve_space(self, data_size: int):
|
||||
""" Reserve space in the cache """
|
||||
"""Reserve space in the cache"""
|
||||
self.__cache_size += data_size
|
||||
|
||||
@synchronized(ARTICLE_COUNTER_LOCK)
|
||||
def free_reserved_space(self, data_size: int):
|
||||
""" Remove previously reserved space """
|
||||
"""Remove previously reserved space"""
|
||||
self.__cache_size -= data_size
|
||||
|
||||
def space_left(self) -> bool:
|
||||
""" Is there space left in the set limit? """
|
||||
"""Is there space left in the set limit?"""
|
||||
return self.__cache_size < self.__cache_limit
|
||||
|
||||
def save_article(self, article: Article, data: bytes):
|
||||
""" Save article in cache, either memory or disk """
|
||||
"""Save article in cache, either memory or disk"""
|
||||
nzo = article.nzf.nzo
|
||||
if nzo.is_gone():
|
||||
# Do not discard this article because the
|
||||
@@ -115,7 +115,7 @@ class ArticleCache:
|
||||
self.__flush_article_to_disk(article, data)
|
||||
|
||||
def load_article(self, article: Article):
|
||||
""" Load the data of the article """
|
||||
"""Load the data of the article"""
|
||||
data = None
|
||||
nzo = article.nzf.nzo
|
||||
|
||||
@@ -145,7 +145,7 @@ class ArticleCache:
|
||||
logging.debug("Failed to flush item from cache, probably already deleted or written to disk")
|
||||
|
||||
def purge_articles(self, articles: List[Article]):
|
||||
""" Remove all saved articles, from memory and disk """
|
||||
"""Remove all saved articles, from memory and disk"""
|
||||
logging.debug("Purging %s articles from the cache/disk", len(articles))
|
||||
for article in articles:
|
||||
if article in self.__article_table:
|
||||
|
||||
@@ -30,7 +30,15 @@ from typing import Tuple, Optional, List
|
||||
|
||||
import sabnzbd
|
||||
from sabnzbd.misc import get_all_passwords, match_str
|
||||
from sabnzbd.filesystem import set_permissions, clip_path, has_win_device, diskspace, get_filename, get_ext
|
||||
from sabnzbd.filesystem import (
|
||||
set_permissions,
|
||||
clip_path,
|
||||
has_win_device,
|
||||
diskspace,
|
||||
get_filename,
|
||||
get_ext,
|
||||
has_unwanted_extension,
|
||||
)
|
||||
from sabnzbd.constants import Status, GIGI, MAX_ASSEMBLER_QUEUE
|
||||
import sabnzbd.cfg as cfg
|
||||
from sabnzbd.nzbstuff import NzbObject, NzbFile
|
||||
@@ -259,7 +267,7 @@ SAFE_EXTS = (".mkv", ".mp4", ".avi", ".wmv", ".mpg", ".webm")
|
||||
|
||||
|
||||
def is_cloaked(nzo: NzbObject, path: str, names: List[str]) -> bool:
|
||||
""" Return True if this is likely to be a cloaked encrypted post """
|
||||
"""Return True if this is likely to be a cloaked encrypted post"""
|
||||
fname = os.path.splitext(get_filename(path.lower()))[0]
|
||||
for name in names:
|
||||
name = get_filename(name.lower())
|
||||
@@ -288,7 +296,7 @@ def is_cloaked(nzo: NzbObject, path: str, names: List[str]) -> bool:
|
||||
|
||||
|
||||
def check_encrypted_and_unwanted_files(nzo: NzbObject, filepath: str) -> Tuple[bool, Optional[str]]:
|
||||
""" Combines check for unwanted and encrypted files to save on CPU and IO """
|
||||
"""Combines check for unwanted and encrypted files to save on CPU and IO"""
|
||||
encrypted = False
|
||||
unwanted = None
|
||||
|
||||
@@ -334,29 +342,30 @@ def check_encrypted_and_unwanted_files(nzo: NzbObject, filepath: str) -> Tuple[b
|
||||
zf.setpassword(password)
|
||||
except rarfile.Error:
|
||||
# On weird passwords the setpassword() will fail
|
||||
# but the actual rartest() will work
|
||||
# but the actual testrar() will work
|
||||
pass
|
||||
try:
|
||||
zf.testrar()
|
||||
password_hit = password
|
||||
break
|
||||
except rarfile.RarWrongPassword:
|
||||
# This one really didn't work
|
||||
pass
|
||||
except rarfile.RarCRCError as e:
|
||||
# CRC errors can be thrown for wrong password or
|
||||
# missing the next volume (with correct password)
|
||||
if "cannot find volume" in str(e).lower():
|
||||
# We assume this one worked!
|
||||
password_hit = password
|
||||
break
|
||||
# This one didn't work
|
||||
pass
|
||||
except Exception as e:
|
||||
# Did we start from the right volume? Skip the checks for now.
|
||||
if match_str(
|
||||
str(e).lower(),
|
||||
("need to start extraction from a previous volume", "non-fatal error"),
|
||||
):
|
||||
return encrypted, unwanted
|
||||
# This one failed
|
||||
pass
|
||||
except:
|
||||
# All the other errors we skip, they might be fixable in post-proc.
|
||||
# For example starting from the wrong volume, or damaged files
|
||||
# This will cause the check to be performed again for the next rar, might
|
||||
# be disk-intensive! Could be removed later and just accept the password.
|
||||
return encrypted, unwanted
|
||||
|
||||
# Did any work?
|
||||
if password_hit:
|
||||
@@ -376,7 +385,7 @@ def check_encrypted_and_unwanted_files(nzo: NzbObject, filepath: str) -> Tuple[b
|
||||
if cfg.unwanted_extensions() and cfg.action_on_unwanted_extensions():
|
||||
for somefile in zf.namelist():
|
||||
logging.debug("File contains: %s", somefile)
|
||||
if get_ext(somefile).replace(".", "").lower() in cfg.unwanted_extensions():
|
||||
if has_unwanted_extension(somefile):
|
||||
logging.debug("Unwanted file %s", somefile)
|
||||
unwanted = somefile
|
||||
zf.close()
|
||||
|
||||
@@ -26,6 +26,7 @@ from typing import List, Dict, Optional
|
||||
|
||||
import sabnzbd
|
||||
from sabnzbd.constants import BYTES_FILE_NAME, KIBI
|
||||
from sabnzbd.misc import to_units
|
||||
import sabnzbd.cfg as cfg
|
||||
|
||||
DAY = float(24 * 60 * 60)
|
||||
@@ -38,14 +39,14 @@ RE_HHMM = re.compile(r"(\d+):(\d+)\s*$")
|
||||
|
||||
|
||||
def tomorrow(t: float) -> float:
|
||||
""" Return timestamp for tomorrow (midnight) """
|
||||
"""Return timestamp for tomorrow (midnight)"""
|
||||
now = time.localtime(t)
|
||||
ntime = (now[0], now[1], now[2], 0, 0, 0, now[6], now[7], now[8])
|
||||
return time.mktime(ntime) + DAY
|
||||
|
||||
|
||||
def this_week(t: float) -> float:
|
||||
""" Return timestamp for start of this week (monday) """
|
||||
"""Return timestamp for start of this week (monday)"""
|
||||
while 1:
|
||||
tm = time.localtime(t)
|
||||
if tm.tm_wday == 0:
|
||||
@@ -56,19 +57,19 @@ def this_week(t: float) -> float:
|
||||
|
||||
|
||||
def next_week(t: float) -> float:
|
||||
""" Return timestamp for start of next week (monday) """
|
||||
"""Return timestamp for start of next week (monday)"""
|
||||
return this_week(t) + WEEK
|
||||
|
||||
|
||||
def this_month(t: float) -> float:
|
||||
""" Return timestamp for start of next month """
|
||||
"""Return timestamp for start of next month"""
|
||||
now = time.localtime(t)
|
||||
ntime = (now[0], now[1], 1, 0, 0, 0, 0, 0, now[8])
|
||||
return time.mktime(ntime)
|
||||
|
||||
|
||||
def last_month_day(tm: time.struct_time) -> int:
|
||||
""" Return last day of this month """
|
||||
"""Return last day of this month"""
|
||||
year, month = tm[:2]
|
||||
day = DAYS[month]
|
||||
# This simple formula for leap years is good enough
|
||||
@@ -78,7 +79,7 @@ def last_month_day(tm: time.struct_time) -> int:
|
||||
|
||||
|
||||
def next_month(t: float) -> float:
|
||||
""" Return timestamp for start of next month """
|
||||
"""Return timestamp for start of next month"""
|
||||
now = time.localtime(t)
|
||||
month = now.tm_mon + 1
|
||||
year = now.tm_year
|
||||
@@ -100,6 +101,8 @@ class BPSMeter:
|
||||
self.bps_list: List[int] = []
|
||||
|
||||
self.server_bps: Dict[str, float] = {}
|
||||
self.cached_amount: Dict[str, int] = {}
|
||||
self.sum_cached_amount: int = 0
|
||||
self.day_total: Dict[str, int] = {}
|
||||
self.week_total: Dict[str, int] = {}
|
||||
self.month_total: Dict[str, int] = {}
|
||||
@@ -125,7 +128,7 @@ class BPSMeter:
|
||||
self.quota_enabled: bool = True # Scheduled quota enable/disable
|
||||
|
||||
def save(self):
|
||||
""" Save admin to disk """
|
||||
"""Save admin to disk"""
|
||||
sabnzbd.save_admin(
|
||||
(
|
||||
self.last_update,
|
||||
@@ -147,7 +150,7 @@ class BPSMeter:
|
||||
)
|
||||
|
||||
def defaults(self):
|
||||
""" Get the latest data from the database and assign to a fake server """
|
||||
"""Get the latest data from the database and assign to a fake server"""
|
||||
logging.debug("Setting default BPS meter values")
|
||||
with sabnzbd.database.HistoryDB() as history_db:
|
||||
grand, month, week = history_db.get_history_size()
|
||||
@@ -164,7 +167,7 @@ class BPSMeter:
|
||||
self.quota = self.left = cfg.quota_size.get_float()
|
||||
|
||||
def read(self):
|
||||
""" Read admin from disk, return True when pause is needed """
|
||||
"""Read admin from disk, return True when pause is needed"""
|
||||
res = False
|
||||
quota = self.left = cfg.quota_size.get_float() # Quota for this period
|
||||
self.have_quota = bool(cfg.quota_size())
|
||||
@@ -195,18 +198,24 @@ class BPSMeter:
|
||||
res = self.reset_quota()
|
||||
except:
|
||||
self.defaults()
|
||||
# Force update of counters and validate data
|
||||
try:
|
||||
for server in self.grand_total.keys():
|
||||
self.update(server)
|
||||
except TypeError:
|
||||
self.defaults()
|
||||
self.update()
|
||||
return res
|
||||
|
||||
def update(self, server: Optional[str] = None, amount: int = 0):
|
||||
""" Update counters for "server" with "amount" bytes """
|
||||
def update(self, server: Optional[str] = None, amount: int = 0, force_full_update: bool = True):
|
||||
"""Update counters for "server" with "amount" bytes"""
|
||||
t = time.time()
|
||||
|
||||
# Add amount to temporary storage
|
||||
if server:
|
||||
if server not in self.cached_amount:
|
||||
self.cached_amount[server] = 0
|
||||
self.server_bps[server] = 0.0
|
||||
self.cached_amount[server] += amount
|
||||
self.sum_cached_amount += amount
|
||||
|
||||
# Wait at least 0.05 seconds between each full update
|
||||
if not force_full_update and t - self.last_update < 0.05:
|
||||
return
|
||||
|
||||
if t > self.end_of_day:
|
||||
# current day passed. get new end of day
|
||||
self.day_label = time.strftime("%Y-%m-%d")
|
||||
@@ -221,60 +230,62 @@ class BPSMeter:
|
||||
self.month_total = {}
|
||||
self.end_of_month = next_month(t) - 1.0
|
||||
|
||||
if server:
|
||||
if server not in self.day_total:
|
||||
self.day_total[server] = 0
|
||||
self.day_total[server] += amount
|
||||
# Add amounts that have been stored temporarily to statistics
|
||||
for srv in self.cached_amount:
|
||||
cached_amount = self.cached_amount[srv]
|
||||
if cached_amount:
|
||||
self.cached_amount[srv] = 0
|
||||
if srv not in self.day_total:
|
||||
self.day_total[srv] = 0
|
||||
self.day_total[srv] += cached_amount
|
||||
|
||||
if server not in self.week_total:
|
||||
self.week_total[server] = 0
|
||||
self.week_total[server] += amount
|
||||
if srv not in self.week_total:
|
||||
self.week_total[srv] = 0
|
||||
self.week_total[srv] += cached_amount
|
||||
|
||||
if server not in self.month_total:
|
||||
self.month_total[server] = 0
|
||||
self.month_total[server] += amount
|
||||
if srv not in self.month_total:
|
||||
self.month_total[srv] = 0
|
||||
self.month_total[srv] += cached_amount
|
||||
|
||||
if server not in self.grand_total:
|
||||
self.grand_total[server] = 0
|
||||
self.grand_total[server] += amount
|
||||
if srv not in self.grand_total:
|
||||
self.grand_total[srv] = 0
|
||||
self.grand_total[srv] += cached_amount
|
||||
|
||||
if server not in self.timeline_total:
|
||||
self.timeline_total[server] = {}
|
||||
if self.day_label not in self.timeline_total[server]:
|
||||
self.timeline_total[server][self.day_label] = 0
|
||||
self.timeline_total[server][self.day_label] += amount
|
||||
if srv not in self.timeline_total:
|
||||
self.timeline_total[srv] = {}
|
||||
if self.day_label not in self.timeline_total[srv]:
|
||||
self.timeline_total[srv][self.day_label] = 0
|
||||
self.timeline_total[srv][self.day_label] += cached_amount
|
||||
|
||||
# Quota check
|
||||
if self.have_quota and self.quota_enabled:
|
||||
self.left -= amount
|
||||
if self.left <= 0.0:
|
||||
if not sabnzbd.Downloader.paused:
|
||||
sabnzbd.Downloader.pause()
|
||||
logging.warning(T("Quota spent, pausing downloading"))
|
||||
try:
|
||||
# Update server bps
|
||||
self.server_bps[srv] = (self.server_bps[srv] * (self.last_update - self.start_time) + cached_amount) / (
|
||||
t - self.start_time
|
||||
)
|
||||
except:
|
||||
self.server_bps[srv] = 0.0
|
||||
|
||||
# Quota check
|
||||
if self.have_quota and self.quota_enabled:
|
||||
self.left -= self.sum_cached_amount
|
||||
if self.left <= 0.0:
|
||||
if not sabnzbd.Downloader.paused:
|
||||
sabnzbd.Downloader.pause()
|
||||
logging.warning(T("Quota spent, pausing downloading"))
|
||||
|
||||
# Speedometer
|
||||
try:
|
||||
self.bps = (self.bps * (self.last_update - self.start_time) + amount) / (t - self.start_time)
|
||||
self.bps = (self.bps * (self.last_update - self.start_time) + self.sum_cached_amount) / (
|
||||
t - self.start_time
|
||||
)
|
||||
except:
|
||||
self.bps = 0.0
|
||||
self.server_bps = {}
|
||||
|
||||
if server and server not in self.server_bps:
|
||||
self.server_bps[server] = 0.0
|
||||
|
||||
for server_to_update in self.server_bps:
|
||||
try:
|
||||
# Only add data to the current server, update the rest to get correct average speed
|
||||
self.server_bps[server_to_update] = (
|
||||
self.server_bps[server_to_update] * (self.last_update - self.start_time)
|
||||
+ amount * (server_to_update == server)
|
||||
) / (t - self.start_time)
|
||||
except:
|
||||
self.server_bps[server_to_update] = 0.0
|
||||
|
||||
self.last_update = t
|
||||
|
||||
check_time = t - 5.0
|
||||
self.sum_cached_amount = 0
|
||||
|
||||
if self.start_time < check_time:
|
||||
self.start_time = check_time
|
||||
@@ -283,7 +294,7 @@ class BPSMeter:
|
||||
self.reset()
|
||||
|
||||
elif self.log_time < check_time:
|
||||
logging.debug("bps: %s", self.bps)
|
||||
logging.debug("Speed: %sB/s", to_units(self.bps))
|
||||
self.log_time = t
|
||||
|
||||
if self.speed_log_time < (t - 1.0):
|
||||
@@ -328,7 +339,7 @@ class BPSMeter:
|
||||
self.bps_list = self.bps_list[len(self.bps_list) - BPS_LIST_MAX :]
|
||||
|
||||
def get_sums(self):
|
||||
""" return tuple of grand, month, week, day totals """
|
||||
"""return tuple of grand, month, week, day totals"""
|
||||
return (
|
||||
sum([v for v in self.grand_total.values()]),
|
||||
sum([v for v in self.month_total.values()]),
|
||||
@@ -337,7 +348,7 @@ class BPSMeter:
|
||||
)
|
||||
|
||||
def amounts(self, server: str):
|
||||
""" Return grand, month, week, day and article totals for specified server """
|
||||
"""Return grand, month, week, day and article totals for specified server"""
|
||||
return (
|
||||
self.grand_total.get(server, 0),
|
||||
self.month_total.get(server, 0),
|
||||
@@ -349,7 +360,7 @@ class BPSMeter:
|
||||
)
|
||||
|
||||
def clear_server(self, server: str):
|
||||
""" Clean counters for specified server """
|
||||
"""Clean counters for specified server"""
|
||||
if server in self.day_total:
|
||||
del self.day_total[server]
|
||||
if server in self.week_total:
|
||||
@@ -414,7 +425,7 @@ class BPSMeter:
|
||||
return True
|
||||
|
||||
def next_reset(self, t: Optional[float] = None):
|
||||
""" Determine next reset time """
|
||||
"""Determine next reset time"""
|
||||
t = t or time.time()
|
||||
tm = time.localtime(t)
|
||||
if self.q_period == "d":
|
||||
@@ -445,7 +456,7 @@ class BPSMeter:
|
||||
logging.debug("Will reset quota at %s", tm)
|
||||
|
||||
def change_quota(self, allow_resume: bool = True):
|
||||
""" Update quota, potentially pausing downloader """
|
||||
"""Update quota, potentially pausing downloader"""
|
||||
if not self.have_quota and self.quota < 0.5:
|
||||
# Never set, use last period's size
|
||||
per = cfg.quota_period()
|
||||
@@ -475,7 +486,7 @@ class BPSMeter:
|
||||
self.resume()
|
||||
|
||||
def get_quota(self):
|
||||
""" If quota active, return check-function, hour, minute """
|
||||
"""If quota active, return check-function, hour, minute"""
|
||||
if self.have_quota:
|
||||
self.q_period = cfg.quota_period()[0].lower()
|
||||
self.q_day = 1
|
||||
@@ -504,24 +515,24 @@ class BPSMeter:
|
||||
return None, 0, 0
|
||||
|
||||
def set_status(self, status: bool, action: bool = True):
|
||||
""" Disable/enable quota management """
|
||||
"""Disable/enable quota management"""
|
||||
self.quota_enabled = status
|
||||
if action and not status:
|
||||
self.resume()
|
||||
|
||||
@staticmethod
|
||||
def resume():
|
||||
""" Resume downloading """
|
||||
"""Resume downloading"""
|
||||
if cfg.quota_resume() and sabnzbd.Downloader.paused:
|
||||
sabnzbd.Downloader.resume()
|
||||
|
||||
def midnight(self):
|
||||
""" Midnight action: dummy update for all servers """
|
||||
"""Midnight action: dummy update for all servers"""
|
||||
for server in self.day_total.keys():
|
||||
self.update(server)
|
||||
|
||||
|
||||
def quota_handler():
|
||||
""" To be called from scheduler """
|
||||
"""To be called from scheduler"""
|
||||
logging.debug("Checking quota")
|
||||
sabnzbd.BPSMeter.reset_quota()
|
||||
|
||||
@@ -69,7 +69,7 @@ def validate_email(value):
|
||||
|
||||
|
||||
def validate_server(value):
|
||||
""" Check if server non-empty"""
|
||||
"""Check if server non-empty"""
|
||||
global email_endjob, email_full, email_rss
|
||||
if value == "" and (email_endjob() or email_full() or email_rss()):
|
||||
return T("Server address required"), None
|
||||
@@ -78,8 +78,8 @@ def validate_server(value):
|
||||
|
||||
|
||||
def validate_script(value):
|
||||
""" Check if value is a valid script """
|
||||
if value and sabnzbd.filesystem.is_valid_script(value):
|
||||
"""Check if value is a valid script"""
|
||||
if not sabnzbd.__INITIALIZED__ or (value and sabnzbd.filesystem.is_valid_script(value)):
|
||||
return None, value
|
||||
elif (value and value == "None") or not value:
|
||||
return None, "None"
|
||||
@@ -133,7 +133,6 @@ https_chain = OptionDir("misc", "https_chain", create=False)
|
||||
enable_https = OptionBool("misc", "enable_https", False)
|
||||
# 0=local-only, 1=nzb, 2=api, 3=full_api, 4=webui, 5=webui with login for external
|
||||
inet_exposure = OptionNumber("misc", "inet_exposure", 0, protect=True)
|
||||
local_ranges = OptionList("misc", "local_ranges", protect=True)
|
||||
api_key = OptionStr("misc", "api_key", create_api_key())
|
||||
nzb_key = OptionStr("misc", "nzb_key", create_api_key())
|
||||
|
||||
@@ -196,6 +195,7 @@ sanitize_safe = OptionBool("misc", "sanitize_safe", False)
|
||||
cleanup_list = OptionList("misc", "cleanup_list")
|
||||
unwanted_extensions = OptionList("misc", "unwanted_extensions")
|
||||
action_on_unwanted_extensions = OptionNumber("misc", "action_on_unwanted_extensions", 0)
|
||||
unwanted_extensions_mode = OptionNumber("misc", "unwanted_extensions_mode", 0)
|
||||
new_nzb_on_failure = OptionBool("misc", "new_nzb_on_failure", False)
|
||||
history_retention = OptionStr("misc", "history_retention", "0")
|
||||
enable_meta = OptionBool("misc", "enable_meta", True)
|
||||
@@ -282,7 +282,7 @@ helpfull_warnings = OptionBool("misc", "helpfull_warnings", True)
|
||||
keep_awake = OptionBool("misc", "keep_awake", True)
|
||||
win_menu = OptionBool("misc", "win_menu", True)
|
||||
allow_incomplete_nzb = OptionBool("misc", "allow_incomplete_nzb", False)
|
||||
enable_bonjour = OptionBool("misc", "enable_bonjour", True)
|
||||
enable_broadcast = OptionBool("misc", "enable_broadcast", True)
|
||||
max_art_opt = OptionBool("misc", "max_art_opt", False)
|
||||
ipv6_hosting = OptionBool("misc", "ipv6_hosting", False)
|
||||
fixed_ports = OptionBool("misc", "fixed_ports", False)
|
||||
@@ -307,6 +307,7 @@ marker_file = OptionStr("misc", "nomedia_marker")
|
||||
ipv6_servers = OptionNumber("misc", "ipv6_servers", 1, 0, 2)
|
||||
url_base = OptionStr("misc", "url_base", "/sabnzbd", validation=validate_strip_right_slash)
|
||||
host_whitelist = OptionList("misc", "host_whitelist", validation=all_lowercase)
|
||||
local_ranges = OptionList("misc", "local_ranges", protect=True)
|
||||
max_url_retries = OptionNumber("misc", "max_url_retries", 10, 1)
|
||||
downloader_sleep_time = OptionNumber("misc", "downloader_sleep_time", 10, 0)
|
||||
ssdp_broadcast_interval = OptionNumber("misc", "ssdp_broadcast_interval", 15, 1, 600)
|
||||
|
||||
@@ -52,7 +52,7 @@ RE_PARAMFINDER = re.compile(r"""(?:'.*?')|(?:".*?")|(?:[^'",\s][^,]*)""")
|
||||
|
||||
|
||||
class Option:
|
||||
""" Basic option class, basic fields """
|
||||
"""Basic option class, basic fields"""
|
||||
|
||||
def __init__(self, section: str, keyword: str, default_val: Any = None, add: bool = True, protect: bool = False):
|
||||
"""Basic option
|
||||
@@ -81,7 +81,7 @@ class Option:
|
||||
anchor[keyword] = self
|
||||
|
||||
def get(self) -> Any:
|
||||
""" Retrieve value field """
|
||||
"""Retrieve value field"""
|
||||
if self.__value is not None:
|
||||
return self.__value
|
||||
else:
|
||||
@@ -91,11 +91,11 @@ class Option:
|
||||
return str(self.get())
|
||||
|
||||
def get_dict(self, safe: bool = False) -> Dict[str, Any]:
|
||||
""" Return value a dictionary """
|
||||
"""Return value a dictionary"""
|
||||
return {self.__keyword: self.get()}
|
||||
|
||||
def set_dict(self, values: Dict[str, Any]):
|
||||
""" Set value based on dictionary """
|
||||
"""Set value based on dictionary"""
|
||||
if not self.__protect:
|
||||
try:
|
||||
self.set(values["value"])
|
||||
@@ -103,7 +103,7 @@ class Option:
|
||||
pass
|
||||
|
||||
def set(self, value: Any):
|
||||
""" Set new value, no validation """
|
||||
"""Set new value, no validation"""
|
||||
global modified
|
||||
if value is not None:
|
||||
if isinstance(value, list) or isinstance(value, dict) or value != self.__value:
|
||||
@@ -116,11 +116,11 @@ class Option:
|
||||
return self.__default_val
|
||||
|
||||
def callback(self, callback: Callable):
|
||||
""" Set callback function """
|
||||
"""Set callback function"""
|
||||
self.__callback = callback
|
||||
|
||||
def ident(self):
|
||||
""" Return section-list and keyword """
|
||||
"""Return section-list and keyword"""
|
||||
return self.__sections, self.__keyword
|
||||
|
||||
|
||||
@@ -145,7 +145,7 @@ class OptionNumber(Option):
|
||||
super().__init__(section, keyword, default_val, add=add, protect=protect)
|
||||
|
||||
def set(self, value: Any):
|
||||
""" set new value, limited by range """
|
||||
"""set new value, limited by range"""
|
||||
if value is not None:
|
||||
try:
|
||||
if self.__int:
|
||||
@@ -165,12 +165,12 @@ class OptionNumber(Option):
|
||||
super().set(value)
|
||||
|
||||
def __call__(self) -> Union[int, float]:
|
||||
""" get() replacement """
|
||||
"""get() replacement"""
|
||||
return self.get()
|
||||
|
||||
|
||||
class OptionBool(Option):
|
||||
""" Boolean option class, always returns 0 or 1."""
|
||||
"""Boolean option class, always returns 0 or 1."""
|
||||
|
||||
def __init__(self, section: str, keyword: str, default_val: bool = False, add: bool = True, protect: bool = False):
|
||||
super().__init__(section, keyword, int(default_val), add=add, protect=protect)
|
||||
@@ -180,12 +180,12 @@ class OptionBool(Option):
|
||||
super().set(sabnzbd.misc.int_conv(value))
|
||||
|
||||
def __call__(self) -> int:
|
||||
""" get() replacement """
|
||||
"""get() replacement"""
|
||||
return int(self.get())
|
||||
|
||||
|
||||
class OptionDir(Option):
|
||||
""" Directory option class """
|
||||
"""Directory option class"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
@@ -206,7 +206,7 @@ class OptionDir(Option):
|
||||
super().__init__(section, keyword, default_val, add=add)
|
||||
|
||||
def get(self) -> str:
|
||||
""" Return value, corrected for platform """
|
||||
"""Return value, corrected for platform"""
|
||||
p = super().get()
|
||||
if sabnzbd.WIN32:
|
||||
return p.replace("/", "\\") if "/" in p else p
|
||||
@@ -214,7 +214,7 @@ class OptionDir(Option):
|
||||
return p.replace("\\", "/") if "\\" in p else p
|
||||
|
||||
def get_path(self) -> str:
|
||||
""" Return full absolute path """
|
||||
"""Return full absolute path"""
|
||||
value = self.get()
|
||||
path = ""
|
||||
if value:
|
||||
@@ -224,11 +224,11 @@ class OptionDir(Option):
|
||||
return path
|
||||
|
||||
def get_clipped_path(self) -> str:
|
||||
""" Return clipped full absolute path """
|
||||
"""Return clipped full absolute path"""
|
||||
return clip_path(self.get_path())
|
||||
|
||||
def test_path(self) -> bool:
|
||||
""" Return True if path exists """
|
||||
"""Return True if path exists"""
|
||||
value = self.get()
|
||||
if value:
|
||||
return os.path.exists(real_path(self.__root, value))
|
||||
@@ -236,7 +236,7 @@ class OptionDir(Option):
|
||||
return False
|
||||
|
||||
def set_root(self, root: str):
|
||||
""" Set new root, is assumed to be valid """
|
||||
"""Set new root, is assumed to be valid"""
|
||||
self.__root = root
|
||||
|
||||
def set(self, value: str, create: bool = False) -> Optional[str]:
|
||||
@@ -260,16 +260,16 @@ class OptionDir(Option):
|
||||
return error
|
||||
|
||||
def set_create(self, value: bool):
|
||||
""" Set auto-creation value """
|
||||
"""Set auto-creation value"""
|
||||
self.__create = value
|
||||
|
||||
def __call__(self) -> str:
|
||||
""" get() replacement """
|
||||
"""get() replacement"""
|
||||
return self.get()
|
||||
|
||||
|
||||
class OptionList(Option):
|
||||
""" List option class """
|
||||
"""List option class"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
@@ -286,7 +286,7 @@ class OptionList(Option):
|
||||
super().__init__(section, keyword, default_val, add=add, protect=protect)
|
||||
|
||||
def set(self, value: Union[str, List]) -> Optional[str]:
|
||||
""" Set the list given a comma-separated string or a list """
|
||||
"""Set the list given a comma-separated string or a list"""
|
||||
error = None
|
||||
if value is not None:
|
||||
if not isinstance(value, list):
|
||||
@@ -301,20 +301,20 @@ class OptionList(Option):
|
||||
return error
|
||||
|
||||
def get_string(self) -> str:
|
||||
""" Return the list as a comma-separated string """
|
||||
"""Return the list as a comma-separated string"""
|
||||
return ", ".join(self.get())
|
||||
|
||||
def default_string(self) -> str:
|
||||
""" Return the default list as a comma-separated string """
|
||||
"""Return the default list as a comma-separated string"""
|
||||
return ", ".join(self.default())
|
||||
|
||||
def __call__(self) -> List[str]:
|
||||
""" get() replacement """
|
||||
"""get() replacement"""
|
||||
return self.get()
|
||||
|
||||
|
||||
class OptionStr(Option):
|
||||
""" String class."""
|
||||
"""String class."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
@@ -331,15 +331,15 @@ class OptionStr(Option):
|
||||
super().__init__(section, keyword, default_val, add=add, protect=protect)
|
||||
|
||||
def get_float(self) -> float:
|
||||
""" Return value converted to a float, allowing KMGT notation """
|
||||
"""Return value converted to a float, allowing KMGT notation"""
|
||||
return sabnzbd.misc.from_units(self.get())
|
||||
|
||||
def get_int(self) -> int:
|
||||
""" Return value converted to an int, allowing KMGT notation """
|
||||
"""Return value converted to an int, allowing KMGT notation"""
|
||||
return int(self.get_float())
|
||||
|
||||
def set(self, value: Any) -> Optional[str]:
|
||||
""" Set stripped value """
|
||||
"""Set stripped value"""
|
||||
error = None
|
||||
if isinstance(value, str) and self.__strip:
|
||||
value = value.strip()
|
||||
@@ -351,46 +351,46 @@ class OptionStr(Option):
|
||||
return error
|
||||
|
||||
def __call__(self) -> str:
|
||||
""" get() replacement """
|
||||
"""get() replacement"""
|
||||
return self.get()
|
||||
|
||||
|
||||
class OptionPassword(Option):
|
||||
""" Password class. """
|
||||
"""Password class."""
|
||||
|
||||
def __init__(self, section: str, keyword: str, default_val: str = "", add: bool = True):
|
||||
self.get_string = self.get_stars
|
||||
super().__init__(section, keyword, default_val, add=add)
|
||||
|
||||
def get(self) -> Optional[str]:
|
||||
""" Return decoded password """
|
||||
"""Return decoded password"""
|
||||
return decode_password(super().get(), self.ident())
|
||||
|
||||
def get_stars(self) -> Optional[str]:
|
||||
""" Return non-descript asterisk string """
|
||||
"""Return non-descript asterisk string"""
|
||||
if self.get():
|
||||
return "*" * 10
|
||||
return ""
|
||||
|
||||
def get_dict(self, safe: bool = False) -> Dict[str, str]:
|
||||
""" Return value a dictionary """
|
||||
"""Return value a dictionary"""
|
||||
if safe:
|
||||
return {self.ident()[1]: self.get_stars()}
|
||||
else:
|
||||
return {self.ident()[1]: self.get()}
|
||||
|
||||
def set(self, pw: str):
|
||||
""" Set password, encode it """
|
||||
"""Set password, encode it"""
|
||||
if (pw is not None and pw == "") or (pw and pw.strip("*")):
|
||||
super().set(encode_password(pw))
|
||||
|
||||
def __call__(self) -> str:
|
||||
""" get() replacement """
|
||||
"""get() replacement"""
|
||||
return self.get()
|
||||
|
||||
|
||||
class ConfigServer:
|
||||
""" Class defining a single server """
|
||||
"""Class defining a single server"""
|
||||
|
||||
def __init__(self, name, values):
|
||||
|
||||
@@ -422,7 +422,7 @@ class ConfigServer:
|
||||
add_to_database("servers", self.__name, self)
|
||||
|
||||
def set_dict(self, values: Dict[str, Any]):
|
||||
""" Set one or more fields, passed as dictionary """
|
||||
"""Set one or more fields, passed as dictionary"""
|
||||
# Replace usage_at_start value with most recent statistics if the user changes the quota value
|
||||
# Only when we are updating it from the Config
|
||||
if sabnzbd.WEBUI_READY and values.get("quota", "") != self.quota():
|
||||
@@ -459,7 +459,7 @@ class ConfigServer:
|
||||
self.displayname.set(self.__name)
|
||||
|
||||
def get_dict(self, safe: bool = False) -> Dict[str, Any]:
|
||||
""" Return a dictionary with all attributes """
|
||||
"""Return a dictionary with all attributes"""
|
||||
output_dict = {}
|
||||
output_dict["name"] = self.__name
|
||||
output_dict["displayname"] = self.displayname()
|
||||
@@ -487,11 +487,11 @@ class ConfigServer:
|
||||
return output_dict
|
||||
|
||||
def delete(self):
|
||||
""" Remove from database """
|
||||
"""Remove from database"""
|
||||
delete_from_database("servers", self.__name)
|
||||
|
||||
def rename(self, name: str):
|
||||
""" Give server new display name """
|
||||
"""Give server new display name"""
|
||||
self.displayname.set(name)
|
||||
|
||||
def ident(self) -> Tuple[str, str]:
|
||||
@@ -499,7 +499,7 @@ class ConfigServer:
|
||||
|
||||
|
||||
class ConfigCat:
|
||||
""" Class defining a single category """
|
||||
"""Class defining a single category"""
|
||||
|
||||
def __init__(self, name: str, values: Dict[str, Any]):
|
||||
self.__name = name
|
||||
@@ -516,7 +516,7 @@ class ConfigCat:
|
||||
add_to_database("categories", self.__name, self)
|
||||
|
||||
def set_dict(self, values: Dict[str, Any]):
|
||||
""" Set one or more fields, passed as dictionary """
|
||||
"""Set one or more fields, passed as dictionary"""
|
||||
for kw in ("order", "pp", "script", "dir", "newzbin", "priority"):
|
||||
try:
|
||||
value = values[kw]
|
||||
@@ -525,7 +525,7 @@ class ConfigCat:
|
||||
continue
|
||||
|
||||
def get_dict(self, safe: bool = False) -> Dict[str, Any]:
|
||||
""" Return a dictionary with all attributes """
|
||||
"""Return a dictionary with all attributes"""
|
||||
output_dict = {}
|
||||
output_dict["name"] = self.__name
|
||||
output_dict["order"] = self.order()
|
||||
@@ -537,19 +537,19 @@ class ConfigCat:
|
||||
return output_dict
|
||||
|
||||
def delete(self):
|
||||
""" Remove from database """
|
||||
"""Remove from database"""
|
||||
delete_from_database("categories", self.__name)
|
||||
|
||||
|
||||
class OptionFilters(Option):
|
||||
""" Filter list class """
|
||||
"""Filter list class"""
|
||||
|
||||
def __init__(self, section, keyword, add=True):
|
||||
super().__init__(section, keyword, add=add)
|
||||
self.set([])
|
||||
|
||||
def move(self, current: int, new: int):
|
||||
""" Move filter from position 'current' to 'new' """
|
||||
"""Move filter from position 'current' to 'new'"""
|
||||
lst = self.get()
|
||||
try:
|
||||
item = lst.pop(current)
|
||||
@@ -570,7 +570,7 @@ class OptionFilters(Option):
|
||||
self.set(lst)
|
||||
|
||||
def delete(self, pos: int):
|
||||
""" Remove filter 'pos' """
|
||||
"""Remove filter 'pos'"""
|
||||
lst = self.get()
|
||||
try:
|
||||
lst.pop(pos)
|
||||
@@ -579,14 +579,14 @@ class OptionFilters(Option):
|
||||
self.set(lst)
|
||||
|
||||
def get_dict(self, safe: bool = False) -> Dict[str, str]:
|
||||
""" Return filter list as a dictionary with keys 'filter[0-9]+' """
|
||||
"""Return filter list as a dictionary with keys 'filter[0-9]+'"""
|
||||
output_dict = {}
|
||||
for n, rss_filter in enumerate(self.get()):
|
||||
output_dict[f"filter{n}"] = rss_filter
|
||||
return output_dict
|
||||
|
||||
def set_dict(self, values: Dict[str, Any]):
|
||||
""" Create filter list from dictionary with keys 'filter[0-9]+' """
|
||||
"""Create filter list from dictionary with keys 'filter[0-9]+'"""
|
||||
filters = []
|
||||
# We don't know how many filters there are, so just assume all values are filters
|
||||
for n in range(len(values)):
|
||||
@@ -597,12 +597,12 @@ class OptionFilters(Option):
|
||||
self.set(filters)
|
||||
|
||||
def __call__(self) -> List[List[str]]:
|
||||
""" get() replacement """
|
||||
"""get() replacement"""
|
||||
return self.get()
|
||||
|
||||
|
||||
class ConfigRSS:
|
||||
""" Class defining a single Feed definition """
|
||||
"""Class defining a single Feed definition"""
|
||||
|
||||
def __init__(self, name, values):
|
||||
self.__name = name
|
||||
@@ -621,7 +621,7 @@ class ConfigRSS:
|
||||
add_to_database("rss", self.__name, self)
|
||||
|
||||
def set_dict(self, values: Dict[str, Any]):
|
||||
""" Set one or more fields, passed as dictionary """
|
||||
"""Set one or more fields, passed as dictionary"""
|
||||
for kw in ("uri", "cat", "pp", "script", "priority", "enable"):
|
||||
try:
|
||||
value = values[kw]
|
||||
@@ -631,7 +631,7 @@ class ConfigRSS:
|
||||
self.filters.set_dict(values)
|
||||
|
||||
def get_dict(self, safe: bool = False) -> Dict[str, Any]:
|
||||
""" Return a dictionary with all attributes """
|
||||
"""Return a dictionary with all attributes"""
|
||||
output_dict = {}
|
||||
output_dict["name"] = self.__name
|
||||
output_dict["uri"] = self.uri()
|
||||
@@ -646,11 +646,11 @@ class ConfigRSS:
|
||||
return output_dict
|
||||
|
||||
def delete(self):
|
||||
""" Remove from database """
|
||||
"""Remove from database"""
|
||||
delete_from_database("rss", self.__name)
|
||||
|
||||
def rename(self, new_name: str):
|
||||
""" Update the name and the saved entries """
|
||||
"""Update the name and the saved entries"""
|
||||
delete_from_database("rss", self.__name)
|
||||
sabnzbd.RSSReader.rename(self.__name, new_name)
|
||||
self.__name = new_name
|
||||
@@ -662,7 +662,7 @@ class ConfigRSS:
|
||||
|
||||
@synchronized(CONFIG_LOCK)
|
||||
def add_to_database(section, keyword, obj):
|
||||
""" add object as section/keyword to INI database """
|
||||
"""add object as section/keyword to INI database"""
|
||||
global database
|
||||
if section not in database:
|
||||
database[section] = {}
|
||||
@@ -671,7 +671,7 @@ def add_to_database(section, keyword, obj):
|
||||
|
||||
@synchronized(CONFIG_LOCK)
|
||||
def delete_from_database(section, keyword):
|
||||
""" Remove section/keyword from INI database """
|
||||
"""Remove section/keyword from INI database"""
|
||||
global database, CFG, modified
|
||||
del database[section][keyword]
|
||||
if section == "servers" and "[" in keyword:
|
||||
@@ -725,7 +725,7 @@ def get_dconfig(section, keyword, nested=False):
|
||||
|
||||
|
||||
def get_config(section, keyword):
|
||||
""" Return a config object, based on 'section', 'keyword' """
|
||||
"""Return a config object, based on 'section', 'keyword'"""
|
||||
try:
|
||||
return database[section][keyword]
|
||||
except KeyError:
|
||||
@@ -734,7 +734,7 @@ def get_config(section, keyword):
|
||||
|
||||
|
||||
def set_config(kwargs):
|
||||
""" Set a config item, using values in dictionary """
|
||||
"""Set a config item, using values in dictionary"""
|
||||
try:
|
||||
item = database[kwargs.get("section")][kwargs.get("keyword")]
|
||||
except KeyError:
|
||||
@@ -744,7 +744,7 @@ def set_config(kwargs):
|
||||
|
||||
|
||||
def delete(section: str, keyword: str):
|
||||
""" Delete specific config item """
|
||||
"""Delete specific config item"""
|
||||
try:
|
||||
database[section][keyword].delete()
|
||||
except KeyError:
|
||||
@@ -842,7 +842,7 @@ def _read_config(path, try_backup=False):
|
||||
|
||||
@synchronized(SAVE_CONFIG_LOCK)
|
||||
def save_config(force=False):
|
||||
""" Update Setup file with current option values """
|
||||
"""Update Setup file with current option values"""
|
||||
global CFG, database, modified
|
||||
|
||||
if not (modified or force):
|
||||
@@ -1025,7 +1025,7 @@ class ErrorCatchingArgumentParser(argparse.ArgumentParser):
|
||||
|
||||
|
||||
def encode_password(pw):
|
||||
""" Encode password in hexadecimal if needed """
|
||||
"""Encode password in hexadecimal if needed"""
|
||||
enc = False
|
||||
if pw:
|
||||
encPW = __PW_PREFIX
|
||||
@@ -1058,7 +1058,7 @@ def decode_password(pw, name):
|
||||
|
||||
|
||||
def clean_nice_ionice_parameters(value):
|
||||
""" Verify that the passed parameters are not exploits """
|
||||
"""Verify that the passed parameters are not exploits"""
|
||||
if value:
|
||||
parser = ErrorCatchingArgumentParser()
|
||||
|
||||
@@ -1081,7 +1081,7 @@ def clean_nice_ionice_parameters(value):
|
||||
|
||||
|
||||
def all_lowercase(value):
|
||||
""" Lowercase everything! """
|
||||
"""Lowercase everything!"""
|
||||
if isinstance(value, list):
|
||||
# If list, for each item
|
||||
return None, [item.lower() for item in value]
|
||||
@@ -1089,7 +1089,7 @@ def all_lowercase(value):
|
||||
|
||||
|
||||
def validate_octal(value):
|
||||
""" Check if string is valid octal number """
|
||||
"""Check if string is valid octal number"""
|
||||
if not value:
|
||||
return None, value
|
||||
try:
|
||||
@@ -1100,7 +1100,7 @@ def validate_octal(value):
|
||||
|
||||
|
||||
def validate_no_unc(root, value, default):
|
||||
""" Check if path isn't a UNC path """
|
||||
"""Check if path isn't a UNC path"""
|
||||
# Only need to check the 'value' part
|
||||
if value and not value.startswith(r"\\"):
|
||||
return validate_notempty(root, value, default)
|
||||
@@ -1117,7 +1117,7 @@ def validate_safedir(root, value, default):
|
||||
|
||||
|
||||
def validate_notempty(root, value, default):
|
||||
""" If value is empty, return default """
|
||||
"""If value is empty, return default"""
|
||||
if value:
|
||||
return None, value
|
||||
else:
|
||||
@@ -1131,16 +1131,16 @@ def validate_strip_right_slash(value):
|
||||
return None, value
|
||||
|
||||
|
||||
def validate_single_tag(value):
|
||||
def validate_single_tag(value: List[str]) -> Tuple[None, List[str]]:
|
||||
"""Don't split single indexer tags like "TV > HD"
|
||||
into ['TV', '>', 'HD']
|
||||
"""
|
||||
if len(value) == 3:
|
||||
if value[1] == ">":
|
||||
return None, " ".join(value)
|
||||
return None, [" ".join(value)]
|
||||
return None, value
|
||||
|
||||
|
||||
def create_api_key():
|
||||
""" Return a new randomized API_KEY """
|
||||
"""Return a new randomized API_KEY"""
|
||||
return uuid.uuid4().hex
|
||||
|
||||
@@ -75,7 +75,7 @@ DEF_INTERFACES = "interfaces"
|
||||
DEF_EMAIL_TMPL = "email"
|
||||
DEF_STDCONFIG = "Config"
|
||||
DEF_STDINTF = "Glitter"
|
||||
DEF_SKIN_COLORS = {"Glitter": "Default", "plush": "gold"}
|
||||
DEF_SKIN_COLORS = {"Glitter": "Auto", "plush": "gold"}
|
||||
DEF_MAIN_TMPL = os.path.normpath("templates/main.tmpl")
|
||||
DEF_INI_FILE = "sabnzbd.ini"
|
||||
DEF_HOST = "127.0.0.1"
|
||||
@@ -124,8 +124,6 @@ CHEETAH_DIRECTIVES = {"directiveStartToken": "<!--#", "directiveEndToken": "#-->
|
||||
|
||||
IGNORED_FOLDERS = ("@eaDir", ".appleDouble")
|
||||
|
||||
LOCALHOSTS = ("localhost", "127.0.0.1", "[::1]", "::1")
|
||||
|
||||
# (MATCHER, [EXTRA, MATCHERS])
|
||||
series_match = [
|
||||
(compile(r"( [sS]|[\d]+)x(\d+)"), [compile(r"^[-\.]+([sS]|[\d])+x(\d+)"), compile(r"^[-\.](\d+)")]), # 1x01
|
||||
@@ -143,6 +141,8 @@ year_match = r"[\W]([1|2]\d{3})([^\w]|$)" # Something '(YYYY)' or '.YYYY.' or '
|
||||
|
||||
sample_match = r"((^|[\W_])(sample|proof))" # something-sample or something-proof
|
||||
|
||||
resolution_match = r"(^|[\W_])((240|360|480|540|576|720|900|1080|1440|2160|4320)[piP])([\W_]|$)" # 576i, 720p, 1080P
|
||||
|
||||
|
||||
class Status:
|
||||
COMPLETED = "Completed" # PP: Job is finished
|
||||
|
||||
@@ -26,7 +26,7 @@ import logging
|
||||
import sys
|
||||
import threading
|
||||
import sqlite3
|
||||
from typing import Union, Dict
|
||||
from typing import Union, Dict, Optional, List
|
||||
|
||||
import sabnzbd
|
||||
import sabnzbd.cfg
|
||||
@@ -41,7 +41,7 @@ DB_LOCK = threading.RLock()
|
||||
|
||||
|
||||
def convert_search(search):
|
||||
""" Convert classic wildcard to SQL wildcard """
|
||||
"""Convert classic wildcard to SQL wildcard"""
|
||||
if not search:
|
||||
# Default value
|
||||
search = ""
|
||||
@@ -75,14 +75,14 @@ class HistoryDB:
|
||||
|
||||
@synchronized(DB_LOCK)
|
||||
def __init__(self):
|
||||
""" Determine databse path and create connection """
|
||||
"""Determine databse path and create connection"""
|
||||
self.con = self.c = None
|
||||
if not HistoryDB.db_path:
|
||||
HistoryDB.db_path = os.path.join(sabnzbd.cfg.admin_dir.get_path(), DB_HISTORY_NAME)
|
||||
self.connect()
|
||||
|
||||
def connect(self):
|
||||
""" Create a connection to the database """
|
||||
"""Create a connection to the database"""
|
||||
create_table = not os.path.exists(HistoryDB.db_path)
|
||||
self.con = sqlite3.connect(HistoryDB.db_path)
|
||||
self.con.row_factory = sqlite3.Row
|
||||
@@ -117,7 +117,7 @@ class HistoryDB:
|
||||
)
|
||||
|
||||
def execute(self, command, args=(), save=False):
|
||||
""" Wrapper for executing SQL commands """
|
||||
"""Wrapper for executing SQL commands"""
|
||||
for tries in range(5, 0, -1):
|
||||
try:
|
||||
if args and isinstance(args, tuple):
|
||||
@@ -161,7 +161,7 @@ class HistoryDB:
|
||||
return False
|
||||
|
||||
def create_history_db(self):
|
||||
""" Create a new (empty) database file """
|
||||
"""Create a new (empty) database file"""
|
||||
self.execute(
|
||||
"""
|
||||
CREATE TABLE "history" (
|
||||
@@ -198,7 +198,7 @@ class HistoryDB:
|
||||
self.execute("PRAGMA user_version = 2;")
|
||||
|
||||
def close(self):
|
||||
""" Close database connection """
|
||||
"""Close database connection"""
|
||||
try:
|
||||
self.c.close()
|
||||
self.con.close()
|
||||
@@ -207,7 +207,7 @@ class HistoryDB:
|
||||
logging.info("Traceback: ", exc_info=True)
|
||||
|
||||
def remove_completed(self, search=None):
|
||||
""" Remove all completed jobs from the database, optional with `search` pattern """
|
||||
"""Remove all completed jobs from the database, optional with `search` pattern"""
|
||||
search = convert_search(search)
|
||||
logging.info("Removing all completed jobs from history")
|
||||
return self.execute(
|
||||
@@ -215,7 +215,7 @@ class HistoryDB:
|
||||
)
|
||||
|
||||
def get_failed_paths(self, search=None):
|
||||
""" Return list of all storage paths of failed jobs (may contain non-existing or empty paths) """
|
||||
"""Return list of all storage paths of failed jobs (may contain non-existing or empty paths)"""
|
||||
search = convert_search(search)
|
||||
fetch_ok = self.execute(
|
||||
"""SELECT path FROM history WHERE name LIKE ? AND status = ?""", (search, Status.FAILED)
|
||||
@@ -226,7 +226,7 @@ class HistoryDB:
|
||||
return []
|
||||
|
||||
def remove_failed(self, search=None):
|
||||
""" Remove all failed jobs from the database, optional with `search` pattern """
|
||||
"""Remove all failed jobs from the database, optional with `search` pattern"""
|
||||
search = convert_search(search)
|
||||
logging.info("Removing all failed jobs from history")
|
||||
return self.execute(
|
||||
@@ -234,7 +234,7 @@ class HistoryDB:
|
||||
)
|
||||
|
||||
def remove_history(self, jobs=None):
|
||||
""" Remove all jobs in the list `jobs`, empty list will remove all completed jobs """
|
||||
"""Remove all jobs in the list `jobs`, empty list will remove all completed jobs"""
|
||||
if jobs is None:
|
||||
self.remove_completed()
|
||||
else:
|
||||
@@ -246,7 +246,7 @@ class HistoryDB:
|
||||
logging.info("[%s] Removing job %s from history", caller_name(), job)
|
||||
|
||||
def auto_history_purge(self):
|
||||
""" Remove history items based on the configured history-retention """
|
||||
"""Remove history items based on the configured history-retention"""
|
||||
if sabnzbd.cfg.history_retention() == "0":
|
||||
return
|
||||
|
||||
@@ -279,7 +279,7 @@ class HistoryDB:
|
||||
)
|
||||
|
||||
def add_history_db(self, nzo, storage="", postproc_time=0, script_output="", script_line=""):
|
||||
""" Add a new job entry to the database """
|
||||
"""Add a new job entry to the database"""
|
||||
t = build_history_info(nzo, storage, postproc_time, script_output, script_line, series_info=True)
|
||||
|
||||
self.execute(
|
||||
@@ -292,8 +292,16 @@ class HistoryDB:
|
||||
)
|
||||
logging.info("Added job %s to history", nzo.final_name)
|
||||
|
||||
def fetch_history(self, start=None, limit=None, search=None, failed_only=0, categories=None, nzo_ids=None):
|
||||
""" Return records for specified jobs """
|
||||
def fetch_history(
|
||||
self,
|
||||
start: Optional[int] = None,
|
||||
limit: Optional[int] = None,
|
||||
search: Optional[str] = None,
|
||||
failed_only: int = 0,
|
||||
categories: Optional[List[str]] = None,
|
||||
nzo_ids: Optional[List[str]] = None,
|
||||
):
|
||||
"""Return records for specified jobs"""
|
||||
command_args = [convert_search(search)]
|
||||
|
||||
post = ""
|
||||
@@ -304,7 +312,6 @@ class HistoryDB:
|
||||
post += ")"
|
||||
command_args.extend(categories)
|
||||
if nzo_ids:
|
||||
nzo_ids = nzo_ids.split(",")
|
||||
post += " AND (NZO_ID = ?"
|
||||
post += " OR NZO_ID = ? " * (len(nzo_ids) - 1)
|
||||
post += ")"
|
||||
@@ -339,7 +346,7 @@ class HistoryDB:
|
||||
return items, fetched_items, total_items
|
||||
|
||||
def have_episode(self, series, season, episode):
|
||||
""" Check whether History contains this series episode """
|
||||
"""Check whether History contains this series episode"""
|
||||
total = 0
|
||||
series = series.lower().replace(".", " ").replace("_", " ").replace(" ", " ")
|
||||
if series and season and episode:
|
||||
@@ -351,7 +358,7 @@ class HistoryDB:
|
||||
return total > 0
|
||||
|
||||
def have_name_or_md5sum(self, name, md5sum):
|
||||
""" Check whether this name or md5sum is already in History """
|
||||
"""Check whether this name or md5sum is already in History"""
|
||||
total = 0
|
||||
if self.execute(
|
||||
"""SELECT COUNT(*) FROM History WHERE ( LOWER(name) = LOWER(?) OR md5sum = ? ) AND STATUS != ?""",
|
||||
@@ -386,7 +393,7 @@ class HistoryDB:
|
||||
return total, month, week
|
||||
|
||||
def get_script_log(self, nzo_id):
|
||||
""" Return decompressed log file """
|
||||
"""Return decompressed log file"""
|
||||
data = ""
|
||||
t = (nzo_id,)
|
||||
if self.execute("""SELECT script_log FROM history WHERE nzo_id = ?""", t):
|
||||
@@ -397,7 +404,7 @@ class HistoryDB:
|
||||
return data
|
||||
|
||||
def get_name(self, nzo_id):
|
||||
""" Return name of the job `nzo_id` """
|
||||
"""Return name of the job `nzo_id`"""
|
||||
t = (nzo_id,)
|
||||
name = ""
|
||||
if self.execute("""SELECT name FROM history WHERE nzo_id = ?""", t):
|
||||
@@ -409,7 +416,7 @@ class HistoryDB:
|
||||
return name
|
||||
|
||||
def get_path(self, nzo_id: str):
|
||||
""" Return the `incomplete` path of the job `nzo_id` if it is still there """
|
||||
"""Return the `incomplete` path of the job `nzo_id` if it is still there"""
|
||||
t = (nzo_id,)
|
||||
path = ""
|
||||
if self.execute("""SELECT path FROM history WHERE nzo_id = ?""", t):
|
||||
@@ -423,7 +430,7 @@ class HistoryDB:
|
||||
return None
|
||||
|
||||
def get_other(self, nzo_id):
|
||||
""" Return additional data for job `nzo_id` """
|
||||
"""Return additional data for job `nzo_id`"""
|
||||
t = (nzo_id,)
|
||||
if self.execute("""SELECT * FROM history WHERE nzo_id = ?""", t):
|
||||
try:
|
||||
@@ -435,11 +442,11 @@ class HistoryDB:
|
||||
return "", "", "", "", ""
|
||||
|
||||
def __enter__(self):
|
||||
""" For context manager support """
|
||||
"""For context manager support"""
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type, exc_val, exc_tb):
|
||||
""" For context manager support, ignore any exception """
|
||||
"""For context manager support, ignore any exception"""
|
||||
self.close()
|
||||
|
||||
|
||||
@@ -447,7 +454,7 @@ _PP_LOOKUP = {0: "", 1: "R", 2: "U", 3: "D"}
|
||||
|
||||
|
||||
def build_history_info(nzo, workdir_complete="", postproc_time=0, script_output="", script_line="", series_info=False):
|
||||
""" Collects all the information needed for the database """
|
||||
"""Collects all the information needed for the database"""
|
||||
completed = int(time.time())
|
||||
pp = _PP_LOOKUP.get(opts_to_pp(*nzo.repair_opts), "X")
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ except ImportError:
|
||||
|
||||
|
||||
class CrcError(Exception):
|
||||
def __init__(self, needcrc, gotcrc, data):
|
||||
def __init__(self, needcrc: int, gotcrc: int, data: bytes):
|
||||
super().__init__()
|
||||
self.needcrc = needcrc
|
||||
self.gotcrc = gotcrc
|
||||
@@ -59,7 +59,7 @@ class BadYenc(Exception):
|
||||
|
||||
|
||||
class Decoder:
|
||||
""" Implement thread-like coordinator for the decoders """
|
||||
"""Implement thread-like coordinator for the decoders"""
|
||||
|
||||
def __init__(self):
|
||||
logging.debug("Initializing decoders")
|
||||
@@ -106,7 +106,7 @@ class Decoder:
|
||||
|
||||
|
||||
class DecoderWorker(Thread):
|
||||
""" The actuall workhorse that handles decoding! """
|
||||
"""The actuall workhorse that handles decoding!"""
|
||||
|
||||
def __init__(self, decoder_queue):
|
||||
super().__init__()
|
||||
@@ -154,13 +154,16 @@ class DecoderWorker(Thread):
|
||||
sabnzbd.NzbQueue.reset_try_lists(article)
|
||||
continue
|
||||
|
||||
except CrcError:
|
||||
except CrcError as crc_error:
|
||||
logging.info("CRC Error in %s" % art_id)
|
||||
|
||||
# Continue to the next one if we found new server
|
||||
if search_new_server(article):
|
||||
continue
|
||||
|
||||
# Store data, maybe par2 can still fix it
|
||||
decoded_data = crc_error.data
|
||||
|
||||
except (BadYenc, ValueError):
|
||||
# Handles precheck and badly formed articles
|
||||
if nzo.precheck and raw_data and raw_data[0].startswith(b"223 "):
|
||||
@@ -243,7 +246,7 @@ def decode(article: Article, raw_data: List[bytes]) -> bytes:
|
||||
|
||||
|
||||
def search_new_server(article: Article) -> bool:
|
||||
""" Shorthand for searching new server or else increasing bad_articles """
|
||||
"""Shorthand for searching new server or else increasing bad_articles"""
|
||||
# Continue to the next one if we found new server
|
||||
if not article.search_new_server():
|
||||
# Increase bad articles if no new server was found
|
||||
|
||||
@@ -42,7 +42,7 @@ MIN_FILE_SIZE = 10 * 1024 * 1024
|
||||
|
||||
|
||||
def decode_par2(parfile):
|
||||
""" Parse a par2 file and rename files listed in the par2 to their real name """
|
||||
"""Parse a par2 file and rename files listed in the par2 to their real name"""
|
||||
# Check if really a par2 file
|
||||
if not is_parfile(parfile):
|
||||
logging.info("Par2 file %s was not really a par2 file")
|
||||
@@ -89,6 +89,11 @@ def is_probably_obfuscated(myinputfilename):
|
||||
# exactly 32 hex digits, so:
|
||||
return True
|
||||
|
||||
# 0675e29e9abfd2.f7d069dab0b853283cc1b069a25f82.6547
|
||||
if re.findall(r"^[a-f0-9\.]{40,}$", filebasename):
|
||||
logging.debug("Obfuscated: starting with 40+ lower case hex digits and/or dots")
|
||||
return True
|
||||
|
||||
# /some/thing/abc.xyz.a4c567edbcbf27.BLA is certainly obfuscated
|
||||
if re.findall(r"^abc\.xyz", filebasename):
|
||||
logging.debug("Obfuscated: starts with 'abc.xyz'")
|
||||
@@ -127,47 +132,81 @@ def is_probably_obfuscated(myinputfilename):
|
||||
|
||||
|
||||
def deobfuscate_list(filelist, usefulname):
|
||||
""" Check all files in filelist, and if wanted, deobfuscate """
|
||||
"""Check all files in filelist, and if wanted, deobfuscate: rename to filename based on usefulname"""
|
||||
|
||||
# to be sure, only keep really exsiting files:
|
||||
filelist = [f for f in filelist if os.path.exists(f)]
|
||||
|
||||
# Search for par2 files in the filelist
|
||||
par2_files = [f for f in filelist if f.endswith(".par2")]
|
||||
|
||||
# Found any par2 files we can use?
|
||||
run_renamer = True
|
||||
if not par2_files:
|
||||
logging.debug("No par2 files found to process, running renamer.")
|
||||
logging.debug("No par2 files found to process, running renamer")
|
||||
else:
|
||||
# Run par2 from SABnzbd on them
|
||||
for par2_file in par2_files:
|
||||
# Analyse data and analyse result
|
||||
logging.debug("Deobfuscate par2: handling %s", par2_file)
|
||||
if decode_par2(par2_file):
|
||||
logging.debug("Deobfuscate par2 repair/verify finished.")
|
||||
logging.debug("Deobfuscate par2 repair/verify finished")
|
||||
run_renamer = False
|
||||
else:
|
||||
logging.debug("Deobfuscate par2 repair/verify did not find anything to rename.")
|
||||
logging.debug("Deobfuscate par2 repair/verify did not find anything to rename")
|
||||
|
||||
# No par2 files? Then we try to rename qualifying (big, not-excluded, obfuscated) files to the job-name
|
||||
if run_renamer:
|
||||
excluded_file_exts = EXCLUDED_FILE_EXTS
|
||||
# If there is a collection with bigger files with the same extension, we don't want to rename it
|
||||
extcounter = {}
|
||||
for file in filelist:
|
||||
if os.path.getsize(file) < MIN_FILE_SIZE:
|
||||
# too small to care
|
||||
continue
|
||||
_, ext = os.path.splitext(file)
|
||||
if ext in extcounter:
|
||||
extcounter[ext] += 1
|
||||
else:
|
||||
extcounter[ext] = 1
|
||||
if extcounter[ext] >= 3 and ext not in excluded_file_exts:
|
||||
# collection, and extension not yet in excluded_file_exts, so add it
|
||||
excluded_file_exts = (*excluded_file_exts, ext)
|
||||
logging.debug(
|
||||
"Found a collection of at least %s files with extension %s, so not renaming those files",
|
||||
extcounter[ext],
|
||||
ext,
|
||||
)
|
||||
|
||||
logging.debug("Trying to see if there are qualifying files to be deobfuscated")
|
||||
# We start with he biggest file ... probably the most important file
|
||||
filelist = sorted(filelist, key=os.path.getsize, reverse=True)
|
||||
for filename in filelist:
|
||||
# check that file is still there (and not renamed by the secondary renaming process below)
|
||||
if not os.path.isfile(filename):
|
||||
continue
|
||||
logging.debug("Deobfuscate inspecting %s", filename)
|
||||
file_size = os.path.getsize(filename)
|
||||
# Do we need to rename this file?
|
||||
# Criteria: big, not-excluded extension, obfuscated (in that order)
|
||||
if (
|
||||
file_size > MIN_FILE_SIZE
|
||||
and get_ext(filename) not in EXCLUDED_FILE_EXTS
|
||||
os.path.getsize(filename) > MIN_FILE_SIZE
|
||||
and get_ext(filename) not in excluded_file_exts
|
||||
and is_probably_obfuscated(filename) # this as last test to avoid unnecessary analysis
|
||||
):
|
||||
# OK, rename
|
||||
# Rename and make sure the new filename is unique
|
||||
path, file = os.path.split(filename)
|
||||
# construct new_name: <path><usefulname><extension>
|
||||
new_name = get_unique_filename("%s%s" % (os.path.join(path, usefulname), get_ext(filename)))
|
||||
logging.info("Deobfuscate renaming %s to %s", filename, new_name)
|
||||
# Rename and make sure the new filename is unique
|
||||
renamer(filename, new_name)
|
||||
# find other files with the same basename in filelist, and rename them in the same way:
|
||||
basedirfile, _ = os.path.splitext(filename) # something like "/home/this/myiso"
|
||||
for otherfile in filelist:
|
||||
if otherfile.startswith(basedirfile + ".") and os.path.isfile(otherfile):
|
||||
# yes, same basedirfile, only different extension
|
||||
remainingextension = otherfile.replace(basedirfile, "") # might be long ext, like ".dut.srt"
|
||||
new_name = get_unique_filename("%s%s" % (os.path.join(path, usefulname), remainingextension))
|
||||
logging.info("Deobfuscate renaming %s to %s", otherfile, new_name)
|
||||
# Rename and make sure the new filename is unique
|
||||
renamer(otherfile, new_name)
|
||||
else:
|
||||
logging.info("No qualifying files found to deobfuscate")
|
||||
|
||||
@@ -106,7 +106,7 @@ class DirectUnpacker(threading.Thread):
|
||||
return True
|
||||
|
||||
def set_volumes_for_nzo(self):
|
||||
""" Loop over all files to detect the names """
|
||||
"""Loop over all files to detect the names"""
|
||||
none_counter = 0
|
||||
found_counter = 0
|
||||
for nzf in self.nzo.files + self.nzo.finished_files:
|
||||
@@ -126,7 +126,7 @@ class DirectUnpacker(threading.Thread):
|
||||
|
||||
@synchronized(START_STOP_LOCK)
|
||||
def add(self, nzf: NzbFile):
|
||||
""" Add jobs and start instance of DirectUnpack """
|
||||
"""Add jobs and start instance of DirectUnpack"""
|
||||
if not cfg.direct_unpack_tested():
|
||||
test_disk_performance()
|
||||
|
||||
@@ -350,7 +350,7 @@ class DirectUnpacker(threading.Thread):
|
||||
|
||||
@synchronized(START_STOP_LOCK)
|
||||
def create_unrar_instance(self):
|
||||
""" Start the unrar instance using the user's options """
|
||||
"""Start the unrar instance using the user's options"""
|
||||
# Generate extraction path and save for post-proc
|
||||
if not self.unpack_dir_info:
|
||||
try:
|
||||
@@ -432,7 +432,7 @@ class DirectUnpacker(threading.Thread):
|
||||
|
||||
@synchronized(START_STOP_LOCK)
|
||||
def abort(self):
|
||||
""" Abort running instance and delete generated files """
|
||||
"""Abort running instance and delete generated files"""
|
||||
if not self.killed and self.cur_setname:
|
||||
logging.info("Aborting DirectUnpack for %s", self.cur_setname)
|
||||
self.killed = True
|
||||
@@ -494,7 +494,7 @@ class DirectUnpacker(threading.Thread):
|
||||
self.reset_active()
|
||||
|
||||
def get_formatted_stats(self):
|
||||
""" Get percentage or number of rar's done """
|
||||
"""Get percentage or number of rar's done"""
|
||||
if self.cur_setname and self.cur_setname in self.total_volumes:
|
||||
# This won't work on obfuscated posts
|
||||
if self.total_volumes[self.cur_setname] >= self.cur_volume and self.cur_volume:
|
||||
@@ -520,7 +520,7 @@ def analyze_rar_filename(filename):
|
||||
|
||||
|
||||
def abort_all():
|
||||
""" Abort all running DirectUnpackers """
|
||||
"""Abort all running DirectUnpackers"""
|
||||
logging.info("Aborting all DirectUnpackers")
|
||||
for direct_unpacker in ACTIVE_UNPACKERS:
|
||||
direct_unpacker.abort()
|
||||
|
||||
@@ -32,7 +32,7 @@ import sabnzbd.cfg as cfg
|
||||
|
||||
|
||||
def compare_stat_tuple(tup1, tup2):
|
||||
""" Test equality of two stat-tuples, content-related parts only """
|
||||
"""Test equality of two stat-tuples, content-related parts only"""
|
||||
if tup1.st_ino != tup2.st_ino:
|
||||
return False
|
||||
if tup1.st_size != tup2.st_size:
|
||||
@@ -45,7 +45,7 @@ def compare_stat_tuple(tup1, tup2):
|
||||
|
||||
|
||||
def clean_file_list(inp_list, folder, files):
|
||||
""" Remove elements of "inp_list" not found in "files" """
|
||||
"""Remove elements of "inp_list" not found in "files" """
|
||||
for path in sorted(inp_list):
|
||||
fld, name = os.path.split(path)
|
||||
if fld == folder:
|
||||
@@ -89,31 +89,31 @@ class DirScanner(threading.Thread):
|
||||
cfg.dirscan_speed.callback(self.newspeed)
|
||||
|
||||
def newdir(self):
|
||||
""" We're notified of a dir change """
|
||||
"""We're notified of a dir change"""
|
||||
self.ignored = {}
|
||||
self.suspected = {}
|
||||
self.dirscan_dir = cfg.dirscan_dir.get_path()
|
||||
self.dirscan_speed = cfg.dirscan_speed()
|
||||
|
||||
def newspeed(self):
|
||||
""" We're notified of a scan speed change """
|
||||
"""We're notified of a scan speed change"""
|
||||
# If set to 0, use None so the wait() is forever
|
||||
self.dirscan_speed = cfg.dirscan_speed() or None
|
||||
with self.loop_condition:
|
||||
self.loop_condition.notify()
|
||||
|
||||
def stop(self):
|
||||
""" Stop the dir scanner """
|
||||
"""Stop the dir scanner"""
|
||||
self.shutdown = True
|
||||
with self.loop_condition:
|
||||
self.loop_condition.notify()
|
||||
|
||||
def save(self):
|
||||
""" Save dir scanner bookkeeping """
|
||||
"""Save dir scanner bookkeeping"""
|
||||
sabnzbd.save_admin((self.dirscan_dir, self.ignored, self.suspected), SCAN_FILE_NAME)
|
||||
|
||||
def run(self):
|
||||
""" Start the scanner """
|
||||
"""Start the scanner"""
|
||||
logging.info("Dirscanner starting up")
|
||||
self.shutdown = False
|
||||
|
||||
@@ -125,7 +125,7 @@ class DirScanner(threading.Thread):
|
||||
self.scan()
|
||||
|
||||
def scan(self):
|
||||
""" Do one scan of the watched folder """
|
||||
"""Do one scan of the watched folder"""
|
||||
|
||||
def run_dir(folder, catdir):
|
||||
try:
|
||||
@@ -137,6 +137,8 @@ class DirScanner(threading.Thread):
|
||||
files = []
|
||||
|
||||
for filename in files:
|
||||
if self.shutdown:
|
||||
break
|
||||
path = os.path.join(folder, filename)
|
||||
if os.path.isdir(path) or path in self.ignored or filename[0] == ".":
|
||||
continue
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user